Execute JavaScript page refresh on postgres database entry addition - javascript

I have a Spring web app, where entries are added every 10 seconds to the database. I'd like my page to automatically reload when a new entry is added to the database. So far I have come up with such code:
function contentRefresh() {
$.ajax({
url: "/refresh",
success: function(data) {
console.log(data);
$("#main-content").html(data);
}
});
}
And the data that is returned from the controller is a html fragment:
#RequestMapping("/refresh")
public String refreshPage(Model model, Pageable pageable){
PageWrapper<NetworkHashrate> page = new PageWrapper<NetworkHashrate>(netService.getAllNetworks(pageable), "");
model.addAttribute("page", page);
model.addAttribute("networkHashrates", page.getContent());
return "main :: table-content";
}
And a .html that contains refreshed fragment:
<div class="table-responsive" id="main-content" th:fragment="table-content">
<table class="table table-hover ">
<thead class="thead-inverse">
<tr>
<th class="col-md-2 text-center">Network Id</th>
<th class="col-md-2 text-center">Rep_date</th>
<th class="col-md-2 text-center">Hashrate</th>
</tr>
</thead>
<tr style="cursor: pointer;" th:each="networkHashrate : ${networkHashrates}" th:onclick="'javascript:openPoolModal(\''+ ${networkHashrate.id} + '\');'">
<td class="text-center" th:text="${networkHashrate.id}"> Sample id</td>
<td class="text-center" th:text="${networkHashrate.rep_date}">Sample rep-date</td>
<td class="text-center" th:text="${networkHashrate.hashrate}">Sample hashrate</td>
</td>
</tr>
</table>
<button type="button" class="btn btn-success" th:onclick="'javascript:contentRefresh();'">Refresh!</button>
<div class="text-center" id="stat">
<div class="pagination"><p>Displaying <span class="badge" th:text="${page.size * (page.number-1) + 1}"></span> -
<span class="badge" th:text="${page.lastPage ? page.totalElements : page.size * (page.number-1)+ page.size}"></span> of
<span class="badge" th:text="${page.totalElements}"></span> total records</p>
</div>
</div>
</div>
Earlier, I've been refreshing the page via <meta http-equiv="refresh" content="60" /> ...but I've been told that's a bad approach. I have tested the JS code with button and it seems to work, but the refresh thing scares me... How do I refresh the page based on entry addition to the database?

I have added a setInterval to my JS script like:
setInterval("contentRefresh();", 10000 );
Is not a hard refresh, but an Ajax call to reload content, so I guess that works.

Related

Displaying JSON content in table rows using angularjs and codeigniter

I'm just trying to fetch contents from server and display it in a table using Angularjs. I'm been trying this from a while, but did not got any solution yet. Btw, I'm working on CodeIgniter framework.
Here is my CodeIgniter controller;
public function list_agents() {
if($this->is_logged_in ()) {
$agents = $this->generic_model->general_fetch('agent_master');
echo json_encode($agents);
}
else {
redirect(base_url());
}
}
In the above code, instead of echo I used print, print_r also.. But still its not working.
Here is my js file function;
(function () {
var addApp = angular.module('agentApp', ['ngRoute']);
addApp.controller('agentAddController', function ($scope, $http, growl) {
$scope.receivedData = [];
$http({
method : 'POST',
url : 'agent/list_agents',
headers : {
"Content-Type" : "application/json"
}
}).then(function (data) {
$scope.receivedData = JSON.parse(data);
});
});
})();
And in this above code I used with and without JSON.parse function. Didn't got the correct result.
Here is my view;
<section class="content" ng-app="agentApp" ng-controller="agentAddController">
<div class="row">
<div class="col-md-12">
<div class="box box-info">
<div class="box-header with-border">
<h3 class="box-title">Manage Agents</h3>
</div>
<div class="box-body">
<table class="table table-striped table-bordered" id="agents_table">
<thead>
<tr>
<th>Sl No.</th>
<th>Agent Name</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<div ng-repeat="data in receivedData">
<tr>
<td>{{ $index + 1 }}</td>
<td>{{ data.agent_name }}</td>
<td><button class="btn btn-warning btn-xs"><i class="fa fa-trash" aria-hidden="true"></i></button></td>
</tr>
</div>
</tbody>
<tfoot>
<tr>
<th>Sl No.</th>
<th>Agent Name</th>
<th>Actions</th>
</tr>
</tfoot>
</table>
</div>
</div>
</div>
</div>
</section>
I know if I put ng-repeat inside tr tag I'll get the perfect result, but I don't want to do that because, I'm working with adminLTE. So there is a function DataTable() in adminLTE where it'll apply search and pagination to the table. If I give ng-repeat to tr, these functionalities can not be added.
Try: $scope.receivedData = JSON.parse(data.data);
The response object is not only the data itself, that's why the 5 rows. It gives back, data, headers, status, etc...
https://docs.angularjs.org/api/ng/service/$http

