0
votes

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

2

2 Answers

2
votes

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.

1
votes

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.