Titanium appcelerator how to update view inside listview? - titanium

I have an Appcelerator Titanium app to do, i have a Ti.UI.ListView with a view inside (view_one.xml):
...
<ListView onItemclick="getEvaluation" id="myLisview" defaultItemTemplate="templateLm" bottom="0" top="10" onItemclick="changePage" backgroundColor="white">
<Templates>
<Require id="lm_items" src="common/templateLm"/>
</Templates>
</ListView>
...
in common/templateLm :
<Alloy>
<ItemTemplate name="templatePageMission">
<View bindId="evaluate" height="10dp">
<Label text="evaluate"></Label>
</View>
<View bindId="stars" height="15dp"/>
</ItemTemplate>
</Alloy>
in view_one.js :
function getEvaluation(e){
switch(e.bindId){
case 'evaluate':
var item = e.section.getItemAt(e.itemIndex);
console.log(item) // <= this is empty ????
item.stars.backgroundColor = "red";
break;
}
}
and when click on the evaluate view I finally got:
undefined is not an object (evaluating item.stars.backgroundColor)
If anyone can help, this is great, anyway thanks for this great community.

You have assigned the itemclick event twice:
onItemclick="changePage"
and
onItemclick="getEvaluation"
So if you just use the latter one, it should catch the controller function correctly and the item should be updated correctly, since your controller code looks valid.

Related

Titanium/ Alloy/ Appclerator: Remove event listener from a List Item

I have a ListView a bit like this:
<ListView>
<Templates>
<ItemTemplate name="example">
<View id="wrapper" onClick="onClickExampleButton">
<Label>Click Me</Label>
</View>
</ItemTemplate>
</Templates>
<ListSection id="ls">
<ListItem template="example"></ListItem>
<ListItem template="example"></ListItem>
<ListItem template="example"></ListItem>
</ListSection>
</ListView>
I want to prevent double click on the onClickExampleButton function.
So far in the controller I have code like this:
function onClickExampleButton(e) {
var item = $.ls.getItemAt(e.itemIndex);
// TODO: I want to disable the onClick eventListener here
someLongAsyncFuncToServer(function() {
// TODO: I want to re-enable the onClick eventListener here
})
}
Usually removing event listeners is as simple as
$.objId.removeEventListener(onClickExampleButton)
and re-adding it is as simple as:
$.objId.addEventListener(onClickExampleButton)
However, I am not sure how to achieve this on a ListItem
I believe you can achieve this by using source id of event fired by element. The only thing you need to take care of that since events are bubbled up to parent hierarchy, so any child-view can also invoke click event giving you unexpected source ids.
To resolve your query, you can safely use this code:
function onClickExampleButton(e) {
var item = $.ls.getItemAt(e.itemIndex);
// TODO: I want to disable the onClick eventListener here
e.source.touchEnabled = false;
someLongAsyncFuncToServer(function() {
// TODO: I want to re-enable the onClick eventListener here
e.source.touchEnabled = true;
})
}
And make a little change in your XML code like this:
<ListView>
<Templates>
<ItemTemplate name="example">
<View id="wrapper" onClick="onClickExampleButton">
<Label touchEnabled="false">Click Me</Label>
</View>
</ItemTemplate>
</Templates>
<ListSection id="ls">
<ListItem template="example"></ListItem>
<ListItem template="example"></ListItem>
<ListItem template="example"></ListItem>
</ListSection>
</ListView>
The catch here is that first of all you set touchEnabled = 'false' on Label inside View (with id = wrapper), it will make sure that click event won't be fired by Label, and will be bubbled up & fired by parent only.
Next thing is that, in click event method, you are using e.source which is now your wrapper View.
If you do not set touchEnabled=false on Label, then e.source can also contain Label reference. You can read more about events bubbling which will help you understand how you can work with event handling in Titanium efficiently.
I would put a property on the object and use it to determine status. For example,
set a variable when you click the button and then change it after the long running Async function... This way, if the status is running, then ignore the click. Once it is not running any longer, then accept the click.

Appcelerator Titanium Alloy | How to access element of other class

In Alloy Titanium, I can access XML elements with their id $.element_id but how can I get elements of other class? or xml?
EDIT
I have two files.
1. file1.js, file1xml.xml
2. file2.js, file2xml.xml
In File1.js i want to access the variable of file2xml.xml. how can i achieve this?
Anything with an id can be accessed:
file1.xml
<Alloy>
<View id="myView" />
</Alloy>
file2.js
var ctrl1 = Alloy.createController('file1');
ctrl1.myView.backgroundColor = 'red';
if you have required file2.xml in file1.xml like
<Require src="common/viewToolBar" id="viewToolBar"/>
then you can get the element with the id in file1.js like
$. viewToolBar.getView('viewSynch').visible = false;
link for more details
You can use Require tag in alloy with an Id and you can access its elements as below.
**File1.xml**
<Alloy>
<View>
<Label id="labelId">Middle</Label>
</View></Alloy>
**File2.xml**
<Window>
<Require src="File1" id="File1View" type="View"/>
<View id="header"><Label id="headerText">Header</Label></View>
<View id="nav">
<Label class="navButton" onClick="openTab" controllerName="home">Home</Label>
<Label class="navButton" onClick="openTab" controllerName="news">News</Label>
<Label class="navButton" onClick="openTab" controllerName="info">Info</Label>
<Label class="navButton" onClick="openTab" controllerName="more">More</Label>
</View>
</Window>
**File2.js**
$.File1View.labelId.text = "hi";

