mobile css for radio button not applying in knock template binding - jquery-mobile

I have tried to use knockoutjs template binding to bind fieldsets dynamically which contain group of radio buttons. Here my problem is mobile radio button css not applying for radio buttons. I have searched in stackoverflow I have found issue for button but i didn't find for radio buttons. So can you please find me the solution
<script type="text/x-jquery-tmpl" id="MobileQuestionTemplate">
<div data-role="fieldcontain">
<div class="divborder">
<label id="l2" for="select-choice-1" class="questiontext" data-bind="text: QuestionText"></label>
<br />
<fieldset data-role="controlgroup" data-mini="true" align="center" data- bind="attr: { visible: QuestionType==13,id:QuestionID+'_fld'},template: {name:'MobileOptionTemplate', foreach: OptionList}"></fieldset>
</div>
</div>
</script>
<script type="text/x-jquery-tmpl" id="MobileOptionTemplate">
<input type="radio" data-bind="attr: {id:QuestionID+'_'+OptionID+'_rbt',val:OptionID,name: QuestionID+'_selectedObjects'}"/>
<label data-bind="text: OptionText ,attr: { for: QuestionID+'_'+OptionID+'_rbt'}" />
</script>
<table id="tblMobileMgrQuestions" data-bind="template: {name:'MobileQuestionTemplate', foreach: MobileManagerviewmodel.ManagerQuestions}">
</table>
Can you please tell me where I need to change the code in js to apply css
$.ajax(
{
url: "/Render/LoadSurveyManagerQuestions?surveyGuid=" + surveyGuid + "&surveyItemGuid=" + rsg,
success: function (result)
{
ko.bindingHandlers['button'] =
{
init: function (element, valueAccessor)
{
debugger;
$(element).button(ko.utils.unwrapObservable(valueAccessor()));
}
}
debugger;
var SurveyManagerQuestion = function (managerQuestions)
{
var Self = this;
Self.ManagerQuestions = ko.observableArray(managerQuestions);
Self.AssignQuestionAnswer = function (option)
{
ko.utils.arrayFirst(Self.ManagerQuestions(), function (question)
{
if (question.QuestionID == option.QuestionID)
{
question.OptionId = option.OptionID;
question.OptionText = option.OptionText;
}
});
};
Self.Save = function ()
{
alert('hi');
};
};
debugger;
MobileManagerviewmodel = new SurveyManagerQuestion(result);
ko.applyBindings(MobileManagerviewmodel, document.getElementById("tblMobileMgrQuestions"));
}
});
Thanks for any help in advance.

To enhance the markup of radio buttons dynamically, use the below.
$('input[type=radio]').checkboxradio().trigger('create')

Related

knockout.js ul li databinding not proper

HTML
<h4>People</h4>
<ul data-bind="foreach: people">
<li>
<span data-bind="text: name"> </span>
Remove
</li>
</ul>
<button data-bind="click: addPerson">Add</button>
<input type="text" data-bind="value: cardtext" /><br /><br /><br />
JS
function AppViewModel() {
var self = this;
self.cardtext=ko.observable();
self.people = ko.observableArray([
{ name: 'Bert' },
{ name: 'Charles' },
{ name: 'Denise' }
]);
self.addPerson = function() {
self.people.push({ name: self.cardtext });
};
self.removePerson = function() {
self.people.remove(this);
}
}
ko.applyBindings(new AppViewModel());
This is the result
The problem is that the textbox keep adding new elements but the previous newly added elements keep getting updated by the new elements.
3rd element was 3rd element
4th element was 4th element
when I added 5th element the 3rd and the 4th element get updated by 5th element. why it is that? what I am doing wrong?. I have no idea.
You just need to add () at the end of self.cardtext(). If you don't put the parenthesis, what it will do is it will push the observable object of cardtext to the array instead of its value. So when you modify cardtext from the textbox, it will also modify the previous object that was pushed.
function AppViewModel() {
var self = this;
self.cardtext=ko.observable();
self.people = ko.observableArray([
{ name: 'Bert' },
{ name: 'Charles' },
{ name: 'Denise' }
]);
self.addPerson = function() {
self.people.push({ name: self.cardtext() });
};
self.removePerson = function() {
self.people.remove(this);
}
}
ko.applyBindings(new AppViewModel());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<h4>People</h4>
<ul data-bind="foreach: people">
<li>
<span data-bind="text: name"> </span>
Remove
</li>
</ul>
<button data-bind="click: addPerson">Add</button>
<input type="text" data-bind="value: cardtext" /><br /><br /><br />

