How to add Element in te combo box in loop, QML, Sailfish, Sailfish OS - qml

I have a python function that returns a list, with Python, I can get the list, but I don't know how to add that list to qml for sailfish os. code example
menu: ContextMenu {
id: cntmenu
onClicked : test()
MenuItem { "text: option a" }
MenuItem { text: "option b" }
MenuItem { text: "option c" }
.... etc
}
functiontest(){
var testArray=[]
for(var i=0; i<10; i++){
testArray.append({"text":"Item" + i})
console.log(i)
}
return testArray
}

Your question is a bit unclear. But as I understand you want to fill in entries in a combo box.
Following code would fill in entries into a ListModel and add this model to a ComboBox:
function fillModel() {
for (var i=0; i < 10; i++) {
model1.append({"key": "Item " + i, "value" : i});
}
}
ComboBox {
id: combo1
textRole: "key"
Component.onCompleted: fillModel();
model: ListModel {
id: model1
}
}

Related

QML submenu / action creation

I'm trying to create a contextMenu for a rightClick action. The Menu has two SubMenus, "print in ..." and other subMenu. When I hoverover "print in..." it display the submenu, but to create this submenu it has to consult how many printers are availables in that moment. I can create the complete subMenu listing all the printers using the "MENU.addItem()" but I can't set the "onTriggered" handler to add an action to these Items. How can I fix it
Try this:
Menu {
id: contextMenu
Menu {
title: "print in..."
id: submenu1
onPopupVisibleChanged: {
submenu1.clear();
for(var i =0;i < 10;i ++) {
submenu1.addItem("item" + i);
}
}
}
Menu {
title: "another submenu"
MenuItem {
text: "submenu_item1"
}
MenuItem {
text: "submenu_item2"
}
}
}
as #BaCaRoZzo commented the connect and the approach in this answer works very well for this case

access context property from listview checkboxitem when onchechchanged

my qml:
if i create a button and call " _model.writeapp(appname);" from its click event it works fine, but not from the listview checkbox oncheckedchanged event
context is defined
Container {
ListView {
id: listid
dataModel: _model
function getAppName() {
return (_model.readApp());
}
function writeappName(appname) {
_model.writeapp(appname);
}
//! [1]
listItemComponents: [
ListItemComponent {
id: listcomp
type: "item"
Container {
id: conchk
CheckBox {
id: chkbx
text: ListItemData.appname
onCheckedChanged: {
console.log("checked")
if (checked) {
//have to call _model.writeapp(appname);
chkbx.ListItem.view.writeappName("hi")
}
}
}
}
}
]
}
}
Try changing this:
chkbx.ListItem.view.writeappName("hi")
To this:
conchk.ListItem.view.writeappName("hi")

BB Cascade- How to change a variable of an attached object?