Titanium alloy LeftNavButton change dynamic button background image

I try to change the background image of a LeftNavButton after a click, but nothing happens. When I do this with a normal button the image will change. Are there some restrictions in doing that or is there another way to do that?
index.xml:
<Alloy>
<NavigationWindow id="win1" platform="ios">
<Window id="win2" title="Window">
<LeftNavButton>
<Button id="navButtonFilter" class="navButtonFilter" onClick="doClick" platform="ios" autoStyle="true">XX</Button>
</LeftNavButton>
<Button id="button" class="navButtonFilter" onClick="doClick"> </Button>
</Window>
</NavigationWindow>
</Alloy>
index.js:
function doClick(event) {
Ti.API.info('doClick');
$.addClass($.navButtonFilter, 'navButtonFilterActive');
$.addClass($.button, 'navButtonFilterActive');
}
$.win1.open();
index.tss:
"#win1": {
backgroundColor:"white"
}
".navButtonFilter": {
backgroundImage : "/filter.png",
}
".navButtonFilterActive": {
backgroundImage : "/list.png",
}

Titanium Layout not working while set touchEnabled=false inside Listview

When I set touchEnabled="false" for a view which was inside my List view template all my list view layout was broken. when i remove the touch enabled property it working fine. Anyone please help me to solve this issue.
Titanium SDK : 3.4.0 ,
OS : IOS and android,
Here is my sample code.
<Alloy>
<Window backgroundColor="#fff">
<ListView id="LstView" top="50" defaultItemTemplate="template1">
<Templates >
<ItemTemplate id="mytemplate" name="template1">
<View layout="horizontal" width="Ti.UI.FILL" touchEnabled="false">
<View width="Ti.UI.SIZE" height="Ti.UI.SIZE" left="5">
<Label bindId="Lbl1" Id="Lbl1" color="black"></Label>
</View>
<View width="Ti.UI.SIZE" height="Ti.UI.SIZE" left="10" >
<Label bindId="Lbl2" Id="Lbl2" color="black"></Label>
</View>
<View width="Ti.UI.SIZE" height="Ti.UI.SIZE" left="10">
<Label bindId="Lbl3" Id="Lbl3" color="black" ></Label>
</View>
</View>
</ItemTemplate>
</Templates>
<ListSection>
<ListItem Lbl1:text="hello" Lbl2:text="how are you?" Lbl3:text="I am fine" height='70'/>
</ListSection>
</ListView>
</Window>
</Alloy>
According to this article touchEnabled = false will forward the touch event to it's peers. Can you show your whole xml file? I can't clarify anything yet..
it seems a titanium bug.. open a ticket in JIRA.. Jira Bug Report

Titanium Alloy LeftNavButton not showing up in simulator

Not sure where I am doing wrong. I tried via code and by xml, but for some reason the left nav button does not show up. I am using the simulator since I don't have an actual device for ios.
The xml view
<!--filename: playType.xml->
<Alloy>
<Window class="container">
<LeftNavButton platform="ios">
<Button title="Back" onClick="closeWindow"/>
</LeftNavButton>
<View class="buttonContainer">
<Button class="menuButton" title="Single Player"/>
<Button class="menuButton" title ="Duel"/>
</View>
</Window>
</Alloy>
The Controller
//playType.js
var args = arguments[0] || {};
var closeWindow = function(){
$.playType.close();
};
The tss style
//playType.tss
".container" : {
backgroundColor:"white",
height:Ti.UI.FILL,
},
".buttonContainer":{
center:{x:"50%",y:"50%"},
height:Ti.UI.SIZE,
layout:"vertical"
}
I using this from the index.js
var playType = Alloy.createController('playType').getView();
playType.open();
The window shows up fine with the two buttons in the center but the back button doesn't appear.
What am I doing wrong. I went through the doc and also tried the code way too. Same result, no back button. :(
You have to create the window using navigation window otherwise navButton wont show up.here goes the code link for you
http://docs.appcelerator.com/titanium/3.0/#!/api/Titanium.UI.iOS.NavigationWindow
Thanks
Your window must be placed inside a TabGroup which handles all the capabilities of a navigation controller inside each tab.
<Alloy>
<TabGroup>
<Tab id="tab1" title="Tab 1">
<Window id="win1" title="Tab 1">
<LeftNavButton platform="ios">
<Button title="Back" onClick="closeWindow"/>
</LeftNavButton>
...
</Window>
</Tab>
</TabGroup>
</Alloy>
As for the back button, open a child window of the current tab using the tab as the reference to the open method.
tab.open(newWindow);