Ajax append one row instead of array - javascript

I have an ajax function that gets an array of data from the backend and when I try to append those data in the blade it only shows 1 row instead of an array of rows.
Issues
Only 1 row append by ajax
Select option will be empty when results return while I don't have any code to clear my select option.
Code
$(function() {
// get cities
$('#province').on('change', function(e) {
e.preventDefault();
$.ajaxSetup({
headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') }
});
var hospitalId = $(this).val();
$.ajax({
url: '{{ url('hospitals') }}/'+encodeURI(hospitalId),
dataType: "json",
type: 'GET',
success: function(data) {
console.log('dd: ', data.data);
if(data.data != null) {
$('.resError').hide();
$('.result').show();
// data to append
$.each(data.data, function(key, value) {
$('#code').html(value.code);
$('#name').html(value.name);
$('#type').html(value.type);
$('#class').html(value.class);
$('#beds').html(value.beds);
$('#owner').html(value.owner);
$('#province').html(value.province);
$('#city').html(value.city);
$('#address').html(value.address);
});
} else {
$('.resError').show();
$('.result').hide();
$('.resError').html('something went wrong, try again!');
}
},
error:function(err) {
$('.resError').show();
$('.resError').html('You need to select province!');
$('.result').hide();
$('#code').html('');
$('#name').html('');
$('#type').html('');
$('#class').html('');
$('#beds').html('');
$('#owner').html('');
$('#province').html('');
$('#city').html('');
$('#address').html('');
}
});
});
});
results
Update
<p>Results</p>
<div class="resError clearfix mt-4" style="display:none;"></div>
<div class="result clearfix mt-4" style="display:none;">
<table class="mb-3 table table-bordered table-hover">
<tbody>​​​
<tr>
<th width="50">Code</th>
<td id="code"></td>
</tr>
<tr>
<th width="50">Name</th>
<td id="name"></td>
</tr>
<tr>
<th width="50">Type</th>
<td id="type"></td>
</tr>
<tr>
<th width="50">Class</th>
<td id="class"></td>
</tr>
<tr>
<th width="50">Beds</th>
<td id="beds"></td>
</tr>
<tr>
<th width="50">Owner</th>
<td id="owner"></td>
</tr>
<tr>
<th width="50">Province</th>
<td id="province"></td>
</tr>
<tr>
<th width="50">City</th>
<td id="city"></td>
</tr>
<tr>
<th width="50">Address</th>
<td id="address"></td>
</tr>
</tbody>
</table>
</div>

in blade
<p>Results</p>
<div class="resError clearfix mt-4" style="display:none;"></div>
<div class="result clearfix mt-4" style="display:none;">
<table class="mb-3 table table-bordered table-hover">
<tbody id="body">​​​
</tbody>
</table>
</div>
in javascript
$.each(data.data, function(key, value) {
var element = `
<tr>
<th width="50">Code</th>
<td id="code">${value.code}</td>
</tr>
<tr>
<th width="50">Name</th>
<td id="name">${value.name}</td>
</tr>
<tr>
<th width="50">Type</th>
<td id="type">${value.type}</td>
</tr>
<tr>
<th width="50">Class</th>
<td id="class">${value.class}</td>
</tr>
<tr>
<th width="50">Beds</th>
<td id="beds">${value.beds}</td>
</tr>
<tr>
<th width="50">Owner</th>
<td id="owner">${value.owner}</td>
</tr>
<tr>
<th width="50">Province</th>
<td id="province">${value.province}</td>
</tr>
<tr>
<th width="50">City</th>
<td id="city">${value.city}</td>
</tr>
<tr>
<th width="50">Address</th>
<td id="address">${value.address}</td>
</tr>
`;
$('#body')append(element);
});

In your below code, you are appending value by the fieldId, that's why it is only appending only the last row(each iteration, the value is being updated in background) values are being set.
$('#code').html(value.code);
$('#name').html(value.name);
$('#type').html(value.type);
$('#class').html(value.class);
$('#beds').html(value.beds);
$('#owner').html(value.owner);
$('#province').html(value.province);
$('#city').html(value.city);
$('#address').html(value.address);
So, to achieve your purpose, you have to append these as a complete row and insert into the table, not just appending fieldwise value but rowwise and insert that row into the table. I hope you get my point.

