JSFiddle - React, Tailwind, and code Playground
by amitava82
HTML
<script src="http://rniemeyer.github.com/KnockMeOut/Scripts/knockout-latest.debug.js"></script>
<p>
issue: When the select options are read, the inital value gets reset to the first object in the options. How do I keep the original value selected when transitioning to edit mode?
</p>
<div>
<h2>Edit Quote '1001'</h2>
<div class="editor-row" data-bind="with: selectedCustomer">
<label>Customer</label>
<div data-bind="visible: !$root.isEditMode()">
<span data-bind="text: CompanyName"></span>
</div>
<div data-bind="visible: $root.isEditMode()">
<input type="radio" name="customerGroup" value="1" data-bind="checked: id"> Company Name 1
<input type="radio" name="customerGroup" value="2" data-bind="checked: id"> Company Name 2
</div>
</div>
<div class="editor-row">
<label>Project</label>
<div data-bind="visible: !isEditMode()">
<span data-bind="text: selectedProject().Name"></span>
</div>
<div data-bind="visible: isEditMode()">
<select data-bind="options: selectedCustomer().projects, optionsText: 'Name', value: selectedProject"></select>
</div>
</div>
<div>
<button data-bind="click: function() { turnOnEditMode() }">Edit</button>
<button data-bind="click: function() { turnOffEditMode() }">Cancel</button>
</div>
</div>
<hr/>
<div data-bind="text: ko.toJSON($root)"></div>
<!-- inital values from server -->
<div id="customerData" data-id="1" data-companyName="Company Name 1"></div>
<div id="projectData" data-id="13" data-name="project 13"></div>
CSS
h2 { padding:.5em; text-align:center; font-weight:bold; }
.editor-row
{
clear: right;
padding: 1em;
}
.editor-row label
{
display: block;
clear: right;
}
JavaScript
function ajaxCallGetProjectsByCustomer(customerId) {
var database = '[{"CustomerId": 1, "Name":"Company Name 1", "Projects": [ { "ProjectId": "11", "Name": "project 11" }, { "ProjectId": "12", "Name": "project 12" }, { "ProjectId": "13", "Name": "project 13" }] }, {"CustomerId": 2, "Name": "Company Name 2", "Projects": [ { "ProjectId": "21", "Name": "project 21" }, { "ProjectId": "22", "Name": "project 22" }, { "ProjectId": "23", "Name": "project 23" }] }]';
var json = ko.utils.parseJson(database);
//console.log('parseJson(database) - ' + json);
//ko.utils.arrayForEach(json, function(item) {
// console.log('CustomerId: ' + item.CustomerId);
//});
return ko.utils.arrayFirst(json, function(item){
return item.CustomerId == customerId;
});
}
var Customer = function(id, name, projects) {
var self = this;
this.id = ko.observable(id);
this.CompanyName = ko.observable(name);
this.projects = ko.observableArray(ko.utils.arrayMap(projects, function(item) {
return new Project(item.ProjectId, item.Name);
}));
this.id.subscribe(function(){
Customer.load(Number(this.id()));
}, this);
};
Customer.load = function(id) {
var data = ajaxCallGetProjectsByCustomer(id);
var customer = new Customer(
data.CustomerId,
data.Name,
data.Projects);
var oldProjectId = viewModel.selectedProject().id;
viewModel.selectedCustomer(customer);
//******* HERE IS THE MAIN ISSUE *******
// the viewModel.selectedProject instance has been destroyed
// by loading a new customer instance so even though project id 3 may
// be in selectedProject its not the **same** project with id 3 that is in the
// new customer so hence the binding equality comparer fails and it is ignored
// by reselecting the correct istance this can be fixed although it is a hack
var sameProjectDifferentInstance =...