Loading HTML

You can use WebView to load HTML directly from QML. You can supply the HTML in line or as an asset in the assets directory. For more information about referencing the assets directory, see File system access.

Loading HTML in line

This code sample shows you how to provide HTML in line.

WebView {
     id: webView
     html: "<html><head><title>Hello, world!</title></head>" +
           "<body>Hello, world!</body>"+
           "</html>"
}
QString htmlStr = 
"<html><head><title>Hello, world!</title></head>" +
"<body>Hello, world!</body>"+
"</html>"

WebView* webView = new WebView();
webView->setHtml(htmlStr);

Not applicable

This example is basic HTML, and not useful. But you can use basic HTML to display the current temperature in a table in your weather app. Here's a sample of how you can do that:

import bb.cascades 1.4

Page {
    Container {                    
        id: weatherItem
            
        layout: StackLayout {
            orientation: LayoutOrientation.LeftToRight
        }

        Container {
            id: weatherpicture
            layout: StackLayout {}
            topPadding: 30
            leftPadding: 70
           
            layoutProperties: StackLayoutProperties {
                spaceQuota: 1
            }               
            ImageView {
                imageSource: "asset:///images/sun.png"
            }
        }
            
        Container {
            id: weathertable
            layout: StackLayout {}
            topPadding: 30
            leftPadding: 0
            horizontalAlignment: HorizontalAlignment.Left
                
            layoutProperties: StackLayoutProperties {
                 spaceQuota: 3
             }
             WebView {
                 id: webView
                 html: "<html><head>" +
                 "<title>Today's temperature</title>" +
                 "</head>" +
                 "<body>" +
                     "<h2 align=center>Today's temperature</h2>" + 
                     "<table border=1 align=center cellpadding=10>" +
                     "<tr><th>Celsius</th>" + 
                      "<th>Fahrenheit </th>" + 
                      "<th>Feels like</th></tr>" +
                      "<tr><td align=center id=\"tempc\">18C</td>" + 
                      "<td align=center id=\"tempf\">64F</td>" +
                      "<td align=center id=\"templ\">24C</td></tr>" +

                      "</table>"+
                 "</body>"+
                 "</html>"
              } // end WebView
        } // end WebView Container
    } // end main Container
} // end Page
//...

// Using its objectName attribute, access the
// mainContainer object
mainContr = root->findChild<Container*>("mainContainer");
StackLayout* stkLayout = new StackLayout();
stkLayout->setOrientation(LayoutOrientation::LeftToRight);
mainContr->setLayout(stkLayout);

// Create a Container object
Container* weatherpicture = Container::create()
    .layout(new StackLayout())
    .top(30)
    .left(70);

StackLayoutProperties* stkLayoutProps1 = StackLayoutProperties::create()
    .spaceQuota(1);
weatherpicture->setLayoutProperties(stkLayoutProps1);

// Create an ImageView object
ImageView* imgSource = new ImageView();
imgSource->setImageSource(QUrl("asset:///images/sun.png"));

// Add the ImageView to the Container
weatherpicture->add(imgSource);

// Create a 2nd Container object
Container* weathertable = Container::create()
    .layout(new StackLayout())
    .top(30)
    .left(0)
    .horizontal(HorizontalAlignment::Left);

StackLayoutProperties* stkLayoutProps2 = StackLayoutProperties::create()
    .spaceQuota(3);
weathertable->setLayoutProperties(stkLayoutProps2);

// Create a webView object
WebView* webView = new WebView();

// Create the HTML for the webview object
QString htmlStr = "<html><head>";
htmlStr.append("<title>Today's temperature</title>");
htmlStr.append("</head>");
htmlStr.append("<body>");
htmlStr.append("<h2 align=center>Today's temperature</h2>");
htmlStr.append("<table border=1 align=center cellpadding=10>");
htmlStr.append("<tr><th>Celsius</th>");
htmlStr.append("<th>Fahrenheit </th>");
htmlStr.append("<th>Feels like</th></tr>");
htmlStr.append("<tr><td align=center id=\"tempc\">18C</td>");
htmlStr.append("<td align=center id=\"tempf\">64F</td>");
htmlStr.append("<td align=center id=\"templ\">24C</td></tr>");
htmlStr.append("</table>");
htmlStr.append("</body>");
htmlStr.append("</html>");

// Set the HTML for the webview object
webView->setHtml(htmlStr);

// Add the webView to the Container
weathertable->add(webView);

// Add both Containers to the main Container
mainContr->add(weatherpicture);
mainContr->add(weathertable);

//...

Not applicable

And here's what the above code sample HTML would look like in a WebView in your app.

