Reset a form except one field with Javascript - javascript

For some reason, I need to reset a form but I want one field to remain unchanged.
This following code clears all the fields but I would like to keep the first one unchanged.
<form id="myForm">
<input id="01" type="text"/>
<input id="02" type="text"/>
<input id="03" type="text"/>
<input id="04" type="text"/>
</form>
<button onclick="document.getElementById('myForm').reset()">Reset</button>
If possible, I would like to avoid jQuery.

Copy its value to a variable. Reset the form. Reassign the variable back to the value.

I had been working on an answer to this question, which is similar, and has now been marked as a duplicate. That question was using jQuery, so the answer would have been much shorter, leveraging things like event.data, detach(), etc. Below is the general algorithm, and a vanilla version of the approach I would take to handle not just this question's but also more complex scenarios where you want to exclude an entire subsection of a form.
The algorithm
Detach the element from it's parent
Allow the default reset() behavior
Reattach the element in the correct location within the DOM
Here is a very simple translation of that plan in to code. This doesn't actually re-attach the element in the right location within the DOM. Please see the code snippet for a fully functional example.
// within the form's onreset handler, which fires
// before the form's children are actually reset
var form = document.getElementById("myForm"),
exclude = document.getElementById("_01"),
parentNode = exclude.parentNode;
parentNode.removeChild(exclude);
// use a timeout to allow the default reset() behavior
// before re-attaching the element
setTimeout(function() { parentNode.appendChild(exclude); });
NOTE the id change to _01, and refer to the "Side note" at the end of this answer for more info on that.
Important properties and methods
.parentNode
.nextSibling
.removeChild()
.appendChild()
.insertBefore()
var dataKey = 'data-exclude-selector';
function initiateReset(e) {
e = e || window.event;
var button = e.target,
form = button.form,
excludeSelector = button.getAttribute(dataKey);
form.setAttribute(dataKey, excludeSelector);
}
function beforeReset(e) {
e = e || window.event;
var form = e.target,
excludeSelector = form.getAttribute(dataKey),
elements = form.querySelectorAll(excludeSelector),
parents = [],
siblings = [],
len = elements.length,
i, e, p, s;
// When reset #5 is clicked, note the excludeSelector's value is js escaped:
// #\0030\0035 element attribute value becomes #\\0030\\0035 as js var value
for (i = 0; i < len; i++) {
el = elements[i];
parents.push(p = el.parentNode);
siblings.push(s = el.nextSibling);
p.removeChild(el);
}
setTimeout(function() {
for (var j = 0; j < len; j++) {
if (siblings[j]) {
parents[j].insertBefore(elements[j], siblings[j]);
} else {
parents[j].appendChild(elements[j]);
}
}
});
}
<form id="myForm" onreset="beforeReset()" data-exclude-selector="">
<input id="_01" type="text" placeholder="clear" />
<br />
<input id="_02" type="text" placeholder="clear" />
<br />
<input id="_03" type="text" placeholder="clear" />
<br />
<input id="_04" type="text" placeholder="clear" />
<br />
<input id="05" type="text" placeholder="clear" />
</form>
<input value="Reset 1" type="reset" form="myForm" data-exclude-selector="#_01" onclick="initiateReset()" />
<input value="Reset 2" type="reset" form="myForm" data-exclude-selector="#_02" onclick="initiateReset()" />
<input value="Reset 3" type="reset" form="myForm" data-exclude-selector="#_03" onclick="initiateReset()" />
<input value="Reset 4" type="reset" form="myForm" data-exclude-selector="#_04" onclick="initiateReset()" />
<input value="Reset funky ID (05)" type="reset" form="myForm" data-exclude-selector="#\0030\0035" onclick="initiateReset()" />
<br/>
<br />
<hr/>
<br/>
<form id="complexForm" onreset="beforeReset()" data-exclude-selector="">
<input class="exclude" type="text" placeholder="clear" />
<br />
<input class="exclude" type="text" placeholder="clear" />
<br />
<input type="text" placeholder="clear" />
<br />
<input type="text" placeholder="clear" />
<br />
<div class="childTest">
<input type="text" placeholder="clear" />
<br />
<input type="text" placeholder="clear" />
<div class="nestedTest">
<input type="text" placeholder="clear" />
<br />
<input type="text" placeholder="clear" />
</div>
</div>
</form>
<input value="Exclude by class" type="reset" form="complexForm" data-exclude-selector=".exclude" onclick="initiateReset()" />
<input value="Exclude subsection" type="reset" form="complexForm" data-exclude-selector=".childTest" onclick="initiateReset()" />
Additional work
More work will need to be done to handle the case where one would want to allow reset on certain children of excluded nodes, but I imagine this could be handled in multiple different ways with a little thought
a recursive version of this idea
#Quentin's idea could be extended using cloneNode() to make a copy of the entire node, instead of detaching it, allow a full reset, then implement a mechanism to determine which portions of the clone to systematically restore
Side note (...rant?)
Although the HTML5 id attribute allows for 01 as valid, the spec does go on to indicate that it can be used for other purposes.
3.2.5.1 The id attribute
The id attribute specifies its element's unique identifier (ID). [DOM]
The value must be unique amongst all the IDs in the element's home
subtree and must contain at least one character. The value must not
contain any space characters.
Note: There are no other restrictions on what form an ID can take; in
particular, IDs can consist of just digits, start with a digit, start
with an underscore, consist of just punctuation, etc.
Note: An element's unique identifier can be used for a variety of purposes,
most notably as a way to link to specific parts of a document using
fragment identifiers, as a way to target an element when scripting,
and as a way to style a specific element from CSS.
This may not be a problem for you, but it is something to be aware of. For instance, document.querySelector[All]() uses CSS style selectors.
elementList = document.querySelectorAll(selectors);
...
selectors is a string containing one or more CSS selectors separated by commas.
According to the latest draft of the CSS Selectors spec
An ID selector contains a "number sign" (U+0023, #) immediately followed by the ID value, which must be an CSS identifiers.
And at the end of the rabbit hole are the rules for CSS identifiers
In CSS, identifiers (including element names, classes, and IDs in selectors) can contain only the characters [a-zA-Z0-9] and ISO 10646 characters U+00A0 and higher, plus the hyphen (-) and the underscore (_); they cannot start with a digit, two hyphens, or a hyphen followed by a digit. Identifiers can also contain escaped characters and any ISO 10646 character as a numeric code (see next item). For instance, the identifier "B&W?" may be written as "B\&W\?" or "B\26 W\3F".
Note that Unicode is code-by-code equivalent to ISO 10646 (see [UNICODE] and [ISO10646]).
So if you're only using document.getElementById() you might be ok with an element id value like 01, but in general I would avoid it. Yes, with document.querySelector[All](), and any other component that uses CSS style selectors you may be able to get around this limitation by escaping the selector correctly, but this is a pitfall waiting to happen, especially if multiple developers are involved. I've included an example (5th reset button) in the code snippet for completion, if you have to interact with elements that have IDs taking a format like this.
Reference table for hex codes

You could use the following code :
var form = document.getElementById("myForm");
var inputs = form.getElementsByTagName("input")
for (i = 0; i < inputs.length; i++) {
if(i != 0) {
inputs[i].value = "";
}
}

Store the value the one value in variable
Var partNumber=document.getElementById('partNumber').value;
Then reset the form
document.getElementById('form').reset();
Then reasign the value
document.getElementById('partNumber').value=partNumber;

var temp_c = $('#name').val(); //Select input by id
$('#myForm')[0].reset();
$('#name').val(temp_c);

Related

Turn off autocorrect of input using CSS or JavaScript

I need to turn off autocorrect with CSS/JavaScript. I cannot specify it in HTML because I generate multiple inputs over and over and this autocorrect red underline is very disturbing in my case.
I want to apply all these statements with CSS or JavaScript, but it seems that it's not possible.
<input autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" />
Is there a way to generate multiple inputs without autocorrect underlining?
If the inputs already exist and you are unable to set their attributes at the time they are generated, then you could use querySelectorAll and then loop through the resulting nodelist to set their attributes like so:
const inputs = document.querySelectorAll('input');
inputs.forEach(input => {
input.setAttribute('autocomplete', 'off')
input.setAttribute('autocorrect', 'off')
input.setAttribute('autocapitalize', 'off')
input.setAttribute('spellcheck', false)
})
<input />
<input />
<input />
<input />
You can use something like this using JavaScript:
inputs = container.getElementsByTagName('input');
for (i = 0; i < inputs.length; ++i) {
inputs[i].removeAttribute('autocomplete');
}

What is the correct selector string to get the particular elements I want in HTML structured like this?

<body><form>
<fieldset>
<legend>Current Node Information</legend>
<label>Node Name: <input type="text" id="nodeNameField"></label><br>
<label>Node Type: <input type="text" id="nodeTypeField"></label><br>
<label>Node Value: <input type="text" id="nodeValueField"></label><br>
<label>Child Element Count: <input type="text" id="childElementCountField"></label>
</fieldset>
<fieldset id="navFieldset">
<legend>Movement Controls</legend>
<input type="button" value="Parent" data-prop="parentNode" id="parentBtn">
<input type="button" value="First Child" data-prop="firstChild" id="firstChildBtn">
<input type="button" value="Reset to Root" data-prop="root" id="rootBtn">
</fieldset>
</form></body>
It works fine with the selector (String parameter inside querySelectorAll function)
window.onload = function () {
nodeMove.currentElement = document.documentElement;
var elements = document.querySelectorAll("fieldset#navFieldset input");
for (var i = 0, len = elements.length; i < len; i++) {
elements[i].onclick = function () { nodeMove(this) };
}
update(nodeMove.currentElement);
}
Below is the list of the selectors I have tried so far.
#navFieldset input // this works fine
legend > input // ERROR
#navFieldset > input // this works fine
fieldset > input // this works fine
fieldset#navFieldset // ERROR
I need to select all the buttons within the fieldset.
I want to know in the cases which are shown as this woks fine, is there any difference bw those particular selectors. Furthermore, why are the cases shown as ERROR wrong. I wish to know the reasons. I am reading CSS Selectors from this resource.
Working selectors
Yes, those selectors are all different, but select the correct thing. This redundancy/flexibility is needed for CSS selectors for when slightly different markup comes along.
Non-working selectors
legend > input doesn't work, because legend is not a parent of input. Those are siblings. You can use legend ~ input.
fieldset#navFieldset selects the fieldset, but you seem to be interested in the input children. You can use the child selector >: fieldset#navFieldset > input in the same way you use the descendend selector (space): fieldset#navFieldset input.

select particular input field name of particular form

i have some html code like this
<form name="first"><input name="firstText" type="text" value="General" />
<input name="secondText" type="text" value="General" />
<input name="ThirdText" type="text" value="General" />
<input name="FourthText" type="text" value="General" />
<input name="FifthText" type="text" value="General" />
</form>
<form name="second"><input name="firstText" type="text" value="General" />
<input name="secondText" type="text" value="General" />
<input name="ThirdText" type="text" value="General" />
<input name="FourthText" type="text" value="General" />
<input name="FifthText" type="text" value="General" />
</form>
i want to select "secondText" of form "second" using jquery or javascript and i want to change value of it using jquery.
Using jQuery:
var element = $("form[name='second'] input[name='secondText']");
Using vanilla JS:
var element = document.querySelector("form[name='second'] input[name='secondText']");
Changing the value: element.val(value) or element.value = value, depending of what you are using.
To the point with pure JS:
document.querySelector('form[name=particular-form] input[name=particular-input]')
Update:
This selector will return the input named "particular-input" inside form named "particular-form" if exists, otherwise returns null.
The selector filter "form[name=particular-form]" will look for all forms with name equals "particular-form":
<form name="particular-form">
The selector filter "input[name=particular-input]" will look for all input elements with name equals "particular-input":
<input name="particular-input">
Combining both filters with a white space, I mean:
"form[name=particular-name] input[name=particular-input]"
We are asking for querySelector(): Hey, find all inputs with name equals "particular-input" nested in all forms with name equals "particular-form".
Consider:
<form name="particular-form">
<input name="generic-input">
<input name="particular-input">
</form>
<form name="another-form">
<input name="particular-input">
</form>
<script>
document.querySelector('form[name=particular-form] input[name=particular-input]').style.background = "#f00"
</script>
This code will change the background color only of the second input, no matter the third input have same name. It is because we are selecting only inputs named "particular-input" nested in form named "particular form"
I hope it's more clear now.
;)
By the way, unfortunately I didn't found good/simple documentation about querySelector filters, if you know any reference, please post here.
// Define the target element
elem = jQuery( 'form[name="second"] input[name="secondText"]' );
// Set the new value
elem.val( 'test' );
Try
$("form[name='second'] input[name='secondText']").val("ENTER-YOUR-VALUE");
You can do it like this:
jQuery
$("form[name='second'] input[name='secondText']").val("yourNewValue");
Demo: http://jsfiddle.net/YLgcC/
Or:
Native Javascript
Old browsers:
var myInput = [];
myInput = document.getElementsByTagName("input");
for (var i = 0; i < myInput.length; i++) {
if (myInput[i].parentNode.name === "second" &&
myInput[i].name === "secondText") {
myInput[i].value = "yourNewValue";
}
}
Demo: http://jsfiddle.net/YLgcC/1/
New browsers:
document.querySelector("form[name='second'] input[name='secondText']").value = "yourNewValue";
Demo: http://jsfiddle.net/YLgcC/2/
You can try this line too:
$('input[name="elements[174ec04d-a9e1-406a-8b17-36fadf79afdf][0][value]"').mask("999.999.999-99",{placeholder:" "});
Add button in both forms. On Button click find nearest form using closest() function of jquery. then using find()(jquery function) get all input values. closest() goes in upward direction in dom tree for search and find() goes in downward direction in dom tree for search. Read here
Another way is to use sibling() (jquery function). On button click get sibling input field values.

