How to create a table in NativeScript with dynamic row and column count?
Asked Answered
C

2

9

I'm trying to create a table or data grid with dynamic row and column count in my NativeScript application. I have some product categories and some products in these categories. Products have some specifications with respect to its belonging category. Here is an example JSON for products in graphic cards category:

{
  "parts": [
    {
      "id": 1,
      "name": "GTX 1080",
      "stockCount": 10,
      "specifications": [
        {
          "id": 1,
          "name": "Memory",
          "value": "11 GB"
        },
        {
          "id": 2,
          "name": "Core Clock",
          "value": "1500 MHz"
        }
      ]
    },
    {
      "id": 2,
      "name": "RX 580",
      "stockCount": 8,
      "specifications": [
        {
          "id": 1,
          "name": "Memory",
          "value": "8 GB"
        },
        {
          "id": 2,
          "name": "Core Clock",
          "value": "1366 MHz"
        }
      ]
    }
  ]
}

Here is another example in CPU category:

{
  "parts": [
    {
      "id": 3,
      "name": "i5 7600K",
      "stockCount": 8,
      "specifications": [
        {
          "id": 3,
          "name": "Socket",
          "value": "LGA 1151"
        },
        {
          "id": 4,
          "name": "Frequency",
          "value": "3.8 GHz"
        },
        {
          "id": 5,
          "name": "L3 Cache",
          "value": "6 MB"
        }
      ]
    },
    {
      "id": 4,
      "name": "Ryzen 7 1700",
      "stockCount": 15,
      "specifications": [
        {
          "id": 3,
          "name": "Socket",
          "value": "AM4"
        },
        {
          "id": 4,
          "name": "Frequency",
          "value": "3.0 GHz"
        },
        {
          "id": 5,
          "name": "L3 Cache",
          "value": "16MB"
        }
      ]
    }
  ]
}

I want to show graphic cards as a table like this:

  Name     Stock    Memory    Core Clock
GTX 1080     10      11 GB     1500 MHz
 RX 580       8       8 GB     1366 MHz

and CPUs like this:

    Name      Stock    Socket    Frequency    L3 Cache
i5 7600K         8    LGA 1151    3.8 GHz        6 MB
Ryzen 7 1700    15    AM4         3.0 GHz       16 MB

I have tried RadListView with GridLayout but cannot do this. If specification count for all categories would be constant, I could easily create GridLayout with constant number of columns like this:

<GridLayout columns="*, auto, auto, auto, auto">...</GridLayout>

But arbitrary number of specifications put me into a challenge here.

Is there some way in NativeScript Angular to achieve this? I'm using 4.1.0 version of NativeScript.

Confiscatory answered 23/6, 2018 at 21:55 Comment(3)
your question is not clear. you are saying that specification count is not constant but it looks constant in ur example like graphics card has 2 memory and core clock and cpu has 3 socket, frequency and L3 cache. so what is the issue here? also add some code snippet of what you have done and what you want to achieveLebkuchen
if CPU and graphics card is different list then create 2 different list with respective code.Lebkuchen
@bhavinjalodara I thought it was obvious, but I guess it was not: I have an administration panel on which the user can add new specifications to current categories. For example, the user can add "Memory Clock" specification to Graphic Cards category, then graphic cards will have 3 specifications instead of 2. If I design the page with constant number of columns then I need to make a client release each time the user adds a new specification. The user can also add more categories which renders the "2 different list with respective code" solution useless.Orgell
L
8

you can generate value dynamically and then bind it to GridLayout cloumns property something like this

<GridLayout [columns]="genCols(item)">

&

genCols(item){
    if(item.columns){
      return item.columns;
    }else{
      item.columns="*, auto";
      item.specifications.forEach((el)=>{
        item.columns+=",auto";
      })
      return item.columns
    }
}

if users can add specifications and specification count for each item is same then simpler way will be to use single variable and set its value on ngOnInit and update it on specification added like columns=genCol(items[0]) and then <GridLayout [columns]="columns">

Lebkuchen answered 24/6, 2018 at 19:59 Comment(1)
This is absolutely brilliant and what I was looking for. Thanks! Another useful aspect of this answer is that I realized that one can use square brackets around an attribute in XML and calculate that attribute in TypeScript.Orgell
S
5

For those looking for a solution strictly in the template, I used String​.prototype​.repeat() within the [columns] attribute:

[columns]="'*, auto' + ', auto'.repeat(parts.specifications.length)"

Full example:

<GridLayout [colums]="'*, auto, ' + 'auto, '.repeat(parts.specifications.length)">
    <Label col="0" [text]="parts.name"></Label>
    <Label col="1" [text]="parts.stockCount"></Label>
    <Label [col]="i" [text]="spec.value" *ngFor="let spec of parts.specifications; let i=index+2"></Label>
</GridLayout>
Skippie answered 7/6, 2019 at 22:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.