How to avoid javascript retrieving values from non-existing elements - javascript

Update: clarified question (I hope)
Hi.
I'm developing a plugin in Wordpress and I'm outputting elements according to user privileges A and B.
In case of A, I ouput element "Foo".
In case of B, I output element "Bar".
Up till now, I haven't checked if an element exists before I try to retrieve the value.
This of course gives me a javascript error in some browsers (like IE7).
I've looked at using the typeof() function:
if(typeof(element) == 'undefined') {
//do something...
}
I'm also using jQuery. So one solution could be using this:
if ($("#mydiv").length > 0){
// do something here
}
Using the above methods, makes me having to check each element before trying to retrieve any values.
The "ideal" solution would be to get values based on user privileges. E.g:
if (userPriv == A) {
//get values from element 'Foo'
}
This way I can check once, and do the data gathering. The only solutions I can think of are setting the value of a hidden input element or use cookies.
<input type="hidden" id="userPriv" value="A" />
The other solution would be adding a value to the cookie.
setcookie("userPriv", "A");
Unfortunately, this last option gives me a warning message saying that cookie must be set in header (before html output). I think it's because I'm doing this in Wordpress.
I'm looking for opinions on which method is "the best way" to accomplis this.

Forgive me if I'm missing something, but checking for a DOM element in javascript is usually pretty easy.
var elementA = document.getElementById('id_of_a');
var elementB = document.getElementById('id_of_b');
if (elementA) {
//...
} else if (elementB) {
//...
}
The key is the if statement. getElementById will return nothing null if the element is not found, which will evaluate to false in the if statement.
Alternatively, if you don't really want to check for existence of individual DOM elements, can you send the users priv in a hidden input and act on that? That's a cookie free way of sending values clientside. Something like (edited to have jQuery code instead)
<input type="hidden" id="userPriv" value="A" />
...
var priv = $('#userPriv').val();
if (priv == 'A') {
//...
}
I'd still recommend checking for individual elements over checking a hidden input. It seems cleaner to me, more along the unobtrusive lines

You can use object as associative array:
var map = new Object();
map[A.toString()] = new Foo();
map[B.toString()] = new Bar();
In that case is much simpler to check and you will avoid "spaghetti code".

Related

adding .value stops flow of javascript

I'm in the middle of creating a program in the browser which compares the selections of the user with a list of pre-defined holidays using Objects. I tried to create an object from the selections of the user to use in comparisons and select the most matching holiday, however when I try to select the value (adding .value) it seems to break the flow of Java, and none of the code read afterwards is read.
var climateVar = document.getElementById('climateselect')/.value\;
var accVar = document.getElementById('accomadationselect')/.value\;
var durationVar = document.getElementById('duration')/.value\;
var userInput = new Input(climateVar/.value\, accVar/.value\, durationVar/.value\);
for (var key in userInput) {
var woo = userInput[key];
document.getElementById('someDiv').innerHTML += woo/.value\;
}
without any .value/s, this prints[object HTMLSelectElement]null[object HTMLSelectElement] - (I changed "getElementById" to "querySelector" which simply made it print "nullnullnull")
, but when I try to add .value anywhere, the entire script stops working, and so everything under this will not run. Why on earth would adding .value stop the script from working? Nothing else changed.
Also, I'm a novice at this, this was meant to be a practice project, but I've been stuck on this for about a day now. any other advice you might feel like giving would also be appreciated
everywhere I typed /.value\ I've tried to add .value, and it has had the effect of stopping the code
Are you sure you are calling value on a valid object? The object has to exist and support .value to get a result - e.g.
http://jsfiddle.net/pherris/t57ktnLk/
HTML
<input type="text" id="textInput" value="123"/>
<div id="divHoldingInfo">123</div>
JavaScript
alert(document.getElementById('textInput').value);
alert(document.getElementById('divHoldingInfo').innerHTML);
alert(document.getElementById('iDontExist').value); //errors out

Javascript get value by radio button name

