SAP UI5 table's column sorting is lost after table model is refreshed - sapui5

I have a table (sap.ui.table) and all its column have sorting. In the table, one of the columns has a button for changing and saving the value of its cell. On saving, I want to update the table model with new data.
If I have sorted by PO number column, and the table refreshes, then the table is not again sorted in PO numbers, but it is reset to the stockroom name column sort which is default one.
How to ensure the sort that was applied to any of its column retains after model refresh?
XML.view
<table:Table id="abc"
rows="{ path: 'tableModel>/results', sorter: {path: 'FromStockroomName'}}" selectionMode="Single" selectionBehavior="RowOnly">
<table:columns>
<table:Column id="fromStk" sortProperty="FromStockroomName">
<Label text="From Stockroom"/>
<table:template>
<Text class="table-cell-text" text="{dataModel>FromStockroomName}"/>
</table:template>
</table:Column>
<table:Column sortProperty="OrderNumber">
<Label class="smartist-table-column-header" text="PO number"/>
<table:template>
<Link text="{dataModel>OrderNumber}" emphasized="true"/>
</table:template>
</table:Column>
<table:Column sortProperty="BackOrderedQty">
<Label text="B/O Qty"/>
<table:template>
<HBox>
<Button text="Reduce"
visible="{= !${dataModel>qobEditable}}" press="openBOText"/>
<Button text="Save" visible="{= ${dataModel>qobEditable}}" press="boQtySave"/>
<Input visible="{= ${dataModel>qobEditable}}"/>
</HBox>
</table:template>
</table:Column>
Controller.js
getAllBackOrderData: function () {
var filters = [
new Filter("CompanyID", FilterOperator.EQ, vc.company)
];
someService.getBackOrders(vc, filters).then(function (data) {
data.results = vc._sanitizeTableModel(data);
var backOrderModel = new JSONModel(data);
vc.getView().setModel(backOrderModel,"dataModel");
SpinnerUtils.stopSpinner(vc);
}).catch(function (error) {
...
}).then(function () {
SpinnerUtils.stopSpinner(vc);
});
**********************************************************************
_sanitizeTableModel: function (data) {
return data.results.map(function (order) {
order.qobEditable = false;
//need to add this
//order.previousBOQty = order.backOrder
return order;
})
},

Related

suggestion to implement the Grouping, Filtering and Sorting of my table in sapui5

I am trying to implement Grouping, Filtering and Sorting on a table with which I bring some data.
I have been able to perform Grouping and Sorting without problems, but I have not been able to filter correctly.
This would be the code of the fragment that I used for Grouping, Filtering and Sorting:
<core:FragmentDefinition xmlns:core="sap.ui.core" xmlns="sap.m">
<ViewSettingsDialog confirm="onConfirm">
<sortItems>
<ViewSettingsItem selected="true" key="Xao" text="Tipo"/>
<ViewSettingsItem key="Xoccupant" text="Ocupante"/>
</sortItems>
<groupItems>
<ViewSettingsItem key="Xao" text="Tipo"/>
</groupItems>
<filterItems>
<ViewSettingsFilterItem key="Xao" text="Tipo" multiSelect="false" items="{/d/results/Xao}">
<items>
<ViewSettingsItem key="{Xao}" text="{Xao}"/>
</items>
</ViewSettingsFilterItem>
</filterItems>
</ViewSettingsDialog>
</core:FragmentDefinition>
On the part of the controller, this would be the code it occupies:
onPress: function () {
this._Dialog = sap.ui.xmlfragment("LogonPage.LogonPage.fragments.Dialog", this);
this._Dialog.open();
},
onClose: function () {
this._Dialog.close();
},
onTableSettings: function (oEvent) {
// Abra el cuadro de diálogo Configuración de tabla
this._oDialog = sap.ui.xmlfragment("LogonPage.LogonPage.fragments.SettingsDialog", this);
this._oDialog.open();
},
onConfirm: function (oEvent) {
var oView = this.getView();
var oTable = oView.byId("table0");
var mParams = oEvent.getParameters();
var oBinding = oTable.getBinding("items");
// apply grouping
var aSorters = [];
if (mParams.groupItem) {
var sPath = mParams.groupItem.getKey();
var bDescending = mParams.groupDescending;
var vGroup = function (oContext) {
var name = oContext.getProperty("Xao");
return {
key: name,
text: name
};
};
aSorters.push(new sap.ui.model.Sorter(sPath, bDescending, vGroup));
}
// apply sorter
var sPath = mParams.sortItem.getKey();
var bDescending = mParams.sortDescending;
aSorters.push(new sap.ui.model.Sorter(sPath, bDescending));
oBinding.sort(aSorters);
// apply filters
var aFilters = [];
var sQuery = oEvent.getParameter("query");
if (sQuery) {
aFilters.push(new Filter("Xao", FilterOperator.Contains, sQuery));
}
oBinding.filter(aFilters);
},
And this is the view of my table, what I want to filter is all that contains the Xao section of my table.
<Table inset="false" items="{/d/results}" id="table0" width="auto">
<items>
<ColumnListItem type="Active" id="item1">
<cells>
<Text text="{Xao}" id="text7"/>
<Text text="{Xoccupant}" id="text8"/>
<Text text="{ path: 'Validfrom', type: 'sap.ui.model.type.Date', formatOptions:
{ source: {
pattern: 'yyyyMMdd' },
pattern: 'dd/MM/yyyy' } }" id="text9"/>
<Text text="{ path: 'Validto', type: 'sap.ui.model.type.Date', formatOptions:
{ source: {
pattern: 'yyyyMMdd' }, pattern: 'dd/MM/yyyy' } }" id="text10"/>
</cells>
</ColumnListItem>
</items>
<columns>
<Column id="column0">
<header>
<Label text="Tipo" id="label0"/>
</header>
</Column>
<Column id="column1">
<header>
<Label text="Ocupante" id="label1"/>
</header>
</Column>
<Column id="column2">
<header>
<Label text="Fecha de Apartado" id="label2"/>
</header>
</Column>
<Column id="column3">
<header>
<Label text="Fecha de Finalización" id="label3"/>
</header>
</Column>
</columns>
</Table>
And here the code of the view, where I enable Grouping, Filtering and Sorting of my table
<headerToolbar>
<Toolbar id="toolbar3">
<Title text="Puestos de Trabajo"/>
<ToolbarSpacer/>
<Button press="onTableSettings" icon="sap-icon://drop-down-list" tooltip="Settings"/>
</Toolbar>
</headerToolbar>
Any ideas or suggestions to correctly filter my table?
Check your onConfirm function in the controller - the code for the filtering looks more like code for a search field. You have to process the filters coming from the event: https://sapui5.hana.ondemand.com/#/api/sap.m.ViewSettingsDialog%23events/confirm
For you this will contain only filters for your Xao field but my recommendatio is set a breakpoint in the function and analyse the oEvent.getParameters() structure.

