pass only changed fields serialize() jquery - javascript

I have multiple forms on a page. Each of these forms has its own save button. I need to make it so that when you click on the save of any of the forms, all forms are saved. That's all I did, everything works for me and is saved.
In the save function, I am looking for all the forms that are in the block:
let $allForms = $('#post .details').find('form');
Then in the request I collect all the data using serialize() and save:
$.ajax({
url: action,
data: $allForms.serialize(),
type: "POST"
There are no problems with this, everything works.
The problem is this. In serialize(), all fields from all forms are collected and then transferred. But conditionally, in each of the forms, I can change only one field, and in the request I would like to see only the changed fields of all forms.
How can I do that? Now I have all fields transferred, but it is necessary that only changed ones are transferred.
I'm trying to add a new class to all my changed fields, and then in saving, already proceed from this:
functions: {
changeField: function (e) {
$(e.currentTarget).addClass('changed');
}
}
events: function() {
this.$body.on('change', '#post .details form .field', this.functions.changeField.bind(this));
}
But this class is added only for fields with type input and textarea, why doesn't change work for fields with type select?

Related

Sending a html form with hidden elements

Today I came across a weird behaviour. I have made an html form using Bootstrap for users to subscribe. You can subscribe multiple users at once, but to see the second and the third user's input fields, you have to toggle a select button first (https://prnt.sc/t96lxt). The issue is that I can not send the form for only 1 or 2 users, because some fields of the hidden parts are set to be required.
So, my question is, how can a send a form with hidden parts that contain required fields?
My form is to be found at http://debosvrienden.alfapre.be/nl/inschrijving
Maybe you can try something like this using javascript
const checkBox = document.querySelector("YOUR_CHECKBOX");
checkBox.addEventListener("change", (e) => {
if (e.target.checked) {
document.querySelector(".hidden-input-field-1").setAttribute("required", true);
document.querySelector(".hidden-input-field-2").setAttribute("required", true);
} else {
document.querySelector(".hidden-input-field-1").setAttribute("required", false);
document.querySelector(".hidden-input-field-2").setAttribute("required", false);
}
});
Obviously, you would have to use your own selectors.
Here, you are just getting a reference to your checkbox, and once it changes, you are changing the required attribute of the inputs.

EXT JS How to check field on form opening?

I have order form which contains combobox field. When user select specific value, system enables new set of fields in form.
This part of code looks like:
if (action.result.data.field == "1") {
Order.query('fieldset[itemId="set1"]')[0].enable();
Order.query('fieldset[itemId="set2"]')[0].show();
}
But if user open editing form with already selected specific value, system doesn't show this set of fields. I need system to check specific value on opening the edit form. What class I should use?
Have a look at this ExtJS example. May be this can guide you. In your case, may be you have to listen to form.Panel render event and set the form fields based on the values in the record you got from server/present locally. Something like below.
onSelectionChange: function(model, records) {
var rec = records[0];
if (rec) {
this.getForm().loadRecord(rec);
}
}
load form based on record click

Getting JS to set post data

I'm currently working a page that lists a lot of users inside a table using a role id.
The role id value is gathered using the select dropdown and then pressing submit. This shows the table below with all the users with that specific role. The way this is done is that when the form is submitted, the id is returned inside the $_POST of my select box. What i want to do is not use a submit button at all, I want to be able to scroll through the different roles, and when I click on a different role within the select, it update the table below automatically without needing to post.
Let's say my select box is called role:
<select id="role">
And the options are:
id: 1, name: blah1
id: 2, name: blah2
I have been working on trying to get this work using ajax and posting the data back to PHP using the change function. Here is my code:
$(document).ready(function() {
$('#role').change(function(){
var role_id = $('#role').val();
$.ajax({
url: 'assign-roles-2.php',
data: {"roleID":role_id},
type: 'post',
success:function(data){
$('#section').slideDown();
}
});
});
$('#role').trigger("change");
});
I have this in PHP also:
$role_id = trim($_POST["roleID"]);
But this returns as null. How would I go about getting the value I get from the select input and use it to set this role_id variable in PHP without submitting a form?
I am assuming that your description of your option elements: id: 1, name: blah1 does not reflect their markup and that they are defined like so...
<option value="1">blah1</option>
If so, then the following should work fine.
var role_id = $('#role').find('option:selected').val();

Is it possible to change form data before sending it?

I'd like to find any generic method to change data before sending forms. It is, if I have a <form> that contains a <input> of certain type (class) and user press send button, I'd like to transform this input value to another format so it arrive to server in a corrected format.
I know I can set a submit() handler to process data, but I need a generic solution that setup this mechanism on load on all page forms and forgets about it (perhaps some forms are sent by AJAX, other use Jquery.validate to send, etc)
Use jQuery's to select all form elements: $('form') and register a handler for the form submit event. Something like this:
$('form').submit(function(e){
e.preventDefault()
var $this = $(this)
var formData = $this.serialize()
// do some thing to it
var yourData = transform(formData)
$.ajax({
post: $this.attr('action'),
data: yourData,
...
})
})
References
submit()
jQuery CSS Selector
Form serialize()
Perhaps this
$(document).ready(function() {
$("form").on("submit",function() {
var form = $(this);
var field = form.find("input[name=first_name]");
if (field.length()>0) field.val(field.val().replace("a","b"));
});
});
Yes, why not?
Have an onclick on the form submit button and there you can do whatever you like before you invoke submit(). To add a same function to all input type submit, then iterate over all input elements with the type=buttons and add your onclick handler function to it.
All your forms need to be of the same kind, or if some use input type=submit while others use a button element with your own javascript then you will have to adjust for that.

Delete empty values from form's params before submitting it

I have some javascript which catches changes to a form then calls the form's regular submit function. The form is a GET form (for a search) and i have lots of empty attributes come through in the params. What i'd like to do is to delete any empty attributes before submitting, to get a cleaner url: for example, if someone changes the 'subject' select to 'english' i want their search url to be
http://localhost:3000/quizzes?subject=English
rather than
http://localhost:3000/quizzes?term=&subject=English&topic=&age_group_id=&difficulty_id=&made_by=&order=&style=
as it is at the moment. This is just purely for the purpose of having a cleaner and more meaningful url to link to and for people's bookmarks etc. So, what i need is something along these lines, but this isn't right as i'm not editing the actual form but a js object made from the form's params:
quizSearchForm = jQuery("#searchForm");
formParams = quizSearchForm.serializeArray();
//remove any empty fields from the form params before submitting, for a cleaner url
//this won't work as we're not changing the form, just an object made from it.
for (i in formParams) {
if (formParams[i] === null || formParams[i] === "") {
delete formParams[i];
}
}
//submit the form
I think i'm close with this, but i'm missing the step of how to edit the actual form's attributes rather than make another object and edit that.
grateful for any advice - max
EDIT - SOLVED - thanks to the many people who posted about this. Here's what i have, which seems to work perfectly.
function submitSearchForm(){
quizSearchForm = jQuery("#searchForm");
//disable empty fields so they don't clutter up the url
quizSearchForm.find(':input[value=""]').attr('disabled', true);
quizSearchForm.submit();
}
The inputs with attribute disabled set to true won't be submitted with the form. So in one jQuery line:
$(':input[value=""]').attr('disabled', true);
$('form#searchForm').submit(function() {
$(':input', this).each(function() {
this.disabled = !($(this).val());
});
});
You can't do it that way if you call the form's submit method; that will submit the entire form, not the array you've had jQuery create for you.
What you can do is disable the form fields that are empty prior to submitting the form; disabled fields are omitted from form submission. So walk through the form's elements and for each one that's empty, disable it, and then call the submit method on the form. (If its target is another window, you'll then want to go back and re-enable the fields. If its target is the current window, it doesn't matter, the page will be replaced anyway.)
Well one thing you could do would be to disable the empty inputs before calling "serializeArray"
$('#searchForm').find('input, textarea, select').each(function(_, inp) {
if ($(inp).val() === '' || $(inp).val() === null)
inp.disabled = true;
}
});
The "serializeArray()" routine will not include those in its results. Now, you may need to go back and re-enable those if the form post is not going to result in a completely refreshed page.
Maybe some of the proposed solutions worked at the moment the question was made (March 2010) but today, August 2014, the solution of disabling empty inputs is just not working. The disabled fields are sended too in my Google Chrome. However, I tried removing the "name" attribute and it worked fine!
$('form').submit(function(){
$(this).find('input[name], select[name]').each(function(){
if (!$(this).val()){
$(this).removeAttr('name');
}
});
});
Update:
Ok, probably the reason because disabling fields doesn't worked to me is not that something changed since 2010. But still not working in my Google Chrome. I don't know, maybe is just in the linux version. Anyway, I think that removing the name attr is better since, despite what policy takes the browser about disabled fields, there is no way to send the parameters if the name attr is missing. Another advantage is that usually disabling fields implies some style changes, and is not nice to see a style change in the form a second before the form is finally submited.
There is also a drawback, as Max Williams mentioned in the comments, since the remove name attr solution is not toggleable. Here is a way to avoid this problem:
$('form').submit(function(){
$(this).find('input[name], select[name]').each(function(){
if (!$(this).val()){
$(this).data('name', $(this).attr('name'));
$(this).removeAttr('name');
}
});
});
function recoverNames(){
$(this).find('input[name], select[name]').each(function(){
if ($(this).data('name')){
$(this).attr('name', $(this).data('name'));
}
});
}
However, I think this is not a very common case since we are submitting the form so it is assumed that there is no need to recover the missing name attrs.
Your problem helped me figure out my situation, which is a bit different - so maybe someone else can benefit from it. Instead of directly submitting a form, I needed to prevent empty form elements from being collected into a serialized array which is then posted via AJAX.
In my case, I simply needed to loop through the form elements and disable all that were empty, and then collect the leftovers into an array like so:
// Loop through empty fields and disable them to prevent inclusion in array
$('#OptionB input, select').each(function(){
if($(this).val()==''){
$(this).attr('disabled', true);
}
});
// Collect active fields into array to submit
var updateData = $('#OptionB input, select').serializeArray();
Or serialize, clear empty key=value pairs with regex and call window.location:
$("#form").submit( function(e){
e.preventDefault();
//convert form to query string, i.e. a=1&b=&c=, then cleanup with regex
var q = $(this).serialize().replace(/&?[\w\-\d_]+=&|&?[\w\-\d_]+=$/gi,""),
url = this.getAttribute('action')+ (q.length > 0 ? "?"+q : "");
window.location.href = url;
});
Another approach I always recommend is to do that on server side, so you are able to:
Validate the input data correctly
Set default values
Change input values if needed
Have a clean URL or a friendly URL such as "/quizzes/english/level-1/"
Otherwise you will have to deal with text input, select, radio etc...

Categories

Resources