You can use the userStyleSheetLocation property to override the default cascading style sheet in your WebView.

Screen showing an HTML table in WebView on a device.

You can add a button to refresh the temperature data using the evaluateJavaScript() function. Here's a code sample that shows you how to add that button:

Button { 
   id: replyButton
   text: "Refresh"
   preferredWidth: 100
   onClicked: {
       webView.evaluateJavaScript("var c = 25; " +
             "var f = c * 9 / 5 + 32; " +
             "document.getElementById(‘tempc‘).innerHTML= c + ‘C‘;" + 
             "document.getElementById(‘tempf‘).innerHTML= f + ‘F‘;" + 
             "document.getElementById(‘templ‘).innerHTML=‘30C‘;")
   } // end onclicked
} // end button
Button* replyButton = Button::create()
    .text("Refresh")
    .preferredWidth(100)
    .onClicked(this, SLOT(onClicked()));

Here's the onClicked() slot:

void ApplicationUI::onClicked()
{
    QString script = "var c = 25; ";
    script.append("var f = c * 9 / 5 + 32; ");
    script.append("document.getElementById(‘tempc‘).innerHTML= c + ‘C‘;");
    script.append("document.getElementById(‘tempf‘).innerHTML= f + ‘F‘;");
    script.append("document.getElementById(‘templ‘).innerHTML=‘30C‘;");

    webView->evaluateJavaScript(script);
}

Not applicable

To change the appearance of the WebView, you can use any of the Control properties. You can change the size, margins, width, and height of the WebView.

Loading HTML as an asset

You can create an HTML file and deliver it as web content in your app. To use HTML content as an asset, you must specify the asset name and the local path to the assets directory. The local path to the assets directory is local:///. The asset name is the local path of the HTML file in the assets folder, including the file name extension. Let's say that you have an asset called myHTML.html that you placed in the assets/web folder of your project. Here's how to create a WebView with your HTML as an asset.

import bb.cascades 1.4

Page {
    Container {
        WebView {
            id: webView
            url: "local:///assets/web/myHTML.html"  
        }
    }
}

In C++, you could use the following code sample, with some added checking to make sure that the file exists first:

#include "applicationui.hpp"

#include <bb/cascades/Application>
#include <bb/cascades/QmlDocument>
#include <bb/cascades/AbstractPane>
#include <bb/cascades/LocaleHandler>
#include <bb/cascades/Container>
#include <bb/cascades/Page>
#include <bb/cascades/WebView>
#include <bb/cascades/StackLayout>
#include <QFile>
#include <QDebug>

using namespace bb::cascades;

ApplicationUI::ApplicationUI() :
        QObject()
{
    // Create the content container
    Container *contentContainer = new Container();
    contentContainer->setLayout(StackLayout::create());

    if (QFile::exists("app/native/assets/web/myHTML.html"))
    {
        qDebug() << "Found HTML file!";

        WebView* webView = new WebView(contentContainer);
        webView->setUrl(QUrl("local:///assets/web/myHTML.html"));

        // Add the webView to the container
        contentContainer->add(webView);
    }
    else
    {
        qDebug() << "Cannot find HTML file!";
    }

    // Create a page using the root container and set the scene
    Page *page = new Page();
    page->setContent(contentContainer);
    Application::instance()->setScene(page);

}

Not applicable

Adding gesture handling to your WebView

To add support for user interaction on a WebView, you need to add gesture handling to your app. Gesture handling lets a user pinch to zoom in and out of the content that your app loads in your WebView in a ScrollView. To learn about gesture handling, including adding PinchHandler objects to your ScrollView, see Touch screen input.

You must set pinchToZoomEnabled to true on your ScrollViewProperties, and connect your WebView signals to your ScrollView properties. You can set maxContentScale: 5 and minContentScale: 1 to limit how much the content can zoom. If the user reaches the maxContentscale value, the content doesn't zoom any more and bounces to the zoom level allowed by the maxContentScale property.

Here's a code sample that demonstrates gesture handling in a WebView:

Screen that demonstrates pinching in a WebView.
import bb.cascades 1.4

Page {
    ScrollView {
        id: scrollView
        scrollViewProperties {
            scrollMode: ScrollMode.Both
            pinchToZoomEnabled: true
            maxContentScale: 5
            minContentScale: 1 
        }
        
        layoutProperties: StackLayoutProperties { spaceQuota: 1.0 }
        
        Container {
            background: Color.LightGray
            
            WebView {
                id: webView
                url: "local:///assets/web/myHTML.html"
                
                onMinContentScaleChanged: {
                    scrollView.scrollViewProperties.minContentScale
                        = minContentScale;
                }
                
                onMaxContentScaleChanged: {
                    scrollView.scrollViewProperties.maxContentScale
                        = maxContentScale;
                }
            } // end WebView
        } // end container
    } // end ScrollView
}

