Can I have a JSON Schema dependency that adds a field inside an array of objects? - jsonschema

I have a JSON Schema that includes an array of objects. I'd like one of the fields inside those objects to be dependent on a property outside the array.
I created the following schema:
{
type: "object",
properties: {
showNotes: {
title: "Add notes field",
type: "boolean",
},
choices: {
type: "array",
title: "Choices",
items: {
type: "object",
properties: {
itemName: {
type: "string",
title: "Item"
},
isRequired: {
type: "boolean",
title: "Required?",
default: false
},
note: {}
}
},
default: [
{
content: "Thing 1",
correct: false
}
]
}
},
dependencies: {
showNotes: {
oneOf: [
{
properties: {
showNotes: {
enum: [
false
]
}
}
},
{
properties: {
showNotes: {
enum: [
true
]
},
note: {
title: "Note",
type: "string"
}
}
}
]
}
}
}
I was hoping that the new field note would update the one at items/note, but it did not, instead it generated a new field note at the bottom. This can be seen here:
https://codepen.io/samfentr/pen/ZEQpeyg
I assume that the solution will have something to do with adding $ref reference, but I haven't been able to work it out.

I was able to solve this.
I needed to put the entire path to notes in my oneOf option:
showNotes: {
oneOf: [
{
properties: {
showNotes: {
enum: [
false
]
}
}
},
{
properties: {
showNotes: {
enum: [
true
]
},
choices: {
items: {
properties: {
note: {
type: "string",
title: "Note"
}
}
}
}
}
}
]
}
https://codepen.io/samfentr/pen/BajQwYE

Related

AJV validate string against an array of objects

I'm trying to use AJV to check that parent_IDs on child objects are valid IDs on the parent objects.
I can get it to work by validating against a single parent object like this:
const ajv = new Ajv({
$data: true,
allErrors: true,
verbose: true,
});
addFormats(ajv, ["uuid"]);
const schema = {
type: "object",
properties: {
parentObjects: {
type: "array",
items: {
type: "object",
properties: {
id: { type: "string", format: "uuid" },
name: { type: "string" },
},
required: ["id", "name"],
},
},
childObjects: {
type: "array",
items: {
type: "object",
properties: {
id: { type: "string", format: "uuid" },
name: { type: "string" },
parent_id: {
type: "string",
format: "uuid",
const: { $data: "/parentObjects/0/id" },
},
},
required: ["id", "name", "parent_id"],
},
},
},
};
const data = {
parentObjects: [
{
id: "3bc169ba-99c4-448a-8c22-5c2593ccc9ee",
name: "larry",
},
{
id: "d2e92e51-cb56-4451-bf8b-349d82fde107",
name: "curly",
},
{
id: "b99f61f5-f417-4129-9315-ab049d2b618d",
name: "moe",
},
],
childObjects: [
{
id: "bd86603f-fb1d-4075-94f5-619337d43b98",
name: "stan",
parent_id: "3bc169ba-99c4-448a-8c22-5c2593ccc9ee",
},
{
id: "c2b80273-bf2b-4898-a44b-a758a436cb37",
name: "oliver",
parent_id: "e13b7c34-6cb5-4ef4-83a7-7d11c2bd4a1f",
},
],
};
ajv.validate(schema, data);
console.log(ajv.errors);
};
But what I need is to be able to validate against all parent objects, something like:
childObjects: {
type: "array",
items: {
type: "object",
properties: {
id: { type: "string", format: "uuid" },
name: { type: "string" },
parent_id: {
type: "string",
format: "uuid",
enum: { $data: "/parentObjects/*/id" },
},
},
required: ["id", "name", "parent_id"],
},
},
I can't find a way to use a wildcard for the array index "/parentObjects/*/id" or a way to iterate through all of the parentObjects. I could map the parentObject IDs outside of AJV, create another array and validate against that, but it seems like overkill - I feel like I'm missing something simple in AJV which would allow me to do this without generating a new array.

Indexing custom properties with Google Cloud Search API

