Fixes bug 28309: Editing a record that was just created in grid works properly
authorAugusto Mauch <augusto.mauch@openbravo.com>
Tue, 02 Dec 2014 17:05:27 +0100
changeset 25480 e976b465ba65
parent 25479 0c39b04ae731
child 25481 d60c4bb642ea
Fixes bug 28309: Editing a record that was just created in grid works properly

There were two problems when a record that was being created in the grid was opened in form view (the only way to do this is by pressing Ctrl+<F2> while creating the record):
- If the user had not entered all the mandatory fields in the grid, then after saving the record was saved in the form view, two new record would appear in the grid
- If the user had entered all the mandatory fields in the grid before pressing <F2>, then the record would be saved in the database before being open in form view.

To fix this, when a record that is being created in grid view is opened in form view by pressing <F2>:
- The record is not saved even if all the mandatory fields had been entered
- No FIC request in NEW mode is done

After doing this there were two problems:
- The valuemaps were not properly loaded in the form view. To fix this, they are copied from the grid edit form to the form view
- If the addition was canceled in the form view, an empty row would be shown in grid view. To fix this, that empty line is removed from the grid view when the addition is cancelled.
modules/org.openbravo.client.application/web/org.openbravo.client.application/js/form/ob-view-form.js
modules/org.openbravo.client.application/web/org.openbravo.client.application/js/grid/ob-view-grid.js
modules/org.openbravo.client.application/web/org.openbravo.client.application/js/main/ob-standard-view.js
--- a/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/form/ob-view-form.js	Fri Nov 28 09:19:52 2014 +0100
+++ b/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/form/ob-view-form.js	Tue Dec 02 17:05:27 2014 +0100
@@ -185,7 +185,7 @@
     }
   },
 
