I am no JS star so I'm having trouble finding a solution to something that is probably easier than I know.
the page loads, but the ui content stops when it hits the ui code to load the static store data. The preexisting project uses dynamically grabbed data from the database but this just needs a small list of options. (I miss the days of just using HTML). Firebug shows a non-helpful error in ext-all.js that q is undefined, but since that's obfuscated well maintained code I'm sure it's a problem in my code. Do I need to define the proxy for this even if it's static data? Thank you ahead of time!
Here is the model, store, and ui code
//model
Ext.define('HITS.model.ComboBox', {
extend: 'Ext.data.Model',
fields: [
{type: 'string', name: 'label', mapping: 'label'},
{type: 'string', name: 'value', mapping: 'value'}
]
});
//store
Ext.define('HITS.store.ReportType', {
extend: 'Ext.data.Store',
model: 'HITS.model.ComboBox',
storeId:'ReportType',
data: [
{label:'All Tags', value: 'AllTags'},
{label:'Key Findings', value: 'KeyFindings'}
]
});
//ui
<ui:ComboBox
renderTo="ui_report_list"
fieldLabel="Report:"
inputId="reportSelect"
store="ReportType">
The solution had a couple of changes required. The first was the "value" column, which is of course a reserved word in the database(oracle). The other was because I didn't add some prefunction comments for the model that trigger autogenerated code(I hate this practice).
The code here should mostly work but you'd need the model I ended up using. If you check sencha and don't use reserved words you should be ok.
Related
I have several questions about Apostrophe CMS:
Is it possible to add a unique field type in apostrophe-pieces? I can't find a way to do this.
Edit: I noticed that I wasn't specific enough. I want to make sure that there can't be two instances in the database with the same value in an added field. It should be something like an additional id. Is there an option for this? Maybe something like:
addFields: [
{
name: 'secondId',
label: 'Second ID',
type: 'string',
required: true,
unique: true
}
]
I want to access the apostrophe-headless api and get a specific element by passing a certain value of one of the created field types of the correspondent piece in a GET-parameter. Is something like this possible?
For example:
Piece:
module.exports = {
extend: 'apostrophe-pieces',
name: 'article',
label: 'Article',
pluralLabel: 'Articles',
restApi: {
safeFor: 'manage'
},
addFields: [
{
name: 'title',
label: 'Name',
type: 'string',
required: true
},
{
name: 'author',
label: 'Author',
type: 'string',
required: true
}
]
};
Desired api call for getting all articles which have strored "Jon" as author:
http://example.com/api/v1/article?author=Jon
Thank you very much in advance!
Custom field types
You can add custom field types at project level by extending apostrophe-schemas and adding the proper definition. You'll need to add a converter for server-side sanitization and a populator for the front-end of the form field.
You can follow the examples in Apostrophe's schema module, linked are the functions defining a float
https://github.com/apostrophecms/apostrophe/blob/0bcd5faf84bc7b05c51de7331b17f5929794f524/lib/modules/apostrophe-schemas/index.js#L1367
https://github.com/apostrophecms/apostrophe/blob/0bcd5faf84bc7b05c51de7331b17f5929794f524/lib/modules/apostrophe-schemas/public/js/user.js#L991
You would add your definitions in your project level lib/modules/apostrophe-schemas's index.js and public/js/user.js respectively.
Filtering
You can search your piece index for a string like Jon by adding ?search=jon to your query but more likely you want to filter pieces by the value of a join.
If you had piece types article and authors, you could have a joinByOne field in article's schema that lets you relate that article to an author piece. Then, by enabling pieceFilters you could filter directly on those joined properties.
A complete rundown of piecesFilters can be found here https://apostrophecms.org/docs/tutorials/intermediate/cursors.html#filtering-joins-browsing-profiles-by-market
I think you'd also need to mark that filter as safe for api use in your apostrophe-headless configuration https://github.com/apostrophecms/apostrophe-headless#filtering-products
I have a Rally grid that I'm creating using the Rally app builder. Standard grid using the defect model. One of the fields in the defect model is set to hidden in the field setup in the Rally Workspaces and Projects setup. I'd like to dynamically make the field visible in my grid so that it only appears on my grid and not on the defect page when entering a defect. Any ideas on how to do that? Thanks.
This was a pretty tricky one. The grid and board components are hard wired to not show data from hidden fields by default and unfortunately there are not any config properties exposed to turn this behavior off. Here's what I came up with:
this.add({
xtype: 'rallygrid',
columnCfgs: [
'FormattedID',
'Name',
'Owner',
{
text: 'Hidden Field', //set column header text
renderer: function(value, meta, record) {
//return the rendered field data
return record.get('c_HiddenField');
}
}
],
context: this.getContext(),
storeConfig: {
model: 'userstory',
fetch: ['c_HiddenField'] //need to explicitly fetch
}
});
Basically you include a column in your columnCfgs without a dataIndex specified. Set the text and renderer to work with your field.
You'll also need to manually fetch your field in the storeConfig since the grid won't understand how to do it otherwise.
I was trying to asynchronously update a Select field via Memory and ObjectStore. This doesn't work. Setting the data to the Memory object before creating the Select element works fine. Updating the Memory object after creating the Select element doesn't work anymore.
Example code:
require([
"dojo/ready",
"dijit/form/Select",
"dojo/store/Memory",
"dojo/store/Observable",
"dojo/data/ObjectStore",
'dojo/domReady!'
], function(ready, Select, Memory, Observable, ObjectStore, dom){
ready(function() {
var mymem = new Memory();
var myobs = new Observable(mymem);
var mystore = new ObjectStore({ objectStore: myobs });
/* updating memory here works :) */
//mymem.setData([ { id: 2, label: 'qwertz2' }, { id: 3, label: 'qwertz3' } ]);
var s = new Select({
store: mystore
}, 'appsAdminQueueContainer');
s.startup();
/* updating memory here doesn't work :( */
mymem.setData([ { id: 2, label: 'qwertz2' }, { id: 3, label: 'qwertz3' } ]);
});
}
);
Real working example: https://jsfiddle.net/mirQ/ra0dqb63/5/
Is this a bug or is there a solution to be able to update the content of the Select field after creating it - without having to access the Select field directly?
UPDATE
Thank you for your response.
The use of dojo/ready was just a missed leftover while simplifying my code, sorry.
That the use of the ObjectStore is not necessary was not clear to me. Thanks for clearing up.
Okay, the real problem seems to be indeed the last point. I think I have to extend my description.
Updated/extended problem description:
I'm using a grid. At first I was using dojox/grid/DataGrid, but then I switched to dgrid. Everything works well, but I want to use dijit.form.Select as editor for one column. This works also well if the data is static. But in one column I have to read dynamic data from the server. This data comes in JSON format.
First I tried to solve this with the use of dojo/data/ItemFileReadStore - that worked. But it's deprecated and I need to implement a formatter for that column that has to have access to the same JSON data read from the server. I don't have the code for that solution anymore, but it didn't work. I wasn't able to successfully query the data from within the formatter function.
Then I switched to Memory and xhr. The response from the server comes after the Memory object is created (and, as it seems, after creating the Select), so I had to use setData to bring my loaded data in the store. And because the Select is only an editor of a grid, I don't have access to the object itself to be able to re-set the store after updating the data.
I hope my extended description makes my real problem a bit clearer. Thanks in advance for your help!
Mirko
This works for me:
require([
'dijit/form/Select',
'dojo/store/Memory',
'dojo/store/Observable',
], function (Select, Memory, Observable) {
var mymem = new Memory({
data: [{
id: 2,
label: 'qwertz2'
}, {
id: 3,
label: 'qwertz3'
}]
});
var myobs = new Observable(mymem);
var s = new Select({
labelAttr: 'label',
store: myobs
}, 'appsAdminQueueContainer');
s.startup();
myobs.add({ id: 4, label: 'qwerty' });
});
Notable changes:
There's no reason to use dojo/ready in this code. The require callback already waits for modules to load, and as long as this script is at the bottom of the body, there's no need to wait for the DOM to load, either.
There's no need to use a dojo/data store adapter. dijit/form/Select supports dojo/store as well (as of 1.8 if I recall correctly). This might also have been why observation wasn't working. The only difference is labelAttr must be specified on the Select since dojo/store has no concept of a label property.
(Edit) now that I re-read the question, I notice you are calling setData. setData does not fire observers. setData completely resets the store's data, and to reflect that, you would need to actually reset the store on the select entirely (which requires calling setStore, not set('store', ...), if you are using 1.9 or earlier, because Select was never updated properly to support the set API until 1.10).
(Edit #2) Given that the primary reason you are calling setData is due to creating the store before actually having data for it, your case would probably be greatly simplified by using the RequestMemory store implementation from dojo-smore. It basically re-adds the url support that dojo/data/ItemFileReadStore had but dojo/store/Memory didn't.
Could someone please explain how the insert works to add a record in a datastore
with tha fields: "title", "info" and "price"?
because i tried some things and none of them work. and the sencha website doesnt make it very clear.
Adding a new item to an existing Store isn't that hard actually.
First of you will need to configure your model and store. In your question you name the fields 'title, 'info' and 'price'.
Model:
Ext.regModel('myModel', {
fields: [
{name: 'id', type: 'int' },
{name: 'title', type: 'string' },
{name: 'info', type: 'string' },
{name: 'price', type: 'int' }
]
});
Next you configure the store that will hold the data, based on the above model. I think that, in your case, it should be a model without any data preloaded via, for example, JSON?
So lets make a localstorage (empty store). The Store consists of the model (myModel), you give it a storeID (so that you can later on reference the store by this ID). The proxy is localstorage and the unique ID of the Store will be the ID field of the Model.
Store:
var myStore = new Ext.data.Store({
model: "myModel",
storeId: "myStoreID",
proxy: {
type: "localstorage",
id: "id"
}
});
Now, suppose you have some kind of Form (in which the user can add input a title, info and price, and you want to add these items to the existing store on submittal.
Within the handler of the submittal button you now have to 'call' the store, and perform the add function on it. Within this add function you will have to define the params (the model params) and the data to insert.
Below I have used a mixture of fixed data and a variable to insert.
myStoreID.add({ title: "Mijn Titel", info: "Informatie, price: prijsvar });
The store will now be filled will now be filled with an extra data-record which you can use. Lets say for example that the store is attached to a dataview, then you can perform:
dataView.update();
The above isn't a full tutorial, but I think this will help you along?
Just an update of the YDL answer.
As per the dataView should be related to the updated store, the last sentence dataView.update() should not be needed, due to the automatic update of the views related to a store when it change.
new Ext.DataView({
store: MyStore,
itemSelector: 'div.thumb',
tpl: thumbTpl
});
later, if I do the following, the new item should be displayed in views (List, DataView, etc.) that have MyStore as store.
MyStore.add(newItem);
HTH.
Milton RodrÃguez.
If you are trying to pass in an object that was returned from a getValue() on your form, make sure that you run a
myStore.sync();
after you have called the add() method, or you wont see it in your browsers local store.
It is Very easy try these
// first get those values and store in locally
var A_select1=Ext.getCmp('select1').getValue(); // get value
localStorage.setItem("Adult1_select1",A_select1); // set localStore
var AdultSalutation={
'Adult1_select1':A_select1, // assign the value
};
var AdultSalutationstore = Ext.getStore('Adult_AdultSalutationstore'); // get store
AdultSalutationstore.add(AdultSalutation); // add object
AdultSalutationstore.sync(); // sync
AdultSalutationstore.load(); // load
I've set up a WCF service to provide table data in JSON:
{
"d":{
"__type":"ExtJsDataResults:#MyProject.WebServices",
"rows":[
["TitleA","1.98","English"],
["TitleB","1.98","Spanish"],
["TitleC","1.98","Korean"]
],
"totalcount":10
}
}
How to read this into an ExtJS Store? I need a JsonStore to begin with, but then an ArrayReader-type type interpret the row data. Something like this:
var itemStore = new Ext.data.JsonStore({
proxy: new Ext.data.HttpProxy({
url: "../WebServices/ItemsService.svc/getData",
method: "GET"
}),
root: "d.rows",
totalProperty: "d.totalcount",
fields: ['Book Title', 'Unit Price', 'Language'],
reader: new Ext.data.ArrayReader({},
Ext.data.Record.create([
{name:'Book Title'},
{name:'Unit Price'},
{name:'Language'}
])
)
});
Of course, this doesn't work. When bound to a DataGrid w/ a paging toolbar, it displays blank rows, but the correct number of them, and the paging toolbar values are all correct.
Any ideas?
FIXED. Changed to a regular Store and added the "root" and "totalProperty" values to the config object of the ArrayReader.
cf. this Sencha Forum thread
I was also facing this problem but got through with this solution -
http://dotnetkeeda.blogspot.in/2013/11/working-with-sencha-extjs-and-wcf.html
Nice and important tips thanks to the author.