How do i refresh or redraw table rows - javascript

Below is the classical issue which I am facing during my app development.
I have an array of JSONObjects in my spring controller that I have to iterate in the jsp;
Also another status attribute called JSONArrayStatus is set that suggests if JSON array is empty or not.
Using jquery if JSONArray is empty I will show noDataImageDiv otherwise will show tableDIV (Binding the data from JSONArray using JSTL)
The problem I am facing is as below.
1. Edit a row in the table and click on Update. At this time I make an Ajax Call say, "UpdatedUser", which will return all the records along with the updated records. I could use refresh however thats not a recommended user experience and hence a no no.
To reflect the updated users in the table, I use jquery as below
clearing table rows table.clear().draw()
Loop the result set as follows.
redraw code
function reDrawExternalContactUsers(externalUsers) {
table.clear().draw();
var row = "";
$.each(externalUsers, function (i, field) {
row = '<tr><td></td><td></td><td class="edit">edit</td></tr>';
$("#tableDIV").append(row);
});
}
afetr this redraw or refresh process
This function is NOT working
$(".edit").click(function(){
});
This function is working
$("#tableDIV .edit").click(function(){
});
Suggest a better way of refreshing table rows, if any.
<div id="tableDIV">
<table id="tableID">
<thead>
<tr>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
if data exist
loop{
<tr>
<td></td>
<td></td>
<td class="edit">edit</td>
</tr>
} // loops ends
if close
</tbody>
</table>
</div>
<div id="noDataImageDiv"> No data image</div>

html code :
<div id="tableDIV">
<table id="tableID">
<thead>
<tr>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
if data exist
loop{
<tr>
<td class="user-name"></td>
<td></td>
<td class="edit" data-user-id="">edit</td> //set user_id in attr data-user-id
</tr>
} // loops ends
if close
</tbody>
</table>
</div>
<div id="noDataImageDiv"> No data image</div>
jquery code :
you should use click event on document
$(document).on('click', '.edit', function () {
var btn = $(this);
var user_id = btn.attr("data-user-id"); //user_id of user will update
// extra user data
$.ajax({
method: "POST",
url: url,
data: {
'id': id,
// extra data to send
},
success: function (data) {
if (data.status) // successfully user updated
{
var user = data.user;
/* you can set user data like this */
btn.closest('tr').find('.user-name').html(user.name);
}
}
});
});

Related

Get calling table from column option

I have a few Bootstrap table on one page. Each table has some data attributes (like data-link="test-page" and so on). Besides that, one column of each Bootstrap table uses a column formatter, using data-formatter="actionFormatter". However, I want to get the current table data attributes when actionFormatter is called, so based on the data attributes I can return a string.
Both this and $(this) return an Object, which doesn't work. $(this).closest('table').data() doesn't work either, while I expected that one to be the most true.
Here's the code I use:
<th data-field="actions" data-formatter="actionFormatter" data-events="actionEvents">Actions</th>
this returns a JSON object with the row properties, and $(this).closest('table').data(XXX) return undefined. I expected it to return an array with all the data attributes.
Is there any way to get the current processing table from within the formatter?
Example code:
<!-- table 1 -->
<table
data-actions="edit,remove"
data-url="some/url"
>
<thead>
<tr>
<th data-formatter="actionFormatter">Actions</th>
</tr>
</thead>
</table>
<!-- table 2 -->
<table
data-actions="edit,remove"
data-url="some/url"
>
<thead>
<tr>
<th data-formatter="actionFormatter">Actions</th>
</tr>
</thead>
</table>
// actionFormatter:
function actionFormatter(value, row, index, field) {
// get data-actions from the right table somehow,
// and return a string based on data-url/other
// data attributes
}
It seems that when the action formatter is called, the execution context this is an object with all the bootstrap table row associated data as well as all the data-* attributes of the row.
Taking that into account you can add an id to each table and a data-table-id attribute to your rows like:
<table
id="table-1"
data-actions="edit,remove"
data-url="some/url"
>
<thead>
<tr>
<th data-formatter="actionFormatter" data-table-id="table-1">Actions</th>
</tr>
</thead>
so that in your formatter you can retrieve the table DOM Element by using that id:
function actionFormatter(value, row, index, field) {
// get data-actions from the right table somehow,
// and return a string based on data-url/other
// data attributes
var data = $('#' + this.tableId).data();
}

