JQuery get 'id' attribute - javascript

So I have the following code that generates a table and applies a click function to each td within the table. It also applies an incremental id starting with 1. When the user clicks on a td element I'm trying to retrieve the id of the <td> they clicked on. However the value of selector is [object Window]. I'm sure it is something simple but I none of the similar questions on here have helped, and I'm not seeing it.
$("#CMGame").click(function() {
$("#TTTContent").hide();
$("#CMContent").show();
var board = $("#CMBoard");
var htmlString = "";
var count = 0;
for (var i = 0; i < 20; i++) {
htmlString += "<tr>";
for (var i2 = 0; i2 < 20; i2++) {
count++;
htmlString += "<td id='" + toString(count) + "'></td>";
}
htmlString += "</tr>";
}
board.html(htmlString);
$("#CMBoard td").click(function() {
var piece = $(this);
var selector = piece.attr('id');
alert(selector);
/*
if (CMBArray[selector] != 1 OR CMBArray[selector] != 2) {
CMBArray[selector] = 1;
piece.addClass('selected');
}
*/
});
});

There are 2 errors in your code, the td id you create can't be just a number, it has to start with a letter and then you can either remove toString(count) and use only count or change it to count.toString(), which is the correct way.
Here is the specs. for a DOM id:
https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/id
And here for toString():
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toString

The toString is wrong in the code. Change
toString(count)
to
count.toLocaleString()

toString(count) is effectively like saying this.toString() which, in your case basically means window.toString(), which results in [object Window].
Instead, use count.toString().
Here's a quick test:
var count = 0;
console.log('second toString: ' + toString(count) );
console.log('second toString: ' + count.toString );
Bear in mind that, whenever you concatonate strings in Javascript, the toString method is called on all objects by default. For example, these two expressions yield the same output:
var number = 5;
console.log( 'The number is ' + number.toString() );
console.log( 'The number is ' + number );

The toString method you are calling is actually window.toString.
By not specifying a parent object for toString, you are invoking the method on the global window object. That is why you see "[object Window]", it is returning a string representation of the invoking object.
You don't need the toString at all. Javascript cast numberics to a string when you add it to a string.

this.id will return the id of the a jQuery element. E.g.:
$("td").click(function(){
alert(this.id);
});