Foreach not updating HTML list elements

Using knockout 2.2.0
I'm trying to use the same dialog for add and edit. I have the code mostly working, but when I replace the observable with the new edited one, it doesn't cause an update in the foreach (or at least it continues to display the old values) It does update the actual model, as I can see in dev tools. I even tried to force an update with .valueHasMutated(), but with no luck.
self.editReference = function () {
self.isEdit(true);
self.open();
self.dialogReferences(this);
};
self.saveEditReference = function () {
self.references.replace(this, self.dialogReferences);
self.references.valueHasMutated();
self.dialogReferences(newReferences());
self.close();
};
And here is the some of the partial view with the references section of HTML code:
<ul class="sortable references-summary" data-bind="foreach: references">
<li class="ui-state-default"><b>Name: </b><!-- ko text:name --><!-- /ko--><br /><b>Company: </b><!-- ko text:company --><!-- /ko--><span class="ui-icon ui-icon-closethick"></span><span class="ui-icon ui-icon-wrench"></span></li>
</ul>
Thanks to CrimsonChris for pointing out my bug. The updated code below works as expected.
The approach is to have a reference you are editing, in addition to the references in your array. When you start to edit, you copy the values from the array to your edit reference. When you save the edit, you copy them back. There is no need for valueHasMutated for this to work.
function reference(name, company) {
return {
name: ko.observable(name),
company: ko.observable(company)
};
}
// Copy r1 into r2
reference.copy = function(r1, r2) {
r2.name(r1.name());
r2.company(r1.company());
}
var self = {
editingReference: undefined,
dialogReferences: reference('', ''),
references: ko.observableArray([
reference('One', 'First Company'),
reference('Two', '2nd Company')
]),
dialogIsOpen: ko.observable(false),
open: function() {
self.dialogIsOpen(true);
},
close: function() {
self.dialogIsOpen(false);
}
};
self.editReference = function(item) {
self.editingReference = item;
self.open();
reference.copy(item, self.dialogReferences);
};
self.removeReference = function(item) {
self.references.remove(item);
self.close();
};
self.saveEditReference = function(item) {
reference.copy(item, self.editingReference);
self.close();
};
ko.applyBindings(self);
<link href="//code.jquery.com/ui/1.11.3/themes/smoothness/jquery-ui.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/2.2.0/knockout-min.js"></script>
<ul class="sortable references-summary" data-bind="foreach: references">
<li class="ui-state-default"> <b>Name: </b>
<!-- ko text:name() -->
<!-- /ko-->
<br /> <b>Company: </b>
<!-- ko text:company() -->
<!-- /ko--> <span class="ui-icon ui-icon-closethick"></span>
<span class="ui-icon ui-icon-wrench"></span>
</li>
</ul>
<div data-bind="if: dialogIsOpen">
<div data-bind="with:dialogReferences">
<label>Name</label>
<input data-bind="value:name" />
<br/>
<label>Company</label>
<input data-bind="value:company" />
<input type="button" value="Save" data-bind="click: $parent.saveEditReference" />
</div>
</div>

How to open the same jQuery Dialog from dynamically and non-dynamically created controls

