This is a migrated thread and some comments may be shown as answers.

Show Selected (image) Item on Detail Page from RadListView

7 Answers 115 Views
ListView
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Stan
Top achievements
Rank 1
Stan asked on 27 Jul 2017, 11:28 PM

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>

 

7 Answers, 1 is accepted

Sort by
0
Nikolay Tsonev
Telerik team
answered on 28 Jul 2017, 03:36 PM
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.
0
Stan
Top achievements
Rank 1
answered on 28 Jul 2017, 04:58 PM

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

0
Nikolay Tsonev
Telerik team
answered on 31 Jul 2017, 06:55 AM
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  the correct approach to the index of the selected item and to get the image path via the 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. file should be the same as this inside the RadListView component. In your case, it should be "" 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.
0
Stan
Top achievements
Rank 1
answered on 31 Jul 2017, 11:47 PM
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.
0
Accepted
Nikolay Tsonev
Telerik team
answered on 01 Aug 2017, 02:52 PM
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.
0
Stan
Top achievements
Rank 1
answered on 03 Aug 2017, 09:10 PM

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>

0
Nikolay Tsonev
Telerik team
answered on 04 Aug 2017, 05:55 AM
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.
Tags
ListView
Asked by
Stan
Top achievements
Rank 1
Answers by
Nikolay Tsonev
Telerik team
Stan
Top achievements
Rank 1
Share this question
or