Data Binding from TableSelectDialog to Form

I'm using TableSelectDialog to view some Carrier details. All I need is: If I select any item (row), then all the values from that row should get automatically populated to the form input fields.
In the attached image, if Carrier Name is selected from TableSelectDialog, then the remaining fields should be populated based on that value.
You can achieve the required functionality using the Binding context that you receive from the TableSelcect Dialog.
But for binding context to work properly, both form and the table select dialog should refer to the same Model.
Below is the working code:
VIEW.XML:
Has a Button to trigger the table select dialog.
Has a form.
<l:VerticalLayout class="sapUiContentPadding" width="100%">
<l:content>
<Button class="sapUiSmallMarginBottom" text="Show Table Select Dialog"
press="handleTableSelectDialogPress">
</Button>
<VBox class="sapUiSmallMargin">
<f:SimpleForm id="SimpleFormDisplay354">
<f:content>
<Label text="Supplier Name" />
<Text id="nameText" text="{SupplierName}" />
<Label text="Description" />
<Text text="{Description}" />
<Label text="ProductId" />
<Text text="{ProductId}" />
<Label text="Quantity" />
<Text id="countryText" text="{Quantity}" />
</f:content>
</f:SimpleForm>
</VBox>
</l:content>
</l:VerticalLayout>
Controller:
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);
},
handleTableSelectDialogPress: function (oEvent) {
if (!this._oDialog) {
this._oDialog = sap.ui.xmlfragment("sap.m.sample.TableSelectDialog.Dialog", this);
}
this.getView().addDependent(this._oDialog);
// toggle compact style
this._oDialog.open();
},
handleClose: function (oEvent) {
var aContexts = oEvent.getParameter("selectedContexts");
if (aContexts && aContexts.length) {
// MessageToast.show("You have chosen " + aContexts.map(function(oContext) { return oContext.getObject().Name; }).join(", "));
this.byId('SimpleFormDisplay354').setBindingContext(aContexts[0]);
}
oEvent.getSource().getBinding("items").filter([]);
}
Now, we also have a Select dialog and on click of any Item we call method : handleClose
In handleClose, we obtain the clicked Item binding context and then tell the form : hey! refer to this context ( which is present in the model). Binding context has a path which tells the form from where to do the relative binding.
Please feel free to contact for more information.

oData binding to Simple Form

