Show Selected (image) Item on Detail Page from RadListView

Thread is closed for posting
8 posts, 1 answers
  1. Stan
    Stan avatar
    40 posts
    Member since:
    May 2017

    Posted 27 Jul 2017 Link to this post

    I'm trying to following the samples from http://docs.telerik.com however mine will go to the detail page but with no picture and no errors. Please let me know what I'm missing. Thank you so much.

    package.json

    {
      "description": "NativeScript Application",
      "license": "SEE LICENSE IN <your-license-filename>",
      "readme": "NativeScript Application",
      "repository": "<fill-your-repository-here>",
      "nativescript": {
        "id": "org.nativescript.BasicNew",
        "tns-ios": {
          "version": "3.1.0"
        },
        "tns-android": {
          "version": "3.1.1"
        }
      },
      "dependencies": {
        "nativescript-telerik-ui": "^3.0.4",
        "nativescript-theme-core": "~1.0.2",
        "tns-core-modules": "~3.1.0"
      },
      "devDependencies": {
        "babel-traverse": "6.25.0",
        "babel-types": "6.25.0",
        "babylon": "6.17.4",
        "lazy": "1.0.11"
      }
    }

    main-page.xml

    <Page xmlns="http://schemas.nativescript.org/tns.xsd" xmlns:lv="nativescript-telerik-ui/listview" navigatingTo="onNavigatingTo">
        <ActionBar title="Rlv Horizontal Scroll"/>
            <GridLayout rows="auto, *">
                <Button text="Go To Next Page" textWrap="true" tap="tapAction1" />
                <lv:RadListView id="listView" items="{{ myItems }}" selectionBehavior="Press" itemSelected="onItemSelected" row="1">
                    <lv:RadListView.listViewLayout>
                        <lv:ListViewLinearLayout scrollDirection="Horizontal" itemHeight="100" itemWidth="130"/>
                    </lv:RadListView.listViewLayout>
                    <lv:RadListView.itemTemplate>
                        <StackLayout orientation="horizontal">
                            <!-- Need loadMode="async" for Android or get OutOfMemory error  -->
                            <Image src="{{ myPaths }}" decodeWidth="400" decodeHeight="400" loadMode="async" height="100" width="130" />
                        </StackLayout>
                    </lv:RadListView.itemTemplate>
                </lv:RadListView>
            </GridLayout>
    </Page>

    main-page.js

    var fs = require("file-system");
    var frameModule = require("ui/frame");
    var observable = require("data/observable");
    var ObservableArray = require("data/observable-array").ObservableArray;

    var myImages = new ObservableArray();
    var viewModel = new observable.Observable();
        viewModel.set("myItems", myImages);

    function readFiles() {
        var documents = fs.knownFolders.currentApp();
        var myFolder = documents.getFolder("Wines");
        var array = myFolder.getEntitiesSync();
        array.forEach(function (element) {
            myImages.push({myPaths: element._path});
        });
    }

    var listView;
    exports.onItemSelected = function(arg) {
        var selectedItems = listView.getSelectedItems();
        console.log(selectedItems)  //returns [object Object]
        var detailPic;
        for (var i = 0; i < selectedItems.length; i++) {
            detailPic = selectedItems[i].itemObject;  //goes to detail page, no pic, no errors
        }
        console.log(detailPic)  //returns undefined
        frameModule.topmost().navigate({
            moduleName: "detail-page",
            bindingContext: {detailPic}
        });  
    }

    //Tap event tapAction1 = nav to detail page
    //Test nav to detail-page, this works but only in iOS
    exports.tapAction1 = function() {
        var detailPic = "~/Wines/wine1.jpg"
        frameModule.topmost().navigate({
            moduleName: "detail-page",
            bindingContext: {detailPic}
        });
    }

    exports.onNavigatingTo = function(args) {
        readFiles();
        var page = args.object;
        listView = page.getViewById("listView");
        page.bindingContext = viewModel;
    }

    detail-page.xml

    <Page navigatingTo="onNavigatingTo">
        <ActionBar title="">
            <NavigationButton text="Go Back" />
        </ActionBar>    
        <Image src="{{ detailPic }}" stretch="aspectFill"/>
    </Page>

     

  2. Nikolay Tsonev
    Admin
    Nikolay Tsonev avatar
    340 posts

    Posted 28 Jul 2017 Link to this post

    Hello Stan,
    If I understand you correctly, you have an issue with displaying the image for the details page. I reviewed your code, however, was unable to find the javascript file corresponding to the detail-page.xml, which prevents me from debugging your case. 

    It would help if you could provide a sample project, which could be debugged locally or at least missing resource.

    thank you in advance for your cooperation.
    Regards,
    nikolay.tsonev
    Progress Telerik
    Did you know that you can open private support tickets which are reviewed and answered within 24h by the same team who built the components? This is available in our UI for NativeScript Pro + Support offering.
  3. Stan
    Stan avatar
    40 posts
    Member since:
    May 2017

    Posted 28 Jul 2017 in reply to Nikolay Tsonev Link to this post

    Thank you for your reply.

    Yes, you are correctly, I'm having an issue with displaying the image for the details page.

    This is the interesting thing, in iOS simulator: It works with or without the detail-page.js file.

    detail-page.js

    exports.onNavigatingTo = function(args) {
        var page = args.object;
        page.bindingContext = page.navigationContext;
    }

    // In iOS simulator: It works with or without the detail-page.js file

  4. Nikolay Tsonev
    Admin
    Nikolay Tsonev avatar
    340 posts

    Posted 31 Jul 2017 Link to this post

    Hello Stan,

    I reviewed the attached code and find that the issue in the code is related to the way you are getting the object for the selected ListViewItem.

    To get the selected item while using itemSelectedEvent the correct approach to the index of the selected item and to get the image path via the myImages ObservableArray.
    exports.onItemSelected = function(arg) {
        // var selectedItems = arg.view
        console.log("getSelectedItems");
     
        var detailPic = myImages.getItem(arg.index);
        console.log(detailPic.myPaths);
        var tmpObservable = new observable.Observable();
        tmpObservable.set("detailPic", detailPic);
        frameModule.topmost().navigate({
            moduleName: "detail-page",
            context: detailPic
        }); 
    }
    I am attaching a project with the needed fixes.
    Also, you could review this article in the docs, where it is shown how to navigate to the details page and pass the content for selected item.


    Bear in mind that the binding name of the Image source inside the detail-page.xml file should be the same as this inside the RadListView component. In your case, it should be "myPaths" in the both places

    Regards,
    nikolay.tsonev
    Progress Telerik
    Did you know that you can open private support tickets which are reviewed and answered within 24h by the same team who built the components? This is available in our UI for NativeScript Pro + Support offering.
  5. Stan
    Stan avatar
    40 posts
    Member since:
    May 2017

    Posted 31 Jul 2017 in reply to Nikolay Tsonev Link to this post

    Thank you for sending me your project files.

    When I run it, I do get to the detail-page tapping the image, however when I go back it adds another instance of the image to the main page.

    Also when I tap the button text, I don't get the detail image but get an error on the console: CONSOLE ERROR file:///app/tns_modules/tns-core-modules/trace/trace.js:165:30: Binding: Property: 'myPaths' is invalid or does not exist. SourceProperty: 'myPaths'

    Since your image's name is icon.png I changed the following code:
    exports.tapAction1 = function() {
        // var detailPic = new observable.Observable()
        // detailPic.set("detailPic","~/image/icon.jpg");
        var detailPic = "~/image/icon.png";  // still the same error
        // var detailPic = "~/image/icon.jpg";
        frameModule.topmost().navigate({
            moduleName: "detail-page",
            bindingContext: {detailPic}
        });
    }

    Please can you explain why the binding name of the Image source inside the detail-page.xml file should be the same as this inside the RadListView component. In my case, it should be "myPaths" in the both places?

    Thanks so much.
  6. Answer
    Nikolay Tsonev
    Admin
    Nikolay Tsonev avatar
    340 posts

    Posted 01 Aug 2017 Link to this post

    Hello,
    The described problem is related to the fact that in the object that you are sending for the context there is no property named myPaths. To fix this you could send the context in the following structure {myPaths:detailPic}. Also, bear in mind that in the navigate method you should use navigationContext instead of bindingContext inside the navigate method. For example:
    exports.tapAction1 = function() {
        var detailPic = "~/image/icon.png";
        frameModule.topmost().navigate({
            moduleName: "detail-page",
            bindingContext: {myPaths: detailPic}
        });
    }


     Then you will be able to get the context as it is described here in the documentation. 
    Regarding the second question about using the same binding name. In the example the is shown one of the possible techniques for reusing the context. In this case context for the listview item is reused and also the same binding name has been taken. 

    In case you have some further problems, please provide sample project, which could be debugged locally.

    Regards,
    nikolay.tsonev
    Progress Telerik
    Did you know that you can open private support tickets which are reviewed and answered within 24h by the same team who built the components? This is available in our UI for NativeScript Pro + Support offering.
  7. Stan
    Stan avatar
    40 posts
    Member since:
    May 2017

    Posted 03 Aug 2017 in reply to Nikolay Tsonev Link to this post

    Thank you for your patience with me, someone who is new to NativeScript & RadListView methods. Also, thanks for the insight on using navigationContext instead of bindingContext inside the navigate method in my main-page.js code. As this lead me to test the differences between the two following documentation examples:

    http://docs.nativescript.org/core-concepts/navigation#example-5--how-to-provide-bindingcontext-automaticlly-while-navigating-to-a-page

    http://docs.nativescript.org/core-concepts/navigation#example-7--bind-the-content-received-from-main-page

    The documentation is not very clear as to when to use each of these examples (#5 or #7) and what are the advantages/disadvantages to each. In my case I'm opting to go with #5's bindingContext for now, because I don't have a need for a detail-page.js file at this point. Later I may have to go with #7's navigationContext if I need more functionality for the detail-page and a js file for it.

    Thanks again for your help!

    Here is my final working code to share with the forum with no detail-page.js file:

    main-page.xml:
    <Page xmlns="http://schemas.nativescript.org/tns.xsd" xmlns:lv="nativescript-telerik-ui/listview" navigatingTo="onNavigatingTo">
        <ActionBar title="Rlv Horizontal Scroll"/>
            <GridLayout rows="auto, *">
                <Button text="Go To Next Page" textWrap="true" tap="tapAction1" />
                <lv:RadListView id="listView" items="{{ myItems }}" selectionBehavior="Press" itemSelected="onItemSelected" row="1">
                    <lv:RadListView.listViewLayout>
                        <lv:ListViewLinearLayout scrollDirection="Horizontal" itemHeight="100" itemWidth="130"/>
                    </lv:RadListView.listViewLayout>
                    <lv:RadListView.itemTemplate>
                        <StackLayout orientation="horizontal">
                            <!-- Need loadMode="async" for Android or get OutOfMemory error  -->
                            <Image src="{{ myPaths }}" decodeWidth="100" decodeHeight="100" loadMode="async" height="100" width="130" />
                        </StackLayout>
                    </lv:RadListView.itemTemplate>
                </lv:RadListView>
            </GridLayout>
    </Page>

    main-page.js:
    var fs = require("file-system");
    var frameModule = require("ui/frame");
    var observable = require("data/observable");
    var ObservableArray = require("data/observable-array").ObservableArray;

    var listView;
    var myImages = new ObservableArray();
    var viewModel = new observable.Observable();
        viewModel.set("myItems", myImages);

    function readFiles() {
        var documents = fs.knownFolders.currentApp();
        var myFolder = documents.getFolder("image");
        var array = myFolder.getEntitiesSync();
        myImages = new ObservableArray();  // empty array so images don't load again in multiple sets coming back to this page
        array.forEach(function (element) {
            myImages.push({myPaths: element._path});
        });
        viewModel.set("myItems", myImages);  // reset the new array in the view-model
    }

    exports.onItemSelected = function(arg) {
        var selectedItem = myImages.getItem(arg.index);
        var detailPic = selectedItem.myPaths
        // console.log(detailPic);
        frameModule.topmost().navigate({
            moduleName: "detail-page",
            bindingContext: {detailPic}
        });
    }

    //Tap event tapAction1 = test nav to detail page
    exports.tapAction1 = function() {
        var detailPic = "~/image/icon.png";
        frameModule.topmost().navigate({
            moduleName: "detail-page",
            bindingContext: {detailPic}
        });
    }

    exports.onNavigatingTo = function(args) {
        readFiles();
        var page = args.object;
        listView = page.getViewById("listView");
        page.bindingContext = viewModel;
    }

    detail-page.xml:
    <Page navigatingTo="onNavigatingTo">
        <ActionBar title="">
            <NavigationButton text="Go Back" />
        </ActionBar>    
        <Image src="{{ detailPic }}" />
    </Page>

  8. Nikolay Tsonev
    Admin
    Nikolay Tsonev avatar
    340 posts

    Posted 04 Aug 2017 Link to this post

    Hello Stan,

    Thank you for your feedback.

    Regarding the examples in the article, I logged a new issue in our repository here and we will improve the article's content and examples. About the progress, you could keep track on the issue.

    Best Regards,
    nikolay.tsonev
    Progress Telerik
    Did you know that you can open private support tickets which are reviewed and answered within 24h by the same team who built the components? This is available in our UI for NativeScript Pro + Support offering.
Back to Top