I have a page with a set of radio buttons that is dynamically created by knockout based on the selection of a drop down on the page. This is all working fine but the problem I have is that the "checked" binding on the radio buttons does not seem to be cleared if the radio button is removed due to a change of the drop down. This leaves me with a ViewModel with a value for "checked" when in fact nothing on the view is checked (or at least nothing that can be seen).
What I would expect to happen is that once the radio button is removed the checked binding would go back to being null but I can only assume the binding does not get updated if the radio button is removed from the DOM.
You can see this happening on jsfiddle - basically if you select a radio button and then change the drop down the selected value will still refer to the now removed (and therefore unchecked) radio button.
HTML:
<ul data-bind='foreach: availableChildren'>
<li>
<label>
<input type="radio" name="children" data-bind="checked: $root.selectedChild, value: id" /><span data-bind="text: name"></span>
</label>
</li>
ViewModel:
var ViewModel = function (settings) {
var availableParents = ko.observableArray(settings.parents),
selectedParent = ko.observable(),
availableChildren = ko.computed(function () {
if (!selectedParent()) {
return null;
}
return selectedParent().children;
}),
selectedChild = ko.observable();
return {
availableParents: availableParents,
selectedParent: selectedParent,
availableChildren: availableChildren,
selectedChild: selectedChild,
};
};
Is there anyway to get this to work as I would expect or is this just something that has been missed from Knockout?
I added this snippet to your viewmodel to get the behaviour you wanted:
// create internal computed
ko.computed(function() {
// add dependency to selectedParent
var s = selectedParent();
// reset selectedChild
selectedChild('');
});
Your updated fiddle: http://jsfiddle.net/danne567/avbU7/2/
Related
Basically I replaced the div in the content as soon as I click "Delete" on the Setting menu above. Well it does changes from collapsible set into checkbox with footer below containing two buttons. The buttons are delete and cancel but I can't perform anything with those buttons. For example, If Cancel clicked it should pop the alert popup (For the sake of testing). Please help..
<div data-role="content">
Tambah Katagori
<div id="Outcome" data-role="collapsibleset" data-theme="a" data-content-theme="a" data-collapsed-icon="arrow-r" data-expanded-icon="arrow-d"></div>
</div>
$("#Delete").click(function(){
$("#Outcome").replaceWith('<form><fieldset data-role="controlgroup" id="OutcometoDelete">');
db.transaction (function (transaction)
{
var sql = "SELECT * FROM KatagoriPengeluaran";
transaction.executeSql (sql,[],
function (transaction, result)
{
if (result.rows.length)
{
for(var i = 0; i< result.rows.length; i++ ) {
All2 =result.rows.item(i);
element = $(' <input type="checkbox" name="'+All2.Katagori+'" id="'+All2.Katagori+'"><label for="'+All2.Katagori+'">'+All2.Katagori+'</label>').appendTo($('#OutcometoDelete'));
}
All2 =result.rows.item((result.rows.length-1));
$('#'+All2.Katagori).append('</form></fieldset>');
$("#OutcometoDelete").append('<div id="someFooter" data-role="footer" data-position="fixed"><div id ="navbarFooter" data-role="navbar"><ul><li><a data-role="button" href="#popUpDelete">Delete</a></li><li><a data-role="button" href="index.html#Pengeluaran" data-ajax="false" id="cancelDelete" >Cancel</a></li></ul></div></div>');
$("#OutcometoDelete").trigger('create');
$("#someFooter").trigger('pagecreate');
$('#navbarFooter').trigger('pagecreate');
}
else
{
alert ("Retrieval Error");
}
}, error);
});
});
$("#cancelDelete").click(function(){
alert("oi");
});
This is because your way of event binding will not work for future elements. You can't just bind click event and expect it will work in the future, event(s) must be bind to something inside the DOM.
So this code will not work:
$("#cancelDelete").click(function(){
alert("oi");
});
On the other hand this code will work:
$(document).on('click',"#cancelDelete",function(){
alert("oi");
});
Second code will work because event is bind to document and it will propagate as soon as needed element is part of the DOM and appropriate event is trigger on it. This is also called delegated event binding.
Have the following READONLY textbox:
#Html.TextBoxFor(model => model.ClientNumber, new {#readonly = "readonly", #class ="message-label"})
and Save button:
<button type="submit" id="btnSave" name="Command" value="Save">Save</button>
When user clicks on Client Number text box and hits Enter, then submit behavior is invoked and next page is displayed after data is saved to the database.
How to change this, so that hitting Enter while in this field does nothing, similar to how page behaves for a usual label?
You can do this with a little bit of javascript, handling keydown event and checking whether Enter was hit:
$(document).ready(function() {
$('input[name=ClientNumber]').keydown(function(e) {
if (e.keyCode === 13) {
e.preventDefault();
return false;
}
});
});
I am new to jquery mobile. In my UI, one text box and one select menu are there. Initially select menu is empty.If the textbox value is more than 1 then some data is added to the select menu otherwise select menu is empty. For this, i am calling the function at the onchange of select menu but it is not working. Please can anybody help me.
Edit:
Ex:
$('#Goal_Time').bind( "focus", function(event, ui)
{
if(Goal_WeightVar.val() > 0)
{
Goal_WtVar = Math.abs(weightVar.val() - Goal_WeightVar.val());
Min_DurationVar = Math.round(Goal_WtVar * 2.2);
for(var i=0;i<10;i++)
{
$('#Goal_Time').append('<option value=Min_DurationVar>Min_DurationVar</option>');
}
}
});
thanks
Well Kinda working example:
http://jsfiddle.net/v5DC3/5/
JS
$('#Goal_WeightVar').live('change', function() {
var weightVar = 0; // for testing only
var goalWeightVar = $('#Goal_WeightVar').val();
if(goalWeightVar > 0)
{
Goal_WtVar = Math.abs(weightVar - goalWeightVar);
Min_DurationVar = Math.round(Goal_WtVar * 2.2);
for(var i=0;i<10;i++)
{
$('#Goal_Time').append('<option value='+Min_DurationVar+'>'+Min_DurationVar+'</option>');
}
$('#Goal_Time').listview('refresh');
}
});
HTML
<div data-role="page" id="Goal_Time_Page">
<div data-role="content">
<label for="Goal_WeightVar">Goal Weight:</label>
<input type="text" name="Goal_WeightVar" id="Goal_WeightVar" value="" />
<label for="Goal_Time" class="select">Goal Time:</label>
<select name="Goal_Time" id="Goal_Time">
<!-- Add options here -->
</select>
</div>
</div>
You will need to tweak it
As it says in the docs of jQuery Mobile, you have to tell the select menu to update it's contents by calling $('select').selectmenu();
If it still doesn't work you'll have to post a little sample code so I can have a look at it.
Edit:
Actually, that's not even necessary. If you have an empty <select id="to-append"></select>, you can just add options via $('#to-append').append('<option value="a">A</option>')!
The onchange event of the select is probably not the right event to do this though. The select will not change as long as it's empty, thus your event will never get triggered. Try the blur event of the text box.
jQuery Mobile Docs - Select
How I can create a drop down list using select_tag "xyz", options_for_select or any way where on selecting any option from down list and hitting button will redirect me.
Any help??
<td>
<%= select_tag "options", options_for_select(
[["Dashboard",
"/homes/"+registrar.enrollment_application.id.to_s
]] ) %>
</td>
<input type="button" value="Select" onclick = "check_options()" >
if above code is right then all i need to write a javascript?? please let me now
function = check_options() {
If you can use javascript or even jquery on the client side you could set the window.location based on the selected item in the drop down, after you click the button:
HTML: This is how you set up your select list and a button
<select id="options">
<option value="http://stackoverflow.com">Stack Overflow</option>
<option value="http://google.com/">Google</option>
</select>
<input type="button" id="optionsbutton" value="Go" />
JavaScript: This is how you wire up the button click to the window redirect
var onButtonClick = function() {
window.location.replace($("#options").val()) //<--- This gets the selected value
// and redirects the window
}
$(document).ready(function(){
$("#optionsbutton").click(onButtonClick); //<--- This hooks up the button click
// to do the onButtonClick function
});
See How to redirect to another webpage in JavaScript/jQuery? for more details.
Update Using Provided Code
You'd just have to make your check_options function find the selected value and set the window location:
var check_options = function() {
window.location.replace($(" [ use selector for select element ] ").val());
});
You should add javascript like this
function check_options() {
window.location = document.getElementById("options").value
}
I've read a few solutions on here, but my problem differs enough where those will not work. Basically if the radio button is checked, add a css class to the parent div. If the radio is not checked, remove the css class. Sounds simple?
I have more than one radio button group, so in other words, there will be multiple radio buttons selected at a time. Each radio button group also is on different parts of the page seperated by other html.
Here is what I came up with:
$(document).ready(function () {
$('input').click(function () {
if ($('input:not(:checked)')) {
$('div').removeClass('style1');
}
if ($('input').is(':checked')) {
$(this).parent().addClass('style1');
}
});
});
I think I'm on the right path with the input:not(:checked), but on the next line it removes style1 from all div elements instead of checking if other divs radio button child is checked.
I guess what I'm asking is how do I write a script that when a radio button is clicked, add a css class to the parent and then find all div tags on the page that have a child of input. If the divs child input is not checked, remove the css class. So if a div has a child input element and it is checked, don't remove the css class from the inputs div.
I hope that makes sense.
Why not using the following: http://jsfiddle.net/Q2bzT/
$(document).ready(function () {
$('input').click(function () {
$('input:not(:checked)').parent().removeClass("style1");
$('input:checked').parent().addClass("style1");
});
});
Assuming your radio buttons utilize the name property to properly group them, when one changes, you can find the radios with the same name, and remove the class, then add the class to the one that was activated.
Try it out: http://jsfiddle.net/U2AAQ/
$(document).ready(function () {
$(':radio').change(function () {
$(':radio[name=' + this.name + ']').parent().removeClass('style1');
$(this).parent().addClass('style1');
});
});
I had a similar issue but I needed to target the radio button's label instead of a parent div element. I also needed to make sure the other related label elements did not have the class.
Here's what I came up with based on #user113716's answer:
HTML
MVC code removed so there is only HTML in this example
<ol class="list-group">
<li class="list-group-item">
<div class="input-group">
<label for="choice_ChoiceId" class="form-control">ChoiceDescription</label>
<span class="input-group-addon">
<input type="radio" id="choice_ChoiceId" value="choiceValue" name="choiceName" required />
</span>
</div>
</li>
</ol>
jQuery
$(':radio').click(function () {
var _groupName = $(this).attr('name'),
_radioId = $(this).attr('id'),
_radioGroup = $(':radio[name="' + _groupName + '"]');
//remove class from all labels for this group of radio buttons
_radioGroup.each(function(){
$('label[for*="' + $(this).attr('id') + '"]').removeClass('style1');
});
//add the class to the selected radio button
$('label[for*="' + _radioId + '"]').addClass('style1');
});
JavaScript
'use strict';
var o = 'label.input-check, label.input-radio';
$(o).find('input').change(function () {
$(o).find('input').filter('input[name="' + (this).name + '"]').each(function () {
$(this).parent(o).toggleClass('checked', (this).checked);
});
}).trigger('change');
Demo: http://jsfiddle.net/3uwp9c2n/
Just optimize if you need.