Datepicker inside a handlebars template - jquery-ui

I am trying to figure out a way to have jqueryui datepicker inside handlebars template. So far I have the following that doesn't seem to work:
> <script src="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.10.0/jquery-ui.min.js"></script>
> <script>
> $(function () {
> $(".datePicker").datepicker();
> }); </script>
<script id="template-row" type="text/x-handlebars-template">
<div class="returnRow{{#if altRow}} returnRow-alt{{/if}} clearfix">
<input type="hidden" class="return-id" value="{{ID}}" />
<input type='hidden' class='return-last-updated' value='{{LastUpdated}}' />
<div class="pull-left returnRow-date">
<input type="text" class="datePicker" />
</div>
<div class="pull-left returnRow-return">
<input type="text" style="width: 90%" class="return-value" onchange='SaveSingleRow(this)' value="{{textValue}}" />
</div>
<div class="pull-left returnRow-message">
<span class="row-message"></span>
</div>
</div>
</script>

I think you have two options:
Bind the datepicker after adding the filled-in template to the DOM.
Bind the datepicker to a jQuery-wrapped version of the filled-in template and then add that jQuery object to the DOM.
The first option looks like this:
var t = Handlebars.compile($('#template-row').html());
$(something_already_in_the_dom).append(t(data));
$('.datePicker').datepicker();
Demo: http://jsfiddle.net/ambiguous/w2wyU/7/
The second option looks like this:
var t = Handlebars.compile($('#template-row').html());
var $html = $(t(data));
$html.find('.datePicker').datepicker();
$(something_already_in_the_dom).append($html);
Demo: http://jsfiddle.net/ambiguous/PMP8R/
Note that both options take place outside the template. The underlying problem is that .datepicker needs to be called on a jQuery object but everything is only text inside the template, you can't have a jQuery wrapped version of that text until after the template has been processed and filled in.

Related

Dynamically adding checkboxradio [duplicate]

