I have a for loop inside a button for an image gallery. When you click the button it will get the next group of items and add them to the page until there are no items left to grab. I was originally keeping track of the position in the array by adding the amount of items that should be added with each click to the previous value on each click. I wanted to change these vars to const, but if const in ES6 is not supposed to change (stay constant) how do you achieve this same result by not changing the value of the variables? Are my methods of keeping track of the current count of items not how I should be doing this?
var itemCurrent = 10; // Starting number of items on page.
var itemsAdded = 15; // Number of items to add to page per button click.
document.getElementById('myButton').addEventListener('click', function() {
for (let i = itemCurrent; i < itemCurrent + itemsAdded; i++) {
if(i < data.projects.length) {
//Do Stuff---------------------
}
}
itemCurrent = itemCurrent + itemsAdded;
});
I thought maybe there would be a more elegant way to do what I wanted, but it seems using let instead of var and leaving everything the way it was is the best way.
Related
Is there a way to go to this page:
http://www.canadiantire.ca/en/dyson.html
Add a script that will select only the product images on the tiles and when I click on them will create an alert with potentially their price on it but right now I'd be happy with just a random phrase.
I am going to assume that I need to loop into an array just those images and maybe use an addeventlistener for those images that I just tagged? Is there any way to do this without going into each image and adding an ID to it.
First fetch all product elements, I chose this selector .product-tile-srp__content-wrapper
Then, for each product, attach a click event and then fetch the price from .product-tile__price
Here's the code:
var products = document.querySelectorAll('.product-tile-srp__content-wrapper');
for (var i = 0; i < products.length; i++) {
products[i].addEventListener('click', function(event) {
var product = this;
var price = product.querySelector('.product-tile__price').innerText;
window.alert(price);
});
}
Note that the for loop is important because the NodeList.forEach is not supported on IE.
With jQuery this is pretty simple, just select based on the class. You need to also prevent the click from causing the browser to navigate to the product page. Then you can get the price by searching the descendants for the element containing the price. In my example, since I just selected the image and not the whole product element, I first had to search up through the ancestors (with closest) to get the base product element, and then find the price element.
Here is the example which activates when you click the image, just enter this into your browser's console while on the page:
$('.product-tile-srp__image').on('click', (e) => {
// Prevent click from actually opening the product page
e.stopPropagation();
e.preventDefault();
price = $(e.target).closest('.product-tile-srp__content-wrapper').find('.product-tile__price').text();
alert(price);
});
I'm using ChartJS to generate a pie chart in that elements are added every time the user clicks a specific button (I have 14 buttons that trigger the adding of a specific element in the pie chart, each one triggers a function that adds info to 3 arrays as needed in order for the chart to work.
Every time the user clicks a button a new one is created in a div that contains all the elements that are present in the chart because I want them to be able edit or delete the elements as needed.
To know what which elements from my arrays is edited by which edit button I'm using a variable named btnctr that I initialized with 0 at the beginning of my JS file. That variable gives every new ”edit button” an ID and then then increments, like this:
function CreateEditButton() {
var buttonnode= document.createElement('input');
buttonnode.setAttribute('type','button');
buttonnode.setAttribute('id',btnctr);
...
$("#rotationelements").append(buttonnode);
$("#rotationelements").append(' ');
btnctr++;
};
My problem is that I also have to make deleting elements possible. I'm using splice for deleting elements from the arrays, but that also messes up the position of other elements and my edit buttons become useless.
I want to also edit the IDs of my buttons when I delete elements, because I need them to be in sync.
Here's what I've come with so far:
// Get editbuttons
var editbuttons = document.getElementsByClassName('editbtn');
// Delete element
function deleteElement (x) {
names.splice(x,1);
dataset.splice(x,1);
colors.splice(x,1);
chart1.update();
time=time-length[x];
length.splice(x,1);
UpdateTime();
var delbtn=$("#"+x);
$(delbtn).remove();
var newid=x;
for (var i=0; i<editbuttons.length;i++) {
if (editbuttons[i].id>x) {
editbuttons[i].id=newid;
newid++;
btnctr=newid++;
}
}
}
Thanks!
Lulian, inside of your for loop it looks like you are only changing the id's of editbtns after the one that was deleted above. You may want to try taking out the if statement and replacing "newid" with "i":
for (var i=0; i<editbuttons.length;i++) {
// if (editbuttons[i].id>x) {
editbuttons[i].id=i;
//newid++;
btnctr=i;
// }
}
This way you can re-initialize all of you editbtn's and btnctr to match from beginning to end.
I am trying to make a javascript/jquery carousel. I have an unordered list and inside the ulist i have more lists. I get the first lit with:
list = $(wrapper).find("li:eq(0)").show()
On the button-next down i want it to show next list so it would be:
list = $(wrapper).find("li:eq(1)").show()
on the button-previous i want the list to show previous list. How could I achieve something like this, to append ("li:eg(x+1/x-1)).show()
Introduce a variable to keep track of the current list. When a user clicks the next button, increment it by one, and vice-versa for when previous is clicked. Then use this variable in your selector.
list = $(wrapper).find("li:eq("+ currentList +")").show()
Sidenote: You might want to introduce some bounds checking so currentList never goes below 0 and never exceeds the number of lists you have available.
//On previous click
if(currentList - 1 > 0){
//do something
}
//assign a variable to keep track of the upper bounds
var maxList = $(wrapper).find('li').length;
//On next click
if(currentList + 1 < maxList - 1){
//do something
}
Is there any way to figure out which cell position is clicked if you have merged table cells? We have 20 cells etc merged together and we would like to figure out if the user has clicked on what would have been for example the 7th cell
We have merged cells which mean specific things but we now need to figure out logically which cell was clicked by a user (even though they are merged).
Is this possible?
You can judge it based on the dimensions of unmerged cells in the same table. Here is an example using jQuery (just because it's much more concise than native JS to demonstrate this point):
var $mergedTd = $('td.myMergedTd'),
$unmergedThs = $('th');
$mergedTd.click(function(e) {
var clickedUnmergedIndex = 0;
$unmergedThs.each(function(i) {
var $th = $(this);
if(e.pageX < $th.pageX + $th.width()) {
clickedUnmergedIndex = i;
} else {
// Stop iterating; we've found the unmerged index
return false;
}
});
alert('You just clicked 0-based cell index #' + clickedUnmergedIndex);
});
I would keep two copies of that table in DOM. One visible and one hidden. You take click events on the visible table, and before you merge the cells, mark the clicked cell (e.g. add a data attribute to it indicating it was marked such as data-marked='1') and copy that table to the hidden one.
If you take a look at: http://www.thebullionstore.co.uk/_shop/?_cat=9
You will see a list of products each wrapped in a div with the class product_box. Inside product_box there several other divs and a form with an add to cart button. inside the form there is a hidden input field called stock_amount with a value, the value attribute is the amount of each product that is in stock. Iv also added a number base to the stock_amount class name to distinguish each product listing such as stock_amount0, stock_amount1 ans so on.
I want to be able to disable each button for each individual product after a certain amount of clicks. The amount of clicks will be equal to the value of stock_amount so in-effect a user cant add more products to the cart than is available.
Adding to the cart is currently done with Jquery but I don't know jquery well enough to figure out how to loop through each product listing and do what I described above.
Any help would be much appreciated.
$("button.addtocart").click(function(e) {
// fetch <input name='stock_amount'> within the clicked buttons form element
var stock_amount_input = $("input[name='stock_amount']", $(this).parent());
// fetch <input name='_qty'> within the clicked buttons form element
var qty_input = $("input[name='_qty']", $(this).parent());
// maybe you want to do some check here
var new_amount = stock_amount_input.val() - qty_input.val();
// set the new calculated value in the stock_amount input
stock_amount_input.val(new_amount);
// if the new_amount is less than 1 we dissable the clicked button
if(new_amount < 1) {
$(this).attr("disabled", "disabled");
}
});
To loop thorough elements you can use the jQuery.each(). Or write something like this:
var nodes = $("form");
for(var i=0; i<nodes.length; i++) {
var node = nodes[i];
// do something
}
But I don't think you need to do this. You can preform the check and the disabling of the button in the click-event-handler. Furthermore you shouldn't forget to check if the entered amount (e.g. 1000) doesn't exceed the stock amount.