Knockout and jQuery Mobile: Checkboxes - jquery-mobile

I'm trying to dynamically add checkbox and label elements to the document. Checkbox element has Knockout's data-bind attribute to bind its value to an observable value in the ViewModel. However when I try to style the checkboxes with jQuery Mobile by executing
$('input[type="checkbox"]').checkboxradio();
data-bind attributes will be removed. If I leave out the above line, data-bind attributes are properly set and the binding works.
Is there a way to have both jQuery Mobile styling and Knockout bindings at the same time?
I'm using jQuery Mobile RC1 and Knockout 1.2.1.

I have also encountered this problem. Unfortunately, all the suggestions here either did not work for me or had other issues. So I have created a simple custom binding that works in all versions of KO (including the latest v3):
ko.bindingHandlers.jqmChecked = {
init: ko.bindingHandlers.checked.init,
update: function (element, valueAccessor) {
//KO v3 and previous versions of KO handle this differently
//KO v3 does not use 'update' for 'checked' binding
if (ko.bindingHandlers.checked.update)
ko.bindingHandlers.checked.update.apply(this, arguments); //for KO < v3, delegate the call
else
ko.utils.unwrapObservable(valueAccessor()); //for KO v3, force a subscription to get further updates
if ($(element).data("mobile-checkboxradio")) //calling 'refresh' only if already enhanced by JQM
$(element).checkboxradio('refresh');
}
};
Should be used like this:
<input type="checkbox" data-bind="jqmChecked: someValue" id="checkbox1"/>
See a complete working example here:
http://jsfiddle.net/srgstm/ub6sq/

See: https://gist.github.com/1006808
Then you can do something like the following:
var $checkbox = $('input[type="checkbox"]');
$checkbox.checkboxradio();
$checkbox.dataBind({
your options..
});
Hope this'll help!

There is a problem with using knockouts default checked binding with styled objects like jQuery mobile does. It has the same issues that jQueryUi's Button/Buttonset functions. There is a label over the checkbox that indicates what is happening and it doesn't get updated properly via standard knockout checked binding.
It is discussed at http://therunningprogrammer.blogspot.com/2011/10/how-to-use-jquery-uis-button-with.html.
To use knockout directly with these styled objects from jQuery Mobile, the demonstrated code will have to be modified to handle the different DOM context. I'll post an update to the code when I can get some free time to do it.
EDIT
In Google Groups - Knockout, luv2hike posted a solution. You can see it working at http://jsfiddle.net/luv2hike/nrJBC/. Looks like a working fix for your problem.

I created a simple binding that works with jQuery Mobile 1.2.0 and Knockout 2.2.1 and works with default jQuery mobile checkboxes. This binding has no dependency on custom icons or JQuery Mobile's CSS styles. It also allows the use of regular checkbox markup in your HTML (<input type="checkbox" ... />) as opposed to using an alternate markup element like a div.
Here's the fiddle: http://jsfiddle.net/thedude458/52baX/
Note: Presently, the example only supports a single checkbox, not a list, as that is all I currently have a need for. It also assumes that the bound property is an observable.

Here is my heavily commented code on a custom handler I built for jQueryMobile checkboxes:
ko.bindingHandlers.checkbox = {
init: function(element, valueAccessor) {
// set the dom element to a checkbox and initialize it (for jquerymobile)
var checkbox = $(element);
checkbox.checkboxradio();
checkbox.attr('type', 'checkbox');
// register change event to update the model on changes to the dom
ko.utils.registerEventHandler(element, "change", function() {
valueAccessor()(
// off because it is before the ui has refreshed
$(this).siblings('label.ui-checkbox-off').length > 0
);
});
},
update: function(element, valueAccessor) {
// update the checked binding, i.e., check or uncheck the checkbox
ko.bindingHandlers.checked.update(element, valueAccessor)
// and refresh the element (for jquerymobile)
var checkbox = $(element);
checkbox.checkboxradio('refresh')
}
};

Related

Passing DOM element to controller when using jquery autocomplete

