Javascript and using variables instead of strings in bracket notation - javascript

I have a PHP script that takes a text list with a variable number of questions and generates HTML form code that looks like this.
What did you think of X?<br />
<input type="hidden" name="$survey[0][0]" value="What did you think of X?">
<input type="radio" name="$survey[0][1]" value="1">Didn't like it.
<input type="radio" name="$survey[0][1]" value="2">I was indifferent.
<input type="radio" name="$survey[0][1]" value="3">Liked it.
$survey[n][0] is the question, $survey[n][1] is the answer, and n is the variable number of questions.
To validate using Javascript, I have a loop that loops through the questions, and a loop inside it that makes sure each question has an answer. My problem is referencing the elements with [] in their names. Here's what I think is the relevant part of my code.
var formElements = document.forms["form"].elements;
var groupCount = document.getElementsByTagName("li").length;
var groupNdx = 0;
var groupName = "";
var btnCount = 0;
while (groupNdx < groupCount) {
groupName = "'$survey[" + groupNdx + "][1]'";
btnCount = formElements[groupName].length;
That last line doesn't work because formElements[groupName] is "undefined."
formElements['$survey[3][1]'] works just fine, but that hardcodes the element's name, and I'd need to repeat the code for each question, and worse, it's a variable number of questions.
As I was typing, the Similar Questions sidebar suggested I read Why aren't variable names converted to strings when using bracket notation in javascript?, so now I that's just how it is in Javascript.
But then what workaround would you suggest? I could just forget about validating with Javascript since I also validate the form with PHP, but I understand it's good practice to validate forms at both the client and server sides. Thanks for your help!

You have an extra set of single quotes that you shouldn't here:
groupName = "'$survey[" + groupNdx + "][1]'";
That adds single quotes into the key itself. Change that to:
groupName = "$survey[" + groupNdx + "][1]";
Notice that x["'key'"] is a different from x['key'] in Javascript. The first has a key of 'key' (including the quotes) while the second has just the string: key

Related

What is the best way to get the data from an array that is stored in localstorage?

Below as you can see in my code i created a input field for users that i want to store inside of an array, which also i want to store that array into localstorage. Now i think that stored the values that i give trough the input field in localsorage , beacuse that i can see from my browser application in chrome. Now with this code i have some problem.
Each value that i add one by one as you can see in the picture below ,whenever i refresh the browser , the values disapear from the browser?
So if someone can help me out with my code i would appriciate a lot , and also give me some advice , since im very new to localstorage and cookies and i am trying to learn
<input type="text" id="username"><br><br>
<input type="submit" id="btn">
<p id="demo"></p>
<script>
var btn=document.getElementById("btn");
var user=document.getElementById("username");
var names=[];
btn.onclick=function(){
names.push(user.value);
localStorage.setItem("names",JSON.stringify(names));
var f =JSON.parse(localStorage.getItem("names"));
var x;
var i;
for(i=0;i<f.length;i++){
x+=f[i]+"<br>";
}
document.getElementById("demo").innerHTML=x;
}
</script>
You're getting undefined because you never assign a value to x prior to using it in x+=f[i]+"<br>", so it gets the default value undefined, which is then converted to string. Assign "" to x before the loop.
Side note: There's no need for f in that code at all. Just use names:
localStorage.setItem("names",JSON.stringify(names));
var x = "";
for (var i = 0; i < names.length; ++i) {
x += names[i] + "<br>";
}
You might also consider using join instead of a loop:
localStorage.setItem("names",JSON.stringify(names));
var x = names.join("<br>");
Beware that if any name is entered that contains a < or &, it could potentially mess up your output, since of course those characters start things that are special in HTML (tags and character references, respectively). To prevent that, you might use map before join:
localStorage.setItem("names",JSON.stringify(names));
var x = names.map(function(name) {
return name.replace(/&/g, "&").replace(/</g, "<");
}).join("<br>");
or in modern JavaScript:
localStorage.setItem("names",JSON.stringify(names));
const x = names.map(name => name.replace(/&/g, "&").replace(/</g, "<"))
.join("<br>");
That's only valid if you're outputting to an element's body, as you are in that code; if you were outputting to an attribute value, it would be more complicated. (Some folks would also change > to >, but there isn't any need to if, again, you're outputting to the body of an element and not within a tag.)

multiplication inside an input with "*" operator

I am trying to get a multiplication entered in an input replaced by its solution.
Basicaly, when you enter 3*3 into the input, I would like my javascript code to replace 3*3 by 9.
Probably not so hard to obtain but I'm a total noob with javascript here. I get this so far, but I should miss a crucial point!
Thanks for your help :)
function multiply() {
var string = document.getElementById("mult").value;
var array = string.split("*");
var res = Number(array[0]*array[1]);
document.getElementById("res").value = res;
}
input{width:80px; text-align:right;}
input[readonly]{border:0;}
entrer: <input type="text" id="mult" onblur="multiply()">
<br>result: <input type="text" id="res" readonly>
Your code actually works as it is now. Just make sure you tab out of the input field after typing in the equation and you'll see it do its job. That's because your code is running on the blur event, which is when the focus leaves an element.
But, as far as your conversion code goes:
Number(array[0]*array[1])
Attempts to convert the product of array[0] and array[1], when what you need is to convert each array value to a number first and then do the math.
Number(array[0]) * Number(array[1])
Now, instead of Number(), you can just prepend a + to each value that needs conversion.
+array[0] * +array[1]
But, in reality, anytime you attempt to do multiplication, division or subtraction on strings, they are automatically converted to numbers, so you really don't even need that here.
Lastly, since you are just displaying the result and don't want the user to be able to modify it, just put it into a regular element, like a span instead of a form field element that you then have to set to readonly. Form fields are primarily for collecting information, not displaying it. When you do work with a non-form field element, you don't use the value property, you use .textContent (when there is straight text) or .innerHTML (when the string contains HTML to be parsed).
function multiply() {
var string = document.getElementById("mult").value;
var array = string.split("*");
var res = array[0] * array[1];
document.getElementById("res").textContent = res;
}
input{width:80px; text-align:right;}
input[readonly]{border:0;}
entrer: <input type="text" id="mult" onblur="multiply()">
<br>result: <span id="res"></span>

