Search code examples
javascripteventsdojoevent-delegationdojox.mobile

Dojo Prevent onclick events from children nodes


I have programmatically created an ul like follows:

var paneaux= dojo.byId("personsListPane");

var list = new dojox.mobile.RoundRectList({
    id: 'personsList',
    select:"single",
}).placeAt(paneaux).startup();

var listaux=dojo.byId("personsList");

for (var i = 0, len = persons.length; i < len; i++){
    var person= persons[i];
    var li = new dojox.mobile.ListItem({
        id:person.IdPerson,
        label: person.Surname + " " + person.Surname2 + ", " + person.Name,
        clickable : true,
    }, domConstruct.create("li", {}, listaux));

    li.startup();

    on(li, "click",  lang.hitch(this, function(evt){
        li= evt.target;
        var person = gpt._sessionData.userPersons.filter(function(obj){
            return obj.IdPerson==li.id;
        });                         
        gpt._sessionData.defaultPersonEmployee =person[0];
        initImpl();
    }));  
}

Which gives the following html result:

<li class="mblListItem mblListItemUnchecked" tabindex="0" id="1vxki6w6vb8uihiu9crhocy3e" widgetid="1vxki6w6vb8uihiu9crhocy3e" aria-selected="false" role="button">
    <div class="mblListItemRightIcon">
       <div title="" class="mblDomButtonArrow mblDomButton">
         <div> </div>
       </div>
    </div>
    <div class="mblListItemLabel">López Ibarra, Alberto</div>
</li>

The problem is the following: When I click on the name of the person, it enters in the event i created with on(..) but the event target is not the ListItem, but the ListItemLabel. However, the label is slightly smaller than the item, and when I click in that small accesible space of the ListItem, the event.target is the ListItem. The problem is obvious, I would have to check the type of item that is entering the method to get the info that I need one way or another...

  1. Is there any way to force that, if I click anywhere in the ListItem, this is the element that will be the target of the event??

  2. Why ListItemLabel is entering on that method if I connected the handler to the ListItiem?

  3. Is there any way to connect the handler exclusively to the ListItem and NOT the child nodes??

Thank you a lot in advance!!


Solution

  • You have two possibilities , the first one is to compare if the event.target equals your li element, if so then get directly the id otherwise get target parent and acces the li id .

    The second is just to use the currently click element context (this) , knowing that you have to remove the lang.hitch function to prevent executing the event in the globale context ( window context in this case ) So remove the lang.hitch because you're not using it inside the click (no need of calling context here), and the this will refer to your clicked li element and the id is just acceses by this.id .

    See below worknig snippet :

    require(["dojo/ready","dojo/dom","dojo/dom-construct","dojo/on","dojo/_base/lang","dojox/mobile/parser", "dojox/mobile/Icon", "dojox/mobile/RoundRectList", "dojox/mobile/ListItem"], function (ready, dom, domConstruct, on, lang, parser, Icon, RoundRectList, ListItem) {
      var paneaux = dom.byId("personsListPane");
      var list = new RoundRectList({
          id: 'personsList',
          select:"single",
      }).placeAt(paneaux).startup();
    	
      var listaux = dom.byId("personsList");
      for (var i = 1, len = 5; i < len; i++) {
        //var person= persons[i];
        var li = new dojox.mobile.ListItem({
            id:i,
            label: "Surname" + i,
            clickable : true,
        }, domConstruct.create("li", {}, listaux));
    
        li.startup();
    		
        on(li, "click", function(evt){
          console.log("Id of clicked = "+ this.id);
          /*var person = gpt._sessionData.userPersons.filter(function(obj){
            return obj.IdPerson==li.id;
          });                         
          gpt._sessionData.defaultPersonEmployee =person[0];
          initImpl();*/
        }); 
      }
      });
    .as-console-wrapper {
      max-height: 65px !important;
    }
    <link href="https://ajax.googleapis.com/ajax/libs/dojo/1.9.0/dojox//mobile/themes/iphone/iphone.css" rel="stylesheet"/>
    <script src="https://ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>
    <div id="personsListPane"></div>