Add if condition on View (ASP.NET MVC 4) - asp.net-mvc

I have this code in my View
#using (Html.BeginForm("Add", "AdminUsers"))
{
<div class="control-group">
<span class="control-label">* Role:</span>
<div class="controls">
<select name="Role">
<option value="#Argussite.SupplierService.Core.Domain.Role.Manager"
#if (Model.Role == Argussite.SupplierService.Core.Domain.Role.Manager) { <text>selected="selected"</text> }>
#Argussite.SupplierService.Core.Domain.Role.ManagerTitle</option>
<option value="#Argussite.SupplierService.Core.Domain.Role.ChiefManager"
#if (Model.Role == Argussite.SupplierService.Core.Domain.Role.ChiefManager) { <text>selected="selected"</text> }>
#Argussite.SupplierService.Core.Domain.Role.ChiefManagerTitle</option>
<option value="#Argussite.SupplierService.Core.Domain.Role.Ceo"
#if (Model.Role == Argussite.SupplierService.Core.Domain.Role.Ceo) { <text>selected="selected"</text> }>
#Argussite.SupplierService.Core.Domain.Role.CeoTitle</option>
</select>
</div>
</div>
//...
<div class="control-group">
<span class="control-label">* Phone:</span>
<div class="controls">
#Html.TextBoxFor(m => m.PhoneNumber)
#Html.ValidationMessageFor(m => m.PhoneNumber, null, new {#class="text-error"})
</div>
</div>
<div class="control-group">
<div class="controls">
<button type="submit" class="btn btn-primary">Add</button>
Cancel
</div>
</div>
}
And I need to add a checking if I selected at the list
Model.Role == Argussite.SupplierService.Core.Domain.Role.Manager
I need to show
<div class="control-group">
<span class="control-label">* Phone:</span>
<div class="controls">
#Html.TextBoxFor(m => m.PhoneNumber)
#Html.ValidationMessageFor(m => m.PhoneNumber, null, new {#class="text-error"})
</div>
</div>
If I changed selected value at the list
Model.Role == Argussite.SupplierService.Core.Domain.Role.ChiefManager
or
Model.Role == Argussite.SupplierService.Core.Domain.Role.Ceo
I need to show Phone Field without * and I dont need Validation this field.
How can I do that?
It's my control
[HttpPost]
public ActionResult Add(AddArgussoftUserInput input)
{
if ((input.Role == Role.Manager || input.Role == Role.ChiefManager) && string.IsNullOrWhiteSpace(input.PhoneNumber))
{
ModelState.AddModelError("PhoneNumber", "Please, provide a valid Phone Number");
}
if (!Context.IsUserNameUnique(input.Name))
{
ModelState.AddModelError("Name", AddArgussoftUserInput.NameIsNotUniqueError);
}
if (!Context.IsUserEmailUnique(input.Email))
{
ModelState.AddModelError("Email", AddArgussoftUserInput.EmailIsNotUniqueError);
}
if (!ModelState.IsValid)
{
return View(input);
}
var user = new User(input.Name, input.Email, input.FullName, input.Role, input.PhoneNumber);
Context.Users.Add(user);
Register(new UserCreatedNotification(user, null /* supplier */, UrlBuilder));
TriggerPopupSuccess(string.Format("Account '{0}' for user {1} has been created.", input.Name, input.FullName));
return RedirectToAction("Index");
}