get name of hidden form

What i want to do is get the name of the hidden form which in this case is named:6ca3787zz7n149b2d286qs777dd8357b, the problem is, that form name always changes, the only thing that is the same is its value, which is 1, well 99% of the time, the only thing that is 100% the same that i guess could be somehow used to retrieve the form name is:L2ZvcnVtcy8 which is just above it. I am also attempting to do this via running javascript manually on the browser (chrome), so having that in mind where the javascript code is run through the url bar like this javascript:codegoeshere, how can i get the form name, -->(6ca3787zz7n149b2d286qs777dd8357b)?
<form action="index.php?feature=xxxxxx" method="post" name="login">
<input type="submit" name="submit" class="button" value="Logout" />
<input type="hidden" name="option" value="username" />
<input type="hidden" name="task" value="logout" />
<input type="hidden" name="return" value="L2ZvcnVtcy8=" />
<input type="hidden" name="6ca3787zz7n149b2d286qs777dd8357b" value="1" /> </form>
</li>
Check all the solutions below in this fiddle.
Some possibilities:
Assuming there is only one element with the name login and that element is the <form>, you can use:
document.getElementsByName('login')[0].getElementsByTagName('input')[4].name
If the return <input> has a fixed name attribute, then this should work (the additional .nextSibling is because there is a text node between them):
document.getElementsByName('return')[0].nextSibling.nextSibling.name
If any other of of those <input>s has a fixed name, you can use (in the example I take the <input> with name=task):
document.getElementsByName('task')[0].parentNode.getElementsByTagName('input')[4].name);
If all you really have is that fixed value, you'll have to use a for loop through all the <input>s:
var lastResortName = (function () { for(var i=0, ipts = document.getElementsByTagName('input'), n = ipts.length; i < n; i++) { if (ipts[i].value === "L2ZvcnVtcy8=") return ipts[i+1].name; } })();
Note: If there are duplicated values for the mentioned name attributes, test with the index ([0], [1], [2] and so on) until you find the expected elements.
That's really easy if you use JQuery:
$('input[type="hidden"]:eq(3)').attr('name')
Here your code running:
http://jsfiddle.net/7CHYa/

