How to drag and drop rows of a table - sapui5

In my view.xml file:
<html:div class="container-fluid">
<html:div class="row">
<Table id="ConnectorModuleTable"
items="{
path: '/datalist'}">
<columns>
<Column ><Text text="Connector Module"/></Column>
<Column ><Text text="Setting A"/></Column>
<Column ><Text text="Setting B"/></Column>
<Column ><Text text="Custom Pin"/></Column>
<Column ><Text text="Actions"/></Column>
</columns>
<items>
<ColumnListItem>
<cells>
<Text text="{Connectormodule}" wrapping="false" />
<Text text="{settingA}" wrapping="false" />
<Text text="{settingB}" wrapping="false" />
<Text text="{settingB}" wrapping="false" />
</cells>
</ColumnListItem>
</items>
</Table>
</html:div>
</html:div>
I am trying to drag and drop the rows of this table
I have referred the link from docs showing for list as:
Documentation example link here
The same I have applied with the table in controller as :
attachDragAndDrop: function () {
var oList = this.byId("MyTable");
oList.addDragDropConfig(new DragInfo({
sourceAggregation: "items"
}));
oList.addDragDropConfig(new DropInfo({
targetAggregation: "items",
dropPosition: "Between",
dropLayout: "Vertical",
drop: this.onDrop.bind(this)
}));
},
onDrop: function (oInfo) {
var oDragged = oInfo.getParameter("draggedControl"),
oDropped = oInfo.getParameter("droppedControl"),
sInsertPosition = oInfo.getParameter("dropPosition"),
oDraggedParent = oDragged.getParent(),
oDroppedParent = oDropped.getParent(),
oDragModel = oDraggedParent.getModel(),
oDropModel = oDroppedParent.getModel(),
oDragModelData = oDragModel.getData(),
oDropModelData = oDropModel.getData(),
iDragPosition = oDraggedParent.indexOfItem(oDragged),
iDropPosition = oDroppedParent.indexOfItem(oDropped);
// remove the item
var oItem = oDragModelData[iDragPosition];
oDragModelData.splice(iDragPosition, 1);
if (oDragModel === oDropModel && iDragPosition < iDropPosition) {
iDropPosition--;
}
// insert the control in target aggregation
if (sInsertPosition === "Before") {
oDropModelData.splice(iDropPosition, 0, oItem);
} else {
oDropModelData.splice(iDropPosition + 1, 0, oItem);
}
if (oDragModel !== oDropModel) {
oDragModel.setData(oDragModelData);
oDropModel.setData(oDropModelData);
} else {
oDropModel.setData(oDropModelData);
}
},
initData: function (datalist) {
this.byId("MyTable").setModel(new JSONModel([
datalist
]));
}
Here datalist has all rows data in JSON (for ref)
But this did n't work , any help or guiding links are appreciated

I used the following view with your onDrop() and it worked.
Can you describe, what is not working?
<Table id="MyTable" items="{/}">
<columns>
<Column ><Text text="Connector Module"/></Column>
<Column ><Text text="Setting A"/></Column>
<Column ><Text text="Setting B"/></Column>
</columns>
<dragDropConfig>
<dnd:DragDropInfo
sourceAggregation="items"
targetAggregation="items"
dropPosition="Between"
drop=".onDrop"/>
</dragDropConfig>
<items>
<ColumnListItem>
<cells>
<Text text="{Connectormodule}" wrapping="false" />
<Text text="{settingA}" wrapping="false" />
<Text text="{settingB}" wrapping="false" />
<Text text="{settingB}" wrapping="false" />
</cells>
</ColumnListItem>
</items>
</Table>

