I am trying to build an Ajax.BeginForm (that has a dropdown) which uses server side validation that checks the model's annotations. I am having trouble getting the dropdown to work properly. Originally I populated the dropdown using the viewbag as such:
view:
#Html.DropDownList("CheckIn_Location", ViewBag.CageLocationList as IEnumerable<SelectListItem>, "(Select one)", new { #class = "form-control" })
controller:
public void GetCageLocations()
{
IEnumerable<SelectListItem> selectList =
from c in db.Locations
select new SelectListItem
{
Text = c.LocationName,
Value = c.Id.ToString()
};
ViewBag.CageLocationList = selectList;
}
But that didn't seem to play friendly with server side validation so I am tried reworking my model/view/controllers as such:
Here is my Model:
public class CheckInViewModel
{
public int CheckIn_Id { get; set; }
[Required(ErrorMessage = "Location Required.")]
public IEnumerable<SelectListItem> CheckIn_Location { get; set; }
[Required(ErrorMessage = "Quantity Required.")]
[Range(1, 100, ErrorMessage = "Quantity must be between 1 and 100000")]
public int CheckIn_Quantity { get; set; }
public string CheckIn_Comment { get; set; }
}
Here is my Controller:
[HttpPost]
public ActionResult CheckIn(CheckInViewModel model)
{
if (ModelState.IsValid)
{
var New_Transaction = new Transaction
{
Id = model.CheckIn_Id,
Quantity = model.CheckIn_Quantity,
LocationId = Convert.ToInt32(model.CheckIn_Location),
TransactionDate = DateTime.Now,
TransactionComments = model.CheckIn_Comment.Replace("\r\n", " ")
};
unitOfWork.TransactionRepository.Insert(New_Transaction);
unitOfWork.Save();
return PartialView("CheckIn", model);
}
return PartialView("CheckIn", model);
}
Here is my PartialView called CheckIn.cshtml
#model ViewModels.CheckInViewModel
<!-- Modal -->
<div class="modal fade" id="CheckInModal" 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>
<h1 class="modal-title" id="CheckInModalLabel">Check In</h1>
</div>
<div class="modal-body">
#using (Ajax.BeginForm("CheckIn", "Cage", null, new AjaxOptions { HttpMethod = "POST", OnSuccess = "success", OnFailure = "failure"}, new { #id = "CheckInForm", #class = "form-horizontal" }))
{
#Html.ValidationSummary(true)
#Html.HiddenFor(model => model.CheckIn_Id, new { #class = "form-control" })
<div class="form-group">
<label for="CheckIn_Location" class="col-sm-4 control-label">Location</label>
<div class="col-sm-8">
#Html.DropDownListFor(x => x.CheckIn_Location, Model.CheckIn_Location, "Select One")
#Html.ValidationMessageFor(model => model.CheckIn_Location)
</div>
</div>
<div class="form-group">
<label for="CheckIn_Quantity" class="col-sm-4 control-label">Quantity</label>
<div class="col-sm-8">
#Html.TextBoxFor(model => model.CheckIn_Quantity, new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.CheckIn_Quantity)
</div>
</div>
<div class="form-group">
<label for="CheckIn_Comment" class="col-sm-4 control-label">Comment</label>
<div class="col-sm-8">
#Html.TextAreaFor(model => model.CheckIn_Comment, new { #class = "form-control" })
</div>
</div>
}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary" onclick="SubmitCheckInForm()">Check In</button>
</div>
</div>
</div>
</div>
here is the JS function that fire the submit:
function SubmitCheckInForm() {
$('#CheckInForm').submit();
}
Can someone show me how to:
populate the dropdown with (value/text) using the model as the binding agent (not the viewbag as I previously did it)
return the selected option to the controller and insert it into the transaction table's location element (which is an int)
properly hook this all up so the server side annotations work and return messages when something is incorrect in the form.
Thanks in Advance!
If I have understood you correctly, there is more than one way to do this. For instance, you could have two properties in your model to manage the Dropdown control.
1- CheckIn_Location_Selected. To store the value selected by the user
2- CheckIn_Location_List. To fill the DropdownList.
This could be your model.
public class CheckInViewModel
{
[Required(ErrorMessage = "Location Required.")]
public int CheckIn_Location_Selected { get; set; }
public IEnumerable<SelectListItem> CheckIn_Location_List { get; set; }
//Rest of the properties...
}
So now in your GET action you could have something like this:
[HttpGet]
public ActionResult CheckIn()
{
var model = new CheckInViewModel
{
CheckIn_Location_List = repository.GetCageLocations().Select(
location => new SelectListItem
{
Value = location.Id.ToString(),
Text = location.LocationName
})
};
return View(model);
}
And in your view:
#Html.DropDownListFor(x => x.CheckIn_Location_Selected, Model.CheckIn_Location_List, "Select One")
We need to change a bit your POST action.
[HttpPost]
public ActionResult CheckIn(CheckInViewModel model)
{
if (!ModelState.IsValid)
{
// This is necessary because we are sending the model back to the view.
// You could cache this info and do not take it from the DB again.
model.CheckIn_Location_List = repository.GetCageLocations().Select(
location => new SelectListItem
{
Value = location.Id.ToString(),
Text = location.LocationName
});
return PartialView("CheckIn", model);
}
var New_Transaction = new Transaction
{
Id = model.CheckIn_Id,
Quantity = model.CheckIn_Quantity,
LocationId = Convert.ToInt32(model.CheckIn_Location_Selected),
TransactionDate = DateTime.Now,
TransactionComments = model.CheckIn_Comment.Replace("\r\n", " ")
};
unitOfWork.TransactionRepository.Insert(New_Transaction);
unitOfWork.Save();
return PartialView("CheckIn", model);
}
Related
I tried to set my dropdown list values from my model as it is the value I need to see in the dropdown
But I'm facing an error:
The type arguments for method
'System.Web.Mvc.Html.SelectExtensions.DropDownListFor(System.Web.Mvc.HtmlHelper,
System.Linq.Expressions.Expression>,
System.Collections.Generic.IEnumerable,
string)' cannot be inferred from the usage. Try specifying the type
arguments explicitly.
And here is my code:
#model IEnumerable<Language>
#using Web.Helpers
#{
ViewBag.Title = "";
}
<div class="">
<div class="row">
<div class="col-md-12 col-sm-12 col-xs-12">
<div class="x_panel">
<div class="x_title">
<h2><i class="fa fa-filter"></i> </h2>
<div class="clearfix"></div>
</div>
<div class="x_content">
<br />
#using (Html.BeginForm("Settings","Language", FormMethod.Post, new { #class = "form-horizontal form-label-left" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<div class="col-md-12 col-sm-12">
<div class="col-md-12 col-sm-12">
#Html.DropDownListFor(WHATTOWRITEHERE, new SelectList(ViewBag.Languagess, "Id", "Name"), new { #class = "form-control" })
</div>
</div>
}
}
}
}
}
}
Controller action:
public ActionResult Settings()
{
List<Language> activeL = LanguageController.GetAll();
ViewBag.Languagess = activeLanguages;
return View(activeL);
}
Maybe I could delete ViewBag.Languagess at all, so I can use (Model, "Id", "Name") there instad of (ViewBag.Languagess, "Id", "Name")
Since you've requested how to do this with a strongly typed model instead of a ViewBag....
Right now your view requires a model of type IEnumerable<Language>. Change this to be a new class that holds all values your page needs.
public class LanguagesViewModel
{
List<Language> ActiveLanguages { get; set; }
}
Then in your controller:
var model = new LanguagesViewModel();
model.ActiveLanguages = activeLanguages;
return View(model);
Change your View to require a LanguagesViewModel:
#model LanguagesViewModel
Now you won't be working with the dynamic view bag.
#Html.DropDownListFor(m => m.LanguageId, Model.ActiveLanguages, new { #class = "form-control" })
public ActionResult Settings()
{
List<Language> activeL = LanguageController.GetAll();
ViewBag.Languages = activeLanguages.Select(item => new SelectListItem{
Text = item.Name,
Value = item.Id
});
return View(activeL);
}
#Html.DropDownListFor(m => m.LanguageId, ViewBag.Languages, new { #class = "form-control" })
You need to write html like this
#Html.DropDownListFor(WHATEVER, new SelectList(ViewBag.languages, "Id", "Name"), new { #class = "form-control" })
And in your controller
public ActionResult Settings()
{
List<Language> activeL = LanguageController.GetAll();
ViewBag.Languagess = activeL;
return View();
}
I thing your model could been an other type like Settings.
public class SettingsModel
{
public int LanguageId { get; set; }
}
public class Language
{
public int Id { get; set; }
public string Name { get; set; }
}
.cshtml
#model SettingsModel
#using Web.Helpers
#{
ViewBag.Title = "";
}
<div class="">
<div class="row">
<div class="col-md-12 col-sm-12 col-xs-12">
<div class="x_panel">
<div class="x_title">
<h2><i class="fa fa-filter"></i> </h2>
<div class="clearfix"></div>
</div>
<div class="x_content">
<br />
#using (Html.BeginForm("Settings","Language", FormMethod.Post, new { #class = "form-horizontal form-label-left" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<div class="col-md-12 col-sm-12">
<div class="col-md-12 col-sm-12">
#Html.DropDownListFor(model => model.LanguageId, new SelectList(ViewBag.Languagess, "Id", "Name"), new { #class = "form-control" })
</div>
</div>
}
}
}
}
}
}
controller
[HttpGet]
public ActionResult Language()
{
List<Language> activeL = LanguageController.GetAll();
ViewBag.Languagess = activeLanguages;
return View();
}
[HttpPost]
public ActionResult Language(SettingsModel settings)
{
Language selectedLanguage = LanguageController.GetAll().Where(l => l.Id == settings.LanguageId).SingleOrDefault();
//... your post operations.
}
model
public class LanguageViewModel
{
public int LanguageId { get; set; }
public IEnumerable<Language> ActiveLanguages{get; set;}
}
public class Language
{
public int Id { get; set; }
public string Name { get; set; }
}
Controller
[HttpGet]
public ActionResult Language()
{
var languageViewModel = new LanguageViewModel
{
ActiveLanguages = LanguageController.GetAll();
}
return View(languageViewModel);
}
View
#model LanguageViewModel
#using Web.Helpers
#{
ViewBag.Title = "";
}
<div class="">
<div class="row">
<div class="col-md-12 col-sm-12 col-xs-12">
<div class="x_panel">
<div class="x_title">
<h2><i class="fa fa-filter"></i> </h2>
<div class="clearfix"></div>
</div>
<div class="x_content">
<br />
#using (Html.BeginForm("Settings","Language", FormMethod.Post, new { #class = "form-horizontal form-label-left" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<div class="col-md-12 col-sm-12">
<div class="col-md-12 col-sm-12">
#Html.DropDownListFor(model => model.LanguageId, new SelectList(Model.ActiveLanguages, "Id", "Name"), new { #class = "form-control" })
</div>
</div>
}
}
}
}
}
}
It would work like in this example:
#{
List<SelectListItem> listItems= new List<SelectListItem>();
listItems.Add(new SelectListItem
{
Text = "Exemplo1",
Value = "Exemplo1"
});
listItems.Add(new SelectListItem
{
Text = "Exemplo2",
Value = "Exemplo2",
Selected = true
});
listItems.Add(new SelectListItem
{
Text = "Exemplo3",
Value = "Exemplo3"
});
}
#Html.DropDownListFor(model => model.tipo, listItems, "-- Select Status --")
I am working to develop an application asp.net MVC that has a text box and two drop down lists. Users can input a numeric value and choose from the list from - to to process . My problem is trying to validate the drop down list as I tried to use the required validation but didn't work. I also tried to check on the drop downs when sending null values but the error validation doesn't work!
The error type:
There is no ViewData item of type 'IEnumerable<SelectListItem>' that has the key 'fromCurrency.Name'.
Contorller
[HttpPost]
public ActionResult Index(Currencies cur)
{
if (ModelState.IsValid)
{
if (String.IsNullOrWhiteSpace(cur.fromCurrency.Name) || String.IsNullOrWhiteSpace(cur.toCurrency.Name))
{
ModelState.AddModelError(string.Empty, "you can not leave the empty dropdown please select any of these");
}
else
{
var fromCurrencyList = CurrenciesClient.GetFromCurrencyListAsync().Result;
ViewBag.FromCurrencies = new SelectList(fromCurrencyList, "CurrencyCode", "Name");
var ToCurrencyList = CurrenciesClient.GetToCurrencyListAsync().Result;
ViewBag.ToCurrencies = new SelectList(ToCurrencyList, "CurrencyCode", "Name");
var fromcurrname = cur.fromCurrency.Name;
string tocurrname = cur.toCurrency.Name;
//rate is taking by passing both dropdown currency code
decimal rate = CurrenciesClient.GetConversionRate("Currencies/GetConversionRate?fromcurrname=" + fromcurrname + "&tocurrname=" + tocurrname).Result;
ViewBag.TheResult = cur.CurrencyToConvert * rate;
}
}
return View();
}
Index View
#model ViewModel.Currencies
#{
ViewBag.Title = "Index";
}
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<div id="ConversionSection">
<form class="form-horizontal" method="post" id= "CurrencyConversion" action="/Currency/Index">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
<label class="col-sm-4 control-label">
#Html.LabelFor(m => m.CurrencyToConvert, "Enter Currency")
</label>
<div class="col-sm-4">
#Html.EditorFor(m => m.CurrencyToConvert, new { #class = " form-control" })
#*#Html.ValidationMessageFor(m => m.CurrencyToConvert)*#
#Html.ValidationMessageFor(m => m.CurrencyToConvert, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">
#Html.LabelFor(model => model.fromCurrency.Name, "From Currency")
</label>
<div class="col-sm-4">
#Html.DropDownListFor(m => m.fromCurrency.Name, ViewBag.FromCurrencies as SelectList, "--select--", new { #class = " form-control" })
#Html.ValidationMessageFor(model => model.fromCurrency.Name)
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">
#Html.LabelFor(model => model.toCurrency.Name, "To Currency")
</label>
<div class="col-sm-4">
#Html.DropDownListFor(m => m.toCurrency.Name, ViewBag.ToCurrencies as SelectList, "--select--", new { #class = "form-control" })
#*#Html.ValidationMessageFor(model => model.toCurrency.Name)*#
#Html.ValidationSummary(false, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">
#Html.LabelFor(l => l.ConvertedCurrency, "Value")
</label>
<div class="col-sm-4">
#Html.Editor("TheResult", new { #class = " form-control" })
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-4">
<button type="submit" class="btn btn-success">Submit</button>
</div>
</div>
</form>
</div>
Currencies.cs
public class Currencies
{
[Required]
[DataType(DataType.Currency)]
[DisplayFormat(ConvertEmptyStringToNull = false)]
public decimal CurrencyToConvert { get; set; }
public Currency fromCurrency { get; set; }
public Currency toCurrency { get; set; }
public double ConvertedCurrency { get; set; }
}
Since nothing is return if your modelstate will be invalid. So viewbag.FromCurrencies and Viewbag.ToCurrencies should be outside of if (ModelState.IsValid).If you will not add Viewbag properties code after if(ModelState.IsValid) null value will be passed through it and you will get this exception. I am writing here refactored code in httppost method.
[HttpPost]
public ActionResult Index(ConvertCurrencyViewModel cur)
{
if (ModelState.IsValid)
{
string fromcurrname = cur.fromCurrency.Name;
string tocurrname = cur.toCurrency.Name;
//rate is taking by passing both dropdown currency code
decimal rate = CurrencyClient.GetConversionRate("Currency/GetConversionRate?fromcurrname=" + fromcurrname + "&tocurrname=" + tocurrname).Result;
ViewBag.result = cur.CurrencyToConvert * rate;
}
//getting this select list value form Currency client class
var fromCurrencyList = CurrencyClient.GetFromCurrencyListAsync().Result;
ViewBag.FromCurrencies = new SelectList(fromCurrencyList, "CurrencyCode", "Name");
var ToCurrencyList = CurrencyClient.GetToCurrencyListAsync().Result;
ViewBag.ToCurrencies = new SelectList(ToCurrencyList, "CurrencyCode", "Name");
return View();
}
And modifiy your curreny class like this to show validation error.
public class Currencies
{
[Required(AllowEmptyStrings = false, ErrorMessage = "Please enter amount to convert")]
[DataType(DataType.Currency)]
[DisplayFormat(ConvertEmptyStringToNull = false)]
public decimal CurrencyToConvert { get; set; }
[Required(AllowEmptyStrings = false, ErrorMessage = "Please select country Name")]
public Currency fromCurrency { get; set; }
[Required(AllowEmptyStrings = false, ErrorMessage = "Please select country Name")]
public Currency toCurrency { get; set; }
public double ConvertedCurrency { get; set; }
}
This will help you to validate your fields.
How do I save multiple data from dynamically added textbox via javascript? I have done the dynamically added textbox for product list and payment terms. What should I do for the controller and View
I have test This but didn't work
here is my controller
public ActionResult Create([Bind(Include = "PurchaseInvoiceTable,PurchaseInvoiceDetailsTable,PaymentTerm")]InvoiceWrapper model)
{
try
{
if (ModelState.IsValid)
{
db.PurchaseInvoiceTables.Add(model.PurchaseInvoiceTable);
db.SaveChanges();
var PID = model.PurchaseInvoiceTable.PurchaseInvoiceID;
model.PurchaseInvoiceDetailsTable.InvoiceID = PID;
model.PaymentTerm.InvoiceID = PID;
db.PurchaseInvoiceDetailsTables.Add(model.PurchaseInvoiceDetailsTable);
db.PaymentTerms.Add(model.PaymentTerm);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.InvoiceID = new SelectList(db.PurchaseInvoiceTables, "PurchaseInvoiceID", "PurID", model.PurchaseInvoiceDetailsTable.InvoiceID);
ViewBag.InvoiceID = new SelectList(db.PurchaseInvoiceTables, "PurchaseInvoiceID", "PurID", model.PaymentTerm.InvoiceID);
return View(model);
}
catch (DbEntityValidationException e)
{
//catch validation here
}
}
Here is my invoiceWrapper
using System;
using System.Collections.Generic;
namespace OnlineInvoiceSystem.Models
{
public class InvoiceWrapper
{
public PurchaseInvoiceTable PurchaseInvoiceTable { get; set; }
public PurchaseInvoiceDetailsTable PurchaseInvoiceDetailsTable { get; set; }
public PaymentTerm PaymentTerm { get; set; }
}
}
here is my javascript You can test it on Jsfiddle
my view is this
#model OnlineInvoiceSystem.Models.InvoiceWrapper
#{ Layout = null; Layout = "~/Views/Shared/_Layout.cshtml"; }
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
<form>
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<h2>Product List</h2>
<div class="panel panel-default product_wrapper">
//dynamic added textbox will appear here
</div>
<button class="add_field_button btn btn-primary pull-right">Add More Fields</button>
<div class="wrapper-payment-details">
<tr style="background-color:black; color:white;" class="payment_term_wrapper">
// here is the dynamic added payment terms textbox
</tr>
</div>
<div class="form-group">
<div>
<input type="submit" value="Create" class="btn btn-primary pull-right" /> #Html.ActionLink("Back", "Index", null, new { #class = "btn btn-small btn-danger pull-right", #style = "margin-right:2%;" })
</div>
</div>
</form>
}
You should Model
#Html.TextBoxFor(m => m.PurchaseInvoiceID, new {id="PurchaseInvoiceID" ,#class = "form-control" })
#Html.TextBoxFor(m => m.InvoiceID , new {id="InvoiceID " ,#class = "form-control" })
then pass this variable through ajax or post json
You should use a javascript ajax (POST call), with a json containing all of your dynamic added fields (as a list maybe of item value objects), and on server side you need an action method that can process the list, you can't do it directly from MVC.
I have ASP.NET MVC application and I am failing to Server-side and client-side validation for partial page. In the start of my application there is login page which validating correctly. so if I press submit with no values in form, app don't show any error messages
model class
public class CreateFunctionNavigation_SP_Map
{
public CreateFunctionNavigation_SP_Map()
{
}
//Function Table
[StringLength(250)]
[Required(ErrorMessage = "Required Function Title")]
[Display(Name = "Function Title")]
public string FunctionName { get; set; }
[Required(ErrorMessage = "Required Function Hierarchy; i.e Where Function Exists In Hierarchy Tree \n Top-Level Start From 1 ")]
[Display(Name = "Function Hierarchy Level")]
public int FunctionHierarchy_Level { get; set; }
//Controller Table
[StringLength(250)]
[Required(ErrorMessage = "Required Controller Title")]
[Display(Name = "Controller Title")]
public string ControllerName { get; set; }
//Action Table
[StringLength(250)]
[Required(ErrorMessage = "Required Action Title")]
[Display(Name = "Action Title")]
public string ActionName { get; set; }
// Hierarchy Table
[Required(ErrorMessage = "Required Function Parent - Child Relation ID \n Put 0 In Case Given Function doesn't Have Any Parent Function ")]
[Display(Name = "Function Parent's FunctionID")]
public int Function_ParentsFunctionID { get; set; }
}
controller method
#region CreateNewFunctionNavigation
[HttpGet]
public ActionResult CreateNewFunctionNavigation()
{
return PartialView("CreateNewNavigation_Partial");
}
#endregion
[HttpPost]
public ActionResult CreateNewFunctionNavigation(CreateFunctionNavigation_SP_Map obj )
{
try
{
if(ModelState.IsValid)
{
_FN_Services_a2.CreateFunctionNavigation(obj);
}
}
catch (DataException ex)
{
ModelState.AddModelError("", "Unable To Create New Function Navigation" + ex);
}
return RedirectToAction("SystemCoreHome");
} //end
view
#model App.DAL.Model.CreateFunctionNavigation_SP_Map
<div class="_Form_Block">
#using (Html.BeginForm("CreateNewFunctionNavigation", "SystemCore", FormMethod.Post, new { id = "NewFunctionNavigationForm" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(#model => #model.FunctionName, new { #class = "control-label col-md-2" })
<div class="form-group">
#Html.EditorFor(#model => #model.FunctionName)
#Html.ValidationMessageFor(#model => #model.FunctionName)
</div>
</div>
<div class="form-group">
#Html.LabelFor(#model => #model.FunctionHierarchy_Level, new { #class = "control-label col-md-2" })
<div class="form-group">
#Html.EditorFor(#model => #model.FunctionHierarchy_Level)
#Html.ValidationMessageFor(#model => #model.FunctionHierarchy_Level)
</div>
</div>
<div class="form-group">
#Html.LabelFor(#model => #model.ControllerName, new { #class = "control-label col-md-2" })
<div class="form-group">
#Html.EditorFor(#model => #model.ControllerName)
#Html.ValidationMessageFor(#model => #model.ControllerName)
</div>
</div>
<div class="form-group">
#Html.LabelFor(#model => #model.ActionName, new { #class = "control-label col-md-2" })
<div class="form-group">
#Html.EditorFor(#model => #model.ActionName)
#Html.ValidationMessageFor(#model => #model.ActionName)
</div>
</div>
<div class="form-group">
#Html.LabelFor(#model => #model.Function_ParentsFunctionID, new { #class = "control-label col-md-2" })
<div class="form-group">
#Html.EditorFor(#model => #model.Function_ParentsFunctionID)
#Html.ValidationMessageFor(#model => #model.Function_ParentsFunctionID)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default _formButton" />
<input type="button" value="Cancel" class="btn btn-default _formButton" onclick="CancelPage();" />
</div>
</div>
}
</div> <!--End _Form_Block-->
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
instead of
return RedirectToAction("SystemCoreHome");
use
return PartialView("CreateNewNavigation_Partial", obj);
Ajax Form
#using (Ajax.BeginForm(new AjaxOptions { UpdateTargetId = "TargetID" }))
{
...
}
<div class="_Form_Block" id="TargetID">
</div>
You need to handle this case.
Presently you are not doing anything in the event that the ModelState is invalid. Try the following:
public ActionResult CreateNewFunctionNavigation(CreateFunctionNavigation_SP_Map obj)
{
if (!ModelState.IsValid)
{
return View(obj);
}
// rest of method here
if(ModelState.IsValid)
{
_FN_Services_a2.CreateFunctionNavigation(obj);
}
else
{
return View();
}
Should do the trick.
Model:
public class SelectBillingSiteReportModel
{
public IEnumerable<SelectListItem> Sites { get; set; }
public string SelectedSiteName { get; set; }
public string SelectedSiteKey { get; set; }
[Required]
[DataType(DataType.Date)]
public DateTime FromDateTime { get; set; }
[Required]
[DataType(DataType.Date)]
public DateTime ToDateTime { get; set; }
}
View:
#model MuseReport.Models.SelectBillingSiteReportModel
#{
ViewBag.Title = "Select Site and Date Range";
}
<div class="page-header">
<h4>Select Site and Date Range for Ecg Billing Summary</h4>
</div>
<div class="row">
#using (Html.BeginForm("EcgBilling", "BillingRpt"))
{
<div class ="form-horizontal" role="form">
<div class="form-group">
#Html.Label( "Muse Site", new { #class = "col-md-2 control-label"})
<div class="col-md-10">#Html.DropDownListFor(model => model.SelectedSiteKey, Model.Sites, new { id="museSites", #class = "selectpicker"})</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.FromDateTime, "From Date", new { #class = "col-md-2 control-label"})
<div class="col-md-10">#Html.EditorFor(model => model.FromDateTime)</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ToDateTime, "To Date", new { #class = "col-md-2 control-label"})
<div class="col-md-10">#Html.EditorFor(model => model.ToDateTime)</div>
</div>
<div class="form-group">
<div class="col-md-10">#Html.HiddenFor(model => model.SelectedSiteName)</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<button type="submit" class="btn btn-primary">Go</button>
</div>
</div>
</div>
}
In a perfect world, I would like to get the whole SelectListItem that the user has selected in the dropdown, rather than just the Value in model.SelectedSiteKey. At worst, I would like to get the Text associated with the Value that was selected into the hidden field (model.SelectedSiteName).
My research suggests that I could use javascript, or I could use an EditorTemplate, neither of which I am clear on how to do.
It seems like this is a lot of work just to trap one extra text string. Am I missing an obvious way to get the text value from the dropdown on the selection?
I just want to save the text value for display with my results without
having to do another call back to the first db.
Based on your comment, you can combine both Text and Value store inside Value. Then split it when the Form is posted back.
For example -
public ActionResult EcgBilling()
{
var model = new SelectBillingSiteReportModel
{
Sites = new List<SelectListItem>
{
new SelectListItem {Text = "One", Value = "One:1"},
new SelectListItem {Text = "Two", Value = "Two:2"},
new SelectListItem {Text = "Three", Value = "Three:3"},
}
};
return View(model);
}
[HttpPost]
public ActionResult EcgBilling(SelectBillingSiteReportModel model)
{
string[] array = model.SelectedSiteKey.Split(':');
string text = array[0];
string value = array[1];
return View();
}
create two fields, 1-value, 2-text,
in the html page
get the selected item's text and assign it to text field
<input id="text_field" name="text_field" type="hidden" />
#Html.DropDownList("value_field", null, " ---Select ---", new { #id = "value", #class = "form-control selectpicker", required = "required", style = "width:180px" })
//jquery
$('#value').change(function () {
var text = $("option:selected", this).text();
$('#text_field').val(text);
});
this way you can save both text and value