Cannot get value of HtmlAttributes item in kendo MVC treeview - asp.net-mvc

I am using the Kendo MVC wrapper extensions to create a TreeView from my models. I would like to pass some data from the model with HtmlAttributes to the view.
Here is my Action :
public ActionResult Index()
{
var nodeList = new List<TreeViewItemModel>();
nodeList.Add(new TreeViewItemModel
{
Id = "1",
Text = "Item 1",
HasChildren = true,
HtmlAttributes = new Dictionary<string, string>
{
{"class","XXXX"}
},
Items = new List<TreeViewItemModel>
{
new TreeViewItemModel{Id="1.1", Text = "sub Item 1.1",HasChildren = false},
new TreeViewItemModel{Id="1.2", Text = "sub Item 1.2",HasChildren = false}
});
nodeList.Add(new TreeViewItemModel { Id = "2", Text = "Item 2", HasChildren = false });
return View(nodeList);
}
Here is my view :
#using Kendo.Mvc.UI
#model IEnumerable<Kendo.Mvc.UI.TreeViewItemModel>
#(Html.Kendo().TreeView()
.Name("treeView")
.BindTo(Model)
.DragAndDrop(true)
)
Here is the element from Chrome
<li class="k-item k-first" data-id="1" data-uid="6263f4c5-85f3-446c-a843-7d3786fb0f68" role="treeitem" id="treeView_tv_active">
As you can see there isn't any class:XXX in my li Tag So how can I give The XXX class to li Tag?

