Giter Site home page Giter Site logo

rnicholus / ajax-form Goto Github PK

View Code? Open in Web Editor NEW
233.0 22.0 44.0 783 KB

HTML forms on performance-enhancing drugs

Home Page: https://ajax-form.raynicholus.com

License: MIT License

JavaScript 64.57% HTML 30.53% CSS 4.90%
ajax-form javascript html-form html web-components ajax custom-elements

ajax-form's People

Contributors

fabianlupa avatar feltnerm avatar jonataa avatar rnicholus avatar trystanj avatar tsnieman avatar zenorocha avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ajax-form's Issues

Documentation updates

Would it be favorable to include documentation updates that detail how to get ajax-forms working with polymer elements that nest html tags inside of the Shadow DOM? For example the paper-button nests the input tag and thus an additional click event handler must be used to submit the form. Also when you describe setting up event listeners in the documentation it doesn't show in code that 'form' is defined.

e.g. var form = document.getElementsByTagName('form')[0];

This is a great project but i just find myself hunting here or across github, stackoverflow and IRC just to make sure I am doing things right.

Prevent submitting ajax-form in "submitting" state.

Hi,

I'm working on form consist of traditional inputs and polymer components and I've found that the easiest way to submit this form is to attach an event handler to ajax-form's submitting event and concatenate the object named criteria bound to the polymer elements on the fly. However I want to implement a basic check and if the criteria object is empty I'd display a notification to the user and prevent the form from submitting.

if (formCriteria.length > 0) {
    event.detail.formData.criteria = formCriteria;
} else {
    displayFlashMessage(errormsgs.criteria, ERROR_MISSING);
    event.preventDefault();
    return false;
}

The code above works like a charm except that the form gets submitted. Any thoughts on how to prevent the form from submitting? Should I do something differently?

ajax-form does not work with vulcanize

Hello,
I this polymer in my application, and as mentioned in the documentation, I put a <form> tag with is="ajax-form" in my page, like this:

<form is="ajax-form" action="my/form/handler" method="post">
    <label>Enter your name: <input type="text" name="full_name"></label>
    ...
</form>

This works well with a non vulcanized code, but when I vulcanize my application it does not work anymore, the <form is="ajax-form"> does not appear in the page.
If I put <ajax-form> instead of <form is="ajax-form"> it works when I vulcanize my application, but it seems that the polymer element "ajax-form" is not fully functional when used in this way, some of my javascript code is broken.
Do you know where is the issue and how I can fix it ?
Thanks.

Regards,
Alexandre

polymer.html imported twice

I'm inspecting your demo here. It looks like that "polymer.html" is imported twice:

  • in /components/ajax-form/ajax-form.html
  • in /components/core-ajax/core-xhr.html

Could this be optimized?


Here's the full dependency graph of the demo page:

Demo page (demo.html)

  • loads "platform.js"
  • imports "ajax-form.html"
    • imports "polymer.html"
      • imports "layout.html"
      • loads "polymer.js"
    • imports "core-ajax.html"
      • imports "core-xhr.html"
        • imports "polymer.html" again
    • loads "ajax-form.js"

Refactor Test Suite

I've been running into problems when trying to test #15 and #9. I believe the problems stem from the fact that platform.js and polymer are not present in the test suites. I did a bit of an attempt with getting them hosted via karma, but to no avail...