Can you see data in the original table?
Setting of the model is incorrect: the JSONModel constructor needs an object rather than an array as listed in your initData function. It seems like a binding problem to me...
I just tried to modify your code as follows and everithing works fine:
onDrop: function (oInfo) {
var oDragged = oInfo.getParameter("draggedControl"),
oDropped = oInfo.getParameter("droppedControl"),
sInsertPosition = oInfo.getParameter("dropPosition"),
oDraggedParent = oDragged.getParent(),
oDroppedParent = oDropped.getParent(),
oDragModel = oDraggedParent.getModel(),
oDropModel = oDroppedParent.getModel(),
oDragModelData = oDragModel.getData(),
oDropModelData = oDropModel.getData(),
iDragPosition = oDraggedParent.indexOfItem(oDragged),
iDropPosition = oDroppedParent.indexOfItem(oDropped);
// remove the item
var oItem = oDragModelData.datalist[iDragPosition];
oDragModelData.datalist.splice(iDragPosition, 1);
if (oDragModel === oDropModel && iDragPosition < iDropPosition) {
iDropPosition--;
}
// insert the control in target aggregation
if (sInsertPosition === "Before") {
oDropModelData.datalist.splice(iDropPosition, 0, oItem);
} else {
oDropModelData.datalist.splice(iDropPosition + 1, 0, oItem);
}
if (oDragModel !== oDropModel) {
oDragModel.setData(oDragModelData);
oDropModel.setData(oDropModelData);
} else {
oDropModel.setData(oDropModelData);
}
},
initData: function (datalist) {
//just an example
var oData = {
datalist: [{
Connectormodule: "one",
settingA: "one",
settingB: "one"
}, {
Connectormodule: "two",
settingA: "two",
settingB: "two"
}, {
Connectormodule: "three",
settingA: "three",
settingB: "three"
}]
};
var oModel = new sap.ui.model.json.JSONModel(oData);
this.byId("ConnectorModuleTable").setModel(oModel);
},

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.

Why does my searchfield work on one table but not at another one?

