Populating a kendo multiselect with ajax data - ajax

I am using a kendo multiselect widget for users to select different values pulled from the database via an ajax call. The ajax call takes one parameter, searchValue, which will narrow down the returned data. Here is my controller:
[HttpPost]
public JsonResult ProfitabilitySearch(string searchValue)
{
return Json(InventoryDataAccess.ProfitabilitySearch(searchValue));
}
1) How do you get the value from the text box to use as your searchValue? I commented the area in question below.
Here is my dataSource:
var searchDataSource = new kendo.data.DataSource({
transport: {
read: function () {
$.ajax({
type: 'POST',
url: Firm.ProfitabilitySearchURL,
contentType: 'application/json; charset=utf-8',
dataType: 'json',
//'SuperClient' is test data to see if it works, but what do i
//need to make searchValue = what I type?
data: JSON.stringify({ searchValue: 'SuperClient'}),
success: function (data) {
return data.RESULT;
}
});
}
},
group: { field: 'category' },
serverFiltering: true
});
And here is where I create the multiselect widget:
var TKSearch = $("#TKSearch").kendoMultiSelect({
dataSource: searchDataSource,
autoBind: false,
minLength: 3,
placeholder: 'Search Timekeepers...',
dataTextField: 'label',
dataTextValue: 'value',
delay: 200
}).data("kendoMultiSelect");
I'm not sure if this will help, but here is the structure of the json that is returned from the ajax call:
{"label":"SUNFLOWER REALTY CORP. (023932)","value":"023932","category":"RC"}
Solving the first question above may answer my second question so I will wait to ask that until after.

You can use functions for the request parameters.
var searchDataSource = new kendo.data.DataSource({
transport: {
read: function (options) {
$.ajax({
type: 'POST',
url: Firm.ProfitabilitySearchURL,
contentType: 'application/json; charset=utf-8',
data: {
searchValue: function () {
// better: use a model property instead of this
return $("#TKSearch").data('kendoMaskedTextBox').value();
}
},
success: function (data) {
options.success(data.RESULT);
}
});
}
},
group: { field: 'category' },
serverFiltering: true
});
Notes
This really should be a GET request. Use POST for requests that actually change data on the server and GET for requests that merely retrieve data from the server.
You do not have to JSON.stringify() yourself. jQuery does that transparently.
Specifying dataType is completely superfluous, jQuery will figure this out from the response headers.
Reading the input value via jQuery is not clean. Use the data-bound model property instead.
The callback invocation (options.success())
This sample lacks HTTP error handling, you must add that.

Related

Kendo Datasource Transport custom function not getting called

Im experiencing a rather annoying bug (?) in Kendo UI Datasource.
My Update method on my transport is not getting called when I pass a custom function, but it does work if I just give it the URL.
This works:
...
transport: {
update: { url: "/My/Action" }
}
...
This does not
...
transport: {
update: function(options) {
var params = JSON.stringify({
pageId: pageId,
pageItem: options.data
});
alert("Update");
$.ajax({
url: "/My/Action",
data:params,
success:function(result) {
options.success($.isArray(result) ? result : [result]);
}
});
}
}
...
The function is not getting invoked, but an ajax request is made to the current page URL, and the model data is being posted, which is rather odd. Sounds like a bug to me.
The only reason I have a need for this, is because Kendo can't figure out that my update action returns only a single element, and not an array - so, since I dont want to bend my API just to satisfy Kendo, I though I'd do it the other way around.
Have anyone experienced this, and can point me in the right direction?
I also tried using the schema.parse, but that didn't get invoked when the Update method was being called.
I use myDs.sync() to sync my datasource.
Works as expected with the demo from the documentation:
var dataSource = new kendo.data.DataSource({
transport: {
read: function(options) {
$.ajax( {
url: "http://demos.kendoui.com/service/products",
dataType: "jsonp",
success: function(result) {
options.success(result);
}
});
},
update: function(options) {
alert(1);
// make JSONP request to http://demos.kendoui.com/service/products/update
$.ajax( {
url: "http://demos.kendoui.com/service/products/update",
dataType: "jsonp", // "jsonp" is required for cross-domain requests; use "json" for same-domain requests
// send the updated data items as the "models" service parameter encoded in JSON
data: {
models: kendo.stringify(options.data.models)
},
success: function(result) {
// notify the data source that the request succeeded
options.success(result);
},
error: function(result) {
// notify the data source that the request failed
options.error(result);
}
});
}
},
batch: true,
schema: {
model: { id: "ProductID" }
}
});
dataSource.fetch(function() {
var product = dataSource.at(0);
product.set("UnitPrice", product.UnitPrice + 1);
dataSource.sync();
});
Here is a live demo: http://jsbin.com/omomes/1/edit

