0

I am building a simple table component with Polymer. I am passing the list of items (an array of objects), and also the list of properties I'd like to display.

So, for example, I want to tell the component: only display the "name" and "number" properties of each object I'll pass to you.

this is how I the component is called:

<cool-table 
  items="[[projects]]" 
  columns='[
    {"heading": "Project name", "property": "name"}, 
    {"heading": "Project number", "property": "number"}]'>
</cool-table>

So basically it will create a table with two columns, with headings "Project name" and "Project number", and then each row will show project.name and project.number

Here is the component:

<dom-module id="cool-table">
  <template>

    <div class="table-header">
      <template is="dom-repeat" items="{{columns}}" as="column">
        <div class="cell">
          [[column.heading]]
        </div>
      </template>
    </div>

    <div class="table-content">
      <template is="dom-repeat" items="{{columns}}" as="column">
        <div class="cell">
          <!-- 
          here is where I am getting stuck:
          I want to to display [[ item.[[column.property]] ]]
          So I need to dynamically generate 
          the name of the property I'll put in the data binding
          -->
          item.[[column.property]]
        </div>
      </template>
    </div>

  </template>

  <script>
    Polymer({
      is: 'cool-table',
      properties: {
        items: {type: Array},
        columns: {type: Array}
      }
   });
  </script>

</dom-module>

In PHP I would do something like eval("\$item.$column.property")

Any idea how this can be achieved with Polymer?


Update:

I am rephrasing the question since I realized I made a mistake in describing the component. I'm using another example where I've simplified everything.

Basically I need to create a component that displays an array of objects. Each object will be on a row, and each object's key will be in a column.

Like this:

object1.name | object1.number | object1.type
object2.name | object2.number | object2.type
object3.name | object3.number | object3.type

So far, so good, that's easy.

Now what I'd like to do is to tell the component which keys need to be displayed, as I don't want to display all of them.

So, I need to tell the component: display only "name" and "number". Then we'll have:

object1.name | object1.number
object2.name | object2.number
object3.name | object3.number

To do that I'm passing the name of the keys I want to display:

<cool-table item="[[items]]" keys="['name', 'number']"></cool-table>

In cool-table.html I would have this:

<!-- loop through all items -->
<template is="dom-repeat" items="{{items}}" as="item">
  <div class="row">

      <!-- now loop through the keys we want to display -->
      <template is="dom-repeat" items="{{keys}}" as="key">
        <div class="cell">

          <!-- 
          Here I want to display the item's value for that key
          for example if key is "name" I want to display item.name
          that's what I can't figure out how to do
          -->

        </div>
      </template>

  </div>
</template>

Hopefully this now makes more sense. Thanks for hanging there with me!

Hubert
  • 369
  • 3
  • 21

2 Answers2

2

Ah, I found the solution. I needed to use a computed binding:

<!-- loop through all items -->
<template is="dom-repeat" items="{{items}}" as="item">
  <div class="row">

      <!-- now loop through the keys we want to display -->
      <template is="dom-repeat" items="{{keys}}" as="key">
        <div class="cell">

          [[getValueFromKey(item, column.key)]]

        </div>
      </template>

  </div>
</template>

<script>
  getValueFromKey: function(item, key) {
    return item[key];
  }
</script>
Hubert
  • 369
  • 3
  • 21
0

If I'm understanding your question correctly, you want an inner loop inside the columns array loop, where you iterate through the various keys of your column object?

If so, perhaps this question / answer would help?

Hi Hubert, again, not sure if I understand your question properly now, as I don't see a name property in your data. But I added one, and maybe this is what you are looking for?

Your component would look like this:

  <div class="table-header">
  <template is="dom-repeat" items="{{columns}}" as="column">
    <div class="cell">
      [[column.heading]]
    </div>
  </template>
</div>

<div class="table-content">
  <template is="dom-repeat" items="{{columns}}" as="column" filter="{{isPropertyEqName('name')}}">
    <div class="cell">
      <!-- 
      here is where I am getting stuck:
      I want to to display [[ item.[[column.property]] ]]
      So I need to dynamically generate 
      the name of the property I'll put in the data binding
      -->

        [[column.name]]


    </div>
  </template>
</div>

  </template>

  <script>
Polymer({
  is: 'cool-table',
  properties: {
    items: {type: Array},
    columns: {type: Array}
  },
  isPropertyEqName: function(search){
    return function(item){
      return item.property === 'name';
    }

  }

});

    </dom-module>

and your use of the component would look as follows, where I addded the name property

<cool-table 
  items="[[projects]]" 
 columns='[
{"heading": "Project name", "property": "name", "name": "hello"}, 
{"heading": "Project number", "property": "number", "name": "world"}]'>
</cool-table>
Community
  • 1
  • 1
Bruce
  • 152
  • 3
  • 11
  • Thanks for the link! Actually I don't really need an additional loop through the various keys of the column object. If the "property" key of the column is "name", then what I need is to display "item.name". – Hubert Dec 28 '16 at 19:56
  • Thanks so much Bruce for your help. I realized I made a mistake in the way I described the component's code. I've made an update in the first post with another example, which hopefully should be clearer. – Hubert Dec 29 '16 at 02:02