How to parse json using sapui5 - javascript

I am currently parsing json and displaying the data in a table control using sapui5,but i am unable to parse inner objects values
CODE:
<!DOCTYPE html>
<html><head>
<meta http-equiv='X-UA-Compatible' content='IE=edge' />
<title>Table example</title>
<!-- Load UI5, select gold reflection theme and the "commons" and "table" control libraries -->
<script id='sap-ui-bootstrap' type='text/javascript'
src='resources/sap-ui-core.js'
data-sap-ui-theme='sap_goldreflection'
data-sap-ui-libs='sap.ui.commons,sap.ui.table'></script>
<script>
// create the DataTable control
var oTable = new sap.ui.table.Table({editable:true});
// define the Table columns
var oControl = new sap.ui.commons.TextView({text:"{comments/data/from/username}"}); // short binding notation
oTable.addColumn(new sap.ui.table.Column({label: new sap.ui.commons.Label({text: "Group"}), template: oControl }));
var oControl = new sap.ui.commons.TextView({text:"{comments/data/from/id}"}); // short binding notation
oTable.addColumn(new sap.ui.table.Column({label: new sap.ui.commons.Label({text: "Group Text"}), template: oControl }));
var oModel = new sap.ui.model.json.JSONModel();
var aData =
jQuery.ajax({
url: "https://api.instagram.com/v1/media/popular?client_id=d6ff37e000de4fc7882e4e5fccfff236", // for different servers cross-domain restrictions need to be handled
dataType: "json",
success: function(data, textStatus, jqXHR) { // callback called when data is received
var JsonData = data;
oModel.setData(JsonData); // fill the received data into the JSONModel
alert("sparta");
},
error: function(jqXHR, textStatus, errorThrown) {
alert("error");
}
});
// create a JSONModel, fill in the data and bind the Table to this model
// oModel.setData(aData);
oTable.setModel(oModel);
oTable.bindRows("/data");
// finally place the Table into the UI
oTable.placeAt("content");
</script>
</head>
<body class='sapUiBody'>
<div id='content'></div>
</body>
</html>
How do i fetch the inner element values such as username and id etc..

Try something like
var oControl = new sap.ui.commons.TextView().bindProperty("text", "user/usernme");
oTable.addColumn(new sap.ui.table.Column({label: new sap.ui.commons.Label({text: "User Name"}), template: oControl}));
var oControl = new sap.ui.commons.TextView().bindProperty("text", "user/id");
oTable.addColumn(new sap.ui.table.Column({label: new sap.ui.commons.Label({text: "UserID"}), template: oControl}));
https://sapui5.hana.ondemand.com/sdk/#docs/guide/JSONModel.html

var arr = oModel.getData();
Using this you get the data for that model, then you can loop through the data or parse it.

Related

How to transfer param from js file to javascript in HTML?

