Here is an example (works on playground) that creates widgets with a forEach loop.
I use index
to create a unique ID for the widgets:
id: 'txiFirstName' + (index + 1)
I understand I can change properties of the widgets by using id’s and classes which is very useful.
Is it possible to reference the widgets without .apply
?
Something like:
txiFirstName[1] //which doesn’t work
Thanks,
CODE (Tabrisjs 2.5)
const {Button, CheckBox, TextInput, TextView, ui} = require('tabris')
let persons = [
{ 'firstName': 'Bob', 'lastName': 'Smith', 'member': true },
{ 'firstName': 'Bill', 'lastName': 'Jones', 'member': false },
{ 'firstName': 'Fred', 'lastName': 'Picard', 'member': true }
]
let d = new Date()
persons.forEach((person, index) => {
console.log(person.firstName + ' ' + person.lastName + ' Member: ' + person.member)
let txiFirstName = new TextInput({
id: 'txiFirstName' + (index + 1),
left: 20, top: 'prev() 20', width: 80,
text: person.firstName
}).appendTo(ui.contentView)
let txiLastName = new TextInput({
id: 'txiLastName' + (index + 1),
left: 110, top: 'prev() -20', width: 100,
text: person.lastName
}).appendTo(ui.contentView)
let chkMember = new CheckBox({
id: 'chkMember' + (index + 1),
class: 'chkMember',
right: 5, top: 'prev() -20',
checked: person.member
}).appendTo(ui.contentView)
let txvDate = new TextView({
class: 'txvDate',
right: 5, top: 'prev()',
text: d
}).appendTo(ui.contentView)
}) // end forEach
let btnNotMember = new Button({
centerX: 0, top: 'prev() 20',
text: ' Make all persons non-members'
})
.on('select', () => {
ui.contentView.apply({'.chkMember': {checked: false}})
}).appendTo(ui.contentView)
let btnMember1 = new Button({
centerX: 0, top: 'prev() 20',
text: 'Change member 1 to Sherlock'
})
.on('select', () => {
ui.contentView.apply({'#txiFirstName1': {text: 'Sherlock'}})
}).appendTo(ui.contentView)
let btnUpdateDate = new Button({
centerX: 0, top: 'prev() 20',
text: 'Update date'
}).on('select', () => {
let d = new Date()
ui.contentView.apply({'.txvDate': {text: d}})
}).appendTo(ui.contentView)
This depends on how you structure your code.
Your example shows you looping over an array to create a list layout. If the layout ends up being taller than what can fit on the screen, there are performance gains to be had by switching to a CollectionView
. This is because the CollectionView
will render only what is necessary to be shown on the screen whereas drawing every element will keep the entire layout in memory. So if your persons
array is going to get large, I'd switch it to a CollectionView
and it sounds like you already have the code to style that.
All widgets can be referenced from a JavaScript variable, like so:
let square = new Composite({
centerX: 0, centerY: 0,
height: 25,
width: 25,
}).appendTo(ui.contentView);
square.background = 'blue';
In your example, this code:
txiFirstName[1]
will not work because:
tabris.TextInput
and is not an arraylet
inside an arrow function and therefore is only in scope inside that loop*. Anywhere else it is not defined.It looks like you got the hang of it with the three buttons at the bottom. You can reference a widget directly by using the ID or class you assign to the widget. If, for some reason you don't want to assign them IDs, you'd need to pop your elements in to a variable that is properly scoped: i.e. use var
inside the loop to hoist it or declare it outside the loop.
*Specifically, it is only in scope during that loop iteration. The next iteration of the loop will not have access to any of the variables that were set during the previous iteration.