Button event is only selecting the first class. (Jquery) - javascript

I am trying to select the saveBtn class on each button so that when I click it it saves it into local storage. However it is only saving the first instance of the selected class. Can anyone help?
html:
<div class="hour-container" id="8am">
<div class="hour"> 8 AM </div>
<textarea class="text-content"></textarea>
<button class="btn saveBtn"><i class="fas fa-save"></i></button>
</div>
js:
// Function to save the users input to the text area
function saveText() {
var textContent = $(".saveBtn").siblings(".text-content").val();
var hour = $(".saveBtn").parent().attr("id");
localStorage.setItem(hour, textContent);
console.log(textContent);
}
// Call saveText on save button click
$(".saveBtn").on("click", saveText);

In the event handler, the searching scope of $(".saveBtn") is the whole web page.
That means the reference point of all actions is referred to the beginning of the web page.
So, the function $(".saveBtn") always refer to the first element which has the saveBtn CSS class.
You may modify the saveText function as the following:
function saveText() {
var textContent = $(this).siblings(".text-content").val();
var hour = $(this).parent().attr("id");
localStorage.setItem(hour, textContent);
console.log(hour,textContent);
}
For my solution, the this refers to the element which has been clicked by a user, so the reference point of all actions is referred to the element which has been clicked, therefore it should be work fine.

Related

Javascript Generating Text into Textbox?

I wrote this little bit of code but I'm not sure why it's not working? It's supposed to take in the persons name and depending on what they selected it will output a website with their name at the end of it.
JSFiddle
http://jsfiddle.net/tQyvp/135/
JavaScript
function generateDynamicSignature() {
var dynSig = "";
var user = document.getElementById("usernameInput");
var e = document.getElementById("scriptListInput");
var strUser = e.options[e.selectedIndex].text;
if (strUser == "example") {
dynSig = "http://example.com/users/";
}
document.getElementById("generateSignature").addEventListener('click', function () {
var text = document.getElementById('dynamicSignatureOutput');
text.text = (dynSig + user);
});
}
HTML
<select class="form-control" id="scriptListInput">
<option value="example">Example 1</option>
</select>
There are a few problems with your code, I'll try to list them all.
First, you never added the username input to your HTML.
Next, you seem mixed up on the way to access/set the text of an HTML input. You do this through the value field. For the username input, you forgot to access any property, so you'll need to change it to:
var user = document.getElementById("usernameInput").value;
You later used the text property of both the select element and the output. These should also both be value.
Another problem is that you've placed a listener inside a listener. Your outer function, generateDynamicSignature, listens for the onclick event of the button. This function only runs after the button is clicked. But inside this function, you attach a new listener. This inner listener will only run if someone clicks the button twice.
I've included these changes in a new fiddle:
https://jsfiddle.net/zdfnk77u/
where is usernameInput in your html?
in the if, use === instead of ==
If and when you add the missing "usernameInput" element in your HTML, all you'll have to do is...
dynSig='http://example.com/users/'+usernameInput.value;
I think part of the problem is that you want to access the value and not the text of input elements. So for text and strUser, you want to do text.value instead of text.text and such.
Also, based on the JSfiddle, you probably want to rewrite how you're using the document listener and the onclick of the html element. Every time the button is clicked it goes through the generateDynamicSignature and creates a listener to change the value, but doesn't necessarily change the value itself. If you move the logic of the generate function inside the click listener, that should fix most of your problems.
You create your generateDynamicSignature inside $(document).ready.
There are two approaches.
define function generateDynamicSignature outside
$(document).ready
or
bind your button.click to a handler inside $(document).ready
Do not mix these two.

How to apply a click function, that changes the clicked div, to new div elements that are created

