Stack of Screens Passing Information Around

BlackBerry 10 Cascades Navigation Stack Comic

Lately I’ve been getting some requests for this topic and it seems like a good one to do a tutorial on… So imagine a scenario where there are multiple pages where you have the user go from one to the next.  That is called a NavigationPane in Cascades.  Now imagine that you want things on page 1 to affect things on page 2 and 3.  And page 2 to affect pages 1 and 3. And page 3 to affect 1 and 2. To do that you need property aliases… See past the break how to make this work!

First we’ll set up the 3 pages with a text field (what we’ll send to other pages), and a few buttons:

main.qml

import bb.cascades 1.0

NavigationPane {
    id: nav
    Page {
        Container {
            TextField {
                id: field1
                text: ""
            }
            Button {
                text: "Send text to Page 2"
                onClicked: {
                }
            }
            Button {
                text: "Send text to Page 3"
                onClicked: {
                }
            }
            Button {
                text: "Go to Page 2"
                onClicked: {
                    nav.push(pushed)
                }
            }
            Label {
                id: label1
                text: "Main Page Label: "
            }
        }
    }
    attachedObjects: [
        Pagetwo {
            id: pushed
        },
        Pagethree {
            id: pushed2
        }
    ]
}

Pagetwo.qml

import bb.cascades 1.0

Page {
    Container {
        TextField {
            id: field2
            text: ""
        }
        Button {
            text: "Send to Main Page"
            onClicked: {
            }
        }
        Button {
            text: "Send to Page 3"
            onClicked: {
            }
        }
        Button {
            text: "Go to Page 3"
            onClicked: {
                nav.push(pushed2)
            }
        }
        Label {
            id: page2label
            text: "Page 2 Label: "
        }
    }
}

Pagethree.qml

import bb.cascades 1.0

Page {
    Container {
        TextField {
            id: field3
            text: ""
        }
        Button {
            text: "Send to Main Page"
            onClicked: {
            }
        }
        Button {
            text: "Send to Page 2"
            onClicked: {
            }
        }
        Label {
            id: page3label
            text: "Page 3 Label: "
        }
    }
}

What we have above is a stack of 3 pages where main.qml pushes to Pagetwo.qml, Pagetwo.qml pushes to Pagethree.qml.  And going backwards Pagethree.qml pops to Pagetwo.qml and Pagetwo.qml pops to main.qml. 

This is done by setting up main.qml as a NavigationPage (id: nav) then attaching Pagetwo and Pagethree as attachedObjects (with id: pushed and id: pushed2, respectiviely) to the that NavigationPane.  Then on the button clicks have the page push to the id of the attachedObject.

BlackBerry 10 Cascades Navigation Stack

Now our goal is to make it so what’s in the TextField on each page can be “sent” to the label on the other pages.  To do that we need to expose the id of the label on Pagetwo.qml and Pagethree.qml to all the pages by using a property alias.  Note the label in main.qml is exposed by default as you will see a bit later on. To create the property alias we do the following:

Pagetwo.qml

import bb.cascades 1.0

Page {
    property alias page2label: page2label
    Container {
...
    }
}

The creation of the alias is the line: “property alias page2label: page2label” which means anytime you call page2label in another QML file it will call page2label in from this QML file.  You do not have to call them the same but I find it easiest/less confusing to do it this way.  If you don’t want to call them the same the format is:

property alias <whatever you want the alias to be> : <the element id you are calling>

The same can be done for page3label inside of Pagethree.qml.

Next, we can add the following code to the onClicked of the “Send to Page 2” button on main.qml:

Button {
                text: "Send text to Page 2"
                onClicked: {
                    pushed.page2label.text = "Page 2 Label: " + field1.text;
                }

What we are doing here is calling the id of the attachedObject “pushed” the alias “page2label” the property we’d like to change “text” then what we want to change it to… So a string of text plus what we’ve typed into field1.

Then as I mentioned above you don’t need to do this for main.qml id’s so in Pagetwo.qml the onClicked of “Send to Main Page would look like:

Button {
            text: "Send to Main Page"
            onClicked: {
                label1.text = "Main Page Label: " + field2.text;
            }

Repeat thes methods for all the buttons and they should all talk to each other as you would expect.  Just in case, full source code for each is pasted below.

-Brian

main.qml

import bb.cascades 1.0

NavigationPane {
    id: nav
    Page {
        Container {
            TextField {
                id: field1
                text: ""
            }
            Button {
                text: "Send text to Page 2"
                onClicked: {
                    pushed.page2label.text = "Page 2 Label: " + field1.text;
                }
            }
            Button {
                text: "Send text to Page 3"
                onClicked: {
                    pushed2.page3label.text = "Page 3 Label: " + field1.text;
                }
            }
            Button {
                text: "Go to Page 2"
                onClicked: {
                    nav.push(pushed)
                }
            }
            Label {
                id: label1
                text: "Main Page Label: "
            }
        }
    }
    attachedObjects: [
        Pagetwo {
            id: pushed
        },
        Pagethree {
            id: pushed2
        }
    ]
}

Pagetwo.qml

import bb.cascades 1.0

Page {
    property alias page2label: page2label
    Container {
        TextField {
            id: field2
            text: ""
        }
        Button {
            text: "Send to Main Page"
            onClicked: {
                label1.text = "Main Page Label: " + field2.text;
            }
        }
        Button {
            text: "Send to Page 3"
            onClicked: {
                pushed2.page3label.text = "Page 3 Label: " + field2.text;
            }
        }
        Button {
            text: "Go to Page 3"
            onClicked: {
                nav.push(pushed2)
            }
        }
        Label {
            id: page2label
            text: "Page 2 Label: "
        }
    }
}

Pagethree.qml

import bb.cascades 1.0

Page {
    property alias page3label: page3label
    Container {
        TextField {
            id: field3
            text: ""
        }
        Button {
            text: "Send to Main Page"
            onClicked: {
                label1.text = "Main Page Label: " + field3.text;
            }
        }
        Button {
            text: "Send to Page 2"
            onClicked: {
                pushed.page2label.text = "Page 2 Label: " + field3.text;
            }
        }
        Label {
            id: page3label
            text: "Page 3 Label: "
        }
    }
}