kendo grid custom delete not persisting to datasource

I simply want to use my own workflow for deleting a record from my grid. Is this not the proper way to do it via Javascript? The function below removes the row but refreshing the page shows the row was not actually deleted from the datasource and I do not see any requests sent in the network tab of Chrome. I should add that I am able to obtain a reference to the grid and the dataItem perfectly.
function delete(e) {
var $tr = $(e.currentTarget).closest("tr"),
grid = this,
dataItem = grid.dataItem($tr),
id = $tr.attr(kendo.attr("uid")),
model = grid.dataSource.getByUid(id);
e.preventDefault();
grid.dataSource.remove(model);
grid.dataSource.sync();
}
Edit - Here is how my datasource is defined:
$scope.contacts = new kendo.data.DataSource({
transport: {
read: {
url: apiUrl,
dataType: "json",
type: "GET"
},
update: {
url: apiUrl,
dataType: "json",
type: "POST"
},
destroy: {
url: apiUrl,
type: "DELETE"
},
create: {
url: apiUrl,
dataType: "json",
type: "POST"
}
},
pageSize: 10
});
I found something and I dont know if it works in your side.
I needed to add this line in my kendo.datasource
schema: {
model:{id:"id"}
}
and trigger like this
data_source_inspection.remove(selected.data);
data_source_inspection.sync();
this works for me.

Jquery ajax returning null values back to controller - MVC3

I'm using jQuery ajax to build a viewmodel list and then trying to send that viewmodel to another ActionResult in order to create PartialViews. The first part works well, and I'm able to create the viewmodel (List), but when I try to send the viewmodel back to the controller to build up the partial views, everything within the viewmodel is 0. It returns the correct number of items in the list, but it seems to lose the values.
Can anyone see if I'm missing anything here?
jQuery:
$.ajax({
async: false,
type: 'GET',
dataType: "json",
url: '#Url.Action("GetMapDetails")',
success: function (data) {
$.ajax({
async: false,
type: 'POST',
dataType: "json",
url: '#Url.Action("GetMapItems")',
data: {
list: data
},
success: function (list) {
//callback
});
}
});
}
});
and the controller:
public ActionResult GetMapDetails()
{
List<ViewModel> vm = new List<ViewModel>();
//create viewmodel here
return Json(vm.ToArray(), JsonRequestBehavior.AllowGet);
}
[HttpPost]
public ActionResult GetMapItems(List<ViewModel> list)
{
return PartialView("_MapItemsPartial", list);
}
I've tried also using contentType: 'application/json' and JSON.stringify(data) but that gave me an Invalid JSON primitive error.
Any help appreciated - thanks
You could send them as JSON request:
$.ajax({
async: false,
type: 'POST',
contentType: 'application/json',
url: '#Url.Action("GetMapItems")',
data: JSON.stringify({
list: data
}),
success: function (result) {
//callback
}
});
Also notice that I have removed the dataType: 'json' parameter because your GetMapItems POST controller action doesn't return any JSON. It returns a PartialView. So I guess you did something wrong and this is not what it was meant to be returned from this controller action because from what I can see in your success callback you are expecting to manipulate JSON.
Oh, and please remove this async:false => it defeats the whole purpose of AJAX as you are no longer doing any AJAX, you are now doing SJAX.

jquery autocomplete using mvc3 dropdownlist

