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.
Related
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.
I've been working on this for days and finally have a partially working solution, but it doesnt feel quite right. In fact, i'm not sure any of this is right.
My problem is three fold:
generating the filter value in the read function doesnt seem right. I feel like i should be able to bind the multiselects text value or something and use that in the function,
the filter stops processing if i keep typing characters beyond the minLength setting. If i type "cha" the ds fetches "Charles" and "Chad". But if i continue typing and enter "chad", the filter still shows "Charles".
names already selected in the "value" property continue to display in subsequent searches. So if i select "Charles", then i select "Tim", then i type "cha", "Charles" will show up on the list again. But because he's already selected he should not appear on the list.
I'm using the kendo-knockout js, here's what i have so far:
<select data-bind="kendoMultiSelect: { dataSource: ds, autoBind: false, change:'filterTypeOnChanged', search: relatesSearch, minLength: 3, filter:'contains', value: selectedPersons, dataTextField:'PersonName'}"></select>
And here's the datasource (ds) that i'm binding to. (it's in typescript, so hopefully that wont hang anybody up).
ds = new kendo.data.DataSource({
serverFiltering: true
, type: 'json'
, transport: {
read: (options) => {
var srch: string;
debugger;
if (options.data[0] != undefined)
srch = options.data[0].value;
else
srch = options.data.filter.filters[0].value;
jQuery.ajax({
url: "/Person/GetPersons",
cache: false,
dataType: "json",
async: true,
data: JSON.stringify({ textToBeSearched: srch }),
type: "POST",
contentType: 'application/json, charset=utf-8',
processData: false,
success: result => {
options.success(result.data);
},
error: function (e) {
debugger;
console.log(e);
}
});
}
}
});
html part
<input data-bind="kendoComboBox: { dataTextField: 'FirstName', dataValueField: 'PersonID', data: AllUsers,template: '<span>#= data.FirstName # #= data.LastName # </span>', value: SelectedUserID,
change: UserSelectionChanged}" />
event handler inside model
var self= this;...
self.UserSelectionChanged = function () {
$.ajax({
type: "POST",
url: defaultUri + '/Home/GetUserTasks',
data: JSON.stringify({ PersonID: self.SelectedUserID() }),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (o) {
self.SelectedUserTask(null);
self.SelectedUserTask(o);
//RRM: Added this line below so that whenever user dropdown is changed or refresh button is clicked in AssignedTo the first task of that particular user is Selected.
self.selectTask(o[0]);
}
});
};
here the event is being called but the data in self is not there. The event doesn't seems to be bind well with knockout.
how to properly bind the ko event in the kendo combobox event?
Instead of registring to the change event, I'd subscribe to SelectedUserID:
var self= this;
...
self.SelectedUserID.subscribe(function(selectedUserId) {
$.ajax({
type: "POST",
url: defaultUri + '/Home/GetUserTasks',
data: JSON.stringify({ PersonID: selectedUserId }),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (o) {
self.SelectedUserTask(null);
self.SelectedUserTask(o);
//RRM: Added this line below so that whenever user dropdown is changed or refresh button is clicked in AssignedTo the first task of that particular user is Selected.
self.selectTask(o[0]);
}
});
});
This way it doesn't matter when or how the SelectedUserID is being changed.
As sroes wrote subscribing to the observable is the best choice here.
In cases where you have to bind to the kendo event then you can do this:
data-bind="... change: UserSelectionChanged(), ...."
Notice the function call parenthesis at the end ^
Now you function has to be like this:
this.UserSelectionChanged = function () {
var self = this;
return function(e) {
$.ajax({
self.blah ...
});
}
}
Now you have created a closure and you can access your view model using self but you also have the original Telerik event args inside e like e.dataItem etc.
So now you are unstoppable, you can do everything!
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.
I'm trying to make my inline edit to be dynamic so it will just depend on some data- attributes from my markup so here's the code for now:
$(".inline-edit").editable(
function(value, settings) {
var editableField = $(this);
$.ajax({
type: 'PUT',
url: editableField.attr('data-href'),
dataType: 'html',
success: function(html) {
editableField.parents('.replaceable').replaceWith(html);
},
data: { 'regression_test_environment[name]' : value }
});
return(value);
},
{
event: 'click',
width: '80%',
height: '20',
submit : 'OK'
}
)
i want the name in regression_test_environment[name] to be editableField.attr('data-column-name') but it always fails in compiling because it keeps taking the key as a string. I tried making a variable after the editable field variable assignment and building the string as a different variable but it doesn't want to evaluate the key as a function.
Is there a way to do this? or am i stuck in creating a separate .editable call for each of my editable fields?
You may try like this:
var name = editableField.data('column-name');
var values = { };
values['regression_test_environment[' + name + ']'] = value;
$.ajax({
type: 'PUT',
url: editableField.data('href'),
dataType: 'html',
data: values,
success: function(html) {
editableField.parents('.replaceable').replaceWith(html);
}
});
Better, less confusing answer:
var data = {};
data[thisField] = $(this).text();
$.ajax({
data: data
});
Best is to pass dynamic values by serializing it :
var data = $('#formid').serialize(); // serialize all the data in the form
$.ajax({
url: 'test.php', // php script to retern json encoded string
data: data, // serialized data to send on server
...
});