The problem is that you are always changing the same elements of the same table. I think you will need to append one table per row:
$.each(data.data, function(key, value) {
$(".result").append('<table class="mb-3 table table-bordered table-hover">...</table>')
});
However, you may want to use Handlebars or some other templating library to avoid creating a long string with the table.

Related

Dynamically added table data and table rows have zero height

I am using angular.element to dynamically inject table data into my table. Onload my table already has data, when I double click on the content it hides the old tbody and shows the new tbody where the dynamic data needs to be added and this tbody contains a form as well to send the edited data.
here's the html:
<table class="table table-striped table-bordered table-hover">
<thead>
<tr>
<td class="text-center"><b>Code</b></td>
<td class="text-center"><b>Particulars</b></td>
<td class="text-center"><b>Amount(Rs. in lakh)</b></td>
</tr>
</thead>
<tbody ng-if="loading == false && iseditstmt == false">
<tr ng-repeat="b in blsheetinfo">
<td class="text-left"><b>{{b.key}}</b></td>
<td class="text-left">{{b.particular}}</td>
<td class="text-right" ng-dblclick="editstmt();editRec(blsheetinfo,'edit','stmtupdate');">{{b.amt}}</td>
</tr>
<tr ng-if="blsheetinfo == null">
<td class="text-center" colspan="3">No data found.</td>
</tr>
</tbody>
<tbody ng-if="iseditstmt == true">
<form role="form" ng-submit="updatestmt(data)" name="updatedata" id="updatedata" >
</form>
</tbody>
<tr ng-if="loading == 1"><td class="text-center" colspan="3">Loading...</td></tr>
</table>
This is the js code:
var HTMLcontent = "";
angular.forEach($scope.blsheetinfo, function (d) {
HTMLcontent += `<tr class="form-group">
<td class="text-left " ng-model="frmdata.key" name="key" id="key" ><b> `+d.key+`</b></td>
<td class="text-left" ng-model="frmdata.particular" name="particular" id="particular" >`+d.particular+`</td>
<td class="text-right" ng-model="frmdata.amt" name="amt" id="amt" ><input class="form-control" type="text">`+d.amt+`</td>
</tr>`
});
setTimeout(function(
)
{
// angular.element("#updatedata").html(HTMLcontent);
// tried both of these options
angular.element("#updatedata").append(HTMLcontent);
},2000);
The problems that I am facing are that it looks like my data is being added to the DOM but i am not able to see it. The tbody element has height set to 0

How can I hide <tr> if it's <td> is empty