We are having issues indexing metadata with items added to Google Cloud Search with 3rd-party datasources, using the REST API. We are following this guide: https://developers.google.com/cloud-search/docs/guides/schema-guide.
What we tried: uploaded the schema successfully ✅, indexed some items ✅, made them available in the search UI ✅, but it seems the properties and facets not showing up whether it’s in the green metadata bits in search results or in API results -- we get an empty structuredData object. Search results seem to only query the content.inlineContent and nothing else. We’re not getting any errors from the API when we make the index request (using https://developers.google.com/cloud-search/docs/reference/rest/v1/indexing.datasources.items/index_). It seems like it’s just ignoring everything in structuredData.
Other attempts: In addition to the REST API, we’ve also used the official nodejs SDK, (which has additional validation because it’s in TypeScript), to no avail. We’ve verified that auth params are correct (it returns 401 otherwise) and that there are no other validation issues (it returns 400 otherwise). Requests return 200 and do upload successfully, just not the structuredData. The original schema upload was also successful (200), and the response included the full schema we gave.
What are we missing?
schema JSON:
{
"objectDefinitions": [{
"name": "page",
"options": {
"displayOptions": {
"objectDisplayLabel": "Page",
"metalines": [
{
"properties": [
{
"propertyName": "title"
},
{
"propertyName": "content"
},
{
"propertyName": "author"
},
{
"propertyName": "siteSection"
}
]
}
]
}
},
"propertyDefinitions": [
{
"name": "title",
"isReturnable": true,
"isWildcardSearchable": true,
"isSuggestable": true,
"isRepeatable": false,
"isFacetable": false,
"textPropertyOptions": {
"operatorOptions": {
"operatorName": "title"
}
},
"displayOptions": {
"displayLabel": "Title"
}
},
{
"name": "content",
"isReturnable": true,
"isRepeatable": false,
"isFacetable": false,
"htmlPropertyOptions": {
"retrievalImportance": {
"importance": "DEFAULT"
}
},
"displayOptions": {
"displayLabel": "Content"
}
},
{
"name": "author",
"isReturnable": true,
"isRepeatable": true,
"isFacetable": true,
"textPropertyOptions": {
"operatorOptions": {
"operatorName": "author"
}
},
"displayOptions": {
"displayLabel": "Author(s)"
}
},
{
"name": "siteSection",
"isReturnable": true,
"isWildcardSearchable": false,
"isSuggestable": false,
"isRepeatable": false,
"isFacetable": true,
"textPropertyOptions": {
"operatorOptions": {
"operatorName": "sitesection"
}
},
"displayOptions": {
"displayLabel": "Site Section"
}
}
]
}]
}
indexing code:
const version = '4';
const apiUrl = `https://cloudsearch.googleapis.com/v1/indexing/datasources/${sourceId}/items/exampleItem:index`;
const title = "Example Item";
const url = "https://example.com";
fetch(apiUrl, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer " + token,
},
body: JSON.stringify({
item: {
name: `datasource/${sourceId}/items/exampleItem`,
acl: {
readers: [
{
gsuitePrincipal: {
gsuiteDomain: true,
},
},
],
},
metadata: {
title: title,
sourceRepositoryUrl: url,
objectType: "page",
},
structuredData: {
object: {
properties: [
{
name: "title",
textValues: {
values: [title],
},
},
{
name: "author",
textValues: {
values: ["Unknown Author"],
},
},
{
name: "siteSection",
textValues: {
values: ["exampleSection"],
},
},
{
name: "content",
htmlValues: {
values: [exampleContentHTML],
},
},
],
},
},
content: {
inlineContent: b64(exampleContentHTML),
contentFormat: "TEXT",
},
version: b64(version),
itemType: "CONTENT_ITEM",
},
mode: "SYNCHRONOUS",
}),
})
indexing result:
{
"name": "datasources/DATASOURCE_ID/items/exampleItem",
"acl": {
"readers": [{
"gsuitePrincipal": {
"gsuiteDomain": true
}
}]
},
"metadata": {
"title": "Example Item",
"sourceRepositoryUrl": "https://example.com",
"objectType": "page"
},
"structuredData": {
"object": {}
},
"content": {
"inlineContent": "... base 64 encoded content...",
"contentFormat": "TEXT"
},
"version": "NQ==",
"status": {
"code": "ACCEPTED"
},
"queue": "default",
"itemType": "CONTENT_ITEM"
}

Elastic (animated) edges in graph with nodes exerting gravitational pull on neighbours?

