javascript - Unique value validation with Knockout-Validation plugin -


i'm using knockoutjs knockout-validation plugin validate fields on form. i'm having problems validating value unique using native validation rule - unique

i'm using editor pattern ryan niemeyer allow user edit or create location. here's fiddle see problem in entirety.

function location(data, names) {     var self = this;      self.id = data.id;     self.name = ko.observable().extend({ unique: { collection: names }});     // other properties     self.errors = ko.validation.group(self);      // update method left out brevity }  function viewmodel() {     var self = this;      self.locations = ko.observablearray([]);         self.selectedlocation = ko.observable();     self.selectedlocationforediting = ko.observable();      self.names = ko.computed(function(){         return ko.utils.arraymap(self.locations(), function(item) {             return item.name();         });     });        self.edit = function(item) {         self.selectedlocation(item);         self.selectedlocationforediting(new location(ko.tojs(item), self.types));     };      self.cancel = function() {         self.selectedlocation(null);         self.selectedlocationforediting(null);     };      self.update = function(item) {         var selected = self.selectedlocation(),             updated = ko.tojs(self.selectedlocationforediting()); //get clean copy          if(item.errors().length == 0) {             selected.update(updated);             self.cancel();         }         else             alert("error");             };      self.locations(ko.utils.arraymap(seeddata, function(item) {         return new location(item, self.types, self.names());     }));  } 

i'm having issue though. since location being edited "detached" locations observablearray (see location.edit method), when make changes name in detached location value isn't updated in names computed array. when validation rule compares names array return valid state of true since counter ever 1 or 0. (please see knockout-validation algorithm below)

within options argument unique validation rule can pass in property externalvalue. if value not undefined check see if count of matched names greater or equal 1 instead of 2. works except cases when user changes name, goes on field, , goes name , wants change original value. rule sees value exists in names array , returns valid state of false.

here algorithm knockout.validation.js handles unique rule...

function (val, options) {     var c = utils.getvalue(options.collection),         external = utils.getvalue(options.externalvalue),         counter = 0;      if (!val || !c) { return true; }      ko.utils.arrayfilter(ko.utils.unwrapobservable(c), function (item) {         if (val === (options.valueaccessor ? options.valueaccessor(item) : item)) { counter++; }     });     // if value external 1 same value in collection means value not unique     return counter < (external !== undefined && val !== external ? 1 : 2); } 

i've thought using base create custom validation rule keep getting stuck on how handle situation when user wants go original value.

i appreciate , help.

one possible solution not include the name of edit item (of course when creating new item need full list) in unique validator.

so unique check won't triggered when changing location name original value:

self.namesexceptcurrent = function(name){     return ko.utils.arraymap(self.locations(), function(item) {         if (item.name() !== name)             return item.name();     }); }  self.edit = function(item) {     self.selectedlocation(item);     self.selectedlocationforediting(         new location(ko.tojs(item),          self.types,          self.namesexceptcurrent(item.name()))); }; 

demo jsfiddle.


Comments

Popular posts from this blog

android - getbluetoothservice() called with no bluetoothmanagercallback -

sql - ASP.NET SqlDataSource, like on SelectCommand -

ios - Undefined symbols for architecture armv7: "_OBJC_CLASS_$_SSZipArchive" -