I need to open the same jQuery dialog from different input text controls (including those that have been created dynamically)
This is what my page displays when it loads for the first time.
When the user presses the "Add" button a new row is added to the table
So far so good. The problem comes when I have to open the dialog that will let users enter text into the inputs ( the dialog will display upon clicking on them)
At first , I thought it would only be necessary to add a class to all the controls and then using the class selector just call the dialog.
Unfortunately then I learned that with dynamic controls you have to use ".on" to attach them events.
Once overcome these difficulties , I run into one more that I haven't been able to solve yet. This is that if you don't want the dialog to be automatically open upon initialization, you have to set "autoOpen" to false. I did so but the only result I got was that none on the inputs worked.
I have also tried putting all the code ,regarding the dialog, into a function and then calling that function when an input is clicked
I did also try declaring a variable and setting that variable to the dialog , something like this:
var dialog= $( "#dialog" )
But it didn't work either
I have tried some possibles solutions , but no luck as of yet.
EDIT : Here's a fiddle so you can have a better idea of what I'm talking about:
http://jsfiddle.net/3BXJp/
Full screen result: http://jsfiddle.net/3BXJp/embedded/result/
Here is the html code for the aspx page (Default.aspx):
<form id="form1" runat="server">
<div>
<fieldset>
<legend>Expression Builder</legend>
<table id="myTable" class="order-list">
<thead>
<tr>
<td colspan="2">
</td>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: right;">
IF(<input type="text" name="condition1" class="showDialog" />
:
</td>
<td>
<input type="text" name="trueValue" class="showDialog" />
)
</td>
<td>
<a class="deleteRow"></a>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="5" style="text-align: left;">
<input type="button" id="addrow" value="+ Add" />
</td>
</tr>
<tr>
<td colspan="">
ELSE (
<input type="text" name="else" id="else" class="showDialog" />)
</td>
</tr>
</tfoot>
</table>
</fieldset>
<br />
<input type="button" id="btnEnviar" value="Send" />
</div>
<div id="dialog-form" title="Add New Detail">
<p>
All the fields are required.</p>
<table>
<tr>
<td>
<label for="condition" id="lblcondition">
Condition</label>
</td>
<td>
<input type="text" name="condition" id="condition" class="text ui-widget-content ui-corner-all" />
</td>
</tr>
<tr>
<td>
<label for="returnValue" id="lblreturnValue">
Return Value</label>
</td>
<td>
<input type="text" name="returnValue" id="returnValue" class="text ui-widget-content ui-corner-all" />
</td>
</tr>
</table>
</div>
</form>
and here is the javascript code:
<script type="text/javascript">
$(document).ready(function () {
var counter = 0;
$("button, input:submit, input:button").button();
$('input:text').addClass("ui-widget ui-state-default ui-corner-all");
var NewDialog = $("#dialog-form");
NewDialog.dialog({ autoOpen: false });
var Ventana = $("#dialog-form");
$("#addrow").on("click", function () {
var counter = $('#myTable tr').length - 2;
$("#ibtnDel").on("click", function () {
counter = -1
});
var newRow = $("<tr>");
var cols = "";
cols += '<td>ELSE IF(<input type="text" name="condition' + counter + '" class="showDialog1" /> </td>';
cols += '<td>: <input type="text" name="TrueValue' + counter + '" class="showDialog1" />)</td>';
cols += '<td><input type="button" id="ibtnDel" value="-Remove"></td>';
newRow.append(cols);
var txtCondi = newRow.find('input[name^="condition"]');
var txtVarlorV = newRow.find('input[name^="TrueValue"]');
newRow.find('input[class ="showDialog1"]').on("click", function () {
//Seleccionar la fila
$(this).closest("tr").siblings().removeClass("selectedRow");
$(this).parents("tr").toggleClass("selectedRow", this.clicked);
Ventana.dialog({
autoOpen: true,
modal: true,
height: 400,
width: 400,
title: "Builder",
buttons: {
"Add": function () {
txtCondi.val($("#condition").val());
txtVarlorV.val($("#returnValue").val());
$("#condition").val("");
$("#returnValue").val("");
$(this).dialog("destroy");
},
Cancel: function () {
//dialogFormValidator.resetForm();
$(this).dialog("destroy")
}
},
close: function () {
$("#condition").val("");
$("#returnValue").val("");
$(this).dialog("destroy")
}
});
return false;
});
$("table.order-list").append(newRow);
counter++;
$("button, input:submit, input:button").button();
$('input:text').addClass("ui-widget ui-state-default ui-corner-all");
});
$("table.order-list").on("click", "#ibtnDel", function (event) {
$(this).closest("tr").remove();
});
$("#btnEnviar").click(function () {
//Armo el objeto que servira de parametro, para ello utilizo una libreria JSON
//Este parametro mapeara con el definido en el WebService
var params = new Object();
params.Expresiones = armaObjeto();
$.ajax({
type: "POST",
url: "Default.aspx/Mostrar",
data: JSON.stringify(params),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data, textStatus) {
if (textStatus == "success") {
loadMenuVar(data);
}
},
error: function (request, status, error) {
alert(jQuery.parseJSON(request.responseText).Message);
}
});
});
$(".showDialog").click(function () {
Ventana.dialog({
autoOpen: true,
modal: true,
height: 400,
width: 400,
title: "Constructor",
buttons: [
{ text: "Submit", click: function () { doSomething() } },
{ text: "Cancel", click: function () { $(this).dialog("destroy") } }
],
close: function () {
$(this).dialog("option", "autoOpen", false);
$(this).dialog("destroy")
}
});
return false;
});
});
This is the closest I've been able to get to the solution, but still can't get the dialog to remain hidden until a input is clicked
Any advise or guidance would be greatly appreciated.
P.S. Sorry for my bad english
I suspect it's because you're using destroy() rather than close() on the dialog. At the moment it looks like you're creating and destroying the dialog each time, don't do that. You should create the dialog once, isolate the dialog functionality to a separate function, and then just use open() and close() on it (you'll have to do some extra work to get the values into the right fields).
You can make your current code work if you style the dialog as hidden it'll stop happening, add this to your HTML (in the <HEAD>):
<style>
#dialog-form {
display: none;
}
</style>
you should probably have a separate style-sheet file you include that has that style in it. Similarly you should put all your JS in a separate file if it isn't already.
But I'd definitely look at re-writing the whole thing to follow the guidelines above, it does look like it can be made a lot simpler which makes it easier to support in the future.
EDIT
This is a simplified version that shows how I would do it.
Script:
var counter = 1; // Counter for number of rows
var currentRow = null; // Current row selected when dialog is active
// Create the dialog
$("#dialog-form").dialog({
autoOpen: false,
dialogClass: "no-close", // Hide the 'x' to force the user to use the buttons
height: 400,
width: 400,
title: "Builder",
buttons: {
"OK": function(e) {
var currentElem = $("#"+currentRow); // Get the current element
currentElem.val($("#d_input").val()); // Copy dialog value to currentRow
$("#d_input").val(""); // Clear old value
$("#dialog-form").dialog('close');
},
"Cancel": function(e) {
$("#d_input").val(""); // Clear old value
$("#dialog-form").dialog('close');
}
}
});
// This function adds the dialog functionality to an element
function addDialog(elemId) {
elem = $("#"+elemId);
elem.on('click', function() {
currentRow = $(this).attr('id');
$("#dialog-form").dialog('open');
});
}
// Add functionality to the 'add' button
$("#addRow").on('click', function () {
counter = counter + 1;
var newId = "in"+counter;
var newRow = "<tr><td><input id='"+newId+"' class='showDialog'></td></tr>";
$('TBODY').append(newRow);
// add the dialog to the new element
addDialog(newId);
});
// add the dialog to the first row
addDialog("in1");
HTML:
<div>
<fieldset>
<legend>Expression Builder</legend>
<table id="myTable" class="order-list">
<tbody><tr>
<td><input id='in1' class='showDialog'></td>
</tr>
</tbody>
</table>
<input type='button' id='addRow' value='add'></input>
</fieldset>
<br />
<input type="button" id="btnEnviar" value="Send" />
</div>
<div id="dialog-form" title="Add New Detail">
<input type="text" id="d_input" />
</div>
Fiddle
This isolates the different functionality into different functions. You can easily expand it to do what you want. If you want the remove functionality I'd consider having a remove button for every row with a given class with a trigger function that removes that row (and the button). Then have a separate count of active rows. At the start use disable() to disable the single button, when you add a row enable() all the buttons of that class. When you remove a row then disable the buttons is existingRows <= 1.

