Bind knockout.js to a boolean JQuery Mobile flip switch toggle - jquery-mobile

i have a boolean value bound to a JQM flip switch toggle, but i'm not able to see it reacting to changes to the underlying observable.
This is my true/false observable:
ko.booleanObservable = function (initialValue) {
var _actual = ko.observable(initialValue);
var result = ko.computed({
read: function () {
var readValue = _actual().toString();
return readValue;
},
write: function (newValue) {
var parsedValue = (newValue === "true");
_actual(parsedValue);
}
});
return result;
};
Which is the best way to combine JQM flip switch toggle and Knockout?
jsFiddle here: http://jsfiddle.net/nmq7z/
Thanks in advance to all
UPDATED: with a better test case:
http://jsfiddle.net/FU7Nq/

I got it,
Thanks to kadumel which point out that my first piece of code was really bad.
Then, i switched from a computed observable to a custom binding, which seems to me a good solution:
ko.bindingHandlers.jqmFlip = {
init: function (element, valueAccessor) {
var result = ko.bindingHandlers.value.init.apply(this, arguments);
try {
$(element).slider("refresh");
} catch (x) {}
return result;
},
update: function (element, valueAccessor) {
ko.bindingHandlers.value.update.apply(this, arguments);
var value = valueAccessor();
var valueUnwrapped = ko.utils.unwrapObservable(value);
try {
$(element).slider("refresh");
} catch (x) {}
}
};
<select name="select-ismale" id="select-ismale" data-bind="jqmFlip: isMale.formattedValue" data-role="slider">
<option value="false">No</option>
<option value="true">Yes</option>
</select>
Here is the working Fiddle: http://jsfiddle.net/FU7Nq/1/
Hope this can help some other People to deal with the JQM Flip Switch Toggle.
The binding with a "true" boolean observable is realized through an extender: this is the meaning of isMale.formattedValue.
This very clean and powerful solution is described in Tim's blog (thank You, Tim!).

Two things of note -
When you are making the checked value dependent on something I believe you need to use value: binding instead of checked: binding.
Second - You are setting it equal to a string of 'true' instead of boolean true, but your binding is to a boolean of true.
Try those adjustments in your binding and let me know if that doesn't fix it.

ko.bindingHandlers.jqmBindFlipSwitch = {
init: function (element, valueAccessor) {
$(element).change(function () {
var value = valueAccessor();
value($(element).is(":checked"));
}).blur(function () {
var value = valueAccessor();
value($(element).is(":checked"));
});
},
update: function (element, valueAccessor) {
var value = valueAccessor();
var valueUnwrapped = ko.utils.unwrapObservable(value);
$(element).prop('checked', valueUnwrapped)
.flipswitch().flipswitch('refresh');
}
};
<input data-bind="jqmBindFlipSwitch: siteVisitRequired" type="checkbox" data-on-text="Yes" data-off-text="No" />
This seems to work fairly cleanly

Related

Using "IIFE" to create private scope; do I need parentheses?

This is my code:
var badget = function () {
var privetVar = 23;
var privetFunc = function (a) {
return privetVar + a;
}
return {
publicFunc: function (b) {
console.log(privetFunc (b));
}
}
}();
It works well; I have access to the publicFunc() using badget.publicFunc(), which has access to the privetVar and privetFunc() due to "closures".
However, someone told me I must use parentheses like this:
var badget = (function() {
var privetVar = 23;
var privetFunc = function(a) {
return privetVar + a;
}
return {
publicFunc: function(b) {
console.log(privetFunc(b));
}
}
})();
Is this second example considered a preferable syntax?
No, the parentheses are not required in this example. Typically people don't use the return value of an IIFE, so the parentheses are required to differentiate a function expression from a function statement.
Since your function declaration in your first example is already part of an assignment expression, it's already a function expression, so the parentheses aren't required.
TL;DR
Valid
var badget = function () {
...
}();
(function () {
...
})();
(function () {
...
}());
Valid (but not necessary)
var badget = (function () {
...
})();
var badget = (function () {
...
}());
Invalid (function statements cannot be IIFEs)
function () {
...
}();

JavaScript Module Pattern across multiple files