You can make a HtmlHelper that extends the MvcHtml.
I've handled this problem somewhat like this but with custom authorizeattributes.
namespace System.Web.Mvc.Html
{
public static class HtmlHelperExtensions
{
public static MvcHtmlString AuthorizeCeo()
{
return Model.Role == "Ceo" ? value : MvcHtmlString.Empty;
}
}
This way you can use it like:
#Html.ActionLink("Phonenumber *", "actionName", "controllerName").AuthorizeCeo()
And it will only show if the user is authorized.

You can use jQuery to hook the change event of the select list and show a div based on the selected Role.
I set up a quick jsFiddle to show you here
http://jsfiddle.net/nwdev/X5Zva/
<select id="RoleList">
<option value="Manager">Manager</option>
<option value="CEO">CEO</option>
</select>
<div id="RequiredPhone">
phone field with validation
</div>
<div id="OptionalPhone">
optional phone field here
</div>
And some jQuery to get it wired up...
jQuery(function() {
jQuery('#RequiredPhone').hide();
jQuery('#OptionalPhone').hide();
});
function updateOption() {
jQuery('#RequiredPhone').toggle(this.value == 'Manager');
jQuery('#OptionalPhone').toggle(this.value == 'CEO');
}
jQuery(document).ready(function() {
jQuery("#RoleList").each(updateOption);
jQuery("#RoleList").change(updateOption);
});
So, if you select Manager from the dropdrop it will show the ReqiredPhone div and if you select the CEO it will show the OptionalPhone div.
This should get you going in the right direction.
I haven't tested this with the validation field. You might have to add it dynamically.

Related

Data not populating in form upon clicking edit

I am working on this ASP.NET MVC project where I am performing simple CRUD operations. On clicking Edit button, I want to get the data from the database and populate it in the Create View (same view with the help of which I entered the data).
The issue that I have is that, though I am able to enter the data into the database using the Create.cshtml view, I am not able to populate the data back into the fields to the same View upon clicking Edit. On checking, I see that I am able to get the data from the database from the Controller and I am sending it to the View - Create. But, the fields are not getting populated in the View.
Where am I going wrong?
View - Create.cshtml
<form method="post" action="/Books/Create" id="formBooks">
<div class="form-group">
<div class="form-row">
<div class="form-group col-md-6">
<div>
<label asp-for="Title" class="label">Title</label>
<input asp-for="Title" class="form-control" id="title" name="title" required />
<span asp-validation-for="Title" class="text-danger"></span>
</div>
<div>
<label asp-for="Author" class="label">Author</label>
<input asp-for="Author" class="form-control" id="author" name="author" required />
<span asp-validation-for="Author" class="text-danger"></span>
</div>
...
</div>
<div class="form-group col-md-6">
<button type="submit" value="Save" class="btn bgm-orange waves-effect mybtn">SAVE</button>
</div>
</div>
</div>
</form>
Controller - BooksController.cs
public ActionResult Create(int? Id)
{
if(Id == null)
{
return View();
}
else
{
var bookData = _context.Books
.Where(b => b.ID == Id)
.FirstOrDefault();
return View(bookData);
}
}
public ActionResult Create(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Books books= db.Books.Find(id);
if (books== null)
{
return HttpNotFound();
}
return View(books);
}
//Try this i hope this will work
The name attribute plays a vital role in binding the data to the <input></input> field. Also, value attribute gets the value to display in the Edit view.
<input asp-for="Title" class="form-control" id="title" name="title" placeholder="Enter title..." value="#(Model != null ? Model.Title : "")" required />

Partial View replaces Parent view

I'm working on web app developed in ASP.Net MVC, having a partial view which should be rendered inside its parent view.
Parent view has a HTML Dropdown, on-change event should bind respective data to partial view. But on selection change, the complete parent view is replaced with partial view (child view).
Parent View (Index.cshtml)
<h3>Please Select Group</h3>
#using (Html.BeginForm("EmployeeDeptHistory", "Home", FormMethod.Post))
{
#Html.AntiForgeryToken()
if (ViewBag.DepartmentList != null)
{
#Html.DropDownList("DepartmentName", ViewBag.DepartmentList as SelectList, "-- Select --", new { Class = "form-control", onchange = "this.form.submit();" })
}
}
<div>
#{Html.RenderPartial("_EmployeeDeptHistory");}
</div>
Partial View (_EmployeeDeptHistory.cshtml)
#model IEnumerable<PartialViewApplSol.Models.EmployeeDepartmentHistory>
#if (Model != null)
{
<h3>Employees Department History : #Model.Count()</h3>
foreach (var item in Model)
{
<div style="border:solid 1px #808080; margin-bottom:2%;">
<div class="row">
<div class="col-md-2">
<strong>Name</strong>
</div>
<div class="col-md-5">
<span>#item.Name</span>
</div>
</div>
<div class="row">
<div class="col-md-2">
<strong>Shift</strong>
</div>
<div class="col-md-5">
<span>#item.Shift</span>
</div>
</div>
<div class="row">
<div class="col-md-2">
<strong>Department</strong>
</div>
<div class="col-md-5">
<span>#item.Department</span>
</div>
</div>
<div class="row">
<div class="col-md-2">
<strong>Group Name</strong>
</div>
<div class="col-md-5">
<span>#item.GroupName</span>
</div>
</div>
<div class="row">
<div class="col-md-2">
<strong>Start Date</strong>
</div>
<div class="col-md-5">
<span>#item.StartDate</span>
</div>
</div>
<div class="row">
<div class="col-md-2">
<strong>End Date</strong>
</div>
<div class="col-md-5">
<span>#item.EndDate</span>
</div>
</div>
</div>
}
}
I think the possible mistake is returning partial-view on drop down selection changed.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult EmployeeDeptHistory(FormCollection form)
{
IEnumerable<EmployeeDepartmentHistory> empHistList;
using (IDbConnection con = new SqlConnection(connectionString))
{
empHistList = con.Query<EmployeeDepartmentHistory>("sp_StoredProc", new { DeptId = form["DepartmentName"] }, commandType: CommandType.StoredProcedure);
}
return View("_EmployeeDeptHistory", empHistList);
}
Instead of standard form submit, you need to use jQuery.ajax() function to load partial view inside HTML element without replacing parent view. Here are those steps:
1) Remove onchange event from DropDownList helper, and assign AJAX callback bound to change event:
View
#Html.DropDownList("DepartmentName", ViewBag.DepartmentList as SelectList, "-- Select --", new { #class = "form-control" })
jQuery (inside$(document).ready())
$('#DepartmentName').change(function () {
var selectedValue = $(this).val();
if (selectedValue && selectedValue != '')
{
$.ajax({
type: 'POST',
url: '#Url.Action("EmployeeDeptHistory", "ControllerName")',
data: { departmentName: selectedValue };
success: function (result) {
$('#targetElement').html(result); // assign rendered output to target element's ID
}
});
}
});
2) Remove FormCollection and use a string argument which has same name as AJAX callback argument, also make sure the action method returns PartialView:
Controller
[HttpPost]
public ActionResult EmployeeDeptHistory(string departmentName)
{
IEnumerable<EmployeeDepartmentHistory> empHistList;
using (IDbConnection con = new SqlConnection(connectionString))
{
empHistList = con.Query<EmployeeDepartmentHistory>("sp_StoredProc", new { DeptId = departmentName }, commandType: CommandType.StoredProcedure);
}
return PartialView("_EmployeeDeptHistory", empHistList);
}
3) Finally, don't forget to add ID for target element specified by AJAX callback's success part to load partial view:
View
<div id="targetElement">
#Html.Partial("_EmployeeDeptHistory")
</div>

