ProgressNS / nativescript-ui-feedback

This repository is used for customer feedback regarding Telerik UI for NativeScript. The issues system here is used by customers who want to submit their feature requests or vote for existing ones.
Other
115 stars 21 forks source link

Possible to 1) isolate click on Category and 2) show/hide data w/RadListView groupingfunction? #965

Open NL33 opened 5 years ago

NL33 commented 5 years ago

Did you verify this is a real problem by searching the NativeScript Forum?

Yes.

Tell us about the problem

I am displaying data with RadListView that has categories, and subentries. I want to have the page load showing only the categories, and if the user clicks on any category, it toggles the entries (showing on click, then hiding on another click).

I have not seen this successfully accomplished with the current version of pro ui and NS. I have not been able to get it to work myself.

Is this possible?

I have run into two problems:

1) How do I isolate the click on category itself? The grouping function seems to "hide" the category title programmatically--I have not been able to know when the user clicks on it (instead of registering just clicks on the whole group) and have not been able to style that group header.

2) Once the category header is clicked, how do I show / hide the entries below? Normally, I would use something like visibility="{{isClicked ? 'visible' : 'collapsed'}}, but that is not working with RadListView.

In researching this, I have seen various approaches from over the last few years, but none have worked for me to accomplish the above.

For example, I have seen this discussion about selections with grouping ; this discussion about how 'visibility' does not function properly with RadListView; and this discussion about making selections in ListView.

These discussions seem to hit on something similar, but not this exact issue; also, they seem to be from before the pro-ui plugin changed.

So I am hoping for one place that can say the current proper way to do this.

Which platform(s) does your issue occur on?

iOS (any version) (focused on NS Angular)

Please provide the following version numbers that your issue occurs with:

Progress NativeScript UI version: "nativescript-ui-listview": "^5.0.0" CLI: 5.1.0-2018-12-05-12710 Cross-platform modules:"^5.0.5" Runtime(s):"5.1.0-rc-2018-12-10-183052-02"

Please tell us how to recreate the issue in as much detail as possible.

See discussion above and code below. Current code does not isolate click event category header (in this case, the "country" name).

Note I have also seen enableCollapsibleGroups="true" used before, but I get a warning saying that iOS does not support "Collapsible Groups".

Is there code involved? If so, please share the minimal amount of code needed to recreate the problem.

Basic code sample reflecting current attempt:

$ tns plugin add nativescript-pro-ui

sampleComponent.html:

<GridLayout >
    <RadListView [items]="places" selectionBehavior="Press" (itemSelected)="itemSelected($event)" [groupingFunction]="myGroupingFunc" >
        <ng-template tkListItemTemplate let-place="item" >
            <StackLayout>
                <Label [text]="place.city"></Label>
                 <Label [text]="place.people" ></Label> //NOTE: I have not yet determined how to show this second level data within RadListView. 
            </StackLayout>
        </ng-template>
    </RadListView>
</GridLayout>

sampleComponent.ts:

import { Component, OnInit, } from "@angular/core";
import { Router, } from "@angular/router";
import { ObservableArray } from "tns-core-modules/data/observable-array";
import { RadListView, ListViewEventData, } from "nativescript-ui-listview";

@Component({
    selector: "Sample",
    moduleId: module.id,
    templateUrl: "./sample.component.html",
})

export class SampleComponent implements OnInit  {

    public places = [
      {country: 'US', city: 'New York', people: [{name: 'Bill', age: 22}, {name: 'Suzy', age: 23} ] }, 
        {country: 'US', city: 'Los Angeles', people: [{name: 'Sarah', age: 21}, {name: 'Barb', age: 23} ] },     
        {country: 'Canada', city: 'Toronto', people: [{name: 'Fred', age: 30}, {name: 'Ted', age: 31} ] },
        {country: 'England', city: 'London', people: [{name: 'Jim', age: 22}, {name: 'Joe', age: 19} ] }
        ]

    constructor() {
    }

    myGroupingFunc(value) {
      return value.country;
    }

    itemSelected(args) {
       /***is there a way this can isolate the tap on country name?*****/
    }
} 