How to get text box value in ember.js

i have started to work on ember.js just day before.
i don't know how to get text box value while submitting. i have tried like this
this is html
<script type="text/x-handlebars" data-template-name="index">
<div >
<p>{{view Ember.TextField valueBinding="fname"}}</p>
</div>
<div>
<p>{{view Ember.TextField valueBinding="lname"}}</p>
</div>
<button {{action save}}>submit</button>
</script>
this is my ember.js file
App = Ember.Application.create();
App.IndexController = Ember.ObjectController.extend({
save:function()
{
var fname=this.get('fname');
var lname=this.get('lname');
alert(fname+','+lname);
}
});
whenever i am clicking on submit button, i am getting undefined in alert.so how to get value? i hope anyone will help me for to continue in ember.js
in js like this
App.WebFormController = Ember.Controller.extend({
fname: null,
lname: null,
save: function () {
var fname = this.get('fname');
var lname = this.get('lname');
alert(fname + ',' + lname);
}
});
without need a model
in template like this
<script type="text/x-handlebars" data-template-name="web_form">
<form {{action save on="submit"}}>
<div >
<p>{{input type="text" valueBinding="fname"}}</p>
</div>
<div>
<p>{{input type="text" valueBinding="lname"}}</p>
</div>
<button>submit</button>
</form>
</script>
Your problem is that your form doesn't have a model. You can provide it using model or setupController hook.
App.IndexRoute = Ember.Route.extend({
model: function() {
return {};
},
// or
setupController: function(controller) {
controller.set('model', {});
}
});
In addition some tips:
Use the action name on="submit" in the form, instead of action name in submit button. So you can execute the action when the user press enter key, in input.
And the input type="text" helper is a shortcut for view Ember.TextField
<script type="text/x-handlebars" data-template-name="index">
<form {{action save on="submit"}}>
<div >
<p>{{input type="text" valueBinding="fname"}}</p>
</div>
<div>
<p>{{input type="text" valueBinding="lname"}}</p>
</div>
<button>submit</button>
<form>
</script>
Here a live demo
That is really nice tutorial by mavilein.
We can do it at controller level also.
App.IndexController = Ember.ObjectController.extend({
content:function(){
return {fname:null,lname:null}
}.property(),
save:function()
{
var fname=this.get('fname');
var lname=this.get('lname');
alert(fname+','+lname);
}
});
Or we can do it
App.IndexController = Ember.ObjectController.extend({
fname:null,
lname:null,
save:function()
{
var fname=this.get('fname');
var lname=this.get('lname');
alert(fname+','+lname);
}
});
Below code is working for me:
cshtml: In script on tag specify data-template-name="text"
<script type="text/x-handlebars" data-template-name="text">
{{view Ember.TextField value=view.message}}
{{view Ember.TextField value=view.specy}}
{{textarea value=view.desc id="catdesc" valueBinding="categor" cols="20" rows="6"}}
<button type="submit" {{action "submit" target=view}}>Done</button>
</script>
app.js:
App.TextView = Ember.View.extend({
templateName: 'text',
message:'',
specy: '',
desc:'',
actions: {
submit: function (event) {
var value = this.get('specy');
var spc = this.get('message');
var de = this.get('desc');
}
}
});