This code sample uses the following HTML file in the assets/web folder:

<!DOCTYPE html>
<html>
<body>

<img src="http://www.ezilon.com/maps/images/world-physical-map.gif">

</body>
</html>
#include "applicationui.hpp"

#include <bb/cascades/Application>
#include <bb/cascades/QmlDocument>
#include <bb/cascades/AbstractPane>
#include <bb/cascades/Page>
#include <bb/cascades/Container>
#include <bb/cascades/StackLayout>
#include <bb/cascades/LocaleHandler>
#include <bb/cascades/ScrollView>
#include <bb/cascades/WebView>
#include <bb/cascades/Color>

using namespace bb::cascades;

ApplicationUI::ApplicationUI() : QObject()
{
    bool res;
    Q_UNUSED(res);

    // Create the content container
    Container *contentContainer = new Container();
    contentContainer->setLayout(StackLayout::create());
    contentContainer->setTopPadding(20.0f);
    contentContainer->setBackground(Color::LightGray);

    // Create a ScrollView
    scrollView = ScrollView::create().content(contentContainer);
    ScrollViewProperties *scrollViewProp = scrollView->scrollViewProperties();
    scrollViewProp->setScrollMode(ScrollMode::Horizontal);
    scrollViewProp->setScrollMode(ScrollMode::Both);
    scrollViewProp->setPinchToZoomEnabled(true);
    scrollViewProp->setMaxContentScale(5);
    scrollViewProp->setMinContentScale(1);

    // Add a WebView object to the Container
    WebView* webView = new WebView(contentContainer);
    webView->setUrl(QUrl("local:///assets/web/myHTML.html"));

    // Connect the minContentScaleChanged() signal to
    // the onMinContentScaleChanged slot
    res = QObject::connect(webView,
            SIGNAL(minContentScaleChanged(float)),
            this,
            SLOT(onMinContentScaleChanged(float)));
    Q_ASSERT(res);

    // Connect the maxContentScaleChanged() signal to
    // the onMaxContentScaleChanged slot
    res = QObject::connect(webView,
            SIGNAL(maxContentScaleChanged(float)),
            this,
            SLOT(onMaxContentScaleChanged(float)));
    Q_ASSERT(res);

    // Add the webView to the container
    contentContainer->add(webView);

    // Create a page using the root container and set the scene
    Page *page = new Page();
    page->setContent(scrollView);
    Application::instance()->setScene(page);
}

// Slot to set the minContentScale value
void ApplicationUI::onMinContentScaleChanged(float minContentScale)
{
    scrollView->scrollViewProperties()->setMinContentScale(minContentScale);
}

// Slot to set the maxContentScale value
void ApplicationUI::onMaxContentScaleChanged(float maxContentScale)
{
    scrollView->scrollViewProperties()->setMaxContentScale(maxContentScale);
}

This code samples also defines a ScrollView and two slots in the applicationui.hpp file:

#ifndef ApplicationUI_HPP_
#define ApplicationUI_HPP_

#include <QObject>
#include <bb/cascades/ScrollView>

namespace bb
{
    namespace cascades
    {
        class LocaleHandler;
    }
}

/*!
 * @brief Application UI object

 */
class ApplicationUI : public QObject
{
    Q_OBJECT
public:
    ApplicationUI();
    virtual ~ApplicationUI() {}
private slots:
    void onMinContentScaleChanged(float minContentScale);
    void onMaxContentScaleChanged(float maxContentScale);
private:
    bb::cascades::ScrollView* scrollView;
};

#endif /* ApplicationUI_HPP_ */

This code sample also uses the following HTML file in the assets/web folder:

<!DOCTYPE html>
<html>
<body>

<img src="http://www.ezilon.com/maps/images/world-physical-map.gif">

</body>
</html>

Not applicable

Integrating a WebView with other apps

To integrate a WebView with other apps, set the activeTextEnabled property to true to indicate that you want a postprocessor to run to highlight any ActiveText segments and connect them to the invocation framework. This setting allows users to click ActiveText segments in the web content and invoke other apps on the device. To learn about invoking another app or an external service from a WebView, see App integration.

This processing takes place immediately after a webpage is loaded and may cause delays to loading the webpage in your app.

Last modified: 2015-07-24



Got questions about leaving a comment? Get answers from our Disqus FAQ.

comments powered by Disqus