removing clicked item from array in javascript - javascript

I have a click function to make a list of chosen items. Also, I push the chosen items to an array. There is no problem in that part, here is the function.
$('#addToCartButton2').click(function(){
var toAdd=$("#chooseItem2 option:selected").text();
var itemNbr2=$("#itemNbr2").val();
if(toAdd !== defaultSelectFormText && itemNbr2 >=1){
$('#defaultText').remove();
$('.col-md-5').append('<p id="items">' + itemNbr2 + ' Adet ' + toAdd + '<span class="extra">Sipariş listesinden çıkarmak için tıklayın!</span>' + '</p>');
ordersArray.push(itemNbr2 + ' Adet ' + toAdd);
alert(ordersArray.toString());
};
});
But I also have a function to remove the clicked item from that list. So I want to remove that item also from array when it is clicked. I tried to use splice method but I can not get the index of the clicked item. Here is the remove function.
$(document).on('click', '#items', function() {
$(this).remove();
var index = ordersArray.indexOf($(this).val());
alert(index);
if (index > -1) {
ordersArray.splice(index, 1);
}
});
How can I get the index of the clicked item in the list?

Firstly, either you make id of items unique or use class instead of id as I done in this solution.
$('#addToCartButton2').click(function(){
var toAdd=$("#chooseItem2 option:selected").text();
var itemNbr2=$("#itemNbr2").val();
if(toAdd !== defaultSelectFormText && itemNbr2 >=1){
$('#defaultText').remove();
$('.col-md-5').append('<p class="items"><span>' + itemNbr2 + ' Adet ' + toAdd + '</span><span class="extra">Sipariş listesinden çıkarmak için tıklayın!</span>' + '</p>');
ordersArray.push(itemNbr2 + ' Adet ' + toAdd);
alert(ordersArray.toString());
};
});
$(document).on('click', '.items', function() {
var index = ordersArray.indexOf($('span:first', this).text());
alert(index);
if (index > -1) {
ordersArray.splice(index, 1);
}
$(this).remove();
});

In function to remove the clicked item from that list, make the following changes:
$(document).on('click', '#items', function() {
var index = ordersArray.indexOf($(this).text());
alert(index);
if (index > -1) {
ordersArray.splice(index, 1);
}
$(this).remove();
});

It seems like you're way of deleting the item is a little to complex.
Why not just use a uniqe ID for each item you're appending and just delete
the item by it's ID ?

Related

How can I change the value of div, which was previously created by jQuery

