I want to get container data dynamically. Can any one help me to display the container items dynamically. The date or store url may be some external page, I want to get the container store/date using MVC. Can any help me?
Below is my code
Ext.define('Mvcapp.view.LayoutList',{
extend: 'Ext.Container',
xtype: 'layoutlist',
config:{
title: 'Layout',
iconCls:'star',
styleHtmlContent: true,
items:[{
data: [{
fname: 'Stratton',
lname: 'Sclavos',
role: 'Executive Chairman'
}, {
fname: 'Michael',
lname: 'Mullany',
role: 'CEO'
}, {
fname: 'Ted',
lname: 'Driscoll',
role: 'Vice President Worldwide Sales'
}, {
fname: 'Abraham',
lname: 'Elias',
role: 'Chief Technical Officer'
}, {
fname: 'Jeff',
lname: 'Hartley',
role: 'Vice President of Services and Training'
}, {
fname: 'Adam',
lname: 'Mishcon',
role: 'Vice President of Operations'
}, {
fname: 'Judy',
lname: 'Lin',
role: 'Vice President of Engineering'
}], // data
tpl: '<tpl for="."><div style="float:left;width:300px;"><strong>{lname}</strong>, {fname} <em class="muted">({role})</em></div></tpl>'
}]
}
});
Things you need to do is, first define a model having required fields. Next create a store and set model config to previously defined. While defining the store you need to choose from various proxies sencha touch has give. If you are building app that is to be built for mobile phones then there's not much choice to make. You simply have to use JsonP proxy.
Here's what I'd do -
var listitem=Ext.define('ListItem', {
extend: 'Ext.data.Model',
config: {
fields: ['fname','lname','role']
}
});
var store = Ext.create('Ext.data.Store', {
model: listitem,
autoLoad: true,
proxy: {
type: 'jsonp',
url: 'http://localhost/json_feed_url.php',
reader: {
type: 'json',
rootProperty: 'data'
}
}
});
var myList = Ext.create('Ext.List', {
styleHtmlContent:true,
store:store,
itemTpl:['<div style="float:left;width:300px;"><strong>{lname}</strong>, {fname} <em class="muted">({role})</em></div>']
});
Ext.Viewport.add(myList);
As you can see, i first defined model for our store. Store is created using JsonP proxy and it is set to load automatically. I've also set up reader, that will read the response received from server and parse it. I don't have to worry about it anymore now because all I've to do it just set the rootPropery.
Next a list is created and previously defined store is assigned in it's config. So whenever this piece of code is run, store will get data from server and display it in list. Guess that's what you want.
To start, just put this piece inside launch method of your app.js and you're good to go. In case you want php code here's it -
<?php header('Content-type:application/javascript');
$items =array();
$items[] = array('fname'=>'A','lname'=>'B','role'=>1);
$items[] = array('fname'=>'C','lname'=>'D','role'=>2);
$items[] = array('fname'=>'E','lname'=>'F','role'=>3);
$items[] = array('fname'=>'G','lname'=>'H','role'=>4);
$items[] = array('fname'=>'I','lname'=>'J','role'=>5);
print $_GET['callback'].'('.json_encode(array('data'=>$items)) .')';
?>
I'm familiar with php n all, but you can use whatever suits you. Idea is same. :D
Related
Fiddle with the problem is here https://fiddle.sencha.com/#view/editor&fiddle/2o8q
There are a lot of methods in the net about how to locally filter grid panel that have paging, but no one is working for me. I have the following grid
var grid = Ext.create('Ext.grid.GridPanel', {
store: store,
bbar: pagingToolbar,
columns: [getColumns()],
features: [{
ftype: 'filters',
local: true,
filters: [getFilters()],
}],
}
Filters here have the form (just copy pasted part of my filters object)
{
type: 'string',
dataIndex: 'name',
active: false
}, {
type: 'numeric',
dataIndex: 'id',
active: false
},
The store is the following
var store = Ext.create('Ext.data.Store', {
model: 'Store',
autoLoad: true,
proxy: {
data: myData,
enablePaging: true,
type: 'memory',
reader: {
type: 'array',
}
},
});
Here myData - comes to me in the form of
["1245", "Joen", "Devis", "user", "", "email#com", "15/6/2017"],
["9876", "Alex", "Klex", "user", "", "email#com", "15/6/2017"],[...
Also I have the the pagingToolbar
var pagingToolbar = Ext.create('Ext.PagingToolbar', {
store: store, displayInfo: true
});
So all the elements use the store I declared in the top. I have 25 elements per grid page, and around 43 elements in myData. So now I have 2 pages in my grid. When I am on first page of grid and apply string filter for name, for example, it filters first page (25 elements), when I move to 2d page, grid is also filtered, but in scope of second page. So as a result each page filters seperately. I need to filter ALL pages at the same time when I check the checkbox of filter, and to update the info of pagingToolbar accordingly. What I am doing wrong?
Almost sure that it is a late answer, but I have found the local store filter solution for paging grid you are probably looking for:
https://fiddle.sencha.com/#fiddle/2jgl
It used store proxy to load data into the grid instead of explicitly specify them in store config.
In general:
create empty store with next mandatory options
....
proxy: {
type: 'memory',
enablePaging: true,
....
},
pageSize: 10,
remoteFilter: true,
....
then load data to the store using its proxy instead of loadData
method
store.getProxy().data = myData;
store.reload()
apply filter to see result
store.filter([{ property: 'name', value: 'Bob' }]);
See President.js store configuration in provided fiddle example for more details.
Hope it helps
I have a complex JSON response that is iterated over using ng-repeat. Only a relatively small subset of the attributes within the result set are displayed on the screen, so filtering of the results should be restricted to values the user can actually see, otherwise the filtering behavior would be confusing to the end-user.
Since one of the attributes I wish to filter on is a deeply nested array, a custom filter was needed since the built-in AngularJS filterFilter does not iterate over the array elements to the best of my knowledge.
I was able to get this working some time back in AngularJS v1.2.28, but unfortunately it appears to break during a migration to v1.4.3. I have not spent time to isolate where in the release cadence this functionality broke however.
I have not found any helpful information in the migration guides that would indicate what has changed. All I know is that the actual/expected parameters to the filter receive different values in the latest major version of AngularJS, which leads to the failure.
ng-repeat filter expression:
<li ng-repeat="user in users | list_filter:{establishment: {id: filterText, names: [{name: filterText}], locations: [{streetAddress1: filterText, streetAddress2: filterText, city: filterText, stateProvince: filterText, postalCode: filterText}]}}">
Example data structure of a single element:
data = [{
id: 234567,
name: 'John Doe',
establishment: {
id: 067915959,
locations: [{
id: '134B030365F5204EE05400212856E994',
type: 'postal',
streetAddress1: 'P O BOX 900',
city: 'Grover',
stateProvince: 'CA',
postalCode: '902340900',
isoCountryCode: 'US',
region: 'MONROE'
}, {
id: '999B030365F4204EE05400212856E991',
type: 'postal',
streetAddress1: '2590 Atlantic Ave',
city: 'Fredricks',
stateProvince: 'VA',
postalCode: '45487',
isoCountryCode: 'US',
region: 'MONROE'
}],
names: [{
name: 'Grover Central School Dst',
type: 'PRIMARY'
}, {
name: 'Grover Central School Dst',
type: 'MARKETING'
}, {
name: 'Grover CENTRAL SCHOOL DISTRICT',
type: 'LEGAL'
}]
}
}];
Supporting Plunker Examples:
Plunker for version 1.2.28:
http://plnkr.co/edit/KD1MmNMBEhO7X2v9yK4S?p=info
Plunker for version
1.4.3: http://plnkr.co/edit/OmPOOwRWCHuPutUtWOcC?p=info
Edit:
The issue appears to be directly related to the changes introduced in v1.3.6.
It appears the issue is related to the fact that an implicit AND condition is now being applied but was previously an implicit OR, which is what is desired in my case. You can import the old version as a separate filter, if the old behavior is desired.
I am using JSONIX for marshalling and unmarshalling XML files. So far it works pretty well. What I am missing is the possibility to get default values and restrictions like minOccours and maxOccours-Values. Is this somehow possible with JSONIX?
These properties:
<xsd:sequence>
<xsd:element name="inflowMin" type="framework:flowType" minOccurs="0" maxOccurs="1"/>
<xsd:element name="inflowMax" type="framework:flowType" minOccurs="0" maxOccurs="1"/>
<xsd:element name="unitOfFlowControl" type="framework:flowUnit" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
<xsd:attribute name="waterCosts" type="xsd:double" default="0.0"/>
<xsd:attribute name="controllable" type="xsd:boolean" default="0"/>
<xsd:attribute name="scalingOfControl" type="xsd:double" default="1.0" />
Get:
propertyInfos: [{
type: 'element',
name: 'inflowMin',
elementName: 'inflowMin',
typeInfo: ...
}, {
type: 'element',
name: 'inflowMax',
elementName: 'inflowMax',
typeInfo: ...
}, {
type: 'element',
name: 'unitOfFlowControl',
elementName: 'unitOfFlowControl',
typeInfo: 'String'
}, {
name: 'waterCosts',
typeInfo: 'Double',
attributeName: 'waterCosts',
type: 'attribute'
}, {
name: 'controllable',
typeInfo: 'Boolean',
attributeName: 'controllable',
type: 'attribute'
}, {
name: 'scalingOfControl',
typeInfo: 'Double',
attributeName: 'scalingOfControl',
type: 'attribute'
}]
}
Thanks!
The feature you requested is now implemented in Jsonix 2.3.2 and Jsonix Schema Compiler 2.3.7.
Jsonix Schema Compiler now produces required, minOccurs and maxOccurs in the generated mappings and the JSON schema.
This is how it looks in the mappings:
{
localName: 'Items',
propertyInfos: [{
name: 'item',
minOccurs: 0,
maxOccurs: 100,
collection: true,
elementName: {
localPart: 'item'
},
typeInfo: '.Items.Item'
}]
}
And in the JSON Schema:
"Items":{
"type":"object",
"title":"Items",
"properties":{
"item":{
"title":"item",
"allOf":[
{
"type":"array",
"items":{
"$ref":"#/definitions/Items.Item"
},
"maxItems":100,
"minItems":0
}
],
"propertyType":"element",
"elementName":{
"localPart":"item",
"namespaceURI":""
}
}
},
"typeType":"classInfo",
"typeName":{
"localPart":"Items",
"namespaceURI":""
},
"propertiesOrder":[
"item"
]
}
You can access this metadata from the Jsonix context as follows:
var context = new Jsonix.Context([ PO ]);
var itemsClassInfo = context.getTypeInfoByName("PO.Items");
var itemPropertyInfo = itemsClassInfo.getPropertyInfoByName("item");
test.equal(false, itemPropertyInfo.required);
test.equal(0, itemPropertyInfo.minOccurs);
test.equal(100, itemPropertyInfo.maxOccurs);
test.done();
Disclaimer: I'm the author.
At the moment not, this information is not generated yet. There was this issue back then, but it was not implemented.
If you're interested in this functionality, please file two issues here (one for the default value and the other one for minOccurs/maxOccurs).
In principle, this information is available from the XML Schema, but in some cases it is not clearly mappable to the generated model. In a few weird cases like repeatable choice or sequence this won't work, but in most cases it will. So it is implementable, please file the issues.
Do you just need these things in the generated mappings? Or some kind of API to access it?
I have a form that is suposed to help to user to choose a specific thing at the end, but as the user fills the first options, the others below change. Something like this:
Type:
{
t1:{
Number of X:{
1:{...}
2:{...}
}
Number of Y:{...}
}
t2:{
Number of X:{
100:{...}
200:{...}
}
Number of Y:{...}
}
}
The user has the field Type with the options t1 and t2, when they choose t1, the field "Number of X" will be filled with 1 and 2, if they choose t2, the field "Number of X" will be filled with 100 and 200, and so on. Some of the choices depend on more than one field, its not straight down dependency (something like, if the user chooses "Number of X" = 100 then Foo is "A", else, Foo can be "A", "B" or "C", but Foo is not bellow "Number of X").
I tried a really naive implementation where I would set up event listeners on every field and see their changes, but eventually the code started growing out of control and I have a bunch of $("#foo").change(function(){...}); and its not imediatly obvious that the field listening to this is bar and not fbar.
I also tried JSON (as the example above), but there's a lot of repetition, the deeper the tree grows and the number of possibilites increase, I have to write the same fields again and again. Sometimes choosing t1 will change an option directly even though its not directly bellow it, and even though it usually depends on another field entirely, and that's more repetition in JSON.
How do I approach this problem? Is there a readable solution? Too much code is not the problem, as long as one can look at the code and understand the dependencies and their effects.
A code example (kinda like my code right now):
HTML:
<select id="type">
<option value=1>a</option>
<option value=2>b</option>
</select>
<select id="numOfX">
</select>
<select id="numOfY">
</select>
js:
$("#type").change(function()
{
if($("#type").val() == 1)
{
$("#numOfX").append(new Option(1, "1", false, false));
$("#numOfX").append(new Option(2, "2", false, false));
}
else if($("#type").val() == 2)
{
$("#numOfX").append(new Option(1, "100", false, false));
$("#numOfX").append(new Option(2, "200", false, false));
}
});
$("#numOfX").change(function()
{
...
});
Update - Add example
Have you try backbone.js library? It will make the Javascript code more manageable by adding models & structures. There is a learning curve though but it is really great. Once you learn Backbone, you can make use of the Backbone Forms plugin which will help in the dropdown management. Below is the demo link & sample code:
Example 1
$(function() {
var cities = {
'UK': ['London', 'Manchester', 'Brighton', 'Bristol'],
'USA': ['London', 'Los Angeles', 'Austin', 'New York']
};
var subAreas = {
'London' : ['L1', 'L2', 'L3', 'L4'],
'Manchester' : ['M1', 'M2', 'M3', 'M4'],
'Brighton' : ['B1', 'B2', 'B3', 'B4'],
'Bristol' : ['BR1', 'BR2', 'BR3', 'BR4'],
'Los Angeles' : ['LA1', 'LA2', 'LA3', 'LA4'],
'Austin' : ['A1', 'A2', 'A3', 'A4'],
'New York' : ['NY1', 'NY2', 'NY3', 'NY4']
};
//The form
var form = new Backbone.Form({
schema: {
country: { type: 'Select', options: ['UK', 'USA'] },
city: { type: 'Select', options: cities.UK },
subArea: { type: 'Select', options: subAreas[cities.UK[0] ] }
}
}).render();
form.on('country:change', function(form, countryEditor) {
var country = countryEditor.getValue(),
newOptions = cities[country];
form.fields.city.editor.setOptions(newOptions);
var city = newOptions[0],
areaOptions = subAreas[city];
form.fields.subArea.editor.setOptions(areaOptions);
});
form.on('city:change', function(form, cityEditor) {
var city = cityEditor.getValue(),
newOptions = subAreas[city];
form.fields.subArea.editor.setOptions(newOptions);
});
//Add it to the page
$('body').append(form.el);
});
Example 2
$(function() {
var cities = {
'UK': ['London', 'Manchester', 'Brighton', 'Bristol'],
'USA': ['London', 'Los Angeles', 'Austin', 'New York']
};
var subAreas = {
'UK.London' : ['L1', 'L2'],
'USA.London' : ['L3', 'L4'],
'UK.Manchester' : ['M1', 'M2', 'M3', 'M4'],
'UK.Brighton' : ['B1', 'B2', 'B3', 'B4'],
'UK.Bristol' : ['BR1', 'BR2', 'BR3', 'BR4'],
'USA.Los Angeles' : ['LA1', 'LA2', 'LA3', 'LA4'],
'USA.Austin' : ['A1', 'A2', 'A3', 'A4'],
'USA.New York' : ['NY1', 'NY2', 'NY3', 'NY4']
};
var hashFunc = function(country, city){
return country + "." + city;
};
//The form
var form = new Backbone.Form({
schema: {
country: { type: 'Select', options: ['UK', 'USA'] },
city: { type: 'Select', options: cities.UK },
subArea: { type: 'Select', options: subAreas[ 'UK.London' ] }
}
}).render();
form.on('country:change', function(form, countryEditor) {
var country = countryEditor.getValue(),
newOptions = cities[country];
form.fields.city.editor.setOptions(newOptions);
var city = newOptions[0],
areaOptions = subAreas[hashFunc(country, city) ];
form.fields.subArea.editor.setOptions(areaOptions);
});
form.on('city:change', function(form, cityEditor) {
var city = cityEditor.getValue(),
newOptions = subAreas[hashFunc(form.getValue().country, city)];
form.fields.subArea.editor.setOptions(newOptions);
});
//Add it to the page
$('body').append(form.el);
});
As you also develop for mobile (probably Phonegap), you can also try ZeptoJS as an alternative for jQuery. It will improve the speed alot.
The task outlined is complex because of dependencies, so you must think of the ways to define your dependencies. Here is one way I would do it:
Define models which handle data.
Define dependencies.
Manage dependencies.
Below you can see a conceptual model how I see this all implemented (at the end of my answer I describe things which are not provided in this pseudo code):
//data/model structure for Type.
var type = {
//list all values.
values: [
{ id: 1, text: 't1', visible: true },
{ Id: 2, text: 't2', visible: true }
],
//evaluates visibility of item using dependencies.
//depends on nothing, so takes no arguments except item.
evaluate: function(item) {
return; //depends on nothing.
},
// this event fires when selected item changes.
onChange: event
};
//data/model structure for number of X.
var numberOfX = {
//list all values.
values: [
{ id: 1, text: '1', visible: true },
{ id: 2, text: '2', visible: true },
{ id: 3, text: '100', visible: true },
{ id: 4, text: '200', visible: true }
],
//evaluates visibility of item using dependencies.
//since numberOfX depends on Type, it takes type as second argument.
//it would take more arguments if it depended on other things too.
evaluate: function(item, type) {
// next line will fire onChange event.
item.visible =
( [1,2].indexOf(item.id) >=0 && type.id == 1 ) ||
( [3,4].indexOf(item.id) >=0 && type.id == 2 );
},
// this event fires when selected item changes.
onChange: event
};
//data/model structure for number of Y.
var numberOfY = { /* omitted. This is similar to the previous ones */ }
//numberOfX depends on Type.
//if it depended on more objects, then we would pass them as additional arguments.
register_dependency(numberOfX, type);
//numberOfY depends on Type.
register_dependency(numberOfY, type);
//... etc: define other dependencies.
Event mechanism is not there in JavaScript, but implementing one is not hard. You can use some framework for that as well.
register_dependency function builds a graph of dependencies simply by registering for events, as described below (managing dependencies):
When onChange event fires on any model, evaluate is called for each item in the dependency tree. For example, when type.onChange fires, we have numberOfX and numberOfY objects. Their values array is enumerated in loop and evaluate is called for each item (passing item and type as arguments).
Conclusion: although this code seems complex, still it's more self-descriptive and allows to have graph of dependencies between multiple objects on the page. Also, all the complexity lays on the toolkit/framework level, which could be easily re-used when implemented only once.
EDIT: Forgot to outline that you would need to have some mechanism to bind to this kind of model and show it on the page, which is also trivial. For example, have a look at knockout.js.
I am trying to interact with a javascript api (bare in mind I have never done this before). An example of what I am attempting to work with is here:
SearchSpring.Catalog.init({
leaveInitialResults : true,
facets : '.leftNav',
results : '#results',
result_layout: 'list',
results_per_page : 12,
layout: 'top',
loadCSS: false,
filters: {
color: ['Blue']
},
backgroundFilters: {
category: ['Shirt', 'Shoes'],
department: ['Mens']
},
maxFacets: 5,
maxFacetOptions: 10,
sortText: 'Sort By ',
sortType: 'dropdown',
filterText: 'Refine Search Results',
previousText: 'Previous',
scrollType: 'scroll',
scrollTo: 'body',
backgroundSortField: 'price',
backgroundSortDir: 'desc',
compareText: 'Compare Items',
summaryText: 'Current Filters',
showSummary: true,
subSearchText: 'Subsearch:',
showSubSearch: true,
forwardSingle: false,
afterResultsChange: function() { $('.pagination').hide(); },
filterData: function(data) { console.debug(data); }
});
In the example I want to add a "backgroundFilter" to this with a value:
var cat="MyNewCategory";
cat.value="ANewValue;
How would I add this category and value to the backgroundFilters: listed above?
This is a very common framework initialization pattern when working with frameworks.
Your example code is passing a JavaScript Object {} as a parameter into a function () that is called init.
Taking out all definitions the pattern looks like this:
SomeFramework.frameworkFunction({});
In the above code the {} is an empty object used for initialization. There are two ways that you can work with that object in practice.
Regarding your first code snippet, you can add code into that 'object literal'.
backgroundFilters: {
category: ['Shirt', 'Shoes'],
department: ['Mens'],
cat: ['My value']
},
Notice the added comma, this is an important tripping point. This may or may not fit your needs, depending on a few factors.
Regarding your second code snippet, you can apply members to JavaScript objects at runtime. What I mean is, your var cat can be added to the anonymous object-literal that is being passed in. Hard to say, but a simple concept. Here is how:
//Say this is initialized in some separate way. //There is a bug here I'll describe later.
var cat="MyNewCategory";
cat.value="ANewValue";
//Extract and name the initialization object. It is verbatim at this point.
var initObject = {
leaveInitialResults : true,
facets : '.leftNav',
results : '#results',
result_layout: 'list',
results_per_page : 12,
layout: 'top',
loadCSS: false,
filters: {
color: ['Blue']
},
backgroundFilters: {
category: ['Shirt', 'Shoes'],
department: ['Mens']
},
maxFacets: 5,
maxFacetOptions: 10,
sortText: 'Sort By ',
sortType: 'dropdown',
filterText: 'Refine Search Results',
previousText: 'Previous',
scrollType: 'scroll',
scrollTo: 'body',
backgroundSortField: 'price',
backgroundSortDir: 'desc',
compareText: 'Compare Items',
summaryText: 'Current Filters',
showSummary: true,
subSearchText: 'Subsearch:',
showSubSearch: true,
forwardSingle: false,
afterResultsChange: function() { $('.pagination').hide(); },
filterData: function(data) { console.debug(data); }
};
//Now we can add variables (and functions) dynamically at runtime.
initObject.cat = cat;
//And pass them into the framework initialization in a separated way.
SearchSpring.Catalog.init(initObject);
Now for the bug. I don't know the solution because I do not know what it is intended to do, but I can point out what is potentially incorrect.
var cat="MyNewCategory";
cat.value="ANewValue;
This code is: 1 creating a String Object called cat. 2 changing the value to a new string.
I do not think this is what you really want.
To add a new backgroundFilter, in the separated way above, it would be:
initObject.backgroundFilters.cat = ['A', 'B'];
//Line above would give you this type of definition within the initObject (at runtime):
backgroundFilters: {
category: ['Shirt', 'Shoes'],
department: ['Mens'],
cat: ['A','B']
},
For this to work it will depend on what the framework is expecting regarding backgroundFilters.
Hope that helps.
All the best!
Nash
I don't quite understand - do you want to have the backgroundFilters categories as structured objects rather than plain strings? If you are in control of the entire API, you can do something like
...
backgroundFilters: {
category: [
new SearchSpring.Catalog.Category("Shirt"),
new SearchSpring.Catalog.Category("Shoes"),
new SearchSpring.Catalog.Category("MyNewCategory", "ANewValue")
],
department: 'Mens'
}
...