Looking at the polymer project, I noticed their test suite is mocha/chai and HTML pages (see: 1 & 2). I think this is a good idea. First, because setting up a Polymer element in HTML is much easier than in JS. Second, the test cases are closer to real use which means higher chance of catching errors and the added bonus of code examples. Last, like I said, I am running into roadblocks with the current suite (I've also run into problems with PhantomJS ... others have too .. which I assume is due to its webkit engine).

The cost of this transition would be speed, as nothing really competes with headless Phantom in that sense. I think for now, at least, the test suites should be HTML pages, with JS assertions thrown in.

Travis could be set up to run Chrome/Firefox in a virtual framebuffer.

If there is any interest in this, I may attempt a short sprint to see what I can accomplish with a new test method.

Can't get it to work with paper-dropdown-menu

I have this form:

<!doctype html>
<html>

<head>

  <title>App</title>

  <meta name="viewport"
        content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">

  <script src="bower_components/platform/platform.js"></script>

  <link rel="import" href=bower_components/core-icons/core-icons.html">

  <link rel="import" href="bower_components/font-roboto/roboto.html">
  <link rel="import"
        href="bower_components/core-header-panel/core-header-panel.html">
  <link rel="import"
        href="bower_components/core-toolbar/core-toolbar.html">
  <link rel="import"
        href="bower_components/ajax-form/ajax-form.html">
  <link rel="import"
        href="bower_components/paper-tabs/paper-tabs.html">
  <link rel="import"
        href="bower_components/paper-input/paper-input.html">
  <link rel="import"
        href="bower_components/paper-dropdown-menu/paper-dropdown-menu.html">
  <link rel="import"
        href="bower_components/paper-dropdown/paper-dropdown.html">
  <link rel="import"
        href="bower_components/paper-item/paper-item.html">
  <link rel="import"
        href="bower_components/paper-button/paper-button.html">
  <link rel="import"
        href="bower_components/core-menu/core-menu.html">
  <link rel="import"
        href="bower_components/google-signin/google-signin.html">
  <link rel="import"
        href="bower_components/paper-toast/paper-toast.html">


  <style>
    html, body {
      height: 100%;
      margin: 0;
      background-color: #E5E5E5;
      font-family: 'RobotoDraft', sans-serif;
    }

    core-header-panel {
      height: 100%;
      overflow: auto;
      -webkit-overflow-scrolling: touch;
    }

    core-toolbar {
      background: #03a9f4;
      color: white;
    }

    #tabs {
      width: 100%;
      margin: 0;
      -webkit-user-select: none;
      -moz-user-select: none;
      -ms-user-select: none;
      user-select: none;
      text-transform: uppercase;
    }

    .container {
      width: 80%;
      margin: 50px auto;
    }

    @media (min-width: 481px) {
      #tabs {
        width: 200px;
      }

      .container {
        width: 400px;
      }
    }

    .hidden {
      display: none;
    }

  </style>

</head>

<body unresolved>
<core-header-panel>

  <div class="container" layout vertical center>

    <h1 id="pleaseWait" class="hidden">Sending your data...</h1>


<form is="ajax-form" action="/api/v1/posts" method="post" id="postform">

      <paper-input label="username" name="username"></paper-input>
      <paper-input label="text" name="text"></paper-input>
      <br/>
      <paper-dropdown-menu label="Your avatar" name="avatar">
        <paper-dropdown class="dropdown">
          <core-menu class="menu">
            <paper-item>avatar-01.svg</paper-item>
            <paper-item>avatar-02.svg</paper-item>
            <paper-item>avatar-03.svg</paper-item>
          </core-menu>
        </paper-dropdown>
      </paper-dropdown-menu>
      <br/>
      <!--<paper-button raised>Submit</paper-button>-->
      <input type="submit"/>

    </form>

  </div>

</core-header-panel>

<paper-toast id="toast2" role="alert" text="Error submitting. SHOW MORE INFO HERE">
  <div style="color: #eeff41;" onclick="console.log('RETRY')">Retry</div>
</paper-toast>

<script>
  (function() {
    var form = document.getElementById('postform')

    form.addEventListener('invalid', function() {
     document.querySelector('#toast2').show()
    });

    form.addEventListener('submitting', function() {
      document.getElementById('pleaseWait').className = '';
    });

    form.addEventListener('submitted', function(event) {
      document.getElementById('pleaseWait').className = 'hidden';

      if (event.detail.status > 299) {
        document.querySelector('#toast2').show()
      }
      else {
        window.location.replace("/");
      }
    });
  }());
</script>

</body>

</html>

The paper-input's get sent, but the paper-dropdown-menu does not. Any ideas?

ajax-form ignores empty fields

I have a simple form containing two input fields.
When one of them is empty, ajax-form doesn't mention it in the request.
I think, that ajax-form should put its name with empty value instead of ignoring it, because this has serious implications with validation.

Travis tests fail on all pull requests

According to the logs, the encrypted sauce user/pass environment variables aren't being added to the machine instance during build setup when the build has been triggered by a pull request.

