Search code examples
angularjsx-editable

Angular XEditable Dialog


I have an AngularJS application in which I use Xeditable in order to modify table values on the fly. I am using a standard method of editing values without showing any buttons and using the blur attribute in order to submit all my changes rapidly and in-line.

<a href="#" buttons="no" blur="submit">{{ myValue }}</a>

Instead of the confirmation being seen as buttons such as on countless examples, they should be only shown in a dialog upon saving (onblur).

Due to user interaction issues, I would like to show a confirmation dialog when a field is changed and then clicked away from (or when the field exits its edit state). Basically something within the "onbeforesave=" attribute.

This is when the confirmation should pop up informing that user that the value was changed and asking if they want to save it or not.

I know how call a function on the onbeforesave event although since it lies within the controller I don't know how to invoke a confirmation dialog.

The basic Steps are as follows:

  1. User Clicks on a table cell value
  2. Cell becomes editable.
  3. User changes the cell value.
  4. User clicks away from the cell.
  5. small confirmation dialog pops up (any user friendly or boostrappy way)
  6. User confirms or cancels the edit which was made.
  7. Rinse / Repeat.

Any help is appreciated.

See current fiddle

UPDATE: My latest attempts lead me to implement angular-dailog-service which solved my initial problem above, but I am still unable to resolve the final part of my original question.

Upon clicking onto a cell, changing a value and clicking away, I receive a dialog window (confirmation) which when I hit YES will call my api and save the value - which works. Upon clicking NO however, my value remains changed in the table. This value now needs to be reverted to the previous value. Any help?

  • I now use a onshow attribute in order to save my current value of the cell being edited to the scope.
  • I use the onbeforesave attribute in order to launch my dialog and perform the Yes/No check.

HTML:

<a href="#" editable-text="myValue" buttons="no" blur="submit" onbeforesave="launchDialog($data)" onshow="onShow($data)" >{{ myValue || 'empty' }}</a>

Controller:

$scope.oldValue = "";

    $scope.onShow = function(data){
      $scope.oldValue = data;
      };

    $scope.launchDialog = function(data) {
      var dlg = null;
      dlg = dialogs.confirm('Value Changed','Do you want to save this change?');
      dlg.result.then(function(btn){

        //TODO: HIT API AND SAVE VALUE

      },function(btn){
        //RESET TO OLD VALUE
        return "";
      });

    };

The final piece of the puzzle if figuring out what needs to happen inside my NO click function (where the RESET TO OLD VALUE is).


Solution

  • I have managed to complete my task by adding xeditable and doing everything as follows, exactly as I wanted from the start. The dialog is launched with the attribute onbeforesave : onbeforesave="launchDialog(this.$editable.name, $data)"

    1. Add x-editable
    2. Create a scope property in my controller to store my old value. This is done on the onShow event.
    3. Add an e-ng-keypress (editable state keypress event)
    4. Make relevant changes in the controller.

    PS: Worrying about how to fill the table data via json at a later stage may complicate things, and you will likely need to create variables for each entry but it is still doable for my purposes.

    HTML:

        <tr data-ng-repeat="item in [1,2]">
                                <td>{{ item }}</td>
                                <td><a href="#" editable-text="avg.jan" e-name="jan" e-ng-keypress="enterpress($event, this.$editable.name)" buttons="no" blur="submit" onbeforesave="launchDialog(this.$editable.name, $data)" onshow="onShow($data)" >{{ avg.jan || 'empty' }}</a></td>
     <td><a href="#" editable-text="avg.jan" buttons="no" blur="submit">{{ avg.jan || 'empty' }}</a></td>
    

    I added a comparative standard td above as well to show the new changes.

    Controller

    The controller will need a few things, somewhere to store and then assign the old variable (if a value is changed and then cancelled). It will also need the Enter keypress detection, saving and the dialogue code.

    $scope.oldValue = "";
    
        $scope.onShow = function(data){
          $scope.oldValue = data;
          };
    
    
        $scope.saveData = function(key, data) {
          //TODO: SAVE DATA TO API
        }
    
        $scope.enterpress = function (e, data) {
          if (e.which === 13) {
            $scope.saveData();
          }
        }
    
        $scope.launchDialog = function(key, data) {
          var dlg = null;
    
          if(data != $scope.oldValue) {
    
            //ON ENTER KEY PRESS SKIP THE DIALOG + SAVE
    
            dlg = dialogs.confirm('Value Changed', 'Do you want to save this change?');
            dlg.result.then(function (btn) {
              //SAVE VALUE
              $scope.saveData(key, data);
    
            }, function (btn) {
              //RESET OLD VALUE
              $scope.avg[key] = $scope.oldValue;
    
            });
          }
        };
    

    Overall im glad I finally figured this out, pulled out a few hairs but it was fun in the end. Hope it serves to help someone with similar requirements: A way in which to extend xeditable functionality.