Dynamic table with JSON data and sticky collapsible rows

I'm using Angular 1 with a factory that polls a REST API for JSON data. This JSON then populates a table with ng-repeat-start, and using ng-repeat-end I have a hidden table row with additional data.
Seems rather ordinary to me.
But the problem is, when I poll the API every 5 or 10 seconds, how can I keep the collapsible table row open when the next poll occurs?
In most cases the data does not change, so there's no reason to close the collapsible row, yet it closes at every poll that my factory makes.
Here's an example of one of the tables.
<table class="pure-table pure-table-horizontal alerts-table" id="alert-nagios-host-table">
<thead>
<tr>
<th>Hostname</th>
<th>Status</th>
<th>Output</th>
</tr>
</thead>
<tbody>
<tr class="parent-row" ng-repeat-start="alert in alerts" ng-click="child.expanded = !child.expanded">
<td>{{alert.hostname}}</td>
<td ng-class="{3:'grayBg', 2:'redBg', 1:'yellowBg', 0:'greenBg'}[alert.state]">{{alert.status}}</td>
<td>{{alert.output}}</td>
</tr>
<tr class="child-row" ng-init="child.expanded = false" ng-show="child.expanded" ng-repeat-end>
<td colspan=4>Duration: {{alert.duration}}</td>
</tr>
</tbody>
</table>
Here is my factory that polls the data, and an example of one of the angular controllers.
mondashApp.factory('AlertsPoller', function ($http, $timeout) {
var data = {resp: {}, count: 0};
var count=0;
var poller = function (url, success) {
count++;
$http.get(url).then(function (responseData) {
data.count = count;
data.resp = responseData.data;
success(data);
$timeout(function () {poller(url, success);}, 5000);
});
};
return {
poller: poller
};
});
mondashApp.controller('nagiosHostAlertsCtrl', function nagiosHostAlertsCtrl($scope, AlertsPoller) {
AlertsPoller.poller('/alert/nagios/host', function(response) {
$scope.alerts = response.resp.alerts;
});
});

Update Individual MySQL Records on Checkbox Click with AngularJS

I am creating a golf tournament check-in app and want to be able to update an individual record in the MySQL database when a checkbox is clicked. So, when someone checks in they click the checkbox by their name and I want it to then update the database record of that person (the checked in column set to 1 for the specific id of the person) so that others can see that the person is checked in almost immediately.
I am not sure how to get both the id and the checkedin value to update only the affected record when a checkbox is clicked.
app.js
var checkinApp = angular.module('checkinApp', []);
checkinApp.controller('checkinController', function($scope, $http, $location, $anchorScroll) {
$http.get('lib/api.php').success(function(data) {
$scope.checkindata = data;
});
$scope.processForm = function(checkedindata) {
$http.post('lib/process.php', { gid : checkedindata.gid, checkedin : checkedindata.checkedin })
.then(function(data) {
console.log(data);
})
};
});
HTML/Output
<table class="table table-striped table-responsive">
<tbody>
<tr>
<th>Checked In</th>
<th>First Name</th>
<th>Last Name</th>
<th>Company</th>
<th>Starting Hole</th>
</tr>
<tr ng-repeat="item in checkindata">
<td><input type="checkbox" name="checkedin" ng-model='checkedin' ng-change='processForm(checkedindata)' ng-checked="item.checkedin == 1"/></td>
<td>{{item.fname}}</td>
<td>{{item.lname}}</td>
<td>{{item.cname}}</td>
<td>{{item.hole}}</td>
</tr>
</tbody>
</table>
process.php
<?php
require_once('../includes/cred.php');
$checkedin = $_POST['checkedin'];
$sth = $dbh->prepare("UPDATE golfers SET checkedin=$checkedin");
$sth->execute();
DB Table
DB Table
Output
Output
Simply replace ng-change='processForm(checkedindata)'
by ng-change='processForm(item)'
and in your PHP code do something like :
$sth = $dbh->prepare("UPDATE golfers SET checkedin=$checkedin->checkedin WHERE gid=$checkedin->gid");

Need to update table cell one by one during ajax call when the table is iterated in a loop