I'm creating a read only form that will be used to display a summary of information. I need to send a parameter to the backend first before getting the information but I don't seem to see that parameter is reaching it.
It does reach the entity set but it does not show the parameter. Am I binding correctly?
This is on the controller:
onInit: function() {
var urlEnding = "1000012233";
var oFilterDist = new sap.ui.model.Filter("ID",
sap.ui.model.FilterOperator.EQ, urlEnding);
var summaryText = this.getView().byId("summaryForm");
summaryText.bindElement({
path: "/SummaryScreenSet",
filters: [oFilterDist]
});
}
This is on the View
<VBox class="sapUiSmallMargin" fitContainer="true"
height="100%" width="100%" justifyContent="End"
displayInline="true" id="leftVBox" items="{/SummaryScreenSet}">
<items>
<f:SimpleForm editable="true" layout="ResponsiveGridLayout" id="summaryForm" columnsL="1" columnsXL="1" labelSpanL="5" title="Account Summary" labelSpanM="5">
<f:content>
<Label text="Status" id="__label6" design="Bold" class="sizeText"/>
<ObjectStatus text="{CONTRACT_STATUS}" id="__status6" state="Success" class="boldText"/>
<Label text="Permit Required" id="__label10" design="Bold" class="sizeText"/>
<Text text="{PERMIT_REQD}" id="__text32" wrapping="false" class="sizeText"/>
<Label text="Bill Date | Due Date" id="__label11" design="Bold" class="sizeText"/>
<Text text="{BILL_DATE} | {DUE_DATE}" id="__text33" wrapping="false" class="sizeText"/>
<Label text="Last Estimated Date | Next MR Date" id="__label17" design="Bold" class="sizeText"/>
<Text text="{LAST_PAYMENT_DATE} | {nextMRDate}" id="__text39" wrapping="false" class="sizeText"/>
</f:content>
</f:SimpleForm>
</items>
</VBox>
Going to assume you want a single, specific entry. In that case, what you're looking for is the Entity, not the EntitySet + filter. Coincidentally, here's one I wrote yesterday that works. I've changed the paths and ID's to reflect yours:
var form = this.getView().byId('summaryForm');
form.bindElement({
path: "/SummaryScreenSet('" + urlEnding + "')",
events: {
change: function() {
//triggers on error too I think
form.setBusy(false);
},
dataRequested: function() {
form.setBusy(true);
}
}
});
In that case you don't need the VBOX either, just the form. Don't forget to implement SUMMARYSCREEN_GET_ENTITY or whatever the method is on your DPC_EXT.
Edit: might want to set editable on the form to false, it shrinks the layout to suit text instead of inputs.

Get selected item from sap.m.Select from a sapui5 table column

I am using sap.m.Table, where I have 3 columns, as sap.m.text, sap.m.setect and the last one is button.
My model code
var oModel = new sap.ui.model.odata.OData("url");
sap.ui.getCore().setModel(oModel ,"data");
Table view code(cells)
var oTemplate = new sap.m.ColumnListItem({
cells : [
new sap.m.Text({
text: "{data>Address}"
}),
new sap.m.Select({
id:"sel",
items: {
path: "data>/OPERATORS", // this is a diffent table
template: new sap.ui.core.Item({
text: "{data>firstName} {data>lastName}"
})
},
forceSelection: false
}),
new sap.m.Button({
text : "Start",
press : [oController.onPressStart, oController]
})
]
});
oTable.bindItems("data>/ORDR", oTemplate); //differnt table
Working fine, getting all required data on the specific table.(Notice first column is coming from ORDR table and second one is coming from OPERATORS table).
Now on button click I wanted the specific row data. My code as follows -
onPressStart : function(oEvent){
var obj = oEvent.getSource().getBindingContext("data").getObject();
},
"obj" gives me ORDR table row objects(where I pressed the button).
Now I also want the value I will select on the dropdown box. How to get it.
Please suggest, Thank you
JSbin Link - http://jsbin.com/quhomoloqo/edit?html,console,output
See this working example:
Please note how (for the sake of this question) created two models:
One named 'orig' which holds your original OPERATOR and ODRD data, and
one named 'data' which holds a copy of the OPERATOR data, with an added Address property.
See the view code on how the two models are used (the new one for the table, the old one for populating the dropdown)
sap.ui.controller("view1.initial", {
onInit : function(oEvent) {
},
onAfterRendering : function() {
// your original model
var oModel = new sap.ui.model.json.JSONModel();
var oData = {
"ODRD":[
{"Address":"UK"},
{"Address":"US"}
],
"OPERATORS":[
{"firstName":"a","lastName":"b"},
{"firstName":"c","lastName":"d"}
]
};
oModel.setData(oData);
this.getView().setModel(oModel, "orig");
// the model you actually need
var oNewModel = new sap.ui.model.json.JSONModel();
var oNewData = oData.OPERATORS.map(function(result) {
return {
firstName : result.firstName,
lastName : result.lastName,
keyToAddress : null
}
})
oNewModel.setData({
"OPERATORS" : oNewData
});
this.getView().setModel(oNewModel, "data");
},
showData : function(oEvent) {
alert(JSON.stringify(oEvent.getSource().getBindingContext("data").getObject()));
}
});
sap.ui.xmlview("main", {
viewContent: jQuery("#view1").html()
})
.placeAt("uiArea");
<script id="sap-ui-bootstrap"
src="https://sapui5.hana.ondemand.com/resources/sap-ui-core.js"
data-sap-ui-theme="sap_bluecrystal"
data-sap-ui-xx-bindingSyntax="complex"
data-sap-ui-libs="sap.m"></script>
<div id="uiArea"></div>
<script id="view1" type="ui5/xmlview">
<mvc:View
controllerName="view1.initial"
xmlns="sap.m"
xmlns:core="sap.ui.core"
xmlns:mvc="sap.ui.core.mvc" >
<Table id="tbl" items="{data>/OPERATORS}">
<columns>
<Column>
<Text text="First" />
</Column>
<Column>
<Text text="Last" />
</Column>
<Column>
<Text text="ODRD" />
</Column>
<Column>
<Text text="" />
</Column>
</columns>
<items>
<ColumnListItem>
<cells>
<Input value="{data>firstName}" />
<Input value="{data>lastName}" />
<Select items="{orig>/ODRD}" selectedKey="{data>keyToAddress}">
<items>
<core:ListItem key="{orig>Address}" text="{orig>Address}" />
</items>
</Select>
<Button text="Show data" press="showData" />
</cells>
</ColumnListItem>
</items>
</Table>
</mvc:View>
</script>

