user3510945
user3510945

Reputation: 113

Polymer 1.0 dynamically add options to menu

Hi I am having some trouble getting a menu to add options dynamically. They idea is the selection of the first menu decides what the second menu contains. I have built this before successfully without polymer. And it semi-works with polymer. dropdown one gets its content from json based on the selection, dropdown two gets its content also from a json. This part works, the issue is when you make a selection from dropdown one and then change it, dropdown two doesn't delete the old selection. I got this working last time with a function that first deletes all dropdown two's children before repopulating the content. Issue with Polymer is once the childNodes are deleted the dropdown breaks and no other children can be added via data binding. tried adding native with plain JS which populates the menu but the children are not selectable(from what I have read this might be a bug). Also I believe data binding on dynamic items also doesnt work anymore. anyway here is what I have:

<link rel="import" href="../../../bower_components/polymer/polymer.html">
<link rel="import" href="../../../bower_components/paper-material/paper-material.html">
<link rel="import" href="../../../bower_components/paper-dropdown-menu/paper-dropdown-menu.html">
<link rel="import" href="../../../bower_components/paper-menu/paper-menu.html">
<link rel="import" href="../../../bower_components/paper-item/paper-item.html">
<link rel="import" href="../../../bower_components/iron-ajax/iron-ajax.html">
<link rel="import" href="../../../bower_components/paper-button/paper-button.html">
<link rel="import" href="../../../bower_components/iron-dropdown/demo/x-select.html">

<dom-module id="add-skill">
  <template>
    <paper-material elevation="1">
      <paper-dropdown-menu id="ddMenu" attr-for-selected="value" >
        <paper-menu class="dropdown-content" id="vendorSelect" on-iron-select="_itemSelected">
          <template is="dom-repeat" items="{{vendorList}}">
            <paper-item id="vendorName" value="item">[[item]]</paper-item>
          </template>
        </paper-menu>
      </paper-dropdown-menu>

      <paper-dropdown-menu>
        <paper-menu class="dropdown-content" id="certificationSelect" on-iron-select="_itemSelected">
        </paper-menu>
      </paper-dropdown-menu>

      <!-- testing ideas -->
      <paper-dropdown-menu>
        <paper-menu class="dropdown-content" id="test" on-iron-select="_itemSelected">
          <option extends="paper-item"> Option </option>
          <option extends="paper-item"> Option1 </option>
          <option extends="paper-item"> Option2 </option>
        </paper-menu>
      </paper-dropdown-menu>

      <paper-button on-click="_deleteElement">
        Delete
      </paper-button>
    </paper-material>
    <iron-ajax
      id="vendorSubmit"
      method="POST"
      url="../../../addskill.php"
      handle-as="json"
      on-response="handleVendorResponse"
      debounce-duration="300">
    </iron-ajax>

    <iron-ajax
      id="certificationSubmit"
      method="POST"
      url="../../../addskill.php"
      handle-as="json"
      on-response="handleCertificationResponse"
      debounce-duration="300">
    </iron-ajax>
  </template>
  <script>
    Polymer({
      is: 'add-skill',
      ready: function() {
        this.sendVendorRequest();
        this.vendorList = [];
        this.certificationList = [];
      },

      sendVendorRequest: function() {
        var datalist = 'vendor=' + encodeURIComponent('1');
        //console.log('datalist: '+datalist);
        this.$.vendorSubmit.body = datalist;
        this.$.vendorSubmit.generateRequest();
      },

      handleVendorResponse: function(request) {
        var response = request.detail.response;

        for (var i = 0; i < response.length; i++) {
          this.push('vendorList', response[i].name);
        }
      },

      vendorClick: function() {
        var item = this.$;
        //var itemx = this.$.vendorSelect.selectedItem.innerHTML;
        //console.log(item);
        //console.log(itemx);
      },

      sendCertificationRequest: function(vendor) {
        var datalist = 'vendorName=' + encodeURIComponent(vendor);
        console.log('datalist: ' + datalist);
        this.$.certificationSubmit.body = datalist;
        this.$.certificationSubmit.generateRequest();
      },

      handleCertificationResponse: function(request) {
        var response = request.detail.response;

        //var vendorSelect = document.getElementById('vendorSelect');
        for (var i = 0; i < response.length; i++) {

          this.push('certificationList', response[i].name);
        }

        console.log(this.certificationList);
      },

      _itemSelected: function(e) {
        var selectedItem = e.target.selectedItem;
        if (selectedItem) {
          this.sendCertificationRequest(selectedItem.innerText);
          console.log("selected: " + selectedItem.innerText);
        }
      },

      _removeArray: function(arr) {
        this.$.certificationList.remove();
        for (var i = 0; i < arr.length; i++) {
          console.log(arr[i]);
          arr.splice(0, i);
          arr.pop();
        }

        console.log(arr.length);
      },

      _deleteElement: function() {
        var element = document.getElementById('certificationSelect');

        while (element.firstChild) {
          element.removeChild(element.firstChild);
        }
      },

      _createElement: function() {
        var doc = document.querySelector('#test');
        var option = document.createElement('option');
        option.extends = "paper-item";
        option.innerHTML = "Option";
        doc.appendChild(option);
      }
    });
  </script>
</dom-module>

Any guidance is always appreciated

Upvotes: 1

Views: 2492

Answers (1)

Jeff Posnick
Jeff Posnick

Reputation: 56144

Here's a working version of your JSBin, which uses data binding and a <template is="dom-repeat"> to create new, selectable <paper-item> elements dynamically.

I'm not sure what specific issues you ran into when using data binding to stamp out the <paper-item> elements, but the important thing to remember in Polymer 1.0 is that when you modify an Array (or an Object) that is bound to a template, you need to use the new helper methods (like this.push('arrayName', newItem)) to ensure the bindings are updated.

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <base href="http://element-party.xyz">
  <script src="bower_components/webcomponentsjs/webcomponents-lite.js"></script>
  <link rel="import" href="all-elements.html">
</head>

<body>
  <dom-module id="x-module">
    <template>
      <paper-material elevation="1">
        <paper-dropdown-menu>
          <paper-menu class="dropdown-content" on-iron-select="_itemSelected">
            <template is="dom-repeat" items="[[_menuItems]]">
              <paper-item>[[item]]</paper-item>
            </template>
          </paper-menu>
        </paper-dropdown-menu>
        <paper-button on-click="_createItem">Add</paper-button>
      </paper-material>
    </template>

    <script>
      Polymer({
        _createItem: function() {
          this.push('_menuItems', 'New Option ' + this._menuItems.length);
        },

        _itemSelected: function() {
          console.log('Selected!');
        },

        ready: function() {
          this._menuItems = ['First Initial Option', 'Second Initial Option'];
        }
      });
    </script>
  </dom-module>

  <x-module></x-module>
</body>

</html>

Upvotes: 2

Related Questions