I try to bind a object in the Kendo Autocomplete widget.
the trouble is that the model turns in a string when i fill the options, and when i change the scope the input show me the text [object object] because the model isn't a string. is a object Example:
Cliente : {NombreMostrar:''}
How i can link properly the model in way when i change the scope model, show me the name in the input, and when a selected a item from widget update correctly the object model.
<input kendo-auto-complete k-ng-model="Credito.Cliente" k-options="ClientesBusqueda" style="width: 100%;" />
$scope.ClientesBusqueda = {
dataTextField: 'NombreMostrar',
dataSource: {
type: "get",
serverFiltering: true,
transport: {
read: {
url: "/Cliente/Buscar",
dataType: "json",
cache: false
},
parameterMap: function (data, action) {
var newParams = {
clienteNombre: data.filter.filters[0].value
};
return newParams;
}
},
schema: {
data: function (response) {
var clientes = response.clientes.map(function (cliente) {
cliente.NombreMostrar = (cliente.RazonSocial || [cliente.ApellidoPaterno, cliente.ApellidoMaterno, cliente.PrimerNombre, cliente.SegundoNombre].join(' ')).toUpperCase();
cliente.RFC = cliente.RFC.toUpperCase();
return cliente;
});
return clientes;
}
}
}
}
I answer to myself i found a solution in this link, him create a directive for bind model to the control.
https://codereview.stackexchange.com/questions/61638/custom-angular-directive-for-data-binding-on-teleriks-kendo-ui
Related
I've gotten xeditable and select2 to work with an api call as the source and everything works great EXCEPT the following.
After submitting the select2 dropdown, the value of the table is displayed as EMPTY and requires a page refresh in order to update to the correct value.
Does anyone know how to update the value to the selected select2 dropdown value?
my html:
<td class="eo_role"><a href="#" data-pk={{r.pk}} data-type="select2" data-url="/api/entry/{{r.pk}}/"
data-name="eo_role" data-title="Enter EO_role">{{r.eo_role}}</a></td>
here is my JS:
$('#example .eo_role a').editable( {
params: function(params) { //params already contain `name`, `value` and `pk`
var data = {};
data[params.name] = params.value;
return data;
},
source: 'http://localhost:8000/api/eo_role/select_two_data/',
tpl: '<select></select>',
ajaxOptions: {
type: 'put'
},
select2: {
cacheDatasource:true,
width: '150px',
id: function(pk) {
return pk.id;
},
ajax: {
url: 'http://localhost:8000/api/eo_role/select_two_data/',
dataType: "json",
type: 'GET',
processResults: function(item) {return item;}
}
},
formatSelection: function (item) {
return item.text;
},
formatResult: function (item) {
return item.text;
},
templateResult: function (item) {
return item.text;
},
templateSelection : function (item) {
return item.text;
},
});
Again - everything works (database updates, dropdownlist populates etc.) however the <td> gets updated with "EMPTY" after submitting the dropdown - requiring a page refresh to show the correct value.
I figured out a workaround. I'm SUPER PUMPED.
//outside of everything, EVERYTHING
//test object is a global holding object that is used to hold the selection dropdown lists
//in order to return the correct text.
var test = {};
$('#example .eo_role a').editable( {
params: function(params) { //params already contain `name`, `value` and `pk`
var data = {};
data[params.name] = params.value;
return data;
},
//MUST be there - it won't work otherwise.
tpl: '<select></select>',
ajaxOptions: {
type: 'put'
},
select2: {
width: '150px',
//tricking the code to think its in tags mode (it isn't)
tags:true,
//this is the actual function that triggers to send back the correct text.
formatSelection: function (item) {
//test is a global holding variable set during the ajax call of my results json.
//the item passed here is the ID of selected item. However you have to minus one due zero index array.
return test.results[parseInt(item)-1].text;
},
ajax: {
url: 'http://localhost:8000/api/eo_role/select_two_data/',
dataType: "json",
type: 'GET',
processResults: function(item) {
//Test is a global holding variable for reference later when formatting the selection.
//it gets modified everytime the dropdown is modified. aka super convenient.
test = item;
return item;}
}
},
});
I faced that same issue. I handle it that way:
In x-editable source code look for:
value2html: function(value, element) {
var text = '', data,
that = this;
if(this.options.select2.tags) { //in tags mode just assign value
data = value;
//data = $.fn.editableutils.itemsByValue(value, this.options.select2.tags, this.idFunc);
} else if(this.sourceData) {
data = $.fn.editableutils.itemsByValue(value, this.sourceData, this.idFunc);
} else {
//can not get list of possible values
//(e.g. autotext for select2 with ajax source)
}
As you can see, there is else statment, without any code (only 2 comments) that is the situation, with which we have a problem. My solution is to add missing code:
(...) else {
//can not get list of possible values
//(e.g. autotext for select2 with ajax source)
data = value;
}
That's fix problem without tags mode enabled. I do not detect any unwanted behaviors so far.
Example code:
jQuery('[data-edit-client]').editable({
type: 'select2',
mode: 'inline',
showbuttons: false,
tpl: '<select></select>',
ajaxOptions: {
type: 'POST'
},
select2: {
width: 200,
multiple: false,
placeholder: 'Wybierz klienta',
allowClear: false,
formatSelection: function (item) {
//test is a global holding variable set during the ajax call of my results json.
//the item passed here is the ID of selected item. However you have to minus one due zero index array.
return window.cacheData[parseInt(item)].text;
},
ajax: {
url: system.url + 'ajax/getProjectInfo/',
dataType: 'json',
delay: 250,
cache: false,
type: 'POST',
data: {
projectID: system.project_id,
action: 'getProjectClients',
customer: parseInt(jQuery("[data-edit-client]").attr("data-selected-company-id"))
},
processResults: function (response) {
window.cacheData = response.data.clients;
return {
results: response.data.clients
};
}
}
}
});
I'm loading multiple values into a Select2 element through Javascript, ajax and jquery. While the data is loading properly and can be accessed once loaded, I'm unable to set stored data in the Select2 element.
Edit: I'm using Select2 v3.5.
My code:
HTML:
<input class="jsData" style="width: 100%" id="select2Data"></input>
Javascript:
$(".jsData").select2({
ajax: {
minimumInputLength: 4,
contentType: 'application/json',
url: '<%=Url.Action("GetData","Controller")%>',
type: 'POST',
dataType: 'json',
data: function (term) {
return {
sSearchTerm: term
};
},
results: function (data) {
return {
results: $.map(JSON.parse(data), function (item) {
return {
text: item.term,
slug: item.slug,
id: item.Id
}
})
};
}
},
multiple: true
});
So, this creates a Select2 element where I can traverse to and from a database and load data depending on what I've typed. I can also access the data (entered by the user) using the following line:
$('.jsData').select2('val')
The above line returns an array, which I can store in the database. My current objective is to set the stored data back into the Select2 element. Any help in this matter would be most welcome.
Update: A relevant link for what I want to accomplish:
https://select2.github.io/examples.html#programmatic
I want the example of setting multiple elements in Select2. However, the difference would be in the fact that the example in the Select2 documentation brings data at the time of loading the page, while I will be making trips to fetch the data.
The Select2 v3.5.4 docs are a bit confusing around this. I think there's a typo in the docs that's misleading.
First, notice that when I retrieve the data from the remote source I'm returning it as an object in the format of {id: ##, name: NAME}.
The first step is to add the initSelection parameter and pass the function to retrieve the previously selected items.
The next step, where I believe there's a typo, is to define the formatSelection parameter (not the formatResult it states in the docs). This function defines how the previously selected result is displayed. In this case I'm merely showing the name property of the result.
The formatResult parameter defines how newly selected options are displayed. You'll notice formatResult and formatSelection are the same below. I could have reused a single function but felt this was better for demonstration.
$(document).ready(function() {
function formatResult(data) {
return data.name;
};
function formatSelection(data) {
return data.name;
}
$(".jsData").select2({
ajax: {
minimumInputLength: 4,
url: "https://jsonplaceholder.typicode.com/users",
type: "GET",
dataType: "json",
results: function(data) {
return {
results: $.map(data, function(user) {
return {
name: user.name,
id: user.id
};
})
};
}
},
initSelection: function(element, callback) {
var id = $(element).val();
if (id !== "") {
$.ajax("https://jsonplaceholder.typicode.com/users/" + id, {
dataType: "json"
}).done(function(data) {
callback(data);
});
}
},
formatResult: formatResult,
formatSelection: formatSelection,
multiple: true
});
});
Here's the full working example:
$(document).ready(function() {
function formatResult(data) {
return data.name;
};
function formatSelection(data) {
return data.name;
}
$(".jsData").select2({
ajax: {
minimumInputLength: 4,
url: "https://jsonplaceholder.typicode.com/users",
type: "GET",
dataType: "json",
results: function(data) {
return {
results: $.map(data, function(user) {
return {
name: user.name,
id: user.id
};
})
};
}
},
initSelection: function(element, callback) {
var id = $(element).val();
if (id !== "") {
$.ajax("https://jsonplaceholder.typicode.com/users/" + id, {
dataType: "json"
}).done(function(data) {
callback(data);
});
}
},
formatResult: formatResult,
formatSelection: formatSelection,
multiple: true
});
});
.jsData {
width: 200px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/3.5.4/select2.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/3.5.4/select2.css" rel="stylesheet"/>
<input class="jsData" style="width: 100%" id="select2Data" value="10"></input>
The aim is to import data from the Controller side to a Select2 element (with multiselect toggled on). I want the setup to look something like the tags box in Stack Overflow, wherein you can begin typing a tag, select it, and select another one later.
I have been using the Select2 documentation as a reference, however the request isn't being sent to the Controller.
Select2 Documentation
My Code:
$(".jsData").select2({
ajax: {
contentType: 'application/json',
url: '<%=Url.Action("GetDataMethod","RelevantController")%>',
type: 'POST',
dataType: 'json',
data: function (term) {
return {
sSearchTerm: term
};
},
results: function (data) {
var datajs = $.map(data, function (obj) {
obj.text = obj.someterm; // desired field,
obj.id = obj.someId;
return obj;
});
return {
results: JSON.parse("[" + datajs.split(",") + "]")
};
}
},
multiple: true
});
I'm relatively new to bringing data dynamically to Select 2, so any help would be most appreciated. Thanks!
UPDATE: Found the solution, posting it here for others.
HTML
<input class="jsData" style="width: 100%" id="select2Data" ></input>
Javascript
$(".jsData").select2({
ajax: {
minimumInputLength: 4,
contentType: 'application/json',
url: '<%=Url.Action("GetData","Controller")%>',
type: 'POST',
dataType: 'json',
data: function (term) {
return {
sSearchTerm: term
};
},
results: function (data) {
return {
results: $.map(JSON.parse(data), function (item) {
return {
text: item.term,
slug: item.slug,
id: item.Id
}
})
};
}
},
multiple: true
});
I have a Kendo Grid that loads data via ajax with a call to server-side ASP.NET read method:
public virtual JsonResult Read(DataSourceRequest request, string anotherParam)
In my client-side JS, I trigger a read when a button is clicked:
grid.dataSource.read( { anotherParam: 'foo' });
grid.refresh();
This works as expected, only I lose the additional param when I move through the pages of results in the grid, or use the refresh icon on the grid to reload the data.
How do I persist the additional parameter data in the grid?
I have tried setting
grid.dataSource.data
directly, but without much luck. I either get an error if I pass an object, or no effect if I pass the name of a JS function that returns data.
if you want to pass additional parameters to Read ajax datasource method (server side), you may use
.DataSource(dataSource => dataSource
...
.Read(read => read.Action("Read", controllerName, new { anotherParam= "foo"}))
...
)
if you want to pass additional parameters through client scripting you may use datasource.transport.parameterMap, something as below
parameterMap: function(data, type) {
if (type == "read") {
return { request:kendo.stringify(data), anotherParam:"foo" }
}
Use the datasource.transport.parameterMap
parameterMap: function(data, type) {
if (type == "read") {
return kendo.stringify(data, anotherParam);
}
I'm not sure where your other param is coming from, but this is generally how I send extra parameters to the server.
http://docs.telerik.com/kendo-ui/api/javascript/data/datasource#configuration-transport.parameterMap
if use datasource object :
var dataSource = new kendo.data.DataSource({
transport: {
read: {
url: '/Api/GetData',
contentType: "application/json; charset=utf-8", // optional
dataType: "json",
data: function () {
return {
additionalParam: value
};
}
},
//parameterMap: function (data, type) {
// and so use this property to send additional param
// return $.extend({ "additionalParam": value }, data);
//}
},
schema: {
type: "json",
data: function (data) {
return data.result;
},
},
pageSize: 5,
serverPaging: true,
serverSorting: true
});
and set options in grid:
$("#grid").kendoGrid({
autoBind: false,
dataSource: dataSource,
selectable: "multiple cell",
allowCopy: true,
columns: [
{ field: "productName" },
{ field: "category" }
]
});
and in click event this code :
dataSource.read();
and in api web method this action:
[HttpGet]
public HttpResponseMessage GetData([FromUri]KendoGridParams/* define class to get parameter from javascript*/ _param)
{
// use _param to filtering, paging and other actions
try
{
var result = Service.AllCustomers();
return Request.CreateResponse(HttpStatusCode.OK, new { result = result });
}
catch (Exception ex)
{
return Request.CreateResponse(HttpStatusCode.BadRequest, new { result = string.Empty });
}
}
good luck.
To persist the updated value of the additional parameter through pagination, you will need to create a global variable and save the value to it.
var anotherParamValue= "";//declare a global variable at the top. Can be assigned some default value as well instead of blank
Then, when you trigger the datasource read event, you should save the value to the global variable we created earlier.
anotherParamValue = 'foo';//save the new value to the global variable
grid.dataSource.read( { anotherParam: anotherParamValue });
grid.refresh();
Now, this is important. In your datasource object transport.read.data must be set to use a function as shown below:
var dataSource = new kendo.data.DataSource({
transport: {
read: {
url: '/Api/GetData',
contentType: "application/json; charset=utf-8", // optional
dataType: "json",
//Must be set to use a function, to pass dynamic values of the parameter
data: function () {
return {
additionalParam: anotherParamValue //get the value from the global variable
};
}
},
},
schema: {
type: "json",
data: function (data) {
return data.result;
},
},
pageSize: 5,
serverPaging: true,
serverSorting: true
});
Now on every page button click, you should get the updated value of the anotherParam which is currently set to foo
I wrote two functions,assume that one of them get us list of all notifications and one of them get new notification, i wrote a script which call first method and get list of all notifications in Json format, and write another script which call second method every 8 second, and get us new notifications in Json format too. i show these notifacations in a KendoUI Datasource. so i have two datasource for just one KendoUI Datasource component, i want to add two data source in one datasource, is there any way to do this?
EDIT: This is my code
<script id="template" type="text/x-kendo-template">
<tr>
<td>#= ID #</td>
<td>#= TITLE #</td>
<td>#= DESC #</td>
</tr>
</script>
My first script which get us list of all notification :
var datas = function () {
var objects = [];
$.ajax({
type: "POST",
url: "./WebForm1.aspx/GetNoti",
data: {},
async: false,
contentType: "application/json; charset=utf-8",
dataType: "json",
success:
function (response) {
for (var i = 0; i < response.d.length; i++) {
objects.push({ 'ID': response.d[i].ID, 'TITLE': response.d[i].TITLE, 'DESC': response.d[i].DESC });
}
},
});
return objects;
};
var dataSource = new kendo.data.DataSource({
data: datas(),
change: function () {
$("#movies tbody").html(kendo.render(template, this.view()));
}
});
dataSource.read();
and this is my seccond script which call method that give us new notifications every 8 sec:
$("#go").click(function () {
setInterval(
function () { test2();}, 8000);
});
var p = function () {
var objects = [];
$.ajax({
type: "POST",
url: "./WebForm1.aspx/GetUnCheckNotification",
data: {},
async: false,
contentType: "application/json; charset=utf-8",
dataType: "json",
success:
function (response) {
for (var i = 0; i < response.d.length; i++) {
objects.push({ 'ID': response.d[i].ID, 'TITLE': response.d[i].TITLE, 'DESC': response.d[i].DESC });
}
},
});
return objects;
};
function test2() {
var dataSource2 = new kendo.data.DataSource({
data: p(),
change: function () {
$("#movies tbody").html(kendo.render(template, this.view()));
}
});
dataSource2.read();
}
Now i want some thing like this :
dataSource = dataSource + dataSource2
dataSource.read();
Is there anyway?
JSON format cab be a nested structure. Define a view model and then use it.
public class Report
{
public int Id {set; get;}
public string Title {set; get;}
public string Desc {set; get;}
}
public class MyReportViewModel
{
public List<Report> NewNotifications {set;get;}
public List<Report> AllNotifications {set;get;}
}
Then serialize this new MyReportViewModel { ... } using Json.NET library (server side).
On the client side, you can use the returned JSON format as usual.
Never tried anything like this. But when I was looking for your answer, I found this link at Telerik Forums.
Two Data Sources, One Grid
This might help.! :)