Alternative in regular expression's ending

I have the following DOM structure:
<form>
<input type="text" id="a">
<button>Submit</button>
</form>
or:
<form>
<input type="text" id="a">
</form>
which one depends on what user have done, it's created dynamically.
I want to be able to add another input right below the previous one (it can not exist yet and be the first one). To do that, I wanna get all text until the place I'm adding new input. How can I get that text using regex?
I tried the following:
'(.*?)[<button.*?>Submit<\/button><\/form>|<\/form>]'
But it doesn't work, because it displays empty string as a result.
var afterRegex = new RegExp('(.*?)[<button.*?>Submit<\/button><\/form>|<\/form>]', 'i');
var appendAfter = $(".downloadCode textarea").val().match(afterRegex)[1];
alert(appendAfter);
I'm a little confused by your code, but, based on what you've said (and that you've tagged your question with jQuery), I think that you can accomplish what you are trying to do with this code:
var $newInput = **CREATE_YOUR_NEW_INPUT_ELEMENT_HERE**;
var $form = $("form");
var $lastInput = $form.find("input:last");
// no inputs, make the new input the first element in the form
if ($lastInput.length < 1) {
$form.prepend($newInput);
}
// at least on existing input, add the new input after the last one
else {
$lastInput.after($newInput);
}
You should not parse HTML using Regexp. No, seriously.
That being said, the correct syntax for multi-character alternatives is (?:alternativeA|alternativeB):
(.*?)(?:<button.*?>Submit<\/button><\/form>|<\/form>)
Note that this does not work if you have whitespace characters in between. Yet another reason not to use Regexps here.

Replace Word Within Word - Javascript

I need to get a id from a html element and replace a part of the word. For example:
HTML
<input type="checkbox" id="facebookCheckbox"></div>
JavaScript
var x = document.getElementById("facebookCheckbox");
var name = x.id;
name.replace("Checkbox","");
This obviously does not work because the replacing word has to be standalone for it to be replaced. Is there a different way of doing this?
I'm looking for purely javascript no jQuery
Thank you!
name.replace("Checkbox","");
This obviously does not work because the replacing word has to be standalone for it to be replaced.
No, it does work and there's no need to be "standalone" - any part of the string can be matched. Only you did nothing with the result of the operation:
console.log(name.replace("Checkbox",""));
// or
name = name.replace("Checkbox","");
// or assign back to x.id maybe?
You are creating a copy of string when replacing, so you must assign the result of .replace() back to x.id.
var x = document.getElementById("facebookCheckbox");
x.id = x.id.replace("Checkbox","");
this is not going to work in this way. However you can have a marker kind of character by which you can break the name into array and implement the logic. For example:
var x = document.getElementById("facebook_Checkbox");
//Note I have added underscore in the Id
var name = x.id;
var arr=name.split("_");
//Now you have Checkbox and Facebook as string objects (part of array) and you can use them
name=arr[0]
I hope it will solve the purpose.

Mystery code: +i+ and +x+

In the following code:
for (i=0; i<itemsinlist.length; i++) {
var rating = document.createElement('div');
itemsinlist[i].appendChild(rating);
rating.className = "rating";
rating.id = "thumbnails" +i;
for (x=0; x<4; x++) {
star = document.createElement('span');
star.innerHTML = "★";
star.className = "star";
star.setAttribute("onclick", "ratingsSet("+i+","+x+");");
rating.appendChild(star);
} //createratingsstars
I'm struggling to make sense of the second parameter to star.setAttribute(), in the line:
star.setAttribute("onclick", "ratingsSet("+i+","+x+");");
Specifically, I'm being thrown off by the +i+ and +x+.
At first I thought these were some kind of variation on the increment operator, but later decided it must be concatenating something, but I can't figure out what/how. The HTML that gets generated by the loop is:
<span class="star" onclick="ratingsSet(0,0);">*</span>
<span class="star" onclick="ratingsSet(0,1);">*</span>
<span class="star" onclick="ratingsSet(0,2);">*</span>
<span class="star" onclick="ratingsSet(0,3);">*</span>
But my reverse-engineering chops are failing me (if I had any to begin with).
Help?
It's string concatenation. i is the outer loop counter, and x is the inner loop counter. It appears to be iterating a collection and creating 4 spans per item.
It's putting together this string:
"ratingsSet(0,1);"
The value 0 is in the variable i, and the value 1 is in the variable x. If we add some spaces, it might be more clear:
"ratingsSet(" + i + "," + x + ");"
As far as I can tell it increments i and x and sets attribute on click for element that is:
"ratingsSet("+i+","+x+");"
Then after click ratingsSet("+i+","+x+"); with params is executed.
Weird way of doing it.
You can have more readable code:
star.onclick = function() {
ratingsSet(i, x);
};
Setting event handler as attribute breaks in older browsers plus not very elegant.
JavaScript allows you to concatenate strings and integers (and, AFAIK, the string representation of any object) with the plus operator. The resulting HTML (with its embedded JavaScript!) is just that: instantiations of calls to ratingsSet().
"+" is a infix operator that concatenate two strings.
Example : "mor"+"ning" will give the string "morning".
So it simply print the value of i or x to the HTML.
I have the same question, now i know i have made a funny mistake. You must read this statement in a wrong way like me. This second argument need a string, so "ratingsSet("+i+","+x+");" means
"ratingsSet("+i+","+x+"):"
so this argument will become a string. There are no +x+
:)

Categories

Resources