Create the add page

So far, we've created the main UI for our app, which consists of a ListView, an associated GroupDataModel, and an Add action. We've also set up our app to handle some important signals, such as triggered() of ListView and itemAdded() of GroupDataModel. Our app relies on several custom QML components, so the next thing to do is create these components in their own .qml files.

Create the AddPage.qml file and root control

The first component that we'll create is the AddPage component. This component represents a screen that lets users type information for a new quote, such as first name, last name, and quote text. This component also includes a title bar, with Cancel and Save buttons, that appears at the top of the screen.

Screen showing the main UI for the Quotes app.

Start by creating a new folder called AddPage in the assets folder of your project. Inside the AddPage folder, create a .qml file called AddPage.qml.

The root control of this component is a Page. We also declare a custom signal called addPageClose(), and our AddPage component emits this signal when a user taps Cancel or Save.

import bb.cascades 1.0

Page {
    id: addPage
    signal addPageClose()

Add a title bar

We use the titleBar property to specify a title bar for the Page. We make sure that the title bar is visible by using the visibility property, and we add the Cancel and Save buttons by using the dismissAction and acceptAction properties, respectively.

The dismissAction always appears on the left side of the title bar, and the acceptAction always appears on the right side.

Diagram showing the dismiss and accept actions.

When a user taps Cancel, our app emits the custom addPageClose() signal. This signal indicates that we want to close the Sheet that contains the AddPage component, and we handled this signal earlier in the tutorial. When the user taps Save, our app also emits the addPageClose() signal, but first we call a C++ function called addNewRecord(). This function interacts with the data model and underlying SQL database to add the new quote data. We'll implement this function later when we get to the C++ portion of the tutorial.

titleBar: TitleBar {
    id: addBar
    title: "Add"
    visibility: ChromeVisibility.Visible
        
    dismissAction: ActionItem {
        title: "Cancel"
        onTriggered: {
            addPage.addPageClose();
        }
    }
        
    acceptAction: ActionItem {
        title: "Save"
        onTriggered: {
            _quoteApp.addNewRecord(firstNameField.text, lastNameField.text,
                                   quoteField.text);
            addPage.addPageClose();
        }
    }
}

Add the text fields

Next, we add a Container to represent the entire screen below the title bar. This container uses a DockLayout and includes margins to separate the text fields from the edges of the screen.

Container {        
    id: editPane
    property real margins: 40
    background: Color.create("#f8f8f8")
    topPadding: editPane.margins
    leftPadding: editPane.margins
    rightPadding: editPane.margins
        
    layout: DockLayout {
    }
Diagram showing the TextArea and TextField controls that are used on the add page.

Inside this top-level container, we add our text fields. We use three fields: a TextArea for the quote text, a TextField for the author's first name, and another TextField for the author's last name. Let's add the TextArea first. To get the look we want, we set properties such as margins, preferred height, maximum height, and horizontal alignment. Notice that the enabled property is set to false. We don't allow users to start typing the quote or first name until the last name field is populated. This approach ensures that a last name is always provided for a new quote, which makes it easier to manage the data in the data model (we can assume that every entry in the model includes, at least, a value for the lastname field).

Container {
    layout: StackLayout {
    }

    TextArea {
        id: quoteField
        hintText: "Quote"
        topMargin: editPane.margins
        bottomMargin: topMargin
        enabled: false
        preferredHeight: 450
        maxHeight: 450
        horizontalAlignment: HorizontalAlignment.Fill                
    }

Now, let's add a Container to hold the two TextField controls. We use a left-to-right stack layout for this container to position the fields side-by-side. In the TextField that represents the author's last name, we include the onTextChanging signal handler. When a user types in this field, the textChanging() signal is emitted, and we test to determine whether there is any text in the field (that is, whether the text length is greater than zero). If so, we enable the acceptAction, quote field, and first name field to allow the user to type in them.

        Container {
            layout: StackLayout {
                orientation: LayoutOrientation.LeftToRight
            }

            TextField {
                id: firstNameField
                rightMargin: editPane.margins
                hintText: "First name"
                enabled: false
            }

            TextField {
                id: lastNameField
                hintText: "Last name"                    
                    
                onTextChanging: {
                    if (text.length > 0) {
                        addPage.titleBar.acceptAction.enabled = true;
                        quoteField.enabled = true;
                        firstNameField.enabled = true;
                    } else {
                        addPage.titleBar.acceptAction.enabled = false;
                        quoteField.enabled = false;
                        firstNameField.enabled = false;
                    }
                }
            } // end of last name field
        } // end of name text Container
    } // end of text Container (name text + quote text)
} // end of top-level Container

Create a custom JavaScript function

To finish off the AddPage component, we create a custom JavaScript function called newQuote(). This function prepares the AddPage for a blank entry by clearing all of the text fields and disabling the acceptAction, quote field, and first name field. We call this function from main.qml when the Sheet that contains the AddPage is closed.

    function newQuote() {
        firstNameField.text = "";
        lastNameField.text = "";
        quoteField.text = "";
        addPage.titleBar.acceptAction.enabled = false;
        quoteField.enabled = false;
        firstNameField.enabled = false;
    }
} // end of Page

We're now finished with the AddPage custom component. In the next section, we'll create the screen that displays an individual quote.

Last modified: 2014-06-24



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

comments powered by Disqus