What is the difference between using document.getElementByID and document.form? - javascript

I am trying to teach myself javascript through simple programming ideas. I tasked myself to make a way to calculate two numbers and provide a total of the results by option of using any of the four available operators. It's sort of a very simple calculator, to get to the point. I don't think I need to copy my html code - so I just posted my javascript.
Since I am new to programming in general and javascript, I looked around the web and found some code pointers.
<script>
function add() {
var entry1 = document.getElementById("entry1").value;
var entry2 = document.getElementById("entry2").value;
var sum = Number(entry1)+Number(entry2);
document.getElementById("results").value=sum
}
function sub() {
var entry1 = document.form.entry1.value;
var entry2 = document.form.entry2.value;
var sum = Number(entry1)-Number(entry2);
document.form.results.value=sum
}
function multi() {
var entry1 = document.form.entry1.value;
var entry2 = document.form.entry2.value;
var sum = Number(entry1)*Number(entry2);
document.getElementById("results").value=sum
}
function div() {
var entry1 = document.form.entry1.value;
var entry2 = document.form.entry2.value;
var sum = Number(entry1)/Number(entry2);
document.getElementById("results").value=sum
}
</script>
I think this gives you insight into what I am playing around with. I thought it was interesting I found a way to get around using document.getElementByID, but I guess what I am trying to understand is how you can using both ways...the document.form... and document.getElementById.
Using "document.getElementById" will search the whole DOM looking for "entry1." "Form" in "document.form" refers to the form that encapsulates the whole contents in the <body> tag. As a theory, I did a <div name="blah"> tag in front of <form name="form"> to see if it would use "blah" if I changed document.form to document.blah...it broke. Same thing happened when I tried document.blah.form.entry1....). I think you can see what I am getting at.
I am just curious as to why document.form.entry1.value; works like document.getElementById("entry1").value;?

As others have mentioned,document.getElementById is to be used to select a specific element regardless of what it is. document.forms is to be used to specifically target forms and their elements.

I think document.form points the specific form named or id'ed as the identifier "form" like <form name="form" id="form">.
Please check the syntax document.forms instead of document.<an_identifier> carefully.
document.<an_identifier> may be a dialect of IE.

it's just a kind of syntactic sugar as for me.
Where have you found that "funny" sample? Let me refactor it a bit. hope it will help you better understand to main idea.
<script>
function add(a,b) {
return Number(a) + Number(b);
}
function sub(a,b) {
return Number(a) - Number(b);
}
function multi(a,b) {
return Number(a) * Number(b);
}
function div(a,b) {
return Number(a) / Number(b);
}
function main () { //as an entry point;
var entry1 = document.getElementById('entry1').value,
entry2 = document.getElementById('entry2').value;
$results = document.getElementById("results");
$results.value = add (entry1, entry2);
//$results.value = sub (entry1, entry2);
//$results.value = multi (entry1, entry2);
//$results.value = div (entry1, entry2);
}
</script>
btw: even functions are redundant, but OK I left them as is.
enjoy to JS world

Related

Trying to make a super simple clicker game but im getting NaN instead of numbers

