I have setup a checkbox and a combobox and I am trying to set up a functionality - when a user checks the checkbox the combobox has to appear. I am new to extjs and I am having issues setting up the function for this functionality.
Ext.onReady(function() {
var tests = [
['Test1'],
['Test3'],
['Test2']
];
Ext.define('Testfile.model.Test', {
extend: 'Ext.data.Model',
fields: ['test']
});
var testsStore = new Ext.data.Store({
model: 'Testfile.model.Test',
proxy: {
type: 'memory',
reader: {
type: 'array'
}
},
data: tests
});
var form = Ext.create('Ext.form.Panel', {
renderTo: document.body,
bodyPadding: 10,
width: 550,
style: 'margin:16px',
height: 300,
title: 'Testing example',
items: [{
xtype: 'checkbox',
name: 'system',
boxLabel: 'Production (PACTV)',
iputValue: 'production',
listeners: {
check: function (checkbox, isChecked) {
var sample = Ext.getCmp('secondComboID');
}
}
}, {
xtype: 'combobox'
fieldLabel: 'Select Test',
id: 'secondComboID',
store: testsStore,
valueField: 'id',
displayField: 'test',
typeAhead: true,
forceSelection: true,
allowBlank: false,
editable: true,
triggerAction: 'all',
lastQuery: ''
}]
});
Ext.getBody().add(me.form);
})
Can someone please suggest a fix to the script?
I would use the change event: http://docs.sencha.com/extjs/4.2.2/#!/api/Ext.form.field.Checkbox-event-change
listeners: {
change: function(checkbox, newValue, oldValue, eOpts) {
var combo = checkbox.up('form').down('combobox');
if (newValue) {
combo.show();
} else {
combo.hide();
}
}
}
Also, please notice the use of the hierarchy navigation methods up() and down(). Using these (or other related methods) to find the component is much more preferable than using hard-coded component Ids.
Here's a working example of your code: https://fiddle.sencha.com/#fiddle/ua
Related
I am trying to find the best way to bind items to a textfield in my extjs project. I downloaded the data into a store with one record in the controller. How would I bind to this textfield from the one record? I would preferably bind in the view, not in the controller
You should read this guide to understand better what binding is
The best solution for you is bind the record on the viewmodel of the view, so:
textfield.setBind({
value:'{myRec.valueToRefer}'
})
viewmodel.set('myRec',record.getData());
If you want, you can also use a form to handle this, using form.loadRecord and giving to the textfield a name..
A tip:
set inside the viewmodel a value to null:
data:{
myRec:null
}
Set your record in the viewmodel after setting the bind to the textfield.
Other tip:
If you can, avoid using setBind and prefer to set the binding directly on textfield creation:
//WILL WORK BUT YOU CAN AVOID IT
textfield.setBind({
value:'{myRec.valueToBind}'
})
//YES
var textfield=Ext.create({
xtype:'textfield',
bind:{
value:'{myRec.valueToBind}'
}
});
Refer to Sencha documentation also
You can use bind config to bind the data or any other config for ExtJS component.
Bind setting this config option adds or removes data bindings for other configs.
For example, to bind the title config:
var panel = Ext.create({
xtype: 'panel',
bind: {
title: 'Hello {user.name}'
}
});
To dynamically add bindings:
panel.setBind({
title: 'Greetings {user.name}!'
});
To remove bindings:
panel.setBind({
title: null
});
In this FIDDLE, I have created a demo for biding. I hope this will help/guide you to achieve you requirement.
CODE SNIPPET
Ext.application({
name: 'Fiddle',
launch: function () {
//defining Store
Ext.define('Store', {
extend: 'Ext.data.Store',
alias: 'store.gridstore',
autoLoad: true,
fields: ['name', 'email', 'phone'],
proxy: {
type: 'ajax',
url: 'data1.json',
reader: {
type: 'json',
rootProperty: ''
}
}
});
//defining view model
Ext.define('MyViewModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.myvm',
data: {
formdata: null
},
stores: {
gridstore: {
type: 'gridstore'
}
}
});
//Controller
Ext.define('MyViewController', {
extend: 'Ext.app.ViewController',
alias: 'controller.myview',
onGridItemClick: function (grid, record) {
//Bind the form data for CLICKED record
this.getViewModel().set('formdata', record)
}
});
//creating panel with GRID and FORM
Ext.create({
xtype: 'panel',
controller: 'myview',
title: 'Binding Example',
renderTo: Ext.getBody(),
viewModel: {
type: 'myvm'
},
layout: 'vbox',
items: [{
xtype: 'grid',
flex: 1,
width: '100%',
bind: '{gridstore}',
columns: [{
text: 'Name',
dataIndex: 'name'
}, {
text: 'Email',
dataIndex: 'email',
flex: 1
}, {
text: 'Phone',
dataIndex: 'phone'
}],
listeners: {
itemclick: 'onGridItemClick'
}
}, {
xtype: 'form',
flex: 1,
width: '100%',
defaults: {
anchor: '100%'
},
title: 'Bind this form on Grid item Click',
bodyPadding:15,
margin: '20 0 0 0',
// The fields
defaultType: 'textfield',
items: [{
fieldLabel: 'Name',
name: 'first',
allowBlank: false,
bind: '{formdata.name}'
}, {
fieldLabel: 'Email',
name: 'email',
allowBlank: false,
bind: '{formdata.email}'
}, {
fieldLabel: 'Phone',
name: 'phone',
allowBlank: false,
bind: '{formdata.phone}'
}]
}]
});
}
});
I have a piece of code which makes a combobox active when a checkbox is checked. Once the checkbox is checked I can select a value from the combobox. But I want the combobox to return having no value (blank) once the checkbox is unchecked. How do i do that?
My code is as follows:
var tests = [
['Test1'],
['Test3'],
['Test2']
];
Ext.define('Test', {
extend: 'Ext.data.Model',
fields: ['test']
});
var testsStore = new Ext.data.Store({
model: 'Test',
proxy: {
type: 'memory',
reader: {
type: 'array'
}
},
data: tests
});
var form = Ext.create('Ext.form.Panel', {
renderTo: document.body,
bodyPadding: 10,
width: 550,
style: 'margin:16px',
height: 300,
title: 'Testing example',
items: [{
xtype: 'checkboxfield',
name: 'system',
boxLabel: 'Production (PACTV)',
inputValue: 'production',
listeners: {
change: function (checkbox, newValue, oldValue, eOpts) {
var combo = checkbox.up('form').down('combobox');
if (newValue) {
Ext.getCmp('secondComboID').setReadOnly(false);
Ext.getCmp('secondComboID').allowBlank = false;
Ext.getCmp('secondComboID').validate();
} else {
Ext.getCmp('secondComboID').setReadOnly(true);
Ext.getCmp('secondComboID').allowBlank = true;
Ext.getCmp('secondComboID').validate();
}
}
}
}, {
xtype: 'combobox',
fieldLabel: 'Select Test',
readOnly: true,
id: 'secondComboID',
store: testsStore,
valueField: 'id',
displayField: 'test',
typeAhead: true,
forceSelection: true,
editable: true,
triggerAction: 'all',
lastQuery: ''
}]
});
Here is a working fiddle : https://fiddle.sencha.com/#view/editor&fiddle/1u9n
Use this in your fiddle when you uncheck the checkbox:
Ext.getCmp('secondComboID').reset();
Use this code to remove the datas from the combo or to load empty array data in the combo
Ext.getCmp('secondComboID').getStore().loadRawData([]);
Also if You wish to load the previous datas again here is an example of it which allows us to toggle to load the datas and to remove datas from combo
Try the FIDDLE
I would like to add records after the initialization of a store.
I tried loadData(), loadRawData(), add() but nothing seams to work.
Here is my jsfiddle: http://jsfiddle.net/charlesbourasseau/zVvLc
Any ideas ?
You need to set queryMode: 'local' in the combo box. Minimal example:
Ext.onReady(function() {
var store = Ext.create('Ext.data.Store', {
alias: 'store.ModeStore',
autoLoad: false,
fields: [{
name: 'mode',
type: 'string'
}, {
name: 'id',
type: 'string'
}],
data: [{
mode: 'mode1',
id: 1
}]
});
var container = Ext.create('Ext.form.field.ComboBox', {
renderTo: Ext.getBody(),
displayField: 'mode',
valueField: 'mode',
store: store,
queryMode: 'local'
});
store.add({
mode: 'mode2',
id: 2
});
});
For a panel you can add or remove items by remove() and add()
var store = Ext.create('MyApp.store.Roles', {autoLoad: false});
store.load(function(records, action, success) {
if (success) {
store.remove(store.findRecord('id', 50, 0, false, true, true));//exact match
store.add({'id':110,'name':'Agent' });
}
});
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 },
}
Using the example in "ext-designer-for-ext-js-4-users-guide.pdf" i've put together the following. The issue is that the store is not binding. ie the select is empty.
MyComboBox.js
Ext.define('MyApp.view.MyComboBox', {
extend: 'MyApp.view.ui.MyComboBox',
initComponent: function() {
var me = this;
me.callParent(arguments);
}
});
Ext.define('MyApp.view.ui.MyComboBox', {
extend: 'Ext.form.field.ComboBox',
fieldLabel: 'comboList',
displayField: 'comboList',
queryMode: 'local',
store: 'MyArrayStore',
triggerAction: 'all',
valueField: 'comboList',
initComponent: function() {
var me = this;
me.callParent(arguments);
}
});
store/MyArrayStore.js
Ext.define('MyApp.store.MyArrayStore', {
extend: 'Ext.data.Store',
constructor: function(cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.apply({
autoLoad: true,
storeId: 'MyArrayStore',
data: [
[
'Search Engine'
],
[
'Online Ad'
],
[
'Facebook'
]
],
proxy: {
type: 'ajax',
reader: {
type: 'array'
}
},
fields: [
{
name: 'comboList'
}
]
}, cfg)]);
}
});
** update **
this was driving me crazy. It's [turns out][1] my array need to be json format. When i updated it to
[{"comboList" : "Hello"}, {"comboList" : "Hi"}, {"comboList" : "GoodMorning"}]
it worked.
I started to try and pick apart your implementation but it seems somewhat convoluted, starting with the store where there is local data and a proxy defined but no url for the proxy.
It seemed easier to just give you a simplified implementation of a combobox (using local data because it seems that is what you are trying to do):
// the datastore
var myStore = Ext.create('Ext.data.Store', {
fields: ['value', 'name'],
data: [
{value: 1, name: 'Search Engine'},
{value: 2, name: 'Online Ad'},
{value: 3, name: 'Facebook'}
]
});
// a window to hold the combobox inside of a form
myWindow = Ext.create('Ext.Window', {
title: 'A Simple Window',
width: 300,
constrain: true,
modal: true,
layout: 'fit',
items: [{
// the form to hold the combobox
xtype: 'form',
border: false,
fieldDefaults: {
labelWidth: 75
},
bodyPadding: '15 10 10 10',
items: [{
// the combobox
xtype: 'combo',
id: 'myCombo',
fieldLabel: 'Title',
valueField: 'value',
displayField: 'name',
store: myStore,
queryMode: 'local',
typeAhead: true,
forceSelection: true,
allowBlank: false,
anchor: '100%'
},{
// shows the selected value when pressed
xtype: 'button',
margin: '10 0 0 100',
text: 'OK',
handler: function() {
alert('Name: ' + Ext.getCmp('myCombo').getRawValue() +
'\nValue: ' + Ext.getCmp('myCombo').value);
}
}]
}]
});
// show the window
myWindow.show();
This creates a combobox inside of a little window with an OK button. When you press OK it will alert the visible text of the combobox Ext.getCmp('myCombo').getRawValue() and the value of the item in the combobox Ext.getCmp('myCombo').value.
If you drop this in your project you can get an idea of how it implements, it should just run.
If you actually wanted a remote datastore (from a webservice that returns json for example) you would just need to change the datastore configuration like so:
var myRemoteStore = Ext.create('Ext.data.Store', {
fields: ['value', 'name'],
proxy: {
type: 'ajax',
url: 'myWebservice.php', // whatever your webservice path is
reader: 'json',
},
autoLoad:true
});