summaryrefslogtreecommitdiffstats
path: root/symbian_dev_guide/chapter_03/step_04.rst
blob: 884d4ba94646421fbd78bb71cc3259056006989d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
..
    ---------------------------------------------------------------------------
    Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
    All rights reserved.
    This work, unless otherwise expressly stated, is licensed under a
    Creative Commons Attribution-ShareAlike 2.5.
    The full license document is available from
    http://creativecommons.org/licenses/by-sa/2.5/legalcode .
    ---------------------------------------------------------------------------

Using JavaScript to Generate Test Data
======================================


We now have a `HomePage` that displays the list of our boxes. In order to work on parts of the application which edit and display the todos, we need to find an easy way to create some test data set. In this step, we will generate a test data set using JavaScript and display it on the `BoxPage` as new dummy items.

First we need to create a `ListView` that displays the test data. For this, we should start by defining a model, a delegate and a header for the list as we did in the previous step.

Before we start defining the model, we add an integer `boxId` property to the `BoxPage`. The box id will be used to identify the current box to be shown.

.. code-block:: js

    // BoxPage.qml

    property int boxId: 0 // let's set the default value to 0

The Model
---------

The test data will represent new items and should be displayed as a list, for this we add a `ListModel` component. Unlike in the previous step, when we statically defined the `ListElements`, the content here should be dynamically loaded using JavaScript code.

.. code-block:: js

    // BoxPage.qml

    ListModel {
        id: itemModel
    }

The Delegate
------------

Before we dynamically populate our model we need to have a delegate to display the data. For this we create a new `TodoItemDelegate.qml` file in the `delegates` folder:

.. image:: img/tododelegate-file.png
    :scale: 65%
    :align: center

In the delegate, we want to display the todo title and provide a checkbox which marks the todo as done. The figure below represents the components that will be used to define the `TodoItemDelegate`:

.. image:: img/tododelegate-concept.png
    :scale: 50%
    :align: center

The `TodoItemDelegate` implements a :component:`LisItem<qml-listitem.html>` that contains a :component:`CheckBox <qml-checkbox.html>` and a :component:`ListItemText <qml-listitemtext.html>` within a :qt:`Row <qml-row.html>` element to position them horizontally:


.. code-block:: js

    // TodoItemDelegate.qml

    import QtQuick 1.0
    import com.nokia.symbian 1.1

    ListItem {
        id: listItem;
        // we add a alias to the ListItemText
        // text to be accessible outside of the delegate
        property alias title: todoTitle.text

        Row {
            id: row
            anchors.fill: listItem.paddingItem
            spacing: 8

            CheckBox {
                id: checkBox
                anchors.verticalCenter: parent.verticalCenter
            }

            ListItemText {
                id : todoTitle
                mode: listItem.mode
                anchors.verticalCenter: parent.verticalCenter
            }
        }
    }


The Header
----------

We also define another list header to display the title of the page on top of the list view.

.. code-block:: js

    // BoxPage.qml

    Component {
        id: listHeader

        ListHeading {
            id: listHeading

            ListItemText {
                id: headingText
                anchors.fill: listHeading.paddingItem
                role: "Heading"
                text: "Item List"
            }
        }
    }


As we have already defined the same header component twice, we will show you how you can extract it into a reusable component in a later step.

The View
--------

Now let's add the main `ListView` for this box page. It uses our currently empty item model, our new delegate and the header defined above. When the user clicks on an item, the todo page should be shown with the item's related details.

.. code-block:: js

    // BoxPage.qml

    import "../delegates"
    ...

    ListView {
        id:  itemView
        anchors.fill: parent
        // set listHeader as header
        header: listHeader
        // set itemModel as model
        model: itemModel
        // set TodoItemeDelegate as delegate
        delegate: TodoItemDelegate {
            id: todoItemDelegate
            // use the delegate property alias itemTitle
            // to display the item title via the model
            title: model.title
            onClicked: {
                // on click signal we push TodoPage to the stack
                root.pageStack.push(window.todoPage);
            }
        }
        // set clip to true
        clip: true
    }

We also add a :component:`ToolBarLayout <qml-toolbarlayout.html>`, with two `ToolButtons`: the first one goes back to the `HomePage`, and the second will be used later to create a new item which will then belong to the current box.

.. code-block:: js

    // BoxPage.qml

    tools: ToolBarLayout {
        id: pageSpecificTools
        // ToolButton to move back to the HomePage
        ToolButton {
            iconSource: "toolbar-back"
            // on click signal pop the page from the stack to go back
            onClicked: root.pageStack.pop();
        }
        // ToolButton to be used to add new item
        ToolButton {
            iconSource: "toolbar-add"
            // for now, we just print some text for debugging purposes
            onClicked: print("add todo item to inbox");
        }
    }

The Test Data
-------------

Now that everything is in place, we can provide some test data. So let's define a `dummyData` JavaScript function that generates our data. We pass in a reference to our empty model and populate the model dynamically. To ensure that we don't populate the model twice, we first clear the model.

.. code-block:: js

    // BoxPage.qml

    function dummyData( model ) {
        model.clear()
        for (var i=0; i<10; i++) {
            model.append( { title: "todo "+i, done: false } );
        }
    }


At the current stage, the `dummyData` function should be called once the page is activated. Later on we will replace this function when we introduce the database storage.

The :component:`QML Page <qml-page.html>` component contains a :component:`status <qml-page.html#status-prop>` property which identifies the current status the page is in. To get notified when the page status changes, we override the `onStatusChanged` signal handler. We only want to call the function when the status is `PageStatus.Activating`.

.. code-block::js

    onStatusChanged: {
        if(status == PageStatus.Activating) {
            // do something if the page is activated...
        }
    }

To enhance the loading speed, we unset the view model, call the `dummyData` function and then set the model back to the view.

.. code-block:: js

    // BoxPage.qml

    onStatusChanged: {
        if(status == PageStatus.Activating) {
            itemView.model = 0;
            dummyData(itemModel);
            itemView.model = itemModel;
        }
    }


If we now run the project, we should see our dummy data displayed on the `BoxPage` as shown in the following screenshots:


.. image:: img/pages-dummydata.
    :align: center



.. rubric:: What's next?

To summarize this chapter, we have learned how to build a simple prototype of our application using the following techniques:

     Using `ListView` and `ListModel` to display items
     Defining a reusable component in QML
     Using JavaScript code to provide test data

At this stage, the application doesn't suit all our needs. It only displays the list of boxes on the `HomePage` and some test data on the `BoxPage` as also we can navigate back and forward between the pages.

In the next chapter, we will extend our application with more functionality and introduce you how to use the database storage in QML.