I thought this was going to be a bit easier to do, but I have spent a good 2 hours on it, without being able to figure it out.
I have this output:
<div class="cart-contents">
Your shopping cart is empty
</div>
and I am dynamically creating about 5 spans with JS:
function outputValue(value){
//output.innerHTML = output.innerHTML + value;
output.innerHTML += "<br>" + "<span>" + value + "</span>";
}
so my last span div is a total. I created a CSS class of .total to change a few styles, I tried few things like output.classList.addClass(.total);
How can I dynamically add a class to just the last span?
this would be my output:
var output = document.querySelector(".cart-contents");
var total;
function outputValue(value){
//output.innerHTML = output.innerHTML + value;
output.innerHTML += "<br>" + "<span>" + value + "</span>";
}
<div class="cart-contents">
Your shopping cart is empty
//<span>would go here</span>
//<span>would go here</span>
//<span>would go here</span>
//<span>would go here</span>
//<span class="total">would go here</span>
</div>
To target the last span and add the class with javascript, you'd use a selector, like span:last-child, that gets the last span inside output, and then you'd use classList.add().
There is no addClass(), that's a jQuery method.
output.querySelector('span:last-child').classList.add('total')
FIDDLE
Not a fix for the problem, but this removes the problem:
You can do this in pure CSS, using the last-of-type selector. This is the best solution IMHO.
https://developer.mozilla.org/nl/docs/Web/CSS/:last-of-type
https://developer.mozilla.org/en-US/docs/Web/CSS/%3Alast-child
Codepen example: http://codepen.io/anon/pen/gMOXqK
Since this doesn't even need JavaScript, and only uses CSS without complicated selectors, this seems like the best solution.
Possible fixes for your problem:
Your addClassList syntax is incorrect.
See: https://developer.mozilla.org/en-US/docs/Web/API/Element/classList
output.classList.add("total");
This is the correct addClass syntax.
Is there any reason why you would add the class with JavaScript, instead of adding it instantly? If you would pass an (optional) class parameter, you could pass the class when adding the totals (assuming you know when you're adding the totals).
function outputValue(value){
outputValue(value,"");
}
function outputValue(value, class){
output.innerHTML += "<br>" + "<span class='" + class + "'>" + value + "</span>";
}
Related
I have a list of elements. However, the length of this list varies between trials. For example, sometimes there are 6 elements and sometimes there are 8. The exact number is detailed in an external metadata.
To display this variable list, I've written:
var html = '';
html += '<div id="button' + ind + '" class="buttons">';
html += '<p>' + name + '</p></div>';
display_element.innerHTML = html;
If I were to 'inspect' the elements in my browser, they would appear to have IDs of button0.buttons, button1.buttons, etc.
Now I am trying to attach event listeners to each element but my code is not working so far. Different forms of broken code below:
document.getElementById("button' + ind + '").addEventListener("click", foo);
$("#button' + ind + '").click(foo);
document.getElementById("button").addEventListener("click", foo);
$("#button").click(foo);
Any help would be very appreciated! Thanks.
You wrong at concat string update it as
document.getElementById("button" + ind).addEventListener("click", foo);
var html = '';
var ind = 1;
var display_element = document.getElementById("test");
html += '<div id="button' + ind + '" class="buttons">';
html += '<p>' + name + '</p></div>';
display_element.innerHTML = html;
document.getElementById("button" + ind).addEventListener("click", foo);
function foo(){
alert('click');
}
<div id="test"></div>
Use "document.getElementsByClassName" get all botton elements then foreach to add click function.
document.getElementsByClassName('buttons').map( element => { element.addEventListener("click", foo) })
To answer the question of why neither of those uses of document.getElementById() are working for you, you are mixing your quotes incorrectly. "button' + ind '" evaluates to exactly that, rather than evaluating to "button0", "button1", etc. To make your code more readable, and to avoid similar quote mixing issues, I would recommend looking into template literals https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
With modern JS if you want to execute the same function you won't require to add an id to each button.
Just use the class added to the buttons like this:
document.querySelectorAll('.buttons').forEach(button => {
button.addEventListener('click',foo);
});
Then use the event parameter in that function to get the target node & execute whatever you want. You can also add data attributes in those buttons to use while executing that function.
Our application is been internationalized and being changed to different languages. For that reason we have to hard code all the messages. How can we do that for messages in javascript ?
This is how we are doing in html messages.
<span th:text="#{listTable.deletedFromTable}">deleted</span>
How do we hard code for javascript messages.(update the table)
$('#TableUpdate-notification').html('<div class="alert"><p>Update the Table.</p></div>');
You will need to put the messages in the DOM from the start, but without displaying them. Put these texts in span tags each with a unique id and the th:text attribute -- you could add them at the end of your document:
<span id="alertUpdateTable" th:text="#{listTable.updateTable}"
style="display:none">Update the Table.</span>
This will ensure that your internationalisation module will do its magic also on this element, and the text will be translated, even though it is not displayed.
Then at the moment you want to use that alert, get that hidden text and inject it where you need it:
$('#TableUpdate-notification').html(
'<div class="alert"><p>' + $('#alertUpdateTable').html() + '</p></div>');
You asked for another variant of this, where you currently have:
$successSpan.html(tableItemCount + " item was deleted from the table.", 2000);
You would then add this content again as a non-displayed span with a placeholder for the count:
<span id="alertTableItemDeleted" th:text="#{listTable.itemDeleted}"
style="display:none">{1} item(s) were deleted from the table.</span>
You should make sure that your translations also use the placeholder.
Then use it as follows, replacing the placeholder at run-time:
$successSpan.html($('#alertTableItemDeleted').html().replace('{1}', tableItemCount));
You could make a function to deal with the replacement of such placeholders:
function getMsg(id) {
var txt = $('#' + id).html();
for (var i = 1; i < arguments.length; i++) {
txt = txt.replace('{' + i + '}', arguments[i]);
}
return txt;
}
And then the two examples would be written as follows:
$('#TableUpdate-notification').html(
'<div class="alert"><p>' + getMsg('alertUpdateTable') + '</p></div>');
$successSpan.html(getMsg('alertTableItemDeleted', tableItemCount));
You may have seen the input box with success tick glythicon.
I'm trying to make a form where the input box is normal (not green and no tick showing) and upon successful validation in JavaScript, I want it to change to to the green border and display the glythicon tick. I think that adding the class is the way to do it and I can't quite get it working.
I tried to use the following for adding a class:
document.getElementById('id').className.add('addditional classes');
But I can't figure out the correct syntax to get this code to work.
function validateName() {
var name = document.getElementById("first_name").value;
if(name.match(/^[A-Za-z]*\s{0}$/)){
document.getElementById('firstcheck').classform-group, has-feedback.add(' has-success');
document.getElementById('firstcheck2').classglythicon, glythicon-ok.add(' form-control-feedback');
}
HTML code
<div id="firstcheck" class="form-group has-feedback">
<input onblur="validateName()" id="first_name" type="text" class="form-control" id="inputSuccess2" aria-describedby="inputSuccess2Status">
<span id="firstcheck2" class="glyphicon glythicon-ok" aria-hidden="true"></span>
</div>
Any help would be appreciated!!!
Please always check your code carefully after copy+paste.
The placement of quotation marks is important, as is placement of dots
And this is jquery code:
$('id').addClass('addditional classes');
Try this instead:
function validateName() {
var name = document.getElementById("first_name").value;
if(name.match(/^[A-Za-z]*\s{0}$/)){
document.getElementById('firstcheck').className += 'form-group has-feedback has-success';
document.getElementById('firstcheck2').className += 'glythicon glythicon-ok form-control-feedback';
}
Also dont include , in the classnames string
Try to add the class this way:
//first get the element
var elem = document.getElementById("id");
//append new classes to your existing class
elem.className = elem.className + " additional classes";
//apply the same login in your remaining code
if(name.match(/^[A-Za-z]*\s{0}$/)){
elem = document.getElementById('firstcheck');
elem.className = elem.className + " has-success";
elem = document.getElementById('firstcheck2');
elem.className = elem.className + " form-control-feedback";
}
OR
You can easily achieve this with jquery like this:
$('id').addClass('additional-classes');
Since Bootstrap's JS needs jQuery you can make your life a bit easer here. I've created a small example https://jsfiddle.net/eg8dsgh2/. Just use jQuery's addClass()
Hope it helps
document.getElementById('firstcheck').classform-group, has-feedback.add(' has-success');
Is this invented? Where do you see something like this'
To add a class use className.
document.querySelector('#firstcheck').className += " has-success";
I'm making a code of a online delivery webpage, and I having a hard time trying to figure out how to output the total of the list ordered by the user.
function ListOrder(){
document.getElementById('order').innerHTML += "<div id=\"YourOrders\">" + + document.getElementById('FoodName').value + document.getElementById('quantity').value + document.getElementById('Totality').value + "</div><br>";}
Edited: I want to know how I can get the sum of the total price. So, I placed a parseInt between the document.getElementById('Totality').value . It looks like this now,
function ListOrder(){
document.getElementById('order').innerHTML += "<div id=\"YourOrders\">" + + document.getElementById('FoodName').value + document.getElementById('quantity').value + parseInt(document.getElementById('Totality').value) + "</div><br>";}
Can someone help me make a function or something for that? Javascript only, please. I'm still kinda new at it.
function ListOrder(){
document.getElementById('order').innerHTML +=
"<div id=\"YourOrders\">" +
parseInt(document.getElementById('FoodName').value) +
parseInt(document.getElementById('quantity').value) +
parseInt(document.getElementById('Totality').value) +
"</div><br>";
}
the kernel of your code should look like the following (double + operator deleted, reformatted):
function ListOrder(){
document.getElementById('order').innerHTML +=
"<div id=\"YourOrders\">" + (
document.getElementById('FoodName').value
+ document.getElementById('quantity').value
+ document.getElementById('Totality').value
)
+ "</div><br>"
;
}
You've phrased your question in a way that suggests you wish to output an order list assembled from the content of all (html) elements with certain ids.
this won't work reliably:
Ids should be document unique.
The Js functions you use do not iterate over lists.
instead, proceed along the following lines (which assume that you import jquery, a cross-browser dom-handling and ajax library (which you should use anyway :)):
function ListOrder(){
var e_orders = $("<div id=\"YourOrders\">");
$("#order").append(e_orders);
$(".FoodName").each ( function ( idx_fn, e_fn ) {
$(e_orders).append(
$("<div/>").append(
$(e_fn).val()
+ $(e_fn).nextAll('.quantity').val()
+ $(e_fn).nextAll('.Totality').val()
);
);
$(e_orders).append("<br>");
});
return e_orders;
}
The code template assumes that the source data are elements with value attributes being marked with css classes quantity, Totality and 'FoodName``, that these elements are siblings and unique within a container element for each item incl. quantity information. It should be flexible enough to be tailored to your actual needs and html structure.
I've got this shopping cart script that I'm trying to revise. Trouble is, whenever I try to delete more than one item from the cart, I get a negative value. The cart never goes back to zero when all items are deleted. I can add items fine.
Here is the fiddle.
Below is a code snippet of this feature. The full code is in the fiddle as it is easier to explain by showing you a demo of the problem I am having.
function addToCart(id, container_id, corTitle, corPrice, credit_hrs) {
var amount = parseFloat(corPrice);
var hours = parseFloat(credit_hrs);
var remove = "<button type=\"button\" class=\"remove\"></button>";
var selected_product = "<div class=\"item \">"
+ "<div class=\"title\">"
+"<div class=\"remove\"><button type=\"button\" title=\"remove from cart\" class=\"remove-from-cart\" alt=\"Remove Course\" ></button></div>"
+ corTitle
+ " for $" + corPrice
+ "</div>"
+ "<input name=\"containerId\" value=\"" + container_id
+ "\" type=\"hidden\">" + "</div>";
$(selected_product).insertBefore("#subtotals");
register("add", amount, hours);
$(".remove-from-cart").click(function() {
$(this).parents(".item").slideUp("slow");
console.log(this);
register("subtract", amount, hours);
$(toId(id)).removeAttr("disabled").fadeTo("slow", 1);
$(this).parents(".item").remove();
});
}
The problem appears to be that the click handler attached to the remove button is invoked multiple times when a remove button is clicked. The duplicate invocation of register("subtract", amount, hours) causes the total to go negative. How can I fix this?
The problem is that you re-run $(".remove-from-cart").click(...) each time you add an item to the cart, so all existing remove buttons get an extra handler.
Use jQuery to parse to HTML into a jQuery-wrapped DOM structure, and then use that as a context for your .remove-from-cart selector (as demonstrated in this working fiddle). That way, the .remove-from-cart selector will only apply to your newly-added item.
var selected_product = "<div class=\"item \">" + ...;
// jQuery-wrapped DOM structure
var $prod = $(selected_product)
$prod.insertBefore("#subtotals");
register("add", amount, hours);
// use $prod as jQuery context argument,
// so `.remove-from-cart` only looks in this DOM tree
$(".remove-from-cart", $prod).click(function() {
...
});