I'm having to restructure some ancient code, and there's quite a bit of it in lots of different files. The approach is to use the revealing module pattern, as described in JavaScript Module Pattern: In-Depth (section Cross-File Private State).
The first function expression works great, and I can see in Firebug that the function components are also assigned correctly in the second block. But then the variable suddenly ends up undefined.
I put together a simplified example, and the console shows the variable is undefined after the second assignment.
var test = (function ($, ns, undefined)
{
function test1()
{
console.log("executing test1");
ns.testx.test2();
}
return { test1: test1 };
}(jQuery, test || {}));
console.log(test);
var test = (function ($, ns, undefined)
{
ns.testx = (function ()
{
function test2()
{
console.log("executing test2");
}
return { test2: test2 }
})();
}(jQuery, test || {}));
console.log(test);
// DOM ready
$(function ()
{
test.test1();
});
Several variations, such as defining the variable just once at the top don't work either. If the two function expressions are swapped, test 1 is executed but ns.testx is undefined.
I fear I'm missing the blindingly obvious and would really like to understand why this does not work. I also need to get it to work, so any help is greatly appreciated (merging the files into one is not an option).
Try
var test = (function ($, ns, undefined)
{
function test1()
{
console.log("executing test1");
ns.testx.test2();
}
ns.test1 = test1;
return ns;
}(jQuery, test || {}));
console.log(test);
var test = (function ($, ns, undefined)
{
ns.testx = (function ()
{
function test2()
{
console.log("executing test2");
}
return { test2: test2 }
})();
return ns;
/*
This will be
{
test1: test1,
testx: {
test2: test2
}
}
*/
}(jQuery, test || {}));

Optional callback with optional parameter

I may be doing something wrong syntactically or practically so "don't do that" could be valid but it seems this should work:
class Thing {
//static dynamic noop = () { }; // fails
static dynamic noop = ([dynamic value]) { }; // works for null cases
dynamic _callback;
Thing._([dynamic callback([dynamic value])])
: this._callback = callback != null ? callback : Thing.noop;
factory Thing([dynamic callback([dynamic value])]) {
return new Thing._(callback);
}
}
When I run these tests, the first one fails but the second, third and fourth pass:
//Caught type '() => dynamic' is not a subtype of type '([dynamic]) => dynamic' of 'callback'.
test('callback with optional param', () {
var thing = new Thing(() { });
thing.doCallback();
thing.doCallback('data');
});
test('callback with optional param', () {
var thing = new Thing(([_]) { });
thing.doCallback();
thing.doCallback('data');
});
test('callback with optional param', () {
var thing = new Thing();
thing.doCallback();
thing.doCallback('data');
});
test('callback with optional param', () {
var thing = new Thing(null);
thing.doCallback();
thing.doCallback('data');
});
dynamic callback([dynamic value]) means a callback that can take one parameter or none. In your first test case, the callback you provides (() { }) only handles calls with no parameter. So it does not respect the contract. That's why you get this error.

How do you callback into Dart from jquery with parameters?

I'm writing a Dart class to wrap the jqueryUI slider. The jquery code looks like:
$("#diameter_slider").slider({'range': true, max: 50, min: 0, values: [0, 50],
slide: function( event, ui ) {
//code executed when the slider is moved goes here
});
My Dart class looks like:
class Slider {
Map options;
String css_id;
String units;
var slider;
Slider( {this.options, this.css_id, this.units} ) {
js.scoped((){
slider = js.context.$(css_id);
final updater = new js.Callback.many((d, i, context) { query("#diameter").text = 'here';});
final opts = js.map({ 'range': true,
'values': [options['min'], options['max']],
'slide': updater});
slider.slider(opts);
js.retain(slider);
});
}
void UpdateText( var event, var ui ){
query("#diameter").text = 'here';
}
}
When executed the slider displays correctly (using Dartium). But When the slider is moved Dartium crashes. What is the correct way to get parameters passed to Dart from javascript?
Looking at the slide doc, the callback function seems to handle 2 parameters. So, your updater should be defined like this :
final updater = new js.Callback.many((event, ui) { query("#diameter").text = 'here';});

Knockout array filter and Computed observable not working

i am new to Knockout. I am trying out a scenario and i am not able to make it work. please help. I am using MVC4.
function ViewModel(data) {
var self = this;
this.Collection = ko.observable(data);
self.GetFilteredCollection = ko.computed(function () {
var filteredCollection = ko.utils.arrayFilter(self.Collection(), function (item) {
return item.IsSelected == true;
});
return filteredCollection;
});
self.FilteredCollectionCount = ko.computed(function () {
return self.GetFilteredCollection().length;
});
});
var collectionList = eval('<%= new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(Model.Collection) %>');
var VM = new ViewModel(collectionList);
ko.applyBindings(VM);
I have binded the IsSelected property to checkbox. Initially the IsSelected property will be set to false.
<span id="Span1" data-bind="text:$root.FilteredCollectionCount"></span>
I am always getting the Span value as 0 even if i select the checkbox. But i could see the Property IsSelected changed to true.
You need to make the IsSelected into a observable for the computed observable to be able to be notified when the value of IsSelected has changed
If it already is a observable then you need to change the code to
return item.IsSelected() == true;

Resources