Conditionally skip form fields from submission, Reduce URL clutter - javascript

I have multiple hidden form fields which store values about the the current view (e.g. if certain, normally hidden div's are visible etc.) to restore the layout when the form posts back.
The problem is that I'm always submitting all these hidden fields, even if they are in default, generating lots of unnecessary URL clutter in the process (e.g. http://www.example.com/view?ab=&ac=&ad= and so on).
I'd rather submit only the fields which are actually influencing the view (meaning, don't have a specified default value) so that the URL clutter is at a minimum.
I tried manually deleting/inserting input's but its a nightmare. Is there a better way to do this?

Using jQuery, you might just remove() those form elements before transmitting. Another way I could think of is to remove the name attribute.
$('form').bind('submit', function(){
$(this).children('input').each(function(){
if(this.value === this.defaultValue)
$(this).remove();
});
});

Try disabling them-
"Controls that are disabled cannot be successful." -- http://www.w3.org/TR/html401/interact/forms.html#h-17.13.2

Unless you have a reason for keeping these options in the URL, why not store those values in a cookie? In fact, this is often done on many sites. If you want to be more careful, the display options can be stored in a database for each user, but that's your choice.

Related

Submit form before redirecting to another page with JavaScript

I have a complex form; within it there's also an 'add more items' link that takes the user to another form-page (independent). What happens at the moment is that when they have edited the main form without saving it and they go to the independent form, when they come back to the main form page they have lost the edits.
<form id="form_1">
[...]
Add something else.
<input type='submit'/>
</form>
add-something-else page:
<form id="form_2">
<input type='submit'/ onsubmit='go_back_to_form_1'>
</form>
Saving everything in sessionStorage would be overkill (I think), and scripts like FormPersistence.js mess about with other functionalities of my form (i.e. Django formset). I have tried to achieve what I want by attaching this function to my 'add something else' button:
$.when(document.forms["form1"].submit()).then(function(){
window.location.pathname = '/add-something-esle/'
})
For some reasons, though, when I go back to form1 I see that the form wasn't saved. How can I achieve what I want?
A <form> is made up of input elements, and you can persist all the <input .../>s to session/local storage and recover them all on page reloads; I remember answering a similar question before; but here is the summary from that answer:
basically you set an event listener on input elements you want (i.e. query selector); make sure they have id (or something similar) unique because we are going to use it as key t store the value;
here is an example:
function persist(event) {
// `id` is used here
sessionStorage.setItem(event.target.id, event.target.value);
}
// you may use a more specific selector;
document.querySelectorAll("form input").forEach((formInput) => {
// `id` also used here for restoring value
formInput.value = localStorage.getItem(formInput.id);
formInput.addEventListener("change", persist);
});
this snippet will persist all <form> tag's inputs values into session storage;
you can also use more specialized selector in .querySelectorAll() to meet your need
Full page reloads clear all form state. You need a way to persist the state between full page reloads. You can use sessionStorage for that.

Clearing fieldGroup's fields when hidden

I need to clear all fields when they are hidden by a hideExpression, right now i have some code that adds a watcher to fields, and clearing them if they are hidden.
Problem is that this doesnt work for hideExpression's used on fields with fieldGroup's, since its apearently not allowed to add watcher to that type.
My example might explaine the issue better:
http://jsbin.com/fodijeziyu/1/edit?js,output
If you fill in the values, and click the hide checkbox, they should clear the model/view on the fields that gets hidden.
Generally on angular I would think different ways of doing things so that I won't be using watchers. It decreases performance a lot (and yes that sometimes might mean to use jQuery for it).
Now for angular-formly a way of doing what you want would be to use a function for hideExpression and achieve what you want.
Here is a working example.
Also read this link on the official angular-formly documentation.
There's an example on the website for this: http://angular-formly.com/#/example/very-advanced/remove-property-on-hide
You could use the watch with the true flag, in conjunction with your hideExpression:
$scope.$watch('someMiscForm', function() {
console.log('The model has changed!');
}, true);
Then alter/reset the fields you are interested in.

Form submission string concat/modify

