2

How do you make a paper-menu element required for form submission? I have a custom element with several polymer elements contained within it. The regular paper-inputs prevent form submission when they are empty, but the paper-menu does not.

Edit:

I suppose it is the paper-dropdown-menu that needs to have the required attribute rather than the paper-menu. The desired behaviour would be something like how a required Select tag inside an html form normally behaves.

<link rel="import" href="../../bower_components/polymer/polymer.html">

<dom-module id="rsvp-form">
  <template>
    <style include="shared-styles"></style>
    <style>
      :host {
        display: block;
      }
    </style>
    <form is="ajax-form" id="rsvp" method='post' action='/api/rsvps'>
      <h2 class="page-title">RSVP</h2>
      <div class='layout horizontal wrap'>
        <paper-input label='First Name' class='flex' value='{{firstName}}' name="firstName" required></paper-input>
        <paper-input label='Last Name' class='flex' value='{{lastName}}' name="lastName" required></paper-input>
      </div>
      <div class='layout horizontal flex'>
        <paper-dropdown-menu label="Attendance" class='flex' name="attendance" required>
          <paper-menu class="dropdown-content" selected='{{selectedIndex}}' required>
            <paper-item>I would love to attend!</paper-item>
            <paper-item>I cannot attend.</paper-item>
          </paper-menu>
        </paper-dropdown-menu>
      </div>
      <paper-button id="submitButton" on-tap='submitRsvp' raised>Submit</paper-button>
    </form>
  </template>

  <script>
    (function() {
      'use strict';

      Polymer({
        is: 'rsvp-form',

        properties: {
          selectedIndex: {
            type: Number,
            observer: '_selectedIndexChanged'
          },
          firstName: {
            type: String,
            value: ''
          },
          lastName: {
            type: String,
            value: ''
          },
          attendance: {
            type: String,
            value: ''
          }
        },
        _selectedIndexChanged: function(newIndex) {
          if (newIndex === 0) {
            this.absent = false;
          } else if (newIndex === 1) {
            this.absent = true;
          }
          this.attending = !this.absent;
        },
        submitRsvp: function(e) {
          Polymer.dom(e).localTarget.parentElement.submit();
        }

      });

      document.addEventListener('WebComponentsReady', function() {
        var form = document.getElementById("rsvp");

        //modify existing or add new datapoints to be submitted here
        form.addEventListener('submitting', function(event) {

        });
      });

    })();
  </script>

</dom-module>
dentudave
  • 73
  • 1
  • 5

1 Answers1

1

It looks like you might be using ajax-form, which depends on an obsolete version (pre 1.0) of Polymer that isn't compatible with the newest version (1.5.0). You should actually switch to Polymer's iron-form, which appears to provide the same features as ajax-form.

iron-form should allow your existing code to work as intended (i.e., require paper-dropdown-menu selection). The equivalent to ajax-form's submitting event is iron-form's iron-form-presubmit event.

Here's a demo of the various events you could listen to on iron-form forms:

<head>
  <base href="https://polygit.org/polymer+1.5.0/components/">
  <script src="webcomponentsjs/webcomponents-lite.min.js"></script>
  <link rel="import" href="paper-dropdown-menu/paper-dropdown-menu.html">
  <link rel="import" href="paper-menu/paper-menu.html">
  <link rel="import" href="paper-item/paper-item.html">
  <link rel="import" href="paper-input/paper-input.html">
  <link rel="import" href="paper-button/paper-button.html">
  <link rel="import" href="iron-form/iron-form.html"> 
</head>
<body>
  <rsvp-form></rsvp-form>

  <dom-module id="rsvp-form">
    <template>
      <form is="iron-form" id="rsvp" method="post" action="/api/rsvps">
        <h2 class="page-title">RSVP</h2>
        <div class='layout horizontal wrap'>
          <paper-input label='First Name' class='flex' value='{{firstName}}' name="firstName" required></paper-input>
          <paper-input label='Last Name' class='flex' value='{{lastName}}' name="lastName" required></paper-input>
        </div>
        <div class='layout horizontal flex'>
          <paper-dropdown-menu label="Attendance" class='flex' name="attendance" required>
            <paper-menu class="dropdown-content" selected='{{selectedIndex}}'>
              <paper-item>I would love to attend!</paper-item>
              <paper-item>I cannot attend.</paper-item>
            </paper-menu>
          </paper-dropdown-menu>
        </div>
        <paper-button id="submitButton" on-tap="submitRsvp" raised>Submit</paper-button>
      </form>
    </template>
    <script>
      HTMLImports.whenReady(function() {
        Polymer({
          is: 'rsvp-form',

          properties: {
            selectedIndex: {
              type: Number,
              observer: '_selectedIndexChanged'
            },
            firstName: {
              type: String,
              value: ''
            },
            lastName: {
              type: String,
              value: ''
            },
            attendance: {
              type: String,
              value: ''
            }
          },

          listeners: {
            'rsvp.iron-form-presubmit': '_presubmit',
            'rsvp.iron-form-submit': '_submit',
            'rsvp.iron-form-error': '_error',
            'rsvp.iron-form-invalid': '_invalid',
          },

          _selectedIndexChanged: function(newIndex) {
            if (newIndex === 0) {
              this.absent = false;
            } else if (newIndex === 1) {
              this.absent = true;
            }
            this.attending = !this.absent;
          },

          submitRsvp: function(e) {
            this.$.rsvp.submit();
          },

          _presubmit: function() {
            // you could modify data here before it's sent
            console.log('presubmit request', this.$.rsvp.request);
          },
          _submit: function() {
            // data successfully submitted
            console.log('submitted request', this.$.rsvp.request);
          },
          _error: function(e) {
            // data failed to submit
            console.log('submitted failed', this.$.rsvp.request, e.detail);
          },
          _invalid: function() {
            // form input is invalid
            console.log('input invalid (not submitted)');
          }
          
        });
      });
    </script>
  </dom-module>
</body>

codepen

tony19
  • 125,647
  • 18
  • 229
  • 307
  • Thanks a bunch for mentioning that ajax-form was out of date. Everything I saw when I was trying to get form submission to work said that ajax-form was much better than iron-form, so that is what I went with, but it appears that is no longer true. – dentudave Jun 12 '16 at 22:18
  • No problem. :) Where did you see that `ajax-form` was better than `iron-form`? – tony19 Jun 12 '16 at 22:20
  • "Better" is probably overstating it, but I had issues similar to this [http://stackoverflow.com/questions/24461460/polymer-form-post-data] where data was not getting passed during submission. And it seemed the Polymer blog featured ajax-form at one point as well [http://stackoverflow.com/questions/24952217/how-to-submit-a-form-with-polymer] so I figured it would be okay. – dentudave Jun 12 '16 at 23:46