I am using ASP.Net MVC and JQuery UI autocomplete.
I have a number of input-boxes set up in a table and I have this JavaScript code.
$('.searchfield').autocomplete({
source: '#Url.Action("AutoCompleteFunction")'
});
Which works perfectly. The controller reads from a database and returns a list of matches.
Now I have another column of fields that also need autocomplete. However, these autocomplete lists have to be dependent on what is already in the table.
How can I pass DOM elements to the autocomplete controller?
I have tried something like this. As long as I only pass a string it will work, but not when I try to pass it a DOM element.
$('.newsearch').autocomplete({
source: '#Url.Action("NewAutoCompleteFunction", new { firstParameter = "testing"})'.replace("testing", "'$document.activeElement.value'")
});

cannot applybindings multiple times knockout in MVC partial view

Hi have a parent page in which i have used knockout js to bind model with html element.
Now i make a ajax call to receive a partialviewresult which i place it in a div conbtainer.
All works fine if use the inbuilt mvc model binding.
But when i go for knockout in my partial view as well. I get the errorcannot applybindings multiple times knockout in MVC partial view.
I have even tried using
ko.applybindings(new vm(),document.getelementbyId("div1"))
ko.applybindings(new vm1(),document.getelementbyId("div2"))
But still get the same error. Is it not possible to get the partial view result from the action method and use knockout in partial view ? I do not want hide the div in my parent page and get a JsonResult and bind it to my div element.
If you have the following (general layout):
<div id="parent">
content
<div id="partialTarget"></div>
</div>
and you've already applied your bindings to #parent, you have to clean #partialTarget before applying the viewmodel again. #partialTarget has already been bound from the first pass, so to apply the bindings to the loaded contents, you need to do something like this:
var reapplyBindings = function(element){
var vm = ko.dataFor(element);
if( vm ) {
ko.cleanNode(element);
ko.applyBindings(vm, element);
}
};
element.load(‘path/to/fragment.html’, function() {
//the [0] selector is needed to be sure we have an actual dom element, not the jQuery wrapper
reapplyBindings(element[0]);
//do whatever you’re already doing
});

Disable validation for certain fields

In my Razor view (ASP.NET MVC 4), I have two radiobuttons for showing/hiding some fields. When the first radiobutton is selected, these fields are invisible; when the second radiobutton is selected, the fields become visible. This is done by a Javascript function which is bound to the radiobuttons onclick event.
function displayHiddenFields(value) {
if (value == 'true')
$('#myDiv').removeClass('hidden');
else
$('#myDiv').addClass('hidden');
}
I'm using data annotations on the view model to perform validation. My problem is that the invisible fields are also validated. These fields only have to be validated when they are visible. I tried to manipulate the data-val attribute on the input elements but this doesn't work.
$('input1').attr('data-val', value);
How can I solve my problem? Is there a way to disable validation for the fields that are invisible by using client-side Javascript? Otherwise, I have to do a postback in order to render the fields conditionally.
I solved it by adding the following piece of JavaScript to the bottom of my page:
<script type="text/javascript">
$(function () {
var settings = $.data($('form').get(0), 'validator').settings;
settings.ignore = ".hidden";
});
</script>
This way, all the inputs that have the .hidden class applied to it will be ignored in the client-side validation.
<button id="Submit" type="submit">Submit</button>
<script type="text/javascript">
$("#Submit").on("click", function () {
var validator = $("form").data('validator');
validator.settings.ignore = "input[type=hidden]";
});
</script>
I would suggest using jQuery validation. You can conditionally validate your model:
if($("#field").is(":checked")){
//Add some validation here
}else{
//Default validation here
}
if($("form").valid()){
//Do processing
}
The problem will be on the back-end. if you are using data annotations, I would assume you are validating the model in the controller as well; something like 'Model.isValid()' or the like? As long as both your cases (radio button1 click or button2 clicked) always matches what a "valid" model should be, you will be fine. Otherwise, you may have to turn off some of the data annotations. Just from my experience. jQuery Validation Docs
By default (at least in the later versions of the unobtrusive validation) the ignore field is set to ":hidden" (evaluated by jQuery) which is way better than just checking a class="hidden" or type="hidden".

Dependable drop down list in JSP, Struts2

