KendoUI ComboBox displaying incorrect parsing of REST JSON - javascript

I have a restful service responding with {"SearchMode":["Customer","Address","Street","City"]}, everything looks fine. I'm trying to add each of these as an option in a Kendo ComboBox. However, it's parsing it out and showing each letter as an option:
{
"
S
e
a
r
c
h
you get the point. Here is what I'm doing in the javascript to get this. I'm learning Kendo controls so any help is appreciated.
$(#cboSearch").kendoComboBox({autobind:false, minLength:3, datasource:{type:json, serverFiltering: true, transport:{ read: { url: "http://myrestservicehere?f="}}} });
I know I'm missing something obvious and looking forward for some guidance, thanks.
Scott

You are missing in the DataSource definition saying where in the returned object is the array containing the options. This is done using schema.data. It should be:
$("#cboSearch").kendoComboBox({
autoBind : false,
minLength : 3,
dataSource: new kendo.data.DataSource({
serverFiltering: true,
transport : {
read: {
url: "http://myrestservicehere?f="
}
},
schema : {
data: "SearchMode"
}
})
});

The ComboBox doesn't support binding to array of strings. You could try changing your JSON to something like:
{
"SearchMode": [
{"text":"Customer"},
{"text":"Address"},
{"text":"Street"},
{"text":"City"}
]
}
Then configure the combobox like this:
$("#cboSearch").kendoComboBox({
autoBind : false,
minLength : 3,
dataTextField : "text",
dataValueField : "text",
dataSource: new kendo.data.DataSource({
serverFiltering: true,
transport : {
read: {
url: "http://myrestservicehere?f="
}
},
schema : {
data: "SearchMode"
}
})
});

Related

Kendo UI Grid Javascript datasource call to controller action

I'm having trouble binding my JavaScript kendo ui grid to model data from an action method. All the examples i see are mostly MVC wrappers and the JavaScript examples are all different and none seem to work for me.
Here is where i'm at below.
I did a generic test with static data that works.
var dataSource_Test = new kendo.data.DataSource({
data: [{ LeagueDetailGroupId: "15", GroupName: "Best Team 5"}]
});
Here is the datasource object im trying to create with the controller action:
var dataSource = new kendo.data.DataSource({
transport: {
read: {
url: "#Url.Action("LeagueDetailGroup_Read", "Configuration")?_leagueTypeId=" + leagueTypeId,
// i have tried all kinds of variants here, and not sure what to put
// my action method is returning json using kendo's DataSourceResult method
//contentType: "application/json",
type: "POST"
//dataType: "odata"
},
schema: {
data: "Data", // seen this in examples, dunno what it does
total: "Total", // seen this in examples, dunno what it does
model: {
id: "LeagueDetailGroupId",
fields: {
LeagueDetailGroupId: { editable: false, nullable: true },
GroupName: { validation: { required: true } }
}
}
},
// i seen this is an example from telerik but dont understand the use case for it
parameterMap: function (data, operation) {
// this prints no data before i even start so its a moot point configuring it from products to my stuff at this moment
// but not sure what todo here of if i need this anyways
console.log(data);
if (operation != "read") {
// post the products so the ASP.NET DefaultModelBinder will understand them
var result = {};
for (var i = 0; i < data.models.length; i++) {
var product = data.models[i];
for (var member in product) {
result["products[" + i + "]." + member] = product[member];
}
}
return result;
} else {
return JSON.stringify(data)
}
}
}
});
Here is the grid which works ok with the generic static datasouce object.
var grid = $("#leagueEdit_ldg_grid").kendoGrid({
dataSource: dataSource,
sortable: true,
pageable: true,
autobind: false,
//detailInit: leagueEdit_ldg_detailInit,
dataBound: function () {
this.expandRow(this.tbody.find("tr.k-master-row").first());
},
columns: [
{
field: "LeagueDetailGroupId",
title: "Group Id",
width: "110px"
},
{
field: "GroupName",
title: "Group Name",
width: "110px"
}
]
});
Delayed read, autobind set to false.
dataSource.read();
Here is my simplified Controller action. It runs and gets data, and works fine for my MVC wrapper grids.
[Route("LeagueDetailGroup_Read/{_leagueTypeId:int}")]
public ActionResult LeagueDetailGroup_Read([DataSourceRequest]DataSourceRequest request, int _leagueTypeId = -1)
{
DataSourceResult result =
_unitOfWork.FSMDataRepositories.LeagueDetailGroupRepository.Get(
ld => ld.LeagueTypeId == _leagueTypeId
)
.ToDataSourceResult(request,
ld => new LeagueDetailGroupViewModel
{
LeagueDetailGroupId = ld.LeagueDetailGroupId,
LeagueTypeId = ld.LeagueTypeId,
GroupName = ld.GroupName,
DateCreated = ld.DateCreated,
DateLastChanged = ld.DateLastChanged
}
);
// data looks fine here
return Json(result, JsonRequestBehavior.AllowGet);
}
Currently i'm getting this error:
Uncaught TypeError: e.slice is not a function
at init.success (kendo.all.js:6704)
at success (kendo.all.js:6637)
at Object.n.success (kendo.all.js:5616)
at i (jquery-3.1.1.min.js:2)
at Object.fireWith [as resolveWith] (jquery-3.1.1.min.js:2)
at A (jquery-3.1.1.min.js:4)
at XMLHttpRequest.<anonymous> (jquery-3.1.1.min.js:4)
It's hard to know without testing but let me know how this works.
Change your controller so that you are just returning a json string.
Also, try removing your schema and the parameter map, and set your dataType to json:
var dataSource = new kendo.data.DataSource({
transport: {
read: {
url: "#Url.Action("LeagueDetailGroup_Read", "Configuration")?_leagueTypeId=" + leagueTypeId,
dataType: "json"
}
}
});
For the grid I find simple json data does not usually need a schema/model defined. Kendo is super annoying and hard to debug. Let me know how it goes.
In my experience, an e.slice error happens when you have a record that has a null value in it somewhere. The kendo grid is not really smart enough to deal with this so you either have to make sure your datasource returns empty strings instead of nulls for string fields, or put a client template on the columns that translates a null into an empty string. It's possible that the kendo todatasourceresult made the problem come to light. Note that that is usually the last step before returning your dataset since it can modify the entity queries to give paging, so that you never query more than a single page of data (for ajax grids).

EXTJS Extending Ext.data.JsonStore

I'm an ExtJS (I'm using version 5.1) newbie and I'm trying to split a monolithic single file application in different files. I've moved a store outside in a separate file. This is the store in the separate file:
Ext.define("MT.store.MicroProfilerStore", {
extend: "Ext.data.JsonStore",
singleton : true,
model : 'MT.model.MicroProfilerModel',
storeId: "micro_profiler_store",
autoLoad: false,
proxy: {
type: 'ajax',
url: './backend/profiler.php',
reader: {
type: 'json',
rootProperty: 'answers'
}
}
});
If I use this file the ajax request is correct and I can see the reply but it looks like the store is ignoring the rootProperty and instead of having the array of answers in the store.getData() I have a single item array with the first value that is the entire response converted to javascript like:
[{success: 'true', answers: [{}, {}]}]
But If I create the store directly without subclassing using Ext.create("Ext.data.JsonStore", {...}) it's working!
The hack that I've found after a day of trying that allows me to keep a separate file for the store is this:
Ext.define("MT.store.MicroProfilerStore", function(){
Ext.require(['MT.model.MicroProfilerModel'], function(){
Ext.create("Ext.data.JsonStore", {
singleton : true,
model : 'MT.model.MicroProfilerModel',
storeId: "micro_profiler_store",
autoLoad: false,
proxy: {
type: 'ajax',
url: './backend/profiler.php',
reader: {
type: 'json',
rootProperty: 'answers'
}
}
});
});
return {};
});
Then I can get the store using StoreManger.lookup(). Ok it's working fine but the question is why ?
PS
I've already tried preloading the model before the store, explicity requiring the model and the store in many place It doesn't looks like a precedence error
Thanks for your help
We have many stores which could be made singleton, but it seems that singleton:true isn't part of ExtJS best practices.
If we need a "singleton store", which is like 90% of the time, we still make a normal store, but add that store to the stores array in Application.js, so that the instance is created before Application launch. What makes the store a singleton is a storeId, by which it is referenced from everywhere. All our singleton stores are defined using a special constructor/callParent construction, because we didn't get reader rootProperty to work otherwise:
Ext.define('MyApp.store.Directories',{
extend: 'Ext.data.Store',
storeId: 'DirectoryStore',
constructor: function() {
var me = this;
this.callParent([{
proxy: {
type: 'ajax',
headers:{'Accept':'application/json'},
noCache: true,
pageParam: false,
startParam: false,
limitParam: false,
extraParams: {
q: 'directory'
},
url: '../api/AddressBook',
reader: {
type: 'json',
rootProperty: 'data'
}
},
autoLoad: true
}]);
}
});
The special constructor/callParent part makes the difference here. We don't exactly know WHY it works, but it works - we copied that approach from Sencha Architect-generated code. If we now need that store's content anywhere, we do as follows:
xtype:'combo',
name:'Directory',
store:'DirectoryStore' // <- reference by storeId!
The storeId reference fails if we don't add the store to the stores array in Application.js, where we should keep a list of all "singleton" stores:
Ext.define('MyApp.Application', {
extend: 'Ext.app.Application',
name: 'MyApp',
views: [
/* Allgemein */
...
],
controllers: [
'Configuration',
...
],
stores: [
'Directories',
...
]

Kendo TreeView with remote datasource only populates the root elements

I am having difficulty in fully populating a Kendo TreeView with a remote datasource, although with a local datasource it works fine.
In short, the first sample below uses a local datasource. This all works perfectly:
// local datasource, works perfectly
var local = new kendo.data.HierarchicalDataSource({
data: [
{
"DeviceGroupId": 1,
"DeviceGroupName": "Superdeluxe Devices",
"Devices": [
{
"Id": 1000,
"Name": "My First Device"
},
{
"Id": 1001,
"Name": "My Second Device"
}
]
}
],
schema: {
model: {
children: "Devices"
}
}
});
// initialize - this works!
$("#list-of-devices").kendoTreeView({
dataSource: local,
dataTextField: ["DeviceGroupName", "Name"],
loadOnDemand: false
});
Again, the sample above works just fine. Now, the second sample below does not: it only populates the treeview's root element ("Superdeluxe Devices"). And it totally ignores the children.
// remote datasource
var remote = new kendo.data.HierarchicalDataSource({
transport: {
read: {
url: "/api/devices/list", // <-- confirmed this works
dataType: "json",
contentType: "application/json"
},
schema: {
model: {
children: "Devices"
}
}
}
});
// initialize
$("#list-of-devices").kendoTreeView({
dataSource: remote, // the issue: only shows top level nodes
dataTextField: ["DeviceGroupName", "Name"],
loadOnDemand: false
});
So, the issue in the second sample is that only the top level nodes are shown, without any option to expand.
I have looked into the following:
The data in both datasources, local and remote, are identical (I copied the results from remote into local)
Enabled/disabling the loadOnDemand option, now setting it by default to 'false'
Mapping stuff through the schema.data and schema.parse functions to no effect
Looked into the both the HierarchicalDataSource API and the TreeView API, as well as the Binding to remote data demo
Looked into older UserVoice issue, which indicates that it's possible now to fully load and render a TreeView
Summarized, I can't seem to figure out why the local variant works perfectly - and the remote does not show the children. Any suggestions?
The problem is in your remote DataSource definition where you defined the schema.model as part of the transport and it is not. It should be:
var remote = new kendo.data.HierarchicalDataSource({
transport: {
read: {
url: "list.json",
dataType: "json",
contentType: "application/json"
}
},
schema: {
model: {
children: "Devices"
}
}
});
schema is at the same level than transport.

jqGrid - loading values from JSON

I have a jqGrid working OK using the local datatype, but I now want the values to be loaded via json but having trouble changing it.
This is my jqGrid code
jQuery("#grid").jqGrid({
datatype: "json",
url: "/controller/getItems?id=2",
width: 1405,
colNames: ['id', 'surname'],
colModel: [
{ name: 'id', index: 'id', editable: false, hidden: false, hidedlg: true },
{ name: 'surname', index: 'surname', editable: true }
],
onSelectRow: function (id, status, e) {
...
},
editurl: url,
...
So the method to get the JSON is sucessfully fired.
[HttpGet]
public ActionResult getItems(string id)
{
List<model> items = method.getItems(id);
string jsonText = new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(items);
return Json(jsonText, JsonRequestBehavior.AllowGet);
}
The column names in the JSON do match the colModel names
Example of the json being returned - what the object jsonText above contains
[{"id":434,"surname":"Woods"},
{"id":435,"surname":"Adams"}]
Is there anything I have done wrong or am missing?
Thanks
I suppose that the error in in using of System.Web.Script.Serialization.JavaScriptSerializer().Serialize. You need just return Json(items, JsonRequestBehavior.AllowGet);. Additionally you can remove the column id from the colModel. The id value will be still read and assigned as the value of id attribute of the rows (id of <tr> elements of the grid) known as rowid. You should add loadonce: true option to the grid because you don't implemented paging of data on the server side and to add gridview: true (if you not already use it) to have better performance and autoencode: true to interpret input data as texts instead of HTML fragments.
UPDATED: In case of usage old version of jqGrid one have to include jsonReader parameter which corresponds the format of input data:
jsonReader: {
repeatitems: false,
root: function (obj) { return obj; }
}
One should still use loadonce: true option additionally.

List not populating with a JsonP proxy

I want to have a Navigation view. I am trying to populate the list in Sencha Touch using a JsonP proxy.
Here's the sample code snippet of what I have tried till now :
var view = Ext.define('MyApp.view.NavigateView', {
extend: 'Ext.navigation.View',
xtype:'navigateview',
config : {
fullscreen:true,
styleHtmlContent:true,
scrollable:true,
items : [
{
title:'Navigation',
items : [
{
xtype:'list',
store: {
fields : ['title','author'],
proxy : {
type:'jsonp',
url:'https://ajax.googleapis.com/ajax/services/feed/load?v=1.0&q=http://feeds.feedburner.com/SenchaBlog',
reader: {
type: 'json',
rootProperty: 'responseData.feed.entries'
}
},
autoLoad:true,
},
itemTpl:'<div class="contact">{title} <strong>{author}</strong></div>',
listeners : {
itemtap : function(){
Ext.Msg.alert('Called');
}
}
}
],
}
]
}
});
But the problem is, my list is not getting populated. No items are being shown up in the list.
Also, I am constantly getting this error on console.
XMLHttpRequest cannot load
http://api.tinyhippos.com/xhr_proxy?tinyhippos_apikey=ABC&tinyhippos_rurl=list.php%3F_dc%3D1334462633038%26page%3D1%26start%3D0%26limit%3D25.
Origin http://localhost is not allowed by Access-Control-Allow-Origin.
Anyone please guide ? Anything that I am missing here ?
i was facing the same error when using AJAX request in cross domain.
have a look here
you have to make sure that the server part is configured properly using jsonp
as a first step identify if your application will run correctly when you disable web security in your browser
locate your chrome installation directory
then type in your cmd: chrome --disable-web-security
Your Ext.navigation.View object is containing one Ext.Component object (xtype not defined so defaulted to 'component') that is containing your list. If you put your list directly as an item of your view, it'll be rendered:
var view = Ext.define('MyApp.view.NavigateView', {
extend: 'Ext.navigation.View',
xtype: 'navigateview',
config : {
fullscreen: true,
styleHtmlContent: true,
scrollable: true,
items : [{
title: 'Navigation',
xtype: 'list',
store: {
fields: ['title','author'],
proxy: {
type: 'jsonp',
url: 'https://ajax.googleapis.com/ajax/services/feed/load?v=1.0&q=http://feeds.feedburner.com/SenchaBlog',
reader: {
type: 'json',
rootProperty: 'responseData.feed.entries'
}
},
autoLoad:true
},
itemTpl: '<div class="contact">{title} <strong>{author}</strong></div>'
}]
}
});
Note1: Not sure why your code is not working.
Note2: The error your mentioned is not related to your code snippet

Categories

Resources