How to display JSONModel data using "sap.ui.table.DataTable"? - sapui5

I'm trying to bring data from an internal table in a ABAP program into an SAPUI5 application.
From the ABAP side, I have converted the required data into JSON format and sending it across like it is mentioned in the a guide.
I have written the following code in the 'Read' section of the controller
$.ajax({
type: 'GET',
url: 'http://socw3s1er67.solutions.glbsnet.com:8000/sap/bc/Z_tets_json?sap-client=950',
success: function(data) {
alert(data[1].PROJECT);
alert(data[0].MANDT);
var oModel_Projects = new sap.ui.model.json.JSONModel();
oModel_Projects.setData({ modelData: data });
}
});
Sample JSON response from the server:
[
{
"MANDT": "PJ1",
"PROJECT": "Test Project1",
"DESCRIPTION": ""
},
{
"MANDT": "PJ2",
"PROJECT": "Test Project2",
"DESCRIPTION": ""
}
]
The alerts seem to be working fine and are returning expected data from the internal tables.
I want to know: how to bind this data into a particular table using models?

Well, your code looks ok, but there are other parts, which are missing, and there might be a problem there...
How is your table constructed - ?
It should be:
var table = new sap.ui.table.DataTable({
title: 'My first table',
width: '100%'
});
Do you make following calls to connect table and model?
table.setModel(oModel_Projects);
table.bindRows("modelData");
Are you properly creating columns of the table?
label = new sap.ui.commons.Label({ text: 'Client' });
template = new sap.ui.commons.TextView({ text: '{MANDT}' });
col = new sap.ui.table.Column({ label: label, template: template });
table.addColumn(col);
Is table properly placed into HTML using placeAt method?

Updated the answer after your clarification:
Try this parser:
var html = "<table><tr><td>MANDT</td><td>PROJECT</td><td>DESCRIPTION</td></tr>";
for(var index in data){
html+="<tr><td>"+data[index].MANDT+"</td><td>"+data[index].PROJECT+" </td><td>"+data[index].DESCRIPTION+"</td></tr>";
}
html+="</table>";
//now you can insert this html into some div like as follows: $("#div1").html(html);
Or google for some jquery gridview as I suggested in the comment.

Related

How to bind a form in SAPUI5?

I was trying to figure out how to bind a simple form in UI5 (not a list) so I can submit to my oData backend . How do I do that with a simple form?
Here is my controller code (if I were to do in a List) - But I have no clue how to deal with a Form:
var oList = this.byId("addapp"),
oBinding = oList.getBinding("items"),
// Create a new entry through the table's list binding
oContext = oBinding.create({
"application_id": 0,
"product_name_short": 'Test',
});
This is what I have tried so far, but I got undefined value:
var x =this.getView().byId("addapp").getBinding("items");
If you have set a model to your view, you can bind an existing object to a view using Element.bindElement:
this.getView().byId("addapp").bindElement("/path/to/your/object");
If you want to use a temporary model (to use the data once you click "add" or something similar):
onInit: function () {
// Initial values of the form
this.getView().setModel(new sap.ui.model.json.JSONModel({
property1: "",
property2: "",
property3: ""
}), "newEntry");
// Bind the form to the json model
this.getView().byId("addapp").bindElement("newEntry>/");
},
onAddButtonClick: function() {
// Get the form values
var newEntry = this.getView().getModel("newEntry").getData();
// Use the OData model to create a new entity
var oDataModel = ...;
oDataModel.create("/path/to/your/entityset", newEntry, {
success: function() {
// entity was created
}
});
}

Meteor prefill a collection

I have made the following collection in meteor:
CodesData = new Mongo.Collection('CodesData');
CodesDataSchema = new SimpleSchema({
code: {
label: "Code",
type: Number
},
desc: {
label: "Description",
type: String,
}
});
CodesData.attachSchema(CodesDataSchema);
Now I want to prefill this collection with some data.
For example: code: 1 desc: "hello".
How can I do this manually and easily?
You can use Meteor.startup to run some actions on your collection once the server app has been loaded and is starting:
CodesData = new Mongo.Collection('CodesData');
CodesDataSchema = new SimpleSchema({ code: { label: "Code", type: Number }, desc: { label: "Description", type: String, } });
.attachSchema(CodesDataSchema);
Meteor.startup(()=>{
// Only fill if empty, otherwise
// It would fill on each startup
if (CodesData.find().count() === 0) {
CodesData.insert({ code: 1, description: 'some description' });
}
});
If you have a lot of data to prefill you can define it in a JSON and load it on startup:
Consider the following json named as pre:
{
codesdata: [
{ code: 1, description: 'foo' },
{ code: 7, description: 'bar' }
]
}
Meteor.startup(()=>{
const preData = JSON.parse( pre );
preData.codesData.forEach( entry => {
CodesData.insert( entry );
});
});
This allows you to manage your prefill more easily and also let's you version control the json if desired ( and no sensitive data is revealed ).
Considerations:
The function Meteor.startup runs on each start. So you should consider how to avoid unnecessary inserts / prefill that create doubles. A good way is to check if the collection is empty (see first example).
You may put the startup code an another js file in order to separate definitions from startup routines.
The current script does not differentiate between server or client. You should consider to do this on server and create a publication / subscription around it.
More readings:
https://docs.meteor.com/api/core.html#Meteor-startup
Importing a JSON file in Meteor
https://docs.meteor.com/api/core.html#Meteor-settings