At the moment I am using the following code which on the click of an HTML div element, changes the inner text to "Hello World":
<div id = "one" onclick = "click('one')" >text</div>
<script>
function click(id){
document.getElementById(id).innerHTML = "Hello World";
}
</script>
This works as expected and changes the content of the div to "Hello World".
The problem I am facing is at the moment I am using the id as a parameter input for the function and so that also means that for each div element that I create I would have to manually write its id within the onclick function.
I am able to create div elements using the following script which takes a value from an HTML input box, turns into a number then uses that number in a for loop to create as many div elements as specified:
<script>
function numberOfDivs(){
var divValue = parseInt(document.getElementById("inputbox").value, 10);
for(var i = 1; i < divValue + 1; i++){
var newDiv = document.createElement("div");
var divText = document.createTextNode("text")
//newDiv.setAttribute("onclick", "click()");
newDiv.appendChild(divText);
var whatIAmAppendingTo = document.getElementById("one");
whatIAmAppendingTo.appendChild(newDiv);
}
</script>
Now the problem that I having is applying that click() function to any of the new div elements that have just been created so that the click() function only affects the div that I have clicked on. I have included the setAttribute line when I create the new div elements so there is no problem linking it to the click() function.
I believe that there are two options:
-Either create new code within the numberOfDivs() function and use the var i to create an id that would be different for each new div element that I create, since var i increases to a different value each time the for loop repeats.
or
-Rewrite the click() function so that instead of having to use an id paramater I can instead make the function applicable to all div's. I was roughly thinking along the lines of using the 'this' keyword within that code, or anything along those lines so that it applies to only the div element that I click on.
With both of these possible solutions I'm not quite sure how to execute them so it would be great help if someone would be able to give me an example how it works.
Any questions or clarifications feel free to ask.
The problem I am facing is at the moment I am having to use the id as a parameter input for the function ...
No, you don't; you can pass this into your function, which is a reference to the div the click occurred on:
<div id = "one" onclick = click(this) >text</div>
Then in your function, use that argument rather than document.getElementById(id):
function click(div){
div.innerHTML = "Hello World";
}
Now you can use the same function for multiple divs.
Note, though, that if you're creating the divs programmatically, there's a better answer than setting the onclick attribute: addEventListener (attachEvent on older versions of IE). In your function creating divs:
var newDiv = document.createElement("div");
var divText = document.createTextNode("text")
if (newDiv.addEventListener) {
newDiv.addEventListener("click", click, false);
}
else {
newDiv.attachEvent("onclick", click);
}
Within click, use this:
function click(){
this.innerHTML = "Hello World";
}
typo in innerHTML and onClick
text
<script>
function click(id){
document.getElementById(id).innerHTML = "Hello World";
}
</script>
and
<div id = "one" onClick ="click('one')" >text</div>
Could this idea be helpful? Create your divs as (example for id='one'):
<div class='mydivs' id='one' ></div>
And then, detect the click on the div using a class and one event handler using JQuery:
$(".mydivs").click( function() {
id = $(this).attr('id');
click(id);
});
<div id="one">
<!-- dynamically added child nodes -->
</div>
<script>
$.ready(function(){
$('#one').children().livequery('click', function(event){
this.innerHTML = "Hello world";
});
});
<script>
Here we can use livequery to add click handlers to child elements that will be added dynamically.
if you provide your newly created divs with a common class e.g. clickable you could do this
$function(){
//Any click event of the body element that originates from a ".clickable"
//will be handled by the provided handler
$("body").on("click",".clickable",function(){
$(this).html("Hello world");
});
//... anything else that has to happen on document ready
});

Double insert after is permitted, but before doesnt

The following html markup
<div id="parent" class="parent">
<div id="child" class="child">
<input type="text" class="text"/>
<input id="submit" value="submit" type="submit" onclick="doThis()"/>
</div>
<div>
and JS code
function doThis(){
var span= document.createElement("span");
var parent=document.getElementById("parent");
var child=document.getElementById("child");
var submit=document.getElementById("submit");
child.insertBefore(span,submit.nextSibling);
myKeys=[];
myKeys.push(getAllKeyValuePair(submit));
span.innerHTML=myKeys;
}
function getAllKeyValuePair(obj){
var str="";
for(var key in obj){
try{
str=str+"{"+key+", "+obj[key]+"}";
}
catch(e){
console.log(key);
}
}
return str;
}
JSFIDDLE example.
It works fine and it's ok to click 2,3,...etcetera times on submit button, to click on duplcate of submit button... etc. But if we trying to replace child.insertBefore(span,submit.nextSibling); to child.insertBefore(span,submit); (i.e. insert span before submit button rather than after) we can only 1 time to click to submit button. Consequent clicks will caused exception. JSFIDDLE
The question obviously is why in the case of inserting before submit second and consequent clicks will causes exception, but in the case of insert after submit it's work fine. I think, that the reason of duplicating the submit button is not true.
When you do:
span.innerHTML = myKeys;
you're creating another element with id="submit". The next time you click the button,
var submit = document.getElementById("submit");
assigns this element to the variable, rather than the one in the original HTML. This element is not a child of child, so you get an error.
The version with nextSibling also creates these duplicate IDs, but the original submit element is earlier in the DOM than the added elements, so it gets returned by getElementById and you don't get an error. I don't think there's any guarantee that this will work, since duplicate IDs aren't permitted, but it's how most browsers work.
If you don't want the string returned by getAllKeyValuePairs to be parsed as HTML, assign it to span.innerText rather than span.innerHTML.

