Sanity CMS, referencing arrays within a document - javascript

My goal is to have a custom internalLink mark that is able to reference not just the post (which is easy enough since its a type: document) but also reference name: sections which returns array of section.js. That way editors can link to any section within a post document. And ideally the editors can also reach other post sections as well, not just the current one open.
I want to be able to reference the following collection of section.js in the reference dropdown:
Now I understand reference only works for type: document. Can I make it work for the children (array or object) of type: post?
My custom block.js
marks: {
...
annotations: [
{
name: "internalLink",
title: "Internal link",
type: "object",
fields: [
{
name: "linkto",
type: "reference",
title: "Link To",
to: [{ type: "post" }],
},
],
},
...
post.js
export default {
name: "post",
title: "Document",
type: "document",
fields: [
...
{
name: "sections",
title: "Sections",
type: "array",
of: [{ type: "section" }],
},
],
}
section.js
export default {
title: "Section",
name: "section",
type: "object",
fields: [
{
name: "sectionTitle",
title: "Section Title",
type: "string",
},
{
title: "Content",
name: "content",
type: "blockContent",
},
],
}
Appreciate any help/pointers I can get :)

Related

How to create parameterized Ext Rest Proxy on my Ext Store

I have a API that sends out a paginated result of data and I want it to be consumed my Ext JS app but I don't know how to supply the needed parameters.
Here is the response I expect:
{
"currentPage": 1,
"from": 1,
"items": [
{
"id": 1,
"customer": "Customer 1",
"movie": "Movie 1",
"dateRented": "2021-01-25T01:22:42.143",
"dateReturned": "2021-01-25T01:22:50.447"
},
{
"id": 2,
"customer": "Customer 2",
"movie": "Movie 2",
"dateRented": "2021-01-25T01:22:42.15",
"dateReturned": "2021-01-25T01:22:54.573"
}
],
"pageSize": 2,
"to": 2,
"totalCount": 1000003,
"totalPages": 500002,
"hasPreviousPage": false,
"hasNextPage": true
}
Here is the endpoint:
/api/Rentals/{currentPage}/{pageSize}
Here is my Ext store but I don't know how I will be able to pass the value for currentPage and pageSize:
Ext.define('Vidly.store.PagedRentals', {
extend: 'Ext.data.Store',
alias: 'store.pagedrentals',
storeId: 'pagedrentals',
model: 'Vidly.model.PagedRental',
autoLoad: true,
autoSync: true,
proxy: {
type: 'rest',
url: 'https://localhost:44313/api/Rentals/',
useDefaultXhrHeader: false,
reader: {
type: 'json',
headers: { 'Accept': 'application/json' },
},
writer: {
type: 'json',
writeAllFields: true
}
},
});
And here is the model:
Ext.define('Vidly.model.PagedRental', {
extend: 'Ext.data.Model',
fields: [
{ name: 'currentPage', type: 'int' },
{ name: 'from', type: 'int' },
{ name: 'to', type: 'int' },
{ name: 'pageSize', type: 'int' },
{ name: 'totalCount', type: 'int' },
{ name: 'totalPages', type: 'int' },
],
hasMany: 'Rental',
});
I hope someone can help me with my problem. Thank you.
Ext's rest proxy is designed to use standard REST APIs where paging and filtering options are passed in as query parameters. I.e. something like
https://localhost:44313/api/Rentals?start=1&limit=25
I would recommend to use this approach rather than a non standard REST API. It will enable you to use Ext's related features seamlessly.
If there is no way to change the API and you need to stick with your current server configuration then you need to create a custom proxy overriding some of the related functions. The best bet if you override the buildUrl function and pass your custom generated URL to the request object.
UPDATE
You can start with this code (also created a Fiddle):
Ext.define('Yournamespace.proxy.custom', {
extend: 'Ext.data.proxy.Rest',
alias: 'proxy.custom',
buildUrl: function(request) {
const url = this.callParent([request]);
const operation = request.getOperation();
console.log(url, this.getParams(operation))
return url;
}
});
Ext.define('User', {
extend: 'Ext.data.Model',
});
Ext.application({
name : 'Fiddle',
launch : function() {
var myStore = Ext.create('Ext.data.Store', {
model: 'User',
pageSize: 10,
proxy: {
type: 'custom',
url: 'https://localhost:44313/api/Rentals/',
reader: {
type: 'json',
rootProperty: 'users'
}
},
autoLoad: true
});
}
});
You can write your custom code to the buildUrl function. Currently only the default URL and the params are collected and logged there but it does the default stuff. You can tweak the URL here and return the new URL at the end.

ExtJS - Data from Store don't load

I have a problem with loading data from store. Please tell me what I do wrong. I am using ExtJS 4.1.
Request sends properly, i haven't troubles like file not found or something like that. It also works if I had few stores, and any of this stores loading one 'data type' to his model, for example urls1. But if I have one store and one big model, data don't display.
I have a JSON like this:
{
"root": {
"tName": "name",
"urls1": [{
"url": "http:// ..... :09'"
}, {
"url": "http:// ..... :10'"
}],
"perS": "",
"perD": "",
"urls2": [{
"url": "http:// ..... :0009'"
}, {
"url": "http:// ..... :0010'"
}],
"val2": "",
"list2": [{
"level": "lvl1"
}, {
"level": "lvl2"
}],
"types": [{
"type": "type2"
}, {
"type": "type4"
}],
"accs": [{
"login": "login",
"pass": "p1",
"port": "8858",
"conType": "type3",
}, {
"login": "login3",
"pass": "p13",
"port": "88583",
"conType": "type2",
}]
}
}
My Model:
Ext.define('ACT.model.myModel', {
extend: 'Ext.data.Model',
fields: [
{name: 'tname'},
{name: 'urls1'},
{name: 'psec'},
{name: 'pday'},
{name: 'urls2'},
{name: 'list2'},
{name: 'types'},
{name: 'accs'},
]
});
My Store:
Ext.define('ACT.store.dataStore', {
extend: 'Ext.data.Store',
storeId:'mStore',
model: 'ACT.model.myModel',
autoLoad: true,
proxy: {
type: 'ajax',
url: 'resources/data/configuration/MyConfig.json',
reader: {
type: 'json',
root: 'root',
successProperty: 'success'
}
}
});
and my initComponent function in view:
initComponent: function() {
var me = this;
this.columns = [
{
xtype: 'checkcolumn',
text: ' ',
width: 100,
sortable: false,
hideable: false,
allowBlank: false
},
{
text: 'URL',
width: '85%',
dataIndex: 'urls1',
sortable: true,
hideable: false
}]
this.callParent(arguments);
}
});
The above should load urls1 into the store correctly, however, the data type is array. So the data is in the store but it is only not displayed in the grid as dataIndex points to that array.
You can create another model for urls and associate it with the master model.