X Ray Scraper: Manipulate data before .write

I'm fiddling around with some scraping, and need to manipulate some of the data before writing it to my json file.
var Xray = require('x-ray');
var x = Xray();
x('http://myUrl.com', '#search_results div div a', [{
title: '.responsive_search_name_combined .search_name .title',
price: '.col.search_price.responsive_secondrow',
}])
.paginate('.search_pagination_right a.pagebtn:last-child#href')
.limit(10)
.write('data.json');
When saved, price looks like this: "price": "\r\n\t\t\t\t\t\t\t\t13,99€\t\t\t\t\t\t\t".
I guess its because theres a lot of spaces in div.col.search_price.responsive_secondrow.
<div class="col search_price responsive_secondrow">
9,99€ </div>
So my question is: Would it be possible to manipulate the data before .write?
Yes, you can simply provide a callback function that takes an object which is the result of your scrape. In this function you can take full control of any post-processing you want to do.
So your code would end up something like:
x('http://myUrl.com', '#search_results div div a', [{
title: '.responsive_search_name_combined .search_name .title',
price: '.col.search_price.responsive_secondrow',
}])
(function(products){
var cleanedProducts = [];
products.forEach(function(product){
var cleanedProduct = {};
cleanedProduct.price = product.price.trim();
//etc
cleanedProducts.push(cleanedProduct)
});
//write out results.json 'manually'
fs.writeFile('results.json', JSON.stringify(cleanedProducts));
})
You could use X-Ray native supported approach which is called filter functions and completely covers the case you described.
filters are custom defined functions allowing you to implement custom logic while processing scraped data.
See code sample below. There's a custom defined filter function with name of cleanUpText and apply it to scraped data price.
var Xray = require('x-ray');
var x = Xray({
filters: {
cleanUpText: function (value) { return value.replace('\r\n\t\t\t\t\t\t\t\t', '').replace('\t\t\t\t\t\t\t', ''); },
}
});
x('http://store.steampowered.com/search/?filter=topsellers', '#search_results div div a', [{
title: '.responsive_search_name_combined .search_name .title ',
price: '.col.search_price.responsive_secondrow | cleanUpText', // calling filter function 'cleanUpText'
}])
.paginate('.search_pagination_right a.pagebtn:last-child#href')
.limit(10)
.write('data.json');
data.json looks like below:
{"title": "PLAYERUNKNOWN'S BATTLEGROUNDS",
"price": "$29.99"},
{"title": "PAYDAY 2: Ultimate Edition",
"price": "$44.98"}

Populating Combobox in a Table Column