Get the text within children nodes using jquery

I have the following html page structure:
<div class="result-row clearfix">
<span>Name1</span>
<span>city1</span>
<span>phone1</span>
<span>details1</span>
</div>
<div class="result-row clearfix">
<span>Name2</span>
<span>city2</span>
<span>phone2</span>
<span>details2</span>
</div>
...
... many such similar divs
And I got simple input field from the user
<label for="name">Name</label> <br />
<input type="text" name="name" autocomplete="off" /> <br />
<label for="city">City</label> <br />
<input type="text" name="city" autocomplete="off" /> <br />
On it's blur event, I would like to make invisible all such div's that does not have the text to be searched and just show the div's that has matched (i.e. the div that has the text within the span tag).
I am not able to retrieve and match this using jquery. I have tried the following:
var nodes = $(".result-row");
console.log("Nodes length: "+nodes.length); // Displays the correct number of child nodes
for(var i=0;i < nodes.length; i++) {
var cur = nodes[i];
console.log(cur); // Displays '#text' in browser js console log.
console.log(cur.childNodes[0]); // Gives undefined. Expecting to get the 1st span tag here.
}
EDIT
I need to display the rows that has the span with matching text. Have updated the html little bit, Please refer to the updated question.
I am able to get the complete data as text of all the span's combined. Is there any way to get the array of spans inside the particular div?
You can use :contains selector:
var $row = $('.result-row');
$('input[type=text]').blur(function() {
var val = this.value;
$row.hide();
$row.has('span:contains("'+val+'")').show()
})
http://jsfiddle.net/x3VtX/
nodes[i] is a jquery object, which doesn't have childNodes property i guess.. so you should be using nodes[i].get(0).childNodes instead...

Categories