Missing Sauce credentials. Did you forget to set SAUCE_USERNAME and/or SAUCE_ACCESS_KEY?

I'm not sure why this is yet. Further investigation is needed.

Bind polymer variables in action

I was wanting to do this:

form is="ajax-form" action="api/foo/{{fooId}}/someAction method="post"

And populate fooId from another action, however it never gets replaced - and the form submission fails because of it. Thoughts? Is this a bug?

Ajax-form ignores regular checkbox group

When I have a form with following input group (generated by "@inputCheckboxGroup" in Play Framework"):

<span class="buttonset" id="test2">  
        <input type="checkbox" id="test2_PRESIDENT" name="test2[]" value="PRESIDENT"  />
        <label for="test2_PRESIDENT">President</label>

        <input type="checkbox" id="test2_CEO" name="test2[]" value="CEO" checked="checked" />
        <label for="test2_CEO">Ceo</label>

        <input type="checkbox" id="test2_SPECIALIST" name="test2[]" value="SPECIALIST" checked="checked" />
        <label for="test2_SPECIALIST">Specialist</label>
  </span>

The regular form sends the FormData (in request headers) like this:

test2[]:CEO
test2[]:SPECIALIST

Unfortunately ajax-form sends it like this

test2[]:VALUE_OF_LAST_CHECKBOX_ONLY

Why is that happening?

Remove dependency on core-ajax

While core-ajax does wrap XMLHttpRequest to provide a slightly nicer API, the majority of this component is unused by ajax-form. I don't really think it's necessary to pull this in as a dependency. The task of removing this dependency and replacing it with bare XMLHttpRequest shouldn't be too difficult for me. In the long run, I'd prefer to be "closer to the metal" and not have to deal with an abstraction (and any bugs that may come along with it) when I feel quite comfortable using the native transport directly.

Callback to allow field data to be modified before submission

Split off from #24.

A few users have expressed interest in the opportunity to programmatically gain access to the parsed form field data and possibly modify it just before it is "submitted" to the endpoint. The hook will be exposed via an existing event: submitting. The format of the data passed to this event handler via the event's detail, and the value will be a JavaScript object. Keys will be parsed field names, and values will be the parse field values.

If the integrator wishes to modify the parsed field data in any way, they can do so and attach the full set of data, as a new JavaScript Object, to the associated Event on an ajaxFormData property. ajax-form will then submit this data. If nothing is attached to the ajaxFormData property on the Event, then the originally parsed form data will be submitted.

paper-input-decorator is not read by ajax-form

Hello,

I'm doing some tests and it seems that this type of paper-input (using paper-input-decorator directly) is not read by ajax-form. In addition, I'm using this element with paper-autogrow-textarea included. Can you please check this? A demo example of this element is on https://www.polymer-project.org/components/paper-input/demo.html , labeled as with autogrowing text area + floatingLabel

All other fields are sent ok. Thanks for this awesome component :)

        <paper-input-decorator name="description" label="Description" class="description" floatingLabel>
            <paper-autogrow-textarea>
                <textarea></textarea>
            </paper-autogrow-textarea>
        </paper-input-decorator>

Headers not submitted?

