I am very new to AngularJS. I have read several posts on this topic, but am still unable to get data from external JSON file.
here is my code
data.json
[
{
"id": 1,
"date": "20th August 2016",
"day": "Sat",
"in1": "10:30",
"out1": "02:30",
"in2": "04:00",
"out2": "08:00",
"in3": "",
"out3": "",
"total_hours": "8:00",
"status": "1"
},
{
"id": 2,
"date": "20th August 2016",
"day": "Sat",
"in1": "10:30",
"out1": "02:30",
"in2": "04:00",
"out2": "08:00",
"in3": "",
"out3": "",
"total_hours": "8:00",
"status": "1"
}
];
html
<table ng-table="tctrl.tableEdit" class="table table-striped table-vmiddle">
<tr ng-repeat="w in $data" ng-class="{ 'active': w.$edit }">
<td data-title="'ID'">
<span ng-if="!w.$edit">{{ w.id }}</span>
<div ng-if="w.$edit"><input class="form-control" type="text" ng-model="w.id" /></div>
</td>
...
</tr>
</table>
controller.js
.controller('tableCtrl', function($filter, $sce, ngTableParams, tableService) {
var data = tableService.data;
//Editable
this.tableEdit = new ngTableParams({
page: 1, // show first page
count: 10 // count per page
}, {
total: data.length, // length of data
getData: function($defer, params) {
$defer.resolve(data.slice((params.page() - 1) * params.count(), params.page() * params.count()));
}
});
})
service.js
.service('tableService', [function($http){
this.data = function() {
return $http.get('data/timesheet.json');
}
}])
I'm just trying to pull data from json file but it's not working and getting blank table. I don't know what is the issue. What I will get in this.data?
Related
Showing "Processing..." in datatable when data is empty in mvc view. I am confusing that why it is showing "Processing...". If there is empty data then it want to show "No data available in table"
Here is my code
[View Side]
<div class="row">
<div class="col-md-12">
<table id="dataGrid" class="display table table-striped table-bordered dt-responsive nowrap" width="100%" cellspacing="0">
<thead>
<tr>
<th>Id</th>
<th>Document Name</th>
<th>Other Document Name</th>
<th>Image</th>
<th>Action</th>
</tr>
</thead>
</table>
</div>
</div>
<script>
$(document).ready(function () {
var data = {
'customerId': #Model.Id,
}
addAntiForgeryToken(data);
// DataTable
$("#dataGrid").DataTable({
"scrollX": true, // scrolling horizontal
"bSort": false,
"bFilter": false,
"processing": true, // for show progress bar
"serverSide": true, // for process server side
"pageLength": 5,
"lengthMenu": [5, 10, 50, 100, 1000, 10000],
"ajax": {
"url": "/Admin/FreeLancer/list",
"type": "POST",
"datatype": "json",
"data": data,
"success": function (data) {
}
},
"columnDefs":
[{
"targets": [0],
"visible": false,
"searchable": false,
"orderable": false,
}
],
"columns": [
{ "data": "Id", "name": "Id", "autoWidth": true },
{ "data": "DocumentName", "name": "DocumentName", "autoWidth": true },
{ "data": "OtherDocumentName", "name": "otherdocumentname", "autoWidth": true },
{ "data": "UploadID", "name": "UploadID", "autoWidth": true },
{
"render": function (data, type, row) {
//return "<a target='_blank' href='/Download/GetDownload?downloadId=" + row.UploadID + "' class='btn btn-info'>Download </a>" +
//"<a href='#' class='btn btn-danger' onclick=DeleteData('" + row.Id + "');>Delete</a>"; }
return "<a href='#' class='btn btn-danger' onclick=DeleteData('" + row.Id + "');>Delete</a>";
}
},
],
});
});
</script>
[Controller Side]
[HttpPost]
public IActionResult List(int customerId)
{
// getting all data
var dataList = _customerRegister.DocumentList(customerId,
start: Convert.ToInt32(Request.Form["start"]),
pageSize: Request.Form["length"].ToString() != null ? Convert.ToInt32(Request.Form["length"].ToString()) : 0,
sortColumnName: Request.Form["columns[" + Request.Form["order[0][column]"] + "][name]"],
sortColumnDirection: Request.Form["order[0][dir]"]);
var data = dataList.Select(x => new
{
Id = x.Id,
DocumentName = x.DocumentName,
OtherDocumentName = x.OtherDocumentName,
UploadID = x.UploadID,
});
//returning json data
Response.StatusCode = 200;
return Json(new { draw = Request.Form["draw"], recordsfiltered = dataList.TotalCount, recordstotal = dataList.TotalCount, data = data });
}
This is the code, but I dont think so that their is any problem in the code
Have you checked the DataTables dom property?
$("#table_selector").DataTable({
dom: 'r<"datatable-header"fl><"datatable-scroll"t><"datatable-footer"ip>',
processing: true,
serverSide: true
});
Options
The built-in table control elements in DataTables are:
l - length changing input control
f - filtering input
t - The table!
i - Table information summary
p - pagination control
r - processing display element
https://datatables.net/reference/option/dom
I can see that there is no code for displaying the message. If you are using JQuery Data table which i have notice you can use:
oLanguage: {
sEmptyTable: "Message",
sZeroRecords: "Message",
},
I am trying a proof of concept in SAPui5 to check the content of a searchfield, bind a result into another field, if i don't have any result i display an error message that has been written in a message field of my odata
so far i succeeded that this way
this.getView().bindElement({
path: "/ExcSet('" + evt.getSource().getValue() + "')",
model: "EXCEPTION",
events: {
dataReceived: function(response) {
if (response.mParameters.data.Message !== '') {
MessageBox.error(response.mParameters.data.Message);
}
}
}
(If someone knows how to do that a better way, because using mParameters is not the best way, it is welcome)
Now, I want to extend my odata call with an expand navigation to display a table of results, by not using another odata call that the one i used already, so here is my code so far :
eanSearch: function(evt) {
var oView = this.getView();
var oTemplate = new ColumnListItem({
cells: [
new Text({
text: "{Volum}"
}),
new Text({
text: "{Voleh}"
})
]
});
this.getView().bindElement({
path: "/ExcSet('" + evt.getSource().getValue() + "')",
model: "EXCEPTION",
parameters: {
expand: "ExcMarmNav"
},
events: {
dataReceived: function(response) {
if (response.mParameters.data.Message !== '') {
MessageBox.error(response.mParameters.data.Message);
}
}
}
});
oView.byId("table").bindItems({
path : '/ExcMarmNav',
template : oTemplate
});
}
The data of the expand is loaded into my response as you can see here
data: {
"ExcSet('5410366897766')": {
"__metadata": {
"id": "http://...:8000/sap/opu/odata/sap/ZEXCEPTION_SRV/ExcSet('5410366897766')",
"uri": "http://...:8000/sap/opu/odata/sap/ZEXCEPTION_SRV/ExcSet('5410366897766')",
"type": "ZEXCEPTION_SRV.Exc"
},
"Matnr": "000000000040000000",
"Ean": "5410366897766",
"Message": "",
"ExcMarmNav": {
"__list": [
"MarmSet(Matnr='40000000',Meinh='EA')"
]
}
},
"MarmSet(Matnr='40000000',Meinh='EA')": {
"__metadata": {
"id": "http://...:8000/sap/opu/odata/sap/ZEXCEPTION_SRV/MarmSet(Matnr='40000000',Meinh='EA')",
"uri": "http://...:8000/sap/opu/odata/sap/ZEXCEPTION_SRV/MarmSet(Matnr='40000000',Meinh='EA')",
"type": "ZEXCEPTION_SRV.Marm"
},
"Matnr": "40000000",
"Meinh": "EA",
"Umrez": "1",
"Umren": "1",
"Eannr": "",
"Ean11": "5410366897766",
"Numtp": "HE",
"Laeng": "20.000",
"Breit": "20.000",
"Hoehe": "10.000",
"Meabm": "CM",
"Volum": "4000.000",
"Voleh": "CCM",
"Brgew": "2.500",
"Gewei": "KG",
"Mesub": "",
"Atinn": "0000000000",
"Mesrt": "00",
"Xfhdw": "",
"Xbeww": "",
"Kzwso": "",
"Msehi": "",
"BflmeMarm": "",
"GtinVariant": "",
"NestFtr": "0",
"MaxStack": 0,
"Capause": "0.000",
"Ty2tq": ""
}
}
But i don't know how to use resultset to bind it into a table, my code above is not working, if someone has an idea of the params to use for my binditems, or if there is another way to do it?
Best regards
Denis
I managed to do the binding of my table using an intermediate JSON Model based on the response of the Odata Model
eanSearch: function(evt) {
var oView = this.getView();
this.getView().bindElement({
path: "/ExcSet('" + evt.getSource().getValue() + "')",
model: "EXCEPTION",
parameters: {
expand: "ExcMarmNav"
},
events: {
dataReceived: function(response) {
if (response.mParameters.data.Message !== '') {
MessageBox.error(response.mParameters.data.Message);
} else {
var model = new JSONModel({
"items": response.mParameters.data.ExcMarmNav
});
oView.setModel(model, "itemModel");
}
}
}
});
And this is the XML view:
<Table id="table" items="{itemModel>/items}">
<columns>
<Column><Label/></Column>
<Column><Label/></Column>
</columns>
<ColumnListItem>
<cells>
<Text text="{itemModel>Volum}"/>
<Text text="{itemModel>Voleh}"/>
</cells>
</ColumnListItem>
</Table>
works fine but I would like to avoid using the intermediate JSON Model and bind directly the array of the response in the table
Ok I managed to find what I needed :)
so the controller:
eanSearch: function(evt) {
var oView = this.getView();
this.getView().bindElement({
path: "/ExcSet('" + evt.getSource().getValue() + "')",
model: "EXCEPTION",
parameters: {
expand: "ExcMarmNav"
},
events: {
dataReceived: function(response) {
if (response.mParameters.data.Message !== '') {
MessageBox.error(response.mParameters.data.Message);
}
}
}
});
}
and the view:
<Table noDataText="No Data" items="{EXCEPTION>ExcMarmNav}">
<columns>
<Column><Label/></Column>
<Column><Label/></Column>
</columns>
<items>
<ColumnListItem>
<cells>
<Text text="{EXCEPTION>Volum}"/>
<Text text="{EXCEPTION>Voleh}"/>
</cells>
</ColumnListItem>
</items>
</Table>
I'm trying to format my JSON file so that when parsed it will display as paragraphs with line breaks like this:
This is one line.
This is a second line.
This is a third line.
I've tried \n \\n \p\n but to no avail.
Here is the iPhone screen where I want the text parsed:
Here is the JSON file. Particularly the "body" tag is where I want to do this:
{
"id": 1,
"jsonrpc": "2.0",
"total": 5,
"result": [
{
"id": 1,
"guid": "1d4aa3b2-c059-4fa7-a751-9bca735e4ebb",
"thumb": "http://skounis.s3.amazonaws.com/mobile-apps/barebone-glossy/photo-1-thumb.jpg",
"picture": "http://skounis.s3.amazonaws.com/mobile-apps/barebone-glossy/photo-1.jpg",
"title": "Continuing Education 2015 Class Schedule",
"body": "October 24, 2015 from 9am - 1pm\nOctober 24, 2015 from 9am - 1pm",
"tags": ["continuing ed"]
}
]
}
new.service.js file that downloads the JSON:
(function() {
'use strict';
angular
.module('barebone.news')
.factory('newsService', newsService);
newsService.$inject = ['$http', '$q'];
/* #ngInject */
function newsService($http, $q) {
var url = 'https://s3-us-west- 2.amazonaws.com/cisnerostraininggroup/news.json';
var result = [];
var service = {
all: all,
get: get
};
return service;
// *******************************************************
// http://stackoverflow.com/questions/17533888/s3-access-control-allow- origin-header
function all(callback){
$http.get(url)
.success(function(data, status, headers, config) {
// this callback will be called asynchronously
// when the response is available
result = data.result;
callback(result);
})
.error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
console.log('ERROR (News):' + status);
callback(result);
});
}
function get(articleId) {
// we take an article from cache but we can request ir from the server
for (var i = 0; i < result.length; i++) {
if (result[i].id === articleId) {
return $q.when(result[i]);
}
}
return $q.when(null);
}
}
})();
Ionic views are html views. So \n are ignored unless in <pre> tags, so after loading your data, iterate over your objects as:
var myobject = {
"id": 1,
"jsonrpc": "2.0",
"total": 5,
"result": [
{
"id": 1,
"guid": "1d4aa3b2-c059-4fa7-a751-9bca735e4ebb",
"thumb": "http://skounis.s3.amazonaws.com/mobile-apps/barebone-glossy/photo-1-thumb.jpg",
"picture": "http://skounis.s3.amazonaws.com/mobile-apps/barebone-glossy/photo-1.jpg",
"title": "Continuing Education 2015 Class Schedule",
"body": "October 24, 2015 from 9am - 1pm\nOctober 24, 2015 from 9am - 1pm",
"tags": ["continuing ed"]
}
]
}
myobject.result[0].body = myobject.result[0].body.replace(/(?:\r\n|\r|\n)/g, '<br />');
This will replace all occurrences of line breaks \n with tags and display properly in your html.
The regex to replace newlines with is copied from https://stackoverflow.com/a/784547/2303348
UPDATE:
service to fetch and update results to replace newline with
(function() {
'use strict';
angular
.module('barebone.news')
.factory('newsService', newsService);
newsService.$inject = ['$http', '$q'];
/* #ngInject */
function newsService($http, $q) {
var url = 'https://s3-us-west-2.amazonaws.com/cisnerostraininggroup/news.json';
var result = [];
var nlRegex = new RegExp(/(?:\r\n|\r|\n)/g);
var service = {
all: all,
get: get
};
return service;
// *******************************************************
// https://stackoverflow.com/questions/17533888/s3-access-control-allow- origin-header
function all(callback){
$http.get(url)
.success(function(data, status, headers, config) {
// this callback will be called asynchronously
// when the response is available
result = data.result;
for (var i in result){
result[i].body = result[i].body.replace(nlRegex, "<br />");
}
callback(result);
})
.error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
console.log('ERROR (News):' + status);
callback(result);
});
}
function get(articleId) {
// we take an article from cache but we can request ir from the server
for (var i = 0; i < result.length; i++) {
if (result[i].id === articleId) {
return $q.when(result[i]);
}
}
return $q.when(null);
}
}
})();
{
"id": 1,
"jsonrpc": "2.0",
"total": 5,
"result": [
{
"id": 1,
"guid": "1d4aa3b2-c059-4fa7-a751-9bca735e4ebb",
"thumb": "http://skounis.s3.amazonaws.com/mobile-apps/barebone-glossy/photo-1-thumb.jpg",
"picture": "http://skounis.s3.amazonaws.com/mobile-apps/barebone-glossy/photo-1.jpg",
"title": "Continuing Education 2015 Class Schedule",
"body": "October 24, 2015 from 9am - 1pm<br />October 24, 2015 from 9am - 1pm",
"tags": ["continuing ed"]
}
]
}
So I figured out how to create line breaks in my JSON. I just created new objects and then added those objects to the corresponding HTML.
JSON file:
{
"id": 1,
"jsonrpc": "2.0",
"total": 5,
"result": [
{
"id": 1,
"guid": "1d4aa3b2-c059-4fa7-a751-9bca735e4ebb",
"thumb": "http://skounis.s3.amazonaws.com/mobile-apps/barebone-glossy/photo-1-thumb.jpg",
"picture": "http://skounis.s3.amazonaws.com/mobile-apps/barebone-glossy/photo-1.jpg",
"title": "Continuing Education 2015 Class Schedule",
"body1": "October 24, 2015 from 9am - 1pm",
"body2": "November 7, 2015 from 9am - 1pm",
"body3": "November 18, 2015 from 5:30 - 9:30pm",
"tags": ["continuing ed"]
}
]
}
HTML file (Ionic HTML):
<ion-view view-title="Article">
<ion-content>
<img ng-src="{{vm.article.picture}}" />
<div class="content-inner">
<h1>{{vm.article.title}}</h1>
<p>{{vm.article.body1}}</p>
<p>{{vm.article.body2}}</p>
<p>{{vm.article.body3}}</p>
</div>
</ion-content>
</ion-view>
I am struggling to get serialised JSON data from my controller to display in a Datatable. I previously was able to display data when I was sending it as a 2D array. Now I would like to be able to use my object and match it with the columns (as seen in the second JavaScript). I attempted to follow this solution, but I am unable to see what is wrong after looking at the Datatables docs.
Updated
See below what I currently have. I am trying to have the data come through with named parameters as I wish to have parent rows with a list of child items. These items are visible on selection as seen in this DataTables link. Though I am still unable to get the table working with named parameters via JSON data.
Data:
for (int i = 0; i < 26; i++)
{
list.Add(new MembershipTransactionHistoryModel
{
TransactionDate = "01 May 2014",
StoreName = "Store Name",
CardNumber = "23423566",
TransactionType = "Purchase",
TransactionValue = "$134.25",
PointsEarned = "100",
PointsUsed = "23",
PointsBalance = "40000"
});
}
//return new JavaScriptSerializer().Serialize(list);
return from l in list
select new[] {
l.TransactionDate,
l.StoreName,
l.CardNumber,
l.TransactionType,
l.TransactionValue,
l.PointsEarned,
l.PointsUsed,
l.PointsBalance
};
JavaScript:
var grid = $('#transactionHistoryTable').dataTable({
"bProcessing": true,
"sAjaxSource": 'MembershipTransactionHistoryData',
"fnServerParams": function (aoData) {
aoData.push({ "name": "membershipId", "value": 7 })
},
"aoColumnDefs": [
{
"sTitle": "",
"class": 'details-control',
"orderable": false,
"mData": null,
"aTargets": [0],
"defaultContent": ''
},
{ "sTitle": "Transaction Date", "mData" : "TransactionDate", "aTargets": [1]},
{ "sTitle": "Store Name", "mData": "StoreName", "aTargets": [2] },
{ "sTitle": "Card Number", "mData": "CardNumber", "aTargets": [3] },
{ "sTitle": "Type", "mData": "Type", "aTargets": [4] },
{ "sTitle": "Value", "mData": "Value", "aTargets": [5] },
{ "sTitle": "Points Earned", "mData": "PointsEarned", "aTargets": [6] },
{ "sTitle": "Points Used", "mData": "PointsUsed", "aTargets": [7] },
{ "sTitle": "Points Balance", "mData": "PointsBalance", "aTargets": [8] }
],
"paginate": true,
"scrollY": maxHeight,
"scrollCollapse": false,
"sort": true
});
HTML:
<table id="transactionHistoryTable" class="display" cellspacing="0">
<thead>
<tr>
</tr>
</thead>
<tbody>
</tbody>
</table>
Resulting Error:
DataTables warning: table id=transactionHistoryTable - Requested unknown parameter 'TransactionDate' for row 0. For more information about this error, please see http://datatables.net/tn/4
You have to return it as String Array [] not just a List.
Result should be in Array, it is must: new string[].
Note: After the For loop add below code:
var results = from l in list
select new[] {
l.TransactionDate,
l.StoreName ,
l.CardNumber,
l.TransactionType,
l.TransactionValue,
l.PointsEarned,
l.PointsUsed,
l.PointsBalance
};
return Json(results, JsonRequestBehavior.AllowGet); // Return the Result as a string array.
No need to serialize pro-grammatically. It will be serialized automatically.
Data Table expects your results should be in a array. where as you are passing it as a list of class objects.
Take a look at this DataTables - Server side processing Article.
The way I managed to do this in the end, was to avoid JavaScript entirely and just structure my HTML accordingly via my view's Model.
Eg.
<tbody>
#foreach(var item in Model.GetData())
{
<tr>
<td class="details-control"></td>
<td>#item.TransactionId</td>
<td>#item.TransactionDate</td>
<td>#item.StoreName</td>
<td>#item.CardNumber</td>
<td>#item.TransactionType</td>
<td>#item.TransactionValue</td>
<td>#item.PointsEarned</td>
<td>#item.PointsUsed</td>
<td>#item.PointsBalance</td>
</tr>
}
</tbody>
I then used the documentation from DataTables to construct my sub-item table and performed a post to get that data.
My success method in the ajax post was as below:
success: function (data) {
var html = '<table cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">';
for (var i = 0; i < data.length; i++) {
html += '<tr>' +
'<td>APN:</td>' +
'<td>' + data[i].ProductAPN + '</td>' +
'<td>Desc:</td>' +
'<td>' + data[i].ProductDescription + '</td>' +
'<td>Qty:</td>' +
'<td>' + data[i].Quantity + '</td>' +
'<td>Amount:</td>' +
'<td>' + data[i].Amount + '</td>' +
'<td>Points:</td>' +
'<td>' + data[i].PointsEarned + '</td>' +
'</tr>'
}
html += '</table>';
// Open this row
row.child(html).show();
tr.addClass('shown');
}
I'm trying to get an order from a KnockoutJS viewmodel, but having a hard time getting this done.
This is what the viewmodel looks like:
{"Orders":
[{"Id":16,"Status":2,
"Products":
[{"Id":14,"OrderId":16,"Price":5},
{"Id":15,"OrderId":16,"Price":10},
{"Id":16,"OrderId":16,"Price":20},
{"Id":17,"OrderId":16,"Price":30}]},
{"Id":17,"Status":2,
"Products":
[{"Id":18,"OrderId":17,"Price":0}]}
]}
This is one of my many tries:
var viewModel = ko.mapping.fromJS(#Html.Raw(Json.Encode(Model)));
ko.applyBindings(viewModel);
$(document).on("click", ".btnDetails", function () {
var oId = $(this).attr('id');
debugger;
var order = ko.utils.arrayFirst(viewModel.Orders(), function (item) {
return item.Id === oId;
});
});
How can I get the complete order with Id 16?
This is not an observableArray(), there are no mutations done. This will only serve as showing the details of an order in a Modal (Twitter Bootstrap).
It looks like your code should work just fine, except that your arrayFirst() function has an error. You should have
var order = ko.utils.arrayFirst(viewModel.Orders(), function(item) {
return item.Id() === oId;
});
Because you mapped your viewmodel properties, comparing the Id of item will still be comparing the ko function. You need to get the value and compare that directly. Once you've done that, order should be the first order that matches the id.
I'm not entirely clear on what you mean by the complete order. but have a look at this jsfiddle
EDIT
re-reading the question again its starting to make sense to me.
To get a reference to the order
add a selectedOrder observable to your viewmodel.
then add a function showOrder that takes in an the order. and set the selectedOrder to the incomming item
on the tag that contains the order data-bind to the click.
and that should get you pretty close to what I believe you need as the selectedOrder will contain all the products as well for display purposes
HMTL
<ul class="list-group" data-bind="foreach: data.Orders">
<li class="list-group-item">
<h3 data-bind="click: $parent.showItem">
Order <span data-bind="text: Id"></span>
</h3>
</li>
</ul>
JS
var model = {
"Orders": [{
"Id": 16,
"Status": 2,
"Products": [{
"Id": 14,
"OrderId": 16,
"Price": 5
}, {
"Id": 15,
"OrderId": 16,
"Price": 10
}, {
"Id": 16,
"OrderId": 16,
"Price": 20
}, {
"Id": 17,
"OrderId": 16,
"Price": 30
}]
},
{
"Id": 17,
"Status": 2,
"Products": [{
"Id": 18,
"OrderId": 17,
"Price": 0
}]
}]
};
var selectedOrder = ko.observable();
function showItem(item) {
selectedOrder(item);
alert("Selected Order: " + item.Id());
}
var vm = {
data: model,
showItem: showItem,
selectedOrder: selectedOrder
};
$(document).ready(function () {
var viewModel = ko.mapping.fromJS(vm);
ko.applyBindings(viewModel);
});