jQuery only execute .append once

I want to add an extra row with some extra calculations to an existing table. The table doesn't have a header tag, it's just figuring out what CSS to apply by itself. I'm adding an extra header via the code found below. Right now it's adding the header twice. The (edited) code of the table looks like this:
<!--This code is in a <form> with the id="train_form", hence the usage in the jQuery code-->
<table class="vis" style="width: 100%">
<tbody>
<tr>
<th style="width: 20%">Eenheid</th>
<th style="min-width: 400px">Behoefte</th>
<th>In het dorp/Totaal</th>
<th style="width: 120px">Rekruteren</th>
<th style="width: 80px">To Do:</th>
</tr>
<tr class="row_a">
<td class="nowrap">
<a href="#" class="unit_link" data-unit="spear">
<img src="image.png" style="vertical-align: middle" alt="" class="">
Speervechter
</a>
</td>
</tr>
<!-- There are 3 more entries here, but to not be too long I've removed them. They are not really necessary-->
<tr>
<td colspan="3">
</td>
<td>
<input class="btn btn-recruit" style="float: inherit" type="submit" value="Rekruteren" tabindex="11">
</td>
<th style="width: 80px">To Do:</th>
</tr>
</tbody>
</table>
The lines <th style="width: 80px">To Do:</th> are added by my script. The problem is that it also adds it to the last <td>. I've looked at quite a few 'solutions', but they are not helping. It's still adding the code twice (see screenshot below).
The code that I'm using to add the lines:
$(function() {
var done = false;
if (!done) {
$("#train_form > .vis > tbody > tr:not(.row_a, .row_b)").one().append("<th style='width: 80px'>To Do:</th>");
done = true;
};
}).one();
As you can see I've tried using the .one() methods, and I've tried using a bool for it. Both don't work, since this code still gives the table seen in the image above.
Just to be clear, I have no control over the source, this is a script for an online browser game.
What am I doing wrong?
I think you want $.first() instead of $.one():
$("#train_form > .vis > thead > tr:not(.row_a, .row_b)")
.first()
.append("<th style='width: 80px'>To Do:</th>");

AngularJS: new object not showing in table

I am using dir-paginate library to paginate my data on the page. The issue I am having is when I am adding a new object to the list and viewing this on the page instantly. On the controller side every thing seems to work just alright.
Here is my controller
/**
* Array of all the items
*/
$scope.allItems = [];
$scope.postResource = function() {
ProjectsFactory.save($scope.newProject)
.success(function(data) {
$scope.allItems.push(data);
console.log($scope.allItems);
$scope.newProject = ''
ToastService.show('Added successfully!');
})
.error(function(data) {
sweetAlert("Oops...", "Something went wrong!", "error");
console.log(data);
});
}
Notice the log I am doing right there. On the console page I can see the new object is being added to the rest of the objects. I believe the issue is occurring on the view side which looks just like this.
<table class="table table-bordered table-hover table-condensed bg-white" st-table="rowCollectionBasic">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr dir-paginate="item in allItems | filter: search.query | itemsPerPage : itemPerPage" total-items="totalProjects" current-page="currentPage">
<td>{{item.name}}</td>
<td>{{item.description}}</td>
<td style="width:150px">
<button class="btn btn-info btn-sm" ng-click="showEditDialog($event, item)">
<i class="glyphicon glyphicon-edit"></i>
</button>
<button class="btn btn-danger btn-sm" ng-click="deleteResource(item, $index)">
<i class="glyphicon glyphicon-trash"></i>
</button>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="20" class="text-center">
<dir-pagination-controls on-page-change="pageChanged(newPageNumber)" boundary-links="true"></dir-pagination-controls>
<md-progress-circular md-mode="indeterminate" ng-if="AjaxInProgress"></md-progress-circular>
</td>
</tr>
</tfoot>
To see the new created object on the page, I need to either refresh the page or click somewhere else and return to the same page again.
Someone has an idea what I am doing wrong?
Update #1
The project service has $http
// save a new resource
save: function(data) {
return $http({
url: $rootScope.baseUrl + 'projects',
method: 'POST',
data: data
});
},
Thanks!

How to apply $watchCollection to grid in template(html page) that is included using ng-include in another page?