It appears that since the removal of core-ajax, custom headers aren't being submitted any longer. Looking through ajax-form.js, I don't see the headers being handled. (Is it possible I'm just missing something?)

Assume only core-ajax element seems problematic

I have another core ajax element in my component which performs a GET json request.

It seems that this configuration is being used when submitting multipart/form-data requests.

The content-type header of the request is being set to url-encoded rather than multi-part.

When I move my core-ajax from the beginning of my template to the end, the issue seems to be resolved.
https://github.com/sebbean/herd-components/blob/master/herd-uploader.html

I can only imagine it's because there is some collusion between the shadowRoots?
https://github.com/garstasio/ajax-form/blob/master/ajax-form.js#L304

        sendMultipartForm = function(form) {
            var sender = this.shadowRoot.getElementsByTagName('core-ajax')[0],
                data = parseFormData(form);

            // make sure Polymer/core-ajax doesn't touch the Content-Type.
            // The browser must set this with the proper multipart boundary ID.
            sender.contentType = null;

            if (this.cookies) {
                sender.withCredentials = true;
            }

            sender.body = data;
            sender.go();
        }

Your code is assuming 1 core-ajax child element, however that one seems to be my (GET / JSON) element rather than your internal backing core-ajax request.

Caused some pretty crazy issues with my Rails rack server attempting to parse the file binary data as urlencoded form data.

This post is what finally tipped me off to the incorrect headers being sent. http://stackoverflow.com/a/24615414

Respect HTML5 validation/constraints attributes on form fields

To expose the browser's UI that highlights validation errors, we'll need to call checkValidity on the HTMLFormElement prototype (for Safari after intercepting the submit event. If the form fails validation, the submit event will never be triggered by most browsers, except Safari, which will trigger the submit, and we will have to manually verify via checkValidity ourselves. If validation succeeds, the form can be sent off via XHR.

If may also be useful to trigger an "invalid" event on the form itself if any field is invalid. The invalid event will include an array of all invalid fields in event.detail. We'll have to listen for the "invalid" event on each form field to gather this info, keeping in mind that this particular event does not bubble.

Extending or modifying ajax-form (best practices)?

I have a question about, I guess, how to use it, and perhaps it's just a general Polymer question.

Essentially I want to take what you've created, and modify it. That is, I'd like to use it in a sort of dual-purpose form - one view for editing, one view for displaying. Let's say for the sake of simplicity I simply want to trigger all the inputs to readOnly after submitting. This isn't terribly difficult with the help of getDistributedNodes().

So - what's the Polymer way here? Do I:

  1. Extend your element and create my own super element, adding the necessary functions, but still using it on my page (<form is="extended-ajax-form">) and duplicating <content> and <core-ajax>:
<polymer-element name="my-form" extends="ajax-form" noscript>
    <template>
        <shadow></shadow>
        <content id="contentHere"></content>
        <core-ajax url={{action}} headers={{headers}} method={{acceptableMethod}}></core-ajax>
    </template>
</polymer-element>
  1. Wrap your element in my own, which is a bit like number 1 except the <form is="ajax-form"> tag would have to go inside my <template>, with nested <content> tags and I'd use my own custom element on the main page, with contained <input>s. This also requires me to put the submit button inside my element. In other words:
<polymer-element name="form-wrap" noscript>
    <template>
        <form is="ajax-form" method="post" action="test">
            <content id="contentHere"></content>

            <input type="submit"/>
        </form>
    </template>
</polymer-element>
  1. Wrap it, but instead use my element, with a nested ajax-form on the main page, and just a <content> tag inside my <template>
<polymer-element name="form-bare" noscript>
    <template>
        <content></content>
    </template>
</polymer-element>
  1. Branch / modify your code

To me, option 4 sucks and I immediately lose any benefits of bug fixes, upgrades, etc to ajax-form. Option 1 seems to require me to duplicate the <content> and <core-ajax>, instead of just using <shadow>. Option 2 and 3 seem similar, yet different, and I don't know enough about Polymer to know the pros/cons of each yet. 3 feels a bit funny to me, because the user shouldn't have to worry about know we're using ajax-form. 2 looks the best, but that input absolutely has to be part of my element and can't get it passed across the Shadow DOM as content, unless I am doing something wrong.

What is the best approach to this?

paper-dropdown-menu submitted value

I have a Polymer paper-dropdown-menu and it is submitting the selected items text and not the value attribute. I should have a pull request for this issue coming soon.

Create an awesome web page

...with code samples & demonstrations of the benefits of ajax-form. If anyone is interested in helping out, please let me know.

Too many HTTP requests?

In order to use your Polymer component, 8 HTTP requests have to be made:

reqs

I wonder how this can be optimized. Is there a way to bundle all these resources into one HTTP request?

P.S. I know that SPDY mitigates this issue (and also, once ServiceWorker is enabled in Chrome/Firefox, we'll be able to cache the above mentioned resources quite effectively), but for now, I wonder how to deal with this issue in non-SPDY environments.

handleAs core-ajax

Hi,

it would be nice to have the posibility to get a json response object from the server.
The core-ajax element does support handleAs ajax-form does not.

Thx!
Frank :-)

Respect constraints on custom element form fields

We'll need to pay special attention to required attributes on custom elements, such as <file-element>. These are not standard form fields, so this will be a bit more difficult.

The checkValidity method on the HTMLFormElement won't validate custom elements. We'll need to augment this (if possible) or be aware of custom element form fields and implement some convention to determine if any required custom element form fields are invalid. The other tricky part will be dealing with this in the UI. I'm not sure if there is a way to "trick" the browser into displaying a native validation error message for a custom form field. If not, we'll have to have our own UI to handle this.

This is mentioned in rnicholus/file-input#8.

Add support for custom elements with value properties

The Polymer core and paper inputs both have a value property, meaning parseElement could (as a final check) determine if the element at least exposes a value and if so, it could use that value in the form submission. Other custom form elements could implement a similar interface to work with ajax-form.

@morethanreal is it ok to submit value or should we submit inputValue?

Intercept "submit" events on the form & send data via XHR

This can (hopefully) be easily accomplished by passing the <form> into a FormData object. After intercepting and cancelling the "submit" event, construct FormData, and send using XMLHttpRequest. This of course means that the message-body will always be multipart encoded. That's OK for now.

  • The method attribute will be required at this time, and acceptable values will be PUT and POST. Since we are only using FormData at this time, all message-bodies will be MPE. Support for GET and non-MPE requests can be added later as this will be a bit more complex.
  • The action attribute will be required and, as per usual, will specify the endpoint for the request.
  • The enctype attribute will be ignored for now, since all requests will be MPE at this time.
  • The target attribute will be ignored as this is really no longer needed.

How to retrieve response?

I made a ajax-form wiath a Polymer paper input, the request works and i can see that i got the response in my dev-tools, is there any way to retrieve that data and use it ?

Remove dependence on Polymer

Now that the WC polyfill has been split off into webcomponents.js, there is probably little reason to use Polymer anymore. I'd love to strip any Polymer-specific code out of ajax-form for users who do not want to depend on Polymer in their projects (such as myself).

Ajax-form fails to load in all browsers other than Chrome

Just realized that ajax-form suffers from Polymer/platform#88. Chrome is not affected, and sometimes Firefox loads, sometimes it doesn't. Removing the "action", "enctype" and "method" entries from the element's attribute specification fixes the issue. In hindsight, I'm not sure why I included these attributes in the first place, as they apparently are not necessary (ignorance?).

I'm certain this wasn't an issue until recently. Did something internal to Polymer change that would cause [including native properties in a <polymer-element>'s attribute specification to prevent resolution of the <body>? Not sure.

I intend to have this fixed in 1.2.0.

ajax-form ignores paper checkbox

Hi,
I have a very simple form containing one input and one paper-checkbox.
Although paper-checkbox has a name and an id, it is completely ignored by ajax-form.

When i do:

form.addEventListener('submitting',
        function(event) {
            var formData = event.detail.formData;
            if($('#agreement').attr('checked') !== undefined){
                formData.agreement = true;
            }
        }
);

everything works fine.

Could you please fix it?
Thank you in advance

Allow custom headers to be sent

You can't normally do this with HTML forms, but, since we are using XHR under the covers, this is possible. Headers can be specified in as the value to a headers attribute. The value must be a JSON string Object (keys = header names, properties = header values).

I should probably pull in core-ajax for this.

Form data not submitting in Firefox

This is what my form tag looks like:

<form method="POST" action="http://example.com" accept-charset="UTF-8" is="ajax-form" enctype="multipart/form-data">

</form>

Inside of the form tag I have a set of Polymer paper-input elements. After all is said and done this is what the input looks like:

    <input aria-label="Field" placeholder="Field" is="core-input" committedvalue="{{committedValue}}" on-change="{{ changeAction }}">

When I submit the form I am thrown a validation error. When I expose the GET Variables I see that in Firefox that not all form elements values are showing up.

Does not work for Extended <file-input>

I was building an extension of which parses and displays a file preview for each valid file. This does not work in the current implementation of <ajax-form> since the maybeParseFileInput function checks the tag name explicitly. This also means that <ajax-form> does not work with any alternate web component implementations of a file input.

I'm working on a pull request to fix this.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.