I'm really out of ideas, I've tried everything I can try but can't get this simple thing to work.
JavaScript
var gurus = document.getElementById('clicks')
var x = gurus.value+1
function guru() {
document.getElementById('clicks').innerHTML = x
}
HTML
<p id='clicks'>0</p>
<button onclick='guru()'>Click</button>
I made this in a codepen (link).
First of all you need innerHTML not values , since p tag does not have values attribute. Secondly you need to get the content of the p tag on every click, so put it inside the function. Use parseInt to convert the string to number
var gurus = document.getElementById('clicks')
function guru() {
var x = parseInt(gurus.innerHTML, 10) + 1
document.getElementById('clicks').innerHTML = x
}
<p id='clicks'>0</p>
<button onclick='guru()'>Click</button>
Below is a clearner way to achieve the same thing youre trying to do. The code below makes use of addEventListener and removes JavaScript function calls from inline HTML (it's not best practice). Make sure to use parseInt to convert the innerHTML as that was your original issue with the code you posted:
document.addEventListener('DOMContentLoaded', () => {
const p = document.querySelector('#clicks');
const b = document.querySelector('#btn');
p.append(document.createTextNode("0"));
b.addEventListener('click', function() {
p.innerHTML = parseInt(p.innerHTML) + 1;
});
});
<p id='clicks'></p>
<button id="btn">Click</button>
And the answer is super simple too! You are treating the <p> element as if it was an input field. You need .innerHTML instead of .value. Then, you need to convert that inner HTML into a number (using Number()). Finally, you should move the increment statement:
var x = gurus.value + 1
into the function, otherwise x is just a constant. Here is a working snippet:
var gurus = document.getElementById('clicks');
function guru() {
var x = Number(gurus.innerHTML) + 1;
document.getElementById('clicks').innerHTML = x;
}
<p id='clicks'>0</p>
<button onclick='guru()'>Click</button>

Can I set two different values to an element using getElementById?

Can't I use getElementById twice in javascript file? I want to use it twice because, I want to set a default value to the element with that particular id and then on calling a function i need to change the default value. Can I do this?
Have a look at my code:
function DefaultValue(){
var default = 10.23
var update = document.getElementById('idSpnRWA');
update.innerHTML = default;
}
function setValue(){
var set = 23.56;
var finalUpdate = document.getElementById('idSpnRWA');
finalUpdate.innerHTML = set;
}
I have given a very basic code to make you understand if this way is possible?
In short: yes, you can call getElementById as many times as you want.
Please note however, that default is a reserved word in JavaScript.
Also, you're forgetting to add ; after each line.
Try this (note I renamed the default variable, and added ; where needed.
HTML
<div id="idSpnRWA"></div>
JavaScript
function DefaultValue() {
var dflt = 10.23;
var update = document.getElementById('idSpnRWA');
update.innerHTML = dflt;
}
function setValue() {
var set = 23.56;
var finalUpdate = document.getElementById('idSpnRWA');
finalUpdate.innerHTML = set;
}
DefaultValue();
setValue();
Working Fiddle: http://jsfiddle.net/9e75vnm3/
Of course you can use document.getElementById many times.
But element with a specific id can be only once at your page.
Yes you can use getElementById as many time as you want.
Problem in your code is that you are adding inner html as 10.23% which is not allowed. '%' is consider as a modulo operator. if you want to display in html than you have to concat it as string
function DefaultValue() {
var update = document.getElementById('idSpnRWA');
update.innerHTML = 10.23 + '%';
}
function setValue() {
var finalUpdate = document.getElementById('idSpnRWA');
finalUpdate.innerHTML = 23.56 + '%';
}
DefaultValue();
<div id='idSpnRWA'></div>
You cannot have the same HTML id attribute more than once on a page, but you can get anything as many times as you want, as long as it's not undefined. Of course, this means you can call document.getElementById('idSpnRWA') as many times as you want. You'll want to put percentages in quotes when assigning to .innerHTML, as % is the modulo operator. Better yet, use HTML entities. Element.innerHTML = '10.23&#037';
thank you so much for answering my question. I finally found the solution. it is,
update.value= default;
finalUpdate.value = set;
innerHTML can't be used there. If i use .value, the code is actually working fine.

javascript - coldfusion - working with a list

This is probably easy for someone.
I am returning a list of campaignIDs (12,45,66) via JSON to a javascript variable
var campaignList = res.DATA.CAMPAIGNS
Now, given a specified campaignID passed in the URL
var campaignId ='<cfoutput>#url.campaignID#</cfoutput>'
I want to check if the returned list contains this campaignID
Any help much appreciated.
Plenty of ways to do it, but I like nice data structures, so ...
Split the list on comma, then loop over list, looking for value:
function campaignExists(campaignList,campaignId) {
aCampaignList = campaignList.split(',');
for (i=0;i<aCampaignList.length;i++) {
if (aCampaignList[i]==campaignId)
return true;
}
return false;
}
Since Array.indexOf sadly isn't cross browser, you're looking at something like:
// assume there is no match
var match_found = false;
// iterate over the campaign list looking for a match,
// set "match_found" to true if we find one
for (var i = 0; i < campaignList.length; i += 1) {
if (parseInt(campaignList[i]) === parseInt(campaignId)) {
match_found = true;
break;
}
}
If you need to do this repeatedly, wrap it in a function
Here's a bit of a "out of the box" solution. You could create a struct for your property id's that you pass into the json searilizer have the key and the value the same. Then you can test the struct for hasOwnProperty. For example:
var campaignIDs = {12 : 12, 45 : 45, 66 : 66};
campaignIDs.hasOwnProperty("12"); //true
campaignIDs.hasOwnProperty("32"); //false
This way if the list is pretty long you wont have to loop through all of the potential properties to find a match. Here's a fiddle to see it in action:
http://jsfiddle.net/bittersweetryan/NeLfk/
I don't like Billy's answer to this, variables within the function have been declared in the global scope and it is somewhat over complicated. If you have a list of ids as a string in your js just search for the id you have from user input.
var patt = new RegExp("(^|,)" + campaignId + "(,|$)");
var foundCampaign = campaignList.search(patt) != -1;

Javascript Shorthand for getElementById

Is there any shorthand for the JavaScript document.getElementById? Or is there any way I can define one? It gets repetitive retyping that over and over.
var $ = function( id ) { return document.getElementById( id ); };
$( 'someID' )
Here I used $, but you can use any valid variable name.
var byId = function( id ) { return document.getElementById( id ); };
byId( 'someID' )
To save an extra character you could pollute the String prototype like this:
pollutePrototype(String, '绎', {
configurable: false, // others must fail
get: function() {
return document.getElementById(this);
},
set: function(element) {
element.id = this;
}
});
function pollutePrototype(buildIn, name, descr) {
var oldDescr = Object.getOwnPropertyDescriptor(buildIn.prototype, name);
if (oldDescr && !oldDescr.configurable) {
console.error('Unable to replace ' + buildIn.name + '.prototype.' + name + '!');
} else {
if (oldDescr) {
console.warn('Replacing ' + buildIn.name + '.prototype.' + name + ' might cause unexpected behaviour.');
}
Object.defineProperty(buildIn.prototype, name, descr);
}
}
It works in some browsers and you can access elements this way:
document.body.appendChild(
'footer'.绎 = document.createElement('div')
);
'footer'.绎.textContent = 'btw nice browser :)';
I have chosen the name of the property almost randomly. If you actually wanted to use this shorthand I would suggest coming up with something easier to type.
You can easily create shorthand easily yourself:
function getE(id){
return document.getElementById(id);
}
id's are saved to the window.
HTML
<div id='logo'>logo</div>
JS
logo.innerHTML;
is the same as writing:
document.getElementById( 'logo' ).innerHtml;
I don't suggest using the former method as it is not common practice.
A quick alternative to contribute:
HTMLDocument.prototype.e = document.getElementById
Then just do:
document.e('id');
There's a catch, it doesn't work in browsers that don't let you extend prototypes (e.g. IE6).
(Shorthand for not only getting element by ID, but also getting element by class :P)
I use something like
function _(s){
if(s.charAt(0)=='#')return [document.getElementById(s.slice(1))];
else if(s.charAt(0)=='.'){
var b=[],a=document.getElementsByTagName("*");
for(i=0;i<a.length;i++)if(a[i].className.split(' ').indexOf(s.slice(1))>=0)b.push(a[i]);
return b;
}
}
Usage : _(".test") returns all elements with class name test, and _("#blah") returns an element with id blah.
<script>
var _ = function(eId)
{
return getElementById(eId);
}
</script>
<script>
var myDiv = _('id');
</script>
There are several good answers here and several are dancing around jQuery-like syntax, but not one mentions actually using jQuery. If you're not against trying it, check out jQuery. It let's you select elements super easy like this..
By ID:
$('#elementId')
By CSS class:
$('.className')
By element type:
$('a') // all anchors on page
$('inputs') // all inputs on page
$('p a') // all anchors within paragaphs on page
There's none built-in.
If you don't mind polluting the global namespace, why not:
function $e(id) {
return document.getElementById(id);
}
EDIT - I changed the function name to be something unusual, but short and not otherwise clashing with jQuery or anything else that uses a bare $ sign.
I frequently use:
var byId='getElementById'
var byClass='getElementsByClass'
var byTag='getElementsByTag'
var mydiv=document[byId]('div')
/* as document["getElementById"] === document.getElementById */
I think it's better than a external function (e.g. $() or byId()) because you can do things like this:
var link=document[byId]('list')[byClass]('li')[0][byTag]('a')[0]
Btw, don't use jQuery for this, jQuery is much, much slower than document.getElementById(), an external function like $() or byId(), or my method: http://jsperf.com/document-getelementbyid-vs-jquery/5
Yes, it gets repetitive to use the same function over and over each time with a different argument:
var myImage = document.getElementById("myImage");
var myDiv = document.getElementById("myDiv");
So a nice thing would be a function that takes all those arguments at the same time:
function getElementsByIds(/* id1, id2, id3, ... */) {
var elements = {};
for (var i = 0; i < arguments.length; i++) {
elements[arguments[i]] = document.getElementById(arguments[i]);
}
return elements;
}
Then you would have references to all your elements stored in one object:
var el = getElementsByIds("myImage", "myDiv");
el.myImage.src = "test.gif";
But you would still have to list all those ids.
You could simplify it even more if you want all elements with ids:
function getElementsWithIds() {
var elements = {};
var elementList = document.querySelectorAll("[id]");
for (var i = 0; i < elementList.length; i++) {
elements[elementList[i].id] = elementList[i];
}
return elements;
}
But it would be pretty expensive to call this function if you have many elements.
So, theoretically, if you would use the with keyword you could write code like this:
with (getElementsByIds('myButton', 'myImage', 'myTextbox')) {
myButton.onclick = function() {
myImage.src = myTextbox.value;
};
}
But I don't want to promote the use of with. Probably there's a better way to do it.
Well, you could create a shorthand function, that's what I do.
function $(element) {
return document.getElementById(element);
}
and then when you wanted to get it, you just do
$('yourid')
Also, another useful trick that I found, is that if you want to get the value or innerHTML of an item ID, you can make functions like this:
function $val(el) {
return $(el).value;
}
function $inner(el) {
return $(el).innerHTML;
}
Hope you like it!
I actually made a kind of mini javascript library based on this whole idea.
Here it is.
If this is on your own site, consider using a library like jQuery to give you this and many other useful shorthands that also abstract away browser differences. Personally, if I wrote enough code to be bothered by the longhand, I would include jQuery.
In jQuery, the syntax would be $("#someid"). If you then want the actual DOM element and not the jQuery wrapper, it's $("#someid")[0], but you could most likely do whatever you're after with the jQuery wrapper.
Or, if you're using this in a browser developer console, research their built-in utilities. As someone else mentioned, the Chrome JavaScript console includes a $("someid") method, and you can also click an element in the developer tools "Elements" view and then reference it with $0 from the console. The previously selected element becomes $1 and so on.
If the only issue here is typing, maybe you should just get yourself a JavaScript editor with intellisense.
If the purpose is to get shorter code, then you could consider a JavaScript library like jQuery, or you can just write your own shorthand functions, like:
function byId(string) {return document.getElementById(string);}
I used to do the above for better performance. What I learnt last year is that with compression techniques the server does it automatically for you, so my shortening technique was actually making my code heavier. Now I am just happy with typing the whole document.getElementById.
If you are asking for a shorthand function...
<!DOCTYPE html>
<html>
<body>
The content of the body element is displayed in your browser.
<div id="d1">DIV</div>
<script>
var d=document;
d.g=document.getElementById;
d.g("d1").innerHTML = "catch";
</script>
</body>
</html>
or
<!DOCTYPE html>
<html>
<body>
The content of the body element is displayed in your browser.
<div id="d1">DIV</div>
<script>
var w=window;
w["d1"].innerHTML = "catch2";
</script>
</body>
Arrow functions make is shorter.
var $id = (id) => document.getElementById(id);
wrap the document.querySelectorAll ... a jquery like select
function $(selector){
var s = document.querySelectorAll(selector);
return s.length > 1 ? s : s[0];
}
// usage: $('$myId')
Well, if the id of the element does not compete with any properties of the global object, you don't have to use any function.
myDiv.appendChild(document.createTextNode("Once I was myDiv. "));
myDiv.id = "yourDiv";
yourDiv.appendChild(document.createTextNode("But now I'm yourDiv."));
edit: But you don't want to make use of this 'feature'.
Another wrapper:
const IDS = new Proxy({}, {
get: function(target, id) {
return document.getElementById(id); } });
IDS.camelCaseId.style.color = 'red';
IDS['dash-id'].style.color = 'blue';
<div id="camelCaseId">div 1</div>
<div id="dash-id">div 2</div>
This, in case you don't want to use the unthinkable, see above.
You can use a wrapper function like :
const byId = (id) => document.getElementById(id);
Or
Assign document.getElementById to a variable by binding it with document object.
const byId = document.getElementById.bind(document);
Note: In second approach, If you don't bind document.getElementById with document you'll get error :
Uncaught TypeError: Illegal invocation
What Function.bind does is it creates a new function with its this keyword set to value that you provide as argument to Function.bind.
Read docs for Function.bind
const $id = id => document.getElementById(id);
...
$id('header')
I just use: function id(id) {return document.getElementById(id);}", called by id(target id).action;
It works for me in Chrome, Edge & Firefox, though not in Safari or Opera.
I wrote this yesterday and found it quite useful.
function gid(id, attribute) {
var x = 'document.getElementById("'+id+'")';
if(attribute) x += '.'+attribute;
eval('x =' + x);
return x;
}
This is how you use it.
// Get element by ID
var node = gid('someID'); //returns <p id='someID' class='style'>Hello World</p>
// returns 'Hello World'
// var getText = document.GetElementById('someID').innerText;
var getText = gid('someID', 'innerText');
// Get parent node
var parentNode = gid('someID', 'parentNode');

javascript - search multiple html #ID and pass to function

I've got an order form, to which I can append fields by clicking a button. I've got some back end javascript running which totals up the order price, but the grand total script is eluding me.
My problem is that I need the script to seach the entire DOM and find how many have an ID which matches the following pattern.
totprice01
totprice02
totprice03
totprice(n)
I've been playing with this regex, but with not a lot of luck i'm afraid:
matchStr = new RegExp("\\btotprice\\d{2}\\b", "gi");
Once i've got an array of all the HTML IDs I need to pass them into a function which so far looks like this - notice it's all hard coded, not in the least dynamic:
document.getElementById('totpricetot').value = Math.round((parseFloat(document.getElementById('totprice1').value)+parseFloat(document.getElementById('totprice2').value)+parseFloat(document.getElementById('totprice3').value)+parseFloat(document.getElementById('totprice4').value)+parseFloat(document.getElementById('totprice5').value)+parseFloat(document.getElementById('totprice6').value)+parseFloat(document.getElementById('totprice7').value)+parseFloat(document.getElementById('totprice8').value)+parseFloat(document.getElementById('totprice9').value)+parseFloat(document.getElementById('totprice10').value))*100)/100;
Is anyone able to help me put this into expression + function to return the sum of all the values into ?
Thanks a lot!
EDIT
OK I decided to ditch just using plain ol' javascript - JQuery it is! I've put together this code using some of the examples below, but can someone help me debug it I keep get "not defined" errors from the debugger - it appears this function is unavailable to the rest of the DOM?
<input id="totprice08" onChange="totChange()" class="total_field" />
<input id="totprice09" onChange="totChange()" class="total_field" />
<input id="totprice10" onChange="totChange()" class="total_field" />
etc...
<input id="totpricetot" value="0.00" name="totpricetot" />
jQuery(function($) {
function totChange() {
var sum=0;
$('.total_field').each(function() {
sum += $( this ).val () * 1;
} );
$('#totpricetot').val(sum);
}
});
I love it how every javascript question on SO is answered by, "use jQuery"...
Anyways...you can do it with just plain ol' javascript too:
var inputs = document.getElementsByTagName("input");
var priceInputs = [];
for (var i=0, len=inputs.length; i<len; i++) {
if (inputs[i].tagName.indexOf("totprice") > -1) {
priceInputs[priceInputs.length] = parseInt(inputs[i].value);
}
}
calcTotal(priceInputs);
Then just create a function to loop through the array and sum up (:
There are lots of solutions. Besides giving all the elements in question the same class name and use jQuery (or something similar), you could also simply remember the total number of the elements in some JavaScript variable. Would it be possible? I know - it’s kind of an old school solution. You have not indicated that you are using jQuery or any other JavaScript library, so it may be more suitable for you.
Edit: Just to be more explicit:
// your variable, updated every time you add/remove a new field
var fieldsCount;
// whenever you need to do anything with all the fields:
for (var i = 0; i < fieldsCount; i++)
{
var field = document.getElementById("totprice" + i);
// ...
}
Using jQuery, you could select and sum the elements like this:
var sum = 0;
$('[id^=totprice-]').each(function()
{
sum += $(this).val();
});
Give the inputs you need to sum up a class and then get those inputs by that class name (jQuery or some other framework would come in handy here).
if you would use jQuery you could do something like this:
function calculateSum () {
var sum = 0;
$( '.YourClass' ).each ( function () {
sum += $( this ).val () * 1;
} );
return sum;
}
You could give all your total price elements the same CSS class and then get all elements of this class (nice and easy with JQuery).
Give each element a class and use jQuery.

Categories