I can't figure out how to do this automatically, so here's a workaround.
C# passes back a List<Kendo.Mvc.UI.TreeViewItemModel>() to the treeview->datasource->transport->read event:
var items = new List<Kendo.Mvc.UI.TreeViewItemModel>();
////////////////////////////////////////////////////////////////////////////////
// areas of expertise
var aoe = new Kendo.Mvc.UI.TreeViewItemModel()
{
Text = "Areas of Expertise",
Id = "resume-treeview-category-AreasOfExpertise",
HasChildren = false,
HtmlAttributes = new Dictionary<string, string>(){{ "class", "resume-treeview-category"}, {"cat-id", "AreasOfExpertise" }},
};
items.Add(aoe);
return Json(items, JsonRequestBehavior.AllowGet);
I then hook the dataBound event to add the above attributes into the treeview item.
jQuery(document).ready(function ($) {
$("#document-treeview").kendoTreeView({
dataTextField: "Text",
dataSource: {
transport: {
read: {
type: 'POST',
url: "#Url.Action("GetAllTreeData", "Document2")",
contentType: 'application/json; charset=utf-8',
dataType: 'json'
},
parameterMap: function (data, type) {
if (type == "read") {
return JSON.stringify({
id: ResumeId
});
}
}
},
schema: {
model: {
id: "Id",
hasChildren: "HasChildren",
children: "Items"
}
}
},
dataBound: function(e) {
// Apparently reading an item after treeview creation doesn't apply the html attributes. Do that here.
var len = this.dataSource.data().length;
for (var i = 0; i < len; i++)
{
var dataItem = this.dataSource.data()[i];
var uid = dataItem.uid;
var li = $('#document-treeview li[data-uid="' + uid + '"]');
li.addClass(dataItem['HtmlAttributes']['class']);
li.attr('cat-id', dataItem['HtmlAttributes']['cat-id']);
}
}
});
}
Note the HtmlAttributes added from C# are explicitly handled in JavaScript =/

Related

Populate second Droplist depending on values of first Droplist

How can I change the selection of a second drop down list depending on the first selected dropdown value? For example in the code below if the listDepartments is "Sales" I only want the choice for listCatagory droplist to be Customers, and when selecting HR I only want the choice to be "Resumes" Is this possible with the code below or do I need a new approach, and if so is there a good example somewhere?
Thanks,
EB
List<SelectListItem> listDepartments = new List<SelectListItem>();
listDepartments.Add(new SelectListItem
{
Text = "Sales",
Value = "Sales",
});
listDepartments.Add(new SelectListItem
{
Text = "HR",
Value = "HR"
});
List<SelectListItem> listCatagory = new List<SelectListItem>();
listCatagory.Add(new SelectListItem
{
Text = "Customers",
Value = "Customers",
});
listCatagory.Add(new SelectListItem
{
Text = "Resumes",
Value = "Resumes",
});
When selecting the department is does nothing.
OK I added this to my controller:
public JsonResult GetCategory(int id)
{
var department = db.Documents.Where(t => t.ID == id).FirstOrDefault();
return Json(new SelectList(db.Catagories.Where(t => (t.Department == department.Department)), "Category", "Text"));
}
But I am not sure where it get the data for data: { id: $("#droplist_Departments_ID").val() }, from??
Do I need to change way the droplist is for the departments?
listDepartments.Add(new SelectListItem
{
Text = "Customer Service",
Value = "CustomerService",
You'll have to use Javascript in order to make an Ajax request passing the previous droplist selected item to a method in the controller which will return a SelectList, something like this:
$.ajax({
type: 'POST',
url: 'GetCategory',
dataType: 'json',
data: { id: $("#droplist_Departments_ID").val() },
success: function (mems) {
// states contains the JSON formatted list
// of states passed from the controller
$.each(mems, function (i, member) {
$("#droplist_Category_ID").append('<option value="' + member.Value + '">' + member.Text + '</option>');
});
},
error: function (ex) {
console.log('Failed to retrieve states. Exception: ' + ex);
}
});
In the controller something like (adapt to your db schema, obviously):
public JsonResult GetCategory(int id)
{
var department = db.Departments.Where(t => t.Id == id).FirstOrDefault();
return Json(new SelectList(db.Categories.Where(t => (t.DepartmentId == department.Id)), "CategoryId", "Text"));
}

KendoUpload FileUpload httppostedfile not working on submit

I am using #(Html.Kendo().Upload() in my app. I have to take the top 5 records from csv and bind it to kendo grid in javascript. I'm reading the file info from httppostedfilebase and returning the top 5 records as JSON result in save action method. On Upload success in javascript i'm binding the grid.
Now on submit, i have to read the file again. i'm trying to read the file information from httppostedfilebase but it is null because the save action method returns JSON. If i change the save action method to view, i'm ablet o read the httpostedfilebase on submit.
Is there a workaround?
Thanks!
Code Sample:
view
----
#(Html.Kendo().Upload()
.Name("uploadTemplate")
.Messages(m => m.Select(""))
.ShowFileList(true)
.Async(a => a
.Save("UploadData", "Lead")
.AutoUpload(true)
)
.Multiple(false)
.Events(events => events
.Select(UploadFileControl.onSelect")
.Success("UploadFileControl.onSuccess")
.Upload("UploadFileControl.onUpload")
)
)
form
----
#using (Html.BeginForm("", "", FormMethod.Post, new { id = "LoadForm", enctype = "multipart/form-data" }))
js
--
function SubmitForm(val) {
var url = '#Url.Action("fileSubmit", Test")';
console.log(url);
$.ajax({
url: url,
type: 'POST',
data: $('form#LoadForm').serialize(),
async: false,
success: function (data) {
alert("success");
},
error: function (data, xhr, error) {
alert("error");
}
});
}
onSuccess(e)
{ var grid = $("#grid").data("kendoGrid");
var origData = e.response;
grid.dataSource.data(origData);
}
document ready
--------------
var grid = $("#grid").kendoGrid({
groupable: false,
scrollable: true,
columnMenu: true
}).data("kendoGrid");
code behind
-----------
public JsonResult UploadData(IEnumerable<HttpPostedFileBase> uploadTemplate, FileModel fileModel)
{
Stream inputFileStream = new MemoryStream();
string[] result = new string[] { };
if (uploadOnly)
{
if (uploadTemplate != null)
{
try
{
foreach (var file in uploadTemplate)
{
inputFileStream = file.InputStream;
}
// GET TOP N ROWS AND ASSIGN TO parentRow
return Json(parentRow, JsonRequestBehavior.AllowGet);
}
return null;
}
public ActionResult fileSubmit(IEnumerable<HttpPostedFileBase> uploadTemplate, FileModel fileModel)
{
//retrieve uploadTemplate here (no values in uploadTemplate.)
}

how to set selected values to a multi select dropdown list on form load in .net mvc

I am using a multi select dropdown for a particular entry, which is retrieved from a table. If I am trying to edit this entry the selected dropdown is not showing.
This is my script.
<script type="text/javascript">
$(document).ready(function () {
//$('#Supplier').click(function () {
var sku = $("#SKU").val();
alert(sku);
//var pay = null;
//alert(suppid);
$.ajax({
url: '/SKUMasterSetup/supplierlist',
type: 'POST',
dataType: 'json',
data: { id: sku },
success: function (Supplierdata) {
alert("hi");
alert(Supplierdata);
var x = Supplierdata.length();
alert(x);
//<option value="{$T.data.Value}">{$T.data.Text}</option>
//for (var i = 0; i < Supplierdata.length; i++) {
// $("#supplier").append("Selected", Supplierdata[i], "selected").attr('selected', true);
for (var i in Supplierdata) {
var optionVal = Supplierdata[i];
$("#supplier").find("option[value=" + optionVal + "]").prop("selected", "selected");
}
// $('.class1').append("<option>" + "Please select" + "</option>");
},
//error : function (Supplier) { alert("Error !"); };
});
});
</script>
And my controller code is:
[HttpPost]
public JsonResult supplierlist(int id)
{
var Supplierdata = (from item in db.SupplierSKUMaps
where item.SKU == id
select item.SupplierMaster.SupplierName).ToList();
return Json(Supplierdata, JsonRequestBehavior.AllowGet);
}
And my dropdownlist is:
#Html.DropDownList("Supplier", ViewBag.Supplier as MultiSelectList, new { #class = "chosen", #id="supplier", #multiple = "multiple" })
you could always use #Value = #Html.Action(getMyFields) and within your controller, place an action method that returns Content result(MyData.ToList()).
More information on creating dropdowns can be found here: http://odetocode.com/blogs/scott/archive/2013/03/11/dropdownlistfor-with-asp-net-mvc.aspx

cascading dropdownlist with partial view issue

I have a problem with cascading dropdownlists where the second ddl should appear in a partial view and I can't handle it by myself. Please help me to figure out why I have the following bag?
So, I have a view with the first ddl where the user can choose a brand:
#Html.DropDownList("brands", new SelectList(
#ViewBag.Brands, "Id", "BrandName"),
"--select a Brand--",
new
{
id = "ddlBrands",
data_url = Url.Action("ChooseModel", "Home")
})
<div id="divModel"></div>
The ChooseModel method returns the following partial view :
<div id="chooseModel">
<div class="lead">Model</div>
#Html.DropDownList("models", new SelectList(Enumerable.Empty<SelectListItem>
(), "Id", "ModelName"),
"--select a Model--",
new { id = "ddlModels" })
</div>
When a user selects an item in ddlBrands another dropdownlist for models should appear. So, the script looks like this:
$(function () {
$("#ddlBrands").change(function () {
var url = $(this).data('url');
var value = $(this).val();
$('#divModel').load(url, { id: value });
var brandId = $(this).val();
$('#divModel').html("");
$.getJSON("../Home/LoadModels", { brandId: brandId },
function (modelData) {
var select = $("#ddlModels");
select.empty();
select.append($('<option/>', {
value: 0,
text: "-- select a Model --"
}));
$.each(modelData, function (index, itemData) {
select.append($('<option/>', {
value: itemData.Value,
text: itemData.Text
}));
});
});
});
});
And, finally, LooksModels method loading the models for the particular brand:
public JsonResult LoadModels(string brandId)
{
if (string.IsNullOrEmpty(brandId))
return Json(HttpNotFound());
var modelList = unitOfWork.ModelRepository
.GetModelListByBrand(Convert.ToInt32(brandId)).ToList();
var modelData = modelList.Select(m => new SelectListItem()
{
Text = m.ModelName,
Value = m.Id.ToString()
});
return Json(modelData, JsonRequestBehavior.AllowGet);
}
So, when I launch the application and choose a brand in the first ddl, the child models showing fine in second one. Then I choose another brand, and again the right models appeared. But when I choose the brand that I chose first time, I can't choose any models - ddlModels shows me only --select a Model--.
Can you please tell me what error in script (I suppose) I have?
Try this Script :
<script type="text/javascript">
$(document).ready(function () {
$("#ddlBrands").change(function () {
firstDDLValue = $("#ddlBrands").val();
$.post('#Url.Action("LoadModels", "Home")', { fstValue: firstDDLValue }, function (result) {
var select = $("#ddlModels");
select.empty();
select.append($('<option/>', { value: '', text: '--Select--' }));
$.each(result, function (index, Data) {
select.append($('<option/>', {
value: Data.Value,
text: Data.Text
}));
});
});
});
});
</script>
Use This at Controller:
public JsonResult LoadModels(string fstValue)
{
YourClassname obj= new YourClassname ();
int Id = 0;
if (fstValue != "")
Id = Convert.ToInt32(fstValue);
var result = obj.GetModelListByBrand(Convert.ToInt32(Id ));
IList<SelectListItem> Data = new List<SelectListItem>();
for (int i = 0; i < result.Count; i++)
{
Data.Add(new SelectListItem()
{
Text = result[i].Text,
Value = result[i].Value,
});
}
return Json(Data, JsonRequestBehavior.AllowGet);
}

Send list/array as parameter with jQuery getJson

I have the following where I'm trying to send list/array to MVC controller method:
var id = [];
var inStock = [];
$table.find('tbody>tr').each(function() {
id.push($(this).find('.id').text());
inStock.push($(this).find('.stocked').attr('checked'));
});
var params = {};
params.ids = id;
params.stocked = inStock;
$.getJSON('MyApp/UpdateStockList', params, function() {
alert('finished');
});
in my contoller:
public JsonResult UpdateStockList(int[] ids, bool[] stocked) { }
both paramaters are null.
Note that if I change the params to single items
params.ids = 1;
params.stocked = true;
public JsonResult UpdateStockList(int ids, bool stocked) { }
then it works ok, so I don't think it's a routing issue.
Try setting the traditional flag:
$.ajax({
url: '/home/UpdateStockList',
data: { ids: [1, 2, 3], stocked: [true, false] },
traditional: true,
success: function(result) {
alert(result.status);
}
});
works fine with:
public ActionResult UpdateStockList(int[] ids, bool[] stocked)
{
return Json(new { status = "OK" }, JsonRequestBehavior.AllowGet);
}
Besides calling .ajax() instead of .getJSON() as Darin suggests or setting the global jQuery.ajaxSettings.traditional to true as jrduncans suggests, you can also pass the result of calling the jQuery .param() function on your params object:
var id = [];
var inStock = [];
$table.find('tbody>tr').each(function() {
id.push($(this).find('.id').text());
inStock.push($(this).find('.stocked').attr('checked'));
});
var params = {};
params.ids = id;
params.stocked = inStock;
$.getJSON('MyApp/UpdateStockList', $.param(params, true), function() {
alert('finished');
});
Unfortunately, while it seems that jquery provides a "traditional" flag to toggle this behavior on jQuery.ajax, it does not on jQuery.getJSON. One way to get around this would to be set the flag globally:
jQuery.ajaxSettings.traditional = true;
See the documentation for jQuery.param: http://api.jquery.com/jQuery.param/
Also see the release notes for this change: http://jquery14.com/day-01/jquery-14 (search for 'traditional')
In the view, generate multiple named fields (not id, as id should be unique per field), noting the use of Name not name:
#foreach (var item in Model.SomeDictionary)
{
#Html.TextBoxFor(modelItem => item.Value.SomeString, new { Name = "someString[]" })
}
Then retrieve the input field values using jQuery, so:
var myArrayValues = $('input[name="someString[]"]').map(function () { return $(this).val(); }).get();
You can use this directly in jQuery / AJAX as follows:
$.ajax({
type: "POST",
url: "/MyController/MyAction",
dataType: 'json',
data: {
someStrings: $('input[name="someString[]"]').map(function () { return $(this).val(); }).get(),
someDates: $('input[name="someDate[]"]').map(function () { return $(this).val(); }).get(),
Then in the controller action in MVC:
[HttpPost]
public JsonResult MyAction(string[] someStrings, DateTime[] someDates...

Resources