//Sample code:
I need to update the status in a column of every row one by one in html table when i get response from the ajax call,but the status cell gets updated when all the ajax request is complete.I don't want all the cells getting updated at once.
<script>
for(var i=0;i< count;i++)
{
$.ajax({
url: 'example.php',
type: 'POST',
async : false,
data: {test:test},
success: function (data) {
$("#"+i).html("updated");
}
});
}
</script>
<html>
<table>
<thead>
<tr>
<th>Name</th>
<th>Address</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr><td>Xavier</td><td>London</td><td><span id=0>Pending</span></td></tr>
<tr><td>Jhon</td><td>NY</td><td><span id=1>Pending</span></td></tr>
<tr><td>Sam</td><td>LA</td><td><span id=2>Pending</span></td></tr>
</tbody>
</table>
</html>
The output should be:
Name Address Status
Xavier London Updated
John NY Pending
Sam LA Pending
If you dont want to update the entire row at once then call the ajax function for each rows. When you return a row from your "example.php" display it and then call ajax again and return next row.

Simple show/hide gone wrong in Javascript

I'm trying to create a show/hide function for data within a table populated with data from a mssql database. The function should look for rows with the same value in the "capability" column and onclick, hide all rows with the same value. After this, a row is inserted into the table with the same capability value, but summarizes the data in the hidden rows. This should work in the way that grouping cells together works in excel.
I've managed to get this to work, but it only works for the first click and I receive a "cannot read innerHTML property of NULL" for any of the function's calls after that.
function compactRows(thisrow) {
var totalRows = document.getElementById("DataTable").getElementsByTagName("tr").length;
var summaryVal1= [];
var summaryVal2= [];
for(var i = 1; i < totalRows;i++) {
var trID = "capability" + i;
if(thisrow.innerHTML == document.getElementById(trID).innerHTML) { //The error gets returned on this line
summaryVal1.push(document.getElementById(trID).parentNode.children[5].innerHTML);
summaryVal2.push(document.getElementById(trID).parentNode.children[14].innerHTML);
document.getElementById(trID).parentNode.style.display = 'none';
}
}
createNewRow(thisrow, summaryVal1, summaryVal2);
}
//I took out the logic for the data summarizing in the createNewRow function because I don't think its relevant to the issue I'm having. Also, I didn't want to crowd the area with unrelated code
function createNewRow(row, ibxMobile, overallStatus) {
var table = document.getElementById("DataTable");
var localRow = table.insertRow(row.parentNode.rowIndex);
var cell1 = localRow.insertCell(0);
cell1.setAttribute("id", "entry1");
var cell2 = localRow.insertCell(0);
cell2.setAttribute("id", "Capability");
cell2.innerHTML = row.innerHTML;
var cell3 = localRow.insertCell(0);
cell3.setAttribute("id", "entry3");
}
The function called at the bottom, createNewRow, handles making the row to be entered after all the rows are hidden. It also, handles the logic for summarizing the hidden rows.
All help is greatly appreciated! Thank you
Edit 1: example table set up
<table>
<tr>
<th>Entry1 </th>
<th>Capability</th>
<th>Entry3 </th>
</tr>
<tr>
<td>1.1</td>
<td id="Capability1" onclick="compactRows(this)">Lasers</td>
<td>stuff</td>
</tr>
<tr>
<td>1.2</td>
<td id="Capability2" onclick="compactRows(this)">Lasers</td>
<td>things</td>
</tr>
<tr>
<td>2.1</td>
<td id="Capability3" onclick="compactRows(this)">Beams</td>
<td>more things</td>
</tr>
</table>
//The Below table is what it looks like after clicking either of the first two entries
<table>
<tr>
<th>Entry1 </th>
<th>Capability</th>
<th>Entry3 </th>
</tr>
<tr>
<td>1</td>
<td id="Capability">Lasers</td>
<td></td>
</tr>
<tr>
<td>2.1</td>
<td id="Capability3" onclick="compactRows(this)">Beams</td>
<td>more things</td>
</tr>
</table>
There is no "Capability1" id for any rows after the "CreateNewRow" is called. Therefore, the second time "CompactRows()" is called a null reference is thrown when accessing "document.getElementById("Capability1").innerHTML". Rework the CreateNewRow to inlcude the increment for the Capability id value or test that "getElementById" actually returns an object before attempting to access the innerHTML method.

Categories