Reading JSON array from cross domain sencha

I would like to store an array of json objects from another domain. I have tried all possible configurations in the proxy, but it is still not working. So please help with me.
Response Array:
[
{
"id": 1,
"title": "Take A Bow",
"artist": "Rihanna",
"cover": "resources/images/cd-covers/take-a-bow.jpeg",
"audio": "http://home.no/hamed2ganja12/Single/Rihanna%20-%20Take%20A%20Bow%20%28www.Iran2Music.Org%29.mp3"
},
{
"id": 2,
"title": "Ridin' Solo",
"artist": "Jason Derulo",
"cover": "resources/images/cd-covers/ridin-solo.jpeg",
"audio": "http://ms11.cyworld.com.cn/d044/2010/05/01/167/1272686567306986_file.mp3"
},
{
"id": 3,
"title": "Hero",
"artist": "Nickelback",
"cover": "resources/images/cd-covers/hero.jpeg",
"audio": "http://api.ning.com/files/hXzO1QWnGr6ZgtB05IbaLW5IId7mjLPvOMGA0I8JHY*u*ZMCrczyw*XZrimUE7XQHFHgOLWa2b8s0xGfoHg5nRs-J84KlSGO/NickelBackHeroSpidermanTheme.mp3"
}]
model:
Ext.define('MyApp.model.Track', {
extend: 'Ext.data.Model',
config: {
fields: [
{ name: 'id', type: 'int' },
{ name: 'title', type: 'string' },
{ name: 'artist', type: 'string' },
{ name: 'cover', type: 'string' },
{ name: 'audio', type: 'string' }
]
}
});
Store:
Ext.create('Ext.data.Store',{
requires:['MyApp.model.Track'],
autoLoad:true,
model:'MyApp.model.Track',
storeId:'myStore',
autoSync:true,
fields:["title","artist"],
proxy:{
type:'jsonp',
url: 'http://www.tux-components.com/examples/playlist/app/music.json',
reader: {
type: 'json'
}
},
listeners:{
load: function(store, records, successful,operation,eOpts){
console.log('loaded records count is '+store.getCount());
}
}
});
I found it is giving timeout error. but the URL is working fine in browser.
What should i do next? please help me..
The data returned by the remote server needs to be JSONP, not JSON - the main difference being the callback function that wraps the returned object.
I don't know what framework/version you're using, but read the JSONP Proxy API docs very carefully - all of the answers are within!

