jquery moving rows dynamically with .on - javascript

I'm attempting to move rows between two tables, but I cannot get it to keep the click event bound to it. I'm confused on the selector part on the .on event I'm not sure what I'm supposed to be targeting with that.
Basically I can get it to move to one table, and back but then it losses the click property. Not sure why.
I've attached a fiddle(http://jsfiddle.net/Yjqkn/216/) to make the problem clearer. The approve button moves it down, and the waitlist button moves it back, but then it loses all event listeners do I need to rebind them with .bind What is the best way to solve this.
I tried : .on("click","button.remove-participant",function() didn't work
Javascript
$( ":button" ).on("click",function(){
if($(this).hasClass('remove-participant')) {
$(this).removeClass('remove-participant').addClass('add-participant');
$(this).html('Approve');
var current_row = $(this).closest('tr').html();
$('.table_2 > tbody:last').append('<tr>'+current_row+'</tr>');
$(this).closest('tr').remove();
$( ".table_2 .add-participant" ).bind( "click", function() {
$(this).removeClass('add-participant').addClass('remove-participant');
var current_row = $(this).closest('tr').html();
$(this).html('Waitlist');
$('.table_1 > tbody:last').append('<tr>'+current_row+'</tr>');
$(this).closest('tr').remove();
});
}
});
HTML
<table class="table_1">
<tr>
<th>Info Header 1</th><th>Info Header 2</th>
</tr>
<tbody>
<tr><td>Don</td>
<td><button class="remove-participant" name="">Remove</button></td>
</tr>
</tbody>
</table>
<table class="table_2">
<tr>
<th>Info Header 1</th><th>Info Header 2</th>
</tr>
<tbody>
<tr></tr>
</tbody>
</table>

You should use:
$(".table_1").on("click", "button.remove_participant", function() {
...
});
The general idea with event delegation is that you bind the handler to some element(s) that are static in the DOM and will contain all the dynamically added elements. Then the selector argument should specify the more specific dynamic elements that you want to delegate to.
It also doesn't look right that you're binding a click handler to .table_2 .add_participant within the button.remove_participant click handler. Every time you remove a participant, it's going to add another click handler to every .add_participant element, so when you click on those elements the handler will run multiple times. You should delegate the handler just once -- the whole point of delegation is that it picks up dynamic changes so you don't need to redo it every time you modify the DOM.
BTW,
.removeClass('class1').addClass('class2');
can be combined into:
toggleClass('class1 class2');

In my opinion your code is not working is because of your logic. You are here doing this: In table 1, you are removing the class.
$(this).removeClass('remove-participant').addClass('add-participant');
When you click on table 2, and do the same thing. But you never go back and add the remove-participant class in table 1. So the click in Table 1 doesnt not work because class is set to 'add-participant' and not changed back.

Related

How to add behaviour (onclick) on <span> in a <tr> tag which has different behaviour (onclick)?

I have a data table which has a span element in every row. When someone clicks on the <tr> element JS code is executed. When someone clicks on the <span> element another JS code is execute.
The problem is that often it detects the click on the <tr> even though I click on the <span> element.
Is there any javascript/jquery function which helps me out?
HTML Code
<table class="table">
<thead>
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr class="behaviourTr">
<td></td>
<td></td>
<td></td>
<td><span class="glyphicon glyphicon-pencil"></span>
</td>
</tr>
</tbody>
</table>
JS Code
$('.behaviourTr').on('click', function() { ... });
$('.glyphicon-pencil').on('click', function() { ... });
When you click on the span element, you are technically still clicking on the tr element as well (because the span is a descendant element and the event bubbles up to the tr element).
Inside of the tr click event listener, you could check event.target (which is the clicked element) to see if the span element wasn't clicked. In the snippet below, the is() method is used to determine if event.target is not a span element.
See this example.
$('.behaviourTr').on('click', function(e) {
if (!$(e.target).is('span')) {
// The tr was clicked, but the span wasn't
}
});
It is called event propagation which is very classic in js.
Actually, there is another method through stop propagation, not through detect the target.
Demo is here.http://jsbin.com/sufede/edit?html,css,js,output
Within the callback function, you need to check for the element that is actually caused the event. I bet you'll need one click event for your multiple elements.
I'm on my phone, so hopefully this makes sense...
$('.behaviourTr').on('click', function(e) {
var targetElm = $(e.currentTarget);
If(targetElm.is('.glyphicon-pencil')){
//the pencil was clicked
}
If(targetElm.is('.behaviourTr')){
//the tr was clicked
}
});
e.target == element listening for event
e.currentTarget == element that triggered event

How exactly does this JQuery script work? and how can I modify it to select a specific object?

I am absolutly new in JavaScript and jQuery and I have the following problem.
I have the following jQuery script:
$(document).ready(function () {
$("thead.opening").click(function () {
$(this).next().slideToggle('slow', function () {
$(this).prev("thead.opening").toggleClass("active");
$("thead.opening").find(".imgAccordion").attr("src", "img/arrow.gif");
$("thead.active").find(".imgAccordion").attr("src", "img/arrow_down.gif");
});
return false;
});
});
and in my HTML I have something like this:
<table class="standard-table-cls table-header-cls">
<thead class="opening active">
<tr>
<th>
<img class="imgAccordion" src="img/arrow_down.gif"/>
Ricerca Flussi (la funzione e' consentita per flussi inferiori alle 300 fatture)
</th>
</tr>
</thead>
<tbody class="expanded">
<tr>
<td style="width: 100em;">
SHOW SOMETHING
</td>
</tr>
</tbody>
</table>
...........................................................
...........................................................
...........................................................
<table class="standard-table-cls table-header-cls">
<thead class="opening">
<tr>
<th>
<img class="imgAccordion" src="img/arrow.gif"/>
Ricerca Fatture
</th>
</tr>
</thead>
<tbody class="expanded" style="display: none;">
<tr>
<td style="width: 100em;">
SHOW SOMETHING ELSE
</td>
</tr>
</tbody>
<table>
As you can see in my code there is 2 different tables both having the same classes (standard-table-cls table-header-cls).
When I click on the thead of one of these table it seems to me that the previous script is perfromed (it is right or am I saying wrong assertion?).
I think so because this statment:
$("thead.opening").click(function () {.......
means something like: perform the body of the defined function() when the user click on any thead element having class=opening.
Is it my reasoning correct?
No my doubt (and also the related problem) is: how jQuery know what is the specific thead.opening clicked by the user (the one related to the first table or the one related to the second table)?
What exactly represent the $(this) element in the previous script? (it is the selected object or what?)
And finally, how can I modify the previous script to obtain the reference of the inner tbody of the same table of the thead.opening clicked?
Tnx
I'll keep this as short as possible but this is the scope in the current function. In elements, its an element. So for you?
$("thead.opening").click
runs a function. So the $(this) is the thread.opening that was actually clicked.
Post
this statment ... perform the body of the defined function() when the user click on any thead element having class=opening.
yes that is correct.
how JQuery know what is the specific thead.opening clicked by the user
the answer lies in: $(this).next().slideToggle('slow', function ()....
What exactly represent the $(this) element in the previous script?
the object which is clicked.
obtain the reference of the inner tbody of the same table of the thead.opening clicked
use something similar to the following in the click handler:
$(this).closest('.standard-table-cls').children('tbody')
reference: here and here
hope this helps.
When I click on the thead of one of these table it seems to me that
the previous script is perfromed (it is right or am I saying wrong
assertion?).
You are right
Is it my reasoning correct?
This is correct
What exactly represent the $(this) element in the previous script? (it
it the selected object or what?)
$(this) referes to the element invoking the function $("thead.opening").click(function () {});, so $(this) is equal to $("thead.opening"), where thead.opening is the exact element clicked (not the other thead.opening in your document).
And finnally, how can modify the previous script to obtain the
reference of the inner tbody of the same table of the thead.opening
clicked?
$(this).next() (which is used in your exemple) is the selector to target the tbody. $(this).next()means this (clicked thead), find next sibling element (tbody).
$("thead.opening") returns a array of elements that match the selector, in your case the two separate table headers that have the class opening added to them.
the .click() assigns a click event handler to each of the elements returned by the selector. In your case to both the table headers.
$(this) refers to element which invoked the event in the event handler.
The code $(this).next().slideToggle( is already referencing the next sibling of the thead - in your HTMLs case, the tbody.
You will have to change your script and change selectors. Current $("thead.opening") will for example select all <thead class="opening"> tags, so it would have to be similar to this:
$(document).ready(function () {
$("thead.opening").click(function () {
var thisThead = $(this);
var thisTbody = thisThead.next();
thisTbody.slideToggle('slow', function () {
thisThead.toggleClass("active");
thisThead.find(".imgAccordion").attr("src", thisThead.is('.active') ? "http://placehold.it/30/ffffff/000000" : "http://placehold.it/30/000000/ffffff");
});
});
});
Check this Fiddle with 2 tables.

Selecting a specific input and adding an event to it

I'm experiencing an frustrating problem.
I want to add an on-click event on an dynamically added input but I've been struggling with that for some time.
To show some code, here is my initial view
<div class="js-item-list"></div>
The user can then dynamically add data, this div is then populated for example like this (with initial divs)
<div class="js-item-list">
<div class="js-service-list-item>
<table>
<tr>
<td>Something</td>
<td><input type="text" class="js-consumption"></td>
</tr>
</table>
</div>
<div class="js-service-list-item>
<table>
<tr>
<td>Something</td>
<td><input type="text" class="js-consumption"></td>
</tr>
</table>
</div>
... and so on ...
</div>
I want to add an on-click event with jQuery to all the inputs so that when the users clicks on the input, all of the content of that specific input box would be selected. But I have no idea how to so all suggestions would be greatly appreciated, thanx :)
You can use delegate method for newly added or future elements
refrence
$('.js-item-list').delegate('input', 'click', function(e) {
//some code here
})
or for newer version >1.7 of jquery you should use .on()
As of jQuery 1.7, .delegate() has been superseded by the .on() method
$('.js-item-list').on('input', 'click', function(e) {
//some code here
})
Use the jQuery's event delegate function may resolve your problem, try this :
$(".js-item-list").on("click" , "input.js-consumption" , function(){
var domInput = this ;
var $input = $(this) ;
var value = $input.val();
// to do
});
You can use Jquery .on function, which work on dynamically added html element.
$(".js-item-list").on( "click", ".js-consumption" ,function() {
alert( $( this ).val() );
});
.js-item-list is the selector class which is not change dynamically only inner element of this will be change.
I'm assuming you have some button that the user clicks to add another "Something". I'm also assuming you have somewhere in your JS code $(".js-service-list-item").onclick(someAction).
That initial JS code only applies to the elements with that class that exist at the time it is run. This means every time they add an element to the list, you need to reapply that onclick method.
So what I would do is move that $(".js-service-list-item").onclick(someAction) code into the onclick function you have for the button that adds these service-list-items. That way each time you create a new element, you'll also register the onclick event with it

Display/Hide DIVs on tablecell hover (javascript)

I built a table with about 20 cells. Next to the table I want to display a <div> with a description, which should be displayed on hover or on click. There are heaps of solutions available on the web, but none really fits.
I already know I do need JavaScript, so i have my table cell
<td class="des1">Content</td>
and
<div id="des1">my Description1</div>
I add a class to the cells because some descriptions are called by more than one cell.
So, I need a JavaScript function to show the div "des1" on hover/click of all cells of class "des1", and also hide all other descriptions shown before. And that is my problem.
All my descriptions are wrapped in on other div so can I hide all divs in the wrapper and then display the right description. What is the best way to do this (event handling? inline?) Should I use CSS in Addition?
I do not have much experience in Javascript so I would appreciate any help or tips.
There are two basic parts to what you are trying to achieve:
event handling (to do things in response to the user hovering/clicking)
DOM manipulation (to change the description).
I would strongly advise using the jQuery library to help facilitate both of these.
Using jQuery you can easily "bind" an event handler which will do something in response to a cell being clicked or hovered over. For instance:
$('.des1').click(function() {
// Whatever you put here will be triggered when the user clicks on an element
// with class "des1"
});
The hover handler is similar, although slightly more complicated because it lets you specify both what happens when the user starts hovering and when they stop:
$('.des1').hover(function() {
// Whatever you put here will be triggered when the user hovers over an element
// with class "des1"
}, function() {
// Whatever you put here will be triggered when the user stops hovering over an
// element with class "des1"
});
Inside the handlers you'll want to add logic to modify the text of the element with the appropriate ID, which you can do using jQuery's text method:
$('#des1').text('My Description #1');
Combining the two, and sharing a function between them, you get something like:
var showDescription1 = function() {
// Whatever you put here will be triggered when the user clicks on an element
// with class "des1"
};
$('.des1').click(showDescription1)
$('.des1').hover(showDescription1, function() {
// if you want to change the description back when the user stops hovering, you'd
// add that logic here
});
<style>
div.des {
display: none;
}
</style>
<table>
<tr>
<td class="des1">Content 1</td>
</tr>
<tr>
<td class="des2">Content 2</td>
</tr>
<tr>
<td class="des3">Content 3</td>
</tr>
</table>
<div id="des1" class="des">Description 1</div>
<div id="des2" class="des">Description 2</div>
<div id="des3" class="des">Description 3</div>
<script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
<script>
$('table td').on('click', function() {
var $des = $('#' + $(this).attr('class')),
visible = $des.hasClass('active');
$('div').hide();
if(visible) {
return;
}
$des
.addClass('active')
.show();
});
</script>

How do I delete a particular row of a table using jQuery?

I have a table like the following:
HTML:
<table id="data-filter">
<tr>
<td>1</td>
<td>Harry Potter</td>
<td><span class="delete"></span></td>
</tr>
<tr>
<td>2</td>
<td>Frodo Baggins</td>
<td><span class="delete"></span></td>
</tr>
</table>
If the user clicks "x" in any row, that particular row will be deleted. I am able to find which row is clicked, but I am unable to find exactly which rows "x" is clicked. My jQuery and CSS code are below:
jQuery:
$(document).on('click', '#data-filter tr', function() {
rn = this.rowIndex;
alert('You clicked row: '+rn); // do something to remove this row
});
CSS:
.delete:after { content:"x";}
I want to trigger the delete event, only when the user clicks a particular row's "x", not the whole row or just any part of the row. I think I may be just missing the correct selector for this, but I am not sure.
You can use this to refer to the element targeted by the handler so
$(document).on('click', '#data-filter tr .delete', function() {
$(this).closest('tr').remove()
});
Also from what I can see, you need to delete the row when you click the delete button so you need to add the handler to the delete element and then use .closest() to find the tr element where the delete button is present then call .remove() to delete that row
I was looking at your problem and I have a solution:
$(document).on('click', '#data-filter tr .delete', function() {
this.parentElement.parentElement.remove();
});
And you need to remove the hashtag on your table id (should be just "data-filter") thats how you call it from jQuery not how it's declared on HTML
What I'm doing with the function its set the listener in the span not on the row and calling the parent nodes until the TR
Hope that works for you.

Categories