On click for child element - javascript

I want to trigger an on click event for my <i> tag. I added an ID to it but if i try use:
$("#delete-playlist-song").on("click", function() {
console.log("in"); //doesnt trigger
});
It won't trigger so I want to try a different approach? Something like:
$("master-playlist-entries").find("i.pl-action").on("click", function() {
console.log("in"); //Won't work
});
My HTML code:
<ul id="master-playlist-entries" class="database">
<li id="db-" track-name="James Darren - Goodbye Cruel World" data-path="http://example.com/Cruel%20World.mp3" class="active">
<i style="display:none;" class="fa fa-bars db-action" title="Actions" data-toggle="modal" data-target="#modal"></i>
<i id="delete-playlist-song" class="fa fa-times pl-action" title="Remove Song From Playlist"></i>
<i class="fa fa-music db-icon"></i><span class="sn"> Goodbye Cruel World</span> <span class="bl">James Darren</span></li>
</ul>
What I did try was an onclick event to call a function which worked but you see, I want to grab the data-path information and pass it to that function so I can use: $(this).attr("data-path") which will return a different link each time for different li.
Any help will be appreciated!

Your original code works in a one item snippet, https://jsfiddle.net/TrueBlueAussie/6qhhyxs7/ so I have to guess as your example is incomplete:
It is not shown, but I would guess you have multiple <i> elements with the same id (e.g. id="delete-playlist-song). If that is the case it simply will not find any except the first one as browsers use a fast-lookup cache which can only have one element stored against each ID value. IDs must be unique on a HTML page to work property.
Switch to using classes instead and use a delegated event handler.
https://jsfiddle.net/TrueBlueAussie/6qhhyxs7/1/
e.g.
$(document).on('click', '.delete-playlist-song', function() {
$(this).closest('li').slideUp();
});
Notes:
You should connect delegated event handlers to a non-changing ancestor element, but document is the best default if nothing else is close. Do not use body as it has a bug to do with styling that can cause mouse events to not fire. Use document as your friendly backup as it also exists before DOM ready.

I guess your html is added dynamically - so register the click listener dynamically using this:
$("body").on("click", "#delete-playlist-song", function() {
And for getting the attribute data-path you can use $(this).closest('li').attr("data-path") inside the listener.
See a demo below:
$("body").on("click", "#delete-playlist-song", function() {
console.log($(this).closest('li').attr("data-path"));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
<ul id="master-playlist-entries" class="database">
<li id="db-" track-name="James Darren - Goodbye Cruel World" data-path="http://example.com/Cruel%20World.mp3" class="active">
<i style="display:none;" class="fa fa-bars db-action" title="Actions" data-toggle="modal" data-target="#modal"></i>
<i id="delete-playlist-song" class="fa fa-times pl-action" title="Remove Song From Playlist"></i>
<i class="fa fa-music db-icon"></i><span class="sn"> Goodbye Cruel World</span> <span class="bl">James Darren</span>
</li>
</ul>

Related

How do I make a span element inside an anchor tag as a non anchor element?

I have an anchor tag and a span and an i element embedded in the anchor tag-
<a href="home.html" class="list-group-item" data-toggle="collapse"
aria-expanded="false" style="padding-left: 30px;" id="id1">
<span
id="id2" class="glyphicon glyphicon-eye-close"
style="color: #d6d6d6 !important; font-size: 15px;" title="title1">
</span>
<i class="glyphicon glyphicon-folder-close"></i>
HOME
</a>
When I click on the i element or the span element, the page redirects to home.html the way I want it to.
But I don't want to redirect the page to home.html when I click on the span element. I instead want to bind the span element with a different action for the click event. I know that a quick fix is to have the span outside the anchor tag but unfortunately, I'm constrained to do so as per my requirements. Is there any way around this?
Any help will be appreciated. Thanks in advance.
You can cancel the event of a child element to prevent it from bubbling up to the parent.
Simply return false from the click event.
<a href="home.html">
<span onclick="return clickme();">
CLICK ME
</span>
<i class="glyphicon glyphicon-folder-close"></i>
HOME
</a>
jsfiddle:
https://jsfiddle.net/ksLbrj8y/3/
Note that cancelling the event is subject to a debate all of its own; see this thread for various techniques.
How to stop event propagation with inline onclick attribute?
You'd need to use JavaScript for this. You can add a click event listener to the <span> tag. Then, in the event handler, call .preventDefault() on the click event and redirect the user. Something like this:
document.querySelector('id2').addEventListener("click", function (e) {
e.preventDefault();
window.location = "http://example.com";
});
Be aware that this kinda violates good semantics (i.e. your mileage may vary when dealing with SEO, screen readers, and other non-standard consumers of your site).

onclick not working after append dynamic content

<div class="demo_restaurant">
<li class="school" onclick="dropdown(this)">
<span class="icon glyphicon glyphicon-education">
</span>
<span id="1" class="school_title item_title">ABC
</span>
</li>
<li class="school" onclick="dropdown(this)">
<span class="icon glyphicon glyphicon-education">
</span>
<span id="2" class="school_title item_title">WXY
</span>
</li>
</div>
I was trying to get the li id value when someone click on that li with following code:
$(".demo_restaurant li span").on("click", function (argument) {
alert($(this).attr('id'));
});
But the problem is when i added more li with append after ajax call. Then li onclick doesn't work. In that append elements can't call that click function though it's there in HTML. How can i make it work?
Try this:
$('.demo_restaurant').on('click', 'li span', function(argument) {
alert($(this).attr('id'));
});
Explanation:
When elements are added to the DOM dynamically, you need
to tell jQuery to listen for events on the closest parent that was
there when your handler was bound. (Note that it would also work with any further parent, up to document, but it is considerably less optimal.)
Another way would be to bind the handler to your added DOM everytime you add some new content.

Jquery, change caret class on click

I have this html code below with the caret class fa fa-caret-down. Now I want that if the user clicks on the caret, the caret-down class shall gets removed and get replaced with the fa fa-caret-up class. And the same again, if he klicks on the caret-up class, it shall get back to the caret-down class.
( any other way is also okay ). I've tried this:
$(document).ready(function() {
$('.fa-caret-down').on('click', function () {
$(this).removeClass('fa-caret-down').addClass('fa-caret-up');
});
$(this).removeClass('fa-caret-up').addClass('fa-caret-down');
});
[ This toogle also runs very bad with this code ]
But this only works for the first part. If I'm trying to get back to the caret-down, nothing happens.
Thats my HTML:
<div id="acc-construct" class="hidden">
<div class="acc-group">
<div class="acc-head">
<a class="acc-toggle collapsed acc-default" data-toggle="collapse"
data-parent="#acc" href="#collapse-divsInContainer">
<i data-arrow="" class="pull-right fa fa-caret-down"></i>
</a>
</div>
<div id="collapse-divInContainer" class="acc-body collapse">
<div class="acc-inner">
<dl class="dl-horizontal"></dl>
<div class="separator"></div>
</div>
</div>
</div>
</div>
I'm still new in jquery/Js and sorry for my bad english.
Thanks for any help !
Set another class (caret-icon) on the caret element and attach click event to that class:
<i class="caret-icon fa fa-caret-down"></i>
And use toggleClass() method:
$(document).on('click', '.caret-icon', function() {
$(this).toggleClass('fa-caret-up fa-caret-down');
})
Use 'if - else' condition with 'hasClass' method.
Here is the Jquery
$(document).ready(function () {
$('.fa-caret-down').on('click', function () {
if ($(this).hasClass('fa-caret-down')) {
$(this).removeClass('fa-caret-down').addClass('fa-caret-up');
}else{
$(this).removeClass('fa-caret-up').addClass('fa-caret-down');
}
});
});
$('.fa-caret-down') finds the DOM - elements that have the class fa-caret-down when the code is executed, in your case after initialization. These elements get a click handler that removes fa-caret-down and adds fa-caret-up. The elements that have this handler don't change later. So, a second click on one of the elements also removes fa-caret-down and adds fa-caret-up.
You have to check in the handler if the element currently has class fa-caret-down or fa-caret-up. If it has class fa-caret-down you have to remove fa-caret-down and add fa-caret-up. If it has class fa-caret-up you have to remove fa-caret-up and add fa-caret-down.
Your current code $(this).removeClass('fa-caret-up').addClass('fa-caret-down'); does not help because it is executed only one time after initialization.

Sidebar closes when deleting element of array

I'm using mobile angular ui to open and close a sidebar. In this sidebar a user can search for persons and add or remove these from an array.
I have this repeat that shows the array of persons when clicking on the <a ...></> it closes the sidebar:
<li ng-repeat="recipient in persons.recipients">
<span class="wrapper">
<span class="imageWrap">
<span class="initials">
{{recipient.firstName.charAt(0)}}{{recipient.lastName.charAt(0)}} </span>
</span>
<i class="fa fa-trash-o" aria-hidden="true"></i>
<span class="details">
<span class="info">
{{recipient.firstName}} {{recipient.lastName}}
<span class="persnr">{{recipient.employeeID}}</span>
</span>
</span>
</span>
</li>
The above html snippet is from a directive that is in the sidebar.
The removeRecipient($index); function looks like this:
$scope.removeRecipient = function(index) {
$scope.persons.recipients.splice(index,1);
}
The function works but closes the sidebar and I can't figure out why it does this. So each time a user removes a recipient it has to swipe the sidebar open again. How do I keep this sidebar open?
References:
mobile angular ui: http://mobileangularui.com/docs/sidebars/
SOLUTION
I solved my problem by adding $event.stopPropagation(); in the ng-click right behind the removeRecipient($index); function.
From doc, there was one line.
You can put ui-turn-off='uiSidebarLeft' or ui-turn-off='uiSidebarLeft'
inside the sidebar to make it close after clicking links inside them.
so may be you can use that or you can use or you can do like below.
e.stopPropagation()
for that you need to pass $event in
<i class="fa fa-trash-o" aria-hidden="true"></i>
so in code, you can write.
$scope.removeRecipient = function(index,e) {
if(e){
e.stopPropagation()
}
$scope.persons.recipients.splice(index,1);
}
I didn't used same tool, but may be this is issue.

jsTree 3: use a drag handle to restrict initiating dragging

Using jsTree 3.0.8 I want to allow nodes to be dragged and dropped within the tree, but it should only allow that action if it was initiated by a drag on a specific button or "drag handle", instead of the default behavior of allowing dragging anywhere on the row.
I populate my tree via Html and for each node I draw out a toolbar as part of that row's Html content. I assign delegated jQuery click handlers to the toolbar items. One of the toolbar items needs to have a move icon and only allow that tree item to be moved by dragging on that toolbar button.
jQuery UI has a similar drag handle concept documented here:
https://jqueryui.com/draggable/#handle
Here is one node of my tree. The "Reorder" button is where I want the user to be able to drag the row, and nowhere else.
<li data-jstree="{ 'type': 'page' }">
<i class="jstree-icon jstree-ocl" role="presentation"></i>
<a class="jstree-anchor" href="#" tabindex="-1" id="109_anchor">
<i class="jstree-icon jstree-themeicon fa fa-2x fa-file font-grey-cascade jstree-themeicon-custom" role="presentation"></i>
<div class="pull-left">
<div class="friendly-name">test</div>
<small>/okay/its/a/test</small>
</div>
<span class="nodeToolbar">
<a title="Edit" class="passthrough btn grey-cascade btn-xs" href="/Pages/Edit/109"><i class="fa fa-pencil"></i> Edit</a>
<a title="Preview" class="preview btn grey-cascade btn-xs" target="_pagePreview" href="/Pages/Preview/109"><i class="fa fa-eye"></i> Preview</a>
<button title="Reorder" class="reorder btn grey-cascade btn-xs" href="#">
<i class="fa fa-arrows"></i> Reorder
</button>
</span>
</a>
</li>
I already took a look at some other solutions that involve check_callback but that seems to only prevent the move operation at the end (during the drop) rather than what I need, which is to filter the operation at the beginning (when the drag is initiated).
You will probably need to work with is_draggable:
http://www.jstree.com/api/#/?q=is_dragg&f=$.jstree.defaults.dnd.is_draggable
For a quick and dirty solution - listen for mousedown touchstart events on anchor nodes and set a variable which you can then later use in the is_draggable check:
var allow_drag = false;
$('#tree').on('mousedown touchstart', '.jstree-anchor', function (e) {
allow_drag = e.target.className.indexOf('reorder') !== -1;
});
$('#tree').jstree({
dnd : {
is_draggable : function () { return allow_drag; },
...

Categories

Resources