i got some wired problems..
<core:FragmentDefinition xmlns="sap.ui.table" xmlns:dnd="sap.ui.core.dnd" xmlns:mvc="sap.ui.core.mvc" xmlns:core="sap.ui.core"
xmlns:m="sap.m">
<m:Dialog id="AuftragDialog" title="Aufträge">
<!-- <m:beginButton>
<m:Button text="Fertig" press=".onSaveAufträge"/>
</m:beginButton> -->
<m:endButton>
<m:Button text="Zurück" press=".onCancelAufträge"/>
</m:endButton>
<m:content>
<m:HBox renderType="Bare">
<Table id="table1" selectionMode="MultiToggle" rows="{ path: 'Hallo>/results' }" visibleRowCount="10">
<extension>
<m:OverflowToolbar>
<m:Title text="Alle Aufträge"/>
<m:ToolbarSpacer/>
<m:SearchField id="allOrder" liveChange="onFilterAllOrder">
<m:layoutData><m:OverflowToolbarLayoutData minWidth="25%" maxWidth="30%" /></m:layoutData>
</m:SearchField>
</m:OverflowToolbar>
</extension>
<columns>
<Column >
<m:Text text="Auftrags Nummer"/>
<template>
<m:Text text="{Hallo>Aufnr}" wrapping="false"/>
</template>
</Column>
<Column filterProperty="Ktext">
<m:Text text="Auftrag"/>
<template>
<m:Text text="{Hallo>Ktext}" wrapping="false"/>
</template>
</Column>
</columns>
<dragDropConfig>
<dnd:DragInfo groupName="moveToTable2" sourceAggregation="rows" dragStart="onDragStart"/>
<dnd:DropInfo groupName="moveToTable1" drop="onDropTable1"/>
</dragDropConfig>
</Table>
<m:VBox justifyContent="Center" class="sapUiTinyMarginBeginEnd">
<m:Button class="sapUiTinyMarginBottom" icon="sap-icon://navigation-right-arrow" tooltip="Move to selected" press="moveToTable2"/>
<m:Button icon="sap-icon://navigation-left-arrow" tooltip="Move to available" press="moveToTable1"/>
</m:VBox>
<Table id="table2" selectionMode="MultiToggle" rows="{/ZAUFK_VARSet}" visibleRowCount="10" noData="Bitte wählen sie Ihre Aufträge aus.">
<extension>
<m:OverflowToolbar>
<m:Title text="Selektierte Aufträge"/>
<m:ToolbarSpacer/>
<m:SearchField id="selectedOrder" liveChange="onFilterSelectedOrder">
<m:layoutData><m:OverflowToolbarLayoutData minWidth="25%" maxWidth="30%" /></m:layoutData>
</m:SearchField>
</m:OverflowToolbar>
</extension>
<columns>
<Column>
<m:Text text="Auftrags Nummer"/>
<template>
<m:Text text="{Aufnr}" wrapping="false" />
</template>
</Column>
<Column filterProperty="Ktext">
<m:Text text="Auftrag"/>
<template>
<m:Text text="{Ktext}" wrapping="false" />
</template>
</Column>
</columns>
<dragDropConfig>
<dnd:DragInfo groupName="moveToTable1" sourceAggregation="rows" dragStart="onDragStart"/>
<dnd:DropInfo groupName="moveToTable2" targetAggregation="rows" dropPosition="Between" drop="onDropTable2"/>
<dnd:DragDropInfo sourceAggregation="rows" targetAggregation="rows" dropPosition="Between" dragStart="onDragStart" drop="onDropTable2"/>
</dragDropConfig>
</Table>
</m:HBox>
</m:content>
</m:Dialog>
thats my fragment.. on table1 there is a Searchfield and it works.. like it should.
on my second table on table2 this does not work..
and i dont really know why.. the one is a json model the other not.. maybe thats why?
controller
onFilterAllOrder: function (oEvent) {
var oTable = this.byId("table1");
var searchText = oEvent.getParameters().newValue;
var filters = [];
if (searchText.trim() != '') {
var filter1 = new sap.ui.model.Filter({
path: "Ktext",
operator: sap.ui.model.FilterOperator.Contains,
value1: searchText
});
filters = [filter1];
var finalFilter = new sap.ui.model.Filter({
filters: filters,
and: false
});
oTable.getBinding("rows").filter(finalFilter, sap.ui.model.FilterType.Application);
} else {
oTable.getBinding("rows").filter([], sap.ui.model.FilterType.Application);
}
},
onFilterSelectedOrder: function (oEvent) {
var oTable = this.byId("table2");
var searchText = oEvent.getParameters().newValue;
var filters = [];
if (searchText.trim() != '') {
var filter1 = new sap.ui.model.Filter({
path: "Ktext",
operator: sap.ui.model.FilterOperator.Contains,
value1: searchText
});
filters = [filter1];
var finalFilter = new sap.ui.model.Filter({
filters: filters,
and: false
});
oTable.getBinding("rows").filter(finalFilter, sap.ui.model.FilterType.Application);
} else {
oTable.getBinding("rows").filter([], sap.ui.model.FilterType.Application);
}
}
so maybe i dont see something? or make some mistakes? so i try everything.. but nothing work.. i mean it should be the same as the one before but somehow it dont work...
If the latter is a OData model, the filtering would be done against the service if you have not set the operation mode to client. In this case, a request against the backend is made and if that service does ignore $filter, you'll see no change.
Check the network tab and look if a request is made.

Table Not Getting Refreshed After Deleting a Row

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.

How to set focus on an Input field in a sap.ui.table.Table

