Reloading using Angular - javascript

Hello friends from SO!
I'm new into angular, and I'm trying to keep a table always updated with the information comming from a PHP webservice.
I'm demanding the information the first time using the following:
HTML
<div class="block" ng-controller="demandar_informacion" ng-init="visualizacion_masiva()">
<h1 class="block_header">Welcome admin</h1>
<p class="block_info"></p>
<table>
<thead>
<tr>
<th ng-repeat="header in headers ">{{header}}</th>
</tr>
</thead>
<tr ng-repeat="disponible in disponibles">
<td ng-repeat="(variable, valor) in disponible">{{valor}}</td>
</tr>
</table>
</div>
Then I'm using the following code to get the information:
Js Angular:
function demandar_informacion($scope, $http) {
//pedido de visualizaciĆ³n masiva
$scope.visualizacion_masiva = function() {
var address = "http://127.0.0.1/usa/_code/index_records.php"
+ "?ac=view_all"
var pedido = $http({
method: 'GET',
url: address
})
.success(function(data, status) {
$scope.errors = data.error;
$scope.headers = data.headers;
$scope.disponibles = data.disponibles;
$scope.eliminados = data.eliminados;
$scope.info = data.info;
});
};
}
Main Q:
Is there any way I could re-send the HTTP packet and update the information every, let's say, 3 or 5 seconds? as It's rapidly changing.
Auxiliary:
At the same time, this fragment of code, seems to be altering the order of the values I have on the array, or it might be previously altered somewhere in the Angular code. I've checked the PHP and the Json string seems to be in right conditions, but when it comes to printing the values, it completely looses it's native order (shows the elements in an improper / unknown order)... anyone has a clue?
<tr ng-repeat="disponible in disponibles">
<td ng-repeat="(variable, valor) in disponible">{{valor}}</td>
</tr>
Thanks in advance!
Chris C. Russo

Update
$scope.update = function() {
$timeout(function() {
$http.get('lol').success(function() {
$scope.update();
});
}, 5000);
};
Old
Simplest way to do this:
$interval(function() {
demandar_informacion();
}, 5000);
buuuuutttt as MichaL pointed out in the comments what will happen is that 5 seconds will get eaten up as it becomes 5, 4, 3, 2, 1, DDOSing yourself due to the time it takes to complete the request.
Other ways:
Use firebase to wait and call the load function.
Long poll your php script.

