I have to comboboxes. One of them contains regions and other contains cities. I want to achieve the wollowing behavior: when any region is selected in first combobox, avaliable cities in second combobox also change.
For example if I select Region1 in first combobox, then second combobox will contain CityA and CityB. If I select Region 2, second combobox will contain CityD, CityE and CityF.
I hope it was rather clear :)
I tried to solve it myself using closure style, but my code has an issue: combobox remains masked even when all cities are loaded. Does anyone know how to settle this problem?
Cities combobox code:
var setFilterRegion;
function getCityField() {
var citiesPerPage = 10;
var citiesProxy = Ext.create('Ext.data.proxy.Ajax', {
url: 'service/cities-data.php',
reader: Ext.create('Ext.data.reader.Json', {
root: 'cities',
totalProperty: 'totalCount'
})
});
setFilterRegion = function(regionId) {
citiesProxy.extraParams['region_id'] = regionId;
};
var cities = Ext.create('Ext.data.Store', {
pageSize: citiesPerPage,
model: 'City',
proxy: citiesProxy,
sorters: [{
property: 'name',
direction: 'ASC'
}]
});
var citiesComboBox = Ext.create('Ext.form.ComboBox', {
fieldLabel: 'Город',
store: cities,
displayField: 'name',
valueField: 'id',
listConfig: {
loadingText: 'Загрузка...',
emptyText: 'Нет городов с похожим названием'
},
pageSize: citiesPerPage,
labelWidth: contactInfo.labelWidth,
width: contactInfo.width
});
cities.loadPage(1);
return citiesComboBox;
}
Regions combobox code:
function getRegionField() {
var regionsPerPage = 10;
var regions = Ext.create('Ext.data.Store', {
pageSize: regionsPerPage,
model: 'Region',
proxy: Ext.create('Ext.data.proxy.Ajax', {
url: 'service/regions-data.php',
reader: Ext.create('Ext.data.reader.Json', {
root: 'regions',
totalProperty: 'totalCount'
})
}),
sorters: [{
property: 'name',
direction: 'ASC'
}]
});
var regionsComboBox = Ext.create('Ext.form.ComboBox', {
fieldLabel: 'Регион',
store: regions,
displayField: 'name',
valueField: 'id',
listConfig: {
loadingText: 'Загрузка...',
emptyText: 'Нет регионов с похожим названием'
},
pageSize: regionsPerPage,
labelWidth: contactInfo.labelWidth,
width: contactInfo.width
});
regions.loadPage(1);
return regionsComboBox;
}
Interaction code:
var regionField = getRegionField();
var cityField = getCityField();
var phoneField = getPhoneField();
regionField.on('change', function(t, newVal){
setFilterRegion(newVal);
cityField.getStore().loadPage(1);
});
Артём, take a look at his example, I think it's exactly what you need:
http://extjs.wima.co.uk/example/1
Elegant solution was found in this article:
http://www.learnsomethings.com/2011/05/17/where-did-setextraparam-aka-setbaseparam-go-in-extjs-4-%E2%80%93-one-workaround/
Related
I am trying to get the label for the combobox to show correctly in the example below. I am trying to get it to work in Sencha Fiddle. The text if too long, is getting truncated.
Ext.application({
name : 'Fiddle',
launch : function() {
// The data store containing the list of states
var states = Ext.create('Ext.data.Store', {
fields: ['abbr', 'name'],
data : [
{"abbr":"AL", "name":"Alabama"},
{"abbr":"AK", "name":"Alaska"},
{"abbr":"AZ", "name":"Arizona"}
//...
]
});
// Create the combo box, attached to the states data store
Ext.create('Ext.form.ComboBox', {
fieldLabel: 'Reaaaaaaaaaaaaaaallllllllly long',
fieldlabelStyle: 'width:600px',//doesn't do anything
store: states,
queryMode: 'local',
displayField: 'name',
valueField: 'abbr',
renderTo: Ext.getBody()
});
}
});
Try with labelStyle
Ext.application({
name : 'Fiddle',
launch : function() {
// The data store containing the list of states
var states = Ext.create('Ext.data.Store', {
fields: ['abbr', 'name'],
data : [
{"abbr":"AL", "name":"Alabama"},
{"abbr":"AK", "name":"Alaska"},
{"abbr":"AZ", "name":"Arizona"}
//...
]
});
// Create the combo box, attached to the states data store
Ext.create('Ext.form.ComboBox', {
fieldLabel: 'Reaaaaaaaaaaaaaaallllllllly long',
labelStyle: 'width:600px',
//fieldlabelStyle: 'width:600px',//doesn't do anything
store: states,
queryMode: 'local',
displayField: 'name',
valueField: 'abbr',
renderTo: Ext.getBody()
});
}
});
Use labelWidth: config for this. Define like this
labelWidth: '60%',
I see that Hierarchical trees are labeled as experimental on the Rally site (https://help.rallydev.com/apps/2.0rc3/doc/#!/api/Rally.ui.grid.TreeGrid). I wanted to build an app using the hierarchical tree and I had a few questions about the features. Is it possible to filter the tree or no? Also can i add up the totals of the tasks for a given userstory (estimate, todo, actual, etc) and list that total as the userstory value? Is there another way to get a list of the userstories with the tasks in a list beneath it?
A not-treegrid example: this app that uses group and summary features in a grid of tasks in current iteration grouped by workproduct (user story), where Estimate values of individual tasks are summed up. Full code is in this github repo.
launch: function() {
var that = this;
var today = new Date().toISOString();
var stories = Ext.create('Rally.data.wsapi.Store', {
model: 'UserStory',
fetch: ['Tasks'],
filters: [
{
property: 'Iteration.StartDate',
operator: '<=',
value: today
},
{
property: 'Iteration.EndDate',
operator: '>=',
value: today
}
]
});
stories.load().then({
success: this.loadTasks,
scope: this
}).then({
success:function(results) {
that.makeGrid(results);
},
failure: function(){
console.log("oh noes!")
}
});
},
loadTasks: function(stories){
console.log("load tasks",stories)
var promises = [];
_.each(stories, function(story){
var tasks = story.get('Tasks');
if (tasks.Count > 0) {
tasks.store = story.getCollection('Tasks',{fetch:['Name','FormattedID','Estimate','State','Blocked','WorkProduct']});
promises.push(tasks.store.load());
}
});
return Deft.Promise.all(promises);
},
makeGrid: function(results){
var tasks = _.flatten(results);
var data = [];
_.each(tasks, function(task){
data.push(task.data);
})
_.each(data, function(record){
record.Story = record.WorkProduct.FormattedID + " " + record.WorkProduct.Name;;
})
this.add({
xtype: 'rallygrid',
showPagingToolbar: true,
showRowActionsColumn: true,
editable: false,
store: Ext.create('Rally.data.custom.Store', {
data: data,
groupField: 'Story',
}),
features: [{ftype:'groupingsummary'}],
columnCfgs: [
{
xtype: 'templatecolumn',text: 'ID',dataIndex: 'FormattedID',width: 100,
tpl: Ext.create('Rally.ui.renderer.template.FormattedIDTemplate'),
summaryRenderer: function() {
return "Estimate Total";
}
},
{
text: 'Name',dataIndex: 'Name',
},
{
text: 'State',dataIndex: 'State',xtype: 'templatecolumn',
tpl: Ext.create('Rally.ui.renderer.template.ScheduleStateTemplate',
{
states: ['Defined', 'In-Progress', 'Completed'],
field: {
name: 'State'
}
})
},
{
text: 'Estimate',dataIndex: 'Estimate',
summaryType: 'sum',
},
{
text: 'WorkProduct',dataIndex: 'WorkProduct',
renderer: function(val, meta, record) {
return '' + record.get('WorkProduct').FormattedID + '';
}
},
]
});
}
Update: If you want to filter the task store include a filter here:
tasks.store = story.getCollection('Tasks',{fetch:['Name','FormattedID','Estimate','State','Blocked','WorkProduct'],filters:{property: 'State',operator: '<',value: 'Completed'}});
A treegrid example: Rally.ui.grid.TreeGrid you referred is still a work in progress. I have not seen a working example of a story hierarchy using a treegrid but it does not mean it's impossible.
When I tested a story hierarchy, child stories did not appear under epic stories, however a story/task hierarchy worked. The filtering worked too. Here is an example:
Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
launch:function(){
Ext.create('Rally.data.wsapi.TreeStoreBuilder').build({
models: ['userstory'],
autoLoad: true,
filters:[
{
property: 'Name',
operator: 'contains',
value: 'story'
}
],
enableHierarchy: true
}).then({
success: function(store) {
var grid = Ext.create('Ext.Container', {
items: [{
xtype: 'rallytreegrid',
columnCfgs: [
'Name',
'Owner'
],
store: store
}]
});
that.add(grid);
}
});
}
The screenshot below shows that tasks are nested under a child story as expected,but the child story is not nested under parent. The grid is filtered by Name as expected:
I'm trying to create a custom Rally app that displays data in a grid view. In another question Rally SDK App Using Grid with collapsible tree of children stories, nickm posted some sample code
Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
launch: function() {
var today = new Date().toISOString();
Ext.create('Rally.data.wsapi.Store', {
model: 'UserStory',
fetch: ['ObjectID', 'FormattedID', 'Name', 'ScheduleState', 'Feature'],
autoLoad: true,
filters: [
{
property: 'Iteration.StartDate',
operator: '<=',
value: today
},
{
property: 'Iteration.EndDate',
operator: '>=',
value: today
},
{
property: 'Feature',
operator: '!=',
value: null
}
],
listeners: {
load: this._onDataLoaded,
scope: this
}
});
},
_onDataLoaded: function(store, records){
var that = this;
var promises = [];
_.each(records, function(story) {
promises.push(that._getFeature(story, that));
});
Deft.Promise.all(promises).then({
success: function(results) {
that._stories = results;
that._makeGrid();
}
});
},
_getFeature: function(story, scope) {
var deferred = Ext.create('Deft.Deferred');
var that = scope;
var featureOid = story.get('Feature').ObjectID;
Rally.data.ModelFactory.getModel({
type: 'PortfolioItem/Feature',
scope: this,
success: function(model, operation) {
fetch: ['State'],
model.load(featureOid, {
scope: this,
success: function(record, operation) {
var featureState = record.get('State')._refObjectName;
var storyRef = story.get('_ref');
var storyOid = story.get('ObjectID');
var storyFid = story.get('FormattedID');
var storyName = story.get('Name');
var storyState = story.get('ScheduleState');
var feature = story.get('Feature');
result = {
"_ref" : storyRef,
"ObjectID" : storyOid,
"FormattedID" : storyFid,
"Name" : storyName,
"ScheduleState" : storyState,
"Feature" : feature,
"FeatureState" : featureState,
"FeatureID" : featureOid
};
deferred.resolve(result);
}
});
}
});
return deferred;
},
_makeGrid: function() {
var that = this;
if (that._grid) {
that._grid.destroy();
}
var gridStore = Ext.create('Rally.data.custom.Store', {
data: that._stories,
groupField: 'FeatureID',
pageSize: 1000,
});
that._grid = Ext.create('Rally.ui.grid.Grid', {
itemId: 'storyGrid',
store: gridStore,
features: [{ftype:'grouping'}],
columnCfgs: [
{
text: 'Formatted ID', dataIndex: 'FormattedID', xtype: 'templatecolumn',
tpl: Ext.create('Rally.ui.renderer.template.FormattedIDTemplate')
},
{
text: 'Name', dataIndex: 'Name',
},
{
text: 'ScheduleState', dataIndex: 'ScheduleState',
},
{
text: 'Feature', dataIndex: 'Feature',
renderer: function(val, meta, record) {
return '' + record.get('Feature').FormattedID + '';
}
},
{
text: 'Feature State', dataIndex: 'FeatureState',
}
]
});
that.add(that._grid);
that._grid.reconfigure(gridStore);
}
});
I'd like to display the ScheduleState and Blocked columns the same way that the Rally Grid shows them (as graphic representations). I've tried to figure out how to use templatecolumn xtype by using the following in my columnCfgs block:
{ text: 'State', dataIndex: 'ScheduleState', xtype: 'templatecolumn',
tpl: Ext.create('Rally.ui.renderer.template.ScheduleStateTemplate') }
This fails and causes a JS error in the sdk-debug.js:
Uncaught TypeError: Cannot read property 'getAllowedValueStore' of
undefined sdk-debug.js:190539 Ext.define.loadStates
I get different errors with the Blocked column but I haven't been able to figure out how to get it to display as the red blocked icon.
With some tweaking I expect this to work in the next release of AppSDK2, but right now the rendering of the ScheduleState and Blocked will only work with wsapi data store. Using
tpl: Ext.create('Rally.ui.renderer.template.ScheduleStateTemplate')
is not sufficient. Custom store has no access to the valid states.
UPDATE
Rendering of ScheduleState and Blocked works in the current x version of AppSDK2 as of the date of this update, 5/22
<script type="text/javascript" src="/apps/x/sdk.js"></script>
This fix will eventually make its way to the next official release of AppSDK2 but for now you may use it with x version of AppSDK2.
Warning: x version of AppSDK is never stable - changes are made to it constantly.
See full code example here.
In x version of AppSDK you may do this:
{
text: 'ScheduleState', dataIndex: 'ScheduleState', xtype: 'templatecolumn',
tpl: Ext.create('Rally.ui.renderer.template.ScheduleStateTemplate',
{
states: ['Defined', 'In-Progress', 'Completed', 'Accepted'],
field: {name: 'ScheduleState' }
})
},
{
text: 'Blocked', dataIndex: 'Blocked', xtype: 'templatecolumn',
tpl: Ext.create('Rally.ui.renderer.template.BlockedTemplate')
}
Also, for now, set this to false in the grid config:
enableBlockedReasonPopover: false
I am trying to create an app that will display all test sets in the current project and their states in terms of pass/fail totals.
Issues that I face (BTW just started learning ExtJS and Rally SDK yesterday):
- I need to understand how can I use the currently selected project as the one sued in the grid as a filter
- how should a test set pass/fail totals be queried and then displayed in a column in the grid - example : Test set 123 | 45/70
This is an example of an app that uses a project picker and builds a grid of Test Sets by Project. Also see a code example from this post. There is no filed in Web Services API where pass/fail totals are calculated. You will have to iterate over results and calculate totals in your code. I would encourage limiting the number of test case results by some criteria, e.g. CreationDate. In a scenario when test case results are automated the sheer volume of the data can be problematic.
Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
launch: function() {
var c = Ext.create('Ext.Container', {
items: [
{
xtype: 'rallyprojectpicker',
fieldLabel: 'select project',
listeners:{
change: function(combobox){
if ( this.down('#g')) {
console.log('grid exists');
Ext.getCmp('g').destroy();
console.log('grid deleted');
}
this.onProjectSelected(combobox.getSelectedRecord());
},
scope: this
}
},
],
});
this.add(c);
},
onProjectSelected:function(record){
var project = record.data['_ref'];
console.log('project', project);
var testSetStore = Ext.create('Rally.data.WsapiDataStore', {
model: 'TestSet',
fetch: ['FormattedID','Name', 'Project', 'TestCaseStatus'],
pageSize: 100,
autoLoad: true,
filters: [
{
property: 'Project',
value: project
}
],
listeners: {
load: this.onTestSetsLoaded,
scope: this
}
});
},
onTestSetsLoaded:function(store, data){
var testSets = [];
Ext.Array.each(data, function(testset) {
var ts = {
FormattedID: testset.get('FormattedID'),
_ref: testset.get("_ref"),
Name: testset.get('Name'),
TestCaseStatus: testset.get('TestCaseStatus')
};
testSets.push(ts);
});
this.updateGrid(testSets);
},
updateGrid: function(testSets){
var store = Ext.create('Rally.data.custom.Store', {
data: testSets,
pageSize: 100
});
if (!this.down('#g')) {
this.createGrid(store);
}
else{
this.down('#g').reconfigure(store);
}
},
createGrid: function(store){
console.log("load grid", store);
var g = Ext.create('Rally.ui.grid.Grid', {
id: 'g',
store: store,
columnCfgs: [
{
text: 'Formatted ID', dataIndex: 'FormattedID', xtype: 'templatecolumn',
tpl: Ext.create('Rally.ui.renderer.template.FormattedIDTemplate')
},
{
text: 'Name', dataIndex: 'Name'
},
{
text: 'TestCaseStatus', dataIndex: 'TestCaseStatus'
}
]
});
this.add(g);
},
});
The full html source of this example is available from this repo
I am using Extjs 4 ComboBox with remote mode. but when i typed any character data is not filtered. and even focus is changed only for first 12 value.
I am new to Extjs 4. Please help me how to do this.
my code is:
Ext.define('MyGroup.combo', {
extend: 'Ext.form.ComboBox',
alias: 'widget.mycombo',
emptyText:'select keyword',
store: keywordStore,
valueField:'name',
displayField:'name',
mode: 'remote',
autoSelect: false,
selectOnFocus:true,
//shadow:true,
//forceSelection: false,
//triggerAction: 'all',
hideTrigger:true,
//multiSelect:true,
typeAhead:true,
minChars:1
});
Ext.define('keywordModel', {
extend: 'Ext.data.Model',
proxy: {
type: 'ajax',
url : '/keywordServlet',
method:'POST',
reader: {
type: 'json',
root: 'rows'
//,totalProperty: 'totalCount'
}
},
fields: [
{name: 'name', mapping: 'name'}
]
});
var keywordStore = Ext.create('Ext.data.Store', {
// pageSize: 10,
model: 'keywordModel'
});
As per my knowledge i think this will be helpful for you:
Ext.define('MyGroup.combo', {
extend: 'Ext.form.ComboBox',
alias: 'widget.mycombo',
initComponent: function() {
this.callParent([arguments]);
}
});
var keywordStore = Ext.create('Ext.data.SimpleStore',{
fields: ['id', 'name'],
data: [[1, 'mr'],[2, 'mr(yes)'],[3, 'mr(no)'], [4, 'example'], [5, 'example(yes)'],[6,'example(no)'],[7,'sample'],[8,'sample(yes)'],[9,'sample(no)'],[10,'mrs'],[11,'mrs(yes)'],[12,'mrs(no)']]
});
Ext.widget('mycombo',{
xtype : 'combo',
emptyText:'select keyword',
store: keywordStore,
valueField:'name',
displayField:'name',
mode: 'remote',
autoSelect: false,
selectOnFocus:true,
//shadow:true,
//forceSelection: false,
//triggerAction: 'all',
hideTrigger:true,
//multiSelect:true,
typeAhead:true,
minChars:1,
renderTo :document.body
});
And one more thing is no one is trying to answer each and every question,but every one is trying to help some body like us:-)