I am trying to save data using SelectListItem. I have managed to display the data but, I can't think of a way to save a selected item into the database.
My controller methods are:
public ActionResult Create()
{
ViewBag.ProposerID = new SelectList(db.Proposers, "ID", "ProposerName");
List<SelectListItem> projectType = new List<SelectListItem>();
projectType.Add(new SelectListItem { Text = "Development", Value = "1" });
projectType.Add(new SelectListItem { Text = "Research", Value = "2" , Selected = true});
projectType.Add(new SelectListItem { Text = "Hybrid", Value = "3" });
projectType.Add(new SelectListItem { Text = "Other", Value = "4" });
ViewBag.ProjectType = projectType;
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(
[Bind(Include = "ID,ProjectTitle,Description,ProposedDate,ProjectType,ProjectStatus,ProjectDifficulty,ProposerID")] Project project)
{
try {
if (ModelState.IsValid && ModelState != ModelState)
{
db.Projects.Add(project);
db.SaveChanges();
return RedirectToAction("Index");
}
}
catch (Exception)
{
ViewBag.ErrorMessage = "Something went wrong!! Please try again.";
// Error message
}
ViewBag.ProposerID = new SelectList(db.Proposers, "ID", "ProposerName", project.ProposerID);
return View(project);
}
and my View:
<div class="form-group">
#Html.LabelFor(model => model.ProjectType, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("ProjectType", "")
#Html.ValidationMessageFor(model => model.ProjectType, "", new { #class = "text-danger" })
</div>
</div>
I have managed to display the data but, I am confused on how to get selected item and save it.
My Model is:
public class Project
{
public int ID { get; set; }
[Required]
[DisplayName("Project Title")]
public string ProjectTitle { get; set; }
[Required]
[DataType(DataType.MultilineText)]
[DisplayName("Project Description")]
public string Description { get; set; }
[Required]
[DataType(DataType.Date)]
[DisplayName("Proposed Date")]
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}")]
public DateTime ProposedDate { get; set; }
// Development or Research etc.
[Required]
[DisplayName("Project Type")]
public string ProjectType { get; set; }
// Project Is Taken or Not
[DisplayName("Project Status")]
public ProjectStatus ProjectStatus { get; set; }
[DisplayName("Project Difficulty")]
public ProjectDifficulty ProjectDifficulty { get; set; }
[ForeignKey("Proposer")]
public int ProposerID { get; set; }
public virtual Proposer Proposer { get; set; }
}
First of all change you ViewBag key so it is different than the model property name:
ViewBag.ProjectTypeOptions = projectType;
and in your view use DropDownListFor helper this way:
#Html.DropDownListFor(x=>x.ProjectType, new SelectList(ViewBag.ProjectTypeOptions,"Value","Text"))
now you will get selecred item value posted in Model in ProjectType property.
and your model should have property of type string not IEnumerable<SelectListItem> like this:
public class Project
{
public string ProjectType { get;set;}
............
............
}
Related
There is a problem I have been troubleshooting a day and a half and I need some help.
The code looks fine , but the issue is that it returns Null.
I can get the property of that value on the View Side.
It throws:
No ViewData IEnumerable.
This is what |I have done so far and I need some help , my View use the Multiple Model but its correct class name with correct properties.
[HttpPost]
public ActionResult CourseList()
{
var course = new List<string>()
{ "Private(Copyrighted)","Public Domain", "Creative Commons Licences", "CC Attribution", "CC Attribution Share ALike", "CC Attribution Non-Commercial",
"CC Attribution Non-Commercial Share Alike", "CC Attribution Non Directive", "CC Attribution Non-Commercial No Directives"
};
// List of items here.
List<SelectListItem> select_list = new List<SelectListItem>();
var query = from li in course
select
new SelectListItem
{
Value = li.ToString(),
Text = li.ToString(),
};
select_list = query.ToList();
ViewBag.course = select_list;
eNtsaCourseList eCourse = new eNtsaCourseList();
return View(eCourse);
}
// eNtsaRegCourses.
public class RegCoursesViewModel
{
public eNtsaCourses Courses { get; set; }
public eNtsaCourseList eCourses { get; set; } // I am using this property for my View to access dropdownlist.
public eNtsaDashboardViewModel Dashboard { get; set; }
public List<eNtsaCourseList> lsteNtsaDashboard { get; set; }
public RegCoursesViewModel MainModel { get; set; }
}
public class eNtsaCourseList
{
public string CourseLicence { get; set; }
public string Text { get; set; }
public string Value { get; set; }
public string CourseList { get; set; }
}
#using (Html.BeginForm("CourseList", "Home", FormMethod.Post))
{
<div class="form-group row">
<label for="Content-Licence" class="col-sm-3 col-form-label">Content Licence</label>
<div class="col-sm-5">
#Html.DropDownListFor(m => m.eCourses.CourseList, ViewBag.course as List<SelectListItem>)
</div>
</div>
}
Model Class:
public class Course
{
[Key]
public int Id { get; set; }
[MinLength(5, ErrorMessage = "Code must be (5) characters long")]
[Index(IsUnique = true)]
[Column(TypeName = "VARCHAR")]
[Required]
[Display(Name = "Code")]
public string CourseCode { get; set; }
[Index(IsUnique = true)]
[Column(TypeName = "VARCHAR")]
[Required]
[Display(Name = "Name")]
[Remote("IsCourseNameExist", "Courses", HttpMethod = "POST", ErrorMessage = "Course is existed.")]
public string CourseName { get; set; }
//[System.ComponentModel.DataAnnotations.Compare("CourseName", ErrorMessage = "Already this Course is exist.")]
//[NotMapped]
//public string VeryfyName { get; set; }
[Range(0.5, 5, ErrorMessage = "Credit Must be between (0.5) to (5.0)")]
[Display(Name = "Credit")]
public decimal CourseCredit { get; set; }
public string Description { get; set; }
public int DepartmentId { get; set; }
public int SemesterId { get; set; }
[ForeignKey("DepartmentId")]
public virtual Department Department { get; set; }
[ForeignKey("SemesterId")]
public virtual Semester Semester { get; set; }
}
In Controller Class:
public JsonResult IsCourseNameExist(string CourseName)
{
//var course = .....
return Json(course == null);
}
In View:
<div class="form-group">
#Html.LabelFor(model => model.CourseName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.CourseName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.CourseName, "", new { #class = "text-danger" })
</div>
</div>
Description:
I am using Code First EF and very new in this area.
I have a Model class "Course" which generated a DB table named "Courses".
In view, user will add courses for a selected department and semester. But the Course Name property is unique.If user give a course name already exist in "Courses" table and submit button, then some error generates. That's why I want to make confirm that the user can not put any existing course name. So it needs checking before submission.
I have searched a lot, as I am newbie, everything is not clear to me. I found a way to use [Remote()] in model class and then use an action in controller to solve this. But cant apply it.
I expect some brief how to write the code that I mentioned in Controller class and what additional things need to add in view.
Thanks!
You can use a conditional statement combined with .Any() lambda expression.
public JsonResult IsCourseNameExist(string CourseName)
{
if(dbContext.Courses.Any(x => x.CourseName.Trim().ToUpper().Equals(CourseName.Trim().ToUpper())
{
return Json(false);
}
else
{
return Json(true);
}
}
Using .ToUpper() will help this be more efficient, because if your table you have a course name called Math 101.. and the user types in math 101 that might be submitted without error.
Let me know if this helps.
The code below works fine but, in the textbox the decimal value has this format "0,0000"
(, is the decimal separator). I'd like have only 2 decimal. How can I do this ?
Thanks,
//Database model used with NHibernate
public class Bank
{
public virtual int Id { get; set; }
public virtual string FirstName { get; set; }
public virtual string LastName{ get; set; }
public virtual decimal Amount { get; set; }
}
//MVC Model
public class MyModel
{
public Bank Bank { get; set; }
}
//View
#Html.TextBoxFor(m => m.Bank.Amount, new { id = "tbAmount"})
Update 1
In the debugger, I don't see any decimal, wehn I do step by step inside (o #HTML.Textbofor) the view, the value does not have any decimal but when the page is displayed there are 4 decimals
//Database model used with NHibernate
public class Bank
{
public virtual int Id { get; set; }
public virtual string FirstName { get; set; }
public virtual string LastName{ get; set; }
public virtual decimal Amount { get; set; }
}
//Class for view
public class ViewBank
{
[DisplayFormat(DataFormatString = "{0:n2}", ApplyFormatInEditMode = true)]
public decimal Amount { get; set; }
}
//MVC Model
public class MyModel
{
public Bank Bank { get; set; }
var ViewBank = new ViewBank() { Amount = Bank.Amount};
}
//View
#Html.TextBoxFor(m => m.Amount, new { id = "tbAmount"})
I would use editor templates and I would not use my NHibernate domain models in my views. I would define view models which are specifically tailored to the requirements of the given view (in this case limiting the amount to 2 decimals):
[DisplayFormat(DataFormatString = "{0:n2}", ApplyFormatInEditMode = true)]
public decimal Amount { get; set; }
and then:
#Html.EditorFor(m => m.Bank.Amount)
This works for me
#Html.TextBox("Amount", String.Format("{0:0.00}", Model.Bank.Amount), new { id = "tbAmount"})
EDIT:
This is for TextBoxFor (does not work on MVC3)
#{var formated = String.Format("{0:0.00}", Model.Bank.Amount);}
#Html.TextBoxFor(m => m.Bank.Amount, formated, new { id = "tbAmount"})
In MVC 4 you can now pass the format as the second parameter
//View
#Html.TextBoxFor(m => m.Bank.Amount, "{0:n2}", new { id = "tbAmount"})
If you don't have customized editor template for Decimal type then EditorFor decorated with DisplayFormatAttribute would probably work out of the box.
For a custom editor template I ended up using something like:
#model decimal?
#{
string displayValue;
if (Model == null)
{
displayValue = null;
}
else {
var formatString = (ViewData.ModelMetadata).DisplayFormatString;
displayValue = formatString == null ? Model.ToString() : string.Format(formatString, Model);
}
}
<div class="form-group">
#Html.LabelFor(c => c)
#Html.TextBoxFor(c => c, new { type = "text", Value = displayValue, #class = "form-control" })
#Html.ValidationMessageFor(c => c)
</div>
Which works when the property is decorated with DisplayFormatAttribute like so:
[DisplayFormat(DataFormatString = "{0:n1}", ApplyFormatInEditMode = true), Display(Name = "Commission")]
public decimal? CommissionPercentage { get; set; }
This works for me.
in MVC5, in View:
#Html.TextBoxFor(o => o.Amount, "{0:n0}", new { #class = "form-control" })
Output before StringFormatting --> 15000.00
Output after StringFormatting --> 15000
I´m having a problem creating a DropDownListFor using a relation between to tables that are related on an entity code first:
public class Motivo_Agenda
{
[Key]
[Required]
public string DESC_MOTIVO { get; set; }
}
public class Agenda // Agenda da produção
{
[Key]
public int ID_AGD { get; set; }
[Required]
public DateTime DATA_AGD { get; set; }
[Display(Name = "De")]
public TimeSpan DE { get; set; }
[Required]
[Display(Name = "Até")]
public TimeSpan ATE { get; set; }
[Required]
public virtual Motivo_Agenda MOTIVO_AGENDA { get; set; }
}
I´m tryng to create a Drop Down List to add a new item to the Agenda Table this is my controller:
bAxaltaModel dbAxalta = new dbAxaltaModel();
// GET: Agenda
public ActionResult Edit()
{
ViewBag.MOTIVO_AGENDA = new SelectList(dbAxalta.Motivos_Agenda, "DESC_MOTIVO", "DESC_MOTIVO");
return View();
}
[HttpPost]
public ActionResult Edit([Bind(Include = "DE,ATE,DATA_AGD,FLAG_SAB_DOM,MOTIVO_AGENDA")]Agenda Agendas)
{
var errors = ModelState.Values.SelectMany(v => v.Errors).ToList();
if (ModelState.IsValid != false)
{
dbAxalta.Agendas.Add(Agendas);
dbAxalta.SaveChanges();
var query = dbAxalta.Agendas.Where(m => m.DATA_AGD == Agendas.DATA_AGD);
TempData["Agendas"] = query.ToList();
return View();
}
ViewBag.MOTIVO_AGENDA = new SelectList(dbAxalta.Motivos_Agenda, "DESC_MOTIVO", "DESC_MOTIVO", Agendas.MOTIVO_AGENDA);
return View();
}
And my DropDown is this:
#Html.DropDownListFor(m => m.MOTIVO_AGENDA, ViewBag.MOTIVO_AGENDA as SelectList, htmlAttributes: new { #class = "form-control" })
But I´m getting the following error:
The parameter conversion from type 'System.String' to type 'Axalta_Project.Models.Motivo_Agenda' failed because no type converter can convert between these types.
Any ideas how can I bind these?
When using DropDownListFor, the first parameter is the selected value so you will need to add this to your model.
Ideally, use a Model class rather than ViewBag in a similar format to the following:
public class MyModel {
public int SelectedAgendaId {get; set;}
public SelectList Agendas {get;set;}
}
Then use something like this:
#Html.DropDownListFor(m => m.SelectedAgendaId, Model.Agendas, htmlAttributes: new { #class = "form-control" })
Consider the following model:
public class TagType
{
public int Id { get; set; }
public string Description { get; set; }
}
public class Tag
{
public int Id { get; set; }
public string Description { get; set; }
public TagType TagType { get; set; }
public DropDownListViewModel TagTypeViewModel { get; set; }
public int TagTypeId { get; set; }
}
I have the following Action in a controller:
public ActionResult Edit(int id)
{
// Load from database
IEnumerable<TagType> tagTypes = TagTypeDal.GetAll().ToList();
Tag tag = TagDal.Get(id);
tag.TagTypeViewModel = new DropDownListViewModel();
tag.TagTypeViewModel.Items = new List<SelectListItem>();
tag.TagTypeViewModel.Items.Add(new SelectListItem { Text = "None", Value = "-1" });
tag.TagTypeViewModel.Items.AddRange(tagTypes
.Select(tt => new SelectListItem
{
Text = tt.Description,
Value = tt.Id.ToString(),
Selected = tt.Id == tag.TagType.Id
}).ToList());
return View(tag);
}
The select list has one element that has Selected=true, and it's not the first element.
And on my Edit.cshtml I have:
#model Models.Tag
#Html.DropDownListFor(model => model.TagTypeId,
#Model.TagTypeViewModel.Items,
new { #class = "form-control" })
My problem is that the generated drop down never selects the element that has Selected=true, it always shows the first element.
Am I calling the wrong overload for DropDownListFor? Or am I building the select list wrong? Or is it somethig else?
You should fill model.TagTypeId with selected TagTypeId in your Controller.
DropDownListFor selected value depends on first parameter value.