JSFiddle - React, Tailwind, and code Playground
by g
HTML
<script src="https://github.com/downloads/SteveSanderson/knockout/knockout-1.3.0beta.js"></script>
<ul data-bind="foreach: items">
<li><input type="text" data-bind="value: attemptedValue"/></li>
</ul>
<a data-bind="click: addItem">ADD ITEM</a>
<a data-bind="click: print">PRINT</a>
JavaScript
var viewModel = { items: function(){ return []; }};
var Item = function(item) {
var self = this;
this.value = ko.observable();
this.attemptedValue = ko.dependentObservable({
read: function(){
return self.value();
},
write: function(newValue) {
var oldValue = self.value();
if(oldValue === newValue) { return;}
var cleanValue = newValue.trim().replace(/_/g, ' ') || oldValue;
var allValues = ko.utils.arrayMap(viewModel.items(), function(i) {
var val = i.value();
if(val != oldValue)
return val;
});
if(allValues.indexOf(cleanValue) > -1) {
var m = cleanValue.match(/\W\d$/);
if(m){
cleanAlias = cleanValue.slice(0,-2);
}
var index = 2;
cleanValue = cleanValue + ' ' + index
while(allValues.indexOf(cleanValue) > -1){
index++;
cleanValue = cleanValue.slice(0,-1) + index;
}
}
self.value(cleanValue);
}
});
this.attemptedValue(item.value);
};
viewModel = {
items: ko.observableArray([
new Item({ value: 'Name' }),
]),
addItem: function() {
this.items.push(new Item({ value: 'Name' }))
},
print: function(){ alert(ko.toJSON(viewModel));}
};
ko.applyBindings(viewModel);