I have a table that gets data outputted to it dynamically based on data that is being pulled from my database. I have three hard coded <tr> but I want to hide them if there isn't any data outputted to their <td> from the database.
This is my HTML
<table class="table text-light text-end" id="data_table">
<thead>
<tr>
<th></th>
{{#each response4}}
<th class='title' scope="col">{{commodity}}</th>
{{/each}}
<th scope="col">Total</th>
</tr>
</thead>
<tbody class="text-end">
<tr>
<th scope="row">AUX</th>
{{#each response6}}
<td class="whole">{{fb_plus_fr}}</td>
{{/each}}
</tr>
<tr>
<th scope="row">UEM</th>
{{#each response4}}
<td class="whole">{{fb_plus_fr}}</td>
{{/each}}
</tr>
<tr>
<th scope="row">UT</th>
{{#each response5}}
<td class="whole">{{fb_plus_fr}}</td>
{{/each}}
</tr>
</tbody>
</table>
This is an example I pulled from the inspect tool when the page loads and gets data from the database. The first <tr> doesn't have any <td> and should be hidden.
<tbody class="text-end">
<tr>
<th scope="row">AUX</th>
</tr>
<tr>
<th scope="row">UEM</th>
<td class="whole">8215</td>
<td class="whole">5367</td>
<td class="whole">31193</td>
</tr>
<tr>
<th scope="row">UT</th>
<td class="whole">8215</td>
<td class="whole">5367</td>
<td class="whole">31193</td>
</tr>
</tbody>
This is how I'm attempting it but this doesn't work. It won't hide that first that doesn't have any data. Any advice on how to fix this is greatly appreciated!
window.onload = () => {
$("#data_table > tbody > tr ").each(function () {
if ($(this).find('td').is(":empty")){
$(this.hide())
}
})
};
This code may help you:
<tr th:if="${yourtable.empty}">
<td colspan="2">No Content Available</td>
</tr>
I think the easiest way to go about this would be to have an if block wrapped around the <tr> that checks if the data is empty before displaying the <tr>.

Update parent table cell value from child table

I have a table (parent) and one another table inside that table(child).
I want to update the cell value of parent table from child table.
<table id="example" class="table table-bordered table-striped mt-4 nowrap" style="width:100%">
<thead>
<tr class="bg-primary text-light">
<th></th>
<th>
#Html.DisplayName("Restaurant Name")
</th>
<th>
#Html.DisplayName("Delivery Date")
</th>
<th>
#Html.DisplayName("Status")
</th>
<th class="none">
#Html.DisplayName("Preferred Delivery Date")
</th>
<th class="none">
<b> #Html.DisplayName("Item List") </b>
</th>
<th class="none"></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td></td>
<td>
#Html.DisplayFor(modelItem => item.RestaurantName)
</td>
<td>
#String.Format("{0:dd/MM/yyyy}", item.DELIVERED_DATE)
#*#Html.DisplayFor(modelItem => item.DELIVERED_DATE.Value.ToString("dd/MM/yyyy"))*#
</td>
<td>
#if (item.STATUS == 1)
{
<span class="badge badge-secondary">Draft</span>
}
#if (item.STATUS == 2)
{
<span class="badge badge-warning">Pending confirmation</span>
}
#if (item.STATUS == 3)
{
<span class="badge badge-primary">Confirmed</span>
}
#if (item.STATUS == 4)
{
<span class="badge badge-suceess">Delivered</span>
}
</td>
<td>
: #String.Format("{0:dd/MM/yyyy}", item.PREFERRED_DELIVERY_DATE)
</td>
<td>
:
<table>
<thead>
<tr class="bg-primary text-light">
<th>
#Html.DisplayName("Item Name")
</th>
<th>
#Html.DisplayName("Quantity")
</th>
<th>
#Html.DisplayName("Price")
</th>
</tr>
</thead>
<tbody>
<tr>
#foreach (var test in item.OrderSupplierItems)
{
<tr>
<td>#Html.DisplayFor(modelItem => test.IngredientName)</td>
<td>#Html.DisplayFor(modelItem => test.QUANTITY)</td>
<td>#Html.DisplayFor(modelItem => test.PRICE)$</td>
</tr>
}
<tr>
<td colspan="2">Sum</td>
<td>#item.OrderSupplierItems.Sum(b => b.PRICE)$</td>
</tr>
<tr>
</tbody>
</table>
</td>
<td>
<a class='Confirm btn btn-success' href='javascript:;#item.ID_ORDER_SUPPLIER'>CONFIRM</a>
<a class='btn btn-primary'>MAKE CHANGES</a>
</td>
</tr>
}
</tbody>
</table>
I want to change the status on ajax success request.
$("body").on("click", "#example TBODY .Confirm", function () {
if (confirm("Do you want to confirm this order?")) {
var row = $(this).closest("tr");
var orderSupplierId = $(this).attr('href').substr(12);
$.ajax({
type: "PUT",
url: "#System.Configuration.ConfigurationManager.AppSettings["ServiceUrl"]/api/OrderSupplier/" + orderSupplierId +"?status=3",
contentType: 'application/json', // <---add this
dataType: 'text',
success: function (response) {
//here i want to do this
},
error: function (xhr, textStatus, errorThrown) {
console.log(errorThrown);
}
});
}
I need to update the status field of parent table based on confirm changes button.
I need to replace the current text of status field of current table.
You can use closest('tr').find("td:eq(3)") this will refer to 4th column td in your table i.e : status column and use .html or .text to make changes there .
Demo Code :
$("body").on("click", ".Confirm", function() {
if (confirm("Do you want to confirm this order?")) {
var row = $(this); //declare this outside..ajax call
var orderSupplierId = $(this).attr('href').substr(12);
//ajaxcodes..
//success: function(response) {
//here i want to do this
row.closest('tr').find("td:eq(3)").html('<span class="badge badge-primary">Confirmed</span>')
//},
//other codes
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<table id="example" class="table table-bordered table-striped mt-4 nowrap" style="width:100%">
<thead>
<tr class="bg-primary text-light">
<th></th>
<th>
Restaurant Name
</th>
<th>
Delivery Date
</th>
<th>
Status
</th>
<th class="none">
Preferred Delivery Date
</th>
<th class="none">
<b>Item List </b>
</th>
<th class="none"></th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td>
Somehtings..
</td>
<td>
02/02/202
</td>
<td>
<span class="badge badge-warning">Pending confirmation</span>
</td>
<td>
02/3/2020
</td>
<td>
<table>
<thead>
<tr class="bg-primary text-light">
<th>
Item Name
</th>
<th>
Quantity
</th>
<th>
Price
</th>
</tr>
</thead>
<tbody>
<tr>
<tr>
<td>somehting</td>
<td>abc</td>
<td>12$</td>
</tr>
<tr>
<td colspan="2">Sum</td>
<td>123$</td>
</tr>
<tr>
</tbody>
</table>
</td>
<td>
<a class='Confirm btn btn-success' href='javascript:;#item.ID_ORDER_SUPPLIER'>CONFIRM</a>
<a class='btn btn-primary'>MAKE CHANGES</a>
</td>
</tr>
<tr>
<td></td>
<td>
Somehtings..
</td>
<td>
02/02/202
</td>
<td>
<span class="badge badge-success">Delivered</span>
</td>
<td>
02/3/2020
</td>
<td>
<table>
<thead>
<tr class="bg-primary text-light">
<th>
Item Name
</th>
<th>
Quantity
</th>
<th>
Price
</th>
</tr>
</thead>
<tbody>
<tr>
<tr>
<td>somehting</td>
<td>abc</td>
<td>12$</td>
</tr>
<tr>
<td colspan="2">Sum</td>
<td>123$</td>
</tr>
<tr>
</tbody>
</table>
</td>
<td>
<a class='Confirm btn btn-success' href='javascript:;#item.ID_ORDER_SUPPLIER'>CONFIRM</a>
<a class='btn btn-primary'>MAKE CHANGES</a>
</td>
</tr>
</tbody>
</table>
You can search back from the element you're in, which is the button, with .closest(). Then find the status field from there. Best would be to give the status a class or id. So:
$(this).closest('table').find('.status')

Perform Calculation in Cell of Dynamic HTML Table via Jquery

I am basically performing calculation in dynamic table cell want to change sum of cell value whenever cell value change by user
I have already tried different method of jquery but not get what i want
<table class="table table-responsive table-hover table-bordered" id="tablefinaldata">
<thead>
<tr>
<td>
<h5> Code</h5>
</td>
<td>
<h5> Item</h5>
</td>
<td>
<h5> Price</h5>
</td>
<td>
<h5> Quantity</h5>
</td>
<td>
<h5> Sub Total</h5>
</td>
</tr>
</thead>
<tbody id="tablefinalbody">
</tbody>
function CalSum ()
{
$("#setfinaldata #subtotal").each(function () {
var row = $(this);
var rowTotal = 0;
$(this).find('th').each(function () {
var th = $(this);
if ($.isNumeric(th.text())) {
rowTotal += parseFloat(th.text());
}
});
row.find('th:last').text(rowTotal);
});
}
function CalSum() {
var $trList = $("#tablefinalbody").find('tr');
var rowTotal = new Array($trList.length);
$trList.each(function() {
var row = $(this);
$(this).find('th').each(function(index) {
var th = $(this);
if ($.isNumeric(th.text())) {
if (!rowTotal[index]) rowTotal[index] = 0
rowTotal[index] += parseFloat(th.text());
}
});
});
$trList.last().children().each(function(index) {
$(this).text(rowTotal[index])
})
}
CalSum();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="table table-responsive table-hover table-bordered" id="tablefinaldata">
<thead>
<tr>
<td>
<h5> Code</h5>
</td>
<td>
<h5> Item</h5>
</td>
<td>
<h5> Price</h5>
</td>
<td>
<h5> Quantity</h5>
</td>
<td>
<h5> Sub Total</h5>
</td>
</tr>
</thead>
<tbody id="tablefinalbody">
<tr>
<th>1</th>
<th>2</th>
<th>3</th>
<th>4</th>
<th>5</th>
</tr>
<tr>
<th>123</th>
<th>42</th>
<th>53</th>
<th>64</th>
<th>234</th>
</tr>
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</tbody>
</table>

How do you sort for row details in HTML?

I am using sorttable to sort my columns in table.
Now I have a table as follows:
<table class="sortable draggable">
<thead>
<tr>
<th class="col-salesOrderId">Order Number</th>
<th class="col-orderDate">Date of Order</th>
<th class="col-party">Party</th>
<th class="col-edit">Edit</th>
<th class="col-delete">Delete</th>
</tr>
</thead>
<tbody>
{#orders}
<tr>
<td class="col-salesOrderId">{.salesOrderId}</td>
<td class="col-orderDate">{#formatDate date=orderDate format="DD-MM-YYYY" /}</td>
<td class="col-party">{.party.partyName}</td>
<td class="col-edit">
<button class="btn btn-info btn-edit">
</button>
</td>
<td class="col-delete">
<button class="btn btn-danger btn-delete">
</button>
</td>
</tr>
<tr class="row-details">
<td>{.salesOrderId}</td>
<td colspan="4">
<table class="sortable draggable">
<thead>
<tr>
<th class="col-itemName">Item Name</th>
<th class="col-quantity">Quantity</th>
<th class="col-rate">Rate</th>
<th class="col-amount">Amount</th>
</tr>
</thead>
<tbody>
{#items}
<tr>
<td>{.item.itemName}</td>
<td>{.quantity}</td>
<td>{.rate}</td>
<td>{#math key="{.quantity}" method="multiply" operand="{.rate}"/}</td>
</tr>
{/items}
</tbody>
</table>
</td>
</tr>
{/orders}
</tbody>
</table>
Have you noted in the above mentioned table I have row details for each row?
Now when I click on a column header to sort it, I get the row details first and then I get all the main rows.
Here is how my table looks before sorting:
Here is how my table looks after sorting:
Is there any solution to this problem still using sorttable?
Update:
Here is sample jsFiddle
Row details are now sorted correctly as shown in the above jsFiddle. But now the problem is :
When you click on City column everything looks fine. Now if we again click on City Column, the row details are displayed before the actual rows which is wrong.
Please look at the images below for more information on problem:
After Clicking on City Column: (Which looks perfect)
After Clicking on City Column Again: (Expected for a developer but unexpected for a user)
I'am guessing but maybe the problem is the empty td beside the row details. I added first name as value and set css style display:none. Now the row details will be sorted also correctly.
Updated answer:
try to just nest the table inside the td like the below example.
Try this:
<table class="sortable">
<thead>
<tr>
<th>First Name</th>
<th>LastName</th>
</tr>
</thead>
<tbody>
<tr>
<td>Vishal</td>
<td> Sherathiya
<table>
<thead>
<tr>
<th>Degree</th>
<th>Percentage</th>
</tr>
</thead>
<tbody>
<tr>
<td>B.E.</td>
<td>67</td>
</tr>
</tbody>
</table>
<td>
</tr>
<tr>
<td>Nikunj</td>
<td>Ramani
<table>
<thead>
<tr>
<th>Degree</th>
<th>Percentage</th>
</tr>
</thead>
<tbody>
<tr>
<td>B.E.</td>
<td>80</td>
</tr>
<tr>
<td>M.E.</td>
<td>54</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td>Raj</td>
<td>Gosai</td>
</tr>
</tbody>
</table>

Categories

Resources