Skip to Content
Technical Articles

Save your coding efforts on table updates

Hi all,

So i’ve started just relying awesome tricks that my colleague Kosta Sattsaev is showing me. Reason: He says he can’t write blogs. Trust me i’m working on it 😉

This blog I will show you how to save a lot of coding by using your odata model to bind to an update dialog on a table. If you like many of us (including myself) have been using a local jsonmodel to store the changes and then on a save button or similar then merging the data back to the odata model and then submitting it. Well you are in for a treat.

 

You can find the full source here:

Don’t comment on the rest of the code, i’ve just found a sample I could reuse 😉

So most of our coding will continue to be the same as always, we declare a table and create a dialog for handling the update.

<mvc:View
	controllerName="sap.ui.demo.wt.Detail"
	xmlns="sap.m"
	xmlns:core="sap.ui.core" 
	xmlns:mvc="sap.ui.core.mvc">
	<Page title="Territory Details" showNavButton="true" navButtonPress="onBack">
		<content>
    <Button press="onPress" text="Update" />
<Table id="idProductsTable" items="{view>Territories}" mode="SingleSelectMaster">

    <columns>
      <Column>
        <Label text="TerritoryID" />
      </Column>
      <Column>
        <Label text="TerritoryDescription" />
      </Column>
      <Column>
        <Label text="RegionID" />
      </Column>
    </columns>
    <items>
      <ColumnListItem>
        <cells>
          <Text text= "{view>TerritoryID}" />
          <Text text= "{view>TerritoryDescription}" />
          <Text text= "{view>RegionID}" />
        </cells>
      </ColumnListItem>
    </items>
  </Table>
		</content>
	</Page>
</mvc:View>

Normally your code for opening the fragment would be similar to this.

onPress: function(){
     	var oView = this.getView();
			var oDialog = oView.byId("dlgUpdate");
			// create dialog lazily
			if (!oDialog) {
				oDialog = sap.ui.xmlfragment(oView.getId(), "sap.ui.demo.wt.update", this);
				oView.addDependent(oDialog);
			}
			oDialog.open();
    },

 

Then in your fragment, you would have a local jsonmodel to bind the values and changes to, in case you needed to cancel etc.

But we can do all of this on our odatamodel. So we make a slight change to the opening of the dialog, where we bind the path of our selected item to the dialog, then we can work on the relative path from there.

  onPress: function(){
     	var oView = this.getView();
			var oDialog = oView.byId("dlgUpdate");
			// create dialog lazily
			if (!oDialog) {
				oDialog = sap.ui.xmlfragment(oView.getId(), "sap.ui.demo.wt.update", this);
				oView.addDependent(oDialog);
        
      }
      
      oDialog.bindElement({
        path: this.byId("idProductsTable").getSelectedItem().getBindingContext("view").getPath(),
        model: "view"
      }); 

     oDialog.open();
    },

Our fragment code is quite simple, absolutely no magic here as we just bind to the default stuff from our table.:

<core:FragmentDefinition xmlns:layout="sap.ui.layout" xmlns:f="sap.ui.layout.form" xmlns:core="sap.ui.core" xmlns="sap.m">
	<Dialog id="dlgUpdate" title="Update Vaccination">
		<content>
			<f:SimpleForm editable="false" layout="ResponsiveGridLayout" labelSpanXL="4" labelSpanL="3" labelSpanM="4" labelSpanS="12"
				adjustLabelSpan="false" emptySpanXL="0" emptySpanL="4" emptySpanM="0" emptySpanS="0" columnsXL="2" columnsL="1" columnsM="1"
				singleContainerFullSize="false">
				<f:content>
					<Label text="Territory" />
					<Input value="{view>TerritoryID}"/>
					<Label text="TerritoryDescription" required="true" />
					<Input value="{view>TerritoryDescription}" />
					<Label text="RegionID" required="true" />
					<Input value="{view>RegionID}" />
				</f:content>
			</f:SimpleForm>
		</content>
		<buttons>
			<Button text="Update" press="onUpdate"
			/>
			<Button text="Cancel" press="onCancelUpdate"/>
		</buttons>
	</Dialog>
</core:FragmentDefinition>

 

No on our cancel button, we just reset the changes for the binding context path, if there is any changes that is.

    /**
		 * Closes the update PosReq dialog
		 * @returns {void}
		 */
		onCancelUpdate: function () {
			const oDialog = this.byId("dlgUpdate");
			if (this.getView().getModel("view").hasPendingChanges()) {
        this.getView().getModel("view").resetChanges([oDialog.getBindingContext("view").getPath()]);			}
			oDialog.close();
    }, 

 

And on our update we can just submit our changes if we wanted to save at this point.

 

    onUpdate: function(){
      this.getView().getModel("view").submitChanges();
      this.onCancelUpdate();
    }

 

That’s it! Your result will be similar to this (The update doesn’t work in the video as i’m using the northwind service):

 

4 Comments
You must be Logged on to comment or reply to a post.
  • Hello, thanks for the information!

     

    So, when you fire the submit changes, you are making an Update OData call? you don’t have to build it?

     

    Regards!

    • Hi.

      That is correct. All your changes are captured in the odata model and submit changes just sends it all in a batch request. Even if you used it for create as well it would work. For you to use create all you need to do is use the createentry method if the odata model to get your binding context.

       

       

       

       

       

       

        • Hi Dhanasupriya,

          Please create a question in the Q&A section, also please add in your source code. It’s not easy for me to know what is wrong, when you just say it isn’t working.