I have some variables in sort-item.js file and want to trasfer them to js in html.
Here are the details:
Because of Django CSRF protection when post data, I could only put the $ajax function in html like this:
<html>
<body>...</body>
<script>
var post_data = {
"name": "saveorder",
"item_id": item_dataid,
"from": from_index,
"to": to_index,
"order": order
};
$.ajax({
type: 'POST',
data: post_data,
...
});
</script>
<html>
Meanwhile I have got this below in sort-item.js and can show the data in console log:
var itemContainers = Array.prototype.slice.call(kanban.querySelectorAll('.board'));
itemContainers.forEach(function (container) {
.on('dragReleaseEnd', function (item) {
...
var item_dataid = item.getElement().getAttribute('data-id');
console.log(item_dataid);
var order = muuri.getItems().map(item => item.getElement().getAttribute('data-id'));
console.log(order);
})
.on('move', function (data) {
var from_index = data.fromIndex;
var to_index = data.toIndex;
console.log(from_index + ' ' + to_index);
})
}
My question is how to transfer data.fromIndex, data.toIndex, order from sort-item.js to javascript variable post_data in html?
I have solved this problem by use a globle variable in sort-item.js.

Json.getproperty giving undefined

I have the following code where I need do draw a table using sap ui5 JSON Model. When I run the program I'm getting no data in the output table. I json.getProperty alert I'm getting alert output as undefined.
<!DOCTYPE html>
<html>
<head>
<!-- Load UI5, select gold reflection theme and the "commons" and "table" control libraries -->
<script id="sap-ui-bootstrap"
type="text/javascript"
src="https://sapui5.netweaver.ondemand.com/resources/sap-ui-core.js"
data-sap-ui-theme="sap_bluecrystal"
data-sap-ui-libs="sap.ui.commons,sap.ui.table"></script>
<script>
jQuery.ajax({
url: "/XMII/Illuminator?QueryTemplate=ZTest/QueryTemplates/table%20list&content-type=text/json",
dataType: "json",
success: function(data, textStatus, jqXHR) { // callback called when data is received
var jsonModel = new sap.ui.model.json.JSONModel();
jsonModel.loadData(data);
sap.ui.getCore().setModel(jsonModel);
var weatherTable = new sap.ui.table.Table({
title : "Current Weather Details",
visibleRowCount : 20
});
weatherTable.addColumn(new sap.ui.table.Column({
label : new sap.ui.commons.Label({text : "Tablename"}),
template : new sap.ui.commons.TextView().bindText("TableName")
}));
var oModel1 = new sap.ui.model.json.JSONModel();
var aData = jsonModel.getProperty("/Rowsets/Rowset/Row");
oModel1.setData({modelData : aData});
weatherTable.setModel(oModel1);
weatherTable.bindAggregation("rows","/modelData");
weatherTable.placeAt('content');
var dataLayout = new sap.ui.layout.HorizontalLayout({
id : "dataLayout", // sap.ui.core.ID
});
var Tablename = new sap.ui.commons.TextView({
id : "Tablename",
text : '{TableName}'
})
dataLayout.addContent(Tablename);
dataLayout.placeAt("content");
}
});
</script>
</head>
<body class='sapUiBody'>
<div id='content'></div>
</body>
</html>

Knockout.js Update ViewModel on button click

Well, that's not the best situation description... Anyway, I'm trying to update my ViewModel but it's not working. By default I'm getting data from controller function and by button click - from another function in same contoller, but ViewModel contain only data received after first ViewModel initialization.
<script>
function viewModel () {
var self = this;
self.currentPage = ko.observable();
self.pageSize = ko.observable(10);
self.currentPageIndex = ko.observable(0);
self.salesdata = ko.observableArray();
self.newdata = ko.observable();
self.currentPage = ko.computed(function () {
var pagesize = parseInt(self.pageSize(), 10),
startIndex = pagesize * self.currentPageIndex(),
endIndex = startIndex + pagesize;
return self.salesdata.slice(startIndex, endIndex);
});
self.nextPage = function () {
if (((self.currentPageIndex() + 1) * self.pageSize()) < self.salesdata().length) {
self.currentPageIndex(self.currentPageIndex() + 1);
}
else {
self.currentPageIndex(0);
}
}
self.previousPage = function () {
if (self.currentPageIndex() > 0) {
self.currentPageIndex(self.currentPageIndex() - 1);
}
else {
self.currentPageIndex((Math.ceil(self.salesdata().length / self.pageSize())) - 1);
}
}
//Here I'm trying to update ViewModel
self.request = function (uri) {
$.ajax({
url: uri,
contentType: 'application/json',
data: [],
type: 'GET',
cache: false,
success: function (data) {
ko.mapping.fromJS(data.$values, {}, self.salesdata);
}
});
}
}
$(document).ready(function () {
$.ajax({
url: "/api/sales",
type: "GET",
cache: false,
}).done(function (data) {
var vm = new viewModel();
vm.salesdata(data.$values);
ko.applyBindings(vm);
}).error(function (xhr, status, error) {
var err = eval("(" + xhr.responseText + ")");
alert(err.Message);
});
//Here i'm calling for ViewModel update
$(".btn-default").click(function () {
days = $(this).val();
var uri = "/api/sales?days=" + days;
new viewModel().request(uri);
});
});
</script>
UPDATE.
I chaged block of code where I'm getting new data to be as follow:
self.request = function (uri) {
$.getJSON(uri, function (data) {
ko.mapping.fromJS(data.$values, {}, viewModel);
});
}
Unfortunately this is not working as well. Here is no any JS errors, controller return proper portion of updated data.
I'm new to all of this, but if I'm reading your code correctly, you are calling the request function on a new instance of the view model and not the one that was bound to the html document. You need to make the request call on the view model that you created after the initial get call completed.
Update:
Sorry, I should have been more specific about the code I was referring to. At the end of your code block you have the following code:
$(".btn-default").click(function () {
days = $(this).val();
var uri = "/api/sales?days=" + days;
new viewModel().request(uri);
});
In this code, it appears that each time the default button is clicked, a new view model is created and the request function is called on that view model.
In the document ready function where you are defining what happens after the sales data is loaded, you have the following code which is what creates the view model that the html document is actually bound to:
var vm = new viewModel();
vm.salesdata(data.$values);
ko.applyBindings(vm);
Nothing ever calls the request function on this view model. I wonder if what you really want is to somehow bind the request function in this view model to the default button.
I would try updating the viewmodel salesdata observable, by giving context: self and using the following success method:
self.request = function (uri) {
$.ajax({
url: uri,
contentType: 'application/json',
context: self,
data: [],
type: 'GET',
cache: false,
success: function (data) {
this.salesdata(data.$values);
}
});
}
EDIT:
I can see you attached a click event with jQuery.
You should use knockout clck binding instead:
<button data-bind="click: clickEvent" value="1">Click me!</button>
And in the viewmodel
clickEvent: function (data, event) {
days = event.target.value;
var uri = "/api/sales?days=" + days;
data.request(uri);
}
This way you can retrieve your viewmodel instead of creating a new one as you did with new viewModel().request(uri);
For more on click binding see http://knockoutjs.com/documentation/click-binding.html
Building slightly on the answer from #brader24 here:
In your update button's click event, you use this line of code:
new viewModel().request(uri);
What that is doing is creating a new viewModel (separate from the one that you already have instantiated and have applied bindings for) and filling it's observable array with data via your request function. It isn't affecting your original viewModel at all (the one that has it's bindings applied on the DOM!). So you won't see any errors, but you also won't see anything happening on the page because all you did was create a new viewModel in memory, fill it with data, and do nothing with it.
Try this code (everything in your viewModel function looks fine).
$(document).ready(function () {
var vm = new viewModel(); // declare (and instantiate) your view model variable outside the context of the $.ajax call so that we have access to it in the click binding
$.ajax({
url: "/api/sales",
type: "GET",
cache: false,
}).done(function (data) {
vm.salesdata(data.$values);
ko.applyBindings(vm);
}).error(function (xhr, status, error) {
var err = eval("(" + xhr.responseText + ")");
alert(err.Message);
});
//Here i'm calling for ViewModel update
$(".btn-default").click(function () {
days = $(this).val();
var uri = "/api/sales?days=" + days;
vm.request(uri); // don't use a new instance of a view model - use the one you have already instantiated
});
});
Using a Knockout click binding instead of attaching a click event handler using jQuery is usually the recommended route, but it is not necessary - so your existing code (with the modifications above) should work fine. For more info on that, see Using unobtrusive event handlers in the Knockout docs
Well. Final solution based on #GoTo answer is:
Here is the way to call function in viewmodel via click databind.
<button type="button" class="btn btn-default" id="7" value="7" data-bind="click: getDays.bind($data, '7')">7</button>
Here is the function. As you can see I'm calling self.salesdata instead of viewModel. This solution is working fine but somehow now I have problem with data format that is binded this way -
<td data-bind="text: moment($data.whensold).format('DD.MM', 'ru')"></td>.
self.getDays = function (days) {
var uri = "/api/sales?days=" + days;
$.getJSON(uri, function (data) {
ko.mapping.fromJS(data.$values, {}, self.salesdata);
});
}

How can I trigger a Dojo xhrGet by clicking instead of on page load?

New to Dojo Toolkit, I'm able to successfully get an xhrGet to load on page load but I need to load the xhrGet when a row of a DataGrid is selected. Is there even a way to do so?
<!doctype html>
<html>
<head>
<script type="text/javascript>
dojo.connect(btn, "onclick", function() {
/************************/
/* xhr - AJAX functions */
/************************/
dojo.ready(function(){
var targetNode = dojo.byId("xhr-container");
var xhrArgs = {
url: "info-to-get.html",
handleAs: "text",
load: function(data){
targetNode.innerHTML = data;
},
error: function(error){
targetNode.innerHTML = "You messed up, dummy!: " + error;
}
}
var deferred = dojo.xhrGet(xhrArgs);
});
});
</script>
</head>
<body>
<button type="button" id="btn">TEST</button>
<br>
<br>
<div id="xhr-container"></div>
</body>
</html>
The xhrGet works fine by itself on page load, no dice when trying to call it through a button.
This will wire up the click of an html domNode to firing a function where you can put your xhr code.
dojo.connect(someDomNode, 'onclick', function() {
//xhr code here
});
If it is a widget, like dijit.form.Button you can write
dojo.connect(someWidget, 'onClick', function() {
//xhr code here
});
--EDIT ----------------------
Based on your posted code, I would expect the following to work:
dojo.ready(function(){
var targetNode = dojo.byId("xhr-container");
var fnDoXHR = function() {
var xhrArgs = {
url: "info-to-get.html",
handleAs: "text",
load: function(data){
targetNode.innerHTML = data;
},
error: function(error){
targetNode.innerHTML = "You messed up, dummy!: " + error;
}
};
var deferred = dojo.xhrGet(xhrArgs);
};
dojo.connect(dojo.byId('btn'), 'onclick', fnDoXHR);
});

Passing dynamic JSON data to create a HTML table

I have a function that receives JSON data, it can be any length and contain any number of columns and rows of data.
I have read that jqGrid would be a good jQuery plugin to use for this scenario but I cannot get it to work.
I have the following code to try and get my table to be populated:
//This code is in another section of my web page but the data is valid
//and is populated over a websocket
var ss = $.parseJSON(data);
var theGrid = jQuery("#list1")[0];
theGrid.addJSONData(ss.NewDataSet.SECURITY_GROUPS);
//alert(ss.NewDataSet.SECURITY_GROUPS[0].NAME);
$(document).ready(function() {
jQuery("#list1").jqGrid({
datatype: "local",
height: 250,
multiselect: true,
caption: "Manipulating Array Data"
});
});
<table id="list1"></table>
Maybe give DataTables a try if jqGrid isn't working for you. It's probably my favorite, and super easy to load via JSON as you've described.
Here's how to load from an AJAX source: http://datatables.net/release-datatables/examples/data_sources/ajax.html
$(document).ready(function() {
$('#example').dataTable( {
"bProcessing": true,
"sAjaxSource": '../ajax/sources/arrays.txt'
});
});
UPDATE
var columnArr = [];
var valueArr = [];
var data = ss.NewDataSet.SECURITY_GROUPS; //data is your SECURITY_GROUPS object
//Strip the titles off your first array item only since they are all the same.
$.each(data[0], function(key, value) {
columnArr.push({"sTitle" : key});
});
$.each(data, function(key, value) {
var innerArr = [];
$.each(value, function(innerKey, innerValue) {
innerArr.push(innerValue);
});
valueArr.push(innerArr);
});
$('#example').dataTable( {
"aaData": valueArr,
"aoColumns": columnArr
});

Categories

Resources