MVC 5 RadioButtonFor enum, the default enum value zero is always selected? - radio-button

Say I have an enum:
public enum OrderStatusType
{
Waiting = 0,
Pending,
Picked,
Shipped,
}
I generated the radio button list as follows.
#Html.RadioButtonFor(m => m.Status, OrderStatusType.Shipped, new {#checked = true})
#Html.RadioButtonFor(m => m.Status, OrderStatusType.Waiting)
But the Waiting is always selected. The output HTML is as below:
input type="radio" value="Shipped" name="Status" id="Status" checked="True"
input type="radio" value="Waiting" name="Status" id="Status" checked="checked"
Why is a "checked" attribute automatically added by MVC framework?
Thanks.
The model:
public class OrderViewModel
{
public OrderStatusType Status { get; set; }
}
The view:
#using WebApplication17.Controllers
#model WebApplication17.Models.OrderViewModel
#{
ViewBag.Title = "Home Page";
}
#Html.RadioButtonFor(m => m.Status, OrderStatusType.Picked)
<span>#OrderStatusType.Picked</span>
#Html.RadioButtonFor(m=>m.Status, OrderStatusType.Pending)
<span>#OrderStatusType.Pending</span>
#Html.RadioButtonFor(m => m.Status, OrderStatusType.Shipped, new {#checked = true})
<span>#OrderStatusType.Shipped</span>
#Html.RadioButtonFor(m => m.Status, OrderStatusType.Waiting)
<span>#OrderStatusType.Waiting</span>

