【问题标题】:How to implement a paper-styled "<select multiple>" box with Polymer, without "paper-dropdown-menu"?如何使用 Polymer 实现纸张样式的“<select multiple>”框,而不使用“paper-dropdown-menu”?
【发布时间】:2017-05-11 18:13:57
【问题描述】:

我正在开发一个使用 iron-form 将表单提交到后端 Web 服务的 Polymer 应用程序。表单中的元素之一是一个框,用户可以在其中选择多个元素。

使用paper-dropdown-menupaper-listboxmulti 集可以工作,但是用户体验很糟糕,因为用户在不打开下拉列表(并阻止其他元素)的情况下无法看到选择了哪些元素。此外 - 它需要更多的点击操作。

理想情况下,我们只使用 paper-listbox 而不使用 paper-dropdown-menu,因为这正是我们需要的 UI - 类似于 HTML 的经典 &lt;select multiple&gt;,但具有 Material Design 的光泽。但是如果没有 paper-dropdown-menu 包装器,iron-form 不会选择 paper-listbox 选定的值,也不会提交这些值。

我注意到 iron-form 支持经典 HTML &lt;select&gt;(甚至支持 multiple 行为),但与表单的其余部分相比,它的 UI 不和谐。

还有什么我们可以环绕paper-listbox 来让表单在不修改原始paper-listbox UI 的情况下运行,或者让paper-dropdown-menu 具有“始终打开”模式?如果这些都不起作用(顺便说一句,我也无法工作),我们还能做什么?

【问题讨论】:

    标签: javascript html polymer material-design


    【解决方案1】:

    您可以将&lt;paper-listbox&gt; 包装在实现&lt;iron-form-element-behavior&gt; 的自定义元素中。该行为公开了一个value 属性,该属性可以绑定到&lt;paper-listbox&gt;.selectedValues,从而允许&lt;iron-form&gt; 提交多个列表框值:

    <dom-module id="multi-listbox">
      <template>
        <paper-listbox multi selected-values="{{value}}">
          <content></content>
        </paper-listbox>
      </template>
      <script>
        Polymer({
          is: 'multi-listbox',
          behaviors: [Polymer.IronFormElementBehavior]
        });
      </script>
    </dom-module>
    

    HTMLImports.whenReady(() => {
      Polymer({
        is: 'x-foo',
        _onResponse: function(e) {
          this._response = JSON.stringify(e.detail.response, null, 2);
        },
        _submit: function() {
          this._response = null;
          this.$.form.submit();
        }
      });
      
      Polymer({
        is: 'multi-listbox',
    
        behaviors: [
          Polymer.IronFormElementBehavior
        ],
    
        properties: {
          value: {
            type: Array,
            value: () => [],
            notify: true
          },
          invalid: {
            type: Boolean,
            reflectToAttribute: true
          }
        },
    
        validate: function() {
          const isValid = !this.required || !!(this.value && this.value.length > 0);
          this.invalid = !isValid;
          console.log('invalid', this.invalid);
          return isValid;
        },
        
        _clearError: function() {
          this.invalid = false;
        }
      });
    });
    <head>
      <base href="https://polygit.org/polymer+1.7.1/components/">
      <script src="webcomponentsjs/webcomponents-lite.min.js"></script>
      <link rel="import" href="polymer/polymer.html">
      <link rel="import" href="iron-form/iron-form.html">
        <link rel="import" href="paper-button/paper-button.html">
      <link rel="import" href="paper-checkbox/paper-checkbox.html">
      <link rel="import" href="paper-listbox/paper-listbox.html">
      <link rel="import" href="paper-item/paper-item.html">
      <link rel="import" href="iron-form-element-behavior/iron-form-element-behavior.html">
      <link rel="import" href="iron-validatable-behavior/iron-validatable-behavior.html">
    </head>
    <body>
      <x-foo></x-foo>
    
      <dom-module id="x-foo">
        <template>
          <style>
            multi-listbox,
            paper-checkbox,
            paper-button {
              margin: 0.5em;
            }
          </style>
          <paper-checkbox active="{{_required}}">Required</paper-checkbox>
          <form is="iron-form"
                id="form"
                action="//httpbin.org/get"
                on-iron-form-response="_onResponse">
            <multi-listbox name="listbox-values" required="[[_required]]">
              <paper-item>Item 1</paper-item>
              <paper-item>Item 2</paper-item>
              <paper-item>Item 3</paper-item>
              <paper-item>Item 4</paper-item>
            </multi-listbox>
            <paper-button raised
                          on-tap="_submit">Submit</paper-button>
          </form>
    
          <pre>[[_response]]</pre>
        </template>
      </dom-module>
      
      <dom-module id="multi-listbox">
        <template>
          <style>
            :host {
              display: block;
            }
    
            paper-listbox {
              border: solid 2px lightgray;
            }
    
            :host([invalid]) paper-listbox {
              border: solid 2px var(--error-color, red);
            }
          </style>
          <paper-listbox multi
                         selected-values="{{value}}"
                         on-iron-activate="_clearError">
            <content></content>
          </paper-listbox>
        </template>
      </dom-module>
    </body>

    codepen

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多