If I hide a text input element with javascript can other javascript functions still access a value entered into it?

I am trying to use this function:
function storagecalc(){
var thediv=document.forms["boxes"];
var boxno=thediv.elements["numbofboxes"];
var howmany =0; //If the textbox is not blank */
if(boxno.value!="")
{
howmany=parseInt(quantity.value);
}
return howmany;
document.getElementById('numberprice').innerHTML = "£"+howmany;
}
To grab a value entered here:
<form action="" id="boxes">
<input type="text" id="numbofboxes" value="" name="boxnumber"/>
<button id="smtbxno" onclick="storagecalc">
<img src="images/tick.gif" alt="proceed"/>
</button>
</form>
and display it here:
<div id="grandtotal">
<p class="calctitles">
Grand Total
</p>
<p id="numberprice">
</p>
</div>
Nothing is happening when I enter a value into the textbox and click the button, is this because the button also has jQuery that hides itself and the text box upon clicking?
If not any suggestions for why it won't work?
If I hide a text input element with javascript, can other javascript functions still access a value entered into it?
Every piece of javascript that can obtain a reference to the input element (via a variable, with a DOM selector) can access its value. The visibility of that element has no effect on any of those actions. Only if you would detach it from the DOM, other functions could not select it with DOM methods.
OK, there are some errors in the document you gave us:
<button onclick="storagecalc"> does not execute anything, you will need to call the function: <button onclick="storagecalc();">. Only when assigning a listener to the onclick property with js, the function object needs to be used (document.getElementById("smtbxno").onclick = storagecalc;).
In the function itself, you use a variable quantity which is undefined (and throws an exception). I'm not sure how to fix that.
You are assigning the function but not calling it:
<button id="smtbxno" onclick="storagecalc()" ... >...</button>
------------------------------------------^
Also, members of the form's elements collection should be referenced by name, not by id.
var boxno=thediv.elements["boxnumber"];
I don't understand why you have a different name and ID, that will confuse IE which, in older versions at least, doesn't know the difference.

Why are only some attributes updated from my javascript function?

I have a button script to change the buttons in a frame based on the page loaded in the main frame. The problem I'm experiencing is that while the background images, tabindex and text on the button (innerHTML) all change as expected, the onclick doesn't. It appears to completely ignore it. Here's the script I'm using:
function createbutton(btn_N, btn_I, btn_L, btn_D) // (Div Name, Tab Index, Button Text, Page To Load){
var btnN = top.frames['buttonbar'].document.getElementById(btn_N);
btnN.style.cssText = "display:block; cursor:pointer; padding-left:16px; padding-top:5px;";
btnN.onmouseover = function() {this.style.backgroundImage = "url('./osdimages/navBG_roll.png')";};
btnN.onmouseout = function() {this.style.backgroundImage = '';};
btnN.tabindex = btn_I;
btnN.innerHTML = btn_L;
btnN.onclick = btn_D;
}
The button call looks like this:
createbutton("button01", 1, "New Order/Browse", "parent.frames['content'].location.href='createorder/createorder.asp';");
There is a difference between attributes and properties.
The best example of this is as follows:
HTML: <input type="text" value="hello" id="test" />
Type something in the text box
document.getElementById('test').value is whatever you typed
document.getElementById('test').getAttribute("value") is whatever was in the HTML
Some attributes are directly mapped to properties and vice versa, but this is not always the case.
For instance, the onClick attribute takes a string that is then eval'd, but the onclick property takes a function. This is why your code isn't working.
Either pass a valid function, or use setAttribute.
You are setting onclick with a string, it needs a function to execute.
createbutton("button01", 1, "New Order/Browse", function(){ parent.frames['content'].location.href='createorder/createorder.asp'; });

Categories