I have a form field (a series of checkboxes) that's being created dynamically from a database, so it's possible that the field will not exist on the form (if there are no matching values in the database). I have some code that needs to execute based on whether the field exists, and pull in the values that are selected if it does exist. I can't seem to get javascript to acknowledge that this field exists, though. Here's what I've tried:
function displayAction(){
var f = document.adminForm;
var a = f.action;
if(f.prefix.value!="-") {
a = a + '&task=callExclusionDisplay&prefix=' + f.prefix.value;
}
else {
var exclusions = document.getElementById("exclusions");
if (exclusions != null){
alert("exclusions set");
a = a + '&task=callExclusionCreate&prefix=' + f.prefix.value + '&exclusions=' + exclusions.join();
}
}
alert('after if, action is ' + a);
}
The code never passes the if statement checking to see if exclusions is not null, even though when I look at the page there are a number of checkboxes named exclusions (with the id also set to exclusions). Is the issue with !=null because it's a group of checkboxes, rather than a single form element? How can I get this to work? If I skip the test for null, the code throws errors about exclusions not being defined if the database doesn't return any matching values.
You're using document.getElementById, but form elements have a name.
Try f.elements.namedItem("exclusions") instead of exclusions != null
Multiple elements in the same page cannot share an id attribute (ie. id must be unique or unset). As well, though some (older) browsers erroneously collect elements whose name matches the ID being looked for with getElementById, this is invalid and will not work cross-browser.
If you want to get a group of elements, you can give them all the same name attribute, and use document.getElementsByName to get the group. Note that the result of that will be a NodeList which is kind of like an array in that it can be iterated over.
Do all the checkboxes have the same id == exclusions?
If yes, then you must first correct that.
Before you do so, did you try checking the first checkbox and see if the if condition goes through?
if you have more than one element with the id "exclusions" it will screw up the functionality of getElementById. I would remove the duplicate "exclusions" ids from all of your elements and use getElementByName() instead, and give your group of checkboxes the name="exclusions" instead.
Edit:
But there is a much simpler way using jQuery, and it gives you some cross browser compability guarrantee. To do the same thing with jQuery do this:
var checkBoxesExist = $('[name=exclusions]').count() > 0;
Or if you have given your elements unique ID's then you can do this:
var checkbox1exists = $('#checkBox1').count() > 0;
Each element must have a unique ID.
Then, you can check just like this:
if (document.getElementById('exclusions1')) {
//field exists
}
Or if you need to loop through a bunch of them:
for (x=0; x<10; x++) {
if (document.getElementById('exclusions' + x)) {
//field X exists
}
}
Related
I have a project where a form is required for inputs for a week, so for efficiency elsewhere an array of inputs is used (i.e. start[0] etc) this seems to have exacerbated the issue.
The problem is when validating a form where some inputs are given initial values (its an update) jQuery only returns those initial values instead of changed ones unless use of 'this' is feasible. I found to resolve that I had to use:
$(".weekdays").change(function(){
var newval = $(this).attr('value');
$(this).attr('value', newval);
});
Which seems a crazy thing to have to do! Its here I found using $(this).val(newval); always fails except when setting initial values, though its the common given solution?
In the same vein setting check-boxes seems also problematical, using:
var id = $(this).attr('pid');
$("#choice["+id+"]").prop('checked', false);
$("#choiceLabel["+id+"]").css('background-image','url("images/Open.png")');
Always fails, yet reverting to javascript with:
var id = $(this).attr('pid');
document.getElementById("choice["+id+"]").checked = false;
document.getElementById("choiceLabel["+id+"]").style.backgroundImage = 'url("images/Open.png")';
Works fine!
So does jQuery not like inputs with id's in array form? or am I getting things wrong somewhere?
When attempting to select an element with an id that contains special characters, such as [], you have to remember to escape them for jQuery. For instance..
var id = 12;
console.log(
$('#choice\\['+ id +'\\]').get()
);
console.log(
$('#choice[data-something]').get()
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="choice[12]">weee</div>
<div id="choice" data-something>dang!</div>
Otherwise, jQuery will treat them as special characters, in this case, assuming you are trying to find an element that has an id and has an attribute matching your variable value.
I need to change the href of link in a box. I can only use native javaScript. Somehow I have problems traversing through the elements in order to match the correct <a> tag.
Since all the a tags inside this container are identical except for their href value, I need to use this value to get a match.
So far I have tried with this:
var box = document.getElementsByClassName('ic-Login-confirmation__content');
var terms = box.querySelectorAll('a');
if (typeof(box) != 'undefined' && box != null) {
for (var i = 0; i < terms.length; i++) {
if (terms[i].href.toLowerCase() == 'http://www.myweb.net/2/') {
terms[i].setAttribute('href', 'http://newlink.com');
}
}
}
However, I keep getting "Uncaught TypeError: box.querySelectorAll is not a function". What do I need to do in order to make this work?
Jsfiddle here.
The beauty of querySelectorAll is you dont need to traverse like that - just use
var terms = document.querySelectorAll('.ic-Login-confirmation__content a');
And then iterate those. Updated fiddle: https://jsfiddle.net/4y6k8g4g/2/
In fact, this whole thing can be much simpler
var terms = document.querySelectorAll('.ic-Login-confirmation__content a[href="http://www.myweb.net/2/"]');
if(terms.length){
terms[0].setAttribute('href', 'http://newlink.com');
}
Live example: https://jsfiddle.net/4y6k8g4g/4/
Try This:
var box = document.getElementsByClassName('ic-Login-confirmation__content')[0];
Since you are using getElementsByClassName ,it will return an array of elements.
The getElementsByClassName method returns returns a collection of all elements in the document with the specified class name, as a NodeList object.
You need to specify it as follows for this instance:
document.getElementsByClassName('ic-Login-confirmation__content')[0]
This will ensure that you are accessing the correct node in your HTML. If you console.log the box variable in your example you will see an array returned.
you can select by href attr with querySelector,
try this:
document.querySelector('a[href="http://www.myweb.net/2/"]')
instead of defining the exact href attribute you can simplify it even more :
document.querySelector('a[href?="myweb.net/2/"]'
matches only elments with href attribute that end with "myweb.net/2/"
My problem is, I want to retrieve checkbox id at runtime and use them later for other purpose.
But retrieved id is read as object.
My Code is:
// Following code gives id of checkbox which contains myCheckbox as its id.
var myCheckbox= $('input[id$=myCheckbox]')[0].id;
// and Now I want to check if that checkbox is checked with following code:
if ($(myCheckbox).is(':checked'))
return 1;
else
return 0;
But here myCheckbox id is read as Object instead of id and thus always enter in else condition and returns 0. This code works when I enter id of checkbox directly.
if ($('#ctl001_myCheckbox').is(':checked'))
return 1;
else
return 0;
It shouldnot be so complicated, I have been working with Javascript but new to JQuery.
You are getting the ID correctly, but the jQuery selector requires the # symbol, much in the same way as a CSS selector does. You need to add the # character to your selector:
if ($('#'+myCheckbox).is(':checked'))
return 1;
else
return 0;
BenM is correct, but why are you getting the ID of the element, and then look it up again? You already found the element, there is no need to search for it a second time.
Just keep a reference to the element:
var myCheckbox = $('input[id$=myCheckbox]').first();
// or var myCheckbox = $('input[id$=myCheckbox]')[0];
// and later
if (myCheckbox.is(':checked')) {
// or if (myCheckbox.checked) {
Simply:
return (($('#' + myCheckbox).is(':checked')) ^ false);
Have you tried using:
var myCheckbox= $('input[id$=myCheckbox]').attr('id');
i want to check the first element of multiple radiobutton groups.
I'm using Firebug, which is why i do not want, yes i know there is firequery, but there must be a way like they did it in the old days :)
Any help yould be great, thx in advance.
Loop backwards over document.getElementsByTagName('input') and set checked to true if type is equal to "radio".
If you try to check multiple buttons in the same group, the last one will hold.
Thus, looping backwards will end up checking the first option in each group.
Update
Feeling a bit silly here, you said you were using Firebug, and thus Firefox, and so we have querySelector available. Thus checking the first radio button in any given group is a one-liner:
document.querySelector('input[type="radio"][name="theGroupName"]').checked = true;
Live example
querySelector returns the first matching element, and so the above will return the first input element with type="radio" and name="theGroupName". Then we just set its checked to true.
Granted that doesn't do the first of all groups, but it gives you more control and is (again) a one-liner — handy for Firebug.
Original answer
You can use getElementsByTagName to get all input elements in document order. Then loop through them, only processing the ones with type="radio" and remembering the last name you encoutered; mark checked = true for the first of each name.
E.g.:
var inputs = document.getElementsByTagName('input');
var lastName, index, input;
for (index = 0; index < inputs.length; ++index) {
input = inputs.item(index);
if (input.type.toLowerCase() === "radio") {
if (input.name !== lastName) {
lastName = input.name;
input.checked = true;
}
}
}
Live example
If you want to limit that to some container, you can use the element version of getElementsByTagName.
Other than the fact that my brief research tells me the latter will return a collection rather than a a single element with the ID passed.
Consider the following code:
function validateAllFields()
{
var clientid = document.getElementById("clientid");
var programs = document.getElementById("programs");
var startmonth = document.getElementById("startmonth");
var startday = document.getElementById("startday");
var startyear = document.getElementById("startyear");
var completed = document.getElementsByName("completed");
var goals = document.getElementsByName("goals");
var errors = document.getElementById("errorMsg");
errors.innerHTML = "";
if(isNumeric(clientid, errors, "Please enter a valid client ID")){
if(madeSelection(programs, errors, "Please select a program from the drop-down list")){
if(madeSelection(startmonth, errors, "Please enter a month for the start date")){
if(madeSelection(startday, errors, "Please enter a day for the start date")){
if(madeSelection(startyear, errors, "Please enter a year for the start date")){
if(checked(completed, errors, "Please choose an option that indicate whether the client has completed the program")){
if(checked(goals, errors, "Please choose an option that indicate whether the client has met his/her goals.")){
window.alert("GOT IN TO RETURN TRUE");
return true;
}
}
}
}
}
}
}
return false;
}
</script>
The above code works perfectly after placing it in the onsubmit handler of the form. However, earlier, for the elements (programs, startmonth, startday, startyear) I was using getElementsByName(), the following happened:
The code seems to get to the second line of the if blocks "if(madeSelection(programs...." and it displayed the error msg via innerHTML for a brief second and
Proceeded to submit the form AS IF the JS had indeed returned true. As you can tell, there is a popup alert right before returning true and the popup DID NOT show up at all.
Bad data was submitted to my test database because the form had not been validated. (yet to write server-side validation with this form, but I will).
please assume the elements programs, startmonth, startday, and startyear are drop-down lists with the same id and name attributes.
Also, the madeSelection function is given as:
function madeSelection(element, error, msg) {
if (element[0].value == "none" || element[0].valueOf == "none" || element[0].value == "") {
error.innerHTML = msg;
element.focus();
return false;
} else {
return true;
}
}
My code does work right now after I changed those elements to be using getElementById(), I was just wondering why getElementsByName presented such behavior.
<input type="text" name="foo" id="bar">
^^^^ ^^
getElementsByName gets elements by their name, getElementById gets the element by its id. There may be many elements on a page with the same name (hence getElementsByName always returns a list of elements), but there is (must) only be one element with a given id (therefore getElementById only returns a single element).
The GetElementsByName method returns an array, and when you tried to call element.focus() you got an error because there is no focus method on an array. When you get an error in the event handler it won't prevent the form from posting.
If you use GetElementById you should use element to access the element, and if you use GetElementsByName you should use element[0].
To expand a little on the answers already provided, the name attribute was provided early in the days of the browser DOM, to allow the contents of elements in forms to be submitted with reference to that name attribute, so that parameters could be passed to a CGI script at the server side. This dates from before the more modern ability to reference DOM elements for manipulation of such things as styles by JavaScript.
When the DOM was expanded to allow said modern manipulations, the id attribute was added, so that individual elements could be manipulated at will. When you want to perform DOM manipulations, you select elements to be manipulated either via the id attribute, if you're only interested in manipulating a single DOM element, or via the class attribute (suitably set by yourself), if you want to manipulate several elements together in the same manner. In this latter case, you can set the class attribute to multiple values (name strings separated by spaces), so that you can, for example, designate elements to belong to more than one class, and perform manipulations accordingly. You can mix and match id and class attributes practically at will, provided you exercise some care to avoid name clashes.
So, for example, you could have five buttons on your web page, all set to:
class="Set1"
and change the style of all those buttons, first by using a statement such as:
myButtons = document.getElementsByClassName("Set1");
to obtain an array of Element objects corresponding to your buttons, then running the following loop:
for (i=0; i<myButtons.length; i++)
myButtons[i].style.color="#FF0000";
to change the colour of the text to red. One of those buttons could additionally have an id attribute set to "Special", and you could then do something such as:
ref = document.getElementById("Special");
ref.style.backgroundColor = "#FFFF00";
to set the background colour of that one button in the set to yellow, to signal that it's intended for a special function within the set.
In short, use the name attribute for form submissions, and the id and class attributes for referring to elements you intend to perform DOM manipulations upon, or attach event handlers to, etc.
The name attribute is not designed to be unique, while the id attribute is.
<div name="nonUnique" />
<div id="unique" />
In order for the form to not be submitted, return false needs to be returned (you said you used the onsubmit handler)
in the second line of your code, because a selection is indeed returned by getElementsByName (it would work with .getElementsByName("test")[0] ) a js error is thrown. The rest of the code is not executed, therefore nothing is returned and the form by-passes the rest of the validation completely.
The getElementById method can access only one element at a time, and that is the element with the ID that you specified. The getElementsByName method is different. It collects an array of elements that have the name that you specified. You access the individual elements using an index which starts at 0.
getElementById
It will get only one element for you.
That element bears the ID that you specified inside the parentheses of getElementById().
getElementsByName
It will get a collection of elements whose names are all the same.
Each element is indexed with a number starting from 0 just like an array
You specify which element you wish to access by putting its index number into the square brackets in getElementsByName's syntax below.
function test() {
var str = document.getElementById("a").value;
console.log(str);
var str1 = document.getElementsByName("a")[0].value;
console.log(str1);
var str2 = document.getElementsByName("a")[1].value;
console.log(str2);
}
<input type="text" id="a" value="aValue" />
<br>
<br>
<input type="text" name="a" value="bValue" />
<br>
<br>
<input type="text" name="a" value="cValue" />
<br>
<br>
<button onclick="test()">Click Here</button>