i am working on a project and using Struts2 for it with JSP. In one JSP page, i have two drop down list say dd1 and dd2. The dd2 is dependable on dd1. The values in dd2 should be populated based on the dd1 value. Now i have a java class which gives me all the options for the drop down lists from the database and i am displying them in my JSP using the SELECT tag. How to make the dd2 dependable on dd1? I dont have any knowledge of Ajax. Please help.
Not a very big fan of any Ajax plugin.If you do not want to use any big fancy Ajax tags and are ready to learn a bit of JQuery or any other java-script framework, i suggest you to use simple ajax call.
Play around with the events when the value in your parent drop-down change call a function and make an Ajax call to your action which can return the values in JSON format (use struts2 JSON plugin), parse the JSON data and fill the other drop-down.
benefits of this approach are
More flexible.
Much light and faster.
No need to add any UN-necessary dependencies. Other approach (IMO not the good one) use Struts2-Jquery plugin to get it done but get ready for any undesirable behavior or any other issue and you have to reply on the Plugin community.
Here is an example as suggested
<s:select list="states" label="State" name="state" onchange="ajaxCallForDistrict();"
id="stateList"></s:select>
<s:select list="districts" label="District" name="district" id="district" />
what i am doing here is that District are dependent upon state so once user select a State from first select i am calling a java-script function on onchange event and here is my ajaxCallForDistrict() function
function ajaxCallForDistrict()
{
var selectedState = document.getElementById("stateList");
var statedata = selectedState.options[selectedState.selectedIndex].value;
var formInput='state='+statedata;
$.getJSON('search/getDistricts',formInput,function(data) {
$('.result').html('' + data.districts + '');
$.each(data.districts,function(index, value){
var districtid = document.getElementById("district");
var option=new Option(value,value);
try{
districtid.add(option);
}
catch(e){
districtid.appendChild(option);
}
});
});
}
what i am doing in above function is that i am fetching the value of selected state and giving the Ajax call to getDistricts Action which is simply creating a list of district for the provided state and returning back the result as JSON data.
for filling the District select i am looping through the result (JSON) and appending the element in the select box
JSP are servlets inside so there no way how to make interaction after response is send to client
i would recommend struts2-jquery-plugin - you will be able to solve this problem using ajax and this framework is good place to start if you are not interested in learning javascript (jQuery), showcase
I am not sure but may be this can help you...
jsp page
<s:select name= "" lable = "" onchange="javaScriptFunction(element that you have selected);"></s:select>
JavaScript---
<script>
function javaScriptFunction(element)
{
document.LoginForm.action=element+".action";
document.LoginForm.submit();
}
</script>
Now map these action in struts.xml
My suggestion is use one action but several different methods.
After that populate the other dropdown Box by using s:iterator.

JQueryUI accordion changestart event - how to get data out of it?

http://jqueryui.com/demos/accordion/#event-changestart
I'm trying to have an JQuery ajax request get some data and populate the body of a div inside each of my JQueryUI accordion rows when the row is expanded. My intention is to have a hidden field, or some such, within the clickable h3's of the accordion and when the changestart event fires the ajax will go off and get a unique page for that accordion row and fill it with useful html.
My problem is that I can't seem to find any information about the properties or values attached to the objects returned in the changestart event function parameters. Does anyone know how to do this or get those values?
The code I have right now is this:
$("#accordion").accordion({
collapsible: true,
active: false,
changestart: function(event, ui) {
alert('hello:' + event.target.id + ':' + ui.id);
}
});
Which throws up an alert displaying the message hello:accordion:undefined
I've seen this post which seems to be along the lines of what I'm trying to figure out...
jQuery UI object type for "ui" object passed to the callback function?
Thanks,
Matt.
Looks like ui holds this:
$('.ui-accordion').bind('accordionchangestart', function(event, ui) {
ui.newHeader // jQuery object, activated header
ui.oldHeader // jQuery object, previous header
ui.newContent // jQuery object, activated content
ui.oldContent // jQuery object, previous content
});
You can access the contents of those ui.new|old elements easily.
They are jQuery elements, that is why they look a bit odd.
jQuery way
ui.newHeader.first().html()
And if you need access to the dom element use .get()
ui.newHeader.get().first()

Resources