I am using ASP.NET MVC3 with EF Code First. I have not worked previously with jQuery. I would like to add autocomplete capability to a dropdownlist that is bound to my model. The dropdownlist stores the ID, and displays the value.
So, how do I wire up the jQuery UI auto complete widget to display the value as the user is typing but store the ID?
I will need multiple auto complete dropdowns in one view too.
I saw this plugin: http://harvesthq.github.com/chosen/ but I am not sure I want to add more "stuff" to my project. Is there a way to do this with jQuery UI?
Update
I just posted a sample project showcasing the jQueryUI autocomplete on a textbox at GitHub
https://github.com/alfalfastrange/jQueryAutocompleteSample
I use it with regular MVC TextBox like
#Html.TextBoxFor(model => model.MainBranch, new {id = "SearchField", #class = "ui-widget TextField_220" })
Here's a clip of my Ajax call
It initially checks its internal cached for the item being searched for, if not found it fires off the Ajax request to my controller action to retrieve matching records
$("#SearchField").autocomplete({
source: function (request, response) {
var term = request.term;
if (term in entityCache) {
response(entityCache[term]);
return;
}
if (entitiesXhr != null) {
entitiesXhr.abort();
}
$.ajax({
url: actionUrl,
data: request,
type: "GET",
contentType: "application/json; charset=utf-8",
timeout: 10000,
dataType: "json",
success: function (data) {
entityCache[term] = term;
response($.map(data, function (item) {
return { label: item.SchoolName, value: item.EntityName, id: item.EntityID, code: item.EntityCode };
}));
}
});
},
minLength: 3,
select: function (event, result) {
var id = result.item.id;
var code = result.item.code;
getEntityXhr(id, code);
}
});
This isn't all the code but you should be able to see here how the cache is search, and then the Ajax call is made, and then what is done with the response. I have a select section so I can do something with the selected value
This is what I did FWIW.
$(document).ready(function () {
$('#CustomerByName').autocomplete(
{
source: function (request, response) {
$.ajax(
{
url: "/Cases/FindByName", type: "GET", dataType: "json",
data: { searchText: request.term, maxResults: 10 },
contentType: "application/json; charset=utf-8",
success: function (data) {
response($.map(data, function (item) {
return {
label: item.CustomerName,
value: item.CustomerName,
id: item.CustomerID
}
})
);
},
});
},
select: function (event, ui) {
$('#CustomerID').val(ui.item.id);
},
minLength: 1
});
});
Works great!
I have seen this issue many times. You can see some of my code that works this out at cascading dropdown loses select items after post
also this link maybe helpful - http://geekswithblogs.net/ranganh/archive/2011/06/14/cascading-dropdownlist-in-asp.net-mvc-3-using-jquery.aspx

jqGrid populate select control on row edit

I want to add about 150 element from a xml file to a select control that is inside a jqGrid cell. I was thinking of doing this in two ways:
1.Using the editoptions value:
{ name: 'language', width: 100, sortable: false, editable: true, edittype: 'select', editoptions: { value: languageElem()} }
using data received from the method:
function languageElem() {
$.ajax({
type: 'POST',
contentType: "application/json; charset=utf-8",
url: 'jqService.asmx/GetLanguages',
data: {},
dataType: "json",
success: function (data) {
alert("success");
}
});}
But I'm having trouble forwarding the data from the ajax part.
2.Simply accessing the select control inside the jqGrid cell and manually adding the options whenever the edit button is pressed.
The problem over here is that I have no idea how to access the control itself.
The code I used over here is:
function startEdit() {
if (selRow > -1) {
$.ajax({
type: 'POST',
contentType: "application/json; charset=utf-8",
url: 'jqService.asmx/GetLanguages',
data: {},
dataType: "json",
success: function (data) {
var cell = jQuery("#MainContent_list").getCell(selRow, "language");
cell.options.length = 0;
for (var i=0;i<data.d.length;i++)
{
}
}
});
jQuery("#MainContent_list").jqGrid('restoreRow', selRow);
jQuery("#MainContent_list").jqGrid('editRow', selRow);
}
My questions are:
1.Related to the first idea, what should I do to fix the method so that the control will receive it's needed values?
2.Related to the second idea, how could I access the control inside the row?
Thanks, Catalin
Instead of value property (editoptions: { value: languageElem()}) you should use dataUrl and buildSelect (see the documentation). Because it's difficult to return from ASMX HTML fragment <select><option>...</option></select> you can provide the list serialized as JSON and convert the server response to HTML fragment using buildSelect. In the answer and in this one you will find additional information. If you would search for dataUrl and buildSelect you will find more information and code example which you could use.

Resources