I am new to sapui5, i am trying to make an app with two views.one view with multicomboBox and another with dynamic table , after selection of items from multicomboBox i have to click submit button. on submit button click i have to navigate to another view and create a table with column name, column name will be selected values of multicomboBox.
i am using target to navigate and used xml view.
The problem is i am getting the selected items, how to pass the selected data to another view and create the table is the issue i am facing.
i am posting the views and controllers below. The below code is taken from sapui5 Explored, i have combined multicomboBox and Target Program. Thanks in advance
View1.xml
<mvc:View
xmlns:mvc="sap.ui.core.mvc"
xmlns="sap.m"
xmlns:l="sap.ui.layout"
xmlns:html="http://www.w3.org/1999/xhtml"
controllerName="sap.ui.core.sample.trial.targetsApp.controller.View1"
xmlns:form="sap.ui.layout.form">
<App>
<Page title="Example 1">
<MultiComboBox selectionChange="handleSelectionChange" selectionFinish="handleSelectionFinish" width="500px"
items="{
path: '/Collection',
sorter: { path: 'Name' }
}">
<core:Item key="{ProductId}" text="{Name}" />
</MultiComboBox>
<footer>
<Bar>
<contentRight>
<Button text="Submit" press="onToView2" />
</contentRight>
</Bar>
</footer>
</Page>
</App>
</mvc:View>
View2.xml
<mvc:View
xmlns:mvc="sap.ui.core.mvc"
xmlns="sap.m"
xmlns:l="sap.ui.layout"
xmlns:html="http://www.w3.org/1999/xhtml"
controllerName="sap.ui.core.sample.trial.targetsApp.controller.View2"
xmlns:form="sap.ui.layout.form">
<App>
<Page title="TableView"
showNavButton="true"
navButtonPress="onBack">
<footer>
<Bar>
<contentRight>
<Button text="Submit" press="onToView2" />
</contentRight>
</Bar>
</footer>
</Page>
</App>
</mvc:View>
controller for view1
sap.ui.define([
'jquery.sap.global',
'sap/m/MessageToast',
'sap/ui/core/mvc/Controller',
'sap/ui/model/json/JSONModel'
], function(jQuery, MessageToast, Controller, JSONModel) {
"use strict";
var PageController = Controller.extend("sap.ui.core.sample.trial.targetsApp.controller.View1", {
onInit: function () {
// set explored app's demo model on this sample
var oModel = new JSONModel(jQuery.sap.getModulePath("sap.ui.demo.mock", "/products.json"));
this.getView().setModel(oModel);
},
onToView2 : function () {
this.getOwnerComponent().getTargets().display("page2");
},
handleSelectionChange: function(oEvent) {
var changedItem = oEvent.getParameter("changedItem");
var isSelected = oEvent.getParameter("selected");
var state = "Selected";
if (!isSelected) {
state = "Deselected"
}
MessageToast.show("Event 'selectionChange': " + state + " '" + changedItem.getText() + "'", {
width: "auto"
});
},
handleSelectionFinish: function(oEvent) {
var selectedItems = oEvent.getParameter("selectedItems");
var messageText = "Event 'selectionFinished': [";
for (var i = 0; i < selectedItems.length; i++) {
messageText += "'" + selectedItems[i].getText() + "'";
if (i != selectedItems.length-1) {
messageText += ",";
}
}
messageText += "]";
MessageToast.show(messageText, {
width: "auto"
});
},
handleNav: function(evt){
this.getOwnerComponent().getTargets().display("page2");
}
});
return PageController;
}, true);
controller for view2
sap.ui.define( ["sap/ui/core/mvc/Controller"], function (Controller) {
"use strict";
return Controller.extend("sap.ui.core.sample.trial.targetsApp.controller.View2", {
onBack : function () {
this.getOwnerComponent().getTargets().display("page1");
}
});
},true);
Edited controller2.js
sap.ui.define( ["sap/ui/core/mvc/Controller"], function (Controller) {
"use strict";
return Controller.extend("sap.ui.core.sample.trial.targetsApp.controller.View2", {
onInit:function(){
//console.log(sap.ui.getCore().AppContext.selectedArray);
//console.log(sap.ui.getCore().AppContext.selectedArray.length);
var oTable = new sap.m.Table();
for(var i = 0;i < sap.ui.getCore().AppContext.selectedArray.length;i++){
oTable.addColumn(new sap.m.Column({
demandPopin : true,
header:new sap.m.Text({text:sap.ui.getCore().AppContext.selectedArray[i]})
}));
}
//not working i want to place it in view2.xml
//oTable.placeAt("content");
},
displayPress : function(){
console.log(sap.ui.getCore().AppContext.selectedArray);
console.log(sap.ui.getCore().AppContext.selectedArray.length);
console.log(sap.ui.getCore().AppContext.selectedArray[0]);
console.log(sap.ui.getCore().AppContext.selectedArray[1]);
},
onBack : function () {
this.getOwnerComponent().getTargets().display("page1");
}
});
}, true);
edited view2.xml
<mvc:View
xmlns:mvc="sap.ui.core.mvc"
xmlns="sap.m"
xmlns:l="sap.ui.layout"
xmlns:html="http://www.w3.org/1999/xhtml"
controllerName="sap.ui.core.sample.trial.targetsApp.controller.View2"
xmlns:form="sap.ui.layout.form">
<App>
<Page title="TableView"
showNavButton="true"
navButtonPress="onBack">
<l:HorizontalLayout id="tableid">
</l:HorizontalLayout>
<footer>
<Bar>
<contentRight>
<Button text="Add New Rows" press="displayPress" />
<Button text="display" press="displayPress" />
</contentRight>
</Bar>
</footer>
</Page>
</App>
</mvc:View>
Use in handleNav function:
//yourData can be any variable or object
this.getOwnerComponent().getTargets().display("page2", yourData);
Read more here:
display(vTargets, vData?): sap.ui.core.routing.Targets
Related
I am an ABAP developer who is just trying to take the first steps in SAPUI5/Fiori.
So my very simple task is to create a fiori app with a single tile to show the number of EDIDC records.
View1.controller.js:
sap.ui.define([
"sap/ui/core/mvc/Controller"
], function (Controller) {
"use strict";
return Controller.extend("QuickStartApplication.controller.View1", {
onGetValue: function ( ) {
var oTileValue = this.getView().byId("tile1");
this.getModel().read("/EDIDCSet/$count", {
success: $.proxy(function (oEvent, oResponse) {
// var count = Number(oResponse.body);
var count = "1337";
oTileValue.setValue(count);
}, this)
});
}
});
});
View1.view.xml:
<mvc:View xmlns:html="http://www.w3.org/1999/xhtml" xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m"
controllerName="QuickStartApplication.controller.View1">
<App id="idAppControl">
<pages>
<Page xmlns="sap.m" id="pageId" title="TileTest" floatingFooter="true">
<content>
<Button xmlns="sap.m" text="Button" id="button0" press=".onGetValue"/>
<GenericTile class="sapUiTinyMarginBegin sapUiTinyMarginTop tileLayout" header="Country-Specific Profit Margin" subheader="Expenses"
press="press" id="tile1">
<TileContent unit="EUR" footer="Current Quarter">
<NumericContent scale="M" value="1000" valueColor="Error" indicator="Up" withMargin="false"/>
</TileContent>
</GenericTile>
</content>
</Page>
</pages>
</App>
</mvc:View>
As you can see, I can't even pass the value "1337" that I hardcoded.
My first mistake was to adress the tile and not the numeric content of the file. So first, I gave the ID to the numeric content:
<NumericContent scale="M" value="" valueColor="Error" indicator="Up" withMargin="false" id="num1"/>
Then, I've adjusted the line, to access the object:
var oTileValue = this.getView().byId("num1");
The last thing I learned was, that the model is connected to the view. So to access this, I changed the line to:
this.getView().getModel().read("/EDIDCSet/$count", {
Now I can call my function onGetValue and it's working.
I have a sap.viz.ui5.controls.VizFrame with its data property bound to a two-way JSON model in my view. Additionally, I have a Button and a Text element in the same view. The Text element displays the values of the model, which is bound against the VizFrame, and the Button has a press event handler, which increases the value of one property of the model.
So, when I press the button, the Text updates automatically, unlike the VizFrame. Do you have any suggestions on how to fix this? I saw this vizUpdate method, but it looked very complex and is probably overkill. However, changing the whole model also changes the displayed data of the VizFrame.
Code Example
Main.view.xml
<mvc:View controllerName="demo.chart.controller.Main" xmlns:mvc="sap.ui.core.mvc" displayBlock="true" xmlns="sap.m"
xmlns:viz="sap.viz.ui5.controls" xmlns:viz.data="sap.viz.ui5.data" xmlns:viz.feeds="sap.viz.ui5.controls.common.feeds">
<Shell id="shell">
<App id="app">
<pages>
<Page id="page" title="{i18n>title}">
<content>
<VBox>
<viz:VizFrame id="vizFrame" uiConfig="{applicationSet:'fiori'}" vizType='donut'>
<viz:dataset>
<viz.data:FlattenedDataset data="{data>/}">
<viz.data:dimensions>
<viz.data:DimensionDefinition name="Type" value="{manipulatedData>type}"/>
</viz.data:dimensions>
<viz.data:measures>
<viz.data:MeasureDefinition name="Amount" value="{manipulatedData>amount}"/>
</viz.data:measures>
</viz.data:FlattenedDataset>
</viz:dataset>
<viz:feeds>
<viz.feeds:FeedItem uid="color" type="Dimension" values="Type"/>
<viz.feeds:FeedItem uid="size" type="Measure" values="Amount"/>
</viz:feeds>
</viz:VizFrame>
<Button text="+1 Foo" press="onButtonPress"/>
<Text text="Foo: {data>/0/amount} | Bar: {data>/1/amount}"/>
</VBox>
</content>
</Page>
</pages>
</App>
</Shell>
</mvc:View>
Main.controller.js
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/ui/model/json/JSONModel"
], function (Controller, JSONModel) {
"use strict";
return Controller.extend("demo.chart.controller.Main", {
onInit: function () {
this.mData = new JSONModel([{
type: "foo",
amount: 23
}, {
type: "bar",
amount: 20
}]).setDefaultBindingMode("TwoWay");
this.getView().setModel(this.mData, "data");
},
onButtonPress() {
this.mData.setProperty("/0/amount", this.mData.getProperty("/0/amount") + 1);
}
});
});
I guess I figured it out. You have to rebind the data to the dataset aggregation after you changed the model:
Working Example
Main.controller.js
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/ui/model/json/JSONModel"
], function (Controller, JSONModel) {
"use strict";
return Controller.extend("demo.chart.controller.Main", {
onInit: function () {
this.mData = new JSONModel([{
type: "foo",
amount: 23
}, {
type: "bar",
amount: 20
}]).setDefaultBindingMode("TwoWay");
this.getView().setModel(this.mData, "data");
},
onButtonPress() {
this.mData.setProperty("/0/amount", this.mData.getProperty("/0/amount") + 1);
this.byId("vizFrame").getDataset().bindData({
path: "data>/"
});
}
});
});
I am facing two issues when deleting a record in sap.m.Table as mentioned below.
After deleting a row using delete button, other rows are also getting vanished. Only after refreshing the page, I can see those records.
I have used success and error message after deleting the rows but it is not appearing.
Table.view.xml
<mvc:View
xmlns:core="sap.ui.core"
xmlns:mvc="sap.ui.core.mvc"
xmlns="sap.m"
controllerName="sem.stock_app.controller.table"
>
<Page
title="Material Status"
showNavButton="true"
navButtonPress="onNavBack"
>
<Table id="table"
growing="true"
mode="MultiSelect"
items="{odata>np_on_matid}"
>
<columns>
<Column>
<CheckBox text="Select Entry"/>
</Column>
<Column>
<Text text="Material ID"/>
</Column>
<Column>
<Text text="Category"/>
</Column>
<Column>
<Text text="Material Desc"/>
</Column>
<Column>
<Text text="Plant"/>
</Column>
</columns>
<items>
<ColumnListItem type="Active" press="onPress">
<CheckBox selected="{false}"/>
<Text text="{odata>Matid}"/>
<Text text="{odata>Category}"/>
<Text text="{odata>Matdesc}"/>
<Text text="{odata>Plant}"/>
</ColumnListItem>
</items>
</Table>
<Button
text="Delete"
enabled="true"
press="onDelete"
/>
</Page>
</mvc:View>
Table.Controller.js
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/ui/model/json/JSONModel",
"sap/ui/model/Filter",
"sap/ui/core/routing/History",
"sap/m/MessageToast",
"sap/m/MessageBox"
], function(Controller, JSONModel, Filter, History, MessageToast, MessageBox) {
"use strict";
return Controller.extend("sem.stock_app.controller.table", {
onInit: function() {
this.getOwnerComponent().getRouter().getRoute("r2").attachPatternMatched(this.mynav, this);
},
mynav: function(oeve) {
var key = this.getOwnerComponent().getModel("odata").createKey("matlistSet", {
"Matid": oeve.getParameters().arguments.noti
});
this.getView().bindElement({
path: "odata>/" + key,
parameters: {
expand: "np_on_matid"
}
});
},
onNavBack: function() {
var oHistory = History.getInstance();
var sPreviousHash = oHistory.getPreviousHash();
if (sPreviousHash !== undefined) {
window.history.go(-1);
} else {
var oRouter = sap.ui.core.UIComponent.getRouterFor(this);
oRouter.navTo("r1", {}, true);
}
},
onPress: function(oitem) {
var x = oitem.getSource().getBindingContext("odata").getProperty("Matid");
this.getOwnerComponent().getRouter().navTo("r3", {
matnr: x
});
},
onDelete: function() {
var i, tbl, aSelectedProducts, sPath, oProduct, oProductId;
tbl = this.byId("table").getSelectedItems();
aSelectedProducts = this.byId("table").getSelectedItems();
if (aSelectedProducts.length) {
for (i = 0; i < aSelectedProducts.length; i++) {
oProduct = aSelectedProducts[i];
oProductId = oProduct.getBindingContext("odata").getProperty("Matid");
sPath = oProduct.getBindingContextPath();
this.getOwnerComponent().getModel("odata").remove(sPath, {
success: this._handleUnlistActionResult.bind(this, oProductId, true, i + 1, aSelectedProducts.length),
error: this._handleUnlistActionResult.bind(this, oProductId, false, i + 1, aSelectedProducts.length)
});
}
} else {
this._showErrorMessage(this.getModel("i18n").getResourceBundle().getText("TableSelectProduct"));
}
},
_handleUnlistActionResult: function(sProductId, bSuccess, iRequestNumber, iTotalRequests, oData, oResponse) {
if (iRequestNumber === iTotalRequests) {
MessageToast.show(this.getModel("i18n").getResourceBundle().getText("StockRemovedSuccessMsg", [iTotalRequests]));
}
},
});
});
Component.js
sap.ui.define([
"sap/ui/core/UIComponent",
"sap/ui/Device",
"sem/stock_app/model/models"
], function(UIComponent, Device, models) {
"use strict";
return UIComponent.extend("sem.stock_app.Component", {
metadata: {
manifest: "json"
},
init: function() {
var url = "/sap/opu/odata/sap/ZMATLIST_SRV_03";
var odata = new sap.ui.model.odata.ODataModel(url, {
json: true
});
this.setModel(odata,"odata");
UIComponent.prototype.init.apply(this, arguments);
this.getRouter().initialize();
this.setModel(models.createDeviceModel(), "device");
}
});
});
As discussed in the comments, the issues were:
Use of sap.ui.model.odata.ODataModel which has been out of maintenance since long time ago
There was no $batch operation implemented in the back-end system.
I've got this ObjectPageLayout:
request.view.xml
<ObjectPageLayout>
<headerTitle>
...
</headerTitle>
<headerContent>
...
</headerContent>
<sections>
<ObjectPageSection
mode="Collapsed">
<subSections>
<ObjectPageSubSection title="fooBlock">
<blocks>
<blockdetail:FormBlock columnLayout="auto" /> <!-- MY BLOCK -->
</blocks>
</ObjectPageSubSection>
</subSections>
</ObjectPageSection>
</sections>
</ObjectPageLayout>
FormBlockCollapsed.view.xml (MY BLOCK)
<mvc:View xmlns:f="sap.ui.layout.form" xmlns:mvc="sap.ui.core.mvc"
xmlns:core="sap.ui.core" xmlns:l="sap.ui.layout" xmlns="sap.m"
controllerName="NAMESPACE.blocks.DetailsBlockCommon">
<FlexBox>
<HBox>
<VBox>
<f:SimpleForm >
<f:content>
<CheckBox class="sapUiSmallMarginBegin sapUiSmallMarginTop" id="myCheckbox" />
</f:content>
</f:SimpleForm>
</VBox>
</HBox>
</FlexBox>
...
</mvc:View>
So far, everything is fine. My Object page looks good a the checkbox is shown.
In my Controller request.controller.js i want to validate the checkbox in FormBlockCollapsed.view.xml
validateBlockForm: function(format){
console.log( oView.byId("myCheckbox").checked() ); //oView.byId("myCheckbox") is undefined
}
But i've no access to my checkbox in the block.
Cannot read property 'checked' of undefined
Further infos
FormBlock.js
sap.ui.define(['sap/uxap/BlockBase'], function (BlockBase) {
"use strict";
var MultiViewBlock = BlockBase.extend("NAMESPACE.blocks.FormBlock", {
metadata: {
views: {
Collapsed: {
viewName: "NAMESPACE.blocks.FormBlockCollapsed",
type: "XML"
}
}
}
});
return MultiViewBlock;
}, true);
DetailBlockCommon.js
sap.ui.define([
"NAMESPACE/controller/BaseController"
], function (BaseController) {
"use strict";
return BaseController.extend("NAMESPACE.blocks.DetailsBlockCommon", {
});
});
You can access the elements in a section by having the block's id and element's id.
First we have to define an id for the block in the xml view:
<blocks>
<blockdetail:FormBlock id="formBlock" columnLayout="auto" /> <!-- MY BLOCK -->
</blocks>
Then we generate the id of the elements like the following in the view controller. The state of the art here is to add -Collapsed-- as part of the id that adds by SAPUI5 to sections elements.
var sFieldId = this.getView().createId("formBlock") +
"-Collapsed--myCheckbox";
var oCheckbox = sap.ui.getCore().byId(sFieldId);
Check if oView is defined.
you can easily get it by this.getView()
How to push the data in XML view into the newly created JSON model? I have created the comboBox and retrieved the data from JSON model and also created the text area when I select the item in combo box and insert data into the text area and submit a button both the data should be pushed to newly created JSON model in sapweb ide ui5
page.view.xml:
<mvc:View height="100%" controllerName="pro.controller.Page" xmlns:core="sap.ui.core" xmlns:l="sap.ui.layout" xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m">
<Page title="{i18n>title}">
<content>
<l:VerticalLayout>
<ComboBox items="{ path: '/ProductCollection', sorter: { path: 'Name' } }">
<core:Item text="{Name}" /> </ComboBox>
<TextArea value="" rows="8" />
<Button type="Accept" text="Submit" press="onPress" /> </l:VerticalLayout>
</content>
</Page>
</mvc:View>
page.controller.js
sap.ui.define([
'jquery.sap.global',
'sap/ui/core/mvc/Controller',
'sap/ui/model/json/JSONModel'
], function(jQuery, Controller, JSONModel) {
"use strict";
var PageController = Controller.extend("pro.controller.Page", {
onInit: function() {
// set explored app's demo model on this sample
var oModel = new JSONModel(jQuery.sap.getModulePath("pro", "/model/model.json"));
this.getView().setModel(oModel);
}
});
return PageController;
});
add a 'key' attribute to the combobox item. Also give the combobox and teaxarea some IDs.
<ComboBox id="selectBox" items="{ path: '/ProductCollection', sorter: { path: 'Name' } }">
<core:Item key="{Naame}" text="{Name}" /> </ComboBox>
<TextArea id="textArea" value="" rows="8" />
On click of submit, get the selected values from the combobox and text area and push them into the model. I assume that you wanted to push this new data to the existing model and also your existing model is an array of objects.
sap.ui.define([
'jquery.sap.global',
'sap/ui/core/mvc/Controller',
'sap/ui/model/json/JSONModel'
],function(jQuery, Controller, JSONModel) {
"use strict";
var PageController = Controller.extend("pro.controller.Page", {
onInit: function() {
var oModel = new JSONModel(jQuery.sap.getModulePath("pro", "/model/model.json"));
this.getView().setModel(oModel);
},
onPress: function() {
//get the value of the selected item in the combobox
var selectedVal = this.getView().byId("selectBox").getSelectedKey();
//get the textarea value
var textAreaVal = this.getView().byId("textArea").getValue();
this.getView().getModel().oData.push({
key: selectedVal,
value: textAreaVal
});
}
});
return PageController;
});