I am new to angularJS.
I have a page that contains a grid filled with data.
<table items="personList" tr-ng-grid page-items="9"
selection-mode="SingleRow" selected-items="personGrid"
style="font-size: smaller;">
<thead>
<tr>
<th field-name="Name" display-name="{{ 'settings_grid_name' | translate }}"></th>
<th field-name="address" display-name="{{ 'settings_grid_address' | translate }}"></th>
<th field-name="age" display-name="{{ 'settings_grid_age' | translate }}"></th>
</tr>
</thead>
<tbody>
<tr>
<td field-name="age">
<div class="text-center">
<i style="font-size: 21px" class="base-icon {{getDeviceState(gridItem.age)}}"></i>
</div>
</td>
<td field-name="address">
<div class="text-center">
<i style="font-size: 21px" ng-style="getDeviceColor(gridItem.Id, gridItem.Status)" class="base-icon {{getDeviceIconType(gridItem.address)}}"></i>
</div>
</td>
</tr>
</tbody>
Controller code
$scope.$watchCollection('personGrid', function (newVal, oldVal) {
console.log('Working -- New value');
console.log(newVal);
});
I had applied $watchCollection in controller, when i select any single row it fires the $watchCollection event and all works fine.
I had use the above template in another new hmtl page.
<div class="col-lg-2 col-md-2">
<div ng-include="'settingsModule/views/settingsModuleVehicleGrid.tpl.html'"></div>
</div>
And code in controller used for new html page.
$scope.$parent.$watchCollection('personGrid', function (newVal, oldVal) {
console.log('Working --');
console.log(newVal);
});
But they event is only fired when page load first time. after that when i select any row in table grid , the event is not fired. : (
Any help, some better solution. May be we can add the data in $rootScope and apply $watch.

jQuery overriding hyperlinks on table's td values

I have a table as below and am trying to open a pop-up window with the link '/ledesInvoiceErrors.do?InvoiceId='+parentInstanceId' when user clicks on Invoice number columns of table (INV1 and INV2) instead of going to the hyper link associated with invoice number fields.
http://jsfiddle.net/pmgguwob/3/
<div class="listTable expanded">
<table class="searchResults {id:321}">
<thead>
<tr class="tipAdded">
<th class="first unsortable ui-state-default ui-state-hover ui-state-active"></th>
<th data-name="Invoice Number" class="typeString ui-state-default ui-state-hover sort asc ui-state-active" id="sort_invoiceNumber">
Invoice Number
</th>
<th data-name="Invoice Total" class="typeMoney last ui-state-default ui-state-hover ui-state-active sort" id="sort_invoiceTotal">
Invoice Total
</th>
</tr>
</thead>
<tbody class="">
<tr class="tipAdded">
<td class="first">
<div style="display:none" class="renderedValue">
INV1
</div>
<input value="65" name="invoices0.id" type="hidden" class="check"/>
</td>
<td class="typeString ">
<div class="data typeString"><a tooltip="" class="listLink " title="" href="/CP/show.do?parentInstanceId=51;parentFieldName=invoices">
INV1
</a>
</div>
</td>
<td class="typeMoney ">
<div class="data typeMoney">
15.25 USD
</div>
</td>
</tr>
<tr class="tipAdded">
<td class="first">
<div style="display:none" class="renderedValue">
INV2
</div>
<input value="66" name="invoices1.id" type="hidden" class="check"/>
</td>
<td class="typeString ">
<div class="data typeString"><a tooltip="" class="listLink " title="" href="/CP/show.do?parentInstanceId=55;parentFieldName=invoices">
INV2
</a>
</div>
</td>
<td class="typeMoney ">
<div class="data typeMoney">
111.25 USD
</div>
</td>
</tr>
</tbody>
</table>
Am a very beginner of jQuery and I dont really know how to achieve this. Could anyone please me with this?
Note: I dont have liberty of modifying the hyperlinks associated with Invoice number fields since these links are generated from our internal framework. but I can embed jquery script on my page to override the hyperlinks
SOLUTION UPDATED
http://jsfiddle.net/pmgguwob/10/
To override your hyperlink's behaviour, you can do something along the lines of:
$(function(){
// you may have to narrow down the selector here to a specific class or 'td'
$(".searchResults a").on('click', function(e){
e.preventDefault();
var url = $(this).attr('href');
window.open(url, 'window name', 'window settings');
return false;
});
});
Updated Fiddle
In this case, something like this (fiddle):
$("a").click(function (e) {
e.preventDefault();
var mills = (new Date).getTime();
window.open($(this).attr("href"), mills);
//$("body").append("#" + $(this).attr("href") + "#");
});
I'm using mills to give each window a new handle, so you don't reuse a window and potentially confuse your user by reloading a window that's hidden from them. The last line is just to show the URL it's using for testing; you might want to massage that value a little, but I believe it's right as is.
I know window.open isn't new and cool, but its options let you control the new window's appearance with likely enough granularity. You could jQuery that up instead if you wanted.

Categories

Resources