first of all i am a beginner in javascript, a really big beginer
Can someone give me a hint on this?
I have a form, on the form i have a radio button.
And i would like to that if the radio is set yes , it would show the value of it on another page.
And i would like to get the value by the input name
is it possible?
I'm not asking to write my code, but just an example for a start.
i was tried with this just for a test
<input type="hidden" name="the_name" value="yes">
if(the_name.element == 'yes') {
alert('cool');
}
the_name.value, not the_name.element
You can use getElementsByName() for accessing the elements value via the input name. But as a standard and since it helps load off the DOM we use getElementById() instead of the name. Also you can start from here -> http://eloquentjavascript.net/
You can reference the form using:
document.forms[formName or formId].elements[element-name];
However, name is not necessarily unique in the document. If there is only one element with the name, then only one is returned. If more than one have the same name, then you will get a collection (a bit like an array) and you will have to iterate over them to find the one you want.
You can also use document.getElementsByName, which always returns a collection. So you can do:
var elements = document.getElementsByName('the_name');
// get the one with value 'yes'
for (var i=0, iLen=elements.length; i<iLen; i++) {
if (elements[i].value == 'yes') {
return elements[i];
}
}
You will also need to be careful of case sensitivity, you might want to use toLowerCase() on the value first, or use a case insensitive regular expression:
e.g.
var re = /yes/i;
...
if (re.test(elements[i].value)) {
// value is Yes or YES or yeS or ...
<input type="hidden" name="the_name" id="the_name" value="yes"> <!-- id added -->
if(formName.the_name.value == 'yes')
{
alert('cool');
}
OR better (since you are not accessing the elements by global names)
var element = document.getElementById("the_name");
if(element.value === 'yes')
{
alert("yes, it is");
}

What is the difference between JavaScript's getElementById() and getElementsByName() functions?

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>

JavaScript/JQuery: use $(this) in a variable-name

I'm writing a jquery-plugin, that changes a css-value of certain elements on certain user-actions.
On other actions the css-value should be reseted to their initial value.
As I found no way to get the initial css-values back, I just created an array that stores all initial values in the beginning.
I did this with:
var initialCSSValue = new Array()
quite in the beginning of my plugin and later, in some kind of setup-loop where all my elements get accessed I used
initialCSSValue[$(this)] = parseInt($(this).css('<CSS-attribute>'));
This works very fine in Firefox.
However, I just found out, that IE (even v8) has problems with accessing the certain value again using
initialCSSValue[$(this)]
somewhere else in the code. I think this is due to the fact, that I use an object ($(this)) as a variable-name.
Is there a way arround this problem?
Thank you
Use $(this).data()
At first I was going to suggest using a combination of the ID and the attribute name, but every object might not have an ID. Instead, use the jQuery Data functions to attach the information directly to the element for easy, unique, access.
Do something like this (Where <CSS-attribute> is replaced with the css attribute name):
$(this).data('initial-<CSS-attribute>', parseInt( $(this).css('<CSS-attribute>') ) );
Then you can access it again like this:
$(this).data('initial-<CSS-attribute>');
Alternate way using data:
In your plugin, you could make a little helper function like this, if you wanted to avoid too much data usage:
var saveCSS = function (el, css_attribute ) {
var data = $(el).data('initial-css');
if(!data) data = {};
data[css_attribute] = $(el).css(css_attribute);
$(el).data('initial-css', data);
}
var readCSS = function (el, css_attribute) {
var data = $(el).data('initial-css');
if(data && data[css_attribute])
return data[css_attribute];
else
return "";
}
Indexing an array with a jQuery object seems fishy. I'd use the ID of the object to key the array.
initialCSSValue[$(this).attr("id")] = parseInt...
Oh please, don't do that... :)
Write some CSS and use the addClass and removeClass - it leaves the styles untouched afterwards.
if anybody wants to see the plugin in action, see it here:
http://www.sj-wien.at/leopoldstadt/zeug/marcel/slidlabel/jsproblem.html

Locating text and performing operation based on its existence

I'm trying to learn jQuery, but it's coming slowly as I really don't know any JavaScript.
My site is in VB.NET and I'm putting jQuery code on both my actual .ascx UserControl and in a separate file (something like myscripts.js). This is because I'm using webforms as I still don't know MVC well enough to implement it, so I have to get the clientID's on the page.
What I would like to do is the following:
Grab text from a textbox and make it all lowercase
Get the username from the login info. I've done this like so on my actual page:
var userName = "<%=Split(System.Web.HttpContext.Current.User.Identity.Name.ToLowerInvariant, '|')%>";
Check to see if the username is in the text. If it IS in the text, I want to set a variable to "false", othewise to true.
How do I do this?
I am completely ignorant of the ASP.NET side of it, but as far as jQuery and Javascript....
To get the value of a text field, you use the jQuery function val():
var value = $('#mytextbox').val();
To turn a string to lower case, you use the string method toLowerCase():
var value = $('#mytextbox').val().toLowerCase();
Since val() returns a string we can throw that at the end.
To check if a string is within another string, you use the string method indexOf():
var needle = 'Hello';
var haystack = 'Hello World';
var match = haystack.indexOf(needle); // -1 if no matches, 0 in this case
Another thing to remember is that ASP.NET renames all your control ID's. To access your controls in JavaScript, you should use the following in place of the Control ID <%= txtUserName.ClientID %>.
In jQuery, here is what my selector would look like for a textbox with the ID "txtUserName".
$('#<%= txtUserName.ClientID %>')
Enjoy,
Zach
var userName = "username as it comes out of your web app";
// stuff happens
var $myTextbox = $('#ID_of_textbox');
var userNameIsContained = $myTextbox.val().toLowerCase().indexOf(userName) >= 0;
Short explanation:
$('#ID_of_textbox') // fetches the jQuery object corresponding to your textbox
.val() // the jQuery function that gets the textbox value
.toLowerCase() // self explanatory
.indexOf() // returns the position of a string in a string (or -1)
See the JavaScript String object reference at w3schools.
Alternative (to check if the textbox value equals the username):
var userNameIsEqual = $myTextbox.val().toLowerCase() == userName;
The basics of JQuery are like so: Find a list of dom elements, and perform actions on them.
In your case, you should start off by finding the dom element that is your testbox. For example's sake, we'll choose $('#userName'). The selector # means "id" and together with the name "userName" it finds all elements with the id of "userName". (Ids on a page should be unique if you're following best practices.)
Once you have that list (in this case, a list of one element), you can ask it what the value is.
$('#userName').val()
This gets you the value of the value="" attribute of the input tag.
You can then assign it to a variable and use standard javascript String functions to do the rest!
function checkLogin(userName){
return $('#mytextbox').val().toLowerCase() == userName
}
if ($("#textBoxID").val()) != "") { /*Do stuff*/ }

Categories