Grief with extJS4 treegrid using custom model and async loading

I just cannot seem to get the tree grid up and running.
I have defined the model, the store and the treegrid (as seen below).
The tree grid shows inside target, the data is loaded async (checked with fiddler, two rows came back) however the treegrid just shows two rows with empty cells.
I tried debugging and the store's root node indeed has two child nodes, the model data is under child's raw property (except some fields such as leaf and iconCls which are also in data property), yet the tree grid shows two empty rows, despite dataIndex pointing to a proper model field.
It's like tree grid cannot find the field defined by the model?!?
Here's the source (I am using sandbox because I am integrating this into salesforce vforce, the salesforce merge fields {!} are also valid and render properly)
Ext4.onReady(function() {
var target = '{!$Component.childBlock.childTreeDiv}';
Ext4.define('ConfigurationItem', {
extend: 'Ext4.data.Model',
fields: [
{
id: 'id',
type: 'string'},
{
id: 'name',
type: 'string'},
{
id: 'recordType',
type: 'string'},
{
id: 'ciName',
type: 'string'},
{
id: 'alias',
type: 'string'},
{
id: 'model',
type: 'string'},
{
id: 'status',
type: 'string'},
{
id: 'description',
type: 'string'},
{
id: 'leaf',
type: 'bool'},
{
id: 'iconCls',
type: 'string'}
]
});
var store = Ext4.create('Ext4.data.TreeStore', {
model: 'ConfigurationItem',
root: {
nodetype: 'async',
id: '{!CI__c.Id}',
expanded: true
},
proxy: {
type: 'ajax',
url: 'json_CIChildren',
reader: {
type: 'json',
root: 'children'
}
}
});
tree = Ext4.create('Ext4.tree.Panel', {
width: document.getElementById(target).offsetWidth,
autoHeight: true,
title: 'Child Configuration Items',
collapsible: true,
titleCollapse: true,
renderTo: target,
rootVisible: false,
store: store,
multiSelect: true,
singleExpand: true,
columns: [
{
type: 'treecolumn',
text: 'CI#',
dataIndex: 'name'},
{
text: 'Type',
dataIndex: 'recordType'}
]
});
});​
The request to json_CIChildren?_dc=1329830854458&node=a0NT0000006tYKzMAM was valid (the parentID in root.id got propagated ok) and came back with valid json:
{ "children" : [
{
"id": "a0NT0000006tswhMAA",
"name": "CI334593834",
"recordType": "Rack",
"ciName": "Empty rack",
"alias": "",
"model": "",
"status": "",
"description": "",
"leaf": "true",
"iconCls": "x4-ciicon-Rack"
},
{
"id": "a0NT0000006tYKuMAM",
"name": "CI2345234",
"recordType": "Service",
"ciName": "Business Connect - Premium",
"alias": "",
"model": "",
"status": "",
"description": "",
"leaf": "true",
"iconCls": "x4-ciicon-Service"
}
]}
What am I doing wrong? Why isn't the treegrid seeing name and recordType fields?
Is this because store only saw NodeInterface-like fields and there is none of my custom data in data property?
I think the problem is your model fields aren't mapped right. The "id" property for each field should be the 'name' property instead.