Its selected because the value of your property Status is OrderStausType.Waiting (that's how binding works!).
Remove new {#checked = true} from the #Html.RadioButtonFor() method and in your controller, set the value of Status to OrderStausType.Shipped before you pass it to the view.
Note also you should use a <label> element rather that a <span> to associate the label with the radio button
#Html.RadioButtonFor(m => m.Status, OrderStausType.Picked, new {id = OrderStausType.Picked)
<label for=#OrderStausType.Picked>#OrderStausType.Picked</label>

Related

mvc - How to assign a value to a partial view property from withing its parent view

I have a View A, View B, and a View _C.
View _C is a partial view that is rendered inside of View A and B:
View A:
<div style="margin-top:20px;">
<div>
#Html.Partial("~/Views/_C.cshtml", null, new ViewDataDictionary { { "WithRedirect", "true" } });
</div>
</div>
View B
<div style="margin-top:20px;">
<div>
#Html.Partial("~/Views/_C.cshtml", null, new ViewDataDictionary { { "WithRedirect", "false" } });
</div>
</div>
View C(partial view) - code fragment:
.
.
<td style="padding-bottom: 8px;">
#Html.EditorFor(model => model.CurrentPassword, new { htmlAttributes = new { #class = "form-control k-textbox checkError", placeholder = "Enter current password" } })
</td>
.
.
When rendering partial view, I need to set a flag "WithRedirect" to refer to it later in the controller to decide if I need to redirect to another view or not:
string withRedirect = this.ViewData.ContainsKey("WithRedirect") ? this.ViewData["WithRedirect"].ToString() : string.Empty;
if(WithRedirect.Equals("true")
return Redirect(returnUrl ?? Url.Action("Index", "Page1"));
else
return Redirect(returnUrl ?? Url.Action("Index", "Page2"));
When debugging the controller, WithRedirect variable is an empty string.
What am I doing wrong and what is the solution?
Inside your partial view(_C.cshtml), you can read the value from ViewDataDictionary and set to an input field inside a form. When you submit the form, this value will be also submitted. You can have a parameter in your http post action method which will receive this input field value and using that you can conditionally redirect to page1 or page 2.
#model LoginViewModel
#using (Html.BeginForm("Login","Home"))
{
<input type="hidden" name="withRedirect" value="#ViewData["WithRedirect"]" />
#Html.LabelFor(f=>f.Password)
#Html.TextBoxFor(x=>x.Password )
<input type="submit" />
}
and now in your action method
[HttpPost]
public ActionResult Login (LoginViewModel model,bool withRedirect)
{
//to do : Do something
if(withRedirect)
{
return RedirectToAction("Index","Page1");
}
return RedirectToAction("Index","Page2");
}

MVC partial view wtih different model

I have model as
public class MainDataViewModel
{
[Required]
[Display(Name = "Select Work Orders")]
public string[] SelectedWorkOrdersValues { get; set; }
public MultiSelectList WorkOrderIds { get; set; }
public IEnumerable<ORDERMASTER> ordersDetails;
}
And Main View as
#model InventoryEasy15.Models.MainDataViewModel
<div class="box-body">
<div class="col-md-6">
<div class="form-group">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<label for="fileToUpload">Select the Work Orders</label>
#Html.ValidationMessageFor(m => m.WorkOrderIds, "", new { #class = "text-danger" })
#Html.ListBoxFor(m => m.SelectedWorkOrdersValues, Model.WorkOrderIds as MultiSelectList, new { id = "WorkOrders", #class = "form-control", data_placeholder = "Choose Work Orders..." })
</div>
</div>
</div>
<!-- /.box-body -->
<div class="box-footer">
<input type="submit" value="Get WorkOrder Details" id="btnSubmit" class="btn btn-primary">
</div>
</div>
</div>
</div>
#Html.Partial("MainDataWorkOrderDetails", Model.ordersDetails)
And the Partial view as
#model IEnumerable<InventoryEasy15.ORDERMASTER>
<div id="myDisplayID"><div>
Now I am getting error as
The model item passed into the dictionary is of type 'InventoryEasy15.Models.MainDataViewModel', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable`1[InventoryEasy15.ORDERMASTER]'.
Any thoughts.
The controller here is
public async Task<ActionResult> MainDataWorkOrderDetails(MainDataViewModel m)
{
var model = new MainDataViewModel();
var result = await db.ORDERMASTERs.Where(x => x.WOID == "WO7446708").ToListAsync();
if (result != null)
{
model.ordersDetails = result;
}
return PartialView(model);
}
You are passing model to the PartialView. Now, the model is of type MainDataViewModel, and your partial view expects the model of type IEnumerable<InventoryEasy15.ORDERMASTER>
return PartialView(model);
I think you should consider passing model.orderDetails to the partial view from your action.
return PartialView(model.orderDetails);
Or else, simply return the View containing the partial view if you want to pass the whole model

Return selected objects for MultiSelect DropDownList

I have this DropDownListFor added to my (partial) View _CreateUser.cshtml as:
<div class="modal fade bs-example-modal-lg" id="createUserModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">Create A User</h4>
</div>
#using (Html.BeginForm("Create", "Users", FormMethod.Post))
{
<div class="modal-body">
#Html.LabelFor(model => model.Departments)
<div>
#Html.DropDownListFor(
model => model.SelectedDepartmentIds,
new SelectList(Model.DepartmentSelectList, "Value", "Text"),
new {#class = "multiselect departments", multiple = "multiple"})
</div>
...
Above partial view is declared in main View Index.cshtml and is shown as modal popup on click of 'Create' button
#Html.ActionLink("Create user", "Create", "Users", new { #class = "btn btn-primary", #href = "#createUserModal", #data_toggle="modal" })
...
#Html.Partial("_CreateUser", new UserViewModel()
{ //Populating SelectList required for loading dropdownlist
DepartmentSelectList = modelFactory != null ?
modelFactory.Departments.Select(dept => new SelectListItem{Value = dept.Id.ToString(),Text = dept.Name}).ToList()
: null
})
UserViewModel.cs
public IEnumerable<String> Departments { get; set; }
//Used purely for binding DropDownList
public IEnumerable<SelectListItem> DepartmentSelectList { get; set; }
public string SelectedDepartmentIds { get; set; }
//Ideally, I want to populate selected items in this list
public IEnumerable<DepartmentModel> DepartmentModels { get; set; }
UserController.cs
[HttpPost]
public ActionResult Create(UserViewModel postedModel)
{
if (ModelState.IsValid)
{
//Incorrect - returns only first selected Id
string selectedIds = postedModel.SelectedDepartmentIds;
//Correct - returns correct selected Ids
string selectedIds1 = ModelState["SelectedDepartmentId"].Value.AttemptedValue;
...
...
Two questions:
How can I retrieve all selected items from DropDownList as part of model property "SelectedDepartmentId"? Do I need to use jQuery to update the ModalProperty at run-time?
Can I setup my View so as to bind Modal property "DepartmentModels" with DropDownList - It will help me to retrieve complete objects for selected items?
Currently, if I try to do that, I get this error:
{"The parameter conversion from type 'System.String' to type '...DepartmentModel' failed because no type converter can convert between these types."}
Thank you!
Resolved after looking through various Google searches :-)
Below is the code that loads and returns selected objects correctly -
Model:
public class UserGroupViewModel
{
public IEnumerable<SelectListItem> GroupSelectList
{
get
{
List<Group> groups = new List<Group>
{
new Group() {Id = 1, Name = "AA"},
new Group() {Id = 2, Name = "BB"},
new Group() {Id = 3, Name = "CC"}
};
IEnumerable<SelectListItem> groupsSelectList = groups.Select(group => new SelectListItem { Text = group.Name, Value = group.Id.ToString(), Selected = group.Id == 2}).ToList();
return groupsSelectList;
}
}
[Required]
[Display(Name = "Group")]
public int[] SelectedGroupIds { get; set; }
}
View:
<div class="form-group">
#Html.LabelFor(model => model.SelectedGroupIds, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.SelectedGroupIds,
Model.GroupSelectList,
new { #class = "multiselect", multiple = "multiple" })
#Html.ValidationMessageFor(model => model.SelectedGroupIds)
</div>
</div>
For showing some of the items as 'Selected' on form load, simply set the SelectListItem's 'Selected' property to true.
HTH.

Popup containt become blank at the time of moving the popup positions by selecting popup header

I am opening the view into popup control by using ContentUrl property of popup.
But when I try to move the positions of popup by selecting popup header. popup containt become blank still I am moving or selected the popup header. Same issue is present for in devexpress demo which was provided online.
I refered the following demo of devexpress popup controal
http://demos.devexpress.com/MVCxDockAndPopupsDemos/PopupControl/ContentUrl
I have written the following code
HomeController
public class HomeController : Controller
{
public ActionResult SendProduct(string rowId)
{
Product objProduct = new Product();
return View(objProduct);
}
[HttpPost]
public ActionResult SendProduct(Product objProduct)
{
return View(objProduct);
}
}
Product model
public class Product
{
public int ProductId { get; set; }
[Required]
public string Name { get; set; }
}
Index.chtml
#{
ViewBag.Title = "Home Page";
}
#using DevExpress.Web.Mvc.UI
#using DevExpress.Web.ASPxGridView
#using UI.Infrastructure.Resources;
<script type="text/javascript">
function OnBeginCallback(s, e) {
e.customArgs["rowId"] = 123;
}
function Click() {
pcSendProduct.PerformCallback();
if (!pcSendProduct.IsVisible())
pcSendProduct.Show();
}
</script>
Enumalate menu click
<div>
#Html.DevExpress().Button(settings =>
{
settings.Name = "btnSend";
settings.Width = 80;
settings.Text = "Find";
settings.UseSubmitBehavior = false;
settings.ClientSideEvents.Click = string.Format("function(s, e) {{ Click(); }}");
}).GetHtml()
</div>
#Html.DevExpress().PopupControl(
settings =>
{
settings.Name = "pcSendProduct";
settings.Width = 1050;
settings.Height = 550;
settings.HeaderText = "Plan Customer Interaction";
settings.CloseAction = DevExpress.Web.ASPxClasses.CloseAction.CloseButton;
settings.Styles.Header.HorizontalAlign = System.Web.UI.WebControls.HorizontalAlign.Center;
settings.Styles.Header.VerticalAlign = System.Web.UI.WebControls.VerticalAlign.Middle;
settings.Styles.Header.Font.Size = 10;
settings.Modal = true;
settings.ShowHeader = true;
settings.ShowCloseButton = true;
settings.CloseAction = DevExpress.Web.ASPxClasses.CloseAction.CloseButton;
settings.Left = 1245;
settings.Top = 300;
settings.Styles.ModalBackground.BackColor = System.Drawing.Color.Transparent;
//settings.ContentUrl = Url.Action("SendProduct", "Home");
settings.ShowLoadingPanel = true;
settings.ClientSideEvents.BeginCallback = "OnBeginCallback";
}).GetHtml()
SendProduct.cshtml
#model Demo.Models.Product
#{
ViewBag.Title = "SendProduct";
}
<h2>SendProduct</h2>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Product</legend>
#Html.HiddenFor(model => model.ProductId)
<div class="editor-label">
#Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
In above code when i click on button popup get open on brouser properly. but when I select popup header for changing the positions position or any reason popup containt will get dissapered or popup will show blank containt. When I deselect popup header popup containt view display on popup
Please please give me solution so that w hen user select popup header then popup containt will not become blank. Popup must show the view .
Here devexress team six year ago gave an explanation that it is impossible when you use ContentUrl property because the control render it in the iframe.
You can write view content in the ViewContext but your controller should return PartialView.
public class HomeController : Controller
{
public ActionResult SendProduct(string rowId)
{
Product objProduct = new Product();
return PartialView(objProduct);
}
[HttpPost]
public ActionResult SendProduct(Product objProduct)
{
return PartialView(objProduct);
}
}
Popup settings
settings.SetContent(() =>
{
ViewContext.Writer.Write((Html.Action("SendProduct", "Home").ToHtmlString()));
});
//settings.ContentUrl = Url.Action("SendProduct", "Home");

Editor UI widget not passing input to model

I am new to 'Kendo UI for ASP.NET MVC' and am currently using the Editor UI widget to get data from a database and save changes to the database. The editor correctly displays the model data returned by the controller.
However, after making changes to the editor, the content in the editor is NOT being passed to the controller's HttpPost method and as a result the required validation message is displayed.
Any ideas as to why the Editor not passing the input to the underlying model??
Here is some code:
**#* Create Customer View *#**
#model KendoTest.Models.Customer
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<div class="editor-label">
#Html.LabelFor(model => model.CustomerName)
#Html.EditorFor(model => model.CustomerName)
#Html.ValidationMessageFor(model => model.CustomerName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Notes)
#(Html.Kendo().EditorFor(model => model.Notes).Name("NotesEditor").HtmlAttributes(new { style = "width:400px" }))
#Html.ValidationMessageFor(model => model.Notes)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
**// Customer Controller**
public class CustomerController : Controller
{
private KendoTestDbContext db = new KendoTestDbContext();
//
// GET: /Customer/Create
[HttpGet]
public ActionResult Create()
{
return View();
}
//
// POST: /Customer/Create
[HttpPost]
public ActionResult Create(Customer customer)
{
if (ModelState.IsValid)
{
db.Customers.Add(customer);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(customer);
}
}
Here is the solution from Daniel of the Telerik team:
The value in the editor could not be passed to the post action if the property name does not match the Editor name. The Editor Name is used for the textarea name and the ModelBinder will not be able to associate the value if the name is different. You could use the EditorFor helper and skip the Name method to generate the correct name:
#Html.Kendo().EditorFor(model => model.PropertyName)