sample.module.ts //using lazy loading

import { NativeScriptUIListViewModule } from "nativescript-ui-listview/angular";
...
@ngModule({
   imports: [
    ...
   NativeScriptUIListViewModule,
  ]
...
NL33 commented 5 years ago

Edit: Earlier today I noticed strange behavior with RadListView: the [visibility] attribute works to show and hide entries underneath categories, but only if [visibility] is set to 'visible' when the page loads. So, if you load the page with the entries hidden, they stay hidden.

I suspect the issue is that the list does not resize to make room for the new entries. So you if you load the page with only the categories showing, when you click to try and show the entries, the page is not resizing, so the entries would come in on top of the category headers. Using normal ListView, you can see this behavior. With RadListView, there must be some feature that hides the entries when they overlap on top of the category headers, so it does not show them.

If this is correct, then I would need a way to resize the RadListView when entries are meant to be shown. This is on iOS, and I believe this is what @NickIliev meant when he said in this discussion "On iOS, the list view cells won't be remeasured dynamically when the visibility is changed (by design). That means that we can only show/hide the content via visibility but without remeasuring the item cell."

But then what is the solution to resize the RadListView on iOS? This is a common functionality (a list that resizes to show entries on click), so there should be some way.


Earlier code:

Here is code that works for showing the entries on load, and then being able to show/hide them when you click:

html:

<GridLayout style="text-align: center">
    <RadListView [items]="places" [groupingFunction]="myGroupingFunc" (tap)="tapped()">
        <ng-template let-place="item" >
            <StackLayout>
                <Label [text]="place.city" [visibility]="hideEntry ? 'collapse' : 'visible'"></Label>
            </StackLayout>
        </ng-template>
    </RadListView>
</GridLayout>

ts:

  public places = [
        {country: 'US', city: 'New York', people: [{name: 'Bill', age: 22}, {name: 'Suzy', age: 23} ] }, 
        {country: 'US', city: 'Los Angeles', people: [{name: 'Sarah', age: 21}, {name: 'Barb', age: 23} ] },     
        {country: 'Canada', city: 'Toronto', people: [{name: 'Fred', age: 30}, {name: 'Ted', age: 31} ] },
        {country: 'England', city: 'London', people: [{name: 'Jim', age: 22}, {name: 'Joe', age: 19} ] }
        ]
public hideEntry = false
...
 tapped(){
       if (this.hideEntry != true) {
         this.hideEntry = true
       } else {
         this.hideEntry = false
       }
  }

This code (i) shows the entries (the city of each), and (ii) when click the group, the entries collapse / when click again they appear.

BUT, if I reverse the visibility logic, so the entries start in the collapsed state, they never come back. So with everything the same, and just starting the opening state, it no longer works:

<GridLayout style="text-align: center">
    <RadListView [items]="places" [groupingFunction]="myGroupingFunc" (tap)="tapped()">
        <ng-template let-place="item" >
            <StackLayout>
                <Label [text]="place.city" [visibility]="!hideEntry ? 'collapse' : 'visible'"></Label> /***This starts with the city hidden--and then the city never becomes visible. Why?******/
            </StackLayout>
        </ng-template>
    </RadListView>
</GridLayout>

Again, any solutions for this?

(the other piece is to be able to isolate the click on the category header (here, the country element)--have not figured that one out yet either)

NL33 commented 5 years ago

Bump. I don't seem to be getting much response on showing and hiding categories. But what about the first part of the question: using the RadListView grouping function, is it possible to isolate the click event on the category header itself?

As an example: take the sample array above: using the grouping function, I can display it as:

US
--New York
--Los Angeles

Canada
--Toronto

England
--London

How can I know if someone clicks on the country header here (US or Canada or England)?

This normally would be simple (something like<Label text="place.country" (tap)="youClickedCountry()"></Label>), but the grouping function does not have an html entry for the header, so I am wondering how to attach a tap function to that header.

Any help on this one?

NL33 commented 5 years ago

I posted this to stackoverflow here, in case that is the better spot to get a response.