Add different controls in different rows in UI5 table - javascript

I have table sap.ui.table.Table ans I have a model in which some records have links and some doesn't. I want to render the link in the sap.m.Link component in the column and when the link is not available in the record, it should render "Link is not provided." in the sap.m.Text in the column.
As the sap.ui.table.Column has the template aggregation which does not support binding aggregation as it is only 0 or 1 controls supported. And the formatter is also applicable here. Is there any way that the content of the column can be changed runtime according to the module data?
My module data is :
var data = [{
id : 1,
link : 'abc.com'
},
{
id : 2
},
{
id : 3,
link : 'pqr.com'
}]
I am providing the code:
var link = new sap.m.Link({text : "{link}"});
var noLink = new sap.m.Text({text : "Link is not provided."});
var idColumn = new sap.ui.table.Column({
label : [new sap.m.Label({text : "ID"})],
template : [new sap.m.Text({text : "{id}"})]
});
var linkColumn = new sap.ui.table.Column({
label : [new sap.m.Label({text : "Link"})],
template : [??????]
});
var table = new sap.ui.table.Table({
columns : [idColumn, linkColumn]
});
var model = new sap.ui.model.json.JSONModel();
model.setData({items : data});
table.setModel(model);
table.bindRows("/items");
I want to add the link and noLink in the column likColumn runtime according to the data in the module. How can I achieve this?

The display content of each column can be changed using formatter
e.g:
new sap.m.Link({
width: "20em",
//editable: false,
//text: "{items>link}"
text: {
path: "items>link",
formatter: function(link){
if (link === undefined) return "Link is not provided"
return link;
}
}
});
...
oTable.addEventDelegate({
onAfterRendering: function(){
$('#idTable a:contains("Link is not provided")').removeClass("sapMLnk");
}
}, oTable);
UPDATE: This is a jsbin with the full example of what you need:
UPDATED example

Related

jQgrid colum filtering is not working in single column

jQgrid table is workin fine. In the last line I've enabled column filtering. Search/Filtering in other column is working fine. But not working on the the Status column that has been generated from formatter
$('#jqGrid').jqGrid({
datatype: "local",
data : res.data,
colModel: [
{
label : 'Batch No.', name:'batch_no', firstsortorder:'asc'
},
{
label : 'Batch Wt.', name:'expected_batch_wt', formatter:'number', align:'right'
}
,
// ...
// ...
{
label : 'Status'
,formatter:function (cellvalue, options, rowObject){
if(condition)
status = 'MSG 1';
else if(condition)
status = 'MSG 2';
else
status = 'DEF MSG';
return status;
}
,align : 'center'
// ,sortable : false
}
],
rowNum : 1000,
rownumbers : true,
pager : '#jqGridPager',
caption : `CURRENT STOCK REPORT`,
height : '500px',
width : '1500',
footerrow : true,
userDataOnFooter : true,
gridComplete : function(){
var $grid = $('#jqGrid'),
sum_batch_count = $grid.jqGrid('getCol', 'batch_no', false, 'count'),
sum_batch_wt = $grid.jqGrid('getCol', 'expected_batch_wt', false, 'sum');
$grid.jqGrid('footerData', 'set', {
'batch_no' : sum_batch_count,
'expected_batch_wt' : sum_batch_wt
});
}
});
jQuery("#jqGrid").jqGrid('filterToolbar', { stringResult: true, searchOnEnter: false, defaultSearch: "cn" });
In your case datatype is local and the formatter shows certain value depending on condition. This value is not connected with your actual local data. When a datatype is local the search is performed within local data array - in your case this is: res.data. Since this data does not contain your new constructed values, the search return nothing.
To solve the problem one possible solution is to use unformatter function.
Depending on the jqGrid version used (Guriddo jqGrid, free-jqGrtid, jqGrid <= 4.7) you have diffrent options, but is needed to know the version. I recommend you too to search this site for solving the problem you have.

sapui5 JS in controller table is not binding

