I want list items moved to a div when clicked and vice versa. But it seems, only elements loaded from the source can be moved.
How can I do that?
Thanks.
<div class="green">
<ul id="selectable">
<li class="content-item">Item A</li>
</ul>
</div>
<div class="red">
<span class="selected-item">Item 1</span>
<span class="selected-item">Item 1</span>
<span class="selected-item">Item 1</span>
<span class="selected-item">Item 1</span>
<span class="selected-item">Item 1</span>
<span class="selected-item">Item 1</span>
<span class="selected-item">Item 1</span>
</div>
<script>
$(".selected-item").click(function() {
var text = "<li class='content-item' >"+$(this).text()+"</li>";
$(".green #selectable").prepend( text );
$(this).remove();
});
$(".content-item").click(function() {
var text = "<span class='selected-item'>"+$(this).text()+"</span>";
$(".red").append( text );
$(this).remove();
});
</script>
http://jsfiddle.net/wGz8s/112/
You should use jQuery's event delegation.
The problem is: your jsFiddle is using jQuery 1.4 (very old version), and it doesn't have the .on event.
I've updated it to the version 1.11, and it works like a charm:
$(".abc").on("click", "span", function(e) {
var text = "<li class='content-item' >"+$(e.target).text()+"</li>";
$(".choices #selectable").prepend( text );
$(e.target).remove();
});
$(".choices").on("click", "li", function(e) {
var text = "<span class='selected-item'>"+$(e.target).text()+"</span>";
$(".abc").append( text );
$(e.target).remove();
});
http://jsfiddle.net/wGz8s/113/
Try to use event delegation here since the elements that you are adding at the runtime would not be available during event binding,
$(document).on("click",".selected-item", function() {
var text = "<li class='content-item' >"+$(this).text()+"</li>";
$(".green #selectable").prepend( text );
$(this).remove();
});
and
$(document).on("click",".content-item", function() {
var text = "<span class='selected-item'>"+$(this).text()+"</span>";
$(".red").append( text );
$(this).remove();
});
And in the place of the document in my code use a static closest dom element of the selector which is being passed inside .on()
Related
Aspiring developer and first time posting a question to StackOverflow.
Researched the topic but couldn't find an exact answer to my question.
Background:
Modifying this static shopping cart, to accept dynamically created list item.
https://tutorialzine.com/2014/04/responsive-shopping-cart-layout-twitter-bootstrap-3
Trying to insert a new item to the shopping cart via span tag, span tag information will be dynamically provided by another function.
For testing purpose I'm using a button to insert the new item to the shopping list.
The shopping cart has popover event to "Modify / Delete" individual items lists
Question: I can't figure out the exact JavaScript / jQuery command to attach the popover event. All static items in the list have the popover event automatically attached but the dynamically created items do not.
I tried using the addEventListener(); but the jQuery doesn't get attached properly.
My initial assumption was if the dynamically created list items had the same "class" as the static items that the popoever event would be automatically applied to them as well.
Tried these solutions but didn't work out for me, the popover event doesn't get attached properly.
a. Event binding on dynamically created elements?
Event binding on dynamically created elements?
b. Attach event to dynamically created chosen select using jQuery
Attach event to dynamically created chosen select using jQuery
c. Attaching events after DOM manipulation using JQuery ajax
Attaching events after DOM manipulation using JQuery ajax
Here's the HTML and JavaScript:
var qrcodelist = document.getElementById('qrdemo_list');
function myFunction() {
// HTML for testing when device is not connected: comment out when device is connected
var x = document.getElementsByClassName("decode-value-offline")[0].innerHTML;
// Qty and Price text values
var qty_text = 1;
var price_text = '$150';
// Create li
var entry_li = document.createElement('li');
entry_li.setAttribute("class", "row");
// Create quantity span
var qty_span = document.createElement('span');
qty_span.setAttribute("class", "quantity");
qty_span.appendChild(document.createTextNode(qty_text));
// Create price span
var price_span = document.createElement('span');
price_span.setAttribute("class", "price");
price_span.appendChild(document.createTextNode(price_text));
// Create pop btn span
var popbtn_span = document.createElement('span');
popbtn_span.setAttribute("class", "popbtn");
popbtn_span.setAttribute("data-original-title", "");
popbtn_span.setAttribute("title", "");
//popbtn_span.addEventListener( );
// Create a tag inside pop btn
var popbtn_a_span = document.createElement('a');
popbtn_a_span.setAttribute("class", "arrow");
popbtn_span.appendChild(popbtn_a_span);
// Create item span and text node
var item_span = document.createElement('span');
item_span.setAttribute("class", "itemName");
// Append span to li
entry_li.appendChild(qty_span);
entry_li.appendChild(item_span);
entry_li.appendChild(popbtn_span);
entry_li.appendChild(price_span);
// Create text node and insert qr-code result to li span
item_span.appendChild(document.createTextNode(x));
// Get list node and insert
var list_node = document.getElementById("qrdemo_list").lastChild;
// alert(list_node);
qrdemo_list.insertBefore(entry_li, qrdemo_list.childNodes[3]);
// Write x to console log
console.log(x);
}
// Popover JavaScript
$(function() {
var pop = $('.popbtn');
var row = $('.row:not(:first):not(:last)');
pop.popover({
trigger: 'manual',
html: true,
container: 'body',
placement: 'bottom',
animation: false,
content: function() {
return $('#popover').html();
}
});
pop.on('click', function(e) {
pop.popover('toggle');
pop.not(this).popover('hide');
});
$(window).on('resize', function() {
pop.popover('hide');
});
row.on('touchend', function(e) {
$(this).find('.popbtn').popover('toggle');
row.not(this).find('.popbtn').popover('hide');
return false;
});
});
<!-- Shopping Cart List HTML -->
<div class="col-md-7 col-sm-12 text-left">
<ul id="qrdemo_list">
<li class="row list-inline columnCaptions">
<span>QTY</span>
<span>ITEM</span>
<span>Price</span>
</li>
<li class="row">
<span class="quantity">1</span>
<span class="itemName">Birthday Cake</span>
<span class="popbtn"><a class="arrow"></a></span>
<span class="price">$49.95</span>
</li>
<li class="row">
<span class="quantity">50</span>
<span class="itemName">Party Cups</span>
<span class="popbtn"><a class="arrow"></a></span>
<span class="price">$5.00</span>
</li>
<li class="row">
<span class="quantity">20</span>
<span class="itemName">Beer kegs</span>
<span class="popbtn"><a class="arrow"></a></span>
<span class="price">$919.99</span>
</li>
<li class="row">
<span class="quantity">18</span>
<span class="itemName">Pound of beef</span>
<span class="popbtn"><a class="arrow"></a></span>
<span class="price">$269.45</span>
</li>
<li class="row">
<span class="quantity">1</span>
<span class="itemName">Bullet-proof vest</span>
<span class="popbtn" data-parent="#asd" data-toggle="collapse" data-target="#demo"><a class="arrow"></a></span>
<span class="price">$450.00</span>
</li>
<li class="row totals">
<span class="itemName">Total:</span>
<span class="price">$1694.43</span>
<span class="order"> <a class="text-center">ORDER</a></span>
</li>
<li class="row">
<!-- QR Code Images -->
<span class="itemName"><img src="img/AppleQRCode.png" width="100" height="100"></span>
<span class="price"><img src="img/OrangeQRCode.png" width="100" height="100"></span>
</li>
<li class="row">
<!-- device offline testing span -->
<span class="decode-value-offline">Unknown</span>
</li>
<li class="row totals">
<!-- Button to insert qr-code result to list -->
<span class="order"><a class="text-center" onclick="myFunction()">Insert</a></span>
<span class="itemName">Insert QR Code Result</span>
</li>
</ul>
</div>
<!-- Popover HTML -->
<!-- The popover content -->
<div id="popover" style="display: none">
<span class="glyphicon glyphicon-pencil"></span>
<span class="glyphicon glyphicon-remove"></span>
</div>
<!-- JavaScript includes -->
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="assets/js/bootstrap.min.js"></script>
<script src="assets/js/customjs.js"></script>
Appreciate the great support in advance and please contact me if additional information is needed for clarification.
JSFiddle of Fix: https://jsfiddle.net/0phz61w7/
The issue is that you need to delegate the event. Please do the following:
Change:
pop.on('click', function(e) {
pop.popover('toggle');
pop.not(this).popover('hide');
});
To:
$(document).on('click', '.popbtn', function(e) {
pop.popover('toggle');
pop.not(this).popover('hide');
});
Also, you need to remove the } from line 54, just after console.log(x);. That is throwing an error.
The above modification works, but in the code provided, .popbtn is not visible because the node is empty. So in the jsfiddle provided, I added a CSS rule to include the text POPBTN. Click that and an alert I added to the click event fires.
You need to delegate jquery function to the HTML elements created dynamically like this:
Change your following line
var pop = $('.popbtn');
var row = $('.row:not(:first):not(:last)');
like given here:
var pop = $(document).find('.popbtn');
var row = $(document).find('.row:not(:first):not(:last)');
im working on a project which there is multiple menu selection on tab which i need to onclick on each tab menu will display different type of menuFood. As my jquery not working on the function with onclick and the tab will add class "on" and the display of the table will be different. Kindly advice
html:
<div class="tab" data-type="wx" data-desc="整合">
<span data-type="wx" class="on">整合</span>
<span data-type="sx">第一球</span>
<span data-type="qsm">第二球</span>
<span data-type="zsm">第三球</span>
<span data-type="hsm">第四球</span>
<span data-type="em">第五球</span>
</div>
jquery:
<script type="text/javascript">
$(document).ready(function(){
$('.tab span').each(function(){
if($($(this))[0].href==String(window.location))
$(this).parent().addClass('on');
});
})
</script>
You can use jQuery.on() to handle the clicked element:
var $spans = $('.tab span');
$spans.on('click', function() {
var $el = $(this);
$spans.removeClass('on');
$el.addClass('on');
// Your logic to use type
console.log('Clicked:', $el.data('type'));
});
.on {color: red;}
.tab span {cursor: pointer; margin: 10px;}
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="tab" data-type="wx" data-desc="整合">
<span data-type="wx" class="on">整合</span>
<span data-type="sx">第一球</span>
<span data-type="qsm">第二球</span>
<span data-type="zsm">第三球</span>
<span data-type="hsm">第四球</span>
<span data-type="em">第五球</span>
</div>
$(document).ready(function(){
// to preselect the span from the hash whenever u refresh the page.
$('span[data-type="'+location.hash.substr(1)+'"]').addClass('on')
$('.tab span').click(function(){
$(this).siblings().removeClass('on');
$(this).addClass('on')
location.hash = $(this).data('type')
})
})
I have a div html element that has a click event set on it inline (not the way I want to do it but legacy code). See here
<div class="myDiv" onclick="triggerJavascript();" id="myDiv">
<span id="text1">Text 1<span>
<span id="text2">Text 2<span>
<span id="text3">Text 3<span>
<span id="text4">Text 4<span>
<span id="text5">Text 5<span>
What I want to do is recognize which span tag the click event originates from test5, then dont carry out the logic in triggerJavascript function, otherwise complete logic in triggerJavascript.
How can I set this up? I am working with jquery.
You can use event.target in order to access the element. However, in order to get to this element you have to change your onclick attribute a little bit:
<div class="myDiv" onclick="triggerJavascript(event);" id="myDiv">
then you can access event in triggerJavascript:
function triggerJavascript(e){
var element = e.target;
}
See also this answer for a more detailed explanation why event is needed.
Demo ; Demo with text5 check:
<script>function triggerJavascript(e){
if(e.target.id === "text5")
alert("text 5 hit");
e.stopPropagation();
}
</script>
<div class="myDiv" onclick="triggerJavascript(event);" id="myDiv">
<span id="text1">Text 1</span> <!-- closing tags -->
<span id="text2">Text 2</span>
<span id="text3">Text 3</span>
<span id="text4">Text 4</span>
<span id="text5">Text 5</span>
</div>
You can't use onclick="triggerJavascript();", or the event target (the span which was clicked) will not be passed to the event handler.
Since you state you're using jQuery, use this:
$('#myDiv').click(function(evt) {
alert("The target is: " + evt.target.id);
});
HTML
<div class="myDiv" onclick="triggerJavascript(event);" id="myDiv">
<span id="text1">Text 1<span>
<span id="text2">Text 2<span>
<span id="text3">Text 3<span>
<span id="text4">Text 4<span>
<span id="text5">Text 5<span>
</div>
JavaScript
<script type="text/javascript">
function triggerJavascript(event) {
// event.target will catch the clicked element
if (event.target.id !== 'text5') {
// do something
}
}
</script>
DEMO
If you can't change the HTML, you could try something like this:
var triggerJavascript = (function(){
var clicked;
$("#myDiv span").click(function(e){
clicked = $(e.target).attr("id");
});
return function() {
if (clicked == "text5") {
return;
}
//do something cool...
}
})();
Although I guess, there's no guarantee that the jQuery click handler is executed before the actual triggerJavascript logic, so this might not always work correctly.
im trying to find every <span class ="anime_yellow">.. inside another <span class="toggle">, this is the code:
HTML:
<span class="title_white">Menu 1</span>
<span class="toggle">
this is menu 1 i want to animate
<span id="position" class="anime_yellow">Position</span>
and
<span id ="market" class="anime_yellow">market</span>.
</span>
<br><br>
<span class="title_white">Menu 2</span>
<span class="toggle">
this is menu 2 i want to animate
<span id="simple" class="anime_yellow">Simple</span>
and
<span id ="kool" class="anime_yellow">Kool</span>.
</span>
The Javascript:
$(".toggle").hide();
$(".title_white").click(function() {
$(".toggle").hide();
$(this).next(".toggle").toggle("slow");
// i want to find every span.anime_yellow inside the
// THIS TOGGLE class and get its element ID
// and then run function on the ID
// animate(position) or animate(simple).
});
im trying to use the jquery function .find(), but don't know where to start, this is the jsfiddle for it here: http://jsfiddle.net/wJJBa/2/
Do you mean you want to do this: http://jsfiddle.net/sZUAE/1/
function animate(divID) {
alert(divID);
}
$(".toggle").hide();
$(".title_white").click(function() {
$(".toggle").hide();
var $toggle = $(this).next(".toggle");
$toggle.toggle("slow");
$toggle.find(".anime_yellow").each(function(i, e) {
animate(e.id);
});
});
Edited with your Code Sample:
$(".toggle").hide();
$(".title_white").click(function() {
$(".toggle").hide();
var $toggle = $(this).next(".toggle");
$toggle.toggle("slow");
$toggle.find(".anime_yellow").each(function (i, e) {
animate($(this).attr("id")); //Your ID is HERE
});
});
function animate(divID){
alert(divID);
}
I'm trying to create a filtering system where the user can filter for answers using more than one category, but the user can't choose more than one option from each category, so upon clicking an option from any category, that category will fade out ... I have the following little problem, if the user clicks on another option from the same category while it's fading out, he will be able to choose two options from the same category ... How can I disable any click on the category when it's fading out ??
Here is the code I'm using:
HTML:
<div class="search-list" id="program-list">
<span class="search-title">Category 1</span>
<span data="program-list">Option 1</span>
<span data="program-list">Option 2</span>
<span data="program-list">Option 3</span>
<span data="program-list">Option 4</span>
<span data="program-list">Option 5</span>
<span data="program-list">Option 6</span>
</div> <!-- search-list -->
<div class="search-list" id="trainer-list">
<span class="search-title">Category 2</span>
<span data="trainer-list">Option 1</span>
<span data="trainer-list">Option 2</span>
<span data="trainer-list">Option 3</span>
<span data="trainer-list">Option 4</span>
</div> <!-- search-list -->
<div class="search-list" id="issue-date">
<span class="search-title">Category 3</span>
<span data="issue-date">Option 1</span>
<span data="issue-date">Option 2</span>
<span data="issue-date">Option 3</span>
<span data="issue-date">Option 4</span>
<span data="issue-date">Option 5</span>
<span data="issue-date">Option 6</span>
</div> <!-- search-list -->
JQuery:
$('.search-option').click(function(){
var x = $(this).html();
$('#filtered-items').append(x);
$(this).parent('.search-list').fadeTo('slow', 0);
$('#filtered-items > span').click(function(){
$('#'+$(this).attr('data')).fadeTo('slow', 100);
$(this).hide();
});
});
I tried using the following JQuery code but it didn't work:
$('.search-option').click(function(e) {
e.preventDefault();
});
Thanks in advance...
You can set an indicator in your function:
$('.search-option').click(function(){
if(indicator) {
return false
}
...
}
The indicator is something set when the fade starts and clears when it ends. It could be:
a javascript variable,
or - you can check the current opacity,
or - or you can set/clear a class name during the fade.
Simply remove the 'search-option' class from all options in a category once it is clicked.
You can set the click event to null once it has fired:
$('.search-option').click(function(){
$(this).click(null); // set click to do nothing on the clicked element
var x = $(this).html();
$('#filtered-items').append(x);
$(this).parent('.search-list').fadeTo('slow', 0);
$('#filtered-items > span').click(function(){
$('#'+$(this).attr('data')).fadeTo('slow', 100);
$(this).hide();
});
});
This will only turn off the click action on the specifically clicked element so your other filters will continue to work until each of them has been selected once. If you want to re-enable the click function after everything has happened you can save the function, disable it, then re-enable at the end as below:
$('.search-option').click(function(){
var fun = $(this).click;
$(this).click(null); // set click to do nothing on the clicked element
// OTHER CODE
$(this).click(fun);
});
Since this all hinges on the user clicking on an element with the class "search-option", just remove that class from the element and its siblings before starting the fade and then restore it with a callback after the fade runs. That way, nobody can click twice:
$('.search-option').click(function() {
var x = $(this).html();
$('#filtered-items').append(x);
$(this).parent().children().removeClass('search-option');
$(this).parent('.search-list').fadeTo('slow', 0, function() {
$(this).children().addClass('search-option');
});
});
Hey everyone ... I finally solved it, I had to change the whole structure of the function and use the methods "unbind" and "bind" ... Here is the solution if anyone is interested in it:
$('.search-option').click(work);
});
function work(){
var x = $(this).html();
$('#filtered-items').append(x);
$(this).unbind('click');
$(this).siblings('a').unbind('click');
$(this).parent('.search-list').fadeOut('slow');
$('#filtered-items > span').click(function(){
$('#'+$(this).attr('data')).fadeIn('slow');
$('#'+$(this).attr('data')).children('a').bind('click',work );
$(this).remove();
});
};
Now the user can't choose more than one option at each category ....
Try:
$('.search-option').click(function(){
var x = $(this).html();
$('#filtered-items').append(x);
// ADDED LINES
$(this).parent('.search-list').find('a').each(function(){
$(this).click(function(){return false;});
});
// END: ADDED LINES
$(this).parent('.search-list').fadeTo('slow', 0);
$('#filtered-items > span').click(function(){
$('#'+$(this).attr('data')).fadeTo('slow', 100);
$(this).hide();
});
});