Hello I am using Kendo for ASP.NET MVC.
I have list of string containing data
[0]="str1"
[1]="str2"... and so on
Now I want to bind this list of string into kendo dropdownlist.
I have bind dropdownlist by list of class with name and id but with only one data in list of string, I don't know how to bind that!
I have done that like below:
#(
Html.Kendo().DropDownList()
.Name("ddlstrings")
.DataTextField("stringname")
.DataValueField("stringname")
//.Events(x => x.Select("sourceclick"))
.SelectedIndex(0)
.DataSource(source =>
{
source.Read(read =>
{
read.Action("getData", "String");
});
})
)
But I got undefined.
I am returning the data like this:
public JsonResult getData()
{
try
{
List<string> stringlist = object.getstrlist();
return Json(stringlist, JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
return Json("", JsonRequestBehavior.AllowGet);
}
}
Does anyone have any idea how can I do this!
Any help would be appreciate.
Don't know is it good or not but got the solution with some manual work:
var selectList = new List<SelectListItem>();
foreach (var element in stringlist)
{
selectList.Add(new SelectListItem
{
Value = element.ToString(),
Text = element.ToString()
});
}
return Json(selectList, JsonRequestBehavior.AllowGet);
and at view side:
#(
Html.Kendo().DropDownList()
.Name("ddlstrings")
.DataTextField("Text")
.DataValueField("Value")
//.Events(x => x.Select("sourceclick"))
.SelectedIndex(0)
.DataSource(source =>
{
source.Read(read =>
{
read.Action("getData", "String");
});
})
)
The answer you have provided is right actually. The Action must return List<SelectListItem> as the output. See this Example and in the code see the BindTo property.
You can just update your code to below.
public JsonResult getData()
{
try
{
var stringlist = object.getstrlist().select( x=> new SelectListItem
{
Value = x,
Text = x
}).ToList();
return Json(stringlist, JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
return Json("", JsonRequestBehavior.AllowGet);
}
}
I have just modified your code to not have a for loop.
Try ValuePrimitive:
Html.Kendo().DropDownList()
.Name("ddlstrings")
.ValuePrimitive(true)
.SelectedIndex(0)
.DataSource(source =>
{
source.Read(read =>
{
read.Action("getData", "String");
});
})
What does your getData() return? You need to return an enumerable of object that have a property called stringname or what ever property name you specify in the DataText/DataValue fileds.
Something like this:
return Json(youStringArray.Select(x=>new{stringname = x}))
using TestSolution.Utility;
...
public JsonResult getData()
{
try
{
var stringlist = object.getstrlist();
return Json(stringlist.ToIdNameList(), JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
return Json("", JsonRequestBehavior.AllowGet);
}
}
=============================
using TestSolution.Models;
using System.Collections.Generic;
using System.Linq;
namespace TestSolution.Utility
{
/// <summary>
/// Kendo Drop Down List Extention
/// </summary>
public static class KendoDropDownListExtention
{
public static List<IdName> ToIdNameList(this string[] stringList)
{
return stringList.Select(sl => new IdName() { Name = sl, Value = sl }).ToList();
}
}
}
Related
I'm attempting to set the selected value of a combobox depending on what the controller has set.
My DropDownListFor:
#if (Model.FormType == "Detailed")
{
#Html.DropDownListFor(model => model.FormType,
new SelectList(Enum.GetValues(typeof(FormType))),
"Detailed")
}
else
{
#Html.DropDownListFor(model => model.FormType,
new SelectList(Enum.GetValues(typeof(FormType))),
"Summary")
}
My FormType enum:
public enum FormType
{
Summary,
Detailed
}
When I try this, it's duplicating "Summary" again and selecting it so I end up with duplicate entries:
What am I doing wrong? Thank you!
Your "Detailed" or "Summary" just a title of dropdown list. You can change it to "Select" for example. But if you need to show a selected item :
You need an util to create a SelectList
public static SelectList GetSelectList(string selectedText)
{
Array values = Enum.GetValues(typeof(FormType));
List<SelectListItem> items = new List<SelectListItem>();
foreach (var i in values)
{
var item=new SelectListItem
{
Text = Enum.GetName(typeof(FormType), i),
Value = i. ToString()
};
if(item.Text==selectedText) item.Selected=true;
items.Add(item);
}
return new SelectList(items);
}
Add SelectList to your view model:
public Model ()
{
..... your code
public SelectList SelectList {get; set;}
{
after this you can put this code in your action
model.SelectList=GetSelectList(model.FormType);
and finaly the view:
#Html.DropDownListFor(model => model.FormType, model.SelectList,"Select")
Before I start I'll just say that I've looked at other answers before posting and none specifically help me.
I need to create a Kendo UI grid in ASP.NET MVC that changes depending on what the users selects from a DropDownList. I will eventually be using data from a database, but currently I'm trying to learn with random hard-coded data.
I found a tutorial online that shows me how to do it with data from a sample database, but I can't set that up for reasons I cant explain. So I'm trying to adapt the code from that tutorial to work with my controllers and models. This might be set up completely wrong as I'm relatively new to ASP.NET MVC.
So here's the tutorial I'm trying to follow.
This is my controller:
public class LookupValueController : Controller
{
private List<LookupModel> tables = new
List<LookupModel>()
{ new LookupModel() { TableName = "Table1",
Description = "Table 1" },
new LookupModel() { TableName = "Table2",
Description = "Table 2" } };
private List<LookupValueModel> values = new List<LookupValueModel>()
{ new LookupValueModel() { TableName = "Table1", Description = "Value 1", LookupCode = "1" },
new LookupValueModel() { TableName = "Table2", Description = "Value 2", LookupCode = "2"} };
// GET: LookupValue
public ActionResult Index()
{
return View();
}
public ActionResult GetAllTableA()
{
try
{
var table = tables;
return Json(table, JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
return Json(ex.Message);
}
}
public ActionResult GetAllTableB()
{
try
{
var value = values;
return Json(value, JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
return Json(ex.Message);
}
}
}
Then my 2 models:
public class LookupValueModel
{
public string TableName { get; set; }
public string LookupCode { get; set; }
public string Description { get; set; }
}
public class LookupModel
{
public string TableName { get; set; }
public string Description { get; set; }
}
I've tried just changing the values in the view in the tutorial but it doesn't work, as I believe it isn't as simple as just changing some text.
I'm pretty stuck for how to do this and don't know where to go from here. I know this is a very long winded post with lots of code, but I would really appreciate some help.
Where am I going wrong adapting the tutorial code? What do I have to change to get it to work with hard-coded data?
That's not that hard. What you need to do is to change the DataSource's url for each Action you want. So, depending on what options user selects in the DDL, you change the DataSource. Check this demo.
What you need to change in from the above demo is that your grid's DataSource will call an url instead of a hard-coded json, right? In that url, you change the desired action:
let changeTableData = function changeTableData(option) {
let dataSource = new kendo.data.DataSource({
transport: {
url: "MyApp/" + option
}
});
$("#grid").data("kendoGrid").setDataSource(dataSource);
};
It will read the new url and fetch the data into the grid and updated it.
UPDATE
The transport url ir the url path to your action, e.g.
let url;
if (option == "A") {
url = "#Url.Action("TableA")";
}
else if (option == "B") {
url = "#Url.Action("TableB")";
}
let dataSource = new kendo.data.DataSource({
transport: {
url: url
}
});
1) Remove the grid from this view and create a new partialview and just have the grid located in that.
Now this can be one of two ways. Either an onclick via the drop down list or an onchange. Your choice
function Getdropdown()
{
var id = $("#//dropdownID").val(); //Get the dropdown value
var json = '{dropdownId: ' + id + '}';
$.ajax({
url:'#Url.Action("ViewGrid", "//Controller")',
type:'POST',
data:json,
contentType:'Application/json',
success:function(result){
$("//The Id of of the div you want the partial to be displayed in in the cshtml").html(result);
}
});
}
2) Get the value of the dropdown and pass it to a controller method that calls this new partial view, sending it the ID in a model
public ActionResult ViewGrid(int dropdownId)
{
AModel model = new AModel
{
DropDownID = dropdownId
};
return PartialView("_theGridPartial", model);
}
3) Change your grid to look like this:
#(Html.Kendo().Grid<KendoMvcApp.Models.EmployeeA>()
.Name("EmpGrid")
.Selectable()
.Columns(columns =>
{
columns.Bound(c => c.FirstName);
columns.Bound(c => c.LastName);
})
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Action("GetAllEmployee", "GridDataSource", new {id = Model.DropDownID}))
)
)
4) This is the new Controller read
public ActionResult GetAllEmployee([DataSourceRequest]DataSourceRequest request, int id)
{
try
{
//Have a call that gets the table data based on the id you are passing into here. This id will be the table id you have got from your dropdown list
}
catch (Exception ex)
{
return Json(ex.Message);
}
}
This should allow you to change the table based on the dropdown.
I have list of objects in my coming from controller.
it looks like this
{ Driver = System.Data.Entity.Driver_Driver1, Statuss = NotConfirmed }
{ Driver = System.Data.Entity.Driver_Driver2, Statuss = NotConfirmed }
please note that Driver is a complex type object.
Controller:
var Drivers = _db.Drivers.Where(x => x.DriverCompanyID == id).Where(d => d.CanWorkIn.Where(f => f.CompanyToDriveFor.CompanyID == OwnCompany.CompanyID).Any())
.Select(x => new
{
Driver = x,
Statuss = x.CanWorkIn.FirstOrDefault().Status.ToString()
}).ToList();
ViewBag.ListOfDrivers = Drivers;
return PartialView("_DriverList");
My Model
public class DriverViewItem
{
public Driver Driver { get; set; }
public string Statuss { get; set; }
}
My View
#model List<MyApp.web.Models.DriverViewItem>
and this last bit does not work. model declaration.
First create a strongly typed class with the properties you require. I've called mine DriverViewItem.
Then in your controller change the select to select this DriverViewItem and parse the list as a model to the view.
var Drivers = _db.Drivers.Where(x => x.DriverCompanyID == id).Where(d => d.CanWorkIn.Where(f => f.CompanyToDriveFor.CompanyID == OwnCompany.CompanyID).Any())
.Select(x => new DriverViewItem()
{
Driver = x,
Statuss = x.CanWorkIn.FirstOrDefault().Status
}).ToList();
return PartialView("_DriverList", Drivers);
In the view you will need to tell the view to expect your model you can do this with:
#model List<DriverViewItem>
Then you can iterate through the items like so:
#foreach(DriverViewItem item in Model)
{
<div>
<p>#item.Driver.{what ever property}</p>
<p>#item.Statuss</p>
</div>
}
This is a much cleaner way than parsing data using the ViewBag.
It would be better to use the model instead to pass this kind of data. But to answer the question directly, in the controller, assign it as an array of items to the viewbag
ViewBag.Data = {
new { Driver = System.Data.Entity.Driver_Driver1, Status = NotConfirmed },
new { Driver = System.Data.Entity.Driver_Driver2, Status = NotConfirmed }
}
And in the markup:
#{
if (ViewBag.Data != null){
foreach (var item in ViewBag.Data) {
//show the item in the view
}
}
}
I am trying to create a form that will consist of a series of dropdown lists, all of which are loaded from a database. I will not know how many dropdown lists will be needed, or how many options each dropdown list will have at compile-time.
How can these fields be set-up to allow them to model-bind when posted?
There is a lot of other complexity in each of the below code elements, but I cannot get the model binding to work even when reduced down to a basic level.
The Models:
public class MyPageViewModel
{
public List<MyDropDownListModel> ListOfDropDownLists { get; set; }
}
public class MyDropDownListModel
{
public string Key { get; set; }
public string Value { get; set; }
public List<SelectListItem> Options { get; set; }
}
The Controller Get Action:
[AcceptVerbs(HttpVerbs.Get)]
[ActionName("MyAction")]
public ActionResult MyGetAction()
{
var values_1 = new List<string> {"Val1", "Val2", "Val3"};
var options_1 =
values_1
.ConvertAll(x => new SelectListItem{Text=x,Value=x});
var myDropDownListModel_1 =
new MyDropDownListModel { Key = "Key_1", Options = options_1 };
var values_2 = new List<string> {"Val4", "Val5", "Val6"};
var options_2 =
values_2
.ConvertAll(x => new SelectListItem{Text=x,Value=x})};
var myDropDownListModel_2 =
new MyDropDownListModel { Key = "Key_2", Options = options_2 };
var model =
new MyPageViewModel
{
ListOfDropDownLists =
new List<MyDropDownListModel>
{
myDropDownListModel_1,
myDropDownListModel_2,
}
};
return View(model);
}
The Controller Post Action:
[AcceptVerbs(HttpVerbs.Post)]
[ActionName("MyAction")]
public ActionResult MyPostAction(MyPageViewModel model)
{
//Do something with posted model...
//Except 'model.ListOfDropDownLists' is always null
return View(model);
}
The View:
#model MyPageViewModel
#using (Html.BeginForm("MyPostAction"))
{
foreach (var ddl in Model.ListOfDropDownLists)
{
#Html.DropDownListFor(x => ddl.Value, ddl.Options)
}
<button type="submit">Submit</button>
}
Edit: Corrected typos and copy-paste mistakes.
Solution:
The problem turned out to be the foreach-loop within the view. Changing it into a for-loop instead caused the post to populate as expected. The updated view is below:
#using (Html.BeginForm("MyPostAction"))
{
for (int i = 0; i < Model.ListOfDropDownLists.Count; i++)
{
#Html.HiddenFor(x => x.ListOfDropDownLists[i].Key)
#Html.DropDownListFor(m => m.ListOfDropDownLists[i].Value, Model.ListOfDropDownLists[i].Options);
}
<button type="submit">Submit</button>
}
Your view is only creating multiple select elements named dll.Value (and duplicate ID's) which has no relationship to your model. What you need is to create elements named ListOfDropDownLists[0].Value, ListOfDropDownLists[1].Value etc.
Change you loop in the view to this
for (int i = 0; i < Model.ListOfDropDownLists.Count; i++)
{
#Html.DropDownListFor(m => m.ListOfDropDownLists[i].Value, Model.ListOfDropDownLists[i].Options);
}
You posted code has multiple errors (e.g. your pass a model of type MyPageViewModel but the post action method expects type of MyModel). I assume these are just typo's.
I can give you my solution,It is working:
Method in base controller
//To bind Dropdown list
protected Dictionary<int, string> GenerateDictionaryForDropDown(DataTable dtSource, string keyColumnName, string valueColumnName)
{
return dtSource.AsEnumerable()
.ToDictionary<DataRow, int, string>(row => row.Field<int>(keyColumnName),
row => row.Field<string>(valueColumnName));
}
Code in controller:
DataTable dtList = new DataTable();
dtList = location.GetDistrict();
Dictionary<int, string> DistrictDictionary = GenerateDictionaryForDropDown(dtList, "Id", "DistrictName");
model.DistrictList = DistrictDictionary;
Binding Data in view:
#Html.DropDownListFor(model => model.DiscrictId, new SelectList(Model.DistrictList, "Key", "Value"), new { id = "ddlDist", #class = "form-control" })
Binding Other Dropdown from this(cascading):
Other Dropdown:
#Html.DropDownListFor(model => model.TalukaId, new SelectList(Model.TalukaList, "Key", "Value"), new { id = "ddlTaluka", #class = "form-control" })
JQuery Code:
$("#ddlDist").change(function () {
var TalukaList = "Select"
$('#ddlTaluka').html(TalukaList);
$.ajax({
type: "Post",
dataType: 'json',
url: 'GetTaluka',
data: { "DistId": $('#ddlDist').val() },
async: false,
success: function (data) {
$.each(data, function (index, optionData) {
TalukaList = TalukaList + "<option value='" + optionData.Key + "'>" + optionData.Value + "</option>";
});
},
error: function (xhr, status, error) {
//alert(error);
}
});
$('#ddlTaluka').html(TalukaList);
});
Controller Method Return JSON
public JsonResult GetTaluka(int DistId)
{
LocationDH location = new LocationDH();
DataTable dtTaluka = location.GetTaluka(DistId);
Dictionary<int, string> DictionaryTaluka = GenerateDictionaryForDropDown(dtTaluka, "ID", "TalukaName");
return Json(DictionaryTaluka.ToList(), JsonRequestBehavior.AllowGet);
}
I use this part of code to get informations from my database, using Entity Framework, and add all of it in a IEnumerable property for, at the end, a DropDownListFor display.
I need to use that kind a code many time so I would like to make it the most powerfull at the begenning.
public IEnumerable<SelectListItem> Functions { get
{
List<SelectListItem> result = new List<SelectListItem>();
using (followupconsultantEntities dataModel = new followupconsultantEntities())
{
var myEvents = from e in dataModel.functions
select e;
foreach (var function in myEvents)
{
SelectListItem myList = new SelectListItem
{
Value = function.ID_Function.ToString(CultureInfo.InvariantCulture),
Text = function.FU_Name
};
result.Add(myList);
}
}
return result;
} }
Thanks for help
The view:
<div class="editor-field">
<%: Html.DropDownListFor(m => m.SelectedFunction,Model.Functions) %>
</div>
For information, my controller:
public ActionResult Register()
{
ViewData["PasswordLength"] = MembershipService.MinPasswordLength;
return View(new RegisterModel());
}
Start using System.Web.Mvc.SelectList.
public IEnumerable<SelectListItem> Functions { get
{
using (followupconsultantEntities dataModel = new followupconsultantEntities())
{
return new SelectList(dataModel.functions.ToArray(), "ID_Function", "FU_Name");
}
}
Also consider AutoMapper.
Try this. In this code you will not get from database data that you not need.
public IEnumerable<SelectListItem> Functions { get
{
using (followupconsultantEntities dataModel = new followupconsultantEntities())
{
return new SelectList(dataModel.functions.Select(f=>
new
{
Value = function.ID_Function.ToString(CultureInfo.InvariantCulture),
Text = function.FU_Name
})
.ToArray(), "Value", "Text");
}
}