I'm new to ASP.NET mvc and kendo ui framework and have the following issue:
I have a partialview in a window with a multiselect which receives its values out of the database. the view looks like:
#model SoftwareAdminInterface.Models.Administration.Pattern
<div id="myContentPopupEditRole_div">
#using (Ajax.BeginForm("SetCombi", "Pattern", new { }, new AjaxOptions() { HttpMethod = "post", UpdateTargetId = "myContentPopupEditRole_div" }))
{
<center>
<br />
<table class="table_no_borders">
<tr>
<td style="width: 300px">
#(
Html.Kendo().MultiSelectFor(model => model.RegExId)
.MaxSelectedItems(2)
.Name("RegExID")
.DataTextField("RegExName")
.DataValueField("RegExID")
.Placeholder("Select Patterns...")
.AutoBind(false)
.DataSource(source => {
source.Read(read =>
{
read.Action("GetPatternsForCombi", "Pattern");
})
.ServerFiltering(true);
})
)
</td>
</tr>
</table>
<button class="k-button k-button-icontext k-grid-custom" id="get" type="submit">#Resources.General.BtnSave</button>
</center>
}
</div>
I'm using a model which looks like this:
public class Pattern
{
[ScaffoldColumn(false)]
public int RegExID { get; set; }
[Display(Name = "RegEx")]
[Required]
public string RegExName { get; set; }
[UIHint("GridForeignKey")]
public int CategoryID { get; set; }
public string CategoryName { get; set; }
public string ColumnName { get; set; }
public string RegExTable { get; set; }
[UIHint("GridForeignKey")]
public int? TableID { get; set; }
public string Version { get; set; }
public string Description { get; set;
}
in the SetCombi function which is called in the patterncontroller, I only want to receive the two ID's of the selected objects out of the multiselect, but I've no idea how they should be send to the controller.
thx in advance for your help
I think you have two options:
1) Change RegExID to be a string and then I believe they would come across as comma separated values.
2) (The better option) Add a ViewModel which has many of the same properties as your Pattern model above. The main difference for this is that you would have
public List<int> RegExIDs { get; set; }
Then in your controller you would take the new ViewModel as an argument to your post method and parse out the values in the list as necessary.
Related
First of all, I know this question has been asked many, many times. I've read countless articles and Stack Overflow answers. I've tried to figure this problem out for four days and I think I need help if someone doesn't mind.
I have two databases. The employee database has a field called "DisplayName" -- the second database has a relationship with the first and they work together great. I'm able to call the two databases perfectly in another application.
You can see the in the picture Index Page
that I have a list of people. I want a dropdown below it that lists all display names in the database so employees can add themselves to the list. You'll see a dropdown in the image but it's not populated.
Seems simple. But geez. Part of a problem I'm having is my home controller already has a function to populate the list in the picture so I can't do another on that page. I've tried a lot of suggestions on a lot of sites. I get IEnumerable errors or display reference errors....
Here's my controller (again - it has nothing in it that helps the dropdown):
namespace SeatingChart.Controllers
{
public class HomeController : Controller
{
private ApplicationDbContext db = new ApplicationDbContext();
// GET: Employee
public ActionResult Index()
{
var lists = db.BreakModels
.Include("Employee")
.Include("TimeEntered")
.Include("TimeCleared")
.Include("DisplayName")
.Select(a => new HomeIndexViewModels
{
Employee = a.Employee,
DisplayName = a.EmployeeModels.DisplayName,
TimeEntered = a.TimeEntered,
TimeCleared = a.TimeCleared.Value,
Id = a.EmployeeModels.Id,
});
return View(lists);
}
View:
#model IEnumerable<SeatingChart.Models.HomeIndexViewModels>
#{
Layout = null;
}
#Html.Partial("_Header")
<div class="container_lists">
<div class="container_break col-md-8">
<h5 style="text-align:center">Break List</h5>
<table class="table-bordered col-lg-12">
#if (Model != null)
{
foreach (var item in Model)
{
if (item.TimeCleared == null)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.DisplayName)
</td>
<td>
BV
</td>
<td>
#item.TimeEntered.ToString("HH:mm")
</td>
</tr>
}
}
}
</table>
#using (Html.BeginForm())
{
<div class="row site-spaced">
<div class="col-3">
#Html.DropDownList("DisplayName", new SelectList(new List<string>() { "---Dispatcher---" }), new { #class = "required " })
</div>
</div>
<div class="col-3">
<input type="submit" value="Submit" class="site-control" />
</div>
}
</div>
</div>
ViewModel:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Html;
namespace SeatingChart.Models
{
public class HomeIndexViewModels
{
//Break Model
public int BreakId { get; set; }
public int Employee { get; set; }
public DateTime TimeEntered { get; set; }
public DateTime? TimeCleared { get; set; }
//Employee Model
public int Id { get; set; }
public string DisplayName { get; set; }
public string DisplayNames { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public bool NotActive { get; set; }
public int Force { get; set; }
public string EmployeeList { get; set; }
}
}
I hope this is clear enough. I've tried so many different ways with so much code - the errors are different with everything I've tried.
Thanks in advance for your patience and help!
You can add to your viewmodel
public List<SelectListItem> Employees { get; set; }
Then you can populate this list with controller then in view just call it with:
#Html.DropDownListFor(m => m.Id, Model.Employees, new { #class = "form-control", required = "required" })
Update - how to populate list. Should work (but not tested code).
public List<SelectListItem> GetEmployeeForDropdown(List<HomeIndexViewModels> list)
{
List<SelectListItem> empList = new List<SelectListItem>();
try
{
if (list != null && list.Count > 0)
{
foreach (var item in list)
{
empList.Add(new SelectListItem { Text = item.DisplayName, Value = item.Id.ToString() });
}
}
else
{
empList.Add(new SelectListItem { Text = "No items", Value = string.Empty });
}
}
catch (Exception ex)
{
//handle exceptions here
}
return empList;
}
Edit: Remember to use your model in view!
1st model:
public class VehicleMake
{
[Key]
public int MakeId { get; set; }
public string Make { get; set; }
}
2nd Model:
public class VehicleModel
{
[Key]
public int ModelId { get; set; }
public string Model { get; set; }
public DateTime Year { get; set; }
public int MakeId { get; set; }
public VehicleMake VehcileMake { get; set; }
}
How to pass two models as strongly typed view.
my view has 1) one dropdownlist which bind make and makeid from VehicleMake class
2) one textbox as Model which binds from vehicleModle class
Please suggest how to create a view using multiple models?
#model MvcApplication1.Data.ViewVMModel
....
<h2>CreateModel</h2>
<table>
<tr>
<td>#Html.Label("Select Make")</td>
<td>#Html.DropDownListFor(model=>model.VehicleMake,new SelectList(Model. "MakeId","Make")))</td>
</tr>
<tr>
<td>Enter Model </td>
<td>#Html.TextBoxFor(model=>model.VehcileModel)</td>
</tr>
</table>
You're editing data so first step is to create a view model (add other validation attributes as required).
public class VehicleVM
{
[Required(ErrorMessage = "...")]
public string Model { get; set; }
[Required(ErrorMessage = "...")]
public DateTime? Year { get; set; } // make nullable to protect against under-posting attacks
[Required(ErrorMessage = "...")]
[Display(Name = "Make")]
public int? SelectedMake { get; set; }
public IEnumerable<SelectListItem? MakesList { get; set; }
}
and in the GET method, initialize an instance of your view model, populate it and pass it to the view
var makes = db.VehicleMakes; // get the Makes from the database
VehicleVM vehicle = new VehicleVM()
{
MakesList = new SelectList(makes, "MakeId", "Make")
};
return View(vehicle);
and in the view
#model VehicleVM
....
#using (Html.BeginForm())
{
#Html.LabelFor(m => m.SelectedMake)
#Html.DropDownListFor(m => m.SelectedMake, Model.MakesList)
#Html.ValidationMessageFor(m => m.SelectedMake)
#Html.LabelFor(m => m.Model)
#Html.TextBoxFor(m => m.Model)
#Html.ValidationMessageFor(m => m.Model)
....
Which will post back to
public ActionResult Create(VehicleVM vehicle)
your Viewmodel should be something like this
public VehicleModel VehicleModel { get; set; }
public List<VehicleMake> VehcileMakeList { get; set; }
and in your view
#model MvcApplication1.Data.ViewVMModel
....
<h2>CreateModel</h2>
<table>
<tr>
<td>#Html.Label("Select Make")</td>
<td>#Html.DropDownListFor(model=>model.VehicleModel.MakeId ,new SelectList(Model.VehcileMakeList, "MakeId","Make")))</td>
</tr>
<tr>
<td>Enter Model </td>
<td>#Html.TextBoxFor(model=>model.VehcileModel.Model)</td>
<td>#Html.TextBoxFor(model=>model.VehcileModel.Year )</td>
</tr>
</table>
and in your action
ViewVMModel vm = new ViewVMModel();
vm.VehcileMakeList = //get list of make
vm.VehicleModel = new VehicleModel();
return view(vm);
This question already has answers here:
Post an HTML Table to ADO.NET DataTable
(2 answers)
Closed 6 years ago.
I have class OrderSummaryViewModel
public class OrderSummaryViewModel
{
public int Id { get; set; }
public string PurchaseOrderNumber { get; set; }
public string DeliveryCondition { get; set; }
/// <summary>
/// Order items
/// </summary>
public List<OrderItem> Items { get; set; }
}
And second class OrderItem
/// <summary>
/// Order items
/// </summary>
public class OrderItem
{
public int Id { get; set; }
public string ItemNumber { get; set; }
public string DeliveredQuantity { get; set; }
public string fullyDelivered { get; set; }
}
And i bind model OrderSummaryViewModel into below .csHTML view to show the order with its related items.
#model OrderSummaryViewModel
<div class="baseForm">
<label>PO Number:</label></td>
#Html.DisplayFor(model => model.PurchaseOrderNumber)
<label>Delivery Condition:</label>
#Html.DisplayFor(model => model.DeliveryCondition)
#using (Ajax.BeginForm("RegisterGoodsReceipt",FormMethod.Post, new AjaxOptions { OnSuccess = "OnSuccessRegisterGoodsReceipt", OnFailure = "OnFailureRegisterGoodsReceipt" }, null))
{
var items= Model.Items;
<table class="dataGrid">
#for (var i = 0; i < items.Count; i++)
{
var item = items[i];
<tr>
<td>#Html.DisplayFor(modelItem => item.Id)</td>
<td>#Html.DisplayFor(modelItem => item.ItemNumber)</td>
<td>
<input class="fullyDelivered" id="#(item.Id)" name="fullyDelivered" type="checkbox" />
<input type="text" id="deliveredQuantity#(item.Id)" name="DeliveredQuantity" value="#item.DeliveredQuantity"/>
</td>
</tr>
}
</table>
<button type="submit" class="button">Submit</button>
}
</div>
I want to submit the list of items to below action as below
public ActionResult RegisterGoodsReceipt(OrderSummaryViewModel order)
{
//to do
}
But it always go with null, i tried also to send it as list of items and it gives null also.
public ActionResult RegisterGoodsReceipt(List<OrderItem> items)
{
//to do
}
so any help regarding this issue?
By removing HTML code and writing it using Razor problem solved and it now sends the model with the right data
I create a website for my wife. She's a teacher and she would like to have a possibility to create exercises for their students. The case is that she would like to create for instance the following exercise:
Exercise 1: Fill the sentence using a correct word:
My wife is 30 ............. old
I live in this city for 30 .........
I have the following model:
public class Exercise
{
[Key]
public Guid Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public ExerciseType Type { get; set; }
public DifficulityLevel DifficulityLevel { get; set; }
public List<ExerciseItem> Items { get; set; }
public DateTime TimeOfCreation { get; set; }
public DateTime TimeOfModification { get; set; }
}
public class ExerciseItem
{
[Key]
public Guid Id { get; set; }
public string Content { get; set; }
public List<ExerciseItemOption> Options { get; set; }
public ExerciseItemOption CorrectSelection { get; set; }
}
I creates a View for my Exercise. I can fill in the basic properties like Name, Description, Difficulity Level and Type. Then I would like to create a button "Add exercise item". When clicked, a partial view (or something else) should be added dynamically where new ExerciseItem can be provided.
I've tried to following:
I've added a button
#Ajax.ActionLink("Add exercise item",
"AddExerciseItem",
"Exercise", new AjaxOptions() { HttpMethod="GET", InsertionMode = InsertionMode.InsertBefore, UpdateTargetId="ExerciseItems"})
and the appropriate div:
<div id="ExerciseItems"></div>
My action method looks as follows:
public ActionResult AddExerciseItem()
{
return PartialView("ExerciseItem", new ExerciseItem());
}
and the partial view:
#model ElangWeb.Models.ExerciseItem
<fieldset>
<legend>ExerciseItem</legend>
#Html.HiddenFor(model => model.Id)
<div class="editor-label">
#Html.DisplayNameFor(model => model.Content)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Content, new { style = "width:200px" })
</div>
</fieldset>
It works fine. However when I click button for creating a whole exercise, I do not have ExerciseItem collection in my model:
public ActionResult Create(Exercise exercise)
{
using (PersistanceManager pm = new PersistanceManager())
{
exercise.Id = Guid.NewGuid();
exercise.TimeOfCreation = DateTime.Now;
exercise.TimeOfModification = DateTime.Now;
pm.ExcerciseRepository.Add(exercise);
}
return RedirectToAction("Index");
}
How should I change the code in order to bind my list of added ExerciseItem objects to my model Exercise?
Check out this article about model binding. You basically need to create special names for the exercise items so that they get bound correctly.
e.g. partial:
#model ElangWeb.Models.ExerciseItem
<fieldset>
<legend>ExerciseItem</legend>
<label>content</label>
<input type="hidden" name="ExcersiseItem.Index" value="SomeUniqueValueForThisItem" />
<input type="text" name="ExcersiseItem[SomeUniqueValueForThisItem].Name" value="#Model.Content" />
</fieldset>
You can also look at my answer to this question MVC3 Non-Sequential Indices and DefaultModelBinder. Thanks Yarx for finding it, I was actually trying to find it :)
I Have a Viewmodel based on Nominees . And i can have Multiple Nominees for the viewmodel.
I want to populate the Ilist From the view . Here are my viewmodels
public class DebitViewModel:IValidatableObject
{
public string AgentName { get; set; }
public Debit Debit { get; set; }
public Policy Policy { get; set; }
public PolicyType PolicyType { get; set; }
public Customer Customer { get; set; }
public IList<PolicyType> PolicyTypes { get; set; }
public List<Nominee> Nominees { get; set; }
public Dictionary<int,string> OccupationTypes { get; set; }
}
I want to populate all Nominess automatically when i press submit . so how should i create by view and make it automatically populate List automatically ? instead of serparate objects ?
You could use editor templates:
#model DebitViewModel
#using (Html.BeginForm())
{
... some input fields for the other properties that we are not interested in
#Html.EditorFor(x => x.Nominees)
<button type="submit">OK</button>
}
and then you define a custom editor template for the Nominee model (~/Views/Shared/EditorTemplates/Nominee.cshtml) which will automatically be rendered for each element of the Nominees collection:
#model Nominee
<div>
#Html.EditorFor(x => x.FirstName)
#Html.EditorFor(x => x.LastName)
...
</div>
say for example the Nominee looks like
public class Nominee{
public int Id{get;set;}
public string Name{get;set;}
public int Age {get;set;}
}
the view would look like
#for (int i = 0; i < Model.Nominees.Count(); i++)
{
<tr>
<td>#Html.TextBoxFor(m => m.Nominees[i].Name)</td>
<td>#Html.TextBoxFor(m => m.Nominees[i].Age)</td>
</tr>
}
read more about model binding to a list