So I'm trying to load dynamic content straight into my checkbox container (group_checkboxes)
<div id='group_checkboxes' data-role="fieldcontain">
</div>
This is the statement I'm running to populate the container:
$('#group_checkboxes').append('<fieldset data-role="controlgroup"><input type="checkbox" name="' + $(this).find('data').text() + '" class="custom" /><label for="' + $(this).find('data').text() + '">' + $(this).find('label').text() + '</label></fieldset>');
The checkboxes are all populated but the jQuery style is not applied.
According to the docs all I need to do is call this function to update the checkbox style...
$("input[type='checkbox']").checkboxradio("refresh");
That doesn't work though... Any idea what I'm doing wrong?
When appending checkboxes or radio buttons to a controlgroup dynamically, you deal with two jQuery Mobile widgets, .checkboxradio() and .controlgroup().
Both should be created/updated/enhanced/styled with jQuery Mobile CSS once new elements are added.
The way to achieve this is different in latest stable versions and RC version, but the methods are the same.
jQuery Mobile 1.2.x - 1.3.x (stable versions)
After appending checkbox / radio button to either a static or dynamic controlgroup, .checkboxradio() should be called first to enhance checkbox / radio button markup and then .controlgroup("refresh") to re-style controlgroup div.
$("[type=checkbox]").checkboxradio();
$("[data-role=controlgroup]").controlgroup("refresh");
Demo
jQuery Mobile 1.4.x
The only difference here is elements should be appended to .controlgroup("container")
$("#foo").controlgroup("container").append(elements);
and then enhance both controlgroup and all elements within it, using .enhanceWithin().
$("[data-role=controlgroup]").enhanceWithin().controlgroup("refresh");
Demo
First try their own static demo code:
<div data-role="fieldcontain">
<fieldset data-role="controlgroup">
<legend>Choose as many snacks as you'd like:</legend>
<input type="checkbox" name="checkbox-1a" id="checkbox-1a" class="custom" />
<label for="checkbox-1a">Cheetos</label>
<input type="checkbox" name="checkbox-2a" id="checkbox-2a" class="custom" />
<label for="checkbox-2a">Doritos</label>
<input type="checkbox" name="checkbox-3a" id="checkbox-3a" class="custom" />
<label for="checkbox-3a">Fritos</label>
<input type="checkbox" name="checkbox-4a" id="checkbox-4a" class="custom" />
<label for="checkbox-4a">Sun Chips</label>
</fieldset>
</div>
They are using just one fieldset as I mentioned in comments.
If this works, then adjust your script to generate the same markup dynamically and then refresh them
$("input[type='checkbox']").checkboxradio("refresh");
If this will work with their code, you will know that you have error in markup. If not, there is an error with that refresh function. (I know it's not final solution but you have to do a bit of debugging sometimes :)
Edit:
Found similar problems, solved by using Page()
JQM FAQ
SO Question
try with $("#<id of fieldset controlgroup>").trigger("create");
http://jsfiddle.net/YKvR3/36/
try
$('input:checkbox').checkboxradio('refresh');
<!DOCTYPE HTML>
<html>
<head>
<title>checkbox</title>
<link rel="stylesheet" href="jQuery/css/jquery.mobile-1.0a4.1.min.css" />
<script type="text/javascript" src="jQuery/js/jquery-1.6.1.min.js"></script>
<script type="text/javascript" src="jQuery/js/jquery.mobile-1.0a4.1.min.js"></script>
<script type="text/javascript">
var myArray = [];
$(document).ready(function() {
// put all your jQuery goodness in here.
myArray[myArray.length] = 'Item - 0';
checkboxRefresh();
});
function checkboxRefresh(){
var newhtml = "<fieldset data-role=\"controlgroup\">";
newhtml +="<legend>Select items:</legend>" ;
for(var i = 0 ; i < myArray.length; i++){
newhtml += "<input type=\"checkbox\" name=\"checkbox-"+i+"a\" id=\"checkbox-"+i+"a\" class=\"custom\" />" ;
newhtml += "<label for=\"checkbox-"+i+"a\">"+myArray[i]+"</label>";
}
newhtml +="</fieldset>";
$("#checkboxItems").html(newhtml).page();
//$('input').checkboxradio('disable');
//$('input').checkboxradio('enable');
//$('input').checkboxradio('refresh');
//$('input:checkbox').checkboxradio('refresh');
$("input[type='checkbox']").checkboxradio("refresh");
$('#my-home').page();
}
$('#bAdd').live('click', function () {
myArray[myArray.length] = 'Item - ' + myArray.length;
checkboxRefresh();
});
</script>
</head>
<body>
<div data-role="page" data-theme="b" id="my-home">
<div id="my-homeheader">
<h1 id="my-logo">checkbox</h1>
</div>
<div data-role="content">
<div id="checkboxItems" data-role="fieldcontain"></div>
<fieldset class="ui-grid-b">
<div data-role="controlgroup" data-type="horizontal">
<a id="bAdd" href="#" data-role="button" data-icon="plus" >Add new item</a>
</div>
</fieldset>
</div>
</div>
</body>
</html>
It works just ones for me. Any idea why?
The Answer for me is:
$("input[type='checkbox']").checkboxradio();
What work out for me was to remove the whole fieldset then replace place a new fieldset with the new item I wanted to add then I called the .trigger('pagecreate'); method on the whole page. This is not the most efficient solution but that is the only one that worked in my case.

What is the easiest way to set all the inputs on a page to seperate data-theme than the page data-them in jquery mobile?

I have a webpage with the page div set to data-theme D
<div data-role="page" data-theme="d">
I also have several inputs on the page with the data-theme set to A
<input data-theme='a' type='text'>
<input data-theme='a' type='text'>
<input data-theme='a' type='text'>
Is there an easier way to set all the input's data-theme's to A without having to set each input individually?
1- Solution 1:
Wrap them in data-role="content", but this will change the background color of the div.
<div data-role="content" data-theme="a">
<input type="text" />
</div>
Demo
2- Solution 2:
Globally, set theme to all input on mobileinit event.
<head>
<script src="jquery.js"></script>
<script>
$(document).on("mobileinit", function() {
$.mobile.textinput.prototype.options.theme = "a";
});
</script>
<script src="jquery.mobile.js"></script>
</head>
Demo
3- Solution 3:
Set input theme on pagebeforecreate.
$(document).on("pagebeforecreate", function () {
$("input").textinput({
"theme": "a"
});
});
Demo

Customizing jQuery Mobile checkboxes labels

I've a <fieldset> of checkboxes with custom labels that contains both item names and descriptions, as you can see here:
Demo: http://jsfiddle.net/Zw823/
On the third checkbox I need to have a custom <input type="number" /> below description, which will be editable only if its checkbox is checked. Is it possible? I tried to put a <div data-role="fieldcontain"> with label+input below the <p>, but the <input/> number didn't display as expected... How can I achieve that goal? Thank you in advance!
This is how I managed to do what you want. The trick is to load the jquery scripts at the bottom of the page, so you don't have to call trigger('create') and break your code.
<fieldset data-role="controlgroup" >
<label for="check-1" >
<a class="ui-li-heading" href="">Service 1</a>
<p class="ui-li-desc">Lorem ipsum text</p>
</label>
<input type="checkbox" id="check-1" data-iconpos="left">
</fieldset>
<!-- rest of your data-role="page" -->
</div> <!-- end of page -->
<script src="jquery.min.js"></script>
<script src="jquery-mobile.min.js"></script>
</body>
</html>

How to fix conflict with jQuery UI and jQuery? Datepicker giving error

I am trying to use the jQuery datepicker for a form on a site that uses jQuery 1.3.2 but it's not working. I have to reference a newer jQuery library for some of my form functionality, and also the jQuery ui for datepicker to work. I have used noConflict for the newer jquery library but it's still not working. I get Uncaught TypeError: Cannot read property 'document' of null in the console. Updating/removing the 1.3.2 reference is not an option.
Here is my fiddle, which works. but i get the error above in Chrome (not FF) and the datepicker will not work on my site. http://jsfiddle.net/pnA33/
Can anyone help? It works locally but not on the server (which is a dev enviornment so I can't share a link). I found this but as I am relatively new to jQuery it is over my head.
jQuery:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/jquery-ui.min.js"></script>
<script type="text/javascript">
var jQuery_1_9_1 = jQuery.noConflict(true);
jQuery_1_9_1(document).ready(function() {
jQuery_1_9_1( "#datepicker" ).datepicker({ minDate: -1, maxDate: "+24D" });
jQuery_1_9_1('#pancettaForm').change(function () {
jQuery_1_9_1('.address,#new-ship-date').hide();
if (jQuery_1_9_1('#ship-address').prop('checked')) {
jQuery_1_9_1('.address').show();
}
else if (jQuery_1_9_1('#ship-date').prop('checked')) {
jQuery_1_9_1('#new-ship-date').show();
}
else if (jQuery_1_9_1('#ship-both').prop('checked')) {
jQuery_1_9_1('.address, #new-ship-date').show();
}
});
});
function validateForm()
{
var x=document.forms["pancettaForm"]["order-number"].value;
if (x==null || x=="")
{
alert("Please provide your order number from the confirmation email sent immediately after placing your order.");
return false;
}
}
</script>
HTML:
<form name="pancettaForm" method="post" action="http://lizlantz.com/lcform.php" id="pancettaForm" onsubmit="return validateForm()">
<input type="hidden" value="Pancetta Order Update" name="subject">
<input type="hidden" value="cookware/partners_10151_-1_20002" name="redirect">
<ol>
<li>
<label for="update-ship">I'd like to:</label>
<input id="ship-address" name="update-ship" type="radio" value="update-ship-address"/> Have pancetta shipped to a different address than my skillet<br />
<input id="ship-date" name="update-ship" type="radio" value="update-ship-date" /> Have pancetta shipped sooner than June 14, 2013 <br />
<input id="ship-both" name="update-ship" type="radio" value="update-both" /> Make changes to both the shipping address and shipping date
</li>
<li>
<label for="order-number"><em>*</em>Order Number (available in order confirmation email):</label>
<input type="text" name="order-number">
</li>
<li>
<label for="full-name"><em>*</em>Recipient Full Name:</label>
<input type="text" name="full-name">
</li>
<li class="address" style="display: none;">
<label for="address">
<em>*</em>Address
</label>
<input type="text" name="address">
<label for="address2">
Address Line 2
</label>
<input type="text" name="address2">
</li>
<li class="address" style="display: none;">
<label for="city">
<em>*</em>City
</label>
<input type="text" name="city">
<label for="state">
<em>*</em>State
</label>
<select name="state">
<option value="AL">Alabama</option>
<option value="AK">Alaska</option>
</select>
<label for="zip">
<em>*</em>Zip Code
</label>
<input type="text" name="zip">
</li>
<li id="new-ship-date" style="display: none;">
<em>*</em><label for="updated-ship-date">New Ship Date:</label>
<input type="text" id="datepicker" name="updated-ship-date" value="Update Your Ship Date" />
</li>
<li>
<label for="phone">
<em>*</em>Phone (for delivery questions)
</label>
<input type="text" name="phone">
</li>
</ol>
<input type="submit" id="button" name="submit" value="Update Pancetta">
</form>
Ah ha! You actually cannot run two versions of jQuery on the same document instance at one time...hence the issue here. This solution comes directly from Splendìd Angst's answer in this thread Can I use multiple versions of jQuery on the same page?
Basically you must declare your noConflict version prior to entering the document "main loop" I suppose you can call it.
Declare your noConflict variable outside the document.ready call...use the standard $(document).ready() syntax, then use (and ONLY use) your noconflict variable within the ready closure. That should do it.
I haven't tested this mind you but it makes sense and it won't take you much tweaking of your code to try it out.
TIL something new about jQuery :)

Why am I getting this Javascript HIERARCHY_REQUEST_ERR with jQuery Mobile and Razor?

Dazed and confused here... The field in question is a boolean, and I want the UI to be a checkbox (or a yes/no or on/off jQuery slider). Each time I try to add in this checkbox input, I end up getting a
Microsoft JScript runtime error: DOM Exception: HIERARCHY_REQUEST_ERR (3)
error.
Here's the HTML+Razor
<div data-role="fieldcontain">
<fieldset data-role="controlgroup">
<legend>End Game:</legend>
#Html.TextBoxFor(model => model.HandicapSession.WinByTwo, new { #type="checkbox" })
<label for="WinByTwo">Win By Two?</label>
</fieldset>
</div>
Here's the generated HTML:
<div data-role="fieldcontain">
<fieldset data-role="controlgroup">
<legend>End Game:</legend>
<input data-val="true" data-val-required="The WinByTwo field is required." id="HandicapSession_WinByTwo" name="HandicapSession.WinByTwo" type="checkbox" value="False" />
<label for="WinByTwo">Win By Two?</label>
</fieldset>
</div>
Apparently this error occurs when there are conflicting or overlapping id's as jQuery Mobile creates its checkbox widget
$.widget( "mobile.checkboxradio", $.mobile.widget, { ...etc...
But how do I use the HTML and/or razor to make a simple checkbox work in jQuery Mobile?
If the problem with jQuery Mobile really is duplicate names for the HTML tags, then you'll have to render your own input type=checkbox tag in HTML, as the ASP.NET MVC Html.CheckBoxFor helper method will render an input type=hidden tag with a duplicate name value. See this post for a discussion.
The hidden form tag is there because if you submit an unchecked checkbox to the server, the form value for that field isn't included. So a hidden input tag is included with value=false so that if the checkbox is unchecked, the value false is still submitted. The model binding process in MVC will filter out the duplicate form values for you, but if you're having a client-side problem with the duplicate name attributes, you'll have to render your own checkbox and label in HTML, then handle the fact that no value will be submitted for the HandicapSession.WinByTwo property when the box is unchecked. If no other property for HandicapSession is submitted, then that whole object will be null.
So, you can manually create the checkbox input and still load the checked and value attributes from your model, as desired, but you can run into model binding problems where the value for WinByTwo will still be false even when the box is checked.
Note also that the for attribute on your label doesn't match the ID of the checkbox in your sample. You need the full HandicapSession_WinByTwo.
The following manually creates the input tags:
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a4.1/jquery.mobile-1.0a4.1.min.css" />
<script type="text/javascript" src="http://code.jquery.com/mobile/1.0a4.1/jquery.mobile-1.0a4.1.min.js"></script>
<div data-role="page">
<div data-role="content">
<div data-role="fieldcontain">
<fieldset data-role="controlgroup">
<legend>End Game:</legend>
<input type="checkbox" id="HandicapSession_WinByTwo" name="HandicapSession.WinByTwo" #(Model.HandicapSession.WinByTwo ? "checked=checked" : "") value="#(Model.HandicapSession.WinByTwo.ToString().ToLower())" />
<label for="HandicapSession_WinByTwo">Win By Two?</label>
</fieldset>
</div>
</div>
</div>
The HTML output is as follows for a checked checkbox on load:
<div data-role="page">
<div data-role="content">
<div data-role="fieldcontain">
<fieldset data-role="controlgroup">
<legend>End Game:</legend>
<input type="checkbox" id="HandicapSession_WinByTwo" name="HandicapSession.WinByTwo" checked=checked value="true" />
<label for="HandicapSession_WinByTwo">Win By Two?</label>
</fieldset>
</div>
</div>
</div>
The best would be just to use the MVC helper methods, so I'm not sure if you'd tried the following. The default Html.CheckBoxFor and Html.LabelFor helper methods work with jQuery Mobile 1.0a4.1 or 1.1.0 just fine. The following works for me:
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a4.1/jquery.mobile-1.0a4.1.min.css" />
<script type="text/javascript" src="http://code.jquery.com/mobile/1.0a4.1/jquery.mobile-1.0a4.1.min.js"></script>
<div data-role="page">
<div data-role="content">
#using (Html.BeginForm())
{
<div data-role="fieldcontain">
<fieldset data-role="controlgroup">
<legend>End Game:</legend>
#Html.CheckBoxFor(m => m.HandicapSession.WinByTwo)
#Html.LabelFor(m => m.HandicapSession.WinByTwo, "Win By Two?")
<input type="submit" id="SubmitForm" value="submit" />
</fieldset>
</div>
}
</div>
</div>
This produces the HTML output:
<div data-role="page">
<div data-role="content">
<form action="/Mobile/Mobile" method="post">
<div data-role="fieldcontain">
<fieldset data-role="controlgroup">
<legend>End Game:</legend>
<input checked="checked" data-val="true" data-val-required="The WinByTwo field is required." id="HandicapSession_WinByTwo" name="HandicapSession.WinByTwo" type="checkbox" value="true" />
<input name="HandicapSession.WinByTwo" type="hidden" value="false" />
<label for="HandicapSession_WinByTwo">Win By Two?</label>
<input type="submit" id="SubmitForm" value="submit" />
</fieldset>
</div>
</form>
</div>
</div>
Fix might be pretty simple.
Choice 1: Go scorched earth and turn off Ajax based navigation. This will ensure that unique IDs stay unique. This will ensure that you never encounter this issue again. Only downside is that you lose the pretty little transitions from page to page (someone call the whambulance). You can do this by setting up a global configuration script...
script src="jquery.js"
script src="custom-scripting.js"
script src="jquery-mobile.js"
inside that you'll override the ajax settings to disable them...
$(document).bind("mobileinit", function(){
$.mobile.ajaxEnabled = false;
});
Choice 2: Call pages that are going to require this uniqueness with a link that has an attribute of rel='external' or target='_black' which will accomplish the same thing without disabling all ajax based navigation. If you are reaching the page as a results of a form post, you can use data-ajax='false' on the form tag to accomplish a clean load.

Resources