I want to set the focus on a input field in a row in the table. How can I read the Id of this row and set the focus?
for(var i = 0; i < rowCount; i++) {
var oEntry = this.getView().getModel("items").getProperty(
oTable.getContextByIndex(i).sPath);
if (oEntry.Field1 === sField1){
//Here I will set the focus in an Input field
}
}
Thanks
Edit:
<columns>
<Column width="2rem" sortProperty="Field">
<m:Label text="{i18n>Field}" />
<template>
<m:CheckBox
selected="{
path: 'items>Field',
type: 'sap.ui.model.type.String'
}"
editable="false" />
</template>
</Column>
<Column width="6rem">
<m:Label text="{i18n>Field1}" />
<template>
<m:Text text="{items>Field1}" />
</template>
</Column>
<Column width="6rem">
<m:Label text="{i18n>Field2}" />
<template>
<m:Input
value="{items>Field2}" />
</template>
</Column>
This are the columns of my table in the view: I want to get the focus on the line, where Field1 = s.Field1. How can I set the id in a special line ?
Edit 2.0:
XML View:
<Column width="6rem">
<m:Label text="{i18n>Field2}" />
<template>
<m:Input
id="input2" value="{items>Field2}"/>
</template>
</Column>
Controller:
for(var i = 0; i < rowCount; i++) {
var oEntry = this.getView().getModel("items").getProperty(
oTable.getContextByIndex(i).sPath);
if (oEntry.Field1 === sField1){
this.getView().byId("input2").focus();
}
}
this.getView().getModel("items").refresh(true);
You also could do something like following:
var oTable = this.getView().byId("idTable");
var aRows = oTable.getRows();
for (var i = 0; i < aRows.length; i++) {
if (aRows[i].getBindingContext().getObject().Field1 === sField1) {
var oCell = aRows[i].getCells()[2]; // select 3rd cell
oCell.focus(); // focus on the Input field
break;
}
}
You could try getting the view through its ID and then use the focus() function to set the focus to it.
For example,
var oInput = new sap.m.Input({id: "inputID"})
.addEventDelegate({
onAfterRendering: function(){
oInput.focus();
}
});
or if your input has an id, say "input1" then you can do this
this.getView().byId("input1").focus();
EDIT:
Assuming input is the element you want to ID then it's simple to do so,
<Column width="6rem">
<m:Label text="{i18n>Field2}" />
<template>
<m:Input
value="{items>Field2}"
id="input1" />
</template>
</Column>

SAPUI5: Refreshing table contents after oData.read

Im building an application with two textboxes, a button and a table. On pressing the button, an array of filters is composed from the contents of the textboxes and sent to my oData service in a read request. Right now, when one record is returned (as it shows in the console), the table will not be updated. What am I missing?
This is the table:
<Table id="PLTab" items="{/ORDSET}">
<headerToolbar>
<Toolbar>
<Title text="Planned Orders" level="H2" />
</Toolbar>
</headerToolbar>
<columns>
<Column>
<Text text="Product" />
</Column>
<Column>
<Text text="Planned Order" />
</Column>
<Column>
<Text text="Production Planner" />
</Column>
</columns>
<items>
<ColumnListItem>
<cells>
<ObjectIdentifier title="{Maktx}" text="{Matnr}" />
<Text text="{Ordno}" />
<Text text="{Name}" />
</cells>
</ColumnListItem>
</items>
</Table>
And this is the relevant part of the controller:
onInit: function() {
var oModel = this.getOwnerComponent().getModel("path");
oModel.refresh(true);
this.getView().setModel(oModel);
},
openOrders: function(oEvent) {
var PLFilters = [];
PLFilters.push(new sap.ui.model.Filter({
path: "Matnr",
operator: sap.ui.model.FilterOperator.EQ,
value1: this.getView().byId("Product").getValue()
}));
PLFilters.push(new sap.ui.model.Filter({
path: "Locno",
operator: sap.ui.model.FilterOperator.EQ,
value1: this.getView().byId("Location").getValue()
}));
var oModel = this.getOwnerComponent().getModel("path");
oModel.read("/ORDSET", {
filters: PLFilters,
success: function(oData, oResponse) {
console.log(oData);
}
});
}
Thanks & regards,
Max
var oModel = this.getOwnerComponent().getModel("path");
You use the model named "path" to read data, but in your XML View you use the default model (unnamed).
Try to change to
var oModel = this.getOwnerComponent().getModel();