rnicholus / ajax-form Goto Github PK
View Code? Open in Web Editor NEWHTML forms on performance-enhancing drugs
Home Page: https://ajax-form.raynicholus.com
License: MIT License
HTML forms on performance-enhancing drugs
Home Page: https://ajax-form.raynicholus.com
License: MIT License
This was fixed as part of #35.
Why? This does not trigger a submit event. Discussed more in #8, specifically, in one of my comments.
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.
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?
Via a cookies boolean attribute.
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
I'm inspecting your demo here. It looks like that "polymer.html" is imported twice:
Could this be optimized?
Here's the full dependency graph of the demo page:
Demo page (demo.html)
...so the integrator can display a spinner, for example.
For example when you have fields with same name attribute and you can add or delete them.
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.
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?
Currently, all requests are multipart encoded. Support of other encodings will be a bit more work.
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.
Could you improve event submitted for status net::ERR_INTERNET_DISCONNECTED?
This and your <file-input>
are awesome! It would be great to have a demo.html page hosted on gh-pages and a documentation page.
If you follow this pattern, you get both for free: http://www.polymer-project.org/docs/start/reusableelements.html
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.
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?
I'm trying to submit the select value, but It's not working in current version (1.4.0).
<select name="element-name">
<option value="abc">ABC</option>
</select>
For eg:
<paper-button raised>Submit</paper-button>
Be nice if that would just submit like a normal input submit.
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?
The first paragraph on the doc page says this:
Also allows the custom element to be submitted along with other traditional form elements.
It should read:
Also allows the
<file-input>
custom element to be submitted along with other traditional form elements.
Issue caused by improperly escaped HTML on this line: https://github.com/garstasio/ajax-form/blob/1.0.0/ajax-form.html#L9
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.
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.
for example:
like code above in ajax-form . I expect it sends them all ,not just the last one~
thx for your help
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>
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?)
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
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.
...in addition to PUT and POST. Depends on #8.
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:
<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>
<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>
<content>
tag inside my <template>
<polymer-element name="form-bare" noscript>
<template>
<content></content>
</template>
</polymer-element>
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?
Currently, the <file-input>
custom element, as it stands, can't be integrated into a traditional <form>
. This limitation is documented in rnicholus/file-input#8. The ajax-form element should augment a traditional form and allow a <file-input>
to be submitted with the other traditional form fields.
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.
...with code samples & demonstrations of the benefits of ajax-form. If anyone is interested in helping out, please let me know.
Hi,
it would be nice to be able to submit paper-dropdown-menu values too, as it's going to be used to replace html "select".
The event.detail
will probably just include the underlying XMLHttpRequest
instance for now.
In order to use your Polymer component, 8 HTTP requests have to be made:
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.
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 :-)
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.
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
?
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.
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.action
attribute will be required and, as per usual, will specify the endpoint for the request.enctype
attribute will be ignored for now, since all requests will be MPE at this time.target
attribute will be ignored as this is really no longer needed.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 ?
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).
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.
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
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.
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.
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.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.