Your problem is in the event $("#CMGame").click(function()
when try to convert to string with toString(count) javascript and jquery don't understand that they do understand count.toString() here is the source javaScript toString function.
Suggestion about some code you have:
first this one var board = $("#CMBoard"); you pass the html element to a javascript variable for you can do this board.html(htmlString); i think you do that so your function can be more faster than using other method to manipulate the DOM but in this case it look that we are not looking for best performances so other option is keep it simple with this $("#CMBoard").append(htmlString)
The id you set to each element is a number that is not a good practice at all and also there is a suggestion for compatibility for HTML5 to HTML4 look;
Note: Using characters except ASCII letters and digits, '_', '-' and '.' may cause compatibility problems, as they weren't allowed in HTML 4. Though this restriction has been lifted in HTML 5, an ID should start with a letter for compatibility. you can find this in global attribute id so is better to set a real id name you can do something like this in your code htmlString += "<td id='item_" + count.toString() + "'></td>";
so the id will come out like id="item_1"

Related

How can I convert the string value of a jQuery object into an actual jQuery object?

I have this string in my JS code right now:
newWords = '$(p span.word[style="--' + paraIndex + 'word-index:undefined"], p span.whitespace[style="--' + paraIndex + 'word-index:undefined"])';
I want to convert this string into a jQuery object that I can use do identify those specific elements.
I also saw the eval() function. That looks like it does what I want it to, but is super unsafe/unsecure.
Does anyone know a safe way to do this?
The simplest solution is to remove $( and ) and pass the remaining string as an argument to $():
var paraIndex = 0;
var newWords = '$(p span.word[style="--' + paraIndex
+ 'word-index:undefined"], p span.whitespace[style="--'
+ paraIndex + 'word-index:undefined"])';
var jQ = $(newWords.slice(2, -1));
console.log(jQ);
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Declare JavaScript variable only with ' ' marks

I saw one of the masters doing this:
var example = '';
Then later he continued with this:
example += '<div>just a div</div>';
I wanna know if there's any difference from doing this:
var example;
example += '<div>just a div</div>';
I don't really know if by doing the second method I'm doing wrong and I have to code like shown if the first example.
Updated!
Thank you so much for your answers, Ok I got it I need to define my variable to be able to work woth it, but then another question came... This master also is doing this:
var guess;
and then he does:
guess += myfunction( upper );
where myfunction was declared as follows:
function myFunction( upper ){
return Math.floor( Math.random() * upper ) + 1;
}
So, why here is different? Can any of you answer this please?
Thank you!
Second update!
Again Thanks!
I decided to post the whole code the JS master was doing, at this point I don't understand, so probably you'll be able to clear my doubts.
var randomNumber = myFunction( 10 );
var guess;
var attempts = 0;
var answer = false;
function myFunction( upper ){
return Math.floor( Math.random() * upper ) + 1;
}
do{
guess = prompt( "I created a number from 1 till 10, can you guess it?");
attempts += 1;
if( parseInt( guess ) === randomNumber ){
answer = true;
}
}while( ! answer )
document.write( "Took you " + attempts + " attempts to guess the number " + randomNumber);
Please have a look at:
var guess;
and how later is being declared, so why here works perfectly but in my first example I have to put the '' when declaring my variable?
I hope my question is clear enough for you!
Thank you for your time and patient!
When you do:
var example;
example += '<div>just a div</div>';
You end up with:
`"undefined<div>just a div</div>"`
This is because when you don't initialize a variable, it is undefined, which can be converted to a sensible string "undefined" when you try to add it to another string.
When you do:
var guess;
guess += myfunction( upper );
function myFunction( upper ){
return Math.floor( Math.random() * upper ) + 1;
}
You are adding a number to undefined. This results in NaN (not a number) because undefined cannot be converted into a sensible number.
You can check this yourself next time by opening up your browser's developer tools and running the code in the console.
Edit:
When you do:
var guess;
guess = prompt( "I created a number from 1 till 10, can you guess it?");
There's no issue because you are simply assigning a string to the guess variable. In the previous examples you were adding something to a variable, which means if they are different types then JavaScript has to try to do something sensible.
If you don't initialize your variable it has a value of undefined.
In your last example, you are really saying example = undefined + '<div>just a div</div>' and undefined will be converted to a string and output that way. Probably not what you want.
In general it is a good idea to initialize your variables before you use them which is why var example = '' is preferable in this case.
var myvar
myvar += 'asdf'
console.log(myvar) // prints undefinedasdf
var othervar = ''
othervar += 'sdfasdf'
console.log(othervar) // prints sdfasdf
If you don't initialize the variable then it will be undefined
Appending to undefined object doesn't help.
var example = '';
Here you are initializing an empty string to the variable and therefore appending a string to another string will give the desired output of string concatenation.
Output:
"undefined<div>just a div</div>"
"<div>just a div</div>"
Yes there is a difference the first snipet from the master creates a variable example and gives it a default value, the second statement concatinates the value with 'just a div'
.Your code has an error as it is adding a value to a non-existed value as variable example has no default value.

New to javascript, how to assign an input value to a submit button?

I'm new to javascript and need help with a piece of my code. I am suppose to create a text box that a user can input a number and the function will then roll that many dice. I also need to set limits so a user can't enter -10 or 100 because it is only 1-6. So it looks like this:
var theInput = document.getElementById('num').value;
theInput = parseInt(theInput);
if (theInput < 1) {
theInput="1";
}
else if (theInput > 6) {
theInput = "6";
}
The part I'm stuck on is how I am suppose to link a text box to this piece of code that will then run through my function for dice rolling.
<script type="text/javascript">
function SelectImage6() {
document.getElementById('outputDiv').innerHTML ='';
for(i=0; i<6; i++){
roll2 = Math.floor(Math.random() * 6) + 1;
imgName2 = '../images/die' + roll2 + '.gif';
document.getElementById('outputDiv').innerHTML +=
'<img alt="die image" src="' + imgName2+'" />';
}
}
</script>
<body>
<div style="text-align:center">
<input type="button" value="Click to Roll" onclick="SelectImage6();">
<p id="outputDiv">
<img id="dieImg2" alt="die image"
src="../images/die2.gif" >
</p>
</div>
Where do I assign the var theInput within my code? Any help would be greatly appreciated. Thanks!
Well first you should create the textbox in the html like this:
<input type="text" id="num">
Then have people push a button to start your javascript code. So use the button you already have. Then when the SelectImage6() function is called on the button click, you just put the top javascript code (the one checking the input) into the function SelectImage6() and you will have a nice function that does it all.
To answer the specifics of your question, it makes most sense to get the number of dice to roll inside the SelectImage6 function. To make things nice and clean, you might want to encapsulate that functionality:
// returns the number of dice the user entered. if the user entered a non-numeric
// value, this function will throw an exception. if the user entered less than
// one, the value will be clamped to 1, and if the user entered more than six, the
// value will be clamped to 6.
function getNumDice() {
'use strict';
var numEntered = parseInt( document.getElementById('num').value );
if( isNaN( numEntered ) ) throw 'The number of dice must be numeric.';
if( numEntered < 1 ) numEntered = 1;
if( numEntered > 6 ) numEntered = 6;
return numEntered;
}
I cleaned up your function a little bit. "theInput" is a bit vague for a variable name, so I changed it to something more descriptive. I handled the case where the user doesn't enter a number, and I consolidated the document.getElementById and the parseInt into one line. Also, you were mixing types in your original code. You use parseInt (which returns a numeric type), but then you would set theInput to a string. This may not result in an error thanks to JavaScript's flexible type coercion, but it's bad practice regardless.
Now that you have that function, you can modify your SelectImage6 accordingly:
function SelectImage6() {
'use strict';
var div = document.getElementById('outputDiv'); // cached for efficiency
var html = '';
var roll2, imgName2;
var numDice = getNumDice();
for( i=0; i<numDice; i++ ){
roll2 = Math.floor(Math.random() * 6) + 1;
imgName2 = '../images/die' + roll2 + '.gif';
html += '<img alt="die image" src="' + imgName2+'" alt="die" />';
}
div.innerHtml = html;
}
For SelectImage6, I made some changes (in addition to using the value returned by getNumDice). First, you're repeatedly calling getElementById (once, unnecessarily, at the top of the function, then once for every dice rolled!). Any DOM access is expensive, and if you can avoid doing it multiple times, you should. Secondly, you're repeatedly modifying the innerHtml property which, depending on the complexity of your HTML, and your network latency, could cause flicker or other unpleasant effects. What I chose to do instead was to build up the string first, then set it all at once.
In your original function, you were unwittingly using global variables (implied globals) because you didn't declare roll2 and imgName2 as variables. I fixed that, and added use strict to your functions so this mistake will be caught in the future! (My advice is to always set use strict.);
I hope this helps! Welcome to the world of JavaScript.

Help on eval() function

I need help on this eval() problem:
var ScoreFuncName = 'scoreCondition_' + criteriaName;
var allCheckBox = $('div#'+SubListId).find("input:image[name^='" + ChkBoxPrefix + "'][value='1']");
eval(ScoreFuncName + '(' + allCheckBox.length + ')');
The eval() function is evaluating which checkbox is ticked and will do other things accordingly, it worked great in Firefox but not in google Chrome and IE.
Scratching my head for 3 days on how to fix this. Thank you.
You should not be using eval for that.
If the function is in global scope. All you need to do is
window[ScoreFuncName](allCheckBox.length);
It would be better to name space it instead of using a global with window
Eval is not needed to do this. Also take notice that I am calling size on the jQuery object rather than length.
var scoreFunc = this['scoreCondition_' + criteriaName];
var allCheckBox =
$('div#'+SubListId).find("input:image[name^='" + ChkBoxPrefix + "'][value='1']");
scoreFunc(allCheckBox.size());
Hm... don't.
There realistically is not a need to use eval in this condition (and I would say that there is no need for a string look-up of the function). Since it looks clear that you have a finite and knowable number of conditions and a finite and knowable number of functions, then you can simply use a switch to actually select a function dynamically:
var toRun; // variable to store the function.
switch(criteriaName)
{
case "criteria1":
// keep the actual function in the variable, not some string.
toRun = function(e){console.log("I is so special! " + e)}
break;
case "criteria2":
toRun = function(e){console.log( e + " is not a squid!" )}
break;
}
var allCheckBox = $('div#'+SubListId).find("input:image[name^='" +
ChkBoxPrefix + "'][value='1']");
// then just call it!
toRun(allCheckBox.length)

javascript parseFloat '500,000' returns 500 when I need 500000

How would it be a nice way of handling this?
I already thought on removing the comma and then parsing to float.
Do you know a better/cleaner way?
Thanks
parseFloat( theString.replace(/,/g,'') );
I don't know why no one has suggested this expression-
parseFloat( theString.replace(/[^\d\.]/g,'') );
Removes any non-numeric characters except for periods. You don't need custom functions/loops for this either, that's just overkill.
Nope. Remove the comma.
You can use the string replace method, but not in a one liner as a regexp allows.
while(str.indexOf(',')!=-1)str= str.replace(',','');
parseFloat(str);
Or to make a single expression without a regexp=
return parseFloat(str.split(',').join(''));
I'd use the regexp.
I don't have enough reputation to add a comment, but for anyone wondering on the performance for regex vs split/join, here's a quick fiddle: https://jsfiddle.net/uh3mmgru/
var test = "1,123,214.19";
var t0 = performance.now();
for (var i = 0; i < 1000000; i++)
{
var a = parseFloat(test.replace(/,/g,''));
}
var t1 = performance.now();
document.write('Regex took: ' + (t1 - t0) + ' ms');
document.write('<br>')
var t0 = performance.now();
for (var i = 0; i < 1000000; i++)
{
var b = parseFloat(test.split(',').join(''));
}
var t1 = performance.now();
document.write('Split/join took: ' + (t1 - t0) + ' ms');
The results I get are (for 1 million loops each):
Regex: 263.335 ms
Split/join: 1035.875 ms
So I think its safe to say that regex is the way to go in this scenario
Building on the idea from #kennebec, if you want to make sure that the commas are correct, and you don't want to replace commas, you could try something like this:
function myParse(num) {
var n2 = num.split(",")
out = 0
for(var i = 0; i < n2.length; i++) {
out *= 1000;
out += parseFloat(n2[i])
}
return out
}
alert(myParse("1,432,85"));
// Returns 1432085, as the comma is misplaced.
It may not be as fast, but you wanted alternatives :)
What about a simple function to solve most of the common problems?
function getValue(obj) {
Value = parseFloat( $(obj).val().replace(/,/g,'') ).toFixed(2);
return +Value;
}
The above function gets values from fields (using jQuery) assuming the entered values are numeric (I rather validate fields while user is entering data, so I know for sure field content is numeric).
In case of floating point values, if well formatted in the field, the function will return a float point value correctly.
This function is far from complete, but it quickly fix the "," (comma) issue for values entered as 1,234.56 or 1,234,567. It will return valid number as far the content is numeric.
The + (plus) sign in front of the variable Value in the return command is a "dirty trick" used in JavaScript to assure the variable content returned will be numeric.
it is easy to modify the function to other purposes, such as (for instance), convert strings to numeric values taking care of the "," (comma) issue:
function parseValue(str) {
Value = parseFloat( str.replace(/,/g,'') ).toFixed(2);
return +Value;
}
Both operations can even be combined in one function. I.e.:
function parseNumber(item,isField=false) {
Value = (isField) ? parseFloat( $(item).val().replace(/,/g,'') ).toFixed(2) : parseFloat( item.replace(/,/g,'') ).toFixed(2)
return +Value;
}
In such case, if function is called result = parseNumber('12,092.98'); it will parse the value as it is a String. But if called as result = parseNumber('#MyField', true); it will try to obtain the value from '#MyField'.
As I said before, such functions are far from complete, and can be expanded in many ways. One idea is to check the first character of the given parameter (string) and decide based on the string format where to obtain the value to be parsed (if 1st character is = '#' then it is an ID from a DOM object, otherwise, if it begins with a number, it must be a string to be parsed).
Try it... Happy coding.

Categories

Resources