NativeScript: Tip - access a related view of a GridView/ListView/Repeater

I was asked earlier this week about how to access a related label when you click on a button or other object in the list of a ListView/GridView/Repeater. Since it took me a little while to figure this out for my own project a couple weeks ago and since someone else ran into this issue also, I'm going to post about it.

Pretend our template is such:

<Page xmlns="http://www.nativescript.org/tns.xsd" loaded="pageLoaded">
 <ListView items="{{items}}">
  <ListView.itemTemplate>
   <StackLayout>
    <Label id="wow" text="{{text}}"/>
    <Button text="Tap" tap="onTap"/>
   </StackLayout>
  </ListView.itemTemplate>
 </ListView>
 </Page>

The code would be:
exports.pageLoaded = function(args) {
    var page = args.object;
    // Set our Record Set Data up.  
    var data = [{text: "One", color: "#FF0000"},
                {text: "Two", color: "#00FF00"},
                {text: "Three", color: "#0000FF"}];
    page.bindingContext = {items: data};
};

exports.onTap  = function(args) {
    // Find the Parent StackLayout
    var stackLayoutContainer = args.object.parent;

    // Disable button
    args.object.isEnabled = false;

    // Find the "Label" Child inside the StackLayout
    var label = stackLayoutContainer.getViewById('wow');    

    // Look at our Specific Record 
    var dataRecord = args.object.bindingContext;

    // Set the Label color to our Records color...
    label.backgroundColor = dataRecord.color;
};

So in this example; I'm showing you two cool things about the args that get sent to the onTap function inside a ListView.   The first item, is args.object -- this is the actual button.  So if you wanted to disable the button you could something like args.object.isEnabled = false; and it would disable just that specific button.  However, items in the view tree have a parent.   In our Declarative UI XML you can see that the Button is a child of the StackLayout, then that means the StackLayout is the parent.  So once we have the parent object, we just search its children for the child (label) we want.    Once we have the label we can do whatever we want with it.

The next thing I'm showing you is that in addition to the Button having a parent property, in this case the Button will also have a bindingContext property.  The bindingContext in this case is the single record that was used in the creation of this specific view object (i.e. Button in this case).  So for the first Button, it would have the full "One" record.  The second Button has the "Two" record and the final Button has the "Three" record.  You can use this information to be able to do just about anything from the Button since you now know which record this tap event is now related to.   Instead of a Button, we could have used a Image, Label, or any other view object.   The args passed to the tap event would contain the same information.blog-listview-sample

As you can see in this simple sample, by clicking the second button; it found the "Two" label, changed the color to the color that we set in the "Two" record; and also disabled the tap button.    If you were to tap the Third button, it would change that label to be blue, since the third record has color: "#0000FF" as its color.

1 comment

  1. Thank you very much. I was struggling all morning to find out how this can be done. Your article was super useful.

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.