I am using the prettyCheckable jquery plugin to make my checkboxes and radio buttons look pretty and if I use the data-bind="checked: dateMode" it doesn't work because the plugin hides the actual checkbox and makes it's own override html to pretty up the checkbox/radio, therefore the knockoutjs lib doesn't recognize when I check the radio or checkbox and update the value in the model. I know my code works fine if I don't use prettyCheckable plugin, so don't tell me my model or data binding code is messed up. I tested this.
https://github.com/arthurgouveia/prettyCheckable
Here is my partial view code.
<div id="DatesChooser" class="span5 pull-left">
<h4><i class="icon-calendar"></i>Dates</h4>
<input type="radio" name="Date" value="All" data-label="All Available" data-bind="checked: dateMode" /><br />
<input type="radio" name="Date" value="Range" data-label="Range" data-bind="checked: dateMode" />
<div data-bind="visible: dateMode() == 'Range'">
<input type="text" id="FromYear" placeholder="1970" /> to
<input type="text" id="ToYear" placeholder="2012" /><br />
<div id="Date-Slider" class="ui-slider ui-slider-horizontal ui-widget ui-widget-content ui-corner-all">
<div id="Date-Slider-Bar" class="ui-slider-range ui-widget-header" style="left: 0%; width: 100%;"></div>
<a class="ui-slider-handle ui-state-default ui-corner-all" href="#" style="left: 0%;"></a>
<a class="ui-slider-handle ui-state-default ui-corner-all" href="#" style="left: 100%;"></a>
</div>
</div>
</div>
Here is my knockout model :
function searchVm() {
var self = this;
self.dateMode = ko.observable("All");
self.startSearch = function () { alert(self.dateMode()); };
};
And I initialize the prettyCheckable stuff like this :
$('input:checkbox').prettyCheckable();
$('input:radio').prettyCheckable();
Here is what the code gets rendered as after the prettyCheckable plugin modifies it, notice how the input style is 'display:none' :
<div id="DatesChooser" class="span5 pull-left">
<div class="clearfix prettyradio labelright blue">
<input type="radio" data-bind="checked: dateMode" data-label="All Available" value="All" name="Date" style="display: none;" checked="checked">
<a class="checked" href="#"></a>
<label for="undefined">All Available</label>
</div>
<br>
<div class="clearfix prettyradio labelright blue">
<input type="radio" data-bind="checked: dateMode" data-label="Range" value="Range" name="Date" style="display: none;">
<a class="" href="#"></a>
<label for="undefined">Range</label>
</div>
<div data-bind="visible: dateMode() == 'Range'" style="display: none;">
<input id="FromYear" class="placeholder" type="text" placeholder="1970">
to
<input id="ToYear" class="placeholder" type="text" placeholder="2012">
<br>
<div id="Date-Slider" class="ui-slider ui-slider-horizontal ui-widget ui-widget-content ui-corner-all">
<div id="Date-Slider-Bar" class="ui-slider-range ui-widget-header" style="left: 0%; width: 100%;"></div>
<a class="ui-slider-handle ui-state-default ui-corner-all" style="left: 0%;" href="#"></a>
<a class="ui-slider-handle ui-state-default ui-corner-all" style="left: 100%;" href="#"></a>
<div class="ui-slider-range ui-widget-header" style="left: 0%; width: 100%;"></div>
</div>
</div>
</div>
Pretty Checkable triggers change
events on the checkboxes, but Knockout looks for click
events. This can be fixed with a change in prettyCheckable.js
lines 46-54. Original:
if (input.attr('checked') !== undefined) {
input.removeAttr('checked').change();
} else {
input.attr('checked', 'checked').change();
}
Changed:
if (window.ko) {
ko.utils.triggerEvent(input[0], 'click');
} else {
input.click();
}
Knockout also won't work if you use jQuery's click
trigger function. You must use Knockout's triggerEvent
as above.
jsFiddle: http://jsfiddle.net/mbest/4cX48/
There is nothing wrong here. Pretty Checkable library works that way.
It finds the input dom hide them and put dynamic a and label tag instead of that input. If you want to find that input is checked or not you need to examine class of dynamically added a tag ( Class ="checked"). Not the orginal input tag.
You need to write a binding for prettycheckable and observe the a tag's class. Then change the checked value of your binding according to class of that a tag.
@Michael's modification to prettyCheckbox mostly worked, but if your viewModel already has a selection made when you load, prettyCheckbox will NOT recognize it because it is looking for the "checked" attribute while knockout/plain vanilla html will mark the checkbox as checked via a property .
in prettyCheckbox change:
var isChecked = el.attr('checked') !== undefined ? 'checked' : '';
to
var isChecked = el.prop('checked') == true ? 'checked' : '';
Also, it is important to know that if you modify your knockout viewmodel property in code, it will NOT be reflected in prettyCheckbox because I'm not aware of a way to subscribe (in javascript, not knockout) to a change in a property.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.