Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

vaadin-grid-filter for an Array of Strings not working

I am using the vaadin-grid-filter with Polymer 2.x and I am facing the following problem. I have a vaadin-grid-column as following,

<vaadin-grid-column width="15em">
        <template class="header">
            <vaadin-grid-filter aria-label="Inventory" path="" value="[[_filterItems]]">
                <vaadin-text-field slot="filter" placeholder="Item" value="{{_filterItems}}" focus-target></vaadin-text-field>   
            </vaadin-grid-filter>
        </template>
    <template>[[item]]</template>
</vaadin-grid-column>

[[item]] is an array of strings and the filtering doesn't work when the path is set to an empty string. If I put each string inside a Json object and access it as in the documentation, then it works fine. But I am wondering whether there is a way I can filter this as it is.

Thank you in advance.

like image 606
Will_Panda Avatar asked May 28 '18 11:05

Will_Panda


1 Answers

I did some digging into the vaadin-grid source code and found some less than ideal answers. Unfortunately there doesn't seem to be any "magic" placeholders for the path property value that will get you what you want in the context of using the "x-array-data-provider" component for [[item]]. Here are a couple values I tried and their results:

"" : the filtering mechanism attempts to retrieve the item[""] property for string comparison. Unfortunately item[""] will be undefined and the comparison will fail to match.

null/undefined : there is a check for this very early on in the logic that will abort any filtering process as a whole.

So unfortunately due to the lack of any self-referencing object property (that I'm aware of) available in the default JS objects, I was unable to circumvent the property accessor in a way to get what you want.

I did however find a potential workaround in the context of using a server data provider. Using the vaadin-grid-filter example (from vaadin) here, it appears as though the filtering request can be serialized and sent to the server. If you have full control over the internals of the remote server data provider code then you could write your own custom filtering mechanism there to accomplish what you want. Here is the code from the example (in case of removal):

<x-remote-filtering-example></x-remote-filtering-example>
<dom-module id="x-remote-filtering-example">
  <template>
    <vaadin-grid aria-label="Filtering with Data Provider Example" id="grid">

      <vaadin-grid-column width="50px" flex-grow="0">
        <template class="header">#</template>
        <template>[[index]]</template>
      </vaadin-grid-column>

      <vaadin-grid-column>
        <template class="header">
          <vaadin-grid-filter aria-label="Fist Name" path="firstName" value="[[_filterFirstName]]">
            <input placeholder="First Name" value="{{_filterFirstName::input}}" focus-target>
          </vaadin-grid-filter>
        </template>
        <template>[[item.firstName]]</template>
      </vaadin-grid-column>

      <vaadin-grid-column>
        <template class="header">
          <vaadin-grid-filter aria-label="Last Name" path="lastName" value="[[_filterLastName]]">
            <input placeholder="Last Name" value="{{_filterLastName::input}}" focus-target>
          </vaadin-grid-filter>
        </template>
        <template>[[item.lastName]]</template>
      </vaadin-grid-column>

    </vaadin-grid>
  </template>
  <script>
    addEventListener('WebComponentsReady', function() {
      Polymer({
        is: 'x-remote-filtering-example',

        ready: function() {
          var grid = this.$.grid;

          grid.size = 200;

          grid.dataProvider = function(params, callback) {
            var xhr = new XMLHttpRequest();
            xhr.onload = function() {
              var response = JSON.parse(xhr.responseText);

              // Number of items changes after filtering. We need
              // to update the grid size based on server response.
              grid.size = response.size;

              callback(response.result);
            };

            var index = params.page * params.pageSize;
            var url = 'https://demo.vaadin.com/demo-data/1.0/people?index=' + index + '&count=' + params.pageSize;

            // `params.filters` format: [{path: 'lastName', direction: 'asc'}, ...];
            params.filters.forEach(function(filter) {
              url += '&filters[' + filter.path + ']=' + encodeURIComponent(filter.value);
            });

            xhr.open('GET', url, true);
            xhr.send();
          };
        }
      });
    });
  </script>
</dom-module>
like image 150
Matthew D Avatar answered Oct 21 '22 10:10

Matthew D