How Do I Conditionally Filter a store? - extjs

I am fairly new to ExtJS and I am having trouble with my stores. I have two combo boxes on a pop up and each is set to a store.
items: [
{
xtype: 'combobox', itemId: 'facility', name: 'facilityId', fieldLabel: 'Facility', displayField: 'name', valueField: 'id', queryMode: 'local', allowOnlyWhitespace: false, forceSelection: true,
store: {
model: 'Common.model.Facility', autoDestroy: true, sorters: 'name'
},
listeners: {
change: function (field, newValue) { this.up('window').filterLocations(); }
}
},
{
xtype: 'combobox', fieldLabel: 'Location', name: 'locationId', displayField: 'name', valueField: 'id', queryMode: 'local', allowOnlyWhitespace: false, forceSelection: true,
store: {
model: 'Common.model.PrimaryLocation', autoDestroy: true, sorters: 'name'
},
// Strange hack from Sencha to get around filter-on-load issue http://www.sencha.com/forum/showthread.php?80079-Problem-to-filter-a-combobox-s-store-at-store-s-load-event
triggerAction: 'all', lastQuery: ''
}
],
It is referenced here(I think) in another code file(I'll only post the one I care about for now):
// Load comboboxes
window.getFacilityId().getStore().load({
scope: this,
callback: function (records, operation, success) {
if (!success) {
Ext.log({ level: 'error', msg: 'Error loading facility list', dump: operation });
var text = (operation.getError() ? operation.getError().response.responseText : operation.getResponse().responseText);
var msg = Ext.decode(text).message;
Ext.Msg.show({ title: 'Error', msg: 'Error loading facility data.<br>' + msg, buttons: Ext.Msg.OK, icon: Ext.Msg.ERROR });
}
else {
// Select first entry if only one
if (records.length == 1)
window.getFacilityId().setValue(records[0].get('id'));
}
}
});
There is a field on the form that calls this has a value I need to do a comparison on. If the value is null or 0, then I really don't need to do anything because as it is, it displays all the facilities in the database.
However, if it is not null or 0, then I need the store to be filtered to only show the single facility in the list that matches the one on the value that I am comparing it to.
How do I make this filter work? To make it easy, just assume that the facility store has just id and name as fields and assume that the value I'm comparing it to is facilityId.
Something like:
if (facilityId == null)
// What?
Thank you.

Before using load method on the store, set filter if your condition is met like:
window.getFacilityId().getStore().setFilters({
property: 'id',
operator: '=',
value: facilityId
});

Related

Dynamic DropDownMenu in extjs

I have a 2 DropDownBoxes, where 1 of the drop box value is depanded on the selected value of the first.
How do i create a dynamic store in the second DropDownBoxes.
This is the code:
{
xtype: 'combobox',
displayField: 'vendor_name',
typeAhead: true,
mode: 'local',
triggerAction: 'all',
emptyText:'Choose vendor...',
selectOnFocus:true,
fieldLabel: 'Vendor Name',
margin: 10,
id: 'txtBidVendor',
labelWidth: 100,
store: Ext.create('Ext.data.Store', {
fields:[
{name: 'vendor_name'}
],
proxy: {
type: 'ajax',
timeout: 120000,
url: 'GetVendors.jsp',
reader: {
type: 'json',
root: 'data',
successProperty: 'success'
}
},
autoLoad: true
})
},
{
xtype: 'combobox',
displayField: 'rate_desc',
typeAhead: true,
mode: 'local',
triggerAction: 'all',
emptyText:'Choose Quality...',
selectOnFocus:true,
fieldLabel: 'Vendor Quality',
margin: 10,
id: 'txtBidVendorQuality',
labelWidth: 100,
store: Ext.create('Ext.data.Store', {
fields:[
{name: 'rate_desc'}
],
proxy: {
type: 'ajax',
timeout: 120000,
url: 'GetVendorQuality.jsp?' + Ext.urlEncode({'bid_vendor': Ext.getCmp('txtBidVendor').value}),
reader: {
type: 'json',
root: 'data',
successProperty: 'success'
}
},
autoLoad: true
})
},
I get the error: "Cannot read property 'value' of undefined " ,in the line where i try getting "Ext.getCmp('txtBidVendor').value"
About what you are trying to accomplish here I have two considerations:
The error here is that you are trying to access to the txtBidVendor component at definition time (it doesn't exists), when you send a configuration object (like these two comboboxes here) you are not actually creating them, but just setting the initial configuration that will be used by its parent for later instantiation.
What I think you are trying to do is to change the query parameter value for the store, when the selection changes on txtBidVendor combobox. To accomplish that, you must listen for the selection event of the first combobox and then modify and reload the store of the second one. Something like this:
{
xtype: 'combobox',
displayField: 'vendor_name',>
emptyText: 'Choose vendor...',
selectOnFocus: true,
fieldLabel: 'Vendor Name',
id: 'txtBidVendor',
store: vendorStore,
listeners: {
select: function (combo, records, eOpts) {
var record = records[0]; // just want the first selected item
rateStore.getProxy().extraParams.bid_vendor = record.get('vendor_name');
alert('Store will load now with bid_vendor =' + record.get('vendor_name'));
rateStore.load();
}
}
}
For sake of readability it will be good idea to take store definition out of the components definition itself also. Here you can find a working sample of it.
Hope it helps.

Extjs Combo - get value from store in afterrender function

I have a combo box and I want get id of first record from server by alert(combo.store.data[0].id); But it's not working
Here is my code
xtype: 'combo',
value: '0',
triggerAction: 'all',
forceSelection: true,
editable: false,
allowBlank: false,
fieldLabel: 'example',
mode: 'remote',
displayField:'name',
valueField: 'id',
store: Ext.create('Ext.data.Store', {
......
,listeners: {
'afterrender': function(combo){
alert(combo.store.data[0].id);
}
}
How can i do that thanks.
Probably you are missing something.
combo.store.getAt(0).data.id
Try this.
Inside combobox listeners "afterrender" :
var getState = combo.getState(), //get current combobox state
comboState = parseFloat(getState.value) - 1,
comboStore = combo.store;
comboStore.on("load", function(s,rs) {
comboStore.each(function(record, key) {
if( key == comboState){
//console.log(record);
alert(record.data.id);
}
});
});

Ext-JS 4 - strange behavior with submitting combobox to server

I have a combobox in a form:
{
xtype: 'combobox',
fieldLabel: 'Jurisdictions',
name: 'jurisdiction_id',
id: 'ComboboxJurisdictions',
store: Ext.create('App.store.Jurisdictions'),
queryMode: 'local',
editable: false,
displayField: 'name',
valueField: 'id',
}
Data is:
1 => Administrator
2 => User
3 => Guest
Now, if I don't touch anything when editing a user, on my server for my combobox I get "Administrator" (displayField), but when I change something in combobox I get the "id" (valueField). I really just want "id" in both cases. I was reading about hiddenName? Is that the case?
If you need any more code, feel free to ask. :)
Thank you!
EDIT (more code)
1.) There is no default value.
Here is the whole view code:
Ext.define('App.view.Suits.Update', {
extend: 'Ext.window.Window',
title: 'Suits',
width: 250,
id: 'UpdateWindowSuits',
defaultType: 'textfield',
items: [{
xtype: 'UpdateFormSuits'
}],
buttons: [
{ text: 'Save', id: 'submitUpdateFormButtonSuits'},
{ text: 'Cancel', id: 'cancelUpdateFormButtonSuits'},
]
});
Ext.define('App.view.Suits.UpdateForm', {
extend: 'Ext.form.Panel',
alias: 'widget.UpdateFormSuits',
layout: 'form',
id: 'UpdateFormSuits',
bodyPadding: 5,
defaultType: 'textfield',
items: [{
fieldLabel: 'Id',
name: 'id',
hidden: true
},{
fieldLabel: 'Name',
name: 'name',
allowBlank: false,
},{
fieldLabel: 'Status',
name: 'status',
allowBlank: false
},{
xtype: 'combobox',
fieldLabel: 'Priority',
name: 'suit_priority_id',
id: 'ComboboxSuitPriorities',
store: Ext.create('App.store.SuitPriorities'),
editable: false,
displayField: 'name',
hiddenName: 'id',
valueField: 'id'
},{
xtype: 'combobox',
fieldLabel: 'Jurisdictions',
name: 'jurisdiction_id',
id: 'ComboboxJurisdictions',
store: Ext.create('App.store.Jurisdictions'),
queryMode: 'local',
editable: false,
displayField: 'name',
valueField: 'id',
}],
});
Here is the store:
Ext.define('App.store.SuitPriorities', {
extend: 'Ext.data.Store',
// Where is the Model.
model: 'App.model.SuitPriority',
// "id" of the Store.
storeId: 'SuitPriorities',
// Autoload all data on creation.
autoLoad: true,
// Number of records in one page (for pagination).
pagesize: 20,
// Proxy for CRUD.
proxy: {
// Type of request.
type: 'ajax',
// API for CRUD.
api: {
create : 'php/suitpriorities/update',
read : 'php/suitpriorities/read',
update : 'php/suitpriorities/update',
destroy : 'php/suitpriorities/delete'
},
// Type of methods.
actionMethods: {
create : 'POST',
read : 'POST',
update : 'POST',
destroy : 'POST'
},
// Reader.
reader: {
// Which type will the reader read.
type: 'json',
// Root of the data.
root: 'suitpriorities',
rootProperty: 'data',
// One record.
record: 'SuitPriority',
// Message and success property.
successProperty: 'success',
messageProperty: 'message'
},
// Writer (when sending data).
writer: {
type: 'json',
writeAllFields: true,
root: 'data',
encode: true
},
});
As I sad, the store is getting all the data because it's already loaded when I press the combobox. It's a simple JSON with 'id' and 'name' properties.
EDIT2: I've tried this for my Jurisdictions because I wasn't getting the right data selected in combobox. This is inside my controller.
onJurisdictionComboRender: function(combobox, eOpts){
// Getting the selected row.
var record = this.grid.getSelectionModel().getSelection()[0];
// Selected jurisdiction.
var jurisdiction = record.data.jurisdiction_id;
// Select it in combobox.
combobox.select(jurisdiction);
}
That doesn't make sense... If you read out the combo the correct way, meaning let either the form doing the work or calling getSubmitValue() on your own the combo would always returning the valueField. hiddenName is used for other purposes. Please take a look at the console of this JSFiddle and recheck how you fetch the combo value.
Here's the working demo-code
// The data store containing the list of states
var roles = Ext.create('Ext.data.Store', {
fields: ['id', 'name'],
data : [
{"id":1, "name":"Administrator"},
{"id":2, "name":"User"},
{"id":3, "name":"Guest"}
//...
]
});
// Create the combo box, attached to the states data store
var combo = Ext.create('Ext.form.ComboBox', {
fieldLabel: 'Choose Role',
store: roles,
queryMode: 'local',
editable: false,
displayField: 'name',
valueField: 'id',
renderTo: Ext.getBody()
});
combo.on('select', function(cb){ console.log(cb.getSubmitValue()); })
+1 for everyone for helping but the problems was here:
In my store I've put autoLoad: false and inside my combobox I've put store.load() manually and it works perfectly.
Thank you all! :)

extjs combo won't stop loading 4.07

I have 3 combo box's. When you click the first box the second box needs to update showing the relevant data. I select the first combo the second box updates perfectly. However if i try the same steps again the second box doesn't stop loading ( see image )
Here is the code from my view
{
xtype: 'combobox',
name: 'Clients',
id: 'clients',
displayField: 'Name',
store: 'Clients',
queryMode: 'local',
mode: 'local',
valueField: 'Id',
fieldLabel: 'Clients'
},{
xtype: 'combobox',
name: 'Projects',
id: 'projects',
displayField: 'Name',
editable: false,
store: 'Projects',
queryMode: 'local',
mode: 'local',
valueField: 'Id',
fieldLabel: 'Projects'
}
and from my controller
stores: ['Projects', 'Clients', 'Jobs'],
init: function () {
this.control({
'#clients': {
change: this.onClientSelect
},
'processlist button[action=copy]': {
click: this.onCopyPart
},
'#processColourContainer #processColourGrid': {
edit: this.onPurchaseOrderColourUpdate
}
});
},
onLaunch: function () {
var clients = this.getClientsStore();
clients.load();
},
onClientSelect: function (selModel, selection) {
var projects = this.getProjectsStore();
projects.load({
url: '/Projects/Read/?clientId=' + selection,
scope: this
});
},
Known bug:
http://www.sencha.com/forum/showthread.php?153490-Combo-Box-Store-Loading
Adding this should sort it out:
store.on('load', function (store, records, successful, options) {
if (successful && Ext.typeOf(combo.getPicker().loadMask) !== "boolean") {
combo.getPicker().loadMask.hide();
}
});
I had the same symptom with a local data store with ExtJS Combobox, but the correct fix was to set queryMode properly in the combo box - there's no bug in the store (at least in 4.1 version of ExtJS). queryMode must be set to "local" instead of its default "remote" value, if your data is stored locally within the data store (as in my working example below).
ComboBox:
xtype: 'combobox',
name: 'sizeMaxUnits',
value: 'TB',
editable: false,
displayField: 'abbr',
**queryMode: 'local',**
store: 'UnitsStore',
valueField: 'units'
Store:
Ext.define('DiskApp.store.UnitsStore', {
extend: 'Ext.data.Store',
requires: [
'DiskApp.model.UnitsModel'
],
constructor: function(cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.apply({
autoLoad: false,
model: 'DiskApp.model.UnitsModel',
storeId: 'MyStore',
data: [
{
abbr: 'MB',
units: 'M'
},
{
abbr: 'GB',
units: 'G'
},
{
abbr: 'TB',
units: 'T'
}
]
}, cfg)]);
}
});
I found that hooking into the 'expand' event on the combo worked better (hooking into 'load' on the store somehow destroyed the binding of the combo to the store, causing all sorts of horrible, hard to track down errors).
combo.on('expand', function (field, options) {
if (Ext.typeOf(field.getPicker().loadMask) !== "boolean") {
field.getPicker().loadMask.hide();
}
}, this);
This did the job for me without breaking my application.
A really simple solution is to add the listConfig config to your combo box:
{
xtype:'combobox',
fieldLabel: 'My Combo',
listConfig: { loadingText: null, loadMask: false },
}

