i am having issues with paging on server side with datatables jquery plugin. The paging control at the bottom of the grid shows
Showing 1 to 10 of 10 entries (filtered from 7,253 total entries)
but am not filtering any records. If I click the next or previous links no ajax requests are being sent back to the server. I would expect to see
Showing 1 to 10 of 7253 entries.
Controller Code
public ActionResult GetDataTable(DataTableParamModel param)
{
var allhotelscount = db.Businesses.OfType<Hotel>().Count();
var filteredhotels = db.Businesses.OfType<Hotel>().OrderBy(h => h.Name);
IEnumerable<DataTableHotel> displayedhotels = from c in filteredhotels
.Skip(param.iDisplayStart).Take(param.iDisplayLength)
select new DataTableHotel
{
Id = c.Id,
Name = c.Name,
CityState = c.PhysicalCity + ", " + c.PhysicalState,
PhoneNumber = c.PhoneNumber,
PrimaryContact = c.PrimaryContact.FirstName + " " + c.PrimaryContact.LastName,
PrimaryContactPhone = c.PrimaryContact.OfficePhone,
PrimaryContactEmail = c.PrimaryContact.EmailAddress,
};
return Json(new
{
sEcho = param.sEcho,
iTotalRecords = allhotelscount,
iTotalDisplayRecords = displayedhotels.Count(),
aaData = displayedhotels
},
JsonRequestBehavior.AllowGet);
}
View Code:
<table id="myDataTable" class="display">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>City, State</th>
<th>Phone</th>
<th>Contact</th>
<th>Phone</th>
<th>Email</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<script type="text/javascript">
$(document).ready(function () {
$('#myDataTable').dataTable({
"bServerSide": true,
"sAjaxSource": "/Hotel/GetDataTable",
"bProcessing": true,
"aoColumns": [
{ "mData": "Id" },
{ "mData": "Name" },
{ "mData": "CityState" },
{ "mData": "PhoneNumber" },
{ "mData": "PrimaryContact" },
{ "mData": "PrimaryContactPhone" },
{ "mData": "PrimaryContactEmail" },
]
});
});
You passed a wrong value to iTotalDisplayRecords, see below code:
return Json(new
{
sEcho = param.sEcho,
iTotalRecords = allhotelscount,
iTotalDisplayRecords = allhotelscount,
aaData = displayedhotels
},
JsonRequestBehavior.AllowGet);
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 have a Kendo Grid. The paging numbers are ok, items per page is ok, but when I press on page number the results in grid isn't changing, all results are shown in first page. Please help here.
Below is my code:
<script>
$(function() {
$("#invoices-grid").kendoGrid({
dataSource: {
data: #Html.Raw(JsonConvert.SerializeObject(Model.Invoices)),
schema: {
model: {
fields: {
JobNumber: { type: "string" },
CustomerName: { type: "string" },
DepartmentName: { type: "string" },
DateInvoice: { type: "string" },
ValidDays: { type: "number" },
Delivery: { type: "string" },
IsPayed: { type: "boolean" },
Payed: { type: "number" },
Status: { type: "boolean" },
}
}
},
#*type: "json",
transport: {
read: {
url: "#Html.Raw(Url.Action("List", "Finances"))",
type: "POST",
dataType: "json",
data: additionalData1
},
},
schema: {
data: "Data",
total: "Total",
errors: "Errors"
},*#
error: function(e) {
display_kendoui_grid_error(e);
// Cancel the changes
this.cancelChanges();
},
pageSize: 20,
serverPaging: true,
serverFiltering: true,
serverSorting: true
},
columns: [
{
field: "JobNumber",
title: "#T("gp.Invoice.Fields.JobNumber")",
template: '#= JobNumber #'
},
{
field: "CustomerName",
title: "#T("gp.Invoice.Fields.CustomerName")",
template: '#= CustomerName #'
},
{
field: "DepartmentName",
title: "#T("gp.Invoice.Fields.DepartmentName")",
template: '#= DepartmentName #'
},
{
field: "DateInvoice",
title: "#T("gp.Invoice.Fields.DateInvoice")",
template: '#= DateInvoice #'
},
{
field: "ValidDays",
title: "#T("gp.Invoice.Fields.ValidDays")",
template: '#= ValidDays #'
},
{
field: "Delivery",
title: "#T("gp.Invoice.Fields.Delivery")",
template: '#= Delivery #'
},
{
field: "Payed",
title: "#T("gp.Invoice.Fields.IsPayed")",
template: '#= (Payed == 2) ? "Комп." : ((Payed == 1) ? "ДЕ" : "НЕ") #'
},
{
field: "Id",
title: "#T("Common.Edit")",
width: 100,
template: '#T("Common.Edit")'
},
],
pageable: {
refresh: true,
pageSizes: [5, 10, 20, 50]
},
editable: {
confirmation: false,
mode: "popup"
},
scrollable: false,
selectable: true,
change: function(e) {
var selectedRows = this.select();
var jobId = parseInt($(selectedRows).data('job-id'));
var jobItemId = parseInt($(selectedRows).data('job-item-id'));
var result = $.get("#Url.Action("SideDetails", "Production")/" + jobItemId);
result.done(function(data) {
if (data) {
$(".job-edit .jobItemDetails").html(data);
}
});
},
rowTemplate: kendo.template($("#invoiceRowTemplate").html()),
});
});
</script>
protected virtual void PrepareInvoiceFinanceListModel(FinanceListModel model,FormCollection form/*,string SearchJobItemNumber*/)
{
var customers = model.SearchCustomerId;
var isChecked = model.IsChecked;
var searchString = model.SearchJobItemNumber;
var IsChecked1 = model.IsChecked1;
// searchString = model.SearchJobItemNumber;/* "001/2016";*/
//var searchString = model.SearchJobItemNumber;
//searchString = "091/2016";
if (model == null)
throw new ArgumentNullException("model");
var finishedJobs = _jobService.GetJobsByHasInvoice(false);
finishedJobs = finishedJobs.OrderByDescending(x =>
{
var firstOrDefault = x.JobItems.FirstOrDefault();
return firstOrDefault?.DateCompletition ?? new DateTime();
}).ToList();
foreach (var job in finishedJobs)
{
var jobModel = job.ToModel();
model.FinishedJobs.Add(jobModel);
}
var jobsBycustomers = finishedJobs.GroupBy(x => new { x.CustomerId, x.Customer.Name }).Select(x => new JobCustomersModel()
{
CustomerId = x.Key.CustomerId,
CustomerName = x.Key.Name,
JobsCount = x.Count(),
});
model.FinishedJobStatus = new JobStatusesModel()
{
Status = _localizationService.GetResource("gp.jobs.whitout.invoice"),
Value = (int)JobStatusEnum.Finished,
Count = finishedJobs.Count,
CustomersJobs = jobsBycustomers.ToList()
};
var invoices = _invoiceService.GetAllInvoices(searchString, isChecked, IsChecked1, customers);
foreach (var invoice in invoices)
{
var inv = invoice.ToModel();
// var a = invoice.Payed;
model.Invoices.Add(inv);
}
///////////////////// ////////////////////////
//var allCustomers = _invoiceService.GetAllCustomers(customers);
//foreach (var customer in allCustomers)
//{
// var cust = customer.ToModel();
// model.SearchCustomerId = customer.CustomerId;
// model.Invoices.Add(cust);
//}
var invoiceByCustomer = invoices
.GroupBy(x => new { x.CustomerId, x.CustomerName })
.Select(x => new JobCustomersModel()
{
CustomerId = x.Key.CustomerId,
CustomerName = x.Key.CustomerName,
JobsCount = x.Count(),
});
model.InvoiceStatus = new JobStatusesModel()
{
Status = _localizationService.GetResource("gp.jobs.with.invoice"),
Value = (int)JobStatusEnum.Finished,
Count = invoices.Count,
CustomersJobs = invoiceByCustomer.ToList()
};
var latestOffers = _offerService.GetLatestOffers(0, 10);
foreach (var offer in latestOffers)
{
var offerModel = offer.ToModel();
model.LatestOffers.Add(offerModel);
}
}
Currently server operations are enabled...
serverPaging: true,
serverFiltering: true,
serverSorting: true
... but the transport configuration is commented out. This is the cause of the problem.
If you want to use server operations, then configure the dataSource transport. Otherwise, use local data binding and disable server operations, as in this example:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled</title>
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.3.914/styles/kendo.common.min.css">
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.3.914/styles/kendo.default.min.css">
<script src="http://code.jquery.com/jquery-1.12.3.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2016.3.914/js/kendo.all.min.js"></script>
</head>
<body>
<div id="invoices-grid"></div>
<script>
$(function() {
var d = [];
for (var i = 1; i <= 100; i++) {
d.push({Id: i, CustomerName: "CustomerName " + i});
}
$("#invoices-grid").kendoGrid({
dataSource: {
data: d,
schema: {
model: {
id: "Id",
fields: {
CustomerName: { type: "string" }
}
}
},
error: function(e) {
display_kendoui_grid_error(e);
// Cancel the changes
this.cancelChanges();
},
pageSize: 20,
//serverPaging: true,
//serverFiltering: true,
//serverSorting: true
},
columns: [
{
field: "CustomerName",
title: "gp.Invoice.Fields.CustomerName",
template: '#= CustomerName #'
},
{
field: "Id",
title: "Common.Edit",
width: 100,
template: 'Common.Edit'
},
],
pageable: {
refresh: true,
pageSizes: [5, 10, 20, 50]
},
editable: {
confirmation: false,
mode: "popup"
},
scrollable: false,
selectable: true,
change: function(e) {
}
});
});
</script>
</body>
</html>
I am trying to create batch insert , update , delete using kendo ui grid and MVC.
Here is my code for View and Controller.
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<link href="~/Content/kendo.custom.css" rel="stylesheet" />
<link href="~/Content/kendo.common.min.css" rel="stylesheet" />
<script src="~/Scripts/kendo.all.min.js"></script>
<script src="~/Scripts/kendo.custom.js"></script>
<div>
<div id="grid"></div>
<script>
$(document).ready(function () {
$("#grid").kendoGrid({
editable: true,
pageable: true,
sortable: true,
filterable: true,
toolbar: ["create", "save", "cancel"],
columns: [
"Name",
{ command: "destroy", title: "Delete", width: "110px" }
],
dataSource: {
transport: {
create: {
url: "#Url.Action("Create", "VendorType")",
dataType: "json",
type: "POST"
},
read: {
url: "#Url.Action("Read", "VendorType")",
contentType: "application/json",
type: "POST"
}
},
serverPaging: true,
serverFiltering: true,
serverSorting: true,
pageSize: 5,
schema: {
data: "Data",
total: "Total",
model: {
id: "Id",
fields: {
Id: { editable: false, nullable: true },
Name: { validation: { required: true } }
}
}
}
}
});
});
</script>
</div>
Controller :
[HttpPost]
public ActionResult Read(int take, int skip, IEnumerable<Sort> sort, Kendo.DynamicLinq.Filter filter)
{
var result = db.VendorTypes
.OrderBy(p => p.Id)
.ToDataSourceResult(take, skip, sort, filter);
return Json(result);
}
[HttpPost]
public ActionResult Create(IEnumerable<VendorType> types)
{
var result = new List<VendorType>();
try
{
foreach (var category in types)
{
result.Add(category);
// Add the entity
db.VendorTypes.Add(category);
}
db.SaveChanges();
}
catch (DbEntityValidationException e)
{
foreach (var eve in e.EntityValidationErrors)
{
Console.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
eve.Entry.Entity.GetType().Name, eve.Entry.State);
foreach (var ve in eve.ValidationErrors)
{
Console.WriteLine("- Property: \"{0}\", Error: \"{1}\"",
ve.PropertyName, ve.ErrorMessage);
}
}
}
return Json(result);
}
Now the read operation works fine. but when i try to save the entries the list of objects in CREATE , UPDATE Or DELETE methods are always null. I can see the values being passed in the browser but in the controller they are not available. Can any one point out a mistake i am making ?
I found the solution for this. The model name which you have as parameter in controller need to be mapped using "ParameterMap" of kendo UI.
parameterMap: function (data, operation) {
if (operation != "read") {
var result = {};
for (var i = 0; i < data.models.length; i++) {
var site = data.models[i];
for (var member in site) {
result["projects[" + i + "]." + member] = site[member];
}
}
return result;
} else {
return JSON.stringify(data)
}
}
As my parameters collection is defined as "projects" my controller action method should have the same name for the argument.
i.e
public ActionResult Create(IEnumerable<Project> projects)
{
}
Hope this will help some one.
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 am trying to display characters from different languages on my screen. These characters are generated by a csv file which is convert to JSON format as follows
{
"id": 32,
"name": "Hindi",
"csv": [
{
"keycode": "1",
"unicode": "\u0D15",
"chakra": "1"
},
{
"keycode": "1",
"unicode": "\u0D15",
"chakra": "1"
},
{
"keycode": "1",
"unicode": "\u0D15",
"chakra": "1"
}
]
}
I am seeing the html unicodes displayed on the screen though I am using $sce.trustAshtml() for the unicode values via filter. Here is my angularJS code.
controller :
app.controller("KeyboardController", [
"$scope", "Restangular", "LanguageModel", "KeyboardModel", "$sce", function($scope, Restangular, LanguageModel, KeyboardModel, $sce) {
var languageResource;
$scope.languages = LanguageModel.getAll();
languageResource = Restangular.one("languages");
angular.element("#chakra").css("display", "none");
languageResource.getList("all").then(function(languageobject) {
LanguageModel.addAll(languageobject);
KeyboardModel.addlanguage(languageobject);
$scope.onscreen = KeyboardModel.getallkeys();
$scope.firstmaintablekeys = KeyboardModel.maintablelayout1();
});
}
]);
keyboardModel : service.
app.factory("KeyboardModel", function() {
var KeyboardModel;
KeyboardModel = function() {
this.keys = [];
this.key = [];
this.keyid = {};
this.languageobject = {};
};
KeyboardModel.prototype = {
addlanguage: function(languageobject) {
this.languageobject = languageobject;
},
getallkeys: function() {
var currentlanguage, div, grouped, i, mod, totalrows;
currentlanguage = this.languageobject[1];
totalrows = currentlanguage.csv.length;
grouped = [];
i = 0;
while (i < totalrows) {
div = Math.floor(i / 5);
mod = i % 5;
if (mod === 0) {
grouped[div] = [];
}
grouped[div][mod] = currentlanguage.csv[i];
i++;
}
this.keys = grouped;
return grouped;
},
maintablelayout1: function(language) {
var i, table;
i = 0;
table = [];
while (i < 4) {
table[i] = this.keys[i];
i++;
}
return table;
}
};
return new KeyboardModel();
});
HTML :
<div class="maintable1 frame1" ng-show="frame1">
<table>
<thead></thead>
<tbody>
<tr ng-repeat="data in firstmaintablekeys">
<td ng-repeat="row in data" data-keycode="{{ row.keycode }}" data-chakra="{{ row.chakra }}" ng-mousedown="displaychakra(row.keycode, row.unicode, $event)" ng-mouseup="hidechakra()" ng-click="sharetext(row.unicode)">
<span ng-bind-html="row.unicode | unsafeFilter"></span>
</td>
</tr>
</tbody>
</table>
</div>
Filter :
app.filter("unsafeFilter", function($sce) {
return function(val) {
return $sce.trustAsHtml(val);
};
});
Am I missing something? Why do I get unicodes displayed instead of their corresponding values?
EDIT : I have been told its a server side issue. Here is my controller which reads the CSV file that contains the Unicodes.
class LanguagesController < ApplicationController
def index
end
def all
availablelanguages = {
:data => []
}
#language = Language.all.each do |eachlanguage|
availablelanguages[:data] << {
:id => eachlanguage.id,
:name => eachlanguage.languagename,
:csv => []
}
CSV.foreach(eachlanguage.path) do |row|
availablelanguages[:data].each do |single|
single[:csv] << {
:keycode => row[0],
:unicode => row[1],
:chakra => row[2]
}
end
end
#data = JSON.pretty_generate(availablelanguages[:data])
end
render json: #data
end
end
Here is the screenshot of the JSON response generated. It adds an additional backlash to make the string literal. http://i.imgur.com/FY0F1l9.png?1
I had to do the same recently. JSON returned unicode (Chinese). Didn't have to do any thing to decode it. Just insert this line in your header area.
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>