Created
June 3, 2011 18:03
-
-
Save joelnet/1006808 to your computer and use it in GitHub Desktop.
Unobtrusive Knockout support library for jQuery
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Choose a ticket class: <select id="tickets"></select> | |
<p id="ticketOutput"></p> | |
<script id="ticketTemplate" type="text/x-jquery-tmpl"> | |
{{if chosenTicket}} | |
You have chosen <b>${ chosenTicket().name }</b> | |
($${ chosenTicket().price }) | |
<button data-bind="click: resetTicket">Clear</button> | |
{{/if}} | |
</script> | |
<script type="text/javascript"> | |
var viewModel = { | |
tickets: [ | |
{ name: "Economy", price: 199.95 }, | |
{ name: "Business", price: 449.22 }, | |
{ name: "First Class", price: 1199.99 } | |
], | |
chosenTicket: ko.observable(), | |
resetTicket: function() { this.chosenTicket(null) } | |
}; | |
$("#tickets").dataBind({ | |
options: "tickets", | |
optionsCaption: "'Choose...'", | |
optionsText: "'name'", | |
value: "chosenTicket" | |
}); | |
$("#ticketOutput").dataBind({ template: "'ticketTemplate'" }); | |
ko.applyBindings(viewModel); | |
</script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @preserve Unobtrusive Knockout support library for jQuery | |
* | |
* @author Joel Thoms | |
* @version 1.1 | |
*/ | |
(function($) { | |
if (!$ || !$['fn']) throw new Error('jQuery library is required.'); | |
/** | |
* Private method to recursively render key value pairs into a string | |
* | |
* @param {Object} options Object to render into a string. | |
* @return {string} The string value of the object passed in. | |
*/ | |
function render(options) { | |
var rendered = []; | |
for (var key in options) { | |
var val = options[key]; | |
switch (typeof val) { | |
case 'string': rendered.push(key + ':' + val); break; | |
case 'object': rendered.push(key + ':{' + render(val) + '}'); break; | |
case 'function': rendered.push(key + ':' + val.toString()); break; | |
} | |
} | |
return rendered.join(','); | |
} | |
/** | |
* jQuery extension to handle unobtrusive Knockout data binding. | |
* | |
* @param {Object} options Object to render into a string. | |
* @return {Object} A jQuery object. | |
*/ | |
$['fn']['dataBind'] = $['fn']['dataBind'] || function(options) { | |
return this['each'](function() { | |
var opts = $.extend({}, $['fn']['dataBind']['defaults'], options); | |
var attr = render(opts); | |
if (attr != null && attr != '') { | |
$(this)['attr']('data-bind', attr); | |
} | |
}); | |
}; | |
})(jQuery); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Unobtrusive Knockout support library for jQuery | |
@author Joel Thoms | |
@version 1.1 | |
*/ | |
(function(a){function e(a){var b=[],c;for(c in a){var d=a[c];switch(typeof d){case "string":b.push(c+":"+d);break;case "object":b.push(c+":{"+e(d)+"}");break;case "function":b.push(c+":"+d.toString())}}return b.join(",")}if(!a||!a.fn)throw Error("jQuery library is required.");a.fn.dataBind=a.fn.dataBind||function(f){return this.each(function(){var b=a.extend({},a.fn.dataBind.defaults,f),b=e(b);b!=null&&b!=""&&a(this).attr("data-bind",b)})}})(jQuery); |
jwize
commented
May 24, 2012
via email
Hi Joel,
It seems that I have confirmed that the example you mentioned, "you can
even do this..." doesn't work.
```
$('#fullName').dataBind({
value: 'SelectedCard().CardData.FullName',
cardValueChanged : "SelectedCard().CardData.FullName",
visible: "mode() == 'edit' && isMyCard()",
valueUpdate : "'afterkeydown'",
event : { load : function() {
$("#fullName").addClass("formElement");
$("#fullName").addClass("card-data");
$("#fullName").addClass("fullName");
}}
});
```
On Wed, May 23, 2012 at 4:01 PM, Jaime Weise ***@***.*** wrote:
oops pasted twice
On Wed, May 23, 2012 at 3:13 PM, Jaime Weise ***@***.*** wrote:
> Hi Joel,
>
> Okay, somehow I didn't realize that code like this would work:
>
> ```
> viewModel = {};
> $(document).ready(function () {
> var settings = {
> css: { drag: "'true'", selectedElement: "'true'" }
> };
> $("#one").dataBind(settings);
> ko.applyBindings(viewModel);
> });
> ```
>
> I assumed that I could only put a single css object in the settings. So I
> just have to write code to combine those objects as needed.
>
> On Wed, May 23, 2012 at 2:58 PM, joelnet <
> ***@***.***
>
> > wrote:
> >
> > I'd create a custom combine function that can handle all of this that is
> > separate from the data-bind.
> > ---
> >
> > Reply to this email directly or view it on GitHub:
> > https://gist.github.com/1006808
> ##
>
> *
> Jaime Weise
> *
> Technical Director
>
> MOBILE 778 319 1739
> OFFICE 604 568 2812
> TOLL FREE 1 877 568 2812
>
> EMAIL ***@***.***
> URL www.ellev8.ca
>
> ```
> *
> ```
>
> WARNING: This Electronic communication is protected pursuant to relevant
> international treaties and domestic laws, and is legally privileged. The
> information that is contained within this communication is intended ONLY
> for the individual and/or entity who is the intended recipient, and YOU ARE
> HEREBY ON NOTICE THAT any dissemination, distribution, copying, or other
> use of this communication by anyone other than the intended recipient in an
> unauthorized manner is strictly prohibited by law. IF YOU HAVE RECEIVED
> THIS MESSAGE IN ERROR, PLEASE CONTACT THE SENDER IMMEDIATELY!
> *
##
*
Jaime Weise
*
Technical Director
MOBILE 778 319 1739
OFFICE 604 568 2812
TOLL FREE 1 877 568 2812
EMAIL ***@***.***
URL www.ellev8.ca
```
*
```
WARNING: This Electronic communication is protected pursuant to relevant
international treaties and domestic laws, and is legally privileged. The
information that is contained within this communication is intended ONLY
for the individual and/or entity who is the intended recipient, and YOU ARE
HEREBY ON NOTICE THAT any dissemination, distribution, copying, or other
use of this communication by anyone other than the intended recipient in an
unauthorized manner is strictly prohibited by law. IF YOU HAVE RECEIVED
THIS MESSAGE IN ERROR, PLEASE CONTACT THE SENDER IMMEDIATELY!
*
##
*
Jaime Weise
*
Technical Director
MOBILE 778 319 1739
OFFICE 604 568 2812
TOLL FREE 1 877 568 2812
EMAIL [email protected]
URL www.ellev8.ca
```
*
```
WARNING: This Electronic communication is protected pursuant to relevant
international treaties and domestic laws, and is legally privileged. The
information that is contained within this communication is intended ONLY
for the individual and/or entity who is the intended recipient, and YOU ARE
HEREBY ON NOTICE THAT any dissemination, distribution, copying, or other
use of this communication by anyone other than the intended recipient in an
unauthorized manner is strictly prohibited by law. IF YOU HAVE RECEIVED
THIS MESSAGE IN ERROR, PLEASE CONTACT THE SENDER IMMEDIATELY!
*
what isn't working? what is "fullName"? Is that a text field? if so, I don't believe "load" is a valid event. Can you use chrome's element inspector to look inside "fullName" to see what the data-bind attribute generated is?
http://www.threetipsaday.com/2008/12/debug-inspect-google-chrome-inspector/
Thanks again Joel for your time,
I understand what you are saying and in my event handler load is a valid
event of my input.
This code works and is acceptable.
```
$('#fullName,#_title,#phone,#company').each(function() {
var id = this.id;
var propName = (id.charAt(0).toUpperCase() + id.slice(1));
$(this).dataBind({
value: 'SelectedCard().CardData.' + propName,
cardValueChanged: "SelectedCard().CardData." + propName,
visible: "mode() == 'edit' && isMyCard()",
valueUpdate: "'afterkeydown'",
event: { load: myfunc($(this)) }
});
});
```
function myfunc(obj) {
obj.addClass("formElement");
obj.addClass("card-data");
obj.addClass(this.id);
}
It seems like the inline function doesn't play well.
By the way, I have been studying and working for 10 years and am looking
for work. Send anyone my way who might have a job for a Microsoft .NET web
application developer with excellent server and client-side development
experience. I live in Vancouver, Canada.
On Thu, May 24, 2012 at 1:02 PM, joelnet < ***@***.*** > wrote:
what isn't working? what is "fullName"? Is that a text field? if so, I
don't believe "load" is a valid event. Can you use chrome's element
inspector to look inside "fullName" to see what the data-bind attribute
generated is?
## http://www.threetipsaday.com/2008/12/debug-inspect-google-chrome-inspector/
Reply to this email directly or view it on GitHub:
https://gist.github.com/1006808
##
*
Jaime Weise
*
Technical Director
MOBILE 778 319 1739
OFFICE 604 568 2812
TOLL FREE 1 877 568 2812
EMAIL [email protected]
URL www.ellev8.ca
```
*
```
WARNING: This Electronic communication is protected pursuant to relevant
international treaties and domestic laws, and is legally privileged. The
information that is contained within this communication is intended ONLY
for the individual and/or entity who is the intended recipient, and YOU ARE
HEREBY ON NOTICE THAT any dissemination, distribution, copying, or other
use of this communication by anyone other than the intended recipient in an
unauthorized manner is strictly prohibited by law. IF YOU HAVE RECEIVED
THIS MESSAGE IN ERROR, PLEASE CONTACT THE SENDER IMMEDIATELY!
*
I don't believe the $(this) part will work. use the element inspector and you'll see why. The function get's converted into a string and will lose the "this" context.
Your're right, it doesn't work for the reasons you explained. But, the load
function works by nature because it only executes once and internally. The
binding leaves and empty ..., event: { }" stub in the data-bind attribute
that won't do anything. So, in really it doesn't work as you mentioned and
I have also decided that it doesn't make sense to bind an event such load.
```
$(this).dataBind({
...
event: { click: "alert($('#" + id + "').get(0).id)" }
});
```
This seems to be the only way to pass an object. The expression has to be a
string.
On Thu, May 24, 2012 at 2:57 PM, joelnet < ***@***.*** > wrote:
I don't believe the $(this) part will work. use the element inspector and
you'll see why. The function get's converted into a string and will lose
## the "this" context.
Reply to this email directly or view it on GitHub:
https://gist.github.com/1006808
##
*
Jaime Weise
*
Technical Director
MOBILE 778 319 1739
OFFICE 604 568 2812
TOLL FREE 1 877 568 2812
EMAIL [email protected]
URL www.ellev8.ca
```
*
```
WARNING: This Electronic communication is protected pursuant to relevant
international treaties and domestic laws, and is legally privileged. The
information that is contained within this communication is intended ONLY
for the individual and/or entity who is the intended recipient, and YOU ARE
HEREBY ON NOTICE THAT any dissemination, distribution, copying, or other
use of this communication by anyone other than the intended recipient in an
unauthorized manner is strictly prohibited by law. IF YOU HAVE RECEIVED
THIS MESSAGE IN ERROR, PLEASE CONTACT THE SENDER IMMEDIATELY!
*
I think there's an inconsistency: instead of $.extend()
need to use $['extend']()
/sarcasm.
Is there a reason for this notation?
@unirgy, there is no valid reason for that notation. I would do this differently today. Not sure what the reason was way back then.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment