Skip to Content

Introduction & Recap

In the previous blog post, we learned how to create a second level of drill-down (detail of a detail) and how to interact with OData and ODataModel (v2) in order to delete a database record.

What will be covered on this exercise

With Part 5 of this series of blog posts, we will learn how to create a SimpleForm within a Dialog that will allow us to update the information of a Sales Order Item.

Before updating the database order we have to check that everything typed by the user validates our constraints.

  • ODataModel: we have already used it to display server-side information about our Business Partner, Sales Order, and Sales Order Items. We’ve also used it to delete a database record. We’re now going to use it to update a record thanks to the submitChanges method or remove what we’ve done with the resetChanges method.
  • Expression Binding: an enhancement of the SAPUI5 binding syntax, which allows for providing expressions instead of custom formatter functions
  • SimpleForm: a layout that allows users to create a pixel-perfect form

So our main task here is to allows the user to edit a Sales Order Item and submit those changes (if made) to the backend system.

Here’s a list of the things you have to do to get to the final result:

  • Add a new column to the table to display the Note value (that’s the field we’re going to update)
  • Make the Product Name active (titleActive=”true”) and handle the titlePress event
  • Create a Fragment with inside a Dialog that contains our SimpleForm
  • The SimpleForm will contain a Label/Input couple for each of our Sales Order Item fields
  • All the Input fields won’t be editable except for the Note one
  • Make the Save button of the dialog enabled only if the Note typed by the user has a length greater than zero
  • Handle the save button submitting all the user changes!

Let’s code

UI/UX

We’ve already talked a lot about the UI/UX in this series of blog post. As you already understood this is an important topic for me. A good UX could make a huge difference at the end of the day allowing the end-user to boost his performance and reduce the overall errors he could make.

That’s why you should always, always provide feedback to the user. Clear, intuitive, well-made feedback

Take for instance this screen:

Why is the Save button disabled? Why can’t the user complete the task?

A good UX gives feedback clearly to the user. You should always ask you these questions:

  • Is the user aware that he’s missing some required information?
  • Can the user understand which information is missing or have invalid values?
  • I’m helping the user to fix those errors?
  • When the user has fixed the error am I correctly giving he feedback back (green highlight, enable the Save button)

So now the user knows what he should do. What happens when he has typed the correct new Note value and clicked the “Save” button?

  • We check if the user has submitted some changes (changed values to the model). If there are no changes we just alert the user otherwise we keep with our bullet-point list of task to do
  • Set the Dialog to busy state
  • Ask the framework to deliver all the changes with submitChanges
  • Listen to the callbacks in case of success or error
  • Provide visual feedback to the user with an ok or error message
  • Update the Table with the new values (done automagically by SAPUI5)

User Validation

There are many ways to add user validation to your field. In our simple example, I wanted to implement a simple use case to check only if the Note field has been filled or not. If the Note field is empty you should disable the Save button and prompt an error that highlight the Note field and explain the issue.

To do that we need to listen to the liveChange (this event is triggered everytime that a user changes the value) event on the Note Input field and implement it on our Controller like this:

validateNote: function(oEvent) {
  var oResourceBundle = this.getView().getModel("i18n").getResourceBundle();
  var sValue = oEvent.getParameter("value");
  var oSource = oEvent.getSource();
  if( sValue && sValue.trim().length > 0 ) {
    oSource.setValueState(ValueState.Success);
    oSource.setValueStateText(null);
  } else {
    oSource.setValueState(ValueState.Error);
    oSource.setValueStateText(oResourceBundle.getText("errorEmptyNote"));
  }
}

Update OData model record

Here comes the core part of our exercise. When the user clicks the Save button we’re going to execute a method on our Controller side.

onSalesOrderItemDialogSave: function(oEvent) {
  var controller = this;
  var oResourceBundle = this.getView().getModel("i18n").getResourceBundle();
  var bCompact = !!this.getView().$().closest(".sapUiSizeCompact").length;

  var oModel = this.getView().getModel();
  if( oModel.hasPendingChanges() ) {
    controller._oEditDialog.setBusy(true);
    oModel.submitChanges({
      success: function(oData) {
        MessageBox.success( oResourceBundle.getText("saveSaleItemSuccess"), {
          styleClass: bCompact ? "sapUiSizeCompact" : ""
        });
        controller._oEditDialog.setBusy(false);
        controller._oEditDialog.close();
      },
      error: function(oError) {
        MessageBox.error( oResourceBundle.getText("saveSaleItemError"), {
          styleClass: bCompact ? "sapUiSizeCompact" : ""
        });
        controller._oEditDialog.setBusy(false);
        controller._oEditDialog.close();
      }
    });
  } else {
    MessageBox.success( oResourceBundle.getText("saveSaleItemNoChanges"), {
      styleClass: bCompact ? "sapUiSizeCompact" : ""
    });
    controller._oEditDialog.close();
  }
}

The code is pretty simple and we don’t need to specify too many parameters. The only thing to remember is to execute the submitChanges only if the model has some changes to do otherwise your Dialog will be in the busy state at infinite because the success/error callback (I think for a framework bug) won’t be called.

Conclusion and what’s next?

If you want to check out the final result you can directly go to the step_5 branch of our GitHub Project.

The next part I think will cover test but I think that I will take a little pause from this series because I would like to cover some important things like SplitApp vs FlexibleColumnLayout 😉

But don’t panic, we just talking about some couple of weeks! You have a lot of exercises to finish!

Feedback needed

What do you think about this series? Do you want more focus on some specific SAPUI5 aspect?

Write it down on the comment section! Happy coding to everyone!

To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply