render radio button in asp.net mvc using knockout - asp.net

my model -
public class Model
{
public String SelectedValue;
}
action method -
public ActionResult Index()
{
Model model = new Model();
model.SelectedValue = "a";
return View("Index1", model);
}
view -
<input type="radio" name="Group1" value="a" data-bind="attr: { checked: SelectedValue }" />
<input type="radio" name="Group1" value="b" data-bind="attr: { checked: SelectedValue }" />
<input type="radio" name="Group1" value="c" data-bind="attr: { checked: SelectedValue }" />
<script type="text/javascript">
var data = #Html.Raw(new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(Model));
BindData();
</script>
My javascript -
function BindData() {
viewModelData = ko.mapping.fromJS(data);
ko.applyBindings(viewModelData);
}
When my view is rendered, it renders all three radio buttons with the one with value = "c" selected. But from action method i am selecting radio button with value "a". why is it so?
Can anyone please help me understanding whether i have any issue with my code or how does knockout handle radio button selections internally. Thanks!

Use the checked binding instead of the attr binding which is directly created for this scenario:
The checked binding links a checkable form control — i.e., a checkbox (<input type='checkbox'>) or a radio button (<input type='radio'>) — with a property on your view model.
So in your case you need to write:
<input type="radio" name="Group1" value="a" data-bind="checked: SelectedValue" />
<input type="radio" name="Group1" value="b" data-bind="checked: SelectedValue" />
<input type="radio" name="Group1" value="c" data-bind="checked: SelectedValue" />
Demo JSFiddle.

Related

How to handle multiple checkboxes in ASP.NET WEb Form and Code-Behind File

Here is the Code in the .aspx web form What is the best way to handle a group of multiple checkboxes.
<input id="nonunionexempt" type="checkbox" value="0" name="employeeType" tabindex="8" runat="server" />
<input id="nonexempthourly" type="checkbox" value="1" name="employeeType" tabindex="9" />
<input id="eleven99" type="checkbox" value="2" name="employeeType" tabindex="10" />
<input id="nysna" type="checkbox" value="3" name="employeeType" tabindex="11" />
<input id="cir" type="checkbox" value="4" name="employeeType" tabindex="12" />
Here is the code behind file Is there a better way to deal with multiple checkboxes?
protected void SaveEmployee()
{
Employee model = new Employee();
if (nonunionexempt.Checked)
{
model.EmployeeType = nonunionexempt.Value;
}
if (nonunionexempt.Checked)
{
model.EmployeeType = nonexempthourly.Value;
}
IValueProvider provider = new FormValueProvider(ModelBindingExecutionContext);
if (TryUpdateModel<Employee>(model, provider))
{
LoaRepository.saveData(model);
}
else
{
throw new FormatException("Could not model bind");
}
}
First, your code sounds good and clean. But if I were you I would use web controls instead of HTML ones. Also, I don't think there is a need to write the if statements even if not using web controls. Simply assign the 'checked' property which is of value true or false. Finally, if embedding the check boxes in a web user control then in the case of multiple usages this could bring a valuable help and of course better maintenance. Hope it helps, good luck!
If you can use the ASP.NET Checkbox control instead of input tags, you won't need the if statements. In code behind use checkBoxID.Checked property which will return true or false.

Razor - Radio Button To Be Checked in a Foreach Loop

I have a radio button in a foreach loop within a form to be posted. I want the first one to be checked when they are listed. checked = "checked" below doesn't help. It only works if there is a single radio button.
<form action="/logged/hotel" method="post" >
#foreach (var item in ViewBag.companies)
{
<input type="radio" name="graph" value="#item.Value" checked="checked" /> #item.Text<br />
}
<input type="submit" value ="LOG IN" />
</form>
Add name attribute, this will group your radio buttons together and only displayed one as checked.
Only one radio button in a set can be checked.
all your radio buttons are in the same set.
you want to put them each in a different set so say
name="#item.Value"
However MVC wont like that, so you will have to do something like
[HttpPost]
public ActionResult MyGraphPage(GraphViewModel vm){
foreach(var company in MyDataContext.Companies){
if(Request.Form.AllKeys.Contains(company.Value){
//show the graph
}
}
If you just want the first one to be checked you can do this, its not the most elegant solution, but works.
<form action="/logged/hotel" method="post" >
#{
var isfirst = true;
}
#foreach (var item in ViewBag.companies)
{
if (isfirst) {
isfirst = false;
<input type="radio" name="graph" value="#item.Value" checked="checked" />#item.Text<br/>
} else {
<input type="radio" name="graph" value="#item.Value"/>#item.Text<br/>
}
}
<input type="submit" value ="LOG IN" />
</form>
#{
bool isFirstChecked = false;
foreach (var item in ViewBag.companies)
{
<input #(isFirstChecked ? "" : "checked") type="radio" name="graph" value="#item.Value" checked="checked" />
#item.Text
<br />
isFirstChecked = true;
}
}

How to change the content of ViewResult

bool isChecked = false;
<input type="checkbox" name="x" checked="#isChecked" />
In MVC 4, The above code will be generate as
<input type="checkbox" name="x" />
But in MVC 3,Need to write like this:
bool isChecked = false;
#if(isChecked)
{
<input type="checkbox" name="x" checked="checked" />
}
else
{
<input type="checkbox" name="x" />
}
If we are Microsoft developers, Which assembly need to modify and how to modify it?
How to customize the upgrade code?
Plase help me,thanks!
To be honest I don't really understand the question after those code blocks, but I can say that you can use inline condition in your views in ASP.NET MVC3. Something like that for example:
bool isChecked = false;
<input type="checkbox" name="x" #(isChecked ? "checked=checked" : "") />
It's shorter and it will produce code like that:
<input type="checkbox" name="x">
And BTW, there is a helper method Html.CheckBox to create checkbox in your view and in second parameter you can indicate if you want it to be checked:
#{bool isChecked = false;}
#Html.CheckBox("x", isChecked)
And that will rendrer this:
<input id="x" type="checkbox" value="true" name="x">
<input type="hidden" value="false" name="x">
Try it on your own.

Binding arrays with missing elements in asp.net mvc

I am trying to bind a dynamic array of elements to a view model where there might be missing indexes in the html
e.g. with the view model
class FooViewModel
{
public List<BarViewModel> Bars { get; set; }
}
class BarViewModel
{
public string Something { get; set; }
}
and the html
<input type="text" name="Bars[1].Something" value="a" />
<input type="text" name="Bars[3].Something" value="b" />
<input type="text" name="Bars[6].Something" value="c" />
at the moment, bars will just be null. how could I get the model binder to ignore any missing elements? i.e. the above would bind to:
FooViewModel
{
Bars
{
BarViewModel { Something = "a" },
BarViewModel { Something = "b" },
BarViewModel { Something = "c" }
}
}
Add the .Index as your first hidden input to deal with out of sequence elements as explained in this Phil Haacked blog post:
<input type="text" name="Bars.Index" value="" />
<input type="text" name="Bars[1].Something" value="a" />
<input type="text" name="Bars[3].Something" value="b" />
<input type="text" name="Bars[6].Something" value="c" />
A possible workaround could be to instantiate the ViewModel and the collection to the correct size (assuming it's known), then update it with TryUpdateModel... something like:
[HttpPost]
public ActionResult SomePostBack(FormCollection form)
{
// you could either look in the formcollection to get this, or retrieve it from the users' settings etc.
int collectionSize = 6;
FooViewModel bars = new FooViewModel();
bars.Bars = new List<BarViewModel>(collectionSize);
TryUpdateModel(bars, form.ToValueProvider());
return View(bars);
}H
MVC is able to populate list itself.
public ActionResult Index(FooViewModel model)
{
...
So no matter if anything is missing mvc will create new List<BarViewModel> and
for each found index - [1],[3],[6] it will create new BarViewModel and add it to List. So you will get FooViewModel with populated Bars.
i didnt know even that worked!
bearing that in mind, id have done something like:
<input type="text" name="Bars.Something" value="a" />
<input type="hidden" name="Bars.Something" value="" />
<input type="text" name="Bars.Something" value="b" />
<input type="hidden" name="Bars.Something" value="" />
<input type="hidden" name="Bars.Something" value="" />
<input type="text" name="Bars.Something" value="c" />
which would hopefully post
a,,b,,,c
but I suspect that will bind in the same way as you describe
Youre probably going to have write a custom model binder that looks for the max index, makes a list of that size then puts the elements in the correct place.
Saying all that, wait for someone else to post a really simple attribute you can put on your property that makes it just work ;D

how to make user select only one check box in a checkboxlist

i have an check boxlist with (6 items under it). and i have an search button. if user clicks Search button it gets all the result.
i am binding the items for checkboxlist using database in .cs file
condition1:
but now if user selects a checkbox[item1] its gets selected
and he tries to select an 2 checkbox[item2] then firstselected checkbox[item1] should be unselected. only checkbox[item2] should be selected
condition 2:
now if user as selected checkbox1 [item1] it gets selected. and now if user again clicks on checkboxi[item1] then it should get deselected.
either you can provide me the solution in javascript or JQuery
any help would be great . looking forward for an solution
thank you
use Radio button. The only problem you will face is when you want to de-select the radio button. You can write in a javascript for 'onClick' of radio button. The onClick function can check whether radio button is selected, if it is not select it else deselect it.
Hope this helps. See Example
RDJ
While I definitely agree with the consensus that radio buttons are the way to go for your described use-case, here is a little snipped of jquery that will cause checkboxes to behave like radio buttons. You simply need to add a "groupname" attribute to your checkbox tag.
HTML:
<fieldset>
<legend>Group 1 - radio button behavior</legend>
<input type="checkbox" groupname="group1" value="1" /> Checkbox 1<br />
<input type="checkbox" groupname="group1" value="2" /> Checkbox 2<br />
<input type="checkbox" groupname="group1" value="3" /> Checkbox 3<br />
<input type="checkbox" groupname="group1" value="4" /> Checkbox 4<br />
<input type="checkbox" groupname="group1" value="5" /> Checkbox 5<br />
</fieldset>
<fieldset>
<legend>Group 2 - radio button behavior</legend>
<input type="checkbox" groupname="group2" value="1" /> Checkbox 1<br />
<input type="checkbox" groupname="group2" value="2" /> Checkbox 2<br />
<input type="checkbox" groupname="group2" value="3" /> Checkbox 3<br />
<input type="checkbox" groupname="group2" value="4" /> Checkbox 4<br />
<input type="checkbox" groupname="group2" value="5" /> Checkbox 5<br />
</fieldset>
<fieldset>
<legend>Group 3 normal checkbox behavior</legend>
<input type="checkbox" value="1" /> Checkbox 1<br />
<input type="checkbox" value="2" /> Checkbox 2<br />
<input type="checkbox" value="3" /> Checkbox 3<br />
<input type="checkbox" value="4" /> Checkbox 4<br />
<input type="checkbox" value="5" /> Checkbox 5<br />
</fieldset>
Javascript:
<script type="text/javascript">
$(document).ready(function() {
$('input[type=checkbox]').click(function() {
var groupName = $(this).attr('groupname');
if (!groupName)
return;
var checked = $(this).is(':checked');
$("input[groupname='" + groupName + "']:checked").each(function() {
$(this).prop('checked', '');
});
if (checked)
$(this).prop('checked', 'checked');
});
});
</script>
I'm sure there are opportunities to increase brevity and performance, but this should get you started.
Why don't you use radio buttons, they are ideal for the purpose that you mentioned.
Edit:
If you necessarily want to use checkbox list then assign some logical ids to those checkboxes so that you can access them in JavaScript.
On each onclick event of the checkboxes call the JavaScript and in the JavaScript loop through and see
If any checkbox is checked other
than the present clicked checkbox,
then make them unselected.
If the present checkbox is already
checked then just toggle it.
You can see if a checkbox is checked using $("#checkboxId").is(":checked") which returns true if a checkbox is checked.
Thanks
this was the code that helped me to solve this issue
just add the script -
var objChkd;
function HandleOnCheck()
{
var chkLst = document.getElementById('CheckBoxList1');
if(objChkd && objChkd.checked)
objChkd.checked=false;objChkd = event.srcElement;
}
and register the client event to the 'CheckBoxList1' at the Page_load as
CheckBoxList1.Attributes.Add("onclick","return HandleOnCheck()");
You might want to have a look at the MutuallyExclusiveCheckBoxExtender.
.aspx
<asp:CheckBoxList id="chkList" runat="server" RepeatLayout="Flow" />
.js
$(document).ready(function () {
LimitCheckboxes('input[name*=chkList]', 3);
}
function LimitCheckboxes(control, max) {
$(control).live('click', function () {
//Count the Total Selection in CheckBoxList
var totCount = 1;
$(this).siblings().each(function () {
if ($(this).attr("checked")) { totCount++; }
});
//if number of selected item is greater than the max, dont select.
if (totCount > max) { return false; }
return true;
});
}
PS: Make sure you use the RepeatLayout="Flow" to get rid of the annoying table format.
we can do in java script to get the solution for this.
For this first get the id of the checked item and go thorough the remaining items using loop then unchecked the remaining items
http://csharpektroncmssql.blogspot.com/2011/11/uncheck-check-box-if-another-check-box.html
My jQuery solution for this is coded as follows:
$(document).ready(function () {
SetCheckboxListSingle('cblFaxTypes');
});
function SetCheckboxListSingle(cblId) {
$('#' + cblId).find('input[type="checkbox"]').each(function () {
$(this).bind('click', function () {
var clickedCbxId = $(this).attr('id');
$('#cblFaxTypes').find('input[type="checkbox"]').each(function () {
if (clickedCbxId == $(this).attr('id'))
return true;
// do not use JQuery to uncheck the here because it breaks'defaultChecked'property
// http://bugs.jquery.com/ticket/10357
document.getElementById($(this).attr('id')).checked = false;
});
});
});
}
Try this solution:
Code Behind (C#) :
foreach (ListItem listItem in checkBoxList.Items)
{
listItem.Attributes.Add("onclick", "makeSelection(this);");
}
Java Script :
function makeSelection(checkBox)
{
var checkBoxList = checkBox;
while (checkBoxList.parentElement.tagName.toLowerCase() != "table")
{
checkBoxList = checkBoxList.parentElement;
}
var aField = checkBoxList.getElementsByTagName("input");
var bChecked = checkBox.checked;
for (i = 0; i < aField.length; i++)
{
aField[i].checked = (aField[i].id == checkBox.id && bChecked);
}
}

Resources