Left-side navigationView in Sencha Touch Framework (A question about Ext.data.TreeStore)

I want to dynamically set up the left-side navigation menu just like iPad-style.
So, I make some modification on the demo example. You could also visit this official example here.
sink.StructureStore = new Ext.data.TreeStore({
model: 'Demo',
//root: {
// items: sink.Structure
//},
proxy: {
type: 'ajax',
url: 'words.json',
reader: {
type: 'json',
root: 'items'
}
}
});
For easier implementation, I try to get the JSON data from the "words.json".
(Ideally, JSONP type is better...tried, but no luck.)
Here is the content of "words.json":
{
text: 'User Interface',
cls: 'launchscreen',
items: [{
text: 'Buttons',
card: demos.Buttons,
source: 'src/demos/buttons.js',
leaf: true
},
{
text: 'Forms',
card: demos.Forms,
source: 'src/demos/forms.js',
leaf: true
},
{
text: 'List',
card: demos.List,
source: 'src/demos/list.js',
leaf: true
}]
}
It ends up nothing appearing. What's wrong? Do I mistake it? (API here)
What do I want to do?
Like a dictionary, left side are those navigation items of word. On clicking it, the meaning of the word will be showed in right-side view.
I can't run NestedList example in sencha framework. Clicking on the table cell and push another view on it (i.e., in Sencha: NestedList) is what I want to do.
Have tried and no luck:
use the NestedList example
replace proxy with ScriptTagProxy (JSONP)
use easier proxy implementation (showed in the code)
I am not so sure whether my description is clear enough or not, feel free to tell me which part is unclear. And thanks in advance!
If words.json looks like what you have above then that could be your problem.
This is what it should look like.
{
"text": "User Interface",
"cls": "launchscreen",
"items": [{
"text": "Buttons",
"source": "src/demos/buttons.js",
"leaf": true
}, {
"text": "Forms",
"source": "src/demos/forms.js",
"leaf": true
}, {
"text": "List",
"source": "src/demos/list.js",
"leaf": true
}]
}
I've also attached a fully working copy of what you wanted using both a memory proxy (default) and an ajax proxy.
Ext.regApplication({
name: 'test',
launch : function(){
var nL = new Ext.NestedList({
store: test.stores.testTreeStore,
fullscreen: true,
itemTextTpl : '{text}'
});
}
});
Ext.ns('test.data');
test.data.words = {
text: 'User Interface',
cls: 'launchscreen',
items: [{
text: 'Buttons',
source: 'src/demos/buttons.js',
leaf: true
},
{
text: 'Forms',
source: 'src/demos/forms.js',
leaf: true
},
{
text: 'List',
source: 'src/demos/list.js',
leaf: true
}]
};
test.models.testTreeModel = Ext.regModel('testTreeModel', {
fields: ['text','source','card','leaf'],
proxy: {
type: 'memory',
data: test.data.words,
//type: 'ajax',
//url: 'words.json',
reader: {
type: 'json',
root: 'items'
}
}
});
test.stores.testTreeStore = new Ext.data.TreeStore({
model: 'testTreeModel'
});

Categories