Is there a layout extension for Cytoscape that enables a dynamic behavior similar to that of the Neo4j Browser, i.e. when you drag a node, its edges are elastic to some extend, but that also drag connected nodes along part of the way (I'd call it localized gravity)?
Update:
The example I'm working on uses the CoSE Bilkent (compound) layout extension, but it doesn't seem to support the effect/animation I'm after out of the box. I had hoped the scarcely documented { gravity: 1 } option might be related - after all, when a node pulls other nodes along, that could well be described as gravity - but changing the setting on a small sample graph had no such effect; some digging ensued and I now think that setting has to do with how close to the graph's center nodes are displayed. I then looked at all layout demos, none seem to display the effect I'm after out of the box. AllegroViva appears to implement similar behavior (video), but from my understanding, it's rendering a time series in that video (so might just be manually redrawing the graph). Their website seems to be disfunct, too.
What I'm looking for is something easy, ideally out of the box, or something that can be implemented quickly. Unfortunately, I'm not quite sure what the right search term would be for what I want (especially in Cytoscape's domain). Hence me asking what is admittedly a very high-level question. Today, I found out Visjs calls it physics events (or at least uses the effect I'm after as part of that demo) - but as I mentioned, gravity in Cytoscape is apparently not what I'm looking for. At this point, however, I'm merely trying to establish if Cytoscape is the right library, or whether I need to look at others, like Alchemy (cf. its Philosophers' Relatedness example).
Answer:
Thank you for editing the question, I think i can help you with this one. Cytoscape.js has this feature buried deep in the extension layouts, specifically in cytoscape.js-cola. The layout is a physics layout with "springy" like nodes, so that the distance between them stays the same. The catch here is, that in the paragraph Notes, the author describes this:
If you want to maintain interactivity, you probably should not mix infinite: true with fit: true. Fitting naturally changes the zoom level, making dragging misaligned and feel weird to users --- though it still works technically. Better to just fit: false when infinite: true, and cy.center() or cy.fit() on layoutready.
The alignment option isn't as flexible as the raw Cola option. Here, only integers can be used to specify relative positioning, so it's a bit limited. If you'd like to see a more sophisticated implementation, please send a pull request.
Code:
So this example should work (note that the nodes can be moved, but they tend to stay in formation because of their already optimal position):
document.addEventListener("DOMContentLoaded", function() {
var cy = (window.cy = cytoscape({
container: document.getElementById("cy"),
autounselectify: true,
boxSelectionEnabled: false,
layout: {
name: "cola",
infinite: true,
fit: false
},
style: [{
selector: "node",
css: {
"background-color": "#f92411"
}
},
{
selector: "edge",
css: {
"line-color": "#f92411"
}
}
],
elements: {
nodes: [{
data: {
id: "1",
label: "P"
}
},
{
data: {
id: "2",
label: "sucrose phosphate phosphatase"
}
},
{
data: {
id: "4",
label: "sucrose 6-phosphate"
}
},
{
data: {
id: "6",
label: "sucrose"
}
},
{
data: {
id: "8",
label: "invertase"
}
},
{
data: {
id: "10",
label: "fructose"
}
},
{
data: {
id: "12",
label: "fructokinase"
}
},
{
data: {
id: "14",
label: "fructose 6-phosphate"
}
},
{
data: {
id: "20",
label: "phosphoglucose isomerase"
}
},
{
data: {
id: "22",
label: "glucose 6-phosphate"
}
},
{
data: {
id: "28",
label: "glucose"
}
},
{
data: {
id: "30",
label: "hexokinase"
}
},
{
data: {
id: "33",
label: "sucrose synthase"
}
},
{
data: {
id: "36",
label: "UDP - glucose"
}
},
{
data: {
id: "38",
label: "sucrose phosphate synthase"
}
},
{
data: {
id: "41",
label: "UDP"
}
},
{
data: {
id: "44",
label: "fructose 6-phosphate"
}
},
{
data: {
id: "46",
label: "ATP"
}
},
{
data: {
id: "47",
label: "ATP"
}
},
{
data: {
id: "52",
label: "ATP"
}
},
{
data: {
id: "57",
label: "ADP"
}
},
{
data: {
id: "66",
label: "PP"
}
},
{
data: {
id: "71",
label: "UTP"
}
},
{
data: {
id: "76",
label: "UDP glucose pyrophosphorylase"
}
},
{
data: {
id: "80",
label: "glucose 1-phosphate"
}
},
{
data: {
id: "86",
label: "phospho- glucomutase (cPGM)"
}
},
{
data: {
id: "89",
label: "G1P transporter"
}
},
{
data: {
id: "90",
label: "P"
}
},
{
data: {
id: "95",
label: "P"
}
},
{
data: {
id: "102",
label: "P"
}
},
{
data: {
id: "103",
label: "P"
}
},
{
data: {
id: "104",
label: "G6P transporter"
}
},
{
data: {
id: "109",
label: "glucose 6-phosphate"
}
},
{
data: {
id: "115",
label: "phospho- glucomutase (cPGM)"
}
},
{
data: {
id: "121",
label: "glucose 1-phosphate"
}
},
{
data: {
id: "128",
label: "ADPglucose pyrophosphorylase (pAGPase)"
}
},
{
data: {
id: "130",
label: "ADP - glucose"
}
},
{
data: {
id: "136",
label: "PP"
}
},
{
data: {
id: "141",
label: "ATP"
}
},
{
data: {
id: "148",
label: "inorganic diphosphatase"
}
},
{
data: {
id: "149",
label: "P"
}
},
{
data: {
id: "156",
label: "phosphate transporter"
}
},
{
data: {
id: "158",
label: "P"
}
},
{
data: {
id: "164",
label: "starch synthase (simpl.)"
}
},
{
data: {
id: "166",
label: "ADP"
}
},
{
data: {
id: "172",
label: "starch"
}
},
{
data: {
id: "178",
label: "ATP/ADP transporter"
}
},
{
data: {
id: "179",
label: "ADP"
}
},
{
data: {
id: "184",
label: "ADP"
}
},
{
data: {
id: "189",
label: "ATP"
}
}
],
edges: [{
data: {
source: "2",
target: "1"
}
},
{
data: {
source: "4",
target: "2"
}
},
{
data: {
source: "2",
target: "6"
}
},
{
data: {
source: "6",
target: "8"
}
},
{
data: {
source: "8",
target: "10"
}
},
{
data: {
source: "12",
target: "14"
}
},
{
data: {
source: "14",
target: "20"
}
},
{
data: {
source: "20",
target: "22"
}
},
{
data: {
source: "8",
target: "28"
}
},
{
data: {
source: "28",
target: "30"
}
},
{
data: {
source: "30",
target: "22"
}
},
{
data: {
source: "6",
target: "33"
}
},
{
data: {
source: "33",
target: "10"
}
},
{
data: {
source: "33",
target: "36"
}
},
{
data: {
source: "36",
target: "38"
}
},
{
data: {
source: "38",
target: "4"
}
},
{
data: {
source: "38",
target: "41"
}
},
{
data: {
source: "41",
target: "33"
}
},
{
data: {
source: "44",
target: "38"
}
},
{
data: {
source: "52",
target: "12"
}
},
{
data: {
source: "12",
target: "57"
}
},
{
data: {
source: "46",
target: "30"
}
},
{
data: {
source: "30",
target: "47"
}
},
{
data: {
source: "71",
target: "76"
}
},
{
data: {
source: "76",
target: "66"
}
},
{
data: {
source: "76",
target: "36"
}
},
{
data: {
source: "80",
target: "76"
}
},
{
data: {
source: "22",
target: "86"
}
},
{
data: {
source: "86",
target: "80"
}
},
{
data: {
source: "95",
target: "89"
}
},
{
data: {
source: "89",
target: "90"
}
},
{
data: {
source: "102",
target: "104"
}
},
{
data: {
source: "80",
target: "89"
}
},
{
data: {
source: "104",
target: "109"
}
},
{
data: {
source: "115",
target: "109"
}
},
{
data: {
source: "121",
target: "89"
}
},
{
data: {
source: "121",
target: "115"
}
},
{
data: {
source: "121",
target: "128"
}
},
{
data: {
source: "128",
target: "130"
}
},
{
data: {
source: "141",
target: "128"
}
},
{
data: {
source: "128",
target: "136"
}
},
{
data: {
source: "136",
target: "148"
}
},
{
data: {
source: "148",
target: "149"
}
},
{
data: {
source: "149",
target: "156"
}
},
{
data: {
source: "156",
target: "158"
}
},
{
data: {
source: "130",
target: "164"
}
},
{
data: {
source: "164",
target: "166"
}
},
{
data: {
source: "178",
target: "179"
}
},
{
data: {
source: "184",
target: "178"
}
},
{
data: {
source: "178",
target: "189"
}
},
{
data: {
source: "141",
target: "178"
}
},
{
data: {
source: "104",
target: "103"
}
},
{
data: {
source: "10",
target: "12"
}
},
{
data: {
source: "164",
target: "172"
}
},
{
data: {
source: "22",
target: "104"
}
}
]
}
}));
cy.unbind("tapend");
cy.bind("tapend", "node", function() {
cy.animate({
fit: {
eles: cy.elements(),
padding: 20
},
center: {
eles: cy.elements()
}
}, {
duration: 500
});
});
});
body {
font-family: helvetica;
font-size: 14px;
}
#cy {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
z-index: 999;
}
h1 {
opacity: 0.5;
font-size: 1em;
}
<!DOCTYPE>
<html>
<head>
<title>cytoscape-cola.js demo</title>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1">
<script src="https://unpkg.com/cytoscape/dist/cytoscape.min.js"></script>
<!-- for testing with local version of cytoscape.js -->
<!--<script src="../cytoscape.js/build/cytoscape.js"></script>-->
<script src="https://unpkg.com/webcola/WebCola/cola.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/cytoscape-cola#2.3.0/cytoscape-cola.min.js"></script>
</head>
<body>
<h1>cytoscape-cola demo</h1>
<div id="cy"></div>
</body>
</html>
Conclusion:
Cytoscape.js has the ability to display the force layout, but it is a little worse than the two examples you provided (they can display the graph without moving the nodes to their optimal position but the user preferred one). If you like to use cytoscape.js, you can do that just fine, but always consider which use cases you need and check, if any other application can handle the situation better (cytoscape.js has so many awesome features you can use, so if you can make it work, cytoscape would be my way to go).
Best of luck!
You can use force-directed layout of d3.js Here is an example graph.
I believe Neo4j Browser also uses d3.js
From the official website:
The default Neo4j Server has a powerful, customizable data visualization tool based on the built-in D3.js library.
I found a video that may be similar as your questionUse of Cytoscape.js for Client project, also there is another extension LAYOUT with d3.js cytoscape.js-d3-forcethat may be a good reference.

Complex array at QML

I got in trouble with very simple code:
property var pagesAllModels: {
ru: [
{ title: qsTr("New"), url: "http://bash.im" },
{ title: qsTr("Random"), url: "http://bash.im/random" },
{ title: qsTr("Best"), url: "http://bash.im/best" },
{ title: qsTr("By rating"), url: "http://bash.im/byrating" },
{ title: qsTr("Abyss"), url: "http://bash.im/abyss" },
{ title: qsTr("Abyss top"), url: "http://bash.im/abysstop" },
{ title: qsTr("Abyss best"), url: "http://bash.im/abyssbest" },
],
eng: [
{ title: "Latest", url: "http://bash.org/?latest" },
{ title: "Browse", url: "http://bash.org/?browse" },
{ title: "Random", url: "http://bash.org/?random" },
{ title: "Top", url: "http://bash.org/?top" }
]
}
That code in QML gives me error at line "eng: [" with error "expected lexem ," but in pure javascript everything work fine. What's wrong?
That's because your code is illegal JSON array definition. Web browsers are accepting it because they aren't strict about JS syntax, but QML engine is really strict :
In a key:value pair in associative array, the key must be a string, so it must have quotes around it, else it would be confused with a (non-existing) variable name.
property var pagesAllModels: {
"ru": [
{ "title": qsTr("New"), "url": "http://bash.im" },
{ "title": qsTr("Random"), "url": "http://bash.im/random" },
{ "title": qsTr("Best"), "url": "http://bash.im/best" },
{ "title": qsTr("By rating"), "url": "http://bash.im/byrating" },
{ "title": qsTr("Abyss"), "url": "http://bash.im/abyss" },
{ "title": qsTr("Abyss top"), "url": "http://bash.im/abysstop" },
{ "title": qsTr("Abyss best"), "url": "http://bash.im/abyssbest" }
],
"eng": [
{ "title": "Latest", "url": "http://bash.org/?latest" },
{ "title": "Browse", "url": "http://bash.org/?browse" },
{ "title": "Random", "url": "http://bash.org/?random" },
{ "title": "Top", "url": "http://bash.org/?top" }
]
}
And it works !
Try this
property var pagesAllModels: {
ru: [
{ title: qsTr("New"), url: "http://bash.im" },
{ title: qsTr("Random"), url: "http://bash.im/random" },
{ title: qsTr("Best"), url: "http://bash.im/best" },
{ title: qsTr("By rating"), url: "http://bash.im/byrating" },
{ title: qsTr("Abyss"), url: "http://bash.im/abyss" },
{ title: qsTr("Abyss top"), url: "http://bash.im/abysstop" },
{ title: qsTr("Abyss best"), url: "http://bash.im/abyssbest" }
],
eng: [
{ title: "Latest", url: "http://bash.org/?latest" },
{ title: "Browse", url: "http://bash.org/?browse" },
{ title: "Random", url: "http://bash.org/?random" },
{ title: "Top", url: "http://bash.org/?top" }
]
}
Hope this will resolve your issue
associative arrays separates by semicolon ";"
Try this
property var pagesAllModels: {
ru: [
{ title: qsTr("New"), url: "http://bash.im" },
{ title: qsTr("Random"), url: "http://bash.im/random" },
{ title: qsTr("Best"), url: "http://bash.im/best" },
{ title: qsTr("By rating"), url: "http://bash.im/byrating" },
{ title: qsTr("Abyss"), url: "http://bash.im/abyss" },
{ title: qsTr("Abyss top"), url: "http://bash.im/abysstop" },
{ title: qsTr("Abyss best"), url: "http://bash.im/abyssbest" },
];
eng: [
{ title: "Latest", url: "http://bash.org/?latest" },
{ title: "Browse", url: "http://bash.org/?browse" },
{ title: "Random", url: "http://bash.org/?random" },
{ title: "Top", url: "http://bash.org/?top" }
]
}

How to specify rootProperty for nested data if it is one level below?

I am fetching nested data to be shown as nested list but whenever I tap on top level item, it again shows same top level list instead of showing children list and a ajax request is fired to fetch json data again. Here is the store:
Ext.define('MyTabApp.store.CategoriesStore',{
extend:'Ext.data.TreeStore',
config:{
model : 'MyTabApp.model.Category',
autoLoad: false,
storeId : 'categoriesStore',
proxy: {
type: 'ajax',
url: 'resources/data/catTree.json',
reader: {
type: 'json',
rootProperty: 'data.categories'
}
},
listeners:{
load: function( me, records, successful, operation, eOpts ){
console.log("categories tree loaded");
console.log(records);
}
}
}
});
and here is the data in that file which I am using to mock service:
{
"data":{
"categories": [
{
"name": "Men",
"categories": [
{
"name": "Footwear",
"categories": [
{ "name": "Casual Shoes", "leaf": true },
{ "name": "Sports Shoes", "leaf": true }
]
},
{
"name": "Clothing",
"categories": [
{ "name": "Casual Shirts", "leaf": true },
{ "name": "Ethnic", "leaf": true }
]
},
{ "name": "Accessories", "leaf": true }
]
},
{
"name": "Women",
"categories": [
{ "name": "Footwear", "leaf": true },
{ "name": "Clothing", "leaf": true },
{ "name": "Accessories", "leaf": true }
]
},
{
"name": "Kids",
"categories": [
{
"name": "Footwear",
"categories": [
{ "name": "Casual Shoes", "leaf": true },
{ "name": "Sports Shoes", "leaf": true }
]
},
{ "name": "Clothing", "leaf": true }
]
}
]
}
}
This is the list:
Ext.define('MyTabApp.view.CategoriesList', {
extend: 'Ext.dataview.NestedList',
alias : 'widget.categorieslist',
config: {
height : '100%',
title : 'Categories',
displayField : 'name',
useTitleAsBackText : true,
style : 'background-color:#999 !important; font-size:75%',
styleHtmlContent : true,
listConfig: {
itemHeight: 47,
itemTpl : '<div class="nestedlist-item"><div>{name}</div></div>',
height : "100%"
}
},
initialize : function() {
this.callParent();
var me = this;
var catStore = Ext.create('MyTabApp.store.CategoriesStore');
catStore.load();
me.setStore(catStore);
}
});
The list starts working properly without any ajax request on each tap if I remove data wrapper over top categories array and change rootProperty to categories instead of data.categories. Since server is actually returning categories in data object I cannot remove it so how do I fix the store in that case? Also why is that additional ajax request to fetch the file?
[EDIT]
Tried to create a fiddle http://www.senchafiddle.com/#d16kl which is similar but not same because it is using 2.0.1 and data is not loaded from external file or server.
Last time I had this exact situation, it was because one of my top level category was a leaf but I had not set leaf:true. Doing so recalled the top level of the nested list as if it was a child.
It seems from your Fiddle that if your data is in this following format, it would work fine:
{
"categories" : [{
"name" : "Foo",
"categories" : [{
...
}]
}]
}
That is, just remove the "data" property and make defaultRootProperty: 'categories' & rootProperty: 'categories'. Check this: http://www.senchafiddle.com/#d16kl#tIhTp
It works with external data file as well.