I have a website with a form. The form is filled by user with data for example i show to user:
<input type='text' value="" name="dsa" />
And he fills it with value of "3";
And he clicks button "save". Now i want to have the whole HTML of the website including values of fields. So i use:
document.documentElement.innerHTML
But i get:
<input type='text' value="" name="dsa" />
But i want to get this:
<input type='text' value="3" name="dsa" />
NOTICE I want to take the whole HTML of the website, not only one field. I dont know what fields will be on the website so i need a general solution.
AFAIK you can't get this from the HTML code, as the HTML code does not change when the user inputs something in a Input text field.
What you could do is get all input fields on the page and get their values with something like this:
var inputs, index;
inputs = document.getElementsByTagName('input');
for (index = 0; index < inputs.length; ++index) {
// deal with inputs[index] element.
}
The code is from this post: https://stackoverflow.com/a/2214077/312312
I was too lazy to write it down my self :P
In jQuery I do
$(function() {
$('input').keyup(function() {
$(this).attr('value', $(this).val());
});
});
Because the value attribute isn't set after key up
You could try to set a live event on a whole document that will set attribustes to html with values user set in or set them on your submit.
First way for example
$("body").on("change", "select,input,textarea", function(){
$(this).attr("value", $(this).val());
});
But this should not be done so blindly, and you'll get problems with reset. And you should solve problem with selected radio, checkbox and other attributes, not only values.
Second way is to serialize whole page when it really needed.
var serialize = function(el){
$("select, input, textarea").each(function(){
$(this).attr("value", $(this).val()); //the same way as upper
});
}
$(".serialize").click(function(){
var inner = $("body"),
html;
serialize(inner);
html = inner.html(); //here you will get whole html with setted attributes
});
This way seems to be better because there wont be delegation of unnecessary event.
http://jsfiddle.net/CeAXL/2/ - test example.
But in both ways it's not good idea to set permanent values to DOM itself.
Related
I'm running into an issue where the value grabbed by jQuery, and what's actually in the input text field, are different.
A form with a variety of inputs are populated when the page loads with information from our database. Thus, the input text fields all have a value.
When the form is submitted, I have a function that runs first to check for text inputs. This is a portion of that function:
$("form#accountSettingsForm input").each(function(){
var input = $(this);
var value = input.attr("value");
}
Lets say the input value is 12 when the page had initially loaded. If I delete the 12 in the textbox and leave the field blank, and submit the form, the above code retrieved "value" is still 12, not empty.
How can I detect what's actually the textbox's value? Thanks in advance.
This is a situation where there's a difference between the value attribute and the value property. The attribute comes from the HTML, the property is from the dynamic state of the DOM. To get the current value of an input after the user has modified it, use the jQuery .val() method.
$("#accountSettingsForm").submit(function() {
$(this).find("input").each(function() {
var input = $(this);
var value = input.val();
console.log(this.name + " = " + value);
});
return false;
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form id="accountSettingsForm">
Input 1:
<input name="field1" type="text">
<br>Input 2:
<input name="field2" type="text">
<br>
<input name="submit" type="submit">
</form>
The following appears to work well. If you want to regularly remember/store the value, register for the on('input') event. With this, you get an event every time the user types in the textbox:
$("#accountSettingsForm :input").on('input', function() {
console.log($(this).val());
});
As far as I can tell, the $(this).val() method of access works fine.
Here's a JSFiddle: https://jsfiddle.net/uz8k7rjp/
And the original post where I got this method: JQuery: detect change in input field
I'm trying to write a function to copy some fields (in real time) from a specific form, to another form
I try to be more specific:
I have 2 forms
- The first form is the one the user will fill in.
- The other form is hidden.
When the user will fill the first form, the second form (hidden) will be filled by the same informations.
Some fields are automatically filled by some calculations, so I can't use keyup/keypress or "click" to start the function
I wrote something like this, but it doesn't work
$(function(){
var form1 = $('#form1'),
form2 = $('#form2');
$('#fieldname_form1').change(function(){
$('input[name="inputname2"]', form2).val(function(){
return $('input[name="inputname1"]', form1).val();
});
});
});
You can copy in real time using the keyup function, something like this. Otherwise, when you say
Some fields are automatically filled by some calculations
What do you mean? These calculations are made by you using JS or what? Because, if you are using JS you can fill the two fields at the same time when you make the calculations.
this works for me...
$(function() {
$('#i1').change(function(evt) {
$('#i2').val(evt.target.value);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
<input type="text" name="name1" id="i1" />
</form>
<form>
<input type="text" name="name2" id="i2" />
</form>
The change event is fired after the element has lost the focus. For the "user editable" elements you should use keyup (for the textbox) and change for the drop down elements.
On the other hand, for the fields filled automatically, you don't have any nice and clean solutions. I can think in two options:
If the calculations trigger is always the user changing some value, you could copy every form value after that happens.
(very bad option, but it would still work) You could be constantly checking for changes in every element and copying them using setInterval function.
As a side note
As well as your code should work, there is a simpler way to do it:
$('#fieldname_form1').change(function(){
var value = $('input[name="inputname1"]', form1).val();
$('input[name="inputname2"]', form2).val(value);
});
This should work -
$(function() {
var form1 = $('#form1'),
form2 = $('#form2');
$('#fieldname_form1').change(function() {
$('input[name="inputname2"]', form2).val($(this).val());
});
});
I have a page with multiple text inputs, and I want to determine which of the text inputs that the user is typing into. All of the text inputs are displayed with the same code. One big constraint is that I cannot modify the actual HTML code, so I cannot add IDs or classes to the input.
Here is what the HTML looks like:
<input type="text" />
<input type="text" />
<input type="text" />
<input type="text" />
Here is the code that I am using to detect a keypress:
$(document).keypress(function(e) {
console.log(e.target) // will be the same for each input
});
Is there a way to distinguish between the different inputs. Is there an underlying DOM property that differentiates the text inputs such that I can access the inputs in constant time in the future(ie, does the DOM assign each input a unique id)?
On document load, you can loop through the input elements and make an "index" => "element" map. This can be used for constant time access in the future. The index of the map can act as the unique ID for the element.
I've put together a working fiddle for this. http://jsfiddle.net/fugHv/6/ . Does this solve your problem?
Here's the gist of the approach,
$(document).ready(function(){
var inputMap = {}, inputArray = [];
$.each($('input'), function(i, v){
//Make an array of the inputs to ensure a constant time access
inputArray.push(v);
//Make a map of inputs with index as the key, for future use
inputMap[i] = v;
});
$('input').keypress(function(e){
var pos = inputArray.indexOf(e.target);
//This should provide the reference for the target input
var inputRef = $(inputMap[pos]);
...
});
});
You can uniquely identify inputs using jQuery index method :
$(document).keypress(function(e) {
console.log(e.target) // will be the same for each input
console.log($(e.target).index());
});
I want to have a web button that is generated dynamically depending on which checkboxes a user selects, without needing to reload the page. I guess jQuery is the way to do this but I am a complete noob with jQuery/JavaScript (trying to learn on the fly, which isn't easy).
Ultimately, I think it s/b a 2-step process: (1) as the user checks checkboxes, store them in an array and delimit them, and (2) output html to create a button that dynamically uses the delimited array values.
HTML form:
<input type="checkbox" name="catChoices[]" value="80s" />80s<br />
<input type="checkbox" name="catChoices[]" value="90s" />90s<br />
<input type="checkbox" name="catChoices[]" value="00s" />00s<br />
Being a jQuery/JS novice, I've only come up with this to do step 1 mentioned above. I don't know if this is on the right track or completely off:
jQuery:
$(document).ready(function() {
$("input").click(function() {
var checkValues = $('input[name=catChoices]:checked').map(function() {
return $(this).val();
}).get();
str = checkValues.join(',');
});
});
I also don't know how to incorporate step 2 (get the button to be created dynamically with jQuery). The solutions I've googled show how to pass the values to html/PHP, which requires a page refresh, but I want the button to update on-the-fly as the user checks/unchecks checkboxes.
Thanks for your help!
Are you sure you want to use such a non-standard (for the web) format?
Have you thought about doing this:
var data = $('input[name="catChoices[]"]').serialize();
This is smart enough to only include checked checkboxes.
Granted, you can always convert it to a comma-separated list by doing
data = data.replace(/&/g, ',').replace(/catChoices%5B%5D=/g, '')
Creating a button is as simple as:
$('<button>', { val: data })
or
$('<input>', { type: 'submit', val: data })
a different api is preferred by some:
$('<input type="submit">').val(data)
Try this. Name of the input box is catChoices[] and it should be in quotes.
$("input").click(function() {
var checkValues = $('input[name="catChoices[]"]:checked').map(function() {
return $(this).val();
}).get();
str = checkValues.join(',');
alert(str );
});
Unfortunately form.reset() function doesn't reset hidden inputs of the form.
Checked in FF3 and Chromium.
Does any one have an idea how to do the reset for hidden fields as well?
Seems the easiest way of doing that is having <input style="display: none" type="text"/> field instead of <input type="hidden"/> field.
At this case default reset process regularly.
This is correct as per the standard, unfortunately. A bad spec wart IMO. IE provides hidden fields with a resettable defaultValue nonetheless. See this discussion: it's not (alas) going to change in HTML5.
(Luckily, there is rarely any need to reset a form. As a UI feature it's generally frowned upon.)
Since you can't get the original value of the value attribute at all, you would have to duplicate it in another attribute and fetch that. eg.:
<form id="f">
<input type="hidden" name="foo" value="bar" class="value=bar"/>
function resetForm() {
var f= document.getElementById('f');
f.reset();
f.elements.foo.value= Element_getClassValue(f.elements.foo, 'value');
}
function Element_getClassValue(el, classname) {
var prefix= classname+'=';
var classes= el.className.split(/\s+/);
for (var i= classes.length; i-->0;)
if (classes[i].substring(0, prefix.length)===prefix)
return classes[i].substring(prefix.length);
return '';
}
Alternative ways of smuggling that value in might include HTML5 data, another spare attribute like title, an immediately-following <!-- comment --> to read the value from, explicit additional JS information, or extra hidden fields just to hold the default values.
Whatever approach, it would have to clutter up the HTML; it can't be created by script at document ready time because some browsers will have already overridden the field's value with a remembered value (from a reload or back button press) by that time that code executes.
Another answer, in case anyone comes here looking for one.
Serialize the form after the page loads and use those values to reset the hidden fields later:
var serializedForm = $('#myForm').serialize();
Then, to reset the form:
function fullReset(){
$('#myForm').reset(); // resets everything except hidden fields
var formFields = decodeURIComponent(serializedForm).split('&'); //split up the serialized form into variable pairs
//put it into an associative array
var splitFields = new Array();
for(i in formFields){
vals= formFields[i].split('=');
splitFields[vals[0]] = vals[1];
}
$('#myForm').find('input[type=hidden]').each(function(){
this.value = splitFields[this.name];
});
}
You can use jQuery - this will empty hidden fields:
$('form').on('reset', function() {
$("input[type='hidden']", $(this)).val('');
});
Tip: just make sure you're not resetting csrf token field or anything else that shouldn't be emptied. You can narrow down element's specification if needed.
If you want to reset the field to a default value you can use(not tested):
$('form').on('reset', function() {
$("input[type='hidden']", $(this)).each(function() {
var $t = $(this);
$t.val($t.data('defaultvalue'));
});
});
and save the default value in the data-defaultvalue="Something" property.
I found it easier to just set a default value when the document is loaded then trap the reset and reset the hidden puppies back to their original value. For example,
//fix form reset (hidden fields don't get reset - this will fix that pain in the arse issue)
$( document ).ready(function() {
$("#myForm").find("input:hidden").each(function() {
$(this).data("myDefaultValue", $(this).val());
});
$("#myForm").off("reset.myarse");
$("#myForm").on("reset.myarse", function() {
var myDefaultValue = $(this).data("myDefaultValue");
if (myDefaultValue != null) {
$(this).val(myDefaultValue);
}
});
}
Hope this helps someone out :)
$('#form :reset').on('click',function(e)({
e.preventDefault();
e.stopImmediatePropagation();
$("#form input:hidden,#form :text,#form textarea").val('');
});
For select, checkbox, radio, it's better you know (hold) the default values and in that event handler, you set them to their default values.
Create a button and add JavaScript to the onClick event which clears the fields.
That said, I'm curious why you want to reset these fields. Usually, they contain internal data. If I would clear them in my code, the post of the form would fail (for example after the user has entered the new data and tries to submit the form).
[EDIT] I misunderstood your question. If you're worried that someone might tamper with the values in the hidden fields, then there is no way to reset them. For example, you can call reset() on the form but not on a field in the form.
You could think that you could save the values in a JavaScript file and use that to reset the values but when a user can tamper with the hidden fields, he can tamper with the JavaScript as well.
So from a security point of view, if you need to reset hidden fields, then avoid them in the first place and save the information in the session on the server.
How I would do it is put an event listener on the change event of the hidden field. In that listener function you could save the initial value to the DOM element storage (mootools, jquery) and then listen to the reset event of the form to restore the initial values stored in the hidden form field storage.
This will do:
$("#form input:hidden").val('').trigger('change');
You can reset hidden input field value using below line, you just need to change your form id instead of frmForm.
$("#frmForm input:hidden").val(' ');