Im trying to create search help using Odata service but my table is showing as undefined in controller, here is my code plz help
index.html
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta charset="UTF-8">
<title>search_help</title>
<script id="sap-ui-bootstrap"
src="../../resources/sap-ui-core.js"
data-sap-ui-libs="sap.m,sap.ui.commons,sap.ui.table,sap.ui.ux3"
data-sap-ui-theme="sap_belize"
data-sap-ui-compatVersion="edge"
data-sap-ui-resourceroots='{"search_help": ""}'>
</script>
<link rel="stylesheet" type="text/css" href="css/style.css">
<script>
sap.ui.getCore().attachInit(function() {
new sap.m.Shell({
app: new sap.ui.core.ComponentContainer({
height : "100%",
name : "search_help"
})
}).placeAt("content");
});
</script>
</head>
<body class="sapUiBody" id="content">
</body>
view1.view.js
sap.ui.jsview("search_help.view.View1", {
getControllerName: function() {
return "search_help.controller.View1";
},
createContent : function(oController) {
var oPanel = new sap.ui.commons.Panel({
text : "Select Order ID"
});
var oLayoutMatrix = new sap.ui.commons.layout.MatrixLayout({
width : "60%",
widths : [ "30%", "40%", "30%" ]
});
var oOrderLabel = new sap.ui.commons.Label("idOrderLabel",
{text: "Order ID"});
// Input Field for Material Number with Value Help
var oOrderInput = new sap.ui.commons.ValueHelpField("idOrderInput", {
valueHelpRequest: function(oEvent){
var oValueHelpDialog = new sap.ui.ux3.ToolPopup({
modal: true,
inverted: false,
title: "Select Order Number",
opener: "idOrderInput",
closed: function (oEvent){
}
});
var oOkButton = new sap.ui.commons.Button({
text: "OK",
press: function (oEvent) {
oEvent.getSource().getParent().close();
}
});
var oHelpTable = new sap.ui.table.Table("pTab1",{
selectionMode: sap.ui.table.SelectionMode.Single,
visibleRowCount: 7,
width: "300pt"
});
oHelpTable.addColumn(
new sap.ui.table.Column({
label: new sap.ui.commons.Label({text: "Maintenance Plane"}),
template: new sap.ui.commons.TextField().bindProperty("value", "Planplant"),
sortProperty: "Planplant",
filterProperty: "Planplant"
})
);
oHelpTable.addColumn(
new sap.ui.table.Column({
label: new sap.ui.commons.Label({text: "Order Number"}),
template: new sap.ui.commons.TextField().bindProperty("value", "Orderid"),
sortProperty: "Orderid",
filterProperty: "Orderid"
})
);
oHelpTable.addColumn(
new sap.ui.table.Column({
label: new sap.ui.commons.Label({text: "OrderType"}),
template: new sap.ui.commons.TextField().bindProperty("value", "OrderType"),
sortProperty: "OrderType",
filterProperty: "OrderType"
})
);
oValueHelpDialog.addContent(oHelpTable);
oValueHelpDialog.addButton(oOkButton);
oValueHelpDialog.open();
}
});
oLayoutMatrix.createRow(oOrderLabel, oOrderInput);
oPanel.addContent(oLayoutMatrix);
return oPanel;
}
});
view1.controller.js
here otable is showing as undefined
sap.ui.define([
"sap/ui/core/mvc/Controller"], function(Controller) {
"use strict";
return Controller.extend("search_help.controller.View1", {
onInit: function()
{
var oModel = new sap.ui.model.odata.ODataModel("/Gateway_Order/sap/opu/odata/SAP/ZP01_FIORI_SRV_01/");
var oTable = this.byId("pTab1");
oTable.setModel(oModel);
oTable.bindRows("/OrderDataSet");
}
});
});
Your problem is how you are fetching the Id of your table.
Solution to your problem is :
var oTable = sap.ui.getCore().byId("pTab1");
However, let us understand the Id creation and fetching.
In JS Views, there are two ways to create Ids.
Way 1: : Provide direct Id. Eg:
var oText = new sap.m.Text('idText'{ text:'Hey!'});
Now, this id -'idText' is associated with your entire application. So, if you have another view, which has a control with same id, you will see duplicate id error in console.
To fetch controls with ids creating with Way1, use the below method:
var oControl = sap.ui.getCore().byId('idText'); // since this is unique everywhere in your application.
Now, let us think 2 or more developers are working in an application and they are creating different views for the application. They may ( with high possibility), create controls with same id. The application will crash when we integrate both views due to duplicate id error. How to solve this?
Way 2: We can use the method createId() of the controller to create a Id for prefixed with view's id. So, this way even if two developers are using the same id, they will end up with different id for controls due to different view Id.
So, let us think we have two views, View1 ( id: view1) and view2 ( id:view2).
If I create a control with same Id in both the controls (using createId() method of controller), two unique id will be generated and duplicate id error will never be raise.
So, View 1( id: view1):
var oText = new sap.m.Text(oController.createId('idText'),{ text:'Hey!'});
Id of oText in view 1 : view1--idText
Similarly,
View 2( id: view2):
var oText = new sap.m.Text(oController.createId('idText'),{ text:'Hey!'});
Id of oText in view 2 : view2--idText
Nicely done. But what if Id of view is auto generated and I might not know what is my view Id? Good question.
Solution is the method : this.byId(). In the cases, where id of controls are prefixed with view's id, always use the method this.byId(). It will append the view's id for you and then search and return the control unique to that view.
So, to fetch oText of View1, you will use (in View1's controller);
var oText = this.byId('idText')// will fetch view1--idText
Again to fetch oText of View2, you will use (in View2's controller);
var oText = this.byId('idText')// will fetch view2--idText
IN XML Views, Id of controls are always prefixed with view's id by framework automatically. This is similar to our Way 2 of JS. ( Way 1 of JS is never possible in XML Views).
View code:
<Text id='idText' text='hey! /> <!-- Id generated is: 'viewid--idText' -->
Hence, when you use XML views, fetching of ID is always done by:
var oControl = this.byId('idText');
I got the output list from odata service to the valuehelprequest table but not able to filter the data.
sap.ui.define([
"sap/ui/core/mvc/Controller
], function(Controller) {
"use strict";
return Controller.extend("Xml_Search.controller.View1", {
handlef4: function(){
var oInput= this.getView().byId("Orderid");
if(!this._oValueHelpDialog){
this._oValueHelpDialog= new sap.ui.comp.valuehelpdialog.ValueHelpDialog("idValueHelp",{
// supportRanges: true,
key: "Orderid",
descriptionKey: "OrderType",
ok: function(oEvent){
var aTokens= oEvent.getParameter("tokens");
oInput.setTokens(aTokens);
this.close();
},
cancel: function(){
this.close();
}
});
}
var oColModel = new sap.ui.model.json.JSONModel();
oColModel.setData({
cols: [
{label: "Orderid", template: "Orderid"},
{label: "OrderType", template: "OrderType"},
{label: "Planplant", template: "Planplant"}
]
});
var oTable = this._oValueHelpDialog.getTable();
oTable.setModel(oColModel,"columns");
var oModel = new sap.ui.model.odata.ODataModel("/Gateway_Order/sap/opu/odata/SAP/ZP01_FIORI_SRV_01/");
oTable.setModel(oModel);
oTable.bindRows({path: "/OrderDataSet", filters: [new
sap.ui.model.Filter("Orderid",sap.ui.model.FilterOperator.EQ,null, oInput)]}
);
this._oValueHelpDialog.open();
}
});
});

Backbone rendering collection in other collection element

I have a structure that I need to render. It has linear type:
{districts : [
{
name : "D17043"
},
{
name : "D91832"
},
{
name : "D32435"
}
],
buildings : [
{
name : "B14745",
district: "D17043",
address: "1st str"
},
{
name : "B14746",
district : "D91832",
address : "1st str"
},
{
name : "B14747",
district : "D17043",
address : "1st str"
}
]
}
It is simplified to look a bit better. Districts have buildings attached to them. Possibly, the structure could be nested, but I thought that it would make additional troubles, and, as this "tree" is not structured I made simple object.
The question is - how it can be properly displayed with backbone?
Right now it looks something like this (some details are left behind the scenes):
App.Collections.Districts = Backbone.Collection.extend({
model : App.Models.District
});
var districtsCollection = new App.Collections.Districts(data.districts);
var districtsView = new App.Views.Districts({collection : districtsCollection});
then somewhere in district collection view we create a loop that make views of a single district:
var districtView = new App.Views.District({model : district});
and inside view of a single district i call another collection in render method:
App.Views.District = Backbone.View.extend({
tagName : 'div',
className : 'districtListElement',
render : function () {
this.$el.html(this.model.get('name'));
var buildingsCollection = new App.Collections.Buildings(allData.buildings);
buildingsCollection.each(function(item){
if (item.get('district') == this.model.get('name')) {
var buildingView = new App.Views.Building({model : item});
this.$el.append(buildingView.render().el);
}
}, this);
return this;
}
});
This thing works but isn't it a bit creepy? Maybe there is a proper way to do it? Especially if I have other instances to be inside buildings.
Thank you.

How to include HTML code within prime ui or jquery datatable "columns" option's headerText?

I am trying to apply internationalization to my web app that uses JSP pages.I found this link How to internationalize a Java web application? and it really helped me.
However I am now trying to use the given tag fmt:message tag within my primeui datatable's headerText so that I can see column name of my datatable in spanish language.But it's being displayed as text on the screen.Whereas I want it to function as it does on my JSP page i.e to pick user.data.userName="spanish translation for username" from my properties file text_es.properties.
Below is the code for my datatable which is included in script tag on my JSP:
$(function() {
$('#tbllocal').puidatatable({
caption : 'Inbox Tasks',
paginator : {
rows : 5
},
columns : [
{
field : 'userName',
**headerText : '<fmt:message key='user.data.userName'/>',**
sortable : true
},{
field : 'userEmailId',
headerText : 'userEmailId',
sortable : true
} ],
datasource : function(callback) {
$.ajax({
type : "GET",
url : 'crud',
dataType : "json",
context : this,
success : function(response) {
callback.call(this, response);
}
});
},
selectionMode : 'single',
rowSelect : function(event, data) {
$('#messages').puigrowl('show', [ {
severity : 'info',
summary : 'Row Selected',
detail : (data.firstName + ': ' + data.lastName)
} ]);
},
rowUnselect : function(event, data) {
$('#messages').puigrowl('show', [ {
severity : 'info',
summary : 'Row Unselected',
detail : (data.firstName + ': ' + data.lastName)
} ]);
},
jsonReader : {
response : "response"
}
});
});
Still there is no support for including html in datatable header till primeui 2.0 i have also posted this question on frimeui forum please refer following link for further details
http://forum.primefaces.org/viewtopic.php?f=16&t=42417

Unable to parse json data and keep it in grid using dojo

I got the json object data from servlet as this:
{"persondetails":[{"salary":"20000","sname":"XXX","sno":"1"},
{"salary":"50000","sname":"yyy","sno":"2"},
{"salary":"20300","sname":"bbb","sno":"3"},
{"salary":"20100","sname":"chan","sno":"4"},
{"salary":"40100","sname":"lorn","sno":"5"},
{"salary":"10100","sname":"san","sno":"6"},
{"salary":"60100","sname":"sun","sno":"7"},
{"salary":"20200","sname":"chan","sno":"8"},
{"salary":"10200","sname":"san","sno":"9"},
{"salary":"40200","sname":"lorn","sno":"10"}]}
Now, I have to put this in datagrid using dojo. I tried but I'm getting a blank page. Please check this and help me understand what I did wrong.
Here's my code:
var grid, dataStore, store;
require([ "dojox/grid/DataGrid", "dojo/store/Memory",
"dojo/data/ObjectStore", "dojo/request/xhr", "dojo/dom",
"dojo/dom-construct", "dojo/json", "dojo/on", "dojo/domReady!" ],
function(DataGrid, Memory, ObjectStore,xhr, dom, domConst, JSON, on) {
xhr("myserveraddress:7080/GridExample/login", {
handleAs : "json"
}).then(
function(data) {
domConst.place("<p>response: <code>"
+ JSON.stringify(data) + "</code></p>",
"output");
store = new Memory({
data : data.items
});
dataStore = new ObjectStore({
objectStore : store
});
grid = new DataGrid({
store : dataStore,
query : {
id : "*"
},
structure : [ {
name : "SNO",
field : "sno",
width : "100px"
},{
name : "SNAME",
field : "sname",
width : "100px"
},{
name : "SALARY",
field : "salary",
width : "200px"
} ]
}, "grid");
grid.placeAt("myGrid");
grid.startup();
}, function(err) {
alert("error");
}, function(evt) {
});
});
You need to give the grid the array inside persondetails.
So your store should be something like::
data.items.persondetails
Also in your grid you dont need the query parameter, unless you want a certain row like
sno:"9"
will only show rows with sno = 9
fiddle::http://jsfiddle.net/theinnkeeper/57pZf/

Categories

Resources