Now I try to add new Div with this code it's work.
The Problem is when I try to add new Div in a lasted row.
It's always after lasted row.
I need to add new Div next to the last row.
Maybe it's because of insertAfter but I can't fix it.
var math = Math.random().toString(36).substr(2, 9);
var math2 = Math.random().toString(36).substr(2, 9);
$(document).ready(function(){
$('<div class="row mt-2"" id="rowExpression'+math+'"></div>').appendTo('#overall');
$('<div class="col-md-9" id="Selector'+math+'"></div>').appendTo('#rowExpression'+math);
$('<h5> e '+math+'</h5>').appendTo('#Selector'+math);
$('<div class="col-md-1 col-md-offset-2" id="CRUDExpression'+math+'"></div>').appendTo('#rowExpression'+math);
$('<i class="btn success-item fas fa-plus-circle pr-1" onclick="addRow(this)" id="'+math+'" ></i>').appendTo('#CRUDExpression'+math);
$('<i class="btn cross-item fas fa-minus-circle pl-1" onclick="deleteRow(this)" id="'+math+'" ></i>').appendTo('#CRUDExpression'+math);
});
function addRow(eId) {
var mathX = Math.random().toString(36).substr(3, 12);
$('#rowExpression'+eId.id).one( "click",function(){
var x = $(this).prev().attr('id');
console.log(x +' neastest div');
console.log(eId.id +' this id');
console.log(mathX +' new id');
var lastedId = $('.row').last().attr("id") ;
console.log(lastedId, "rowExpression"+mathX);
$('<div class="row mt-2"" id="rowExpression'+mathX+'"></div>').appendTo('#overall')
.insertAfter($( "#"+x ));
$('<div class="col-md-9" id="Selector'+mathX+'"></div>').appendTo('#rowExpression'+mathX);
$('<h5> e '+mathX+'</h5>').appendTo('#Selector'+mathX);
$('<div class="col-md-1 col-md-offset-2" id="CRUDExpression'+mathX+'"></div>').appendTo('#rowExpression'+mathX);
$('<i class="btn success-item fas fa-plus-circle pr-1" onclick="addRow(this)" id="'+mathX+'" ></i>').appendTo('#CRUDExpression'+mathX);
$('<i class="btn cross-item fas fa-minus-circle pl-1" onclick="deleteRow(this)" id="'+mathX+'" ></i>').appendTo('#CRUDExpression'+mathX);
});
}
function deleteRow(eId) {
console.log(eId.id);
$("#rowExpression"+eId.id).remove();
}
This is my html.
<form action="#" method ="post">
<div id="overall" class="col-md-12">
</div>
<button type="submit" id="submit" class="btn btn-primary ml-2 mt-2" value="submit" >submit</button>
</form>
In your code, you're using 'insertAfter()' instead you should use '.append()' cause this way you will add your new code after the last one.
Without your HTML is hard to guess (where are those classes and how you structured them.
I will say try and use after instead of insertAfter, that could be the problem.
http://api.jquery.com/insertafter/
I getting my answer with myself now.
Thank you all.
function addRow(eId) {
var mathX = Math.random().toString(36).substr(3, 12);
$('#rowExpression'+eId.id).one( "click",function(){
var nearest = $(this).prev().attr('id');
console.log(nearest +' neastest div');
console.log(eId.id +' this id');
console.log(mathX +' new id');
var lastedId = $('.row').last().attr("id") ;
console.log(lastedId, "rowExpression"+mathX);
/*$('<div class="row mt-2"" id="rowExpression'+mathX+'"></div>').appendTo('#overall')
.insertAfter($( "#"+nearest ));*/
if('rowExpression'+eId.id == lastedId) {
$('<div class="row mt-2"" id="rowExpression'+mathX+'"></div>').appendTo('#overall');
}
else{
$('<div class="row mt-2"" id="rowExpression'+mathX+'"></div>').appendTo('#overall')
.insertAfter($( "#"+nearest ));
}
$('<div class="col-md-9" id="Selector'+mathX+'"></div>').appendTo('#rowExpression'+mathX);
$('<h5> e '+mathX+'</h5>').appendTo('#Selector'+mathX);
$('<div class="col-md-1 col-md-offset-2" id="CRUDExpression'+mathX+'"></div>').appendTo('#rowExpression'+mathX);
$('<i class="btn success-item fas fa-plus-circle pr-1" onclick="addRow(this)" id="'+mathX+'" ></i>').appendTo('#CRUDExpression'+mathX);
$('<i class="btn cross-item fas fa-minus-circle pl-1" onclick="deleteRow(this)" id="'+mathX+'" ></i>').appendTo('#CRUDExpression'+mathX);
});
}
Related
I'm doing an e-trade site with jQuery; however, when I increase then submit one of the products, they all get the properties of the first product. I defined the products as a json to a variable.
How can I create dynamic cards with jquery?
Here is how it looks:
İmage
Here is the source code:
$(document).on('click', '.number-spinner button', function() {
var btn = $(this),
oldValue = btn.closest('.number-spinner').find('input').val().trim(),
newVal = 0;
newVal = (btn.attr('data-dir') === 'up') ? parseInt(oldValue) + 1 : (oldValue > 1) ? parseInt(oldValue) - 1 : 0;
btn.closest('.number-spinner').find('input').val(newVal);
});
let html = data.reduce((acc, {name,value,image,counter,totalMoney}) =>
acc + `
<div class='card col-md-3'>
<img class='card-img-top' src="${image}" alt='Card image cap'>
<div class='card-body'>
<h5 class='card-title'>${name}</h5>
<p class="card-text">${value}</p>
<input class="money-input money" value="${value}"/>
<div class="number-spinner">
<div class="input-group number-spinner">
<span class="input-group-btn">
<button type="button" class="btn btn-default btn-number btn-minus" data-type="minus" data-dir="dwn"><span>-</span></button>
</span>
<input min="1" class="adet input-number" value="${counter}" type="number">
<span class="input-group-btn">
<button type="button" class="btn btn-default btn-number btn-plus" data-type="plus" data-dir="up"><span>+</span></button>
<div class="total-price"></div>
</span>
</div>
</div>
<button class="submit">Add To Card</button>
</div>
</div>`
, ``);
$('#list').append(html);
const adet = $(".adet").val()
const money = $(".money").val()
const totalMoney = adet * money;
var endText = 'Price'
var space = ' '
$( ".submit" ).click(function() {
$(".total-price").text($(".adet").val() * totalMoney);
$('.total-price').append( space + endText);
});
The "problem" is that you have (possibly) multiple elements with the class .adet and .money. However, the .val() method of a jQuery collection only extracts the value of the first element it contains. See the jQuery docs:
Get the current value of the first element in the set of matched elements...
jQuery docs
I am trying to implement a dynamic increment/decrement counter. Here is how it should work:
I have an 'ADD' button. When i click on this, the same should disappear and a minus button, number input, plus button should appear. Clicking on "+" should increment the counter on the "cart" and clicking on "-" should decrement.
Below is html mycode
<body>
<div id="page-wrap">
<h1>Cart Inc Dec</h1>
<a href="#" class="btn btn-info btn-lg mt-5 mr-5 mb-5">
<span class="glyphicon glyphicon-shopping-cart"><span id="itemCount"></span></span> Check Out
</a>
<br>
<a id="btnAddItem" class="btn btn-primary float-right mt-5 mb-5 mr-5">ADD</a>
<div class="addItem">
</div>
</div>
</body>
Jquery:
<script>
var addElement = 0;
$(document).ready(function(){
$("#btnAddItem").on("click", function (event) {
if(addElement==0){
$(".addItem").append(('<button type="button" class="counter decrease">-</button><input type="text" size="5" id="txtCounter" /><button type="button" class="counter increase">+</button>'));
}
addElement++;
});
var $input = $("#txtCounter");
// Initialise the value to 0
$input.val(0);
debugger;
// Increment/decrement count
$(".counter").click(function(){
console.log('here i am');
if ($(this).hasClass('increase'))
$input.val(parseInt($input.val())+1);
else if ($input.val()>=1)
$input.val(parseInt($input.val())-1);
});
});
</script>
Now the problem is after i add the dynamic +, text input counter, - controls, nothing happens when i click on + or minus. console.log inside $(".counter").click(function() is not giving anything.
Am i missing something??
You can do it like this: Adjust the $(".counter").click(function() {}); to $(document).on("click", ".counter", function(){}); as the element with the class counter isn't there when the page is initially loaded and therefore the click() event has to be delegated from a static parent element to the added counter element using on(). Move then the variable declaration var $input = $("#txtCounter"); inside this click function as the element with the id txtCounter isn't there when the page is initally loaded and move the initialization $("#txtCounter").val(0); after appending it.
var addElement = 0;
$(document).ready(function() {
$("#btnAddItem").on("click", function(event) {
if (addElement == 0) {
$(".addItem").append(('<button type="button" class="counter decrease">-</button><input type="text" size="5" id="txtCounter" /><button type="button" class="counter increase">+</button>'));
// Initialise the value to 0
$("#txtCounter").val(0);
}
addElement++;
});
// Increment/decrement count
$(document).on("click", ".counter", function() {
var $input = $("#txtCounter");
if ($(this).hasClass('increase')) {
$input.val(parseInt($input.val()) + 1);
} else if ($input.val() >= 1) {
$input.val(parseInt($input.val()) - 1);
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="page-wrap">
<h1>Cart Inc Dec</h1>
<a href="#" class="btn btn-info btn-lg mt-5 mr-5 mb-5">
<span class="glyphicon glyphicon-shopping-cart"><span id="itemCount"></span></span> Check Out
</a>
<br>
<a id="btnAddItem" class="btn btn-primary float-right mt-5 mb-5 mr-5">ADD</a>
<div class="addItem">
</div>
</div>
You can change the script and try something like below:
var addElement = 0;
var myCounter= function(action){
var val = document.getElementById("txtCounter").value;
val = parseInt(val);
if(action == 2){ //Increase
document.getElementById("txtCounter").value=val+1;
}else if(val > 1){
document.getElementById("txtCounter").value=val-1;
}
};
$(document).ready(function(){
$("#btnAddItem").on("click", function (event) {
if(addElement==0){
$(".addItem").append(('<button type="button" onclick="myCounter(1);" class="counter decrease">-</button><input type="text" size="5" id="txtCounter" value="0" /><button type="button" onclick="myCounter(2);" class="counter increase">+</button>'));
}
addElement++;
});
});
I am generating <ul> and sub <ul>, what I would like to do is to place the html structure of the list only with its values in it. With the following code I get into the text area all the <ul> content not simply the:
HTML
<div id="mindMap">
<ul class="list-unstyled margin-bottom-20">
<li><button class="btn btn-default ul-appending margin-bottom-20">+ voce</button></li>
</ul>
</div>
<div id="mindMapData">
<textarea name="usp-custom-11" id="usp-custom-11" data-required="false" placeholder="Example Input 11" data-richtext="false" class="usp-input usp-textarea usp-form-365" rows="0" cols="30" style="margin: 0px; width: 871px; height: 291px;"></textarea>
</div>
jQuery
$('body').on('click', 'button.ul-appending', function() {
$(this).parent().append(
$('<ul class="main_ul list-unstyled margin-bottom-20">').addClass('newul').append(
$('<li class="margin-bottom-20"><div class="input-group margin-bottom-20"><input placeholder="Aggiungi una voce..." class="form-control" type="text"><div class="input-group-btn"><button type="button" class="btn btn-default list">+ sotto voce</button><button type="button" class="btn btn-default removeThis">elimina</button></div></div></li>')
)
);
});
$('body').on('click', 'button.list', function() {
var newLi = '<ul class="sub_ul list-unstyled margin-bottom-20"><li class="listSub margin-bottom-20"><div class="input-group margin-bottom-20"><input placeholder="Aggiungi una sotto voce..." class="form-control" type="text"><div class="input-group-btn"><button type="button" class="btn btn-default list">+ sotto voce</button><button type="button" class="btn btn-default removeThis">elimina</button></div></div></li></ul>';
var listEl = $(this).parent().parent().parent();
$(listEl).append(newLi);
});
Then I check for the the html changes and insert the html into the textarea like this:
$("#mindMap").on("DOMSubtreeModified",function(){
$("#mindMapData textarea").val($("#mindMap").html());
});
In the text area i get all the html tho:
<ul class="main_ul list-unstyled margin-bottom-20 newul">
<li class="margin-bottom-20">
<div class="input-group margin-bottom-20">
<input placeholder="Aggiungi una voce..." class="form-control" type="text">
<div class="input-group-btn">
<button type="button" class="btn btn-default list">+ sotto voce</button>
<button type="button" class="btn btn-default removeThis">elimina</button>
</div>
</div>
<ul class="sub_ul list-unstyled margin-bottom-20">
<li class="listSub margin-bottom-20">
<div class="input-group margin-bottom-20">
<input placeholder="Aggiungi una sotto voce..." class="form-control" type="text">
<div class="input-group-btn">
<button type="button" class="btn btn-default list">+ sotto voce</button>
<button type="button" class="btn btn-default removeThis">elimina</button>
</div>
</div>
</li>
</ul>
Here it is a working jsFiddle, see the content in the textarea is wrong, I am trying to get:
<ul>
<li>Added node
<ul>
<li>Added sub node</li>
</ul>
</li>
</ul>
You can traverse the DOM with this code:
function ul(indent) {
indent = indent || 4;
var node = $(this);
return node.removeAttr('class').children().map(function() {
var self = $(this);
var value = self.find('> .input-group input').val();
var sub_ul = self.find('> ul');
var ul_spaces = new Array(indent+4).join(' ');
var li_spaces = new Array(indent).join(' ');
if (sub_ul.length && ul) {
return li_spaces + '<li>' + value + '\n' + ul_spaces +
'<ul>\n' + ul.call(sub_ul, indent+8) + '\n' + ul_spaces + '<ul>\n' +
li_spaces + '</li>';
} else {
return li_spaces + '<li>' + value + '</li>';
}
}).get().join('\n');
}
function updateTree() {
$("#mindMapData textarea").val('<ul>\n' + $("#mindMap").clone().find('.main_ul').map(ul).get().join('\n') + '\n</ul>');
}
one side note you should call that updateTree function on keyup for each input because DOMSubtreeModified is not fired when input change it's value, see update fiddle http://jsfiddle.net/44yb96Lb/72/
I think parsing the DOM tree recursively and filtering out unwanted tags is much more easier to understand. Have a look:
/**
* #param {array<string>} allowedTags A list of tags that are allowed in the output
* #returns {function} A function that takes a jQuery elements and returns a copy with only the allowed elements
*/
function filterElementsFactory(allowedTags) {
allowedTags = allowedTags.map(function (tag) { return tag.toUpperCase(); });
/**
* #param {object} element jQuery element
* #returns {documentFragment}
*/
return function filterElements(element) {
element = element.clone();
var elementList = element.contents();
var finalElem = document.createDocumentFragment();
for (element of elementList) {
if (element.nodeType === Node.TEXT_NODE) {
finalElem.appendChild(element);
} else if (element.nodeType === Node.ELEMENT_NODE) {
if (allowedTags.indexOf(element.tagName) !== -1) {
var elemFrame = document.createElement(element.tagName);
elemFrame.appendChild(filterElements($(element)))
finalElem.appendChild(elemFrame);
} else {
finalElem.appendChild(filterElements($(element)));
}
}
};
return finalElem;
}
}
You can use this like this:
var allowedTags = ['ul', 'li'];
var filterElements = filterElementsFactory(allowedTags);
$("#mindMap").on("DOMSubtreeModified",function(){
var placeholderDiv = $('<div/>').append(filterElements($("#mindMap")));
$("#mindMapData textarea").val(placeholderDiv.html());
});
var stringhtml = $('<div class="row" id="ao-clonedata">' + '<div class="col-lg-12 form-inline ao-content-padding">' + '<div class="col-xs-1 pull-left ao-from-triggers">'+'<a class="add-link ao-minus-color" title="Remove">'+'<i class="fa fa-minus fa-lg"></i></a>'+'<a class="add-link ao-plus-color ao-spacing-icon" title="Add"><i class="fa fa-plus fa-lg"></i></a>'+'</div> '+'<div class="col-xs-5 dropdown pull-left ao-padding-zero">'+'<button class="btn dropdown-toggle ao-substitute-dropdown ao-dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">'+'<span class="pull-left" id="ao-substitute-from">Select Value</span><i class="caret pull-right custom-dropdown-caret"></i>'+'</button>'+'<ul class="dropdown-menu ao-substitute-ul-dropdown" aria-labelledby="substituteFrom">'+'<li onclick="ChangeSubstituteStatus(1,'+' "Select Value",'+' this)">Select Value</li>'+'</ul>'+'</div>'+'<div class="col-xs-1">'+'<i class="fa fa-arrow-right fa-lg ao-substitute-arrow" id="ao-arrowbutton"></i>'+'</div>'+'<div class="col-xs-5">'+'<div class="form-inline" id="ao-clonetodata">'+'<div class="dropdown ao-substitute-dropdown pull-left">'+'<button class="btn dropdown-toggle ao-substitute-dropdown ao-dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">'+'<span class="pull-left" id="ao-substitute-to">Select Value</span><i class="caret pull-right custom-dropdown-caret"></i>'+'</button>'+' <ul class="dropdown-menu ao-substitute-ul-dropdown" aria-labelledby="substituteTo">'+'<li onclick="ChangeSubstituteToStatus(1, "Select Value", this)">Select Value</li>'+'<li onclick="ChangeSubstituteToStatus(2, "About Time", this)">About Time'+'</li>'+'</ul>'+'</div>'+'</div>'+'</div>'+'</div>'+'</div>');
Creating this HTML on click of an initial(X) button, after creating this html,need to clone this html on click of ".ao-plus-color" (which is there in above HTML). so whatever method i wrote for ".ao-plus-color" is not working.
method for ".ao-plus-color" is :
$(".ao-plus-color").on('click', function () {
CCounter = $("#ao-clonewrapper > .row").length + 1;
var clonedata = $("#ao-clonedata").clone(true).attr("id", "ao-clonedata" + CCounter).appendTo("#ao-clonewrapper");
CCounter++;
var clonedatalength = $("#ao-clonewrapper > .row").length;
if (clonedatalength > 0) {
$("#ao-remove-all").show();
} });
can any one help me out to solve this? thanks in advance!
You should bind the event to already created element ao-plus-color is also dynamically created.Use document like
$(document).on('click','.ao-plus-color', function () {
You need to use event delegation for attaching events to dynamically added elemens:
$("body").on('click',".ao-plus-color", function () {
CCounter = $("#ao-clonewrapper > .row").length + 1;
var clonedata = $("#ao-clonedata").clone(true).attr("id", "ao-clonedata" + CCounter).appendTo("#ao-clonewrapper");
CCounter++;
var clonedatalength = $("#ao-clonewrapper > .row").length;
if (clonedatalength > 0) {
$("#ao-remove-all").show();
}
});
I have two div html elements with different id and here I am using spinner. Whenever values in the spinner input changes alert box will be displayed.
HTML code
<div id="accordion2" class="panel-group" style="display: block;">
<div id="accordion2" class="panel-group">
<div id="Tea">
<div class="spinner Tea input-group ">
<input type="text" id = "servings" class="form-control input- sm" value="Tea"/>
<div class="input-group-btn-vertical">
<button class="btn Tea btn-default">
<i class="fa fa-caret-up"></i>
</button>
<button class="btn Tea btn-default">
<i class="fa fa-caret-down"></i>
</button>
</div>
<h4 id="energy" class="Tea"> Tea </h4>
</div>
<div id="Coffee">
<div class="spinner Coffee input-group ">
<input type="text" id = "servings" class="form-control input-sm" value="Coffee"/>
<div class="input-group-btn-vertical">
<button class="btn Coffee btn-default">
<i class="fa fa-caret-up"></i>
</button>
<button class="btn Coffee btn-default">
<i class="fa fa-caret-down"></i>
</button>
</div>
<h4 id="energy" class="Coffee">Coffee</h4>
</div>
</div>
</div>
JQuery code
$(function(){
$('.spinner:first-of-type input').on('click', function() {
$('.spinner:first-of-type input').val(parseInt($('.spinner:first-of-type input').val(), 10) + 1);
var val = $('.spinner:first-of-type input').val();
changeValues(val);
});
$('.spinner:last-of-type input').on('click', function() {
$('.spinner input').val( parseInt($('.spinner input').val(), 10) - 1);
});
function changeValues(value){
alert($('#energy').attr('class').split(' '));
};
});
But in the alert box whenever I click the spinner up arrow only Tea is displayed.
what I expect is when the spinner is clicked from Tea div tea should be displayed and when from coffee , coffee should be displayed.Please help me out
I'm not sure I totally got what you are trying to do, but it seems to me that you want to increment and decrement number of beverage cups on up/down buttons click. For this you would better modify mark up a little (remove duplicated ids, add classes for convenience). And I may look like this then:
$(function() {
$('.spinner').on('click', '.servings', function(e) {
$(this).val(parseInt($(this).val() || 0, 10) + 1);
var val = $(this).val();
changeValues.call(e.delegateTarget, val);
})
.on('click', '.up', function(e) {
$(e.delegateTarget).find('.servings').val(function() {
return ++this.value;
});
})
.on('click', '.down', function(e) {
var $input = $(e.delegateTarget).find('.servings');
if (+$input.val() > 1) {
$input.val(function() {
return --this.value;
});
}
});
function changeValues(value) {
var type = $(this).find('.energy').data('type');
alert(type);
};
});
Demo: http://plnkr.co/edit/9vXC0RipxkzqhXrHJAKD?p=preview
try this:
$(function () {
$('.spinner').each(function () {
var $el = $(this),
$buttons = $el.find('button'),
$h4 = $el.find('h4'),
input = $el.find('input').get(0);
function showAlert() {
alert($h4.get(0).className);
}
$buttons.eq(0).on('click', function (event) {
event.preventDefault();
input.value = (parseInt(input.value, 10) || 0) + 1;
showAlert();
});
$buttons.eq(1).on('click', function (event) {
event.preventDefault();
input.value = (parseInt(input.value, 10) || 0) - 1;
});
});
});
JSFiddle http://jsfiddle.net/yLtn57aw/2/
Hope this helps