-  editRecord: function (record, preventFocus, hasChanges, focusFieldName, isLocalTime) {
+  editRecord: function (record, preventFocus, hasChanges, focusFieldName, isLocalTime, wasEditingGrid) {
     var timeFields, ret;
     this.clearValues();
     // if editRecord is called from OBStandardView.editRecord, then the time fields have already
@@ -204,7 +204,7 @@
       this.forceFocusedField = focusFieldName;
     }
 
-    this.doEditRecordActions(preventFocus, record._new);
+    this.doEditRecordActions(preventFocus, record._new, wasEditingGrid);
 
     if (hasChanges) {
       this.setHasChanged(true);
@@ -215,7 +215,7 @@
     return ret;
   },
 
-  doEditRecordActions: function (preventFocus, isNew) {
+  doEditRecordActions: function (preventFocus, isNew, wasEditingGrid) {
     delete this.contextInfo;
 
     this.initializing = true;
@@ -253,7 +253,7 @@
     this.ignoreFirstFocusEvent = preventFocus;
 
     // retrieveinitialvalues does focus and clear of errors
-    this.retrieveInitialValues(isNew);
+    this.retrieveInitialValues(isNew, wasEditingGrid);
 
     if (isNew) {
       this.view.statusBar.mode = 'NEW';
@@ -598,7 +598,7 @@
 
   },
 
-  retrieveInitialValues: function (isNew) {
+  retrieveInitialValues: function (isNew, wasEditingGrid) {
     var parentId = this.view.getParentId(),
         i, fldNames = [],
         requestParams, allProperties, parentColumn, me = this,
@@ -664,47 +664,72 @@
       editRow: this.view.viewGrid.getEditRow()
     } : null;
 
-    this.inFicCall = true;
+    // do not make a request to the FIC in NEW mode if:
+    // - the record is new and
+    // - the record was being edited in the grid
+    if (!isNew || !wasEditingGrid) {
+      this.inFicCall = true;
+      OB.RemoteCallManager.call('org.openbravo.client.application.window.FormInitializationComponent', allProperties, requestParams, function (response, data, request) {
+        // no focus item found, focus on the body of the grid
+        // this makes sure that keypresses end up in the 
+        // bodyKeyPress method
+        if (!me.getFocusItem() || !me.getFocusItem().isFocusable()) {
+          me.view.viewGrid.body.focus();
+        }
 
-    OB.RemoteCallManager.call('org.openbravo.client.application.window.FormInitializationComponent', allProperties, requestParams, function (response, data, request) {
+        me.processFICReturn(response, data, request, gridEditInformation);
 
-      // no focus item found, focus on the body of the grid
-      // this makes sure that keypresses end up in the 
-      // bodyKeyPress method
-      if (!me.getFocusItem() || !me.getFocusItem().isFocusable()) {
-        me.view.viewGrid.body.focus();
+        if (!this.grid || !gridEditInformation || this.grid.getEditRow() !== gridEditInformation.editRow) {
+          // remember the initial values, if we are still editing the same row
+          me.rememberValues();
+        }
+        me.initializing = false;
+
+        // do here because during initial form drawing
+        // fields get blurred and will show an error
+        me.clearErrors(true);
+
+        // only compute a new focus item if the form is active
+        if (me.view.isActiveView()) {
+          me.computeFocusItem();
+        }
+
+        // if the focus item is not really enabled
+        // then find a new one, even if the form is not active
+        if (me.getFocusItem() && !me.getFocusItem().isFocusable(true)) {
+          me.computeFocusItem(me.getFocusItem());
+        }
+        // note the focus is set in the field when the FIC call
+        // returns
+        // at this point select the focused value      
+        if (me.getFocusItem()) {
+          initializingForm = true;
+          me.setFocusInForm(initializingForm);
+        }
+      });
+    } else {
+      // enable the grid (this would have been done in the processFICReturn function)
+      this.disableForm(false);
+      // copy the value maps from the grid edit form
+      this.copyValueMaps();
+      this.markForRedraw();
+    }
+  },
+
+  // use the grid valueMaps to populate the valueMaps of the form
+  copyValueMaps: function () {
+    var itemName, item, storedValueMaps = this.view.viewGrid.storedValueMaps;
+    if (!storedValueMaps) {
+      return;
+    }
+    for (itemName in storedValueMaps) {
+      if (storedValueMaps.hasOwnProperty(itemName)) {
+        item = this.getItem(itemName);
+        if (item) {
+          item.setValueMap(storedValueMaps[itemName]);
+        }
       }
-
-      me.processFICReturn(response, data, request, gridEditInformation);
-
-      if (!this.grid || !gridEditInformation || this.grid.getEditRow() !== gridEditInformation.editRow) {
-        // remember the initial values, if we are still editing the same row
-        me.rememberValues();
-      }
-      me.initializing = false;
-
-      // do here because during initial form drawing
-      // fields get blurred and will show an error
-      me.clearErrors(true);
-
-      // only compute a new focus item if the form is active
-      if (me.view.isActiveView()) {
-        me.computeFocusItem();
-      }
-
-      // if the focus item is not really enabled
-      // then find a new one, even if the form is not active
-      if (me.getFocusItem() && !me.getFocusItem().isFocusable(true)) {
-        me.computeFocusItem(me.getFocusItem());
-      }
-      // note the focus is set in the field when the FIC call
-      // returns
-      // at this point select the focused value      
-      if (me.getFocusItem()) {
-        initializingForm = true;
-        me.setFocusInForm(initializingForm);
-      }
-    });
+    }
   },
 
   rememberValues: function () {
@@ -1482,7 +1507,7 @@
     var i, flds = this.getFields(),
         length = flds.length,
         doClose = !this.hasChanged;
-
+    this.removeRecordFromGridIfNew();
     if (doClose) {
       this.doClose();
       return;
@@ -1507,6 +1532,22 @@
     this.view.toolBar.updateButtonState(true);
   },
 
+  // if a record has been created in the grid and then edited in the form without having been saved first, 
+  // it should be removed from the grid if the edition is canceled in the form
+  removeRecordFromGridIfNew: function () {
+    var values = this.getValues(),
+        grid;
+    // the property _new will only be true if the record has been created in the grid and is being edited
+    // in the form without having been saved 
+    if (values._new) {
+      grid = this.view.viewGrid;
+      // the record addition is being cancelled, remove the record from the grid if possible
+      if (isc.isA.ResultSet(grid.data) && grid.data.find('id', values[OB.Constants.ID])) {
+        grid.data.localData.remove(grid.data.find('id', values[OB.Constants.ID]));
+      }
+    }
+  },
+
   doClose: function () {
     if (this.view.isShowingTree) {
       this.view.treeGrid.refreshRecord(this.getValues());
--- a/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/grid/ob-view-grid.js	Fri Nov 28 09:19:52 2014 +0100
+++ b/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/grid/ob-view-grid.js	Tue Dec 02 17:05:27 2014 +0100
@@ -1434,9 +1434,22 @@
     OB.KeyboardManager.Shortcuts.set('ViewGrid_EditInGrid', 'OBViewGrid.body', ksAction_EditInGrid);
 
     ksAction_EditInForm = function () {
+      var wasEditingGrid = false,
+          autoSaveEditsBackup = me.autoSaveEdits,
+          recordToEdit;
       if (me.getSelectedRecords().length === 1) {
+        if (me.view.isEditingGrid) {
+          wasEditingGrid = true;
+          me.autoSaveEdits = false;
+          recordToEdit = me.getEditedRecord(me.getEditRow());
+        } else {
+          recordToEdit = me.getSelectedRecords()[0];
+        }
+        me.storeValueMaps();
         me.endEditing();
-        me.view.editRecord(me.getSelectedRecords()[0]);
+        me.autoSaveEdits = autoSaveEditsBackup;
+        me.view.editRecord(recordToEdit, null, null, wasEditingGrid);
+        delete me.storedValueMaps;
         return false; // To avoid keyboard shortcut propagation
       } else {
         return true;
@@ -1447,6 +1460,21 @@
     this.Super('enableShortcuts', arguments);
   },
 
+  storeValueMaps: function () {
+    var i, items, editForm = this.getEditForm(),
+        item;
+    if (!editForm) {
+      return;
+    }
+    this.storedValueMaps = {};
+    items = editForm.getItems();
+    for (i = 0; i < items.length; i++) {
+      if (items[i].valueMap) {
+        this.storedValueMaps[items[i].name] = items[i].valueMap;
+      }
+    }
+  },
+
   deselectAllRecords: function (preventUpdateSelectInfo, autoSaveDone) {
     // if there is nothing to deselect then don't deselect
     if (!this.getSelectedRecord()) {
--- a/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/main/ob-standard-view.js	Fri Nov 28 09:19:52 2014 +0100
+++ b/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/main/ob-standard-view.js	Tue Dec 02 17:05:27 2014 +0100
@@ -1439,8 +1439,8 @@
   // ** {{{ editRecord }}} **
   // Opens the edit form and selects the record in the grid, will refresh
   // child views also
-  editRecord: function (record, preventFocus, focusFieldName) {
-    var rowNum,
+  editRecord: function (record, preventFocus, focusFieldName, wasEditingGrid) {
+    var rowNum, recordToEdit,
     // at this point the time fields of the record are formatted in local time
     localTime = true;
     this.messageBar.hide();
@@ -1456,10 +1456,17 @@
     } else {
       this.viewGrid.doSelectSingleRecord(record);
 
-      // also handle the case that there are unsaved values in the grid
+      // also handle the case that there are unsaved values in the grid 
       // show them in the form
       rowNum = this.viewGrid.getRecordIndex(record);
-      this.viewForm.editRecord(this.viewGrid.getEditedRecord(rowNum), preventFocus, this.viewGrid.recordHasChanges(rowNum), focusFieldName, localTime);
+      // If the record to be edited is new and was being edited in the grid, use it,
+      // because this.viewGrid.getEditedRecord would return an empty record in this case
+      if (record._new && wasEditingGrid) {
+        recordToEdit = record;
+      } else {
+        recordToEdit = this.viewGrid.getEditedRecord(rowNum);
+      }
+      this.viewForm.editRecord(recordToEdit, preventFocus, this.viewGrid.recordHasChanges(rowNum), focusFieldName, localTime, wasEditingGrid);
     }
   },