so I'm new to the world of BB developement, QML, and C++ so please bear with me as I try to explain my issue.
I'm in the process of making an application that will seach for people from some far away API that returns an XML file that I will then parse and show the information in a list.
So in the first page I have two textfields that take in first name and last name. I also have a button that goes to the results page and is supposed to also send along the URL for contacting the API. Here's the code for the first page:
import bb.cascades 1.0
NavigationPane {
id: nav
Page {
content: Container {
TextField {
id: firstName
hintText: "First Name"
inputMode: TextFieldInputMode.Text
input {
flags: TextInputFlag.PredictionOff | TextInputFlag.AutoCorrectionOff
}
validator: Validator {
id: firstNameValidator
mode: ValidationMode.Immediate
errorMessage: "You must enter at least three characters."
onValidate: {
if (firstName.text.length >= 3 || firstName.text.length == 0)
state = ValidationState.Valid;
else
state = ValidationState.Invalid;
}
}
}
TextField {
id: lastName
hintText: "Last Name"
inputMode: TextAreaInputMode.Text
input {
flags: TextInputFlag.PredictionOff | TextInputFlag.AutoCorrectionOff
onSubmitted: {
if (firstNameValidator.state == ValidationState.Valid
&& lastNameValidator.state == ValidationState.Valid) {
theButton.text = "Valid enter!"
} else {
theButton.text = "Invalid enter!!!!"
}
}
}
validator: Validator {
id: lastNameValidator
mode: ValidationMode.Immediate
errorMessage: "You must enter at least three characters."
onValidate: {
if (lastName.text.length >= 3 || lastName.text.length == 0)
state = ValidationState.Valid;
else
state = ValidationState.Invalid;
}
}
}
Button {
id: theButton
text: "Search"
onClicked: {
if (firstNameValidator.state == ValidationState.Valid
&& lastNameValidator.state == ValidationState.Valid) {
text = "Valid button press!"
pushed.theUrl = link to url
pushed.dataSource.source = link to url
nav.push(pushed)
} else {
text = "Invalid button press!!!"
}
}
}
}
}
attachedObjects: [
AdvancedResult {
id: pushed
}
]
}
And here's the code for the second page:
import bb.cascades 1.0
import bb.data 1.0
Page {
property string theUrl
property alias dataSource: dataSource
content: ListView {
id: myListView
// Associate the list view with the data model that's defined in the
// attachedObjects list
dataModel: dataModel
listItemComponents: [
ListItemComponent {
type: "item"
// Use a standard list item to display the data in the data
// model
StandardListItem {
imageSpaceReserved: false
title: ListItemData.FIRST + " " + ListItemData.LAST
description: ListItemData.JOB
status: ListItemData.PHONE
}
}
]
onTriggered: {
var selectedItem = dataModel.data(indexPath);
// Do something with the item that was tapped
}
}
attachedObjects: [
GroupDataModel {
id: dataModel
grouping: ItemGrouping.None
},
DataSource {
id: dataSource
// Load the XML data from a remote data source, specifying that the
// "item" data items should be loaded
source: theUrl
query: some query
type: DataSourceType.Xml
onDataLoaded: {
// After the data is loaded, clear any existing items in the data
// model and populate it with the new data
dataModel.clear();
if (data[0] == undefined) {
dataModel.insert(data);
} else {
dataModel.insertList(data);
}
}
}
]
onCreationCompleted: {
// When the top-level Page is created, direct the data source to start
// loading data
dataSource.load();
}
}
As you can see in the first page, I try attaching the source for the data source object in two different ways: by pushing it directly to the global string theURL and by pushing it directly to the source variable of the datasource object but both ways don't seem to be working. What am I doing wrong? This is driving me crazy as I haven't been able to figure it out yet it seems like such an easy answer.
EDIT: Okay this is seriously so unintuitive! So I was able to fix it by simply adding theUrl: "link to url" under the "pushed" object in the main page and for the second page on the top adding "property string theUrl: gibberish". But now that I'm trying to make it so that the url is different depending on the user input, it just doesn't work.
So here's the current code I have so far:
import bb.cascades 1.0
NavigationPane {
id: nav
property string firstName: ""
property string lastName: ""
property string jobTitle: ""
property string test: url1
Page {
content: Container {
TextField {
id: firstNameField
hintText: "First Name"
inputMode: TextFieldInputMode.Text
input {
flags: TextInputFlag.PredictionOff | TextInputFlag.AutoCorrectionOff
}
validator: Validator {
id: firstNameValidator
mode: ValidationMode.Immediate
errorMessage: "You must enter at least three characters."
onValidate: {
if (firstNameField.text.length >= 3 || firstNameField.text.length == 0) {
state = ValidationState.Valid;
firstName = firstNameField.text;
} else {
state = ValidationState.Invalid;
}
}
}
}
TextField {
id: lastNameField
hintText: "Last Name"
inputMode: TextAreaInputMode.Text
input {
flags: TextInputFlag.PredictionOff | TextInputFlag.AutoCorrectionOff
onSubmitted: {
if (firstNameValidator.state == ValidationState.Valid
&& lastNameValidator.state == ValidationState.Valid) {
theButton.text = "Valid enter!"
} else {
theButton.text = "Invalid enter!!!!"
}
}
}
validator: Validator {
id: lastNameValidator
mode: ValidationMode.Immediate
errorMessage: "You must enter at least three characters."
onValidate: {
if (lastNameField.text.length >= 3 || lastNameField.text.length == 0) {
state = ValidationState.Valid;
lastName = lastNameField.text;
} else {
state = ValidationState.Invalid;
}
}
}
}
Button {
id: theButton
text: "Search"
onClicked: {
if (firstNameValidator.state == ValidationState.Valid
&& lastNameValidator.state == ValidationState.Valid) {
//text = "Valid button press!"
pushed.theUrl = url2
text = pushed.theUrl;
nav.push(pushed)
} else {
text = "Invalid button press!!!"
}
}
}
}
}
attachedObjects: [
AdvancedResult {
id: pushed
theUrl: test
}
]
}
So I'm currently using two different urls for testing: url1 and url2. url1 is set to test and test is set to theUrl under pushed. That works fine but when i add the line pushed.theUrl = url2; the page still returns the result for url1. So what I did is add the line text = pushed.theUrl; for testing purposes where "text" is the text shown on the button and when I run the app, even though it doesn't return to me a page, "text" is in fact set to url2 meaning that pushed.theUrl is url2. This has all been very unintuitive and not an enjoyable experience at all so far. What I'm trying to do here (get the input from a textfield, add it to a link and send it off to another page) would have taken me an hour at most on Android to code.

