jQuery Find <th></th> which are not empty with Certain Class Name - javascript

I have a script that was working to parse a table to json.
It worked fine like this
<thead id="itemspecthead" class="itemspectheadc">
<tr>
<th class="ishead isheadname">Name</th>
<th class="ishead isheadvalue">Value</th>
</tr>
</thead>
With the script logic:
var headers = [];
$(rows.shift()).find('th:first:not(:empty), th:nth-child(2):not(:empty)').each(function () {
headers.push($(this).text().toLowerCase());
});
But trying to stylize my table, I added a couple other rows to my table header.
<thead id="itemspecthead" class="itemspectheadc">
<tr><td colspan="2" class="tdheader"><span>Item Specifics:</span></td></tr>
<tr><td colspan="2" class="speccaption"><span>(Generated from Unique Values from All Listings)</span><br /></td></tr>
<tr>
<th class="ishead isheadname">Name</th>
<th class="ishead isheadvalue">Value</th>
</tr>
</thead>
If I remove the two extra rows in my thead, the script works fine.
It seems the error is in this logic .find('th:first:not(:empty), th:nth-child(2):not(:empty)')
I've tried changing it to .find('th.ishead:first:not(:empty), and .find('.ishead th:first:not(:empty), to find it via classname with no luck.
How can I target my ishead th rows while keeping the extra colspan="2" rows in my thead?
Here's my onclick function that is now returning name,value,name,value (duplicating it twice for some reason..). This is literally my entire on click function script, I removed everything else.
$(document).on('click', '#editjson', function() {
var headers = [];
$('th.ishead:not(:empty)').each(function () {
headers.push($(this).text().toLowerCase());
});
alert('headers: ' + headers);
console.log(headers);
});
returns name,value,name,value...

Apply :not(:empty) directly to all th (not on any particular-one)
Do like below:-
$(rows.shift()).find('th.ishead:not(:empty)').each(function () {
headers.push($(this).text().toLowerCase());
});
Working sample:-
$(document).ready(function(){
var headers = [];
$('th.ishead:not(:empty)').each(function () {
headers.push($(this).text().toLowerCase());
});
console.log(headers);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<thead id="itemspecthead" class="itemspectheadc">
<tr><td colspan="2" class="tdheader"><span>Item Specifics:</span></td></tr>
<tr><td colspan="2" class="speccaption"><span>(Generated from Unique Values from All Listings)</span><br /></td></tr>
<tr>
<th class="ishead isheadname">Name</th>
<th class="ishead isheadvalue">Value</th>
</tr>
</thead>
</table>

Related

Datatable undefined error obtaining row data

I'm having an error getting the data of a row in Datatables and I can't figure it out why it's happening.
Reading the Docs, getting the row data it's as simple as:
var table = $('#example').DataTable();
$('#example tbody').on( 'click', 'tr', function () {
console.log( table.row( this ).data() );
} );
So, I've a Jinja2 template that it's filled in server-side (in Python 3 using flask):
<table id="table" class="dataTable display responsive nowrap" cellspacing="0" width="100%">
<thead>
.....
</thead>
<tbody>
.....
</tbody>
</table>
And I initialize the Datatable with:
function createDatatable() {
$('#table').DataTable({
"select": "single",
"order": [[2, "asc"]],
"language": {.....}
}
});
}
And attach some events:
function attachEvents() {
$('#table tbody').on('click', 'td.tdCredits', function () {
var table = $('#table').DataTable();
var rowId = table.row(this).data()[0];
});
.....
}
Then I do:
$(document).ready(function() {
createDatatable();
attachEvents();
});
So, when I want to get the data of the row that I've clicked (regardless of whether it is selected or not) with this code I get an error on the console:
TypeError: table.row(...).data(...) is undefined
What I'm doing wrong? Because I can see the table rendered, with the pagination buttons and I can order the columns as well.
$(document).ready(function() {
createDatatable();
attachEvents();
});
function createDatatable() {
$('#table').DataTable({
"select": "single",
"order": [[2, "asc"]]
});
}
function attachEvents() {
$('#table tbody').on('click', 'td.tdCredits', function () {
var table = $('#table').DataTable();
var rowData = table.row(this).data();
console.log('Clicked row data: ' + rowData);
var rowId = table.row(this).id();
console.log('Clicked row id: ' + rowId);
// Other code
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.datatables.net/1.10.20/js/jquery.dataTables.min.js"></script>
<link href="https://cdn.datatables.net/1.10.20/css/jquery.dataTables.min.css" rel="stylesheet"/>
<table id="table" class="dataTable display responsive nowrap" cellspacing="0" width="100%">
<thead>
<tr>
<th style="display: none;"></th>
<th class="text-center">Header 1</th>
<th class="text-center">Header 2</th>
<th class="text-center">Header 3</th>
<th class="text-center">Header 4</th>
<th class="text-center">Header 5</th>
<th class="text-center">Header 6</th>
<th class="text-center">Header 7</th>
</tr>
</thead>
<tbody>
<tr id="someId" class="filter">
<td style="display: none;"></td>
<td class="text-center">Cell 1</td>
<td class="text-center">Cell 2</td>
<td class="text-center">Cell 3</td>
<td class="text-center">Cell 4</td>
<td class="text-center tdCredits">Click here</td>
<td class="text-center">Cell 6</td>
<td class="text-center">Cell 7</td>
</tr>
</tbody>
</table>
You have a typo. Your variable is initialized as "table" and then you call "tabla". "Tabla" does not exist so it is undefined.
$('#table tbody').on('click', 'td.tdCredits', function () {
var table = $('#table').DataTable();
var rowId = table.row(this).data()[0];
});
Ok, I've found a trick that solved my problem and I don't need to access the '.data()'.
The problem I was having is due as you can edit some fields on each row, so the first time you click in one of the filds of the row, the row it's selected so you can use:
table.row({ selected: true }).index();
But if you click again on other field, the row is deselected and the filter selected:true doesn't work.
Doing the fiddle I discovered that Datatables uses the ID specified in
<tr id="someId" ..>
instead of some internal value. So I pass the ID value to my method and force the row to be selected:
table.row('#' + id).select();
And then I can use:
var rowIndex = table.row({ selected: true }).index();
And update the proper field instead the field of the first visible row:
table.cell({row:rowIndex, column:columnIndex}).data(newValue).draw();
Regards!
You are using array notation data[0] to access your data. But maybe you defined columns.data which means your data is an object.
you can use this.
data["nameofYourColumn"]

Check dynamic Bootstrap Table for class

So i got this table
<table id="table" class="table table-bordered table-hover">
<thead>
<tr>
<th data-field="id" class="hidden">ID</th>
<th data-field="variant">Variant</th>
<th data-field="description">Description</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
it will be filled with data trough
$('#table').bootstrapTable({
data: returnValue
});
then i can click the rows which will add the class .bg-info to it and i want to check if a row has the class and then save the row data in a var
this was my attempt:
var item = $.map(table.rows('.bg-info').data(), function (item) {
return item[0]
});
but table.rows can't be used as a method apparently
If you want to select all the rows with the class bg-info in your table. Use a jQuery selector based on that class :
var bgInfoRows = $("#table tbody .bg-info");
You will have every item in tbody that has the class bg-info.

How can I target a table cell in the same row with jQuery?

I have a table with a single input field and an AJAX script that runs when the input field value is modified. This is all working well. I now need to extend this to insert a date into another cell in the same row, but now sure how to target this as the ID will have to be dynamic. Here's the current table:
<table class="table table-condensed table-striped table-bordered">
<thead>
<th class="text-center" scope="col">Order Number</th>
<th class="text-center" scope="col">Order Date</th>
<th class="text-center" scope="col">Con Note</th>
</thead>
<tbody>
<tr>
<td>123456</td>
<td id="85759.OrderDate"></td>
<td id="85759"><input type="text" class="form-control" placeholder="Con Note" name="conNote" value=""></td>
</tr>
<tr>
<td>987654</td>
<td id="85760.OrderDate"></td>
<td id="85760"><input type="text" class="form-control" placeholder="Con Note" name="conNote" value=""></td>
</tr>
</tbody>
</table>
I need to insert the current data into the Order Data cell when the AJAX script is run, something like this:
$("#85759.OrderDate").html('current date');
but not sure how to dynamically target the Order Data cell? I'm setting the ID for the Order Data cell to be the same ID as the input field with ".OrderDate" appended. Current script is:
$(document).ready(function() {
$("input[type='text']").change(function() {
var recid = $(this).closest('td').attr('id');
var conNote = $(this).val();
$this = $(this);
$.post('updateOrder.php', {
type: 'updateOrder',
recid: recid,
conNote: conNote
}, function(data) {
data = JSON.parse(data);
if (data.error) {
var ajaxError = (data.text);
var errorAlert = 'There was an error updating the Con Note Number - ' + ajaxError;
$this.closest('td').addClass("has-error");
$("#serialNumberError").html(errorAlert);
$("#serialNumberError").show();
return; // stop executing this function any further
} else {
$this.closest('td').addClass("has-success")
$this.closest('td').removeClass("has-error");
}
}).fail(function(xhr) {
var httpStatus = (xhr.status);
var ajaxError = 'There was an error updating the Con Note Number - AJAX request error. HTTP Status: ' + httpStatus;
$this.closest('td').addClass("has-error");
//display AJAX error details
$("#serialNumberError").html(ajaxError);
$("#serialNumberError").show();
});
});
});
You can get the parent element 'tr' and then find the 'td.OrderDate', I suggest you to use a class to identify the td in the context of its parent.
$(function () {
$("input[type='text']").change(function() {
var parent = $(this).parents('tr');
// Get any element inside the tr
$('td.OrderDate', parent).text('[current date]')
})
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td>987654</td>
<td id="85760.OrderDate" class="OrderDate"></td>
<td id="85760"><input type="text" class="form-control" placeholder="Con Note" name="conNote" value=""></td>
</tr>
</table>
You can select the cell by $this.closest('tr').children('td[id$="OrderDate"]').
You can simplify it more by:
Instead of using attribute ends with selector ([id$=".."]), if you can, add a CSS class "OrderDate" for example to all the order date cells, and simplify the selector to $this.closest('tr').children('.OrderData')
Instead of closest() use parents(). This is a micro-optimization. The only difference is that closest tests the actual element itself for matching the selector, and in this case you know you only need to check parent elements
You can also optionally rely on the fact that the cells are siblings and instead of children use siblings like like$this.parents('td').siblings('.OrderDate')
Check the code below. I've removed the ajax call and replaced it with the success block, but the concept is still the same. It gets the cell that has an id that ends with "OrderDate" on the same row and sets the html for that cell. I've used the jQuery Ends With selector for this.
$(document).ready(function() {
$("input[type='text']").change(function() {
var recid = $(this).closest('td').attr('id');
var conNote = $(this).val();
var $this = $(this);
$this.parents('tr:first').find("td[id$='OrderDate']").html(new Date());
$this.closest('td').addClass("has-success")
$this.closest('td').removeClass("has-error");
});
});
.has-success {
border: 1px solid green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="table table-condensed table-striped table-bordered">
<thead>
<th class="text-center" scope="col">Order Number</th>
<th class="text-center" scope="col">Order Date</th>
<th class="text-center" scope="col">Con Note</th>
</thead>
<tbody>
<tr>
<td>123456</td>
<td id="85759.OrderDate"></td>
<td id="85759"><input type="text" class="form-control" placeholder="Con Note" name="conNote" value=""></td>
</tr>
<tr>
<td>987654</td>
<td id="85760.OrderDate"></td>
<td id="85760"><input type="text" class="form-control" placeholder="Con Note" name="conNote" value=""></td>
</tr>
</tbody>
</table>

How to iterate over filtered rows in Angular datatable

Lets say, I have simple datatable
<table datatable="" dt-options="dtOptions" dt-column-defs="dtColumnDefs" class="row-border hover">
<thead>
<th>ID</th>
<th>Name</th>
</thead>
<tbody>
<tr ng-repeat"reservation in reservations">
<td>{{reservation.ID}}</td><td>{{reservation.name}}</td>
</tr>
</tbody>
</table>
When I put some string into search box datatable is being filtered. Now I want to iterate in Angular over filtered rows and read IDs to array. How to deal with it in Angular? I can use jquery but I do not want make a mess in code.
$scope.addressDTInstance = {};
var j = $scope.addressDTInstance.DataTable.rows();
<table id="addressSelectionTable" class="table table-condensed table-bordered" datatable="ng" dt-options="addressdtOptions" dt-column-defs="addressdtColumnDefs" dt-instance="addressDTInstance">
This is something to get you on your way. Need an instance of dtInstance which you don't have. So add dt-instance='dtInstance' in the html table tag.
Then initiate it at the top of your controller, $scope.dtInstance = {};.
Perform a click or some action in your javascript that you can set a break point on and then examine your $scope.dtInstance to see what all properties and methods you have. As you see in my snippet I'm accessing DataTable.Rows of my dtInstance. If you need better example or help let leave me a comment and I'll revise.
UPDATE
Here is a method I found that works. I am ofcourse using the DTOptionsbuilder. This will get called twice, first when it is created and second when i populated the array variable that is populating my table. I just check to see if rows exist and that the first one isn't 'No results'.
$scope.addressdtOptions = DTOptionsBuilder.newOptions()
.withOption('bFilter', false)
.withOption('bInfo', false)
.withOption('paging', false)
.withOption('processing', true)
.withOption('aaSorting', [1, 'asc'])
.withOption('language', { zeroRecords: 'No results' })
.withOption('initComplete', function () {
var rows = $("#addressSelectionTable > tbody > tr");
if (rows.length > 0 && rows[0].innerText !== "No results") {
var x = 3;
}
});
Here i am setting that variable that is ng-repeat for table. You may not be doing it my way, but you should be able to figure it out for your way.
$.when($OfficerService.GetAddressSelections($scope.officer.EntityID, $scope.officer.EntityTypeID, $scope.officer.MemberID)).then(function (result) {
$scope.addresses = result.data;
$scope.$applyAsync();
});
<table id="addressSelectionTable" class="table table-condensed table-bordered" datatable="ng" dt-options="addressdtOptions" dt-column-defs="addressdtColumnDefs" dt-instance="addressDTInstance">
<thead>
<tr>
<th></th>
<th>Type</th>
<th>Address</th>
<th>City</th>
<th>State</th>
<th>Zip</th>
<th>Country</th>
<th></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="a in addresses">
<td class="centerColumn">
<input type="button" class="btn btn-primary" value="Select" ng-click="selectAddress(a.AddressID,a.AddressLocationCode,$event)" />
</td>
<td>
<span ng-if="a.AddressLocationCode == 'E'">Office</span>
<span ng-if="a.AddressLocationCode == 'M'">Member</span>
</td>
<td>
{{a.AddressLine1}}
<span ng-if="a.AddressLine2 != null"><br /> {{a.AddressLine2}}</span>
</td>
<td>{{a.City}}</td>
<td>{{a.StateCode}}</td>
<td>{{a.Zip}}</td>
<td>{{a.CountryCode}}</td>
<td>{{a.AddressID}}</td>
</tr>
</tbody>
</table>
For me it works: $scope.dtInstance.DataTable.rows( { search: 'applied' } ).data()

Getting TD value from TR

I'm new to Javascript and I'm having trouble to get the value from a <td>.
Here is some code to illustrate the problem:
<div id="lista_ativo">
<table class="tabela-basica" width="100%" cellpadding="0px" cellspacing="0px">
<thead>
<tr>
<th width="35px">ID</th>
<th width="200px">Cliente</th>
<th width="200px">Nome</th>
<th width="35px">OAB</th>
<th width="50px">Estado</th>
</tr>
</thead>
<tbody>
<tr class="{classe_row}">
<td data-id="{andamentos_ativos.clienteid}">{andamentos_ativos.clienteid}</td>
<td>{andamentos_ativos.cliente}</td>
<td>{andamentos_ativos.nome}</td>
<td>{andamentos_ativos.oab} / {andamentos_ativos.oab_uf}</td>
<td>{andamentos_ativos.estados}</td>
</tr>
</tbody>
</table>
</div>
My Javascript:
$("#lista_ativo").delegate("tr", "click", function() {
var idbcorporativo = $(this).attr("data-id");
console.log(idbcorporativo);
});
I need the data-id from the first <td>.
You need to go from the tr to the th.
And then reference to the first child beginning by 0.
var idbcorporativo = $(this).children()[0].attr("data-id");
you can try using getAttribute
document.getElementsByTagName("td")[0].getAttribute("data-id");
or with jQuery you can modify your code to
$("#lista_ativo").delegate("tbody tr", "click", function() {
var idbcorporativo = $(this).children().attr("data-id");
console.log(idbcorporativo);
});
here's the example fiddle

Categories

Resources