All fields are "undefined" in a combobox

have a little problem with my combo box fields. All are undefined.
buildMyCombo : function(label)
{
var store = new Ext.data.ArrayStore({
fields: ['name', 'value'],
data : [
['.xls', 1],
['.csv', 2],
['.htm', 3]
]
});
var result = new BGGNE.components.fields.SimpleComboBox({
formFields: {},
enableKeyEvents: true,
store: store,
valueField: 'value',
displayField: 'name',
lazyInit:false,
formFieldDefinition: {
isMandatory: true,
fieldLabel: label,
hideTrigger: false,
selectOnFocus: true,
isEditableInDialog: false,
type: {
kind: 'local',
type: 'Text',
selectableValues: 'name'
},
renderAsExtField: true,
isOnAPropagation: true,
forceSelection: true
}
});
result.on('focus', function ()
{
result.doQuery('', true);
}, this);
result.on('select', this.onComboSelect, this);
return result;
},
So, I should see the 3 items from store, instead I see only 3 items 'undefined'. So, I believe that the combo box reads the store cause it knows how many items I do have there. but because of something the undefined text is displayed.
I manage to solve the problem myself. The problem was that I needed to put this code
store: store,
valueField: 'value',
displayField: 'name',
in the formFieldDefinition. While SimpleComboBox extends ComboBox some code was overridden and the formFieldDefinition is the field that defines the list items.
Thanks and apologize if the question was a waste of your time.

Resources