get name of hidden form - javascript

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/

Related

JavaScript only changes text of first iteration with thymeleaf

I hope you are all well.
I have a school assignment, and I want to dynamically be able to change the name of a 'project'. This assignment is about projects. The way I've done it right now works with the first 'project' from a list of 'projects' iterated through with thymeleaf. I'm aware that what I've done right now is absolutely bad code behavior, but we have had no teaching in JS yet. But I really wanted this feature.
I don't know how to make this work for each project preview, right now it works for the first preview, but for the rest it just erases the project name from database. (see picture)
<div class="projects" th:each="projectNames : ${listOfProjects}">
<form action="deleteProjectPost" method="post">
<input type="hidden" th:value="${projectNames.projectID}" name="deleteID">
<input type="image" src="delete.png" alt="Submit" align="right" class="deleteProject" onclick="return confirm('Are you sure that you want to delete this project?')">
</form>
<form action="/editProjName" method="post">
<input type="hidden" name="projectID" th:value="${projectNames.projectID}">
<input type="hidden" id="oldName" th:value="${projectNames.projectName}">
<input type="hidden" id="newName" name="projectName">
<input type="image" src="edit.png" alt="Submit" onclick="change_text()" align="right" class="editProject">
</form>
<form action="/projectPost" method="post">
<input class="projectInfo" name="projectID" type="text" th:value="'Project No.: ' + ${projectNames.projectID}" readonly="readonly">
<input class="projectInfo" type="text" th:value="'Project name: ' + ${projectNames.projectName}" readonly="readonly">
<input class="projectInfo" type="text" th:value="${projectNames.projectStartDate} + ' - ' + ${projectNames.projectEndDate}" readonly="readonly">
<input type="submit" value="OPEN" class="openProject">
</form>
</div>
<script>
function change_text() {
var changedText;
var projectName = prompt("Please enter name of project:");
var oldName = document.getElementById("oldName").value;
if (projectName === null || projectName === "") {
changedText = oldName;
} else {
changedText = projectName;
}
document.getElementById("newName").value = changedText;
}
</script>
First form in HTML is the red cross to delete an entire 'project'. Second form is what is intended to change the name displayed on the 'project preview', but only works on first preview and deletes project name from the rest. Last form is the actual preview. I couldn't find another way to have multiple forms and do different POSTS while working with Java Spring and Thymeleaf.
My wish is to make the change_text() function work for each 'project preview'
Best regards!
function change_text(imageInput) {
var changedText;
var projectName = prompt("Please enter name of project:");
var oldName = imageInput.parentNode.querySelector('.old-name').value;
if (projectName === null || projectName === "") {
changedText = oldName;
} else {
changedText = projectName;
}
imageInput.parentNode.querySelector('.new-name').value = changedText;
}
<form action="/editProjName" method="post">
<input type="hidden" name="projectID" th:value="${projectNames.projectID}">
<input type="hidden" class="old-name" id="oldName" th:value="${projectNames.projectName}">
<input type="hidden" class="new-name" id="newName" name="projectName">
<input type="image" src="edit.png" alt="Submit" onclick="change_text(this)" align="right" class="editProject">
</form>
Ok so I made a few changes. First, notice the inputs with oldName and newName now have classes on them. These can be repeated. If you are not using the ids for anything other than the script, you should remove them. Otherwise if you have styling rules for them you should consider changing those CSS rules to use the class instead so you can remove the invalid repeating ids.
Secondly, the onlick of the image now passes in this. What that does is it passes in the actual input that the user clicked, so you have some context into which form element the user is interacting with.
Then looking at the logic, the method now accepts in imageInput which is the this from the onclick.
Using imageInput.parentNode we go up the DOM Tree to the parent element of the input, which is the form in this case. We can then turn around and use querySelector to find the other element in the form we want to manipulate. And it will only find the element in our particular form because that is what we are selecting off of.

Reset a form except one field with 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);

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.

Enable checkbox if text field is not empty with inconsistent id

Purpose is to have checkboxes disabled when the page loads, and remain greyed out until textbox is filled.
<input type="text" name="<%=commentID%>" />
<input type="checkbox" name="<%=SkipID%>" value="N" disabled/>
I tried to do something like
<input type="text" name="<%=commentID%>" onkeyup="userTyped('<%=SkipID%>') />
function userTyped(commen){
if(this.value.length > 0){
document.getElementById(commen).disabled=false;
}else{
document.getElementById(commen).disabled=true;
}
}
But it did not work. I am assuming because of the inconsistency of the name, but I have to have that.
You haven't given id to your html elements and is trying to use getElementById, which will return null. Javascript engine will not be able to set disabled attribute of null. Try setting id attribute, for elements as given below.
Also in your userTyped function you are referencing this. this here is the window object and not the input element. You need to pass the reference to input element to make this work, like this onkeyup="userTyped('<%=SkipID%>', this)"
Please find a possible correction below:
<input type="text" name="<%=commentID%>" id="<%=commentID%>" onkeyup="userTyped('<%=SkipID%>', this)" />
<input type="checkbox" name="<%=SkipID%>" id="<%=SkipID%>" value="N" disabled/>
/** commen is the id
* e is the input element
**/
function userTyped(commen, e){
if(e.value.length > 0){
document.getElementById(commen).disabled=false;
}else{
document.getElementById(commen).disabled=true;
}
}
jsFiddle here: http://jsfiddle.net/deepumohanp/dGS9H/