jQuery Mobile and Knockout.js templating, styling isnt applied

Ok so this is beginning to drive me insane. I have for several hours now searched and searched, and every single solution doesnt work for me. So yes, this question might be redundant, but i cant for the life of me get solutions to work.
I have a bunch of checkboxes being generated by a jquery template that is databound via knockout.js. However, it turns up unstyled. Afaik, it is something about jquery mobile does the styling before knockout renderes the template, so it ends up unstyled.
I have tried numerous methods to no avail, so i hope someone here can see what i am doing wrong.
(i am using jquery mobile 1.2.0 , jquery 1.8.2 and knockout 2.2.1)
This is the scripts:
<script type="text/javascript">
jQuery.support.cors = true;
var dataFromServer = "";
// create ViewModel with Geography, name, email, frequency and jobtype
var ViewModel = {
email: ko.observable(""),
geographyList: ["Hovedstaden","Sjælland","Fyn + øer","Nordjylland","Midtjylland","Sønderjylland" ],
selectedGeographies: ko.observableArray(dataFromServer.split(",")),
frequencySelection: ko.observable("frequency"),
jobTypes: ["Kontor (administration, sekretær og reception)","Jura","HR, Ledelse, strategi og udvikling","Marketing, kommunikation og PR","Handel og service (butik, service, værtinde og piccoline)","IT","Grafik og design","Lager, chauffør, bud mv.","Økonomi, regnskab og finans","Kundeservice, telefoninterview, salg og telemarketing","Sprog","Øvrige jobtyper"],
selectedJobTypes: ko.observableArray(dataFromServer.split(",")),
workTimes: ["Fulltid","Deltid"],
selectedWorkTimes: ko.observableArray(dataFromServer.split(","))
};
// function for returning checkbox selection as comma separated list
ViewModel.selectedJobTypesDelimited = ko.dependentObservable(function () {
return this.selectedJobTypes().join(",");
}, ViewModel);
var API_URL = "/webapi/api/Subscriptions/";
// function used for parsing json message before sent
function omitKeys(obj, keys) {
var dup = {};
var key;
for (key in obj) {
if (obj.hasOwnProperty(key)) {
if (keys.indexOf(key) === -1) {
dup[key] = obj[key];
}
}
}
return dup;
}
//Function called for inserting new subscription record
function subscribe() {
if($("#jobmailForm").valid()=== true){
//window.alert("add subscriptiooncalled");
var mySubscription = ko.toJS(ViewModel);
//var json = JSON.stringify(mySubscription);
var jsonSmall = JSON.stringify(omitKeys(mySubscription, ['geographyList','jobTypes','selectedJobTypesDelimited','workTimes']));
//window.alert(jsonSmall);
$.ajax({
url: API_URL,
cache: false,
type: 'POST',
contentType: 'application/json',
data: jsonSmall,
success: function (data) {
window.alert("success");
},
error: function (error) {
window.alert("ERROR STATUS: " + error.status + " STATUS TEXT: " + error.statusText);
}
});
}
}
function initializeViewModel() {
// Get the post from the API
var self = this; //Declare observable which will be bind with UI
// Activates knockout.js
ko.applyBindings(ViewModel);
}
// Handle the DOM Ready (Finished Rendering the DOM)
$("#jobmail").live("pageinit", function() {
initializeViewModel();
$('#jobmailDiv').trigger('updatelayout');
});
</script>
<script id="geographyTmpl" type="text/html">
<input type="checkbox" data-role="none" data-bind="attr: { value: $data }, attr: { id: $data }, checked: $root.selectedGeographies" />
<label data-bind="attr: { for: $data }"><span data-bind="text: $data"></span></label>
</script>
<script id="jobTypeTmpl" type="text/html">
<label><input type="checkbox" data-role="none" data-bind="attr: { value: $data }, checked: $root.selectedJobTypes" /><span data-bind="text: $data"></span></label>
</script>
Note, "jobmail" is the surrounding "page" div element, not shown here. And this is the markup:
<div data-role="content">
<umbraco:Item field="bodyText" runat="server"></umbraco:Item>
<form id="jobmailForm" runat="server" data-ajax="false">
<div id="jobmailDiv">
<p>
<label for="email">Email</label>
<input type="text" name="email" id="email" class="required email" data-bind="'value': email" />
</p>
<fieldset data-role="controlgroup" data-mini="true" data-bind="template: { name: 'geographyTmpl', foreach: geographyList, templateOptions: { selections: selectedGeographies } }">
<input type="checkbox" id="lol" />
<label for="lol">fkfkufk</label>
</fieldset>
<fieldset data-role="controlgroup" data-mini="true">
<p data-bind="template: { name: 'jobTypeTmpl', foreach: jobTypes, templateOptions: { selections: selectedJobTypes } }"></p>
</fieldset>
<fieldset data-role="controlgroup" data-mini="true">
<input type="radio" id="frequency5" name="frequency" value="5" data-bind="checked: frequencySelection" /><label for="frequency5">Højst 5 gange om ugen</label>
<input type="radio" id="frequency3" name="frequency" value="3" data-bind="checked: frequencySelection" /><label for="frequency3">Højst 3 gange om ugen</label>
<input type="radio" id="frequency1" name="frequency" value="1" data-bind="checked: frequencySelection" /><label for="frequency1">Højst 1 gang om ugen</label>
</fieldset>
<p>
<input type="button" value="Tilmeld" class="nice small radius action button" onClick="subscribe();">
</p>
Tilbage
</div>
</form>
Alternate method of invoking the restyling (doesnt work either):
$(document).on('pagebeforeshow', '#jobmail', function(){
// Get the post from the API
var self = this; //Declare observable which will be bind with UI
// Activates knockout.js
ko.applyBindings(ViewModel);
});
// Handle the DOM Ready (Finished Rendering the DOM)
$("#jobmail").live("pageinit", function() {
$('#jobmail').trigger('pagecreate');
});
Use a custom binding (Knockout) to trigger jQuery Mobile to enhance the dynamically created content produced by Knockout.
Here is a simple custom binding:
ko.bindingHandlers.jqmEnhance = {
update: function (element, valueAccessor) {
// Get jQuery Mobile to enhance elements within this element
$(element).trigger("create");
}
};
Use the custom binding in your HTML like this, where myValue is the part of your view model that changes, triggering the dynamic content to be inserted into the DOM:
<div data-bind="jqmEnhance: myValue">
<span data-bind="text: someProperty"></span>
My Button
<input type="radio" id="my-id" name="my-name" value="1" data-bind="checked: someOtherProperty" /><label for="my-id">My Label</label>
</div>
In my own case, myValue was part of an expression in an if binding, which would trigger content to be added to the DOM.
<!-- ko if: myValue -->
<span data-bind="jqmEnhance: myValue">
<!-- My content with data-bind attributes -->
</span>
<!-- /ko -->
Every dynamically generated jQuery Mobile content must be manually enhanced.
It can be done in few ways, but most common one can be done through the jQuery Mobile function .trigger( .
Example:
Enhance only page content
$('#page-id').trigger('create');
Enhance full page (header + content + footer):
$('#page-id').trigger('pagecreate');
If you want to find more about this topic take a look my other ARTICLE, to be more transparent it is my personal blog. Or find it HERE.

Resources