Skip to content

Instantly share code, notes, and snippets.

@bsatrom
Created July 1, 2011 20:07
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save bsatrom/1059292 to your computer and use it in GitHub Desktop.
Save bsatrom/1059292 to your computer and use it in GitHub Desktop.
Moving from markup-based KnockoutJS bindings to unobtrusive bindings (After)
<form id="addSpeaker">
<fieldset>
<legend>Speaker Info</legend>
Name: <input type="text" id="name" /> <br />
Bio: <textarea id="bio"></textarea> <br />
Twitter Handle: <input type="text" id="twitterHandle" /> <br />
State: <input type="text" id="state" /> <br />
Photo Url: <input type="text" id="photoUrl" />
</fieldset>
<fieldset>
<legend>Languages</legend>
New item:
<input type="text" id="languageToAdd" />
<button type="submit" id="addLanguage">Add</button>
<p>Your choices:</p>
<select multiple="multiple" width="50" id="languages"> </select>
</fieldset>
<input type="submit" value="Create" />
<!-- Profile Preview -->
<article id="profilePreview">
<header>
<div><img id="image" /></div>
<div>
<h1>
<span id="displayName"></span> ::
<a id="twitterUrl">
@<span id="displayTwitterHandle"></span>
</a>
</h1>
</div>
<div class="subhead">Programs in <span id="languageList"></span></div>
</header>
<div id="bio">
<span id="displayBio"></span>. He also lives in <span id="displayState"></span>
</div>
</article>
</form>
<form id="addSpeaker">
<fieldset>
<legend>Speaker Info</legend>
Name: <input type="text" id="name" /> <br />
Email: <input type="text" id="email" /> <br />
Bio: <textarea id="bio"></textarea> <br />
Twitter Handle: <input type="text" id="twitterHandle" /> <br />
State: <input type="text" id="state" /> <br />
Photo Url: <input type="text" id="photoUrl" />
</fieldset>
<fieldset>
<legend>Languages</legend>
New item:
<input type="text" id="languageToAdd" />
<button type="submit" id="addLanguage">Add</button>
<p>Your choices:</p>
<select multiple="multiple" width="50" id="languages"> </select>
</fieldset>
<fieldset>
Favorite Topics:
New item:
<input type="text" id="topicToAdd" />
<button type="submit" id="addTopic">Add</button>
<p>Your choices:</p>
<select multiple="multiple" width="50" id="favoriteTopics"> </select>
</fieldset>
<input type="submit" value="Create" />
<!-- Profile Preview -->
<article id="profilePreview">
<header>
<div><img id="image" /></div>
<div>
<h1>
<span id="displayName"></span> ::
<a id="twitterUrl">
@<span id="displayTwitterHandle"></span>
</a>
</h1>
</div>
<div class="subhead">Programs in <span id="languageList"></span></div>
<div class="subhead">Loves to talk about <span id="favoriteTopicsList"></span></div>
</header>
<div id="bio">
<span id="displayBio"></span>. He also lives in <span id="displayState"></span>
</div>
</article>
</form>
var modelBinder = {};
modelBinder.createBindings = function (bindlist) {
function setBinding(id, value) {
var el = document.getElementById(id);
if (el) {
el.setAttribute('data-bind', value);
}
}
for(var inputsKey in bindlist.inputs) {
if (bindlist.inputs.hasOwnProperty(inputsKey)) {
setBinding(bindlist.inputs[inputsKey], 'value: ' + bindlist.inputs[inputsKey]);
}
}
for(var optionsKey in bindlist.options) {
if (bindlist.inputs.hasOwnProperty(optionsKey)) {
setBinding(bindlist.options[optionsKey], 'options: ' + bindlist.options[optionsKey]);
}
}
for(var key in bindlist.custom) {
if (bindlist.custom.hasOwnProperty(key)) {
setBinding(key, bindlist.custom[key]);
}
}
};
var viewModel = {
name: ko.observable(''),
email: ko.observable(''),
bio: ko.observable(''),
twitterHandle: ko.observable(''),
state: ko.observable(''),
photoUrl: ko.observable(''),
languages: ko.observableArray([]),
favoriteTopics: ko.observableArray([]),
averageRating: ko.observable(''),
languageToAdd: ko.observable(''),
topicToAdd: ko.observable('')
};
viewModel.twitterUrl = ko.dependentObservable(function () {
return "http://www.twitter.com/" + viewModel.twitterHandle();
});
viewModel.addLanguage = function () {
if (viewModel.languageToAdd() !== '') {
viewModel.languages.push(viewModel.languageToAdd());
viewModel.languageToAdd('');
}
};
viewModel.addTopic = function () {
if (viewModel.topicToAdd() !== '') {
viewModel.favoriteTopics.push(viewModel.topicToAdd());
viewModel.topicToAdd('');
}
};
viewModel.addSpeaker = function () {
$.ajax({
url: "/speakers/create/",
type: 'post',
data: ko.toJSON(this),
contentType: 'application/json',
success: function (result) { alert(result); }
});
};
var bindings = {
inputs: ['name', 'email', 'bio', 'twitterHandle', 'state', 'photoUrl'],
options: ['languages', 'favoriteTopics'],
custom: {
languageToAdd: 'value: languageToAdd, valueUpdate: "afterkeydown"',
addLanguage: 'enable: languageToAdd().length > 0, click: addLanguage',
topicToAdd: 'value: topicToAdd, valueUpdate: "afterkeydown"',
addTopic: 'enable: topicToAdd().length > 0, click: addTopic',
photo: 'attr: {src: photoUrl, alt: name}',
displayName: 'text: name',
displayState: 'text: state',
displayBio: 'text: bio',
twitterUrl: 'attr: {href: twitterUrl}',
displayTwitterHandle: 'text: twitterHandle',
languageList: 'text: languages',
favoriteTopicsList: 'text: favoriteTopics'
}
};
modelBinder.createBindings(bindings);
ko.applyBindings(viewModel);
var bindings = {
inputs: ['name', 'bio', 'twitterHandle', 'state', 'photoUrl'],
options: ['languages'],
custom: {
languageToAdd: 'value: languageToAdd, valueUpdate: "afterkeydown"',
addLanguage: 'enable: languageToAdd().length > 0, click: addLanguage',
photo: 'attr: {src: photoUrl, alt: name}',
displayName: 'text: name',
displayState: 'text: state',
displayBio: 'text: bio',
twitterUrl: 'attr: {href: twitterUrl}',
displayTwitterHandle: 'text: twitterHandle',
languageList: 'text: languages',
addSpeaker: 'submit: addSpeaker'
}
};
modelBinder.createBindings(bindings);
var modelBinder = {};
modelBinder.createBindings = function (bindlist) {
function setBinding(id, value) {
var el = document.getElementById(id);
if (el) {
el.setAttribute('data-bind', value);
}
}
for(var inputsKey in bindlist.inputs) {
if (bindlist.inputs.hasOwnProperty(inputsKey)) {
setBinding(bindlist.inputs[inputsKey], 'value: ' + bindlist.inputs[inputsKey]);
}
}
for(var optionsKey in bindlist.options) {
if (bindlist.inputs.hasOwnProperty(optionsKey)) {
setBinding(bindlist.options[optionsKey], 'options: ' + bindlist.options[optionsKey]);
}
}
for(var key in bindlist.custom) {
if (bindlist.custom.hasOwnProperty(key)) {
setBinding(key, bindlist.custom[key]);
}
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment