I need to check a checkbox by default:
I tried all of these, nothing is checking my checkbox -
#Html.CheckBoxFor(m => m.AllowRating, new { #value = "true" })
#Html.CheckBoxFor(m => m.AllowRating, new { #checked = "true" })
#Html.CheckBoxFor(m => m.AllowRating, new { #checked = true })
#Html.CheckBoxFor(m => m.AllowRating, new { #checked = "checked"})
You should set the AllowRating property to true, preferably in the controller or model.
Like other inputs, the checkbox's state reflects the value of the property.
This works for me:
<input id="AllowRating" type="checkbox" #(Model.AllowRating?"checked='checked'":"") style="" onchange="" />
If you really wants to use HTML Helpers:
#Html.CheckBoxFor(m => m.AllowRating, new { #checked = Model.AllowRating})
Also take into account that if m.AllowRating is false, it will fail to set to status checked in your examples.
The syntax in your last line is correct.
#Html.CheckBoxFor(x => x.Test, new { #checked = "checked" })
That should definitely work. It is the correct syntax. If you have an existing model and AllowRating is set to true then MVC will add the checked attribute automatically. If AllowRating is set to false MVC won't add the attribute however if desired you can using the above syntax.
You can do this with #Html.CheckBoxFor():
#Html.CheckBoxFor(m => m.AllowRating, new{#checked=true });
or you can also do this with a simple #Html.CheckBox():
#Html.CheckBox("AllowRating", true) ;
you set AllowRating property to true from your controller or model
#Html.CheckBoxFor(m => m.AllowRating, new { #checked =Model.AllowRating })
<input type="checkbox" #( Model.Checked == true ? "checked" : "" ) />
only option is to set the value in the controller, If your view is Create then in the
controller action add the empty model, and set the value like,
Public ActionResult Create()
{
UserRating ur = new UserRating();
ur.AllowRating = true;
return View(ur);
}
If we set "true" in model, It'll always true. But we want to set option value for my checkbox we can use this. Important in here is The name of checkbox "AllowRating", It's must name of var in model if not when we post the value not pass in Database.
form of it:
#Html.CheckBox("NameOfVarInModel", true) ;
for you!
#Html.CheckBox("AllowRating", true) ;
I had the same issue, luckily I found the below code
#Html.CheckBoxFor(model => model.As, htmlAttributes: new { #checked = true} )
Check Box Checked By Default - Razor Solution
I did it using Razor , works for me
Razor Code
#Html.CheckBox("CashOnDelivery", CashOnDelivery) (This is a bit or bool value) Razor don't support nullable bool
#Html.CheckBox("OnlinePayment", OnlinePayment)
C# Code
var CashOnDelivery = Convert.ToBoolean(Collection["CashOnDelivery"].Contains("true")?true:false);
var OnlinePayment = Convert.ToBoolean(Collection["OnlinePayment"].Contains("true") ? true : false);
Related
I am want to have a text area with multiple lines and a value in MVC3. I can't seem to define a textareafor or an editorfor that has a #Value attribute which I can set. I want to have something like
#Html.TextAreaFor(x => x.model, 10, 15, new{#Value="try"})
Also, I want to be able to do this in the view because the default value will depend on an attribute of another model used within the same view.
Any thoughts please.
The textarea html element does not support the value attribute. So you can't set its value using #Html.TextAreaFor.
So what you have to do is this:
#model MvcApplication.Models.Model
#{
if (1 > 2) // your logic here
{
Model.Description = "value1";
}
else
{
Model.Description = "value2";
}
}
#Html.TextAreaFor(model => model.Description, new { #rows = "10", #cols = "15" })
Let the html helper handle the rendering.
Use Telerik control
Html.Telerik().EditorFor(model => model.Description)
.Name("Editor")
.HtmlAttributes(new { style = "height:400px" })
.Encode(false)
.Value((String)ViewBag.Contents)
.Render();
I'm using ASP.NET MVC 3, and just ran into a 'gotcha' using the DropDownListFor HTML Helper.
I do this in my Controller:
ViewBag.ShippingTypes = this.SelectListDataRepository.GetShippingTypes();
And the GetShippingTypes method:
public SelectList GetShippingTypes()
{
List<ShippingTypeDto> shippingTypes = this._orderService.GetShippingTypes();
return new SelectList(shippingTypes, "Id", "Name");
}
The reason I put it in the ViewBag and not in the model (I have strongly typed models for each view), is that I have a collection of items that renders using an EditorTemplate, which also needs to access the ShippingTypes select list.
Otherwise I need to loop through the entire collection, and assign a ShippingTypes property then.
So far so good.
In my view, I do this:
#Html.DropDownListFor(m => m.RequiredShippingTypeId, ViewBag.ShippingTypes as SelectList)
(RequiredShippingTypeId is of type Int32)
What happens is, that the value of RequiredShippingTypeId is not selected in the drop down.
I came across this: http://web.archive.org/web/20090628135923/http://blog.benhartonline.com/post/2008/11/24/ASPNET-MVC-SelectList-selectedValue-Gotcha.aspx
He suggests that MVC will lookup the selected value from ViewData, when the select list is from ViewData. I'm not sure this is the case anymore, since the blog post is old and he's talking about MVC 1 beta.
A workaround that solves this issue is this:
#Html.DropDownListFor(m => m.RequiredShippingTypeId, new SelectList(ViewBag.ShippingTypes as IEnumerable<SelectListItem>, "Value", "Text", Model.RequiredShippingTypeId.ToString()))
I tried not to ToString on RequiredShippingTypeId at the end, which gives me the same behavior as before: No item selected.
I'm thinking this is a datatype issue. Ultimately, the HTML helper is comparing strings (in the Select List) with the Int32 (from the RequiredShippingTypeId).
But why does it not work when putting the SelectList in the ViewBag -- when it works perfectly when adding it to a model, and doing this inside the view:
#Html.DropDownListFor(m => m.Product.RequiredShippingTypeId, Model.ShippingTypes)
The reason why this doesn't work is because of a limitation of the DropDownListFor helper: it is able to infer the selected value using the lambda expression passed as first argument only if this lambda expression is a simple property access expression. For example this doesn't work with array indexer access expressions which is your case because of the editor template.
You basically have (excluding the editor template):
#Html.DropDownListFor(
m => m.ShippingTypes[i].RequiredShippingTypeId,
ViewBag.ShippingTypes as IEnumerable<SelectListItem>
)
The following is not supported: m => m.ShippingTypes[i].RequiredShippingTypeId. It works only with simple property access expressions but not with indexed collection access.
The workaround you have found is the correct way to solve this problem, by explicitly passing the selected value when building the SelectList.
This might be silly, but does adding it to a variable in your view do anything?
var shippingTypes = ViewBag.ShippingTypes;
#Html.DropDownListFor(m => m.Product.RequiredShippingTypeId, shippingTypes)
you can create dynamic viewdata instead of viewbag for each dropdownlist field for complex type.
hope this will give you hint how to do that
#if (Model.Exchange != null)
{
for (int i = 0; i < Model.Exchange.Count; i++)
{
<tr>
#Html.HiddenFor(model => model.Exchange[i].companyExchangeDtlsId)
<td>
#Html.DropDownListFor(model => model.Exchange[i].categoryDetailsId, ViewData["Exchange" + i] as SelectList, " Select category", new { #id = "ddlexchange", #class = "form-control custom-form-control required" })
#Html.ValidationMessageFor(model => model.Exchange[i].categoryDetailsId, "", new { #class = "text-danger" })
</td>
<td>
#Html.TextAreaFor(model => model.Exchange[i].Address, new { #class = "form-control custom-form-control", #style = "margin:5px;display:inline" })
#Html.ValidationMessageFor(model => model.Exchange[i].Address, "", new { #class = "text-danger" })
</td>
</tr>
}
}
ViewModel CompanyDetail = companyDetailService.GetCompanyDetails(id);
if (CompanyDetail.Exchange != null)
for (int i = 0; i < CompanyDetail.Exchange.Count; i++)
{
ViewData["Exchange" + i]= new SelectList(companyDetailService.GetComapnyExchange(), "categoryDetailsId", "LOV", CompanyDetail.Exchange[i].categoryDetailsId);
}
I was just hit by this limitation and figured out a simple workaround. Just defined extension method that internally generates SelectList with correct selected item.
public static class HtmlHelperExtensions
{
public static MvcHtmlString DropDownListForEx<TModel, TProperty>(
this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression,
IEnumerable<SelectListItem> selectList,
object htmlAttributes = null)
{
var selectedValue = expression.Compile().Invoke(htmlHelper.ViewData.Model);
var selectListCopy = new SelectList(selectList.ToList(), nameof(SelectListItem.Value), nameof(SelectListItem.Text), selectedValue);
return htmlHelper.DropDownListFor(expression, selectListCopy, htmlAttributes);
}
}
The best thing is that this extension can be used the same way as original DropDownListFor:
#for(var i = 0; i < Model.Items.Count(); i++)
{
#Html.DropDownListForEx(x => x.Items[i].CountryId, Model.AllCountries)
}
There is an overloaded method for #html.DropdownList for to handle this.
There is an alternative to set the selected value on the HTML Dropdown List.
#Html.DropDownListFor(m => m.Section[b].State,
new SelectList(Model.StatesDropdown, "value", "text", Model.Section[b].State))
I was able to get the selected value from the model.
"value", "text", Model.Section[b].State this section the above syntax adds the selected attribute to the value loaded from the Controller
I need to change the size of textbox :
#Html.SimpleTextBoxFor(m => ((ModifiableProperty<string>)m).Value.TheCurrentValue, new { id = fieldId})
I tried this
#Html.SimpleTextBoxFor(m => ((ModifiableProperty<string>)m).Value.TheCurrentValue, new { id = fieldId, #maxlength = "100" })
but doesn't work.
You can try this too :
#Html.SimpleTextBoxFor(m => ((ModifiableProperty<string>)m).Value.TheCurrentValue, new { id = fieldId, style ="width:200px"})
Just change the 200px value for the size you want.
For maxlength I use the same syntax as you and it is working for me.
#Html.TextBoxFor(model => model.EL_Taille_Initiale, new { style = "width:50px", #maxlength = "5" })
Take out the "#" character for your maxlength attribute. You only need that for reserved keywords (i.e. class). Also, you don't need the quotes around the number for maxlength.
#Html.SimpleTextBoxFor(m => ((ModifiableProperty<string>)m).Value.TheCurrentValue, new { id = fieldId, maxlength = 100 })
If that doesn't solve the problem, then please post what the HTML markup is being generated on the response page.
I am using a constructor for my TextBox that does not allow passing HTML attributes, so I had to add this to my $(document).ready function: $('#textBoxID').attr('maxlength', 30);
Doesn't directly answer the OP question, but offers an alternate starting point.
I have my form with my checkbox inputs, and user can edit that. I can save these values in database good, but I don't know how to refill the form, so user can edit it.
This is my ViewBag var:
ViewBag.NewFriends = preferences.NewFriends;// this value is a boolean, false
I try to pre-set values like this:
#using (Html.BeginForm("SavePreferences", "Conta"))
{
#Html.HiddenFor(model => model.ID)
#Html.CheckBox("newFriends", new { #checked = #ViewBag.NewFriends })
#Html.Label("newFriends", "Solicitações de Amigo de Alma")
<p><input type="submit" value="Send" /></p>
}
As HTML checkbox has the value checked="checked", and not true or false, it doesn't work.
#Html.CheckBox has the first parameter as input name, and second a boolean checked(true or false).
My question is how can I easily set up this value? I tried:
#Html.CheckBox("newFriends", ViewBag.NewFriends) // where ViewBag.NewFriends = false
But it doesn't work at all...
Any idea?
Probably extension method CheckBox can't work with dynamic. I tried following example and it works:
#{ bool isNewFriends = ViewBag.NewFriends; }
#Html.CheckBox("newFriends", isNewFriends);
I have a view that contains a radiobutton list for my terms and conditions of the site.
e.g.
Yes
#Html.RadioButtonFor(model => model.TermsAndConditions, "True")
No
#Html.RadioButtonFor(model => model.TermsAndConditions, "False",
new { Checked = "checked" })
</div>
#Html.ValidationStyledMessageFor(model => model.TermsAndConditions)
All is ok if the user completes the form without any errors however if I do serverside validation and the page is refreshed I lose the selection that the user made for the radiobutton and the selected radio goes back to the default false field.
How am I meant to be binding the radiobutton so if a user selects true this value is maintained even after serverside validation?
Any suggestions would be great!
For the short answer, you need to do three things:
Remove the new { Checked = "checked" } from the second radio button. This hard-coded checked value will override all of the magic.
When you return your ViewResult from the controller action, give it an instance of your model class where TermsAndConditions is false. This will provide the default false value you need in order to have the false radio button preselected for you.
Use true and false as the values for your radio buttons instead of "True" and "False". This is because your property is of type bool. Strictly speaking, you coincidentally chose the correct string representations for true and false, but the value parameter for the RadioButtonFor method is of type object. It's best to pass in the actual type you want to compare to rather than converting it to a string yourself. More on this below.
Here's what's going on in depth:
The framework wants to do all of this for you automatically, but you did those first two things incorrectly which makes you have to fight with the framework to get the behavior you want.
The RadioButtonFor method calls .ToString() on the value of the property you specified and compares it to the .ToString() of the value you passed in when creating the radio button. If they are equal, then it internally sets isChecked = true and ends up rendering checked="checked" in the HTML. This is how it decides which radio button to check. It simply compares the value of the radio button to the value of the property and checks the one that matches.
You can render radio buttons for pretty much any property this way and it will magically work. Strings, ints, and even enum types all work! Any object that has a ToString method that returns a string which uniquely represents the object's value will work. You just have to make sure you're settings the radio button's value to a value that your property might actually have. The easiest way to do this is just to pass in the value itself, not the string representation of the value. Let the framework convert it to a string for you.
(Since you happened to pass in the correct string representations of true and false, then those values will work as long as you fix your two actual mistakes, but it's still wise to pass in the actual values and not their strings.)
Your first real mistake was hard-coding Checked = "checked" for the "No" radio button. This will override what the framework is trying to do for you and results in this radio button always being checked.
Obviously you want the "No" radio button to be preselected, but you have to do it in a way that's compatible with everything above. You need to give the view an instance of your model class where TermsAndConditions is set to false, and let it "bind" that to the radio buttons. Normally, a controller action which responds to the initial GET request of a URL doesn't give the View an instance of the model class at all. Typically, you just return View();. However, since you want a default value selected, you must provide the view with a instance of your model that has TermsAndConditions set to false.
Here is some source code illustrating all of this:
Some sort of Account class that you probably already have. (Your View's model):
public class Account
{
public bool TermsAndConditions { get; set; }
//other properties here.
}
Some methods in your controller:
//This handles the initial GET request.
public ActionResult CreateAccount()
{
//this default instance will be used to pre-populate the form, making the "No" radio button checked.
var account = new Account
{
TermsAndConditions = false
};
return View( account );
}
//This handles the POST request.
[HttpPost]
public ActionResult CreateAccount( Account account )
{
if ( account.TermsAndConditions )
{
//TODO: Other validation, and create the account.
return RedirectToAction( "Welcome" );
}
else
{
ModelState.AddModelError( "TermsAndConditionsAgreement", "You must agree to the Terms and Conditions." );
return View( account );
}
}
//Something to redirect to.
public ActionResult Welcome()
{
return View();
}
The entire View:
#model Account
#{
ViewBag.Title = "Create Account";
}
#using ( Html.BeginForm() )
{
<div>
<span>Do you agree to the Terms and Conditions?</span>
<br />
#Html.RadioButtonFor( model => model.TermsAndConditions, true, new { id = "TermsAndConditions_true" } )
<label for="TermsAndConditions_true">Yes</label>
<br />
#Html.RadioButtonFor( model => model.TermsAndConditions, false, new { id = "TermsAndConditions_false" } )
<label for="TermsAndConditions_false">No</label>
<br />
#Html.ValidationMessage( "TermsAndConditionsAgreement" )
</div>
<div>
<input id="CreateAccount" type="submit" name="submit" value="Create Account" />
</div>
}
BONUS: You'll notice that I added a little extra feature to the radio buttons. Rather than just use plain text for the radio button labels, I used the HTML label element with the for attribute set to the IDs of the each radio button. This lets users click on the label to select the radio button instead of having to click on the radio button itself. This is standard HTML. For this to work I had to set manual IDs on the radio buttons, otherwise they would both get the same ID of just "TermsAndConditions", which wouldn't work.
There are a few things you need to do here in order to ensure the user's selection is maintained after server side validation.
a) Bind the "checked" property of each radio to your model in the view, for example:
Yes
#Html.RadioButtonFor(model => model.TermsAndConditions, "True", model.TermsAndConditions == true ? new { Checked = "checked" } : null)
No
#Html.RadioButtonFor(model => model.TermsAndConditions, "False", model.TermsAndConditions == false ? new { Checked = "checked" } : null)
b) To define the initial default value when the view is first displayed, initialise the model returned to the view in the GET request (in the controller action), for example:
public ActionResult SomeForm()
{
return View(new SomeModel { TermsAndConditions = false });
}
b) Ensure in your [HttpPost] controller action that you return the model when the validation fails, for example:
[HttpPost]
public ActionResult SomeForm(SomeModel model)
{
if (!ModelState.IsValid)
return View(model);
// Do other stuff here
}
This way when the view is rendered in the response after validation fails, it will have the actual model state that was passed in (thus maintaining the user's selection).
I can't really tell since you haven't shown your code, but I suspect that if you're failing on server side validation you're just returning the raw view. When it fails, you need to populate the view with the model that was submitted, same as if you were returning any other validation errors. Otherwise you'll get the default model values (which will always be false for the registration boolean).
Maybe you could post your server side code?
Here I am offering another more complex example.
public enum UserCommunicationOptions
{
IPreferEmailAndSMS = 1,
IPreferEmail = 2,
IPreferSMS = 3
}
Html
#model UserProfileView
// Some other code
<div class="form-group">
<label class="col-lg-2 control-label">Communication</label>
<div class="col-lg-10">
<div class=" col-xs-">
#if (Model.UserCommunicationOption.ToString() == UserCommunicationOptions.IPreferEmailAndSMS.ToString())
{
#Html.RadioButtonFor(x => x.UserCommunicationOption, (int)UserCommunicationOptions.IPreferEmailAndSMS, new { #checked = "checked" })
}
else
{
#Html.RadioButtonFor(x => x.UserCommunicationOption, (int)UserCommunicationOptions.IPreferEmailAndSMS)
}
<label class=" control-label" for="#Model.UserCommunicationOption">I Prefer Email And SMS</label>
</div>
<div class=" col-xs-">
#if (Model.UserCommunicationOption.ToString() == UserCommunicationOptions.IPreferEmail.ToString())
{
#Html.RadioButtonFor(x => x.UserCommunicationOption, (int)UserCommunicationOptions.IPreferEmail, new { #checked = "checked" })
}
else
{
#Html.RadioButtonFor(x => x.UserCommunicationOption, (int)UserCommunicationOptions.IPreferEmail)
}
<label class=" control-label" for="#Model.UserCommunicationOption">I Prefer Email</label>
</div>
<div class=" col-xs-">
#if (Model.UserCommunicationOption.ToString() == UserCommunicationOptions.IPreferSMS.ToString())
{
#Html.RadioButtonFor(x => x.UserCommunicationOption, (int)UserCommunicationOptions.IPreferSMS, new { #checked = "checked" })
}
else
{
#Html.RadioButtonFor(x => x.UserCommunicationOption, (int)UserCommunicationOptions.IPreferSMS)
}
<label class=" control-label" for="#Model.UserCommunicationOption">#DLMModelEntities.Properties.Resource.IPreferSMS</label>
</div>
</div>
</div>
Model
[Required(ErrorMessageResourceName = "Communications", ErrorMessageResourceType = typeof(Resource))]
[Display(Name = "Communications", ResourceType = typeof(DLMModelEntities.Properties.Resource))]
public UserCommunicationOptions UserCommunicationOption { get; set; }
GET
var client = AppModel.Clients.Single(x => x.Id == clientId);
if (Convert.ToBoolean(client.IsEmailMessage) && Convert.ToBoolean(client.IsSMSMessage))
{
model.UserCommunicationOption = UserCommunicationOptions.IPreferEmailAndSMS;
}
else if (Convert.ToBoolean(client.IsEmailMessage))
{
model.UserCommunicationOption = UserCommunicationOptions.IPreferEmail;
}
else if ( Convert.ToBoolean(client.IsSMSMessage))
{
model.UserCommunicationOption = UserCommunicationOptions.IPreferSMS;
}
POST
[HttpPost]
public ActionResult MyProfile(UserProfileView model)
{
// Some code
var client = AppModel.Clients.Single(x => x.Id == clientId);
if (model.UserCommunicationOption == UserCommunicationOptions.IPreferEmail)
{
client.IsSMSMessage = false;
client.IsEmailMessage = true;
}
else if (model.UserCommunicationOption == UserCommunicationOptions.IPreferEmailAndSMS)
{
client.IsSMSMessage = true;
client.IsEmailMessage = true;
}
else if (model.UserCommunicationOption == UserCommunicationOptions.IPreferSMS)
{
client.IsSMSMessage = true;
client.IsEmailMessage = false;
}
AppModel.SaveChanges();
//Some code
}
Database
Webpage
I had a similar issue and solved the problem by setting a ViewData value in controller to keep track of what the user had selected.