Why doesn't this simple Knockout.js example work? - javascript

I am playing around with Knockout.js and created this simple example: http://jsfiddle.net/JcTxT/30/
<div id="term_grp" data-role="fieldcontain"><a>Semester:</a>
<fieldset id="term_fields" data-role="controlgroup" data-type="horizontal">
<input type="radio" name="term" id="ss" value="ss" data-bind="checked: term" />
<label for="ss">Sommersemester</label>
<input type="radio" name="term" id="ws" value="ws" data-bind="checked: term" />
<label for="ws">Wintersemester</label>
</fieldset>
Term is <span data-bind="text: pommes"></span>
var aResult = {
term: ko.observable("ss"),
pommes: "TEST"
};
$(document).on('pagebeforeshow', '#mainPage', function () {
ko.applyBindings(aResult);
});
I expected one of the radio button to be checked (the one with the value "ss" but this is not the case. Does anyone know, why?
Cheers

It works, if you use:
$(function () {
ko.applyBindings(aResult);
});
And turn off jquery mobile.
I tried in your jsfiddle.
If you need jquery mobile, this link works:
http://www.codesizzle.com/jquery-mobile-radio-with-knockout-js/

OK, what needs to be done?
Add another event handler and add it to the binding:
var aResult = {
term: ko.observable("ws"),
pommes: "TEST2"
};
ko.bindingHandlers.mobileradio = {
init: function (element, valueAccessor) {},
update: function (element, valueAccessor) {
var value = valueAccessor();
var valueUnwrapped = ko.utils.unwrapObservable(value);
if (valueUnwrapped == $(element).val()) {
$(element).prop("checked", "true").checkboxradio("refresh");
} else {
$(element).removeProp("checked").checkboxradio("refresh");
}
}
};
$(function () {
ko.applyBindings(aResult);
});
Working fiddle: http://jsfiddle.net/JcTxT/35/

Related

Using prototype function with key event

I'd like to write ajax prototype function that transforms to upper every character after typing it in a formular for several input data.
jQuery.fn.doKeyUpToUpper = function() {
$(this).val($(this).val().toUpperCase());
}
and associate this function with fields :
$('#First').doKeyUpToUpper();
$('#Second').doKeyUpToUpper();
$('#Third').doKeyUpToUpper();
where First, Second and Third are
<input id=First value="" />
<input id=Second value="" />
<input id=Third value="" />
input fields...
Unfortunately, I don't know how to add keyup event to each fields.
Anyone help ?
Thanks
You where well on your way. But only defined the behaviour on "keyup" and didn't actually set the event.
jQuery.fn.doKeyUpToUpper = function () {
$(this).on('keyup', function () {
$(this).val($(this).val().toUpperCase());
});
};
// or a more dynamic alternative
jQuery.fn.toUpperOn = function (event) {
$(this).on(event, function () {
$(this).val($(this).val().toUpperCase());
});
};
// based upon the question in the comments
jQuery.fn.toUpperOn = function (event, callback) {
$(this).on(event, function () {
$(this).val($(this).val().toUpperCase());
if (callback) callback.apply(this, arguments);
});
};
$("#first").doKeyUpToUpper();
$("#second").toUpperOn('keyup');
$("#third").toUpperOn('keyup', function (event) {
console.log(this.id, this.value);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="first" type="text" />
<input id="second" type="text" />
<input id="third" type="text" />
Have a look at the jQuery.on documentation for more details.

How to applyBindings and keep input values with Knockout JS?

I'm building a HTML/KnockoutJS application. My webserver returns a form with input fields with information. When I new up my model and do an ko.applyBindings, naturally the input values are overwritten by the model.
Is there a way to do an ko.applyBindings in which the model is automatically loaded with the data of the input fields?
Example: https://jsfiddle.net/KeesCBakker/p7ygq5y2/1/
HTML:
Title: <input data-bind="textInput: title" value="MyTitle" placeholder="Nothing here!" /><br/>
Text: <input data-bind="textInput: text" value="MyText" placeholder="Nothing here!" /><br/>
<button id="bind">Bind!</button>
JS:
ko.bindingHandlers.initFromInput = {
init: function(element, valueAccessor) {
valueAccessor()(element.value);
}
};
function Model() {
this.title = ko.observable();
this.text = ko.observable();
}
document.getElementById('bind').onclick = function() {
var model = new Model();
ko.applyBindings(model);
};
You could use a custom binding, that tells Knockout to use the input values as default, like this:
ko.bindingHandlers.initFromInput = {
init: function(element, valueAccessor) {
valueAccessor()(element.value);
}
};
Here's a jsfiddle: http://jsfiddle.net/kv3zras3/3/
EDIT:
With the new binding, your data-binds should look something like this:
<input data-bind="initFromInput: title, value: title" value="MyTitle" placeholder="Nothing here!" />
<input data-bind="initFromInput: text, value:text" value="MyText" placeholder="Nothing here!" />
EDIT:
There's an abit nicer way of achieving this, if you make like binding look like this:
var origValueInput = ko.bindingHandlers.value.init;
ko.bindingHandlers.value.init = function(element, valueAccessor, allBindings) {
if (allBindings.has('initValueFromInput')) {
valueAccessor()(element.value);
}
origValueInput.apply(this, arguments);
};
You can write your data-binds like this:
<input value="MyTitle" data-bind="initValueFromInput, value: title"/>
<input value="MyText" data-bind="initValueFromInput, value: text"/>
Here's a fiddle: https://jsfiddle.net/yy51kok5/
I've ended up improving the answer from clean_coding. Add the following anonymous method to a script after loading KnockoutJS. It will reroute both textInput and value handlers.
(function () {
var z = ko.bindingHandlers.textInput.init;
ko.bindingHandlers.textInput.init = function (element, valueAccessor, allBindings) {
if (allBindings.has('initWithElementValue')) {
valueAccessor()(element.value);
}
z.apply(this, arguments);
};
var y = ko.bindingHandlers.value.init;
ko.bindingHandlers.value.init = function (element, valueAccessor, allBindings) {
if (allBindings.has('initWithElementValue')) {
valueAccessor()(element.value);
}
y.apply(this, arguments);
};
}())
It can be used, by specifying it after the textInput or value declaration:
<input type="text" data-bind="textInput: title, initWithElementValue" />
Ended up creating a plugin for Knockout. Added it to GitHub as well.
<script type="text/javascript" src="https://cdn.rawgit.com/KeesCBakker/KnockoutAutomaticFormValueBinding/master/knockout-automatic-form-value-binding-1.0.min.js"></script>
Include the plugin
Set ko.automaticFormValueBinding = true;
Bind ko.applyBindings({yourmodel});
More info at Git: https://github.com/KeesCBakker/KnockoutAutomaticFormValueBinding

Can't get data attribute value from radio button but can from select option

I've written some code that allows me to determine which select option is to be checked based on what is saved to the mysql db. To be able for that to work I need to print value of a data attribute to a hidden input so that I can store the option selected.
My code is working just fine when it comes to the select options, but doesn't seem to be working with the radio buttons. I've put together a demo of the two in jsfiddle or example which can be found here:
http://jsfiddle.net/5ax5Q/
Here is the code, first the html:
<input data-checked="yes" type="radio" name="product-attr-wifi" value="100" checked />Yes
<input data-checked="no" type="radio" name="product-attr-wifi" value="200" />No
<br>
<input type="text" name="product-attr-wifi-checked" />
Here is the jquery:
var optionChecked = function (checkedInput, checkedOuput) {
$(document).ready(function () {
$(checkedInput).bind("change", function () {
var checkedValue = $(this).find(":checked").attr("data-checked");
$(checkedOuput).val(checkedValue);
});
$(checkedInput).trigger("change");
});
};
optionChecked('input[name="product-attr-wifi"]', 'input[name="product-attr-wifi-checked"]');
In the case of radio button, you don't have to use find() because this refers to the radio element which has the data attribute
var optionChecked = function (checkedInput, checkedOuput) {
$(document).ready(function () {
$(checkedInput).bind("change", function () {
var checkedValue = $(this).attr("data-checked");
$(checkedOuput).val(checkedValue);
});
$(checkedInput).filter(':checked').trigger("change");
});
};
Demo: Fiddle
Try this
var optionChecked = function (checkedInput, checkedOuput) {
$(document).ready(function () {
$(checkedInput).on("change", function () {
var checkedValue = $(this).filter(':checked').attr("data-checked");
$(checkedOuput).val(checkedValue);
});
$(checkedInput).filter(':checked').trigger("change");
});
};
DEMO

Convert Javascript onkeypress to knockoutjs to call on enter

I am trying to do everthing I can in KnockoutJS however I am having a hard time getting this to convert to knockoutjs.
I have an input box that upon enter press I need to call addInputName(). This is kind of the old school way I think to do it. Is there a way to do this all in knockout?
<input id="inputName" onkeypress="addInputName(this, event);" />
<input id="addInputName" type="button" data-bind="event: { click: addInputName }" value="Add" />
self.addInputName = function (inputElement, event) {
if (event.keyCode == 13) {
$('#addInputName').click();
}
};
// View
<input id="inputName" data-bind="value: name, enterKey: addInputName" />
<input id="addInputName" type="button" data-bind="click: addInputName" value="Add" />
// ViewModel
function ViewModel() {
var self = this;
self.name = ko.observable();
self.names = ko.observableArray();
self.addInputName = function () {
self.names.push(self.name());
self.name("");
};
}
// Custom Binding
ko.bindingHandlers.enterKey = {
init: function (element, valueAccessor, allBindings, data, context) {
var wrapper = function (data, event) {
if (event.keyCode === 13) {
valueAccessor().call(this, data, event);
}
};
ko.applyBindingsToNode(element, { event: { keyup: wrapper } }, context);
}
};
Custom Bindings #20:05
Look into Custom Bindings. It's an invaluable tool to help get UI logic out of your ViewModel's business logic.
Why not just wrap the inputs inside a form? Then you can change your HTML to
<form data-bind="submit: addInputName">
<input id="inputName" type="text" data-bind="value: name" />
<input id="addInputName" type="submit" value="Submit" />
</form>
Then your KO viewmodel looks something like
var ViewModel = function()
{
var self = this;
self.name = ko.observable();
self.addInputName = function() {
// do stuff
}
}

JQuery UI Diaglog to populate checkbox values to parent

I have a requirement that a user should select the checkbox values from a pop-up and click on submit on pop-up and the selected values should get displayed back to the parent page.
I was playing with some radio box values which I am able to push to the Parent window but struggling with checkbox values.
Here is what my pop-up looks like and my code is
<p>Please Select a language:</p>
<div id="myDialog" title="Select Language">
<br /><br />
<input type="checkbox" name="countryCheckbox[]" value="English" checked = "checked" /> English <br/>
<input type="checkbox" name="countryCheckbox[]" value="French" /> French <br/>
<input type="checkbox" name="countryCheckbox[]" value="Norwagian" /> Norwagian <br/>
<input type="checkbox" name="countryCheckbox[]" value="Swedish" /> Swedish <br/>
<input type="checkbox" name="countryCheckbox[]" value="Hindi" /> Hindi <br/>
<input type="checkbox" name="countryCheckbox[]" value="Chinese" /> Chinese <br/>
<br /><br />
<label for="yes">Yes!</label><input type="radio" id="yes" value="yes" name="question" checked="checked"><br>
<label for="no">No!</label> <input type="radio" id="no" value="no" name="question">
</div>
<p id="text">Selected Languages are: </p>
and my Jquery code that works for the selected radio button is as below
$(function(){
var execute = function(){
var answer;
$("input").each(function(){
(this.checked == true) ? answer = $(this).val() : null;
});
$("<p>").text("You selected " + answer).appendTo($("body"));
$("#myDialog").dialog("close");
}
var cancel = function() {
$("#myDialog").dialog("close");
}
var dialogOpts = {
buttons: {
"Submit": execute,
"Cancel": cancel
}
};
$("#myDialog").dialog(dialogOpts);
});
I'm trying to add the following JQuery code to display the selected checkbox values on the parent pages
$('#myDialog').submit(function(ev){
ev.preventDefault();
var arr = [];
$('input:checkbox:checked').each(function(){
arr.push($(this).val());
});
$(opener.document).contents().find("#text").text(arr.join(","));
self.close();
});
Please suggest as I'm still struggling to integrate the JQuery code of selected checkboxes to be displayed on the parent page.
you would need to iterate over each input and then store that in an array to append it to the body..
$(function () {
var execute = function () {
var answer = [];;
$("input").each(function () {
if (this.checked) answer.push(this.value);
});
for (var i = 0; i < answer.length ; i++)
$("<p>").text("You selected " + answer[i]).appendTo($("body"));
};
});
Check Fiddle
Code
$(function () {
var execute = function () {
var answer = [];;
$("input").each(function () {
if (this.checked) answer.push(this.value);
});
for (var i = 0; i < answer.length; i++)
$("<p>").text("You selected " + answer[i]).appendTo($("body"));
};
var cancel = function () {
$("#myDialog").dialog("close");
}
var dialogOpts = {
buttons: {
"Submit": execute,
"Cancel": cancel
}
};
$("#myDialog").dialog(dialogOpts);
});
EDIT
var cancel = function () {
$("#myDialog").dialog("close");
}
var saveAndCancel = functionI() {
execute();
cancel();
}
var dialogOpts = {
buttons: {
"Submit": saveAndCancel ,
"Cancel": cancel
}
};

Categories

Resources