2

I want to revert a select tag value that is inside a ng-repeat after cancelling a confirm dialog.

Here is what I have so far:

Relevant HTML:

<table>
  <tbody>
    <tr ng-repeat="application in rows">
      <td>
        <select
                ng-model="application.selectedVersion"
                ng-options="apk.versionName for apk in application.versions | orderBy : 'id' : true"
                ng-init="application.selectedVersion=application.versions.filter(currentVersion, application.apkUpdates)[0]"
                ng-change="selectionChanged(application, '{{application.selectedVersion}}')"
                style="padding:0 1em;" />
      </td>
    </tr>
  </tbody>
</table>

Javascript logic:

$scope.selectionChanged = function(application, previousVersion) {
  var dialog = confirm('Change version?');

  if (dialog) {
    console.log('change version confirmed');
  } else {
    application.selectedVersion = previousVersion;
  }
};

Passing '{{application.selectedVersion}}' to the function instead of application.selectedVersion passes the previously selected value instead of the current (explained here: https://stackoverflow.com/a/45051464/2596580).

When I change the select value, perform the dialog interaction and cancel it I try to revert the value by setting application.selectedVersion = angular.copy(previousVersion);. I can see the value is correct by debugging the javascript but the select input is set to blank instead of the actual value.

What am I doing wrong?

JSFiddle demo: https://jsfiddle.net/yt4ufsnh/

Netherdan
  • 85
  • 10

2 Answers2

1

You have to correct couple of things in your implementation

  1. When you pass '{{application.selectedVersion}}' to selectionChanged method, it becomes raw string. When you re assigns back to the application.selectedVersion you have to first parse that previousVersion to JSON using JSON.parse method
  2. Use track by apk.id on ng-options collection. This is needed because the JSON parsed object is not recognized as the same instance of the object used to build the select, so this works as if overriding an intrinsic equals function to use only its id property

Final Version

ng-options="apk.versionName for apk in (application.versions | 
                                           orderBy : 'id' : true) track by apk.id" 

Code

$scope.selectionChanged = function(application, previousVersion) {
    var dialog = confirm('Change version?');
    if (dialog) {
      console.log('change version confirmed');
    } else {
      application.selectedVersion = previousVersion ? JSON.parse(previousVersion) : null;
    }
};

Updated Fiddle

Netherdan
  • 85
  • 10
Pankaj Parkar
  • 134,766
  • 23
  • 234
  • 299
  • That works for actually setting the value on the select input but it's setting the current value. What I want is to set the previous value (i.e. cancel the ng-change update to view). I edited the question to clarify this detail. – Netherdan Sep 13 '18 at 18:16
  • 1
    @Netherdan Can you please have a look at updated answer please? – Pankaj Parkar Sep 13 '18 at 19:01
  • I was posting that same answer when I noticed your update. The reason for that is because a JSON parsed object is not equal to the object used to build the select (i.e. `JSON.parse(previousVersion) === application.versions[previousVersionIndex]` returns false) so it doesn't recognize it as the same instance. The `track by` clause forces the tracking of the object by the id value so maybe even a raw JSON.parse("{id:x}") would work, but I don't need to and won't ever do that. Your solution works as expected. Thanks! – Netherdan Sep 13 '18 at 19:38
  • @Netherdan feel free to edit the answer :) I'll accept the edit – Pankaj Parkar Sep 14 '18 at 10:34
0

if you just remove the else condition from your javascript code, you can reach the behaviour you need.

Your final code should be:

$scope.selectionChanged = function(application, previousVersion) {
  var dialog = confirm('Change version?');

  if (dialog) {
    console.log('change version confirmed');
  }
};
Danizavtz
  • 3,166
  • 4
  • 24
  • 25
  • Then the value is updated (the value I selected before the confirm dialog is set as the current value). What I want is to revert this value to the one previously selected. – Netherdan Sep 13 '18 at 18:26