I am trying to write the values of checkboxes to local storage and then retrieve them. Setting the values works fine. However, when I try to access local storage it accesses it too many times and the number of times it accesses it increments each time the function is called. For example, the first time the function is called a single array is printed to the console. The second time 2 arrays are printed, the third time three arrays are printed and so on.
My subsequent code goes on to display the items from the array in an HTML list, therefore, having multiple arrays confuses it and duplicates the data
Any clue how I can prevent the array from being generated multiple times?
I have attempted to remove the for loop to see if that is the cause but this makes no difference. As far as I am aware it is a problem with the first part but I am not too sure where
$("#confirm-button").click(function(event){
event.preventDefault();
if (localStorage.length===0) {
createAlbum();
}
else if (localStorage.length>0) {
document.getElementById("confirmation").style.display="block";
$("#Yes").click(function(event){
event.preventDefault();
localStorage.clear();
createAlbum();
document.getElementById("confirmation").style.display="none";
})
$("#No").click(function(event){
event.preventDefault();
document.getElementById("confirmation").style.display="none";
})
}
});
function createAlbum(){
if ($("li input:checkbox:checked").length===0){
alert("You have not selected any songs. Please select at least one song")
}
else if ($("li input:checkbox:checked").length>0) {
var searchIDs = $("li input:checkbox:checked").map(function () {
return $(this).val();
}).get();
localStorage.setItem('searchIDs', JSON.stringify(searchIDs));
retrievedObject = localStorage.getItem('searchIDs');
var information = JSON.parse(retrievedObject);
console.log(information);
$('#overlay_text').append("<ol id='newList'></ol>");
for (var i = 0; i < information.length; i++) {
var item = document.createElement('li');
item.append(information[i]);
$('#newList').append(item);
}
}
}
HTML:
<div id="overlay">
<div id="overlay_text">
</div>
</div>
<div id="confirmation">
<div id="confirmation-text">
An album already exists are you sure you want to overwrite it?
<button id="Yes">Yes</button>
<button id="No">No</button>
</div>
</div>
EDIT
Included the code that calls the function. The first bit is to check if any values currently exist in local storage. If no values exist the function is called. If values do exist the user is then asked if they wish to overwrite this data. 'confirmation' is the window that displays the message about overwriting data to the user
I suspect your problem is a result of creating event listeners inside the handler of another event. This is a bad practice in general
Every time the confirm button is clicked you add a new listener to the Yes/No buttons and thus the event handlers for Yes/No are getting called multiple times (once for every time user clicks on confirm)
Move your Yes/No click listeners outside of $("#confirm-button").click or use off() before adding a new click
$("#Yes").off('click').on('click', function(event){...
This is happening because you are adding the events every time when a user clicks on the confirm-button try moving the functions $("#Yes").click(function(event) and $("#No").click(function(event) out of the $("#confirm-button").click(function(event).
In my html website I have a random number function:
<script>
var randomnumber=Math.floor(Math.random()*11)
document.getElementById("random").innerHTML = randomnumber;
</script>
I would like to add a "reload" button that changes the random number generated, without reloading the page. Is there any way to do this besides the location reload?
Whenever you are going to repeat a process, you should use functions.
Your calculation is right. You just need to put it inside a function and call it in case of clicking the button.
function changeRandom(){
var randomnumber=Math.floor(Math.random()*11)
document.getElementById("random").innerHTML = randomnumber;
}
changeRandom();
<div id="random">
</div>
<button onclick='changeRandom()'>Click</button>
I am programming a web frontend for a database application. I have several function calls in the html body, like:
<input type=button value="Set 1" id="btn1" onClick=edit_entry(this,"edit","title")>
<input type=button value="Set 2" id="btn2" onClick=edit_entry(this,"edit","name")>
<input type=button value="Set 3" id="btn3" onClick=edit_entry(this,"edit","gender")>
function edit_entry(src, action, arg1) {
alert(src.onclick);
src.onclick = function () { edit_entry( src, action, arg1 };
alert(src.onclick);
}
When clicked on "btn1", the first alert returns the hardcoded function definition: function onclick(event) { edit_entry(this,"edit","title") }
But the second alert returns the function definition with variables function onclick(event) { edit_entry(src, action, arg1) }
So when these variables change later the function does get the wrong values. How can I apply the content of the variables to the function definition instead of the variables itself so that the definition is again function onclick(event) { edit_entry(this,"edit","title") } ?
P.S.: I know that this code snippet makes no sense as it shall only describe my problem as simple as possible.
Here is my code I was referring to. I hope this all makes more sense now. Sorry for the inconvenience.
HTML Body:
<input type="button" value="Edit" id="group_1_button_edit" class="action_element" onClick=edit_entries(this,"edit","artnr","artalt","bez1","bez2","bez3")>
<input type="button" value="Edit" id="group_9_button_edit" class="action_element" onClick=edit_entries(this,"edit","dok1","dok2","dok3","dok4","dok5")>
The values behind "edit" are the IDs of the input textboxes the content will be read from.
function edit_entries(caller,action,opt1,opt2,opt3,opt4,opt5,opt6,opt7,opt8,opt9,opt10,opt11,opt12) {
caller_id = caller.id.split("_");
id = caller_id[1];
switch(action) {
case "edit":
//Making textboxes writeable for changing values
//[...]
document.getElementById("group_"+id+"_button_edit").value="Save";
document.getElementById("group_"+id+"_button_edit").onclick=function(){ edit_entries(this,"save",opt1,opt2,opt3,opt4,opt5,opt6,opt7,opt8,opt9,opt10,opt11,opt12); };
break;
case "save":
if (confirm("Datensatz wirklich aktualisieren?")) {
artnr_key = XML_OBJ.getElementsByTagName("artnr")[0].textContent;
string = "";
//Building the AJAX Request String: textbox id = value
url = 'mysql_req_n1.php?type=edit_entries&'+string;
send_request(url);
}
break;
}
}
//called by AJAX handler
function edit_entries_unlock() {
//Getting "id" by value check
counter_a = 1;
while (counter_a <= 9) {
if (document.getElementById("group_"+counter_a+"_button_edit").value == "Save") id = counter_a;
counter_a++;
}
//Getting textbox IDs located in the AJAX response
opts = XML_OBJ.getElementsByTagName("opts")[0].textContent;
options = opts.split(",");
//Making textboxes readonly again
//[...]
document.getElementById("group_"+id+"_button_edit").value="Edit";
document.getElementById("group_"+id+"_button_edit").onclick=function(){ edit_entries(this,"edit",options[0],options[1],options[2],options[3],options[4],options[5],options[6],options[7],options[8],options[9],options[10],options[11]); };
}
And that is what happens:
I click on the first button (group_1_button_edit). It jumps to the switch block "edit" making the textboxes writable and changing the edit button to a save button. Works fine.
I click on save. The switch block "save" builds the request string and starts the ajax request.
The ajax handler starts edit_entries_unlock() when the response is there. Part of the XML Response are the textbox IDs I have used before. The onclick function gets changed again to an "edit" function with the corresponding textbox IDs from the XML object.
Now I click on the second button "group_9_button_edit". Everything is working like mentioned above. No problems. The textboxes of group 9 unlock, get saved und locked again as wanted.
But now the bug: I click on the first button again "group_1_button_edit" which now uses the changed function definition. It starts the switch block "edit" but with the values of the textbox IDs of GROUP 9 (which I edited before) and not GROUP 1.
I guess it has something to do with the variables opt1-opt12. They always contain the values of the last "edit_entries_unlock()" run. And as all the edited function definitions uses opt1-opt12 as well they start with the values of the last run and not with the values I used when recreating the function definition.
For that reason I asked how to build a function definition with the content of variables during the function creation process instead of the content during the execution process.
I hope that makes a lot more sense now. Sorry for the wall of text.
This is a very bad way to pass data.
You should avoid using inline code
<input type=button value="Set 1" id="btn1" onClick=edit_entry(this,"edit","title")>
<input type=button value="Set 2" id="btn2" onClick=edit_entry(this,"edit","name")>
<input type=button value="Set 3" id="btn3" onClick=edit_entry(this,"edit","gender")>
Should be
<input type=button value="Set 1" id="btn1" data-field-name="title">
<input type=button value="Set 2" id="btn2" data-field-name="name">
<input type=button value="Set 3" id="btn3" data-field-name="gender">
<script>
(function(){ // or use on load event
// define the click function
var clickFunction = function(event){
// get the element data
var fieldName = event.target.attributes["data-field-name"].value;
// do what you need to do.....
}
// query the DOM to get the elements you are after.
var el = document.getElementsByTagName("input");
// iterate them and add the event handler to each.
for(var i = 0; i < el.length; i++){
el[i].addEventListener("click",clickFunction,false);
}
})();
</script>
As for what you are trying to do in the example you gave I have no clue so maybe this will help you.
You onclick handler creates a closure. So, the values src, action and arg1 in the below (from your edit_entry function) will be what it was at the time this function was created / recreated (the latter for when you click it the next time)
src.onclick = function () { edit_entry( src, action, arg1 };
You'd be able to modify these only within the same method (or it's child methods). Note that since you set the onclick to the above you are basically passing around the same variables into the handler the next time it is clicked.
Any changes you are seeing for these variables would be from within your onclick handler (and not external to it)
Finally with the help of T.J.Crowder I was able to fix the code.
The line that I needed to fix was
options = opts.split(",");
to
var options = opts.split(",");
I didn't know that declaring variables inside a function without var would make them a part of the window object and therefore making it a global variable. So my closure was accessing a global variable instead a local one.
One small word, but with big impact.
I wish to show out other objects when the onclick function is clicked. When i click that button, it will hide one object and show two other objects. I have already set the style.visibility to visible. But the show two object does not works.
Update Sample:
<input type="submit" id="show" name="show" value="show" onclick="RemoveDoc(); document.getElementById('docname').style.visibility='hidden'; document.getElementById('browse').style.visibility='visible'; return false;" />
//browse input
<input type ="file" name="browse" id="browse">
Method 2:
//Using my RemoveDoc() function, I want the button of browse being show out.
function RemoveDoc(Doc)
{
xmlhttp1=new XMLHttpRequest();
xmlhttp1.open("GET","functions/remove.php?Doc="+Doc,true);
xmlhttp1.onreadystatechange=function()
{
if (xmlhttp1.readyState==4 && xmlhttp1.status==200)
{
//when i run debugging, it says that the style of null..
document.getElementById("browse").style.visibility='visible';
}
}
xmlhttp1.send();
return false;
}
</script>
I tried two methods which both also cant show the browse button.
It should call out my visible on browse object as it's visible.. kindly advise.
http://jsfiddle.net/y3Bad/
A few things: you should include the visibility code inside of your removeDoc function, and bind the handler from javascript, not in markup. Also, your variable xmlhttp1 is an implicit global. Your removeDoc function takes a parameter, Doc, but you never pass anything to it. Finally, removeDoc makes an ajax call, which is asynchronous, so your line of code to show the browse button will not execute immediately, and may never execute at all if your ajax calls fails.
HTML:
<input type="button" id="show" name="show" value="show" />
JS:
document.getElementById('show').onclick = function () {
// use display instead of visibility if you don't want the hidden element to take up space
// setting visibility to empty string will show the element
document.getElementById('browse').style.visibility = '';
};
I use these two functions:
function hide(objId) {
document.getElementById(objId).style.display="none";
}
function show(objId) {
document.getElementById(objId).style.display="";
}
Maybe you can try to use jQuery, something like this:
http://jsfiddle.net/7fJuu/
I have a function that executes on page load. The function executes every 30 seconds using setTimeout. I want to be able to enable and disable setTimeout onclick I have the following code below...
<input id="vw" value="" type="hidden">
<a href="#" onclick="document.getElementById('vw').value='0';>click here</a>
<script>
/* JAVASCRIPT BELOW */
function mPb(){
var vw = escape(document.getElementById('vw').value);
if(vw == ''){//DO NOT SWITCH VIEW IF EMPTY
var sTo = setTimeout("mPb()", 30000);
} else {
clearTimeout(sTo);
}
}//END VIEW MY FEED
//ON SERVICE LOAD DISPLAY SHITE INSTEAD OF ONLOAD
window.addEventListener ?
window.addEventListener("load",mPb,false) :
window.attachEvent && window.attachEvent("onload",mPb);
</script>
Your code works if you properly close your onclick attribute with a double quote:
click here
Also, here go two little suggestions to improve your code:
If you're checking for an empty string inside your function, why setting the input value to 0 when you click the link? It works, but it would be more clear if you set the value to ''.
When using setTimeout (and setInterval), do not pass a string containing a function call. It works too, but it's dangerous. Use this instead:
var sTo = setTimeout(mPb, 30000);
sTo needs to go outside of the mPb function, that way you can reference it from you onclick.