So not sure if this is possible but I have a pretty complex form. With multiple levels of processing ie: If you click a radio button 'x' amount options so up in a drop down etc etc.
Well the problem I have is all the form fields need a name, and went I submit the form I'm sending alot of junk. IE Url could be '?meat=3434?fruit=34495?salad=034943' you get the idea. But in the end all I'm looking to is pull the 'salad' value into the url without all the other byproducts. IE: '?salad=034943'
I've tried a few things, pulling all the inputs radios etc out of the form and placing them in a div. The making a form with just a hidden value so I can pull through Mootools (But that made conflicts because I'm using Mootools Form.Validator so then that fails) Then I tired to make two forms, One that would just be all show, then I would pull the value I want into the processing form. Which I thought would work but apparently it still will process both forms.
Any ideas/techniques of how to accomplish this would be greatly appreciated! (because I'm losing my mind)
Disable any form field you don't want sent and it won't show up in the URL.
In HTML it's:
<INPUT type="text" name="foo" DISABLED>
In javascript set document.forms[...].elements[....].disabled = true.
If you hide the field with CSS it will still be sent like normal.
the elegant way you do this is mount your GET url to submit by yourself..
this way you can send only what you want..
dont send any junk.. you can have problems in the future with a variable that you didnt know you were sending..
you can use this util function of jQuery
var params = { width:1680, height:1050 };
var str = jQuery.param(params);
// str is "width=1680&height=1050"

How to reset specific form element in a search form?

I have a search form that has different elements in it, checkboxes, selects, text fields etc. Each change is accompanied by an ajax call that gets the number of results as a sort of counter. I would like to reset only the previous element that caused the counter to return a value of 0.
I was thinking about keeping track of each change in a variable, and each time the counter evaluates to 0, I would then reset the element that caused the change. I however fear that this could force me to handle all the different elements differently with a lot of code and jumping around.
Is there a possible more elegant solution to the problem that anybody can think of? I would appreciate the help.
I cannot comment your question, but : if I understand correcty, there is a big form, and each change on any element, triggers an ajax call, that returns a resultset.
If this resultset size is zero, then, you want the form to reset to previous value.
That would mean, that only the last-changed value has to be tracked down, and reset ?
In this case, your onchange event callback should use this value to get current form element value, and ID. Then, as the resultset comes back, set back the stored value to that element if there are no rows.
Otherwise, if the form is managed globally, you could always store it with a .clone() call, then .remove() it and .insert() the clone back if the resultset is empty.
PS : i know this solution not really elegant :)
Your AJAX module could return a JSON-Encoded string with the data causing this event to occur (PHP-Function: JSON_encode) and from there on, you can cycle through the erroneous values resetting them and displaying further informations. i.e. "Your E-Mail seems to be invalid".
PHP: See JSON_encode
JavaScript: See getElementsByTagName('input') (or textarea or select)
Note: In case of a select item, you may rather want to change the Attribute "selectedIndex" than "value".
I solved the problem by recording each change to the form with
$("#form_id").on("change", function(event) {
//Event bubbling
type = $(event.target).get(0).type;
selector = $(event.target);
}
Then using the Strategy design pattern (Javascript Strategy Design Pattern), I reset each possible field type accordingly. Example for text field,
var Fields = {
"text": {
resetAction: function(fieldSelector) {
fieldSelector.val('');
}
}
};
//To call the reset action for the type of field,
Fields[type].resetAction(selector);
I had to trigger a change event for hidden fields to have their changes also bubble.

How can 2 Html forms share 1 hidden field?

I have a page with 2 forms and a hidden field that is outside of both of the forms.
How can the hidden field be submitted with either of the forms?
I thought about doing something like this with jQuery:
<script type="text/javascript">
$(function() {
$('form').submit(function() {
// do something to move or copy the
// hidden field to the submitting form
});
});
</script>
Will this work? Any other ideas?
EDIT
The hidden field stores a serialized object graph that doesn't change. Both server methods require the object. The serialized object string can get pretty hefty, so I don't want this thing sent down from the server 2 times.
You can simply inject a copy of the element into each form right before submission.
This way, you can have the option of having different information for each hidden form field without affecting the other.
Something like this:
<script type="text/javascript">
$(function() {
$('form').submit(function() {
$("#hidden_element").clone().appendTo(this);
});
});
</script>
If you want to use the exact same element for both forms without creating a fresh copy, just don't use clone()
See documentation for clone() and for appendTo()
EDIT:
If you don't want to send the hidden element with every request the form sends. Consider storing it in the database for that user for that time. You can submit its content once, and once only for every page reload, and then just send the database id of the hidden element with each form post.
On page load, something like this:
$.post("page.php", { reallyBigObject : $("#hiddenfield").val() }, function(insertedID){
$("#hiddenfield").val(insertedID);
});
Then, in the server side code:
//insert $_POST["reallyBigObject"] into databse
//get the just inserted id (in php it's done with mysql_insert_id())
//echo, or print the just inserted id, and exit
This way your js gets the callback.
Now, you can submit the form as you would, but this time, you're only sending the id (integer number) to the server.
You can then simply delete the object from your server (run a cron to do it after X amount of time, or send another request to delete it.
Honestly, though, unless you object is HUGE(!!), I think storing it by submitting it only once is a lot more complex to execute than to simply send two requests to the server.
Let me know if you have any other questions...
With HTML5, you can include a "form" attribute with an input element. The value of the form attribute is the id of the form(s) the field belongs to. To include the field in more than one form, include all form ids in a space-delimited list. Unfortunately, the form attribute is not supported in IE at all (as of IE 9). FF and Chrome support start in version 4 and 10 respectively.
Append the field to both forms at page load:
$(function() {
$('#form1, #form2').append($('input[name=fieldName]'));
});
Assuming you are doing a non ajax submit you could just append the field into the form being submitted. However if you need this info in both forms is it not better to store this value server side in a session store. This way any non js clients will also work!
$(function() {
$('form').submit(function() {
$('input.yourhiddenSubmit').appendTo(this);
});
});
The only way to pass the variable to the next form is to have that variable in the data that is passed when the form is submitted (either GET or POST), unless you want to use AJAX. Assuming you want to have the hidden variable outside of the actual form for a "good reason", I would recommend using jQuery to include the hidden input field into the form just before submission, like so:
<script type="text/javascript">
$(function() {
$('form').submit(function() {
$(this).append("<input type='hidden' name='hiddenField' value='"+$("#hiddenField").val()+"' />");
return true;
});
});
</script>
Replace all the instances of "hiddenField" with the ID of your hidden field outside the form. This will create a new input inside of the form just before it is submitted with the value of the hidden field that is elsewhere on the page.
Beyond that, you'd have to be a bit more specific about what your exact problem was (and why the field isn't being included in the form) for me to help.
Note that the above code should work in theory, but I didn't have a chance to actually test it out myself.

Categories