I have tied an ODataModel with a table. In the table one of the columns is dropdown list. The list has some 3 values. It's slightly confusing for me but how to go with such scenario? Do I have to tie another model consisting of the values I want in the dropdown and then have it's property bound to the response coming from the ODataModel which is tied to the table?
Is the following thing correct? but it may not be good if I have more values to be there in the dropdown and morever.... how to proceed if I want to bind this "key" mentioned below with "Status" in the ODataModel? Here I have tied the "value" property of combobox to the "StatusText" coming from ODataModel.
But I want to tie the "key" property of ListItem with "Status" from ODataModel(which is tied with the table) response
oTable.addColumn(
new sap.ui.commons.ComboBox({
items: [
new sap.ui.core.ListItem({text: "New",key:"1"}).bindProperty("text","StatusText").bindProperty("key","Status"),
new sap.ui.core.ListItem({text: "In Process",key:"2"}),
new sap.ui.core.ListItem({text: "Completed",key:"3"})
]
}).bindProperty("value","StatusText")
);
Any Help would be appreciated.
Thanks
This works in the table, but I think your Combobox still has some error with the bindings.
var oCombobox = new sap.ui.commons.ComboBox({
items: [
new sap.ui.core.ListItem({text: "New",key:"1"}).bindProperty("text","StatusText").bindProperty("key","Status"),
new sap.ui.core.ListItem({text: "In Process",key:"2"}),
new sap.ui.core.ListItem({text: "Completed",key:"3"})
]
}).bindProperty("value","StatusText");
oTable.addColumn(new sap.ui.table.Column({
template : oCombobox,
visible : true,
}));
Lets say you have a oData field called {Firstname}, defined in your result type (table) e.g. for this table, then you bind it in the table as:
oTable.addColumn(new sap.ui.table.Column({
template : new sap.ui.commons.TextView({
text : "{Firstname}",
textAlign : sap.ui.core.TextAlign.Center
}),
visible : true,
}));
As far as I understand, you want to get the possible values out of your oData Service, but I think this is not possible in case of an dropdown / combobox because you get a table from your backend, each line has a value in one field -> how would your bind 3 values in one single table field?
I realised dropdowns in an own service, calling the dropdown values from the backend separately:
getDropdown : function() {
// Create JSON data model
var oModel = new sap.ui.model.json.JSONModel();
oModel.loadData("/sap/opu/odata/sap/YOUR_SERVICE/YourEntitySet");
sap.ui.getCore().setModel(oModel);
// Create a DropdownBox
var oDropdown = new sap.ui.commons.DropdownBox("DropdownBox", {
text: "{Firstname}",
});
oDropdown.setModel(oModel);
var oItemTemplate1 = new sap.ui.core.ListItem({
text : "{Firstname}",
});
oDropdown.bindItems("/d/results", oItemTemplate1);
// "/d/results" may vary depending on your path
// return the box
return oDropdown;
},
you can use the returning result in your table.
e.g. in view:
var dropdown = oController.getDropdown();
dropdown.placeAt("content");

JQGrid Dynamic Select Data

I have utilised the example code at Example Code at this link
and I have got my grid to show a dynamically constructed select dropdown on add and edit. However when it is just showing the data in the grid it shows the dropdown index instead of its associated data. Is there a way to get the grid to show the data associated with the index instead of the index itself.
e.g. the data on my select could be "0:Hello;1:World"; The drop down on the edit/add window is showing Hello and World and has the correct indexes for them. If the cell has a value of 1 I would expect it to show World in the grid itself but it is showing 1 instead.
Here is the row itself from my grid:
{ name: 'picklist', index: 'picklist', width: 80, sortable: true, editable: true,
edittype: "select", formatter: "select", editrules: { required: true} },
I am filling the dynamic data content in the loadComplete event as follows:
$('#mygrid').setColProp('picklist', { editoptions: { value: picklistdata} });
picklist data is a string of "0:Hello;1:World" type value pairs.
Please can anyone offer any help. I am fairly new to JQGrids so please could you also include examples.
I know you have already solved the problem but I faced the same problem in my project and would like to offer my solution.
First, I declare a custom formatter for my select column (in this case, the 'username' column).
$.extend($.fn.fmatter, {
selectuser: function(cellvalue, options, rowdata) {
var userdata;
$.ajax({
url:'dropdowns/json/user',
async:false,
dataType:'json',
cache:true,
success: function(data) {
userdata = data;
}
});
return typeof cellvalue != 'undefined' ? userdata[cellvalue] : cellvalue ;
}
});
This formatter loads up the mapping of id and user in this case, and returns the username for the particular cellvalue. Then, I set the formatter:'selectuser' option to the column's colModel, and it works.
Of course, this does one json request per row displayed in the grid. I solved this problem by setting 10 seconds of caching to the headers of my json responses, like so:
private function set_caching($seconds_to_cache = 10) {
$ts = gmdate("D, d M Y H:i:s", time() + $seconds_to_cache) . " GMT";
header("Expires: $ts");
header("Pragma: cache");
header("Cache-Control: max-age=$seconds_to_cache");
}
I know this solution is not perfect, but it was adequate for my application. Cache hits are served by the browser instantly and the grid flows smoothly. Ultimately, I hope the built-in select formatter will be fixed to work with json data.
If you save in jqGrid ids of the select elements and want to show the corresponding textes then you should use formatter:'select' in the colModel (see http://www.trirand.com/jqgridwiki/doku.php?id=wiki:predefined_formatter#formatter_type_select) together with the edittype: "select".
The Usage of stype: 'select' could be also interesting for you if you plan to support data searching.