How can I bin data to table or list in Sapui5

I want to get data from user input and insert that data into a table or list. When the user clicks the insert button, the data will be inserted into the table. If the user clicks the delete button, the selected row will be deleted.
This my home.view.xml:
<Button text="insert" type="Unstyled" press="insContent"></Button>
<Button text="delete" type="Unstyled" press="deleteContent"></Button>
<l:Grid defaultSpan="L12 M12 S12" width="auto">
<l:content>
<f:SimpleForm columnsL="1" columnsM="1" editable="false" emptySpanL="4" emptySpanM="4" id="SimpleForm" labelSpanL="3" labelSpanM="3" layout="ResponsiveGridLayout" maxContainerCols="2" minWidth="1024">
<f:content>
<Label text="Name" id="lname"></Label>
<Input value="" id="iname"></Input>
<Label text="surname" id="lsurname"></Label>
<Input value="" id="isurname"></Input>
</f:content>
</f:SimpleForm>
</l:content>
</l:Grid>
<Table class="nwEpmRefappsShopControlLayout" growing="true" growingScrollToLoad="true" id="catalogTable">
<columns>
<Column demandPopin="true" id="descriptionColumn"></Column>
<Column demandPopin="true" id="descriptionColumn2"></Column>
</columns>
<ColumnListItem class="nwEpmRefappsShopTableItemLayout" id="columnListItem" type="Active" vAlign="Middle">
<cells>
.
.
</cells>
</ColumnListItem>
</Table>
This my home.controller.js:
insContent: function () {
// Get data from input
this.byId("iname").getValue();
this.byId("isurname").getValue();
}
I don't know how to make xml views but maybe this can help you.
First, you need to have a table with a model. For example (oTableData is a sap.m.Table object):
var oModel = new sap.ui.model.json.JSONModel();
oModel.setData({modelData: aData});
oTableData.setModel(oModel);
oTableData.bindItems("/modelData", oRow);
Also you need an array for store data (in index.html).
var aData = [];
For add users you need the following function.
save: function(firstName, lastName) {
// Add object to array
aData.push({firstName: firstName, lastName: lastName});
// Refresh model
var oTableData = sap.ui.getCore().byId(this.createId("table"));
oTableData.getModel().refresh();
}
Finally for delete users you have to add this to the table.
oTableData.setMode(sap.m.ListMode.Delete);
oTableData.attachDelete(function(oEvent) {
var oSelectedItem = oEvent.getParameter("listItem");
var sItemName = oSelectedItem.getBindingContext().getProperty("firstName");
var path = oSelectedItem.getBindingContext().getPath();
path = path.substring(path.lastIndexOf('/') +1);
var model = oSelectedItem.getModel();
var data = model.getProperty('/modelData');
data.splice(parseInt(path), 1);
model.setProperty('/modelData', data);
sap.m.MessageToast.show("Deleted");
});
I make a repository for reference:
https://github.com/aosepulveda/sapui5-model-crud
You can fetch the first and last name using ids after clicking on the insert button. Once you have the values, create an object
var object = {
firstName: user_enteredValue,
lasName: userEnteredSirName
};
Then, insert into your table model, i.e.
table.getModel().getData().push(object);
table.getModel().refresh();
It will update your table with a new row.