How do I replace part of the value of attributes for a set of elements in jQuery?

I am trying to replace a series of 'for' attributes of labels based on their current contents.
The application is using AJAX to add an item to an invoice without refreshing the page. Upon receiving notification of a successful item add, my script should replace all the labels in the form whose 'for' attribute ends with '-new' with the same attribute minus the '-new' and adding ('-' + itemValue), where itemValue is the item Id of the invoice item that was added.
I know how to select all the labels I want to change at once:
jQuery('label[for$=new]')
I know how to get their 'for' attribute:
jQuery('label[for$=new]').attr('for')
I tried the JavaScript replace method:
jQuery('label[for$=new]').attr('for').replace(/-new/,itemValue)
But that appears to select each label's 'for' attribute, replace the text, and pass the replaced text back (to nothing), since I don't know how to identify the labels that have the 'for' attribute I want to replace.
Here's some sample HTML:
<form id="InvoiceItemsForm-1" action="<?=$_SERVER['PHP_SELF'];?>" method="post" name="InvoiceItemsForm-1" onsubmit="return false">
<div id="InvoiceItem-new-1" class="InvoiceItem">
<label for="InvoiceItemNumber-new">New Invoice Item Number: </label>
<input id="InvoiceItemNumber-new" class="InvoiceItemNumber" type="text" value="" name="InvoiceItemNumber-new">
<label for="InvoiceItemDescription-new">Item Description: </label>
<input id="InvoiceItemDescription-new" class="InvoiceItemDescription" type="text" value="" name="InvoiceItemDescription-new">
<label for="InvoiceItemAmount-new">Item Amount: </label>
<input id="InvoiceItemAmount-new" class="InvoiceItemAmount" type="text" value="" name="InvoiceItemAmount-new">
<input id="addInvoiceItem-1" width="25" type="image" height="25" src="/payapp/images/greenplus.th.png" alt="Add New Invoice Item" onclick="addInvoiceItemButtonPushed(this)" value="invoiceItem">
</div>
<button id="CloseInvoice-1" onclick="closeInvoice(this)" type="button">Close Invoice</button>
</form>
Once I get this to work, I'm going to replace all the ids for all the inputs. Same problem. I imagine the solution looks something like this:
jQuery('input[id$=new]').attr('id').replace(/-new/,itemValue)
I just cannot figure out the syntax for this at all.
No need to use .each() ... the .attr() method accepts a function as the second parameter that returns the new value to be used as replacement
jQuery('label[for$=new]').attr('for', function(index, currentValue){
return currentValue.replace(/-new/,'-' + itemValue);
});
If I may, why not just put the input tag inside the label tag? That way, you won't need a for attribute inside the label tag.
Next, a better way to accomplish what you're trying to do would be to use the invoice ID number as the ID for the surrounding div, and add a 'new` class for "new" invoice entries.
So your form would look something like this:
<form id="InvoiceItemsForm-1" action="<?=$_SERVER['PHP_SELF']" method="post" name="InvoiceItemsForm-1" onsubmit="return false">
<div class="InvoiceItem new">
<label>New Invoice Item Number: <input class="InvoiceItemNumber" type="text" value="" name="InvoiceItemNumber"></label>
<label>Item Description: <input class="InvoiceItemDescription" type="text" value="" name="InvoiceItemDescription-new"></label>
<label for="InvoiceItemAmount-new">Item Amount: <input class="InvoiceItemAmount" type="text" value="" name="InvoiceItemAmount-new"></label>
<input id="addInvoiceItem-1" width="25" type="image" height="25" src="/payapp/images/greenplus.th.png" alt="Add New Invoice Item" onclick="addInvoiceItemButtonPushed(this)" value="invoiceItem">
</div>
<button id="CloseInvoice-1" onclick="closeInvoice(this)" type="button">Close Invoice</button>
</form>
You'll still have all the targetability you need to get the new invoice item field data, but now, you only have two things to do to convert from a "new" invoice row to an "existing" invoice item row: add an id attribute to the div and remove the new class, both of which jQuery will let you do quite easily.
Not sure I get the question, but something like:
var oldFor = $('label[for$=new]').attr('for');
var newFor = oldfor.replace(/-new/,itemValue);
$('label[for$=new]').attr('for', newFor);
.attr( attributeName, value )
attributeName = The name of the attribute to set.
value = A value to set for the attribute.
When selecting multiple elements, you will need to iterate:
$('label[for$=new]').each(function(index) {
$(this).attr('for', $(this).attr('for').replace(/-new/, '-' + itemValue));
});

Categories