You can use the $timeout service to call the server every few seconds. Or use websockets to push the changes from the server to your Angular app (with Ratchet, perhaps (http://socketo.me/))

Related

How to dynamically grab data and post it

Hello everyone I'm using ASP.NET C# MVC architecture to do this.
Right now I have a View "Index.cshtml" which has a table.
<table id="myTableData">
<thead>
<tr>
<th>A</th>
<th>B</th>
<th>C</th>
<th>D</th>
<th>E</th>
</tr>
</thead>
<tbody>
<tr>
<td>val1</td>
<td>val2</td>
<td>val3</td>
<td>500</td>
<td>val5</td>
</tr>
<tr>
<td>val1</td>
<td>val2</td>
<td>val3</td>
<td>1500</td>
<td>val5</td>
</tr>
</tbody>
</table>
<script>
init();
function init(){
addRowHandlers('myTableData');
}
function addRowHandlers(tableId) {
if(document.getElementById(tableId)!=null){
var table = document.getElementById(tableId);
var rows = table.getElementsByTagName('tr');
var AB = '';
var BC = '';
var CD = '';
var DE = '';
for ( var i = 1; i < rows.length; i++) {
rows[i].i = i;
rows[i].onclick = function() {
AB = table.rows[this.i].cells[0].innerHTML;
BC = table.rows[this.i].cells[1].innerHTML;
CD = table.rows[this.i].cells[2].innerHTML;
DE = table.rows[this.i].cells[3].innerHTML;\
};
}
}
}
</script>
Currently I can grab all the information within a row with this script and I'll probably use this ajax to do the post
<script>
function seleccionar() {
$.ajax({
url: '#comercial.Models.Base.DirectorioRaiz()MovimientosCliente/SeleccionarOperacion',
type: 'post',
dataType: 'json',
contentType: 'application/json',
data: { operacion: operacion, metodo: metodo, monto: monto, fecha: fecha },
success: function (response) {
$('#divModalDeFacturas').html(response);
},
error: function (error) {
console.log(error);
}
});
}
</script>
Basically what I need is to grab all the data of a row I select with a buttom and use ajax to post it to another view, can anyone explain this to me?
How can I put both scripts to work together?
I know how to handle FormCollection form data that I post using inputs, most of the times I use hidden inputs inside the td's of the table but I require to do this dynamically and it gets a little difficult that way because I can't put static variables to pull the data, at least the way I tried it, it did not work.
Right now I think the best way would be to put this data in my controller, I've read another stack answer that says that these inputs are grabbed by the controller using paramters inside the ActionResult like this
[HttpPost]
public ActionResult MyView(int val1, int val2, intval3, etc...)
{
return View();
}
I dont know I feel lost browsing the sea of data available on the internet D:
This is answer I said that shows how to retrieve this information by the controller
Link to answer
First of all your action must be decorated with the HttpPostAttribute if you are looking to use POST in your example. The view you must return has to be specified on your return statement:
[HttpPost]
public ActionResult MyView(int val1, int val2, intval3, etc...)
{
return View("The view you want to return");
}
Also looking at your question and javascript code it's not clear what you're aiming for, are you looking to populate an area in your index view with some dynamic content, or are you looking to redirect to another view?
Then your javascript code is quite wrong as well. First of all you are specifying a a json object on your 'data' parameter, but then you're setting the content type to 'application/x-www-form-urlencoded' instead of 'application/json'. Also, If you're trying to post a json, then your 'datatype' should be 'json' not 'text'.
Then your url, appears to be wrong. To avoid confusion and error always use the Url.Action method where you can specify the required action an controller.
To be honest, if I was you, I would revisit the MVC docs, since it appears that you are missing a lot of knowledge on MVC, as it provides a lot of examples and walkthroughs which are really helpful. (https://learn.microsoft.com/en-us/aspnet/mvc/overview/getting-started/).
I would also suggest a recap on the Http protocol, which you can google and there's plenty of sources out there.

Customizing DataTables with WEB API OData service for filtering EF - column search not working

I am using DataTables on the client side and ASP.NET WEB API OData queryable service on the server side. The issue with sorting and filtering DataTable columns on the server side is that DataTables are generating that awful super long request with all columns info, even when they are not used for sorting or filtering. I've decided to write custom AJAX call from client to server to create neat odata query, that can be applied easily to EF context. Unfortunately column searching fields have stopped rendering as a inputs. What can be the issue?
JavaScript and HTML code:
$(document).ready(function() {
var options = new Object();
options.searching = true;
options.searchable = true;
options.aoColumns = [{
"sName": "USER_NAME",
"searchable": true
}];
options.bProcessing = true;
options.bServerSide = true;
options.sAjaxSource = "http://localhost/api/list";
options.fnServerData = function(sSource, aoData, fnCallback) {
var filter = "$top=5"; //just as example
$.getJSON(sSource, filter, function(json) {
fnCallback(json);
});
}
$('#myTable').dataTable(options);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//cdn.datatables.net/1.10.7/js/jquery.dataTables.min.js"></script>
<table id="myTable" class="table">
<thead>
<tr>
<th>
First Name
</th>
...
</tr>
</thead>
<tfoot>
<tr>
<th>
First Name
</th>
...
</tr>
</tfoot>
</table>
The service works fine, and looks like this (I've made this code as easy to understand as possible).
C# code:
public HttpResponseMessage List(ODataQueryOptions<User> options)
{
var result = oDataQueryOptions.ApplyTo(_context.Users) as IEnumerable<User>;
JQueryJsonResponse jsonUserResult = new JQueryJsonResponse
{
Draw = xxx,
iTotalRecords = xxx,
iTotalDisplayRecords = xxx,
aaData = result.ToList()
};
return Request.CreateResponse(HttpStatusCode.OK, jsonUserResult);
}
I would expect something like this:
But I get this:
CAUSE
You have server-side processing mode enabled with options.bServerSide = true;. In server-side processing mode filtering, paging and sorting calculations are all performed by a server.
SOLUTION
You need to handle parameters sent by the client on the server and perform filtering, paging and sorting. See full list of parameters sent in server-side processing mode.
Alternative solution is to disable server-side processing mode with options.bServerSide = false; and let DataTables perform filtering, paging and sorting on the client side.
OK, the question is not well formed, sorry. What I meant, that I want to apply column search to my datatables. During the copy-paste phase from other table I just missed some lines of code.
I've added something like this, and now it's working!
// Setup 'Search'
var filterSelector = '#myTable' + ' tfoot th';
$(filterSelector).each(function() {
var searchbox = $(this);
searchbox.html('<input type="text" class="form-control" placeholder="Search" />');
});
//Apply DataTables
var table = $('#myTable').DataTable(options);
$('.dataTables_filter input').attr("placeholder", "Search");
// Apply generic search
table.columns().every(function() {
var that = this;
var thatFooter = $('input', this.footer());
thatFooter.on('keyup change', function() {
that.search(this.value).draw();
});
});

Angular controller not display data from JSON

I am using Angular and TingoDB (Mongo) inside Node Webkit for a single page application. However I have a strange problem that I have been unable to resolve.
When I use an object literal (option 2) the data displays correctly in the html page. However changing the code to return data from the database (option 1) the results do not appear on the html page. I have converted both styles of data into the a JSON string to prove consistency and then using the angular.fromJSON to return an object. Both methods return the same JSON string in console.log and before anyone asks I have either Option 1 or Option 2 commented out so both are not running concurrently.
I have copied the JSON string based on the data passed from TingoDB into the console.log and re-entered it into the code below to ensure that no differences between the 2 versions of the data existed without changing any other code, but the problem still persists.
Can anyone shed light on why this occurs and how to fix it?
var app = angular.module('myApp', []);
var Engine = require('tingodb')(),
assert = require('assert');
var db = new Engine.Db('./db', {});
var collection = db.collection("clean.db");
app.controller('tingoDataCtrl', ['$scope', function($scope) {
function getData(callback) {
//Option 1
collection.find().toArray(function(err, docs){
callback (JSON.stringify(docs));
});
//Option 2
var docs = [
{name:"tingo1", description:"56",_id:2},
{name:"tingo2", description:"33",_id:3},
{name:"tingo3", description:"22",_id:4},
{name:"tingo4", description:"76",_id:5},
{name:"tingo5", description:"99",_id:6}
];
callback (JSON.stringify(docs));
}
function info(b) {
// I'm the callback
console.log(b);
$scope.items = angular.fromJson(b)
}
getData(info);
}]);
And the Html
<body ng-app="myApp" id="main">
<div class="page page-data ng-scope">
<section class="panel panel-default" ng-controller="tingoDataCtrl">
<div class="panel-heading"><span class="glyphicon glyphicon-th"></span> Tingo Data</div>
<table class="table">
<thead>
<th class="col-md-4">
Name
</th>
<th class="col-md-8">
Description
</th>
<th class="col-md-8">
ID
</th>
<th></th>
<tr>
</tr>
</thead>
<tbody>
<!-- <tr class="reveal-animation" ng-repeat="item in items | filter:query"> -->
<tr ng-repeat="item in items | filter:query">
<td>{{item.name}}</td>
<td>{{item.description}}</td>
<td>{{item._id}}</td>
</tr>
</tbody>
</table>
</section>
</div>
<script src="js/tingo_problem.js"></script>
</body>
TingoDB is an asynchronous API which will work in the background without stop your app. This means that a syncronous code have no time to wait for an answer and in return it gives undefined.
In your case, you have done a asynchronous call, and it returns correctly the answer to the memory, but too late, the DOM have been updated with undefined already even if your javascript has the data (try console.log to see that it was there).
Angular has a way to be forced to update again the DOM with the new elements of the controller. it is called $apply. And the best way to use it to avoid unexpected behaviours is:
function info(b) {
// I'm the callback
console.log(b);
$scope.items = angular.fromJson(b);
if (!$scope.$$phase) {
$scope.$apply(); //forces update the view
}
}//$scope is NECESARY to be defined in the controler, avoid using it with "ControlerAs"

Jquery Loop through table with multiple class

I am trying to loop through the table after the AJAX call is finished using the Jquery. But I am not able to loop through that.
My HTML Looks like this :
<table id="planyourwork" class="data-view plan-internal displayTable">
<thead>All Headers</thead>
<tbody>
<tr class="odd">
<td class="invisible"></td>
....
....
<td class="cell-status"></td>
</tr>
<tr class="odd">
<td class="invisible"></td>
....
....
<td class="cell-status"></td>
</tr>
<tr class="odd">
<td class="invisible"></td>
....
....
<td class="cell-status"></td>
</tr>
<tbody>
In JS file after calling the AJAX
$('.data-view > tbody > tr > td.cell-status').each(function() {
trying to add tool tip
}
When I debug, I see that Loop is not getting through. Debugger is stopping at data-view, but not looping through.
Please help me to resolve this problem
Below is the whole On Click event
filterBtn.click(function() {
loadData();
$('#planyourworktd.cell-status').each(function() {
var typeCell = $(this);
var tooltip = typeCell.parent().find('td.fullNotes').html();
alert("tooltip");
typeCell.attr('title', tooltip);
typeCell.tooltip({track: true,show: 100});
});
return false;
});
// Load the request and planner data
function loadData() {
$.ajax({
type: 'post',
url: url,
data: data,
cache: false,
success: function(html) {
initResults();
enableButtons();
},
error: function(jqXHR, textStatus, errorThrown) {
filterBtn.removeClass('invisible');
},
async: true
});
}
And DOM structure is quite complicated, when I run this in Fiddle it works but not on Page. I am not sure why? Thank you every one for helping me to resolve this.
Please Note : Syntax check may be typo error as I am removing production code, sorry for that.
There are a few mistakes in your html a javascript but I can't be sure whether it was when you typed it up here.
Anyways
'' is not closed, you have another '' instead of ''
You javascript is not closed properly, here is how it should look
$('.data-view > tbody > tr > td.cell-status ').each(function() {
console.log(this);
});
Notice the extra ');' at the end.
Now when I make these changes the output is fine.
I solved the problem. Its quite "sad", I missed few bits here. I am using struts 2 and AJAX call. and when an AJAX call is done, my event is called but by the time it is called data is not loaded. Reason is when an AJAX call is made, data is populated as "tile" which runs on its own. Rest of the elements are populated and data is loaded in parallel. Changing the location of the page solved the problem. Thank you for all your help.

Refreshing list after ajax call with Knockout JS

I have a list of attachments on a page which is generated using a jQuery $.ajax call and Knockout JS.
My HTML looks like (this is stripped back):
<tbody data-bind="foreach: attachments">
<tr>
<td data-bind="text: Filename" />
</tr>
</tbody>
I have a function that gets the list of attachments which is returned as a JSON response:
$(function () {
getFormAttachments();
});
function getAttachments() {
var request = $.ajax({
type: "GET",
datatype: "json",
url: "/Attachment/GetAttachments"
});
request.done(function (response) {
ko.applyBindings(new vm(response));
});
}
My view model looks like:
function vm(response) {
this.attachments = ko.observableArray(response);
};
There is a refresh button that the use can click to refresh this list because over time attachments may have been added/removed:
$(function () {
$("#refresh").on("click", getAttachments);
});
The initial rendering of the list of attachments is fine, however when I call getAttachments again via the refresh button click the list is added to (in fact each item is duplicated several times).
I've created a jsFiddle to demonstrate this problem here:
http://jsfiddle.net/CpdbJ/137
What am I doing wrong?
Here is a fiddle that fixes your sample. Your biggest issue was that you were calling 'applyBindings' multiple times. In general you will call applyBindings on page load and then the page will interact with the View Model to cause Knockout to refresh portions of your page.
http://jsfiddle.net/CpdbJ/136
html
<table>
<thead>
<tr><th>File Name</th></tr>
</thead>
<tbody data-bind="foreach: attachments">
<tr><td data-bind="text: Filename" /></tr>
</tbody>
</table>
<button data-bind="click: refresh">Refresh</button>
javascript
$(function () {
var ViewModel = function() {
var self = this;
self.count = 0;
self.getAttachments = function() {
var data = [{ Filename: "f"+(self.count*2+1)+".doc" },
{ Filename: "f"+(self.count*2+2)+".doc"}];
self.count = self.count + 1;
return data;
}
self.attachments = ko.observableArray(self.getAttachments());
self.refresh = function() {
self.attachments(self.getAttachments());
}
};
ko.applyBindings(new ViewModel());
});
--
You may also want to look at the mapping plugin - http://knockoutjs.com/documentation/plugins-mapping.html. It can help you transform JSON into View Models. Additionally it is able to assign a property to be the "key" for an object... this will be used to determine old vs new objects on subsequent mappings.
Here is a fiddle I wrote a while back to demonstrate a similar idea:
http://jsfiddle.net/wgZ59/276
NOTE: I use 'update' as part of my mapping rules, but ONLY so I can log to the console. You would only need to add this if you wanted to customize how the mapping plugin updated objects.

Categories

Resources