I want to create a script, which would provide possibility of making food table with nutrients counting. Lets say a daily menu.
When user clicks buttons, ingredients are adding to table. There are + and - buttons in the line of ingredient to change amount of it by 1.
html:
<div class="menuContainer">
<div class="foodListContainer">
<div class="row"></div>
</div>
<div class="buttonsContainer">
<button value="100,g.,12.6,2.6,68,355">Buckweat</button>
<button value="1,ps.,6.3,5.7,0.35,78.5">Egg</button>
<button value="1,sp.,2.8,3.2,4.7,58">Butter</button>
<button value="100,g.,12.6,2.6,68,355">Meat</button>
</div>
js:
$(document).ready(function () {
//When user click a button
$(".buttonsContainer button").click(function () {
//catching the name of food
var choosenFood = $(this).text();
//catching the value of pressed button with info
//about this food and making an array with it
var value = $(this).val();
var arr = value.split(',');
//insert div's with info from array
$($.parseHTML(
'<div class="name">' + choosenFood + '</div><button class="up">+</button><div class="value">' + arr[0] + '</div><div class="unit">' + arr[1] + '</div><button class="down">-</button><div class="protein">' + arr[2] + '</div><div class="fat">' + arr[3] + '</div><div class="carbs">' + arr[4] + '</div><div class="kkal">' + arr[5] + '</div><br>')).appendTo(".row");
//trying to change value
$('.down').click(function () {
$(this).prev().prev(".value").html(function (i, val) {
return val * 1 - 1;
});
});
$('.up').click(function () {
$(this).next(".value").html(function (i, val) {
return val * 1 + 1;
});
});
});
The problem starts when there are 2 and more rows in the table. The more rows, the more + and - buttons change value. You better look at it here: https://jsfiddle.net/ts3n35bq/
I assume, that there is some problem with scopes. Probably, the crucial mistake is to call "up" and "down" actions right from "appendTo" action, and it seems like this functions repeated themselves in every row, until the end. But when I try to remove them from there, they don't work at all.
I will appreciate any advice or help. Thanks!
This should work for you.
$(document).ready(function () {
$('body').on('click', '.down', function() {
$(this).prev().prev(".value").html(function (i, val) {
return val * 1 - 1;
});
});
$('body').on('click', '.up', function() {
$(this).next(".value").html(function (i, val) {
return val * 1 + 1;
});
});
//When user click a button
$(".buttonsContainer button").click(function () {
//catching the name of food
var choosenFood = $(this).text();
//catching the value of pressed button with info about this food and making an array with it
var value = $(this).val();
var arr = value.split(',');
//insert div's with info from array
$($.parseHTML(
'<div class="name">' + choosenFood + '</div><button class="up">+</button><div class="value">' + arr[0] + '</div><div class="unit">' + arr[1] + '</div><button class="down">-</button><div class="protein">' + arr[2] + '</div><div class="fat">' + arr[3] + '</div><div class="carbs">' + arr[4] + '</div><div class="kkal">' + arr[5] + '</div><br>')).appendTo(".row");
//trying to change value
});
});
Use unbind on click function
$('.down').unbind().click(function () {
$(this).prev().prev(".value").html(function (i, val) {
return val * 1 - 1;
});
});
$('.up').unbind().click(function () {
alert($(this).next(".value").attr('id'));
$(this).next(".value").html(function (i, val) {
return val * 1 + 1;
});
});
$(".buttonsContainer").on('click','button',function (){
//your code
});
Instead of:
$(".buttonsContainer button").click(function () {
...
});
Use:
$(document).on('click', '.buttonsContainer button', function() {
...
});
Each time you click to add a div to your table you call $('.down').click() which binds the event to all the existing buttons with the "down" class. Adding more than a single row makes it so that for a single click event you have multiple handlers attached to the preexisting buttons.
You can easily fix this without changing much of your code. Instead of appending the new row directly save it to a variable first and add the click handler to the down/up element inside it:
var rowString = '<div class="name">' + choosenFood + '</div><button class="up">+</button><div class="value">' + arr[0] + '</div><div class="unit">' + arr[1] + '</div><button class="down">-</button><div class="protein">' + arr[2] + '</div><div class="fat">' + arr[3] + '</div><div class="carbs">' + arr[4] + '</div><div class="kkal">' + arr[5] + '</div><br>';
var newRow = $($.parseHTML(rowString));
newRow.filter(".down").click( function () {
$(this).prev().prev(".value").html(function (i, val) {
return val * 1 - 1;
});
});
newRow.filter(".up").click(function () {
$(this).next(".value").html(function (i, val) {
return val * 1 + 1;
});
});
newRow.appendTo(".row");

Remove "comma" separator after last element

I have the below code.
$(document).ready(function(){
$('input[type="checkbox"]').click(function(){
elem = $(this);
part = $(this).attr("data-part-name");
//alert(part);
selected_options = "";
$('.' + part).each(function () {
if ($(this).is(":checked")) {
selected_options += $(this).attr("data-option-name") + ' <b>,</b> '
}
});
$("#part_child_" + elem.attr("data-part-id")).html(selected_options);
});
});
If you see I am adding a "comma" to selected options.
Now problem is it adds comma even after the last element.
How can I remove the last comma
.map() will a perfect fit for this. Also you can filter the checked items using :checked and filter
$(document).ready(function () {
$('input[type="checkbox"]').click(function () {
var elem = $(this);
var part = $(this).attr("data-part-name");
//alert(part);
var selected_options = $('.' + part).filter(':checked').map(function () {
return '<b>' + $(this).attr("data-option-name") + '</b>'
}).get();
$("#part_child_" + elem.attr("data-part-id")).html(selected_options.join(', '));
});
});
You can use the index of iteration to compare with length of parts element and do the decision whether a comma needs to be added or not.Modify the code to:
var totalparts=$('.' + part).length;
$('.' + part).each(function (i) {
if ($(this).is(":checked")) {
selected_options += $(this).attr("data-option-name") + totalparts!=(i+1) ?' <b>,</b> ':'';
}});
Just remove last , substring from the string,
if(selected_options.length > 0){
selected_options = selected_options.slice(0,-1)
}
$("#part_child_" + elem.attr("data-part-id")).html(selected_options);
replace this line
$("#part_child_" + elem.attr("data-part-id")).html(selected_options.replace(/[\<\>\,b\/\s]+$/,''));

Multiple Autocomplete function Open render previous items

I'm having a litle problem with my autocomplete. I'm using two autocompletes in same page.
In both I'm rendering my elements from ajax (diferente sources), and also in both, i'm using the _render option to show my elements.
The problem is: In my second autocomplete, in the funcion Open I want use the $('.ui-autocomplete > li') but when I do this, it will return the new ones, but also with the li elements from the previous autocomplete...
This is my second autocomplete:
$(".chooseProduct").autocomplete({
source: function (request, response) {
$.ajax({
....
});
},
select: function (event, ui) {
if (ui.item != null)
selectedProduct(ui.item);
},
open: function (event, ui) {
//this length will return the newest and the other elements :(
var len = $('.ui-autocomplete > li').length;
if (!(len == 8 && showQtd > 8)) {
if ((len % 8) == 0) {
$('.ui-autocomplete').append("<li class='ui-menu-item'><a>------Show more------</a></li>");
}
}
else showQtd = 8;
}
}).data("autocomplete")._renderItem = function (ul, item) {
var extra = "";
if (item.dosagem != null)
extra = "DOS: " + item.dosagem + " ";
return $('<li></li>')
.data('item.autocomplete', item)
.append('<a>COD: <b>' + item.codigo + ' ' + item.name + '</b>' + item.pvp + '<br/>' + extra + '</a>')
.appendTo(ul);
};
How can I instead of using $('.ui-autocomplete > li') use only my returned elements?
Thanks
When you use the selector $('ui-element > li) it will render all the items that are included in the element that you define to do autocomplete. To obtain the current elements (the elements that are being rendered by this autocomplete) do this way:
var len = $(this).data("autocomplete").menu.element.children().length;
To get all elements:
var elements = $(this).data("autocomplete").menu.element.children();

sorting and appending li to ul asc

http://jsfiddle.net/Hms7Y/14/
the code above work well for inserting item according to 'level' without using any complex sorting algo, but there's a problem, when there is no ready markup, the level 2 will be still on top of level 1..
$(document).ready(function() {
$('button').click(function() {
var lvl = $('select').val();
var ref = $('li.level' + lvl).last();
var newLi = $('<li class="level'+ lvl + '">' + lvl + ' </li>');
console.log(ref);
(ref.length > 0) ? newLi.insertAfter(ref) : $("ul").append(newLi);
});
});
I have edited you fiddle to work as you expect: http://jsfiddle.net/Hms7Y/23/
Basically I have added this control on every click:
if($("ul").children().length>0){
$("li").each(function(){
if(lvl <= parseInt($(this).html())){
newLi.insertBefore($(this));
}else{
newLi.insertAfter($(this));
}
});
}else{
$("ul").append(newLi);
}

Insert After Last Item by jQuery

This is my all script, I know this is long, but just one line is important and I add all it for insurance:
//Add new Addable div
$('.AddNewE').click(function () {
var RemoveAddableButton = $('<input type="button" class="RemoveE button red" value="remove" />');
$(RemoveAddableButton).click(function () {
$(this).closest('.Addable').remove();
});
var TargetId = $(this).attr('id');
TargetId = TargetId.substring(3);
var Target = $('.Addable#' + TargetId + ':first');
var Count = $('.Addable#' + TargetId).size();
var CloneTarget = $(Target).clone();
CloneTarget.find('input').val('');
CloneTarget.insertAfter('.Addable#' + TargetId + ':last'); // ***importantOne
var TargetName = $(Target).find('input').attr('name');
if (Count == 1) {
var CloneName = TargetName + '[1]';
TargetName = TargetName + '[0]';
$(Target).find('input').attr('name', TargetName);
$(Target).find('span[class*="field-validation"]').attr('data-valmsg-for', TargetName);
$(CloneTarget).find('input').attr('name', CloneName);
$(CloneTarget).append($(RemoveAddableButton));
if ($(CloneTarget).find('span[class*="field-validation"]').size() > 0) {
$(CloneTarget).find('span[class*="field-validation"]').remove();
$(CloneTarget).append(
$('<span class="field-validation-valid invalid-side-note" data-valmsg-replace="true" data-valmsg-for="' + CloneName + '"></span>')
);
}
} else {
var indx = TargetName.length - 3;
var CloneTargetName = TargetName.substring(0, indx);
CloneTargetName = CloneTargetName + '[' + Count + ']';
$(CloneTarget).find('input').attr('name', CloneTargetName);
$(CloneTarget).append($(RemoveAddableButton));
if ($(CloneTarget).find('span[class*="field-validation"]').size() > 0) {
$(CloneTarget).find('span[class*="field-validation"]').remove();
$(CloneTarget).append(
$('<span class="field-validation-valid invalid-side-note" data-valmsg-replace="true" data-valmsg-for="' + CloneTargetName + '"></span>')
);
}
}
(function ($) {
$.fn.updateValidation = function () {
var form = this.closest("form").removeData("validator").removeData("unobtrusiveValidation");
$.validator.unobtrusive.parse(form);
return this;
};
})(jQuery);
$(Target).updateValidation();
$(CloneTarget).updateValidation();
});
If I click the .AddNewE button then a new div added, but as my script I want to add this new div to the end of the divs so I use
CloneTarget.insertAfter('.Addable#' + TargetId + ':last');
but always the new div added as a second div it means always the :first and :last div is same and is first one also I checked by:
$('.Addable#' + TargetId).css('border', '');
$('.Addable#' + TargetId + ':last').css('border', '3px dotted green');
$('.Addable#' + TargetId + ':first').css('border', '3px dotted red');
So where is the problem? why the jQuery can't recognize last div ?
The problem is in the jQuery selector: $('.Addable#' + TargetId + ':last')
It is not valid HTML when you have multiple elements with the same id (#TargetId). ID is unique and you're not supposed to have more than 1 element with the same ID.
The jQuery selector assumes you use valid correct HTML markups, so it doesn't bother to collect all your elements with that ID. As soon as jQuery found the first element in the DOM with that ID, it stops and appends your new element right after that.
Try updating your jQuery selectors to simply: $('.Addable:first') and $('.Addable:last') and see if it works.

Categories

Resources