MVC - #Html.Dropdown not populating values from ViewBag

I'm pretty new to MVC.
I'm trying to develop an MVC webpage. I'm trying to use #HtmlDropDownList(), which would have to populate values from my web.config, using a ViewBag. The page is getting rendered with the correct values, however on the output screen, there is no output. The dropdown shows only empty values on screen. Can someone please help!
Webconfig code:
<add key="ddlStreams" value="Las Vegas|India|Australia"/>
Controller code:
public ActionResult Index()
{
string reportTypes = ConfigurationManager.AppSettings["ddlStreams"].ToString();
ViewBag.ddlStreamsVB = reportTypes.Split('|')
.Select((value) => new SelectListItem { Value = value.ToString() });
GetData getdata = new GetData();
return View(getdata.GetDataFromTable());
}
This is my view:
<div >
<div class="form-control">
<div class="row">
<div class="col-sm-4">
#Html.Label("Stream name")
</div>
<div class="col-md-8">
#Html.DropDownList("ddlStreamsVB1", ViewBag.ddlStreamsVB as IEnumerable<SelectListItem>)
</div>
</div>
</div></div>
The rendered HTML on clicking on View source:
<div >
<div class="form-control">
<div class="row">
<div class="col-sm-4">
<label for="Stream_name">Stream name</label>
</div>
<div class="col-md-8">
<select id="ddlStreamsVB1" name="ddlStreamsVB1"><option value="Las Vegas"></option>
<option value="India"></option>
<option value="Australia"></option>
</select>
</div>
</div>
</div>
</div>
The final output :(
Final output here!!
Issue is you are not setting Text prop of SelectListItem, update as below:
ViewBag.ddlStreamsVB = reportTypes.Split('|')
.Select((value) => new SelectListItem
{ Value= value.ToString(),
Text = value
});

Additional validation message displayed on mvc app

I have a simple mvc web app, that is searching transactions in the DB using a specified search parameter(named RA number), now I decided to add jquery block ui on my app and I then realized the block fires even when an empty string("" single or double space bar in textbox) is entered.
I have data annotation in my RA view model, I then added an AllowEmptryStrings = false attribute on my view model property, see code below
public class SearchByRAViewModel
{
[Required(ErrorMessage = "Please enter an RA number",AllowEmptyStrings = false)]
public string RANumber { get; set; }
}
Here is my action method from my controller code
public ActionResult SearchTollTransactions(SearchByRAViewModel raViewModel)
{
List<TollScrapingTransactionScreen> tollScrapingList = new List<TollScrapingTransactionScreen>();
if (ModelState.IsValid)
{
tollScrapingList = GetTransactionByRA(raViewModel.RANumber);
ViewBag.RANumber = raViewModel.RANumber;
return View(tollScrapingList);
}
else
{
return View("Index");
}
}
My only problem now is, there seems to be an extra validation message displayed on the search page(index) if there is an empty string in the search text box, see screenshot
Here is my block ui section, in case someone wonders where it is
$('#btnSearch').click(function () {
// there should be at least a value for ra before firing the blockui
var raValue = $('#raNumber').val();
if (!raValue || raValue.trim() === '') {
return;
}
else {
$.blockUI();
}
});
This is the part of my view, which is inside the normal #using(Html.BegingForm)
<div class="form-horizontal">
<div class="form-group">
<div class="panel panel-default">
<div class="panel-heading">Search by RA number</div>
<div class="panel-body">
<div class="col-sm-12">
<table class="table form-table">
<tr>
<th class="col-sm-2">#Html.DisplayNameFor(model => model.RANumber)</th>
<td class="col-sm-10">
#Html.TextBoxFor(model => model.RANumber, new { #class = "form-control", #tabindex = 1, #id = "raNumber" })
#Html.ValidationMessageFor(model => model.RANumber)
</td>
</tr>
</table>
</div>
<div class="btn-toolbar col-sm-12">
<input type="submit" value="Search Transaction" class="btn pull-right" tabindex="2" id="btnSearch" />
</div>
</div>
</div>
</div>
</div>

Validation multiple checkbox form

in the page I have only three checkbox, the client should choose at least one before clicking on the submit button :
Controller :
[HttpPost]
public ActionResult Client(OrderItems model)
{
if (bValidated){
//Code here
}
else
{
model.itemChoosed = false;
return View("Client", model);
}
View Client :
#model WebApp.Models.OrderItems
#using (Html.BeginForm("Client", "Home", FormMethod.Post, new { #class = "form-group", role = "form" }))
{
#Html.AntiForgeryToken();
<h2>Client</h2>
#Html.Partial("SentMessage")
<div>
<div>
<h3>Item 1</h3>
<label>#Html.CheckBoxFor(model => model.CLInfo.Item1) Item 1</label>
</div>
<div>
<h3>Item 2</h3>
<label>#Html.CheckBoxFor(model => model.CLInfo.Item2) Item 2</label>
</div>
<div>
<h3>Item 3</h3>
<label>#Html.CheckBoxFor(model => model.CLInfo.Item3) Item 3</label>
</div>
</div>
<div class="row">
<input type="submit" name="action:Client" id="btnClient" class="btn btn-primary flat btn-large pull-right" value="Client" />
</div>
}
After I choose to put the condition into a Partail View :
Partial View SentMessage:
#model WebApp.Models.OrderItems
#if (!model.itemChoosed)
{
<div>You must choose at least one item</div>
}
I have the error message :
The view 'Client' or its master was not found or no view engine supports the searched locations. The following locations were searched:
~/Views/Home/Client.aspx
..
~/Views/Home/Client.cshtml
..
but Home/Client.cshtml existe since it's the view
Thanks

Resources