Summary: I have a html page which consists of two add buttons and two tables. When add button is clicked, rows are appended to respective table. In the back end i want to collect all the row elements when "button" is clicked and POST to other page.
<div class="report">
<div class="panel">
<div>
<button type="button" class="add btn btn-primary" data-toggle="tooltip" title="Add to configuration list.">
<i class="fa fa-plus"></i>
Add
</button>
</div>
<div class ="configuration-table panel-body">
<table class="table table-striped table-bordered table-condensed">
<thead>
<tr>
<th>Remove</th>
<th>Layer</th>
<th>Display</th>
<th>Unit</th>
<th>Dataset</th>
<th>Ordering</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
<div class = "done">
<input class="btn btn-success" formaction="{% url 'something' %}" formmethod="post" type="submit" value="Done"></input>
</div>
</div>
and here is reports.js
var arr = [];
$('.report')
.on('click','.add', function(){
$(this)
.parents('.report')
.find('.configuration-table tbody')
.append(
'<tr>'+
'<td class="remove-row" role="button" aria-label="Remove Region"><i class="fa fa-times" title="Remove this row." data-toggle="tooltip" data-placement="right" aria-hidden="true"></i></td>'+
'<td>'+layer_text+'</td>'+
map_elements+
'<td>'+unit_text+'</td>'+
'<td>'+dataset_text+'</td>'+
'<td class="ordering" aria-label="Re-order"><i class="fa fa-arrows" title="Re-arrange row order." data-toggle="tooltip" data-placement="right"></i></td>'+
'</tr>'
)
.on('click','.remove-row',function() {
$(this).parents('tr').remove();
})
.sortable({
helper: script
})
.disableSelection();
.on('submit','.done form',function(){
//do domething to collect columns
$('.configuration-table tbody').each(function(){
arr.push({
column.name: column.value
});
});
})
Here as you can see that table rows can be removed/sortable. Dont worry about POST method now. I just need the logic to collect columns from the table after done button is clicked.
Assume script is correct in terms of class names and traversal-filters. I just need the logic to collect column elements and push to "arr".
Thanks in advance
Firstly, you need to loop over the th elements within the thead to get the column names, then the tr in the tbody to get the values. You can get the text() properties from each respective td to fill object. Try this:
.on('submit','.done form',function() {
var arr = [];
var $table = $('.configuration-table');
var columnNames = $table.find('thead th').map(function() {
return $(this).text();
});
$table.find('tbody tr').each(function(){
var rowValues = {};
$(this).find('td').each(function(i) {
rowValues[columnNames[i]] = $(this).text();
});
arr.push(rowValues);
});
});
Example fiddle
Related
I want to open up either picture a or b (if available) with fancybox 3 from any td without a certain class. The pictures should be shown as they are when clicking on the button.
I have included bootstrap, fancybox and jquery. Also i use icons from material icons. Fancybox works perfectly when opening from button.
<table>
<tbody>
<tr>
<td style="cursor:pointer" id="abc">
abc
</td>
<td style="cursor:pointer" id="def">
def
</td>
<td class="1234">
<div class="btn-group float-right" role="group"style="display:flex;">
<#if a??>
<a type="button" class="btn btn-secondary btn-sm"
data-fancybox="test" data-type="image"
data-thumb="${a}" data caption="abc" rel="group"
href="${a}" title="View browser screenshot">
<i class="material-icons md-14"
aria hidden="true">photo_camera</i>
</a>
</#if>
<#if b??>
<a type="button" class="btn btn-secondary btn-sm"
data-fancybox="test" data-type="image"
data-thumb="${a}" data caption="abc"
rel="group" href="${a}"
title="View browser screenshot">
<i class="material-icons md-14"
aria-hidden="true">remove_red_eye</i>
</a>
</#if>`
</div>
</td>
</tr>
</tbody>
</table>
I tried this jquery code:
(Solution for another fancybox question on SO)
$(".table > tbody > tr > td").bind('click',function(e) {
e.stopPropagation();
if (!$(this).hasClass("1234")) {
$(this).find("a").trigger('click');
}
});
and (obviously for tr insted of td)
$('.table > tbody > tr').click(function () {
$(this).addClass('active').siblings().removeClass('active');
});
and
$(document).ready(function(){
$('td').on('click', function() {
if (!$(this).hasClass("1234")) {
$.fancybox();
}
});
});
Simply remove all your fancybox related tags from <a> element and add to <td> element, because it does not matter what HTML elements are you using as trigger elements for fancybox.
If some body is interested in the way i found a solution:
$(document).ready(function(){
$(".table > tbody > tr > td").bind('click',function(e) {
var name = $(this).attr('name');
e.stopPropagation();
if (!$(this).hasClass("1234")) {
$("#" + name).find("a:first").trigger('click');
}
});
});
I have a table, with innumerable rows, when I click the button, I need to get the line id that the button is clicked on. How can I do this?
my attempt code:
function teste(){
$('table tr').each(function(){
var name = $(this).parent().find('.idServico').html();
alert(name);
});
}
my table that my js generate:
tabelaResultado.innerHTML += `
<tr>
<td class="idServico">${idServico}</td>
<td>${dataEntradaServico}</td>
<td>${dataSaidaServico}</td>
<td>${cpfPessoa}</td>
<td>${idStatus}</td>
<td>${descricaoServico}</td>
<td class="actions tirarCor">
<a class="btn btn-success btn-xs" href="/updateService">Visualizar</a>
<a class="btn btn-warning btn-xs" href="/updateService">Editar</a>
<button id="botaoExcluir" class="btn btn-danger btn-xs" onclick="teste()"data-toggle="modal" data-target="#delete-modal">Excluir</button>
</td>
</tr>
Remove the inline event handler from your button and setup an event listener with jQuery. Then you can use $(this) to refer to the button being clicked, .closest() to traverse upward to the parent <tr>, and .find() to get the <td> with the class idServico:
$('button.btn.btn-danger.btn-xs').click(function(){
var name = $(this).closest('tr').find('td.idServico').html();
alert(name);
})
If the rows are being added dynamically, you should instead use a delegated event handler:
$(document).on('click' ,'button.btn.btn-danger.btn-xs' ,function(){
var name = $(this).closest('tr').find('td.idServico').html();
alert(name);
})
i am trying to use the dynamic table at
https://codepen.io/ashblue/pen/mCtuA
I want to have a button that deletes all rows from the table. SO basically, fire the click function on all instances of the class .table-remove
i tried to do the following
function deleteAll() {
jQuery('.table-remove').each(function() {
var currentElement = $(this);
console.log(currentElement);
currentElement.trigger('click');
});
}
where the click is defined as
$('.table-remove').click(function() {
console.log("triggered");
$(this).parents('tr').detach();
});
but nothing happens when i call the deleteAll function. i dont even se anything on the console
am i doing this right?
I want to have a button that deletes all rows from the table. So basically, fire the click function on all instances of the class .table-remove.
You could do it that way but it's far simpler to organise your table into :
a <thead> containing the header row
a <tbody> containing the visible row(s)
a <tbody> containing the row template
Thus, the code behind the "Delete All" button can very simply select all rows in the first <tbody> and .remove() them.
HTML
<div class="container">
<h1>HTML5 Editable Table</h1>
<p>Through the powers of <strong>contenteditable</strong> and some simple jQuery you can easily create a custom editable table. No need for a robust JavaScript library anymore these days.</p>
<ul>
<li>An editable table that exports a hash array. Dynamically compiles rows from headers</li>
<li>Simple / powerful features such as add row, remove row, move row up/down.</li>
</ul>
<div id="table" class="table-editable">
<span class="table-add glyphicon glyphicon-plus"></span>
<table class="table">
<thead> <!-- <<<< wrap the header row in <thead>...</thead> -->
<tr>
<th>Name</th>
<th>Value</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody class="main"> <!-- <<<< wrap the visible row(s) in <tbody>...</tbody> -->
<tr>
<td contenteditable="true">Stir Fry</td>
<td contenteditable="true">stir-fry</td>
<td>
<span class="table-remove glyphicon glyphicon-remove"></span>
</td>
<td>
<span class="table-up glyphicon glyphicon-arrow-up"></span>
<span class="table-down glyphicon glyphicon-arrow-down"></span>
</td>
</tr>
</tbody>
<tbody class="hide"> <!-- <<<< wrap the template row in its own hidden <tbody>...</tbody> -->
<tr>
<td contenteditable="true">Untitled</td>
<td contenteditable="true">undefined</td>
<td>
<span class="table-remove glyphicon glyphicon-remove"></span>
</td>
<td>
<span class="table-up glyphicon glyphicon-arrow-up"></span>
<span class="table-down glyphicon glyphicon-arrow-down"></span>
</td>
</tr>
</tbody>
</table>
</div>
<button id="export-btn" class="btn btn-primary">Export Data</button>
<button id="deleteAll-btn" class="btn btn-primary">Delete All</button>
<p id="export"></p>
</div>
Another aspect is how best to attach click handlers to the three row actions - delete, move-up and move-down.
As the rows are created/appended dynamically, the way to go is to delegate click handling to a container (eg the table) using jQuery's $(static-container).on(event, descendent-selector, handler). This will attach the desired actions to all current rows, and future rows just by appending them.
Javascript
jQuery(function($) {
var $TABLE = $('#table table');
var $BTN = $('#export-btn');
var $BTN2 = $('#deleteAll-btn');
var $EXPORT = $('#export');
$('.table-add').on('click', function() {
$('tbody.hide tr', $TABLE).clone(true).appendTo($('tbody.main', $TABLE));
});
$TABLE.on('click', '.table-remove', function() { // delegate row removal to the table
$(this).closest('tr').remove();
});
$TABLE.on('click', '.table-up', function() { // delegate row-up movement to the table
var $row = $(this).closest('tr');
$row.insertBefore($row.prev());
});
$TABLE.on('click', '.table-down', function() { // delegate row-down movement to the table
var $row = $(this).closest('tr');
$row.insertAfter($row.next());
});
$BTN.on('click', function() {
var $headers = $('thead th', $TABLE).not(':empty').map(function() {
return $(this).text().toLowerCase();
});
var $data = $('tbody.main tr', $TABLE).map(function() {
var $td = $(this).find('td'),
h = {};
$headers.each(function(i, header) {
h[header] = $td.eq(i).text();
});
return h;
});
$EXPORT.text(JSON.stringify($headers.get().concat($data.get())));
});
$BTN2.on('click', function deleteAll() {
$("tbody.main tr", $TABLE).remove();
});
});
DEMO.
If the goal is just to remove the rows, you can do that directly without triggering each individual click event:
function deleteAll() {
$('.table-remove').closest('tr').remove()
}
If you really need to trigger the click event on each '.table-remove' element, you would do that like so:
function deleteAll() {
$('.table-remove').each(function() {
$(this).trigger('click')
});
}
(...which is roughly equivalent to your existing code. I'm not sure why your existing code isn't working for you; perhaps it's down to your use of jQuery() instead of the $() alias, or you're just not calling the deleteAll() function successfully?)
I have a VIEW where I display a table with 15 records (15 rows) and 5 columns, but the very thing that matters is a column, "Actions". In it I have 1 button, "Preview", that when clicking, I want to open a window with a message, for tests.
However, only the first record, when clicking the "View" button, displays the message window, the other 14 records do not.
How do I make all records / lines display the message?
Follow the code below:
<table class="table table-bordered table-hover tablesorter">
<thead>
<tr>
<th class="header text-center" style="width: 100px;"> Ações </th>
</tr>
</thead>
<tbody id="tabela">
#foreach (var item in Model)
{
<tr>
<td>
#this.Hidden("IdClient").Value(item.Id)
<a id="visualizarCliente" class="btn btn-primary btn-xs btn-visualizar" data-toggle="tooltip" title="Visualizar" target="_blank"
href="#Url.Action(MVC.Painel.Clientes.Visualizar(item.Id))">
<i class="fa fa-eye"></i>
</a>
</td>
</tr>
}
</tbody>
</table>
<script type="text/javascript">
$(function () {
$("#visualizarCliente").click(function () {
var idCliente = $("#IdClient").val();
window.alert("Teste");
})
});
</script>
The problem is that you are using the id selector and it can not be repeated. Switch to any other selector, such as data-toggle = "tooltip" for example.
<script type="text/javascript">
$(function () {
$("a[data-toggle='tooltip']").click(function () {
window.alert("Teste");
})
});
</script>
The problem is ID which always be used for something UNIQUE. Try to use CLASS instead. Your function should goes something like this one example:
$(function () {
$(".btn-visualizar").click(function () {
var idCliente = $(this).parent().find("#IdClient").val();
window.alert("Teste");
})
});
In the given example the line $(this).parent().find("#IdClient").val(); specifies that this would be it's nearest element value as it should be.
Summary: I have a html page which consists of two add buttons and two tables. When add button is clicked, rows are appended to respective table. I have included two templates with two different parent ids into one html template. I need to write the script in such a way that when add-btn having parentid == "#a" is clicked ,append rows to table having parentid =="#a".
result.html
//i am using django web framework
<div class="reports">
{% include 'template1.html' with id="a" %}
{% include 'template2.html' with id="b" %}
</div>
Each template shares/extends a base.html template where all the common code is written
<div class="panel">
<div>
<button type="button" class="add btn btn-primary" data-toggle="tooltip" title="Add to configuration list.">
<i class="fa fa-plus"></i>
Add
</button>
</div>
<div class ="configuration-table panel-body">
<table class="table table-striped table-bordered table-condensed">
<thead>
<tr>
<th>Remove</th>
<th>Layer</th>
<th>Display</th>
<th>Unit</th>
<th>Dataset</th>
<th>Ordering</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
and my jquery code is
result.js
$('.reports').on('click','#a .add, #b .add', function(e) {
//how to differentiate two tables here.
$(this).find('configuration-table table').children('tbody')
.append(
'<tr>'+
'<td class="remove-row" role="button" aria-label="Remove Region"><i class="fa fa-times" title="Remove this row." data-toggle="tooltip" data-placement="right" aria-hidden="true"></i></td>'+
'<td>'+layer_text+'</td>'+
map_elements+
'<td>'+unit_text+'</td>'+
'<td>'+dataset_text+'</td>'+
'<td class="ordering" aria-label="Re-order"><i class="fa fa-arrows" title="Re-arrange row order." data-toggle="tooltip" data-placement="right"></i></td>'+
'</tr>'
);
Issue: When i click add button, the row is appending to both the tables. and i dont want that. i want to add rows to the respective table. And i want to do that within same function.
I am looking for logic that i am missing here.
Thanks in advance
Your code is using find which looks for a child of the button. It is not a child, it is a sibling of the parent div of the button.
$(this) //button that was clicked
.parent() //div around the button
.sibling(".configuration-table") //sibling element that has the table
.find("table tbody") //the table
.append(tableRow);
Firstly as per markup, there is no parent child relation between add button and table. Though, there can be many ways of fixing this issue. Proposing 1 option below
Let us say you have both buttons with class add and a data attribute (data-id) containing id of table.
i.e. 1st button having data-id="a" and second button having data-id="b" where a and b are the ids of respective tables.
Now update your js to following
.on('click','.add', function(e) {
var table_id = $(this).data("id");
$("#"+table_id).children('tbody').append..... // your code
}