Invocation from function in Blackberrry 10 qml?

I have invoked invite to BBM while clicking a button in qml,but i need to send the invitation for the contacts how to do this?my code
Button {
text: "Invite"
onClicked: {
invokeQuery.uri = "pin:210000A"
invokeQuery.updateQuery();
}
attachedObjects: [
Invocation {
id: invokeShare
query: InvokeQuery {
id: invokeQuery
}
onArmed: {
trigger("bb.action.INVITEBBM");
}
}
]
}
Can anyone send me some solutions to solve this.?
Thanks
Invocation query is immutable object which means that values in the query are not dynamic. If you want to update query in dynamic you need to do it via control signals or variables.
For example, you have a component called Inviter with the pin property exposed:
import bb.cascades 1.0
Container {
property string pin
Button {
text: "Invite to BBM"
onClicked: {
query.uri = "pin:" + pin
invoke.trigger("bb.action.INVITEBBM")
}
}
attachedObjects: [
Invocation {
id: invoke
query: InvokeQuery {
id: query
invokeTargetId: "sys.bbm.sharehandler"
onQueryChanged: {
invoke.query.updateQuery()
}
}
}
]
}
Then you can use it this way:
import bb.cascades 1.0
Page {
Container {
layout: DockLayout {
}
TextArea {
id: pinEditor
hintText: "Enter PIN to invite"
onTextChanged: {
inviter.pin = text
}
input.submitKey: SubmitKey.Send
}
Inviter {
id: inviter
horizontalAlignment: HorizontalAlignment.Center
verticalAlignment: VerticalAlignment.Center
}
}
}
Also, don't forget to enable "Blackberry Messenger" permission in your bar-descriptor.xml and add following libraries to your .pro file:
LIBS += -lbbplatformbbm
LIBS += -lbbsystem

Dojo CompoButton - onClick event of MenuItem issue with its function

I have the following code in dojo creating a ComboButton with several MenuItems of the correlated Menu:
testfunc = function (input) {
//Code that uses input
}
var menu = new Menu({
id: "saveMenu"
});
//array has 10 json objects and each object has an "Id" field
for(var i=0; i<10; i++) {
var temp = array[i]["Id"];
var menuItem1 = new MenuItem({
label: "Option"+i,
onClick: function() { testfunc(temp); }
});
menu.addChild(menuItem1);
}
var comboButton = new ComboButton({
optionsTitle: "Options",
label: "Combo",
dropDown: menu,
---> onClick:function(){ console.log("Clicked ComboButton"); }
}, "combo");
comboButton.startup();
menu.startup();
I need for each MenuItem its onClick function to pass a different variable in the testfunc. Specifically the value of the array[i]["Id"] which is an array that has 10 json objects. With the above code the parameter that is passed in ALL the testfunc functions of ALL the MenuItems is the last one.
Is it possible to pass for each MenuItem the correct array[i]["Id"] value
i.e.
MenuItem0 -> onClick: testfunc(array[0]["Id"])
MenuItem1 -> onClick: testfunc(array[1]["Id"])
MenuItem2 -> onClick: testfunc(array[2]["Id"])
.
.
.
etc
Thanks
I have found a solution to my problem and I think I should share it.
The issue was solved by passing in the testfunc of the onClick event of the menuItem the parameters using the "this" token e.g.
var menuItem1 = new MenuItem({
id: array[i]["Id"],
label: "Option"+i,
onClick: function() { testfunc(this.id, this.label); }
});