I'm struggling with dropdownlist tried several methods online and all failed will show the methods that I tried.
Objective
Create a Reciept with date,reference... & country. Country is Required and should be a dropdownlist.
So the Table for Reciept("ID, Name, Date, Address, City, CountryList).
RecieptModel
public class TransactionModel
{
public int ID { get; set; }
public int Name{ get; set; }
public DateTime Date { get; set; }
public string Address { get; set;}
public string City { get; set; }
public CountryList CountryList { get; set; }
}
public class ApplicationDbContext : DbContext
{
public DbSet<RecieptModel> Reciepts { get; set;}
public DbSet<CountryList> coutryList { get; set; }
}
CountryList
public class CountryList
{
public byte Id { get; set; }
public enum Country
{
Germany,
US,
UK
}
}
Controller
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "ID,Name,Date,City,CountryList")] Reciepts reciepts)
{
if (ModelState.IsValid)
{
db.Reciepts.Add(reciepts);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(reciepts);
}
View
<div class="form-group">
#Html.LabelFor(model => model.CountryList, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EnumDropDownListFor(model => model.CountryList)
#Html.ValidationMessageFor(model => model.CountryList)
</div>
</div>
This failed I looked for several examples I'm trying to do it without the use of javascript. In the End I just want to learn how to implement a Dropdownlist & save it to the database allot of the methods that I tried to implement failed in MVC5.
I would sugest you to add a html extension method that implement dropdownlist for a generic enumarator. Take a look at this answer.
There is slightly change in your view where you bind the Country
this is actually you write
#Html.EnumDropDownListFor(model => model.CountryList)
Change is need to add name property in your country list (it must be ID that is your taken in your model) , so it must be like this to maintain country list value
#Html.DropDownListFor(model => model.CountryList.Id, new SelectList(model => model.CountryList)
Becouse every HTML control need unique indentifier
Related
Basically i have a editor view where i have a few fields and a list, located in admin -> teacher -> edit
File.cshtml
<fieldset>
<legend>#T("Details")</legend>
#Html.LabelFor(m => m.FirstName, T("First name"))
#Html.TextBoxFor(m => m.FirstName)
#Html.LabelFor(m => m.LastName, T("Last name"))
#Html.TextBoxFor(m => m.LastName)
#Html.LabelFor(m => m.Gender, T("Gender"))
#Html.DropDownListFor(m => m.Gender, genderSelectListItems, "Select gender...")
</fieldset>
<fieldset>
#{
var i = 0;
#Html.LabelFor(m => m.Availability)
#Html.DropDownListFor(m => m.Availability, daysSelectList, "Select day to add...")
<input type="button" id="addDay" value="Add" />
<ul id="daysList">
#foreach (var day in Model.Availability)
{
<li>
#Html.TextBoxFor(m => m.Availability[i].Interval)
</li>
i++;
}
</ul>
}
</fieldset>
Whenever i submit the data, only the fields get saved. The list is never saved, even though fiddler shows that the data is sent back to the server
My models are:
TeacherPartRecord
public class TeacherPartRecord : ContentPartRecord
{
public TeacherPartRecord()
{
TeacherData = new List<TeacherDataRecord>();
}
public virtual string FirstName { get; set; }
public virtual string LastName { get; set; }
public virtual Gender Gender { get; set; }
public virtual IList<TeacherDataRecord> TeacherData { get; set; }
}
TeacherPart - this file is almost the same as TeacherPartRecord so i truncated it, showing only the difference
public class TeacherPart : ContentPart<TeacherPartRecord>
{
................
public IList<AvailabilityRecord> Availability
{
get { return Record.TeacherData.Select(r => r.AvailabilityRecord).ToList(); }
}
}
TeacherDataRecord
public class TeacherDataRecord
{
public virtual int Id { get; set; }
public virtual TeacherPartRecord TeacherPartRecord { get; set; }
public virtual AvailabilityRecord AvailabilityRecord { get; set; }
}
AvailabilityRecord
public class AvailabilityRecord
{
public virtual int Id { get; set; }
public virtual Day Day { get; set; }
public virtual string Interval { get; set; }
}
and TeacherPartDriver
public class TeacherPartDriver : ContentPartDriver<TeacherPart>
{
//GET
protected override DriverResult Editor(TeacherPart part, dynamic shapeHelper)
{
return ContentShape("Parts_Teacher_Edit", () =>
shapeHelper.EditorTemplate(TemplateName: "Parts/Teacher", Model: BuildEditorViewModel(part), Prefix: Prefix));
}
//POST
protected override DriverResult Editor(TeacherPart part, IUpdateModel updater, dynamic shapeHelper)
{
var viewModel = new TeacherEditViewModel();
updater.TryUpdateModel(viewModel, Prefix, null, null);
_teacherService.UpdateTeacher(viewModel, part);
return Editor(part, shapeHelper);
}
}
BuildEditorViewModel only maps properties from TeacherPart to TeacherEditViewModel, which is identical with TeacherPart
The POST Editor method never receives the data from Availability (part.Availability is the same as previously, new data is not received)
I inserted a few entries in the database manually because i can't add a list of type Availability from the edit page, even though the other content (first name, last name, gender) is created
I would like to know how/when does the binding occur, or maybe some suggestions on how i could solve this issue.
I should mention that my c#/MVC experience is 6 months and my orchard experience is about 2 weeks so i'm still learning.
All i hope is that i stated my problem clearly and there is someone that can help.
Thank you for your time
EDIT
As i can see, the values are bound
<input id="Teacher_Availability_0__Interval" name="Teacher.Availability[0].Interval" type="text" value="14-20">
<input id="Teacher_Availability_1__Interval" name="Teacher.Availability[1].Interval" type="text" value="12-18">
and fiddler shows the data is getting sent
Fiddler
so i guess that something wrong happens right after the data is sent and before being received by the server or maybe my models are wrong
How can I choose which property is displayed in Html.DropDownListFor for a some type?
For example I have the following class from which I want to select values
public partial class Artysta
{
public Artysci()
{
this.SpektaklArtysta = new HashSet<SpektaklArtysta>();
}
[Key]
public int ArtystaID { get; set; }
public string Imie { get; set; }
public string Nazwisko { get; set; }
}
Here is a generated code for edit View which sometimes displays Imie and from time to time Nazwisko.
#using (Html.BeginForm())
{
#model Teatr.Models.SpektaklArtysta
<div class="form-group">
#Html.LabelFor(model => model.ArtystaID, "Artysta", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("ArtystaID", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.ArtystaID, "", new { #class = "text-danger" })
</div>
</div>
}
I would like to set displayed property to Nazwisko, how can I achieve that?
UPDATE:
Here is actual model that this View was generated.
public partial class SpektaklArtysta
{
public int SpektaklID { get; set; }
public int ArtystaID { get; set; }
public int RolaArtystyID { get; set; }
[Key]
public int SpektaklArtystaID { get; set; }
public virtual Artysci Artysci { get; set; }
public virtual RolaArtysty RolaArtysty { get; set; }
public virtual Spektakle Spektakle { get; set; }
}
Ok, you need to actually pass a list of possible values to the dropdown list, for example like this:
#Html.DropDownListFor(model => model.ArtystaID, new SelectList(Model.Artysci, "ArtystaID", "Nazwisko", 0))
It says: DropDownList setting models ArtystaID field, which is populated by models Artysci field, which is supposed to contain items that have key under ArtystaID field and display text under Nazwisko field (so, your Artysta class).
Now, your class doesn't have Artysci field, so you have to create it:
public partial class Artysta
{
public Artysci()
{
this.SpektaklArtysta = new HashSet<SpektaklArtysta>();
}
[Key]
public int ArtystaID { get; set; }
public string Imie { get; set; }
public string Nazwisko { get; set; }
public List<Artysta> Artysci = ArtistRepository.GetAllArtists();
}
Or you can pass it directly in DropDownList:
#Html.DropDownListFor(model => model.ArtystaID, new SelectList(ArtistRepository.GetAllArtists(), "ArtystaID", "Nazwisko", 0))
Oh, and just a personal note: I know it's probably not your choice, unless you are a lead/sole developer, but please use English names for your classes, variables etc., it will be much easier if in the future someone else will have to work on your code, and they might not speak Polish ;)
One good option for you is to use the DropDownList as following
#Html.DropDownList("DropDownId", Model.Select(item => new SelectListItem
{
Value = item.ArtystaID.ToString(),
Text = item.Nazwisko.ToString(),
Selected = "select" == item.ArtystaID.ToString() ? true : false
}))
Hope that answers your request!
I am creating a small website which allows users to create questions and exams (and also take those exams). Facing a problem with the Create-examview. The user has to be allowed to check any Questions that should be added to the Exam.
Using the following action to create the view, which passes the Questions in a ViewBag:
public ActionResult Create()
{
QuestionaireDbContext db = new QuestionaireDbContext();
ViewBag.Questions = db.Questions;
return View();
}
In my view then, I can call ViewBag.Questions and (should be able to?) use those to create checkboxes for each Question.
I have tried using the extesionmethod for HtmlHelper, CheckBoxList, which I got through NuGet. But the Html.CheckBoxList doesn't seem to be picked up. I tried adding the using as suggested in their documents but that didn't work either.
How can I create a checkbox for each Question and allow the user to select a variaty of them?
My Exam and Question-models for reference:
public class Exam
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime CreationDate { get; set; }
public ICollection<Question> Questions { get; set; }
}
public class Question
{
public enum Answers
{
A,
B,
C,
D
}
public int Id { get; set; }
public string Name { get; set; }
public string AnswerA { get; set; }
public string AnswerB { get; set; }
public string AnswerC { get; set; }
public string AnswerD { get; set; }
public Answers Correct { get; set; }
}
You will need to create view models to represent what you want to bind to. One possible solution might be
public class ExamVM
{
public int ID { get; set; }
public string Name { get; set; }
public List<QuestionVM> Questions { get; set; }
}
public class QuestionVM
{
public int ID { get; set; }
public string Name { get; set; }
public bool IsSelected { get; set; }
}
In you Create method, initialize and populate the ExamVM details including the collection of possible questions, then in the view
#model YourAssembly.ExamVM
#using (Html.BeginForm())
{
#Html.HiddenFor(m => m.ID)
#Html.DisplayFor(m => m.Name)
for (int i = 0; i < Model.Questions; i++)
{
#Html.HiddenFor(m => m.Questions[i].ID)
#Html.CheckBoxFor(m => m.Questions[i].IsSelected)
#Html.DisplayFor(m => m.Questions[i].Name)
}
<input type="submit" value="Save" />
}
Post method
[HttpPost]
public ActionResult Create(ExamVM model)
{
foreach(QuestionVM q in model.Questions)
{
if (q.IsSelected)
{
// Save the value of exam.ID and question ID to the database
Create a folder called EditorTemplates in your Views/Shared folder.
create a new empty view called _QuestionEditor and add the following code.
#model Question
#Html.HiddenFor(model => model.Id)
#Html.DisplayFor(model => model.Name)
//use DisplayFor or LabelFor accordingly
#Html.CheckboxFor(model => true, Model.AnswerA)
#Html.CheckboxFor(model => true, Model.AnswerB)
#Html.CheckboxFor(model => true, Model.AnswerC)
#Html.CheckboxFor(model => true, Model.AnswerD)
now in your main view use it as follows
#foreach(var question in ViewBag.Questions){
#Html.EditorFor(item => question)
//you can specify the template name i.e `"_QuestionEditor"` as the second parameter
//if you have more than one editor template for the same type
}
This doesn't take into account how you submit your data as you haven't provided any code for that or the model that you use to get the data back into your post action
Which I'd expect to be implemented in .NET MVC, but trying to figure out how to actually do it. Currently on my ViewModel, I have (for example):
public class GroupPolicyViewModel
{
public int PolicyId { get; set; }
public int HistoryId{ get; set; }
public SelectList ProductList { get; set; } // tried this
public List<Product> ProductList1 { get; set; } // tried this
}
Whenever I try and auto-generate my View from this ViewModel, the ProductList gets ignored. Is there any way to auto-generate a DropDownList at all from the ViewModel?
With model
public class GroupPolicyViewModel
{
public int PolicyId { get; set; }
public int HistoryId{ get; set; }
public int SelectedProductId{ get; set; }
public List<Product> ProductList { get; set; }
}
You can create DropDownList
#Html.DropDownListFor(m => m.SelectedProductId,
new SelectList(Model.ProductList, "ProductId", "ProductName"))
Or if you have SelectList of products in your model
#Html.DropDownListFor(m => m.SelectedProductId, Model.ProductSelectList)
If you want some generated code, you need to use scaffolding option with providing data context class. Here is nice tutorial MVC Music Store
You can (from VS2010) when creating a new Controller and using Entity Framework. Specify in the wizard to include Entity Framework and Read/Write ops and the wizard will create both the controller and the views.
It'll generate code like this [there is more] in the controller:
public ActionResult Create()
{
ViewBag.CostCentre_ID = new SelectList(db.CostCentres, "ID", "Name");
ViewBag.Location_ID = new SelectList(db.Locations, "ID", "Name");
ViewBag.User_ID = new SelectList(db.UCMUsers, "User_ID", "EmployeeNo");
return View();
}
and this in the view:
<div class="editor-field">
#Html.DropDownList("User_ID", String.Empty)
#Html.ValidationMessageFor(model => model.User_ID)
</div>
I'm new to MVC and I use MVC4 and I'm new to C#. I want to retrieve data from two tables: tblProduct and tblCategory in one View. In that View I want to get from tblCategory the column "Name" and from tblProduct all the columns.
I've defined my tables in code first in class tables.cs:
public class tblCategory
{
//Primary Key
[Key]
[ScaffoldColumn(false)]
public int CategoryId { get; set; }
[MaxLength(160)]
public string Name { get; set; }
etc...
}
public class tblProduct {
//Primary Key
[Key]
[ScaffoldColumn(false)]
public int ProductId { get; set; }
//Foreign Key
public int CategoryId { get; set; }
[ForeignKey("CategoryId")]
public virtual tblCategory tblCategorys { get; set; }
[MaxLength(500)]
public string MainImageFileName { get; set; }
[MaxLength(160)]
public string Name { get; set; }
ect...
}
My model class, bar.cs:
Namespace xx.Models
public class bar {
public tblProduct product { get; set; }
public tblCategory category { get; set; }
}
How do I define the Index class in the Controller right? So that I can send data from model bar into the View.
public ActionResult Index(){
//How to define this?
}
And how should build up the View?
#model xx.Models.bar
But I want to use a Foreach loop in my View for all the columns from tblProduct.
And one column from tblCategory.
Can somebody help me with this? Thanks!
Your Index action should build an instance of your bar class
public ActionResult Index(){
var b = new bar();
b.product = some loading code;
b.category= some loading code;
return View(b);
}
your Index.cshtml need to expect an instance of that same model
#model ProjectName.xx.Models.bar
<div class="editor-label">
#Html.LabelFor(model => model.category.Name)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.category.Name)
#Html.ValidationMessageFor(model => model.category.Name)
</div>
#* just duplicate this once for each property you want from product *#
<div class="editor-label">
#Html.LabelFor(model => model.product.Name)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.product.Name)
#Html.ValidationMessageFor(model => model.product.Name)
</div>
i wouldn't use a for loop on the properties in product, because then you need reflection, and i doubt that page will function very fast.
I think both of this classes should be model cause clearly they are representation of tables in database. However class Bar i think it's not. I think your structure should be organized like this: product(model class), category(model class) = bar(model collection class). So instead of adding both classes as properties of class Bar you should define dictionary that will contain those class but tie those class with common interface i.e. IViewModel.
public interface IViewModel{
string name {get;set;}
}
public class TblProduct: IVievModel{
/// your code
}
public class TblCategory: IVievModel{
/// your code
}
public class Bar{
private Dictionary<string, IViewModel> viewModels = new Dictionary<string,IViewModel>();
}
Now in your ActionResult method you will just add those two classes to dictionary and return this class Bar to your view.