I'm pretty new to Javascript, so forgive me if this is a simple question.
I'm trying to access the length of a set of checkboxes in a form using Javascript. However, I need to be able to change the "name" field of the checkboxes to check several different sets of them. Right now, my sample code looks like:
var set = "set" + x;
totalLength = optionBoxes.set.length;
The variable x is being incremented by a for loop that wraps the whole thing and the name of the checkbox sets that I'm trying to access are set0, set1, set2, etc.
Thanks.
Edit: small typo fixes
Probably you want this:
var set = "set" + x;
totalLength = optionBoxes[set].length;
In Javascript, properties of an object are usually accessed as object.name, but they can also be accessed by object["name"] if you have the name as a string.
if you think that your code should otherwise work try:
totalLength = optionBoxes[set].length;
Related
I am trying to output som script using SSJS from a computedField like so:
var outScript = "<script>var data = " + datad.toString() + ";</script>"
The problem I have is that the computedField is within a doccollection repeat so I need to make the variable dynamic because I later need to access only the variable from the current entry using client side javascript (also within repeat)
How do I write to make the "data" variable dynamic within my repeat?
I know can create the variable using noteid or index, but I need to know how to write to output the variable i.e data1, data2 etc.
Hope you understand, a bit complicated to explain.
problably an easy answer I havn't thought of
thanks
Thomas
You could use the repeat's indexVar to save the data with a distinct key for each repeat entry:
var outScript = "<script>window.data_myRepeat_" + iRepeat.toFixed(0) + " = " + datad.toString() + ";</script>"
Here, it is assumed that the repeat's ID is "myRepeat" and indexVar is "iRepeat".
I wish to name an array according to the table row containing the button that was clicked.
I get the table row thus:
var rowNum = $(this).parent().parent().index();
Now, I wish to name the array and access it.
var arrayName = 'arrTR' + rowNum;
window[arrayName] = new Array();
window[arrayName]["First"] = "Bob";
window[arrayName]["Last"] = "Roberts";
window[arrayName]["email"] = "me#there.com";
//The array should be accessible as arrTR__
alert(arrTR1["Last"]);
The alert does not work, so I am doing something wrong.
How should I refactor the code to allow me to update and access the array?
jsFiddle
What you're doing with the dynamically named variables is essentially creating an array of those variables (one for each rowNum), but giving each of those array elements its own individual named variable.
There is a much better way to do this. Instead of generating a series of dynamically named variables, make a single array or an object. Then add an element or property for each of the dynamically named variables you were going to generate.
Your test code could look like this:
var arrTR = [];
var rowNum = 1;
arrTR[rowNum] = {
First: 'Bob',
Last: 'Roberts',
email: 'me#there.com'
};
alert( arrTR[1].Last );
Alternatively, you can do something with $.data as mentioned in Johan's answer. But if you do use plain JavaScript code, use a single array as described here instead of multiple dynamically named variables.
There are several reasons to do it this way. It's cleaner and easier to understand the code, it may be faster when there are large numbers of entries, and you don't have to pollute the global namespace at all. You can define the var arrTR = []; in any scope that's visible to the other code that uses it.
Arrays and objects are made for keeping track of lists of things, so use them.
There is nothing wrong with your code, and the only place it has error is the alert since it is not defined on the first click button
see this fiddle with a little update
if(rowNum === 1)
alert(arrTR1["Last"]);
else if(rowNum === 2)
alert(arrTR2["Last"]);
fiddle
How about something like this?
$('.getinfo').click(function() {
var result = $('table tr:gt(0)').map(function(k, v){
return {
firstName: $(v).find('.fname').val(),
lastName: $(v).find('.lname').val(),
email: $(v).find('.email').val(),
}
}).get();
//update to show how you use the jQuery cache:
//1. set the value (using the body tag in this example):
$('body').data({ result: result });
//2. fetch it somewhere else:
var res = $('body').data('result');
});
Not sure how you want to handle the first row. I skip in in this case. You can access each row by result[index].
As you might have noticed, this saves all rows for each click. If you want to use the clicked row only, use the this pointer.
http://jsfiddle.net/nwW4h/4/
I'm trying to create my own JS Password Strength Meter.
It was working before but i didn't like how it worked so I tried using
{score +=10;}
Instead of just:
score++
This is my code:
http://jsfiddle.net/RSq4L/
Best Regards,
Shawn,
Hope someone can help
Multiple issues:
Your passwordStrength() function was not defined in the global scope in the jsFiddle so it wasn't getting called. This is probably an artifact of how you set up the jsFiddle, perhaps not an issue in your real code.
The method of getting the appropriate ratingMsg will not work because you don't have array values for every possible score so many scores will generate an "undefined" ratingMsg.
Your CSS classes are also sparse so there are many score values that they will not match for either and no appropriate CSS class/style will be in effect. If you want a specific class for each rating value, then perhaps you should put the classname in the ratings array so it can be fetched from there along with the ratingsMsg.
For the first issue, in your jsFiddle, you also have to make sure the password processing function is defined in the global scope. The way your jsFiddle is set up, it is not (it's in the onload handler). You can fix this in the jsFiddle by just setting the first drop-down in the upper left to "no wrap (head)".
For the second issue, you are using:
ratingMsg[score]
but, your array is a sparse array not guaranteed to have an entry for most possible scores. You simply can't do it that way because many elements you access will have undefined values which won't give you a meaningful message. For example, if score was 15, you would be accessing ratingMsg[15], but there is no value in that space in the array so you won't get a meaningful rating message.
The solution is to find a different way to select the right message. The simplest way would just be an if/else if/else if statement that would check which range the score is in and set the appropriate msg. There are more elegant table driven ways, but all will involve searching through a data structure to find which two values the current score is between and using that msg.
If you look at this jsFiddle http://jsfiddle.net/jfriend00/dA7XC/, you'll see that your code is getting called, but it only hits values in the array sometimes.
And, here's a rewritten algorithm that finds the appropriate msg no matter what the score show in this fiddle: http://jsfiddle.net/jfriend00/jYcBT/.
It uses a data structure like this:
var ratingMsg = [
0, "Unclassified",
10, "Weak",
20, "Fair",
50, "Better",
60, "Medium",
70, "Good",
90, "Strong"
];
and a for loop like this to get the appropraite ratingMsg:
for (var i = ratingMsg.length - 2 ; i >= 0; i-=2) {
if (score >= ratingMsg[i]) {
msg = ratingMsg[i+1];
break;
}
}
Here you go: http://jsfiddle.net/RSq4L/11/
The first problem is that in your fiddle you have the onLoad option set, so your passwordStrength function is not actually being declared in the global scope. It is being declared inside of the onLoad block that jsFiddle wraps your code with. This causes the page to error out when the keypress handler tries to invoke the function.
You can fix this problem in several different ways:
By explicitly declaring the function as global as per my example above.
By choosing one of jsFiddle's "no wrap" options instead of onLoad.
By dynamically binding your event-handler instead of setting it through the element's onkeydown attribute in the markup.
The second problem is how you are keying your score messages. You have:
var ratingMsg = new Array(0);
ratingMsg[0] = "Unclassified";
ratingMsg[10] = "Weak";
ratingMsg[30] = "Fair";
ratingMsg[50] = "Better";
ratingMsg[60] = "Medium";
ratingMsg[70] = "Good";
ratingMsg[90] = "Strong";
...and you lookup the message by doing ratingMsg[score]. This will only work if the score exactly matches one of your indices. And based upon your math this will not always be the case.
I would suggest doing something like:
ratingMsg = {};
ratingMsg[0] = "Unclassified";
ratingMsg[10] = "Weak";
ratingMsg[30] = "Fair";
ratingMsg[50] = "Better";
ratingMsg[60] = "Medium";
ratingMsg[70] = "Good";
ratingMsg[90] = "Strong";
function closestRating(score) {
var bestKey = 0;
var bestMatch = 100;
for (var key in ratingMsg) {
if (key <= score && score - key < bestMatch) {
bestMatch = score - key;
bestKey = key;
}
}
return ratingMsg[bestKey];
}
On an unrelated note, are you sure you want to be using onkeydown? I think onkeyup would work better.
Your fiddler script had several errors. Here's the corrected one: new script.
You were missing a semicolon here: document.getElementById("passwordDescription").innerHTML = "" + ratingMsg[score] + ""
You forgot to escape '^' on your regular expression
I just wrote this for it:
Jquery Plugin for password strength forcing
I am trying to reduce the repetition in my code but not having any luck. I reduced the code down to its simplest functionality to try and get it to work.
The idea is to take the last two letters of an id name, as those letters are the same as a previously declared variable and use it to refer to the old variable.
I used the alert to test whether I was getting the right output and the alert window pops up saying "E1". So I am not really sure why it wont work when I try and use it.
E1 = new Audio('audio/E1.ogg');
$('#noteE1').click(function() {
var fileName = this.id.slice(4);
//alert(fileName); used to test output
fileName.play();
$('#note' + fileName).addClass('active');
});
The code block works when I use the original variable E1 instead of fileName. I want to use fileName because I am hoping to have this function work for multiple elements on click, instead of having it repeated for each element.
How can I make this work? What am I missing?
Thanks.
fileName is still a string. JavaScript does not know that you want to use the variable with the same name. You are calling the play() method on a string, which of course does not exist (hence you get an error).
Suggestion:
Store your objects in a table:
var files = {
E1: new Audio('audio/E1.ogg')
};
$('#noteE1').click(function() {
var fileName = this.id.slice(4);
//alert(fileName); used to test output
files[fileName].play();
$('#note' + fileName).addClass('active');
});
Another suggestion:
Instead of using the ID to hold information about the file, consider using HTML5 data attributes:
<div id="#note" data-filename="E1">Something</div>
Then you can get the name with:
var filename = $('#note').data('filename');
This makes your code more flexible. You are not dependent on giving the elements an ID in a specific format.
I'm trying to debug some javascript I wrote and can't figure out why it's not working. If I hard code the variables it works fine, but if I use document.getElementById('id').value to get the variable it fails.
The example below works fine but as soon as I un-comment the commented lines it doesn't. Printing the variables before and after the second section they seem to be identical.
Really don't get what's going on. Maybe I just need to sleep on it, but if anyone's got suggestions that would be great!
roof_width = 5;
roof_depth = 3;
panel_width = 2;
panel_depth = 1;
panel_power = 200;
roof_margin = 0.100;
panel_gap = 0.05;
roof_width = document.getElementById('roof_width').value;
roof_depth = document.getElementById('roof_depth').value;
// panel_width = document.getElementById('panel_width').value;
// panel_depth = document.getElementById('panel_depth').value;
panel_power = document.getElementById('panel_power').value;
// roof_margin = document.getElementById('roof_margin').value;
panel_gap = document.getElementById('panel_gap').value;
Are you trying to add numbers that are in text boxes? Because of the way JavaScript's variable typing system works (combined with the overloading of the + operator), 2 + 2 === 4 (adding numbers) but '2' + '2' === '22' (string concatenation). Try changing the lines to, for example:
panel_width = parseFloat(document.getElementById('panel_width').value);
or alternatively:
panel_width = Number(document.getElementById('panel_width').value);
This will ensure that JavaScript treats the numbers as numbers rather than as strings.
JavaScript parameters can't be called in the same way that you're calling HTML elements. In order to call
document.getElementById('roof_margin').value;
you need to assign 'roof_margin' to an HTML form element.
Pherhaps you have multiple dom elements with the same id? Remember the dom element ID must be unique. I suggest you to use jquery for interacting javascript with html.
Make sure your code is in an onload function. Otherwise the elements may not have been loaded into the DOM yet.
window.onload = funciton(){/* code here */};