I have two tables. From the top table you select data items by clicking on a add button which would add that row to the bottom table. In reverse if you select the remove button from the bottom table the row would go back to the top table. Now I am not even sure if it is possible with jQuery to accomplish this without using unique class names...hence me looking for help here.
Here is a Fiddle that is only half working, since I haven't figured out yet if it is possible to do what I am asking.
HTML
<table class="aside-table">
<thead>
<tr>
<th>Data Options
<button type="button" class="btn add-all-selection pull-right" onclick="location.href='#'"><span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Add All Data Options</button></th>
</tr>
</thead>
<tbody>
<tr>
<td>Item 3
<button type="button" class="btn add-selection pull-right"><span class="glyphicon glyphicon-plus" aria-hidden="true"></span></button></td>
</tr>
<tr>
<td>Item 4
<button type="button" class="btn add-selection pull-right"><span class="glyphicon glyphicon-plus" aria-hidden="true"></span></button></td>
</tr>
</tbody>
</table>
<table class="data-selection-table">
<thead>
<tr>
<th>Data Selection Summary
<button type="button" class="btn remove-all-selection pull-right" onclick="location.href='#'"><span class="glyphicon glyphicon-minus" aria-hidden="true"></span> Remove All Data Options</button></th>
</tr>
</thead>
<tr>
<td>Item 1
<button type="button" class="btn pull-right remove-selection"><span class="glyphicon glyphicon-minus" aria-hidden="true"></span></button></td>
</tr>
<tr>
<td>Item 2
<button type="button" class="btn pull-right remove-selection"><span class="glyphicon glyphicon-minus" aria-hidden="true"></span></button></td>
</tr>
</table>
jQuery
$(document).ready(function(e) {
$('.add-selection').click(function(){
$(this).closest('tr').find('td').fadeOut("fast");
});
$('.remove-selection').click(function(){
$(this).closest('tr').find('td').fadeOut("fast");
});
});
Here's a full solution that works in both directions and includes changing the classes for the icons.
I added a common class to each table.
HTML Change:
<table class="aside-table items-table">
This single event handler works for both sets of buttons
/* delegate a click handler for both button classes */
$('table.items-table').on('click', '.add-selection, .remove-selection', function(){
/* "this" is the button element instance */
var $btn = $(this).toggleClass('add-selection remove-selection'),
/* define row to be moved by looking up DOM tree*/
$item = $btn.closest('tr'),
/* define other table */
$otherTable = $('.items-table').not( $btn.closest('table'));
/* fade and move to other table */
$item.fadeOut(function(){
/* fade out has finished, can move now */
$otherTable.append($item);
/* switch button icon classes */
$btn.find('span').toggleClass('glyphicon-plus glyphicon-minus')
/* is in new table, can fade in */
$item.fadeIn()
});
});
Note that the clcik event has to be delegated to the table elements since removing an element removes event listeners also
References:
closest() Docs
toggleClass() Docs
DEMO
This is what I did. Updated fiddle here
First I added tbody to the html table element so we can target the data areas.
Then added click events to the table elements instead of buttons so we can use event delegation.
$(document).ready(function() {
$('.aside-table').on('click', '.add-selection', function(){
var $item = $(this).closest('tr');
$item.fadeOut("fast");
var $new = $item.clone();
$new.find('.add-selection').removeClass('add-selection').addClass('remove-selection');
$new.find('.glyphicon').removeClass('glyphicon-plus').addClass('glyphicon-minus');
$('.data-selection-table').find('tbody').append($new);
});
$('.data-selection-table').on('click', '.remove-selection', function(){
var $item = $(this).closest('tr');
$item.fadeOut("fast");
var $new = $item.clone();
$new.find('.remove-selection').removeClass('remove-selection').addClass('add-selection');
$new.find('.glyphicon').removeClass('glyphicon-minus').addClass('glyphicon-plus');
$('.aside-table').find('tbody').append($new);
});
});
If you're not wanting to keep them in order, then basically you can just remove the row, not the cell, and append it to the last row on the other table. You'll need to add another "tbody" tag to the 2nd table so we don't put the rows in the "thead" if there's no rows in the table.
$('.add-selection').on('click', function(){
var $row = $(this)
.closest('tr')
.fadeOut("fast");
$row.detach()
.appendTo($('.aside-table').find('tbody tr:last'))
.find('button')
.removeClass('add-selection')
.addClass('remove-selection')
.find('span')
.removeClass('glyphicon-plus')
.addClass('glyphicon-minus');
});
For the remove function, it'd be the same code w/ the exception of the table class selector, and switch out the classes for the button as well.
Related
I am trying to have a button that, when clicked, will have some jQuery code linked to it. See the general layout below. However, there will be a variable number of rows on the table. All the buttons should have the same action but applied to its parent element. How can I achieve this?
Thanks
td {
border: 1px solid black;
padding: 10px;
}
<table>
<tr>
<td>Info</td>
<td><button class="remove">Remove row</button></td>
</tr>
<tr>
<td>Info</td>
<td><button class="remove">Remove row</button></td>
</tr>
<tr>
<td>Info</td>
<td><button class="remove">Remove row</button></td>
</tr>
</table>
You can do that in several ways, question is tagged with jQuery so the easiest way using jQuery is :
$("button").on("click", function(ev) {
$(this).parents("tr").remove()
});
This will remove tr element when clicked on it's button, you can do what you want inside that anonymous function
The example below does what you need, it will check any click within a table element to see if it matches the required pattern (in this case a button with class .remove), before then actioning the code.
I've added a dynamically added row so you can test it.
If you aren't having dynamically added rows (i.e. they are all there before this code is run) then you can simply use:
$("table button.remove").click( function() {
$(this).closest("tr").remove();
});
// Add click event linked to the table
// Will trigger whenever a button with class .remove is clicked within the table
$( "table" ).on( "click", "button.remove", function() {
// Move up DOM tree to nearest 'tr' and remove it
$(this).closest("tr").remove();
});
// Add click event to add row button
$("#add-row").click( function() {
// Add dynamic row for testing
$("table").append('<tr><td>Info</td><td><button class="remove">Remove row</button></td></tr>');
});
td {
border: 1px solid black;
padding: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<td>Info</td>
<td><button class="remove">Remove row</button></td>
</tr>
</table>
<button id="add-row">Add Row</button>
Try this
let btns = $("button.remove"); // you will select only buttons with remove class
in your case you want something like this :
btns.each(function(){
let btn = $(this);
btn.on('click',()=>{
// your stuff
})
})
i hope it was useful !
My page has a table with two rows, like this:
<table class="table table-condensed">
<tbody>
<tr>
<td class="col-sm-8 room-status" data-roomstatusid="1" data-value="Active" data-edited="false">Active</td>
<td class="col-sm-4"><i class="fas fa-pencil-alt edit-status" style="font-size: 20px;"></i>
<div class="edit-controls hidden"><i class="fas fa-times-circle cancel-status-edit" style="margin-left: 5px;font-size: 20px;"></i><i class="fas fa-save save-status-edit" style="margin-left: 15px;font-size: 20px;"></i>
</div>
</td>
</tr>
<tr id="status-template" class="hidden">
<td class="col-sm-8 room-status" data-roomstatusid="-1" contenteditable="true"></td>
<td class="col-sm-4"><i class="fas fa-pencil-alt edit-status hidden" style="font-size: 20px;"></i>
<div class="edit-controls" data-mode="new"><i class="fas fa-times-circle cancel-status-edit" style="margin-left: 5px;font-size: 20px;"></i><i class="fas fa-save save-status-edit" style="margin-left: 15px;font-size: 20px;"></i>
</div>
</td>
</tr>
</tbody>
</table>
There is a button on the page that adds a row at the start of the table using the html of the hidden #status-template row. All that works fine.
After the new row has been added, I can click the pencil icon on either it or what is now the second row (the one with "Active" in the first cell) and the javascript that detects the click works correctly.
If I click on the first <td> of the inserted row, the javascript that detects that click also works correctly, but if I click the first cell of what is now the second row (which contains "Active", the click is not detected.
My javascript is all delegated to the table element since I know there will be new elements added to the DOM.
The javascript to detect the click on the first <td> of a row looks like this
$('#room-status-table').on('click', 'tbody tr td:first', function() {
if ($(this).hasClass('row-highlight')) {
$(this).removeClass('row-highlight')
} else {
$('#room-status-table tbody tr').each(function() {
$(this)
.find('td:first')
.removeClass('row-highlight')
})
$(this).addClass('row-highlight')
}
})
The javascript to detect the click on the pencil icon is
$('#room-status-table').on('click', '.edit-status', function() {
var cell = $(this).closest('tr').find('.room-status')
$(cell).attr('contenteditable', 'true')
$(cell).focus()
$(this).addClass('hidden')
$(this).next().removeClass('hidden')
$(this).closest('tr').find('td:first').addClass('row-highlight')
})
The code that creates the new row is
$("#new-status").on("click", function() {
var html = "<tr>" + $("#status-template").html() + "</tr>"
$("table > tbody > tr:first").before(html)
$("table > tbody td:first").focus()
$("#edit-room-submit").attr("disabled", "disabled")
})
Grateful for any help in figuring out why the click on the first <td> of the second <tr> is not triggering my click event.
You've misunderstood the delegated selector td:first. What you will want to use is td:first-child.
While :first matches only a single element, the :first-child selector can match more than one i.e. one for each parent. This is equivalent to :nth-child(1).
Replace
.on('click', 'tbody tr td:first', ...)
with
.on('click', 'tbody tr td:first-child', ...)
I just did this at my project. I can share like an example my code which trigger one click and doubleClick at table row added via ajax:
$('table tbody').on('dblclick', 'tr', function(){
if(!$(this).hasClass('tr.selected-row')){
$(this).parent('tbody').find('tr.selected-row, td.selected-row').removeClass('selected-row');
$(this).addClass('selected-row').find('td').addClass('selected-row');
if($(this).find("td a[title='View']").length > 0){
var href = $(this).find("a[title='View']").attr("href");
if(href) {
window.location = href;
}
} else if($(this).find("td a[title='Update']").length > 0){
var href = $(this).find("a[title='Update']").attr("href");
if(href) {
window.location = href;
}
}
}
}).on('click', 'tr', function(){
if(!$(this).hasClass('tr.selected-row')){
$(this).parent('tbody').find('tr.selected-row, td.selected-row').removeClass('selected-row');
$(this).addClass('selected-row').find('td').addClass('selected-row');
}
})
I have a table with rows. In each row there is a "copy to clipboard" button implemented using Clipboard.js
Now I want the table row to be clickable and I want it to redirect to "google.com", if the user clicks anywhere on the row BUT the button.
When the user clicks the button, I want to copy the text to the clipboard, but NOT redirect.
I have tried using the solution suggested in this answer here, but using event.stopPropagation() also disables the Clipboard.js functionality.
Is there an elegant solution for this problem? Here's some code:
<table>
<tr>
<th>Name</th>
<th></th>
</tr>
<tr class='valign-middle' data-href='www.google.com'>
<td>Text</td>
<td>
<button data-clipboard-text='www.facebook.com' id='clipboard-btn'>
<i class="fa fa-clipboard"></i>
</button>
</td>
</tr>
</table>
<script>
// activate Clipboard buttons
var clipboard = new Clipboard('button#clipboard-btn');
// make table rows clickable
$(function(){
$('.table tr[data-href]').each(function(){
$(this).css('cursor','pointer').hover(
function(){
$(this).addClass('active');
},
function(){
$(this).removeClass('active');
}).click( function(event){
document.location = $(this).attr('data-href');
}
);
});
});
</script>
You can have a class for td in tr except for the last one in which your copy button is present, then instead of applying click event on row you can have this click event on each td and then check in click event whether td has that specified class or not, if it has redirect it to google.com else do nothing.
Below is the sample implementation :
<table>
<tr>
<th>Name</th>
<th></th>
</tr>
<tr class='valign-middle' data-href='www.google.com'>
<td class='normalText'>Text</td>
<td>
<button data-clipboard-text='www.facebook.com' id='clipboard-btn'>Copy
<i class="fa fa-clipboard"></i>
</button>
</td>
</tr>
</table>
<script>
var clipboard = new Clipboard('button#clipboard-btn');
// make table rows clickable
(function(){
$('table tr[data-href] td').each(function(){
$(this).css('cursor','pointer').hover(
function(){
$(this).addClass('active');
},
function(){
$(this).removeClass('active');
});
$(this).click( function(event){
if($(this).hasClass("normalText"))
document.location = $(this).parent().attr('data-href');
}
);
});
});
</script>
I can get the id of the data already but the problem how to find that data on html
this is my html
<table cellspacing="0" cellpadding="0" border="0" id="cards" class="table table-striped table-bordered">
<thead>
<tr>
<th>Description</th>
<th>By</th>
<th>Total Votes</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>If the opening scene of this show scared you as a kid, DRINK!</td>
<td>testing testing</td>
<td>1</td>
<td>
<a data-id="1" data-target="#viewCard" data-toggle="modal" class="btn btn-default btn-xs view" href="#"><span class="fa fa-eye"></span> View Card</a>
<a data-id="1" data-target="#editCard" data-toggle="modal" class="btn btn-primary btn-xs edit" href="#"><span class="fa fa-edit"></span> Edit</a>
<a data-id="1" data-target="#deleteCard" data-toggle="modal" class="btn btn-danger btn-xs delete" href="#"><span class="fa fa-remove"></span> Delete</a>
</td>
</tr>
...
</tbody>
</table>
so when the popup out... It will show button and this is the .submitDelete
Delete
and js
$(document).on('click', '.submitDelete', function(e){
e.preventDefault();
var card_id = $(".submitDelete").data('card_id');
var test = $("#cards table tr .delete[data-id='"+card_id+"']"); //<---- idk how to get the tr to be remove... this is what I've tried so far.
console.log(test);
});
EDIT1
I added jsfiddle so you guys know the flow
http://jsfiddle.net/sdxaV/1/
EDIT2
http://jsfiddle.net/sdxaV/12/
Based on the HTML you provided, the .submitDelete element does't have a card_id attribute.
Therefore, change $(".submitDelete").data('card_id') to $(this).attr('data-id') in order to retrieve the correct attribute of the clicked element, rather than the first matching element.
You were also trying to select a table element that is a descendant of a #cards element. The table element has an id of #cards, therefore the selector should be $("table#cards ..."). Or omit table from the selector.
Then to get the closest tr element, chain .closest('tr'):
Working Example
$(document).on('click', '.submitDelete', function(e) {
e.preventDefault();
var card_id = $(this).attr('data-card_id');
var $row = $("table#cards tr .delete[data-id='" + card_id + "']").closest('tr');
$row.remove();
});
I always use jQuery.closest() for this sort of thing. It will navigate up ancestors until it matches.
$(document).on('click', '.submitDelete', function(e){
e.preventDefault();
var test = $(this).closest('tr');
console.log(test);
});
In this circumstance, this is the .submitDelete button that was clicked.
With a Helper Library
The easiest way to do this is instead of making your own method to do this, pull in a library that already wraps the Bootstrap modal like Bootbox. Your example's delete link would be changed to the following:
<a data-id="1" class="btn btn-danger btn-xs delete" href="#"><span class="fa fa-remove"></span> Delete</a>
Your Javascript would be updated to the following:
$(document).on('click', '.delete', function(e){
e.preventDefault();
var $row = $(this).closest('tr');
bootbox.confirm("Are you sure?", function(result) {
$row.remove();
});
});
Notice that we aren't using Bootstrap's HTML attributes to load up the modal anymore. Bootbox is creating the modal for us.
With Vanilla Bootstrap/jQuery
To do this with straight Bootstrap, I would again not use the Bootstrap HTML attributes to directly load up the modal. Something like the following would work. Notice it's not as clean, but this could easily be cleaned up depending on how your JavaScript is setup.
var $row = null;
$(document).on('click', '.delete', function(e){
e.preventDefault();
$row = $(this).closest('tr');
$('#deleteCard').modal();
});
$(document).on('click', '.submitDelete', function(e){
e.preventDefault();
if($row != null) { $row.remove(); $row = null; }
});
One way of cleaning this up would be to put the card id on a data attribute of the modal. It removes the need to store it in a variable somewhere else. Again, cleaning this up requires looking in-depth into what your JavaScript looks like. Good luck.
This is your anchor element <a>:
var test = $("#cards table tr .delete[data-id='"+card_id+"']");
Though it can be shortened. As this will refer to the anchor that was clicked inside the function passed to the on() method. To make it a jQuery object you will need to pass this to $, $( this );.
Now you need to traverse up through the DOM to the table row <tr>. jQuery provides a method called closest() to do this.
var link = $( this );
var tr = link.closest( 'tr' );
// Do what you need to with variable tr.
Is it possible that i can show edit button after right clicking on row of a table? I wanted to inbuilt this functionality in my html page but i am not getting the idea how to do that. MY html page is like this
<table class="table table-hover table-bordered" id="tblData">
<thead>
<tr>
<th>Parameter Names</th>
<th>Parameter Values</th>
<th>Remarks</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>johnrambo#mail.com</td>
<td>John</td>
<td>Rambo</td>
<td>
<a class="btn btn-mini btnEdit">Edit</a>
</td>
</tr>
<tr>
<td>peterparker#mail.com</td>
<td>Peter</td>
<td>Parker</td>
<td>
<a class="btn btn-mini btnEdit">Edit</a>
</td>
</tr>
</tbody>
</table>
When i right click on the row of this table then it should show me edit buttin which i can use to edit the table. TO edit the table i have js file but that is other thing. Main thing I want to make the edit button visible after right click.And also I have use bootstrap to improve the visibility. Please help me to solve this problem.
This code might help you:
on right clicking on specific <tr>
1) no default browser menu opens
2) Show/hide edit link
On clicking on document (both left and right)
1) hide edit link (can be changed accordingly)
<html>
<head>
<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
<style>
.btnEdit{display:none;}
</style>
</head>
<body>
<table class="table table-hover table-bordered" id="tblData">
<thead>
<tr class ='abc' >
<th>Parameter Names</th>
<th>Parameter Values</th>
<th>Remarks</th>
<th></th>
</tr>
</thead>
<tbody>
<tr id = 'John1' class ='abc'> <!-- id=username+userid -->
<td>johnrambo#mail.com</td>
<td>John</td>
<td>Rambo</td>
<td>
<a class="btn btn-mini btnEdit" href='asd.html' >Edit</a>
</td>
</tr>
<tr id = 'Peter1' class ='abc'>
<td>peterparker#mail.com</td>
<td>Peter</td>
<td>Parker</td>
<td>
<a class="btn btn-mini btnEdit" id ="btnEdit" href='asd.html' >Edit</a>
</td>
</tr>
</tbody>
</table>
</body>
</html>
<script>
$(document).ready(function(){
$('.abc').contextmenu(function(){
$('.btnEdit').hide();
var id = $(this).attr('id');
$('#'+id+' .btnEdit').toggle();
return false;
});
$(document).click(function(){
$('.btnEdit').hide();
});
});
</script>
try it here http://jsfiddle.net/f5n9f4po/2/
The event you're looking to capture is window.oncontextmenu. I'm pretty sure you can tie the event to right click by binding it to the tr tags.
(tr selector).oncontextmenu = function () {
toggleEditButton() // callback fn for showing your edit button
return false; // Prevents actual right click menu from showing up
};
Refer to this for more info.
You can handle it using onmousedown event. When you press the mouse button this event will be fired and by checking it's keyCode you can find if it's the right mouse button.
This should serve your purpose.
HTML :
<div onmousedown="showEditButton(event);">Row Content</div>
<button id="editButton" style="display:none;">Edit</button>
javaScript :
function showEditButton(event){
event = event || window.event;
if(event.which == 3){
var button = document.getElementById("editButton");
button.style.display = 'block';
}
}
jsFiddle - javaScript
jQuery :
$("#editableContent").mousedown(function(event){
if(event.which == 3){
$("#editButton").show();
}
});
jsFiddle - jQuery
Resources :
onmousedown , .mouseDown() , event.which
This answer is based on Making custom right-click context menus for my web-app implemented to work for your situation.
JSFiddle
Here's the JQuery:
// Trigger action when the contexmenu is about to be shown
$('.btnEdit').bind("contextmenu", function (event) {
// Avoid the real one
event.preventDefault();
// Show contextmenu
$(".custom-menu").finish().toggle(100).
// In the right position (the mouse)
css({
top: event.pageY + "px",
left: event.pageX + "px"
});
});
// If the document is clicked somewhere
$(document).bind("mousedown", function (e) {
// If the clicked element is not the menu
if (!$(e.target).parents(".custom-menu").length > 0) {
// Hide it
$(".custom-menu").hide();
}
});
// If the menu element is clicked
$(".custom-menu li").click(function () {
// This is the triggered action name
switch ($(this).attr("data-action")) {
// A case for each action. Your actions here
case "edit":
alert("Edited!");
break;
}
// Hide it AFTER the action was triggered
$(".custom-menu").hide();
});