Have such button on my page (for showing current total in shopping cart):
<div class="col s2 offset-s4 valign" id="shoppingCart">
<a class="waves-effect waves-teal btn-flat no-margin white-text right" th:inline="text"><i class="material-icons right">shopping_cart</i>[[#{${total}+' руб'}]]</a>
</div>
Written function for updating total number on that button:
function updateShoppingCart(newTotal) {
var $div = $("#shoppingCart");
var $a = $("<a class='waves-effect waves-teal btn-flat no-margin white-text right'></a>");
var $i = $("<i class='material-icons right'>shopping_cart</i>");
var $string = formatDecimal(newTotal,',','.') + " руб";
$a.append($i);
$a.append($string);
$div.children().remove();
$div.append($a);
}
But it does not work. Please help find bug or what I'm doing wrong.
It's a lot more efficient to set $div = $('#shoppingCart');; in the global scope and use that var instead. This way your JS won't search through your entire DOM every time the function is called.
Your stuff doesn't work because your vars are very odd. I believe what you want to achieve is this:
HTML
<a class="waves-effect waves-teal btn-flat no-margin white-text right" th:inline="text">
<i class="material-icons right">shopping_cart</i>
<span>[[#{${total}+' руб'}]]</span>
</a>
JS:
function updateShoppingCart(newTotal) {
var $div = $("#shoppingCart");
var $a = $("a", $div); //select the <a> within the shoppingcart div
var $i = $("i", $div); //select the <i> within the shoppingcart div
var $span = $("span", $div); //select the newly added span
var newPrice = formatDecimal(newTotal,',','.') + " руб";
$span.text(newPrice);
}
I kept the $a and $i in as examples, but I don't see a need for you to use them or completely replace them, since you only want to change the text. By using a span, you can target the price without replacing all the html.
On a sidenote, the $ is generally used to state a var is a jquery object. string is not a jquery object in this scenario, so the $ there is a bit odd.
On a sidenote, if you want to replace html within an element, you should try doing it like so:
function updateShoppingCart(newTotal) {
var $div = $("#shoppingCart");
var newPrice = formatDecimal(newTotal,',','.') + " руб";
//Create the new HTML as a string, not as an element
var newHtml= '<i>Shopping_cart</i>'+newPrice+'';
//empties div beforehand current html, no seperate removal needed.
//Then places the html string within the element
$div .html(newHtml);
}
See working JSFiddle here
Related
I am trying to append an Icon to a button, the challenge that I am facing at the moment is that the icon retuns as a string (I see the code I wrote for the Icon).
I've tried changing qoutations marks, I've also tried putting the Icon tag inside a span and a div but it hasn't helped.
HTML code that displays the icon and carries the value the determines the icon
<button type="button" id="btnState" name="btnState" class="btn btn-primary btnState" value="<?php echo $pref; ?>"><?php echo "<span class='spnDash'>".$pref."</span>";?></button>
The code the loops though the results and selects the icon that will be displayed
var status = document.getElementsByClassName('btnState');
var i;
for(i =0; i < status.length; i++){
var j = status[i].value;
if(j === 1){
$(".spnDash").remove();
//$("<i class='far fa-thumbs-down'></i>").appendTo(".btnState");
status[i].append('<i class="far fa-thumbs-up"></i>');
}
The Jquery code scans/checks for a value(1/0/-1) delivered from a server and then assigns an icon according to the value e.g. 1 = thumbs up, -1 = thumbs down, 0 = neutral.
status is a DOM Collection object. You're trying to append a string to a object. Hence you're getting a string output.
You can use:
status[i].innerHTML+="<i class='far fa-thumbs-up'></i>";
Or, if you want to use append(), you have to create a DOM object and do as follows:
var obj = document.createElement("i");
obj.classList = "far fa-thumbs-up";
status[i].append(obj);
try using document.getElementById('btnState') and try not to use name attribute
I'm having a strange problem. I'm trying to make a program that will add and delete div's inside another div called "body". To add divs, I use document.getElementById("body").innerHTML. Adding works fine. However, in the deleting function, I replace the "body" id with a variable with the id of the div that will be deleted. But when I run the code, I get the error "cannot set innerHTML of null". I tried to replace the id variable with a fixed local variable, and it worked fine. I also tried to add quotes to the variable but that didn't work either. Is there any reason why I can't set the id to a changing variable? Thanks.
Here is my code:
var i = 1;
function myFunction() {
var addDiv = document.getElementById("body2");
addDiv.innerHTML += "<div id = '" + i + "'><br><textarea id = '1' > foo < /textarea></div > ";
i++;
}
function myFunction2() {
var deleteDiv = document.getElementById(i);
deleteDiv.innerHTML = "";
i--;
}
<div id="body2">
<div id="0">
<textarea id="text">lol</textarea><button onclick="myFunction()">Add</button>
<button onclick="myFunction2()">Delete</button>
</div>
</div>
you are incrementing i after adding a div so you must use i-1 while deleting to get correct id.
var i = 1;
function myFunction() {
var addDiv = document.getElementById("body2");
addDiv.innerHTML += "<div id = '"+i+"'><br><textarea id = '1'>foo</textarea></div>";
i++;
}
function myFunction2() {
var deleteDiv = document.getElementById(i-1);
deleteDiv.remove();
i--;
}
<div id = "body2">
<div id = "0">
<textarea id = "text">lol</textarea><button onclick =
"myFunction()">Add</button>
<button onclick = "myFunction2()">Delete</button>
</div>
</div>
To remove last child, you can even use CSS selector last-child. You should also add specific class to newly added divs as you would want to remove only newly added divs.
This will also remove dependency of i.
As an addon, you can also use document.createElement + Node.appendChild instead of setting innerHTML. .innerHTMl will be expensive for highly nested structure.
function myFunction() {
document.getElementById("body2").appendChild(getDiv());
}
function getDiv(i){
var div = document.createElement('div');
div.classList.add('inner')
var ta = document.createElement('textarea');
ta.textContent = 'foo';
div.appendChild(ta);
return div;
}
function myFunction2() {
var div = document.querySelector('#body2 div.inner:last-child')
div && div.remove()
}
<div id="body2">
<div id="0">
<textarea id="text">lol</textarea><button onclick="myFunction()">Add</button>
<button onclick="myFunction2()">Delete</button>
</div>
</div>
You can refer "innerHTML += ..." vs "appendChild(txtNode)" for more information.
I am trying to target an id element using a variable in jquery, like so:
var liked_artist = $('#js-helper-liked-artist').val();
var artist_id = $('#js-helper-artist-id').val();
var target = '#individual' + artist_id + '';
$(target).addClass('individual-heart-hover');
However, this is not targeting the id it should correctly. Any ideas? I've tried it without the empty string at the end as well.
EDIT:
HTML:
<i class="fa fa-heart fa-stack-1x individual-heart" id="individual-{{$artist->id}}"></i>
individual-{{$artist->id}} renders as individual-8
and artist_id is 8 (console.log shows this).
Shouldn't it be var target = '#individual-' + artist_id + '';? Unless it's a typo in your post, I think you are missing the dash.
did you enclose your code in the document ready function?
$(document).ready(function() {
// ....
});
I have several divs that use bootstrap Grid system to allow users of the site to "zoom" content.
In this example with the class="abcd b1 col-lg-6" everything works fine.
But then I have my b1 part of the classes.. it will go up beyond b10, which makes my code no longer work.
I have tried to change the code so it would read from right to left... but then when the col-lg-6 becomes col-lg-10 it no longer works either.
So my question: is there a better way to .slice the code so it will work even when my classes length changes?
<div id="col" class="abcd b1 col-lg-6"> //the div
<div class="tn bg1">
<div class="ca">
<div class="bp">
<button type="button" id="plus" class="btn" data-toggle="tooltip" data-placement="left" title="Bigger Size"></button> //the button
<button type="button" id="minus" class="btn" data-toggle="tooltip" data-placement="left" title="Smaller Size"></button>
</div>
</div><!--ca-->
</div><!--tn-->
</div><!--col-->
<!--Plus Button-->
var className = ('col-lg-'); //make className = "col-lg-"
$('button#plus').click(function() { //find button#plus and add clickfunction on it.
$this = $(this).closest('div#col'); //find the div that shall change on click, closest div with id=col
var counter = $this.attr('class').split(className)[1]; //get the last section of the class. class "col-lg-6" will set the counter to = 6
var classList = $($this).attr('class').split(/\s+/); //get all the classes of that div, in an objekt array stored in "classList3"
var classString = classList.toString(); //make that objekt array into a string. classstring = "abcd,b1,col-lg-6"
var oldClass = classString.slice(8); //slice out the part i want. oldClass = "col-lg-6"
var nextNum = 1;
if (counter != '') //if the counter has already started
nextNum = parseInt(counter) + 2; //add +2 on click
if (counter < 12) { //if counter are less then 12
$this.removeClass(oldClass).addClass(className + nextNum); //Remove class "col-lg-6" (or what ever the number are at the moment)
}
else { //if counter are bigger or = 12
//do nothing
}
})
I found a way to fix it :)
First i add the variable:
var otherClasses = $this.attr('class').split(className)[0];
This variable store the other classes " abcd b1 ", not the " col-lg-6 "
Then i changed this:
$this.removeClass(oldClass).addClass(className + nextNum);
To this:
$this.removeClass().addClass(otherClasses + className + nextNum);
This will remove all the classes and then add the old ones + the new one back.
And remove this completly, there are no need for it anymore.
var classList = $($this).attr('class').split(/\s+/);
var classString = classList.toString();
var oldClass = classString.slice(8);
I want my code to instead of creating two texts with my newly created span, i want it to say"Some text x2" and then x3 and so on.
Heres my code
<div>
<li id="myLi">
Some text (This is where i want my other text to be instead)
</li>
</div>
<td class="add" onmousedown="myFunction()">Add</td>
When i click the td, it adds to the li but when i click several times it just comes more text. I want it to say "Some text x2" instead.
function myFunction() {
var proc = document.createElement("SPAN");
var t = document.createTextNode("Some new text.");
proc.appendChild(t);
document.getElementById("myLi").appendChild(proc);
}
Thanks
As Mike said, you can do this with an innerHTML.
If I understand, what you want is :
var i =0;
function doStuff(){
var proc = "<span> my text instead x"+i + "</span>" ;
document.getElementById("myLi").innerHTML = proc;
i++;
}
<div>
<li id="myLi">
<p> something </p>
</li>
<div>
<button onclick="doStuff()"> CLICK ME </button>
How about this piece?
var globalCounter = 1;
function myFunction(){
var current = document.getElementById("myLi");
current.innerHTML = "Some Text x"+globalCounter;
globalCounter++;
}
http://jsbin.com/munukadama/edit?html,js,output
Note you will be using global counter. If you want to avoid global conflicts, either come up with unique variable name, or encapsulate within a class as a private variable (see below).
function MyClass(){
var counter = 1;
this.update = function(){
var current = document.getElementById("myLi");
current.innerHTML = "Some Text x"+counter;
counter++;
};
}
var myInstance = new MyClass();
And then button will become:
<button onClick="myInstance.update()">Click me for Class!</button>
Here is a jQuery solution & a jsfiddle to test it out with:
HTML:
<ul>
<li id="myLi">
Some text (This is where i want my other text to be instead)
</li>
</ul>
Add
JavaScript:
function myFunction() {
$('#myLi').html('<span>Some new text.</span>');
}
$('.add').on('click', myFunction);