Ext JS - Populate combobox using value from another Combobox from Database (SQL) - sql

I have two combobox, values are coming from database i am using json to populate the same. Second combo gets populated when the first combo changes. First time when we set the value of the first combo it works like magic. But second time, it does not get bind. and throws an error
This is my running code:
<script type="text/javascript">
Ext.onReady(function() {
var serverStore = Ext.create('Ext.data.Store', {
storeId: 'serverStore',
fields: [
{
name: 'u_hostname',
mapping: 'u_hostname',
type: 'string'
}
],
proxy: {
type: 'ajax',
url: '/list/data/dbapi/getRecordData',
extraParams: {
type: 'table',
useSql: true,
sqlQuery: 'select distinct(u_hostname) from SCRIPT_SCHEDULE'
},
reader: {
type: 'json',
root: 'records'
}
},
autoLoad: true
});
var dpsStore = Ext.create('Ext.data.Store', {
storeId: 'dpsStore',
fields: [
{
name: 'u_username',
mapping: 'u_username',
type: 'string'
},
{
name: 'u_hostname',
mapping: 'u_hostname',
type: 'string'
}
],
proxy: {
type: 'ajax',
url: '/list/data/dbapi/getRecordData',
extraParams: {
type: 'table',
useSql: true,
},
reader: {
type: 'json',
root: 'records'
}
},
autoLoad: true
});
var dpsCombo = Ext.create('Ext.form.ComboBox',{
id: 'dpsCombo',
fieldLabel: 'Username',
hidden: false,
margin: '5 0 0 25',
queryMode: 'local',
valueField: 'u_username',
displayField: 'u_username'
});
var serverCombo = Ext.create('Ext.form.ComboBox',{
id: 'serverCombo',
fieldLabel: 'Server Name',
hidden: false,
margin: '5 0 0 25',
store: serverStore,
queryMode: 'local',
valueField: 'u_hostname',
displayField: 'u_hostname',
listeners: {
change: changeStore
}
});
function changeStore(combo, value){
var store;
store = dpsStore;
var combobox = Ext.getCmp('dpsCombo');
combobox.clearValue();
console.log(value);
store.getProxy().setExtraParam("sqlQuery", `select distinct(u_username) from SCRIPT_SCHEDULE where u_hostname ='${value}'`);
console.log(value);
combobox.bindStore(store);
store.load();
}
Ext.create('Ext.container.Viewport', {
id: 'processviewport',
layout: 'border',
items: [{
xtype: 'panel',
id: 'filterPanel',
layout: 'hbox',
title: 'Data filter',
region: 'north',
collapsible: true,
items: [{
xtype: 'panel',
layout: 'hbox',
flex: 2,
items:[
{
xtype: 'panel',
layout: 'vbox',
items: [
serverCombo,
dpsCombo
]
}]
}]
}]
});
});
</script>
Error :
Uncaught TypeError: Cannot read property 'call' of undefined

The issue the combobox was not rendering data on the second change was resolved by adding lastQuery: field in the second combo.

Related

Set the edited row in EXTJS grid after editing without refreshing page

I am editing a row in EXTJS grid on clicking the edit action link. On clicking the edit link of a row a new window opens with all the data of the row and "Save" and "Cancel" button.
On clicking the "Save" button, it is saving the record in database. But I want the row should also get refreshed without refreshing the page.
I am new to EXTJS.
Can any one help me to do the same.
Here is my code.
Ext.require([
'Ext.grid.*',
'Ext.data.*',
'Ext.util.*',
'Ext.grid.plugin.BufferedRenderer'
]);
Ext.define('TestResult', {
extend: 'Ext.data.Model',
fields: [
{
name: 'ID',
type: 'int'
},
{
name: 'jobNo',
type: 'int'
},
{
name: 'stageCode',
type: 'String'
},
{
name: 'productTitle',
type: 'String'
},
{
name: 'brand',
type: 'String'
},
{
name: 'category',
type: 'String'
},
{
name: 'ftpDate',
type: 'Date'
}],
idField: 'ID'
});
Ext.onReady(function() {
var store = Ext.create('Ext.data.Store', {
model: 'TestResult',
autoLoad: true,
autoSync: true,
proxy: {
type: 'ajax',
url : 'data.jsp',
reader :
{
type : 'json'
},
writer :
{
type : 'json'
}
}
});
var grid = Ext.create('Ext.grid.Panel', {
width: 700,
height: 500,
title: 'Buffered Grid of records',
store: store,
loadMask: true,
plugins: 'bufferedrenderer',
selModel: {
pruneRemoved: false
},
viewConfig: {
trackOver: false
},
features: [{
ftype: 'groupingsummary',
groupHeaderTpl: 'Department: {name}',
showSummaryRow: false
}],
// grid columns
columns:[{
text: 'ID',
sortable: true,
dataIndex: 'ID',
groupable: false,
locked: true,
width: 70
}, {
text: 'Job No.',
sortable: true,
dataIndex: 'jobNo',
groupable: false,
locked: true,
width: 120
}, {
text: 'Version',
dataIndex: 'stageCode',
groupable: false
}, {
text: 'Product Title',
dataIndex: 'productTitle',
groupable: false
}, {
text: 'Brand',
dataIndex: 'brand',
groupable: false
}, {
text: 'Category',
dataIndex: 'category',
width: 200,
groupable: false
}, {
text: 'FTP Date',
dataIndex: 'ftpDate',
xtype: 'datecolumn',
groupable: false
},
{
xtype:'actioncolumn',
header:'Edit',
width:50,
items: [{
icon: 'assets/images/edit.png', // Use a URL in the icon config
tooltip: 'Edit',
handler: function(grid, rowIndex, colIndex) {
var rec = grid.getStore().getAt(rowIndex);
editForm.show();
editForm.down('form').loadRecord(rec);]
}],
renderTo: Ext.getBody()
});
var editForm = new Ext.Window({
title: 'Edit Window',
items:[
{
xtype: 'form',
url: 'UpdateController',
items: [
{
xtype: 'hidden',
fieldLabel: 'ID',
name: 'ID',
allowBlank: false,
readOnly: true
},
{
xtype: 'textfield',
fieldLabel: 'Job No.',
name: 'jobNo',
allowBlank: false,
readOnly: true
},
{
xtype: 'textfield',
fieldLabel: 'Version',
name: 'stageCode',
allowBlank: false,
readOnly: true
},
{
xtype: 'textfield',
fieldLabel: 'Product Title',
name: 'productTitle',
allowBlank: false
},
{
xtype: 'textfield',
fieldLabel: 'Category',
name: 'category',
allowBlank: false
},
{
xtype: 'textfield',
fieldLabel: 'Brand',
name: 'brand',
allowBlank: false
},
{
xtype: 'datefield',
fieldLabel: 'FTP Date',
name: 'ftpDate',
allowBlank: false
}],
buttons : [{
text : 'Save',
handler: function()
{
this.up('form').getForm().submit(
{
success: function(f,a)
{
store.save();
var win = Ext.WindowManager.getActive();
if (win)
{
win.hide();
}
},
failure: function(f,a)
{
//Ext.Msg.alert('Warning', 'Error');
Ext.Msg.alert('Warning', a.result.errormsg);
this.up('window').hide();
}
});
}
},
{
text: 'Cancel',
handler: function()
{
this.up('window').hide();
}
}]
}
]
});
});
Thanks
In your this.up('form').getForm().submit success handler you can update record, which you loaded into form, by using Ext.form.Basic updateRecord method.
So just add into success handler code:
// update record with form data
f.updateRecord();
// mark record as synchronized with server (because you already sent data to server with form submit method)
f.getRecord().commit();

autocomplete with extjs :ComboBox with REMOTE query store

I want to use ComboBox with REMOTE query ,
I work with extjs 4,
I want to do autocomplete with combobox
meaning when I entered a text in the combobox a request will send to database in order to display a list of emplyees ( in my case ) according to text entered in the combobox
I found some example which use queryMode: 'remote', and hideTrigger:true
this some of link which I found
http://demo.mysamplecode.com/ExtJs/pages/comboBoxes.jsp
currently I have this code which fill out a combo with traditional way
in my emplyeesModel.js I have
Ext.define('GenericComboModel', {
extend: 'Ext.data.Model',
fields: [
{name: 'label', type: 'string'},
{name: 'value', type: 'string'}
]
});
var employeesStore= Ext.create('Ext.data.Store', {
model: 'GenericComboModel'
});
in my emplyeesView.js I have
function fillEmployeesCombo() {
employeesService.getEmployeesList({
callback:function(employeesList){
for(var i=0; i<employeesList.length; i++){
var employeesLabel = employeesList[i].libelleEmployees;
var employeesId = employeesList[i].idEmployees;
employeesStore.add({label: employeesLabel , value: employeesId });
}
}
});
}
var employeesPanel = Ext.create('Ext.panel.Panel', {
title: 'test',
bodyPadding: 5,
width: '100%',
height: '100%',
autoScroll: true,
id: 'tab_Employees',
layout: 'anchor',
defaults: {
anchor: '100%'
},
defaultType: 'textfield',
items:
[
{
xtype: 'container',
layout: {
type: 'hbox'
},
padding: '5 5 5 5',
items:
[
{
xtype: 'combobox',
store: employeesStore,
displayField: 'label',
valueField: 'value',
queryMode: 'local',
fieldLabel: 'test',
editable: false,
id: 'employees_IdCombo'
}
]
},
]
});
in employeesService.java I have
public List<employees> getEmployeesList() {
// TODO Auto-generated method stub
Query query = getSession().createQuery("FROM employees emp ");
List result = query.list();
if(result.size()!=0 && result !=null)
return result;
else
return null;
}
but actually I will change my code in :emplyeesView.js
I will have this kind of code :
xtype: 'combobox',
store: employeesStore,
displayField: 'label',
valueField: 'value',
queryMode: 'remote',
fieldLabel: 'test',
editable: false,
id: 'employees_IdCombo',
hideTrigger:true
also I think in emplyeesModel.js I should add this notion :
proxy: {
type: 'ajax',.......
I think that in order to finish my example I should use a servlet
meaning fo example :
proxy: {
type: 'ajax',
url: 'EmployeesServlet',...
can someone help me to correct my code
I try with this code :
Ext.define('GenericComboModel', {
extend: 'Ext.data.Model',
fields: [
{name: 'label', type: 'string'},
{name: 'value', type: 'string'}
]
});
var employeesStore= Ext.create('Ext.data.Store', {
model: 'GenericComboModel',
proxy: {
type: 'ajax',
url: 'employeesService',
reader: {
type: 'json',
root: 'users'
}
}
});
//Finally your combo looks like this
{
xtype: 'combobox',
store: employeesStore,
displayField: 'label',
valueField: 'value',
queryMode: 'remote',
fieldLabel: 'test',
editable: false,
id: 'employees_IdCombo',
hideTrigger:true
queryParam: 'searchStr' //This will be the argument that is going to be passed to your service which you can use this to return your resulkt set
}
function fillEmployeesComboByParam(String Libelle) {
employeesService.getEmployeesList(Libelle){
callback:function(employeesList){
for(var i=0; i<employeesList.length; i++){
var employeesLabel = employeesList[i].libelleEmployees;
var employeesId = employeesList[i].idEmployees;
employeesStore.add({label: employeesLabel , value: employeesId });
}
}
});
}
in `employeesService.java` I have
public List<employees> getEmployeesList(String libelle) {
// TODO Auto-generated method stub
Query query = getSession().createQuery("FROM employees emp where emp.libelle=:libelle ");
query.setParameter("libelle", libelle);
List result = query.list();
if(result.size()!=0 && result !=null)
return result;
else
return null;
}
juste I want to know want if this url is correct or no
url: 'employeesService,
Below are the changes on the extjs, you have to make your service changes to handle searchStr which is passed as queryParam
//Your model remains the same as you defined
Ext.define('GenericComboModel', {
extend: 'Ext.data.Model',
fields: [
{name: 'label', type: 'string'},
{name: 'value', type: 'string'}
]
});
//Your store will look like
var employeesStore= Ext.create('Ext.data.Store', {
model: 'GenericComboModel',
proxy: {
type: 'ajax',
url: 'Your service URL',
reader: {
type: 'json',
root: 'users'
}
}
});
//Finally your combo looks like this
{
xtype: 'combobox',
store: employeesStore,
displayField: 'label',
valueField: 'value',
queryMode: 'remote',
fieldLabel: 'test',
editable: true,
id: 'employees_IdCombo',
hideTrigger:true
queryParam: 'searchStr' //This will be the argument that is going to be passed to your service which you can use this to return your resulkt set
}

ExtJs:Show Grid after Button is clicked

I have a form in which the values for the Grid is populated as soon as the Form is displayed.But i need to populate the grid after the button is clicked based on text box values.
ExtJs:
var url = location.href.substring(0,location.href.indexOf('/', 14));
var grid;
var store;
var userStore;
Ext.onReady(function(){
var rowEditing = Ext.create('Ext.grid.plugin.RowEditing');
Ext.define('userList', {
extend: 'Ext.data.Model',
fields: [{ name: 'id', mapping: 'id' },
{ name: 'name', mapping: 'name' },
{ name: 'firstName' ,mapping:'personalInfo.firstName'},
{ name: 'lastName' ,mapping:'personalInfo.lastName'},
{ name: 'gender' ,mapping:'personalInfo.gender'},
{ name: 'email' ,mapping:'personalInfo.address.email'}
]
});
store = Ext.create('Ext.data.Store', {
model: 'userList',
autoLoad: true,
proxy: {
type: 'ajax',
url : url+'/lochweb/loch/users/getUser',
reader: {
type: 'json',
root: 'Users'
}
}
});
function swapStrore(){
//userStore = store;
userStore = Ext.create('Ext.data.Store', {
model: 'userList',
autoLoad: true,
proxy: {
type: 'ajax',
url : url+'/lochweb/loch/users/getUser',
reader: {
type: 'json',
root: 'Users'
}
}
});
Ext.getCmp('userGrid').getView().refresh();
return userStore;
}
function updateUsers(id){
window.location = url+'/lochportal/createUser.do';
}
var searchUsers = new Ext.FormPanel({
renderTo: "searchUsers",
frame: true,
title: 'Search Users',
bodyStyle: 'padding:5px',
width: 900,
items:[{
xtype:'textfield',
fieldLabel: 'Username',
name: 'userName'
},{
xtype:'textfield',
fieldLabel: 'First Name',
name: 'firstName'
},{
xtype:'textfield',
fieldLabel: 'Last Name',
name: 'lastName'
},
{
xtype: 'button',
text: 'Search',
listeners: {
click: function(){
Ext.Ajax.request({
method:'GET',
url : url+'/lochweb/loch/users/getUser',
params : searchUsers.getForm().getValues(),
success : function(response){
//console.log(response);
//swapStrore();
}
});
}
}
},{
xtype: 'button',
text: 'Cancel',
listeners: {
click: function(){
window.location = url+'/lochportal/viewSuccessForm.do';
}
}
},
grid = Ext.create('Ext.grid.Panel', {
//plugins: [rowEditing],
id:'userGrid',
width: 900,
height: 300,
frame: true,
store: store,
iconCls: 'icon-user',
columns: [{
text: 'ID',
width: 40,
sortable: true,
dataIndex: 'id'
},
{
text: 'Name',
flex: 1,
sortable: true,
dataIndex: 'name',
field: {
xtype: 'textfield'
}
},
{
text: 'FirstName',
flex: 1,
sortable: true,
dataIndex: 'firstName',
field: {
xtype: 'textfield'
}
},
{
text: 'LastName',
flex: 1,
sortable: true,
dataIndex: 'lastName',
field: {
xtype: 'textfield'
}
},
{
text: 'Gender',
flex: 1,
sortable: true,
dataIndex: 'gender',
field: {
xtype: 'textfield'
}
},
{
text: 'Email',
flex: 1,
sortable: true,
dataIndex: 'email',
field: {
xtype: 'textfield'
}
},
{
xtype: 'actioncolumn',
width: 50,
items:[{
icon : '/lochportal/extJS/resources/themes/images/access/window/edit.gif', // Use a URL in the icon config
tooltip: 'Sell stock',
handler: function(grid, rowIndex, colIndex) {
var rec = store.getAt(rowIndex);
//alert("Sell " + rec.get('id'));
updateUsers(rec.get('id'));
}
}]
}]
})]
});
var win = new Ext.Window({
layout:'fit',
closable: false,
resizable: true,
plain: true,
border: false,
items: [searchUsers]
});
win.show();
});
How to populate the grid after search button is clicked?
Thanks
Use bindStore() method of the grid to assign new or different store to grid which is already displayed. If you want to first show an empty grid - either filter all records out or assign store property to null initially.

Setting the reader on a extjs store

I have a store on extjs4 that return a list of objects, and i want to set the reader property to be able to count the elements so i can use paging afterward.
For reference, the example that extjs use already comes with a count property(totalCount) and the type of object listed(topics), while mine dont have it, just the list.
for reference:
example
Also, in my code the grid doesnt recognize the limit of results per page, but the paging toolbar does:
var sm = Ext.create('Ext.selection.CheckboxModel');
Ext.define('Cliente', {
extend: 'Ext.data.Model',
fields: [{
name: 'ID',
type: 'int'
}, {
name: 'Nome',
type: 'string'
}, {
name: 'Email',
type: 'string'
}, {
name: 'RazaoSocial',
type: 'string'
}, {
name: 'TipoDeCliente',
type: 'string'
}],
idProperty: 'ID'
});
var store = Ext.create('Ext.data.Store', {
pageSize: 3,
model: 'Cliente',
remoteSort: true,
proxy: {
type: 'ajax',
url: 'http://localhost:4904/Cliente/ObterClientes',
extraParams: {
nome: '',
tipopessoa: '',
email: '',
cpf: '',
estado: '',
cidade: '',
cep: ''
},
reader: {
type: 'json',
root: 'data'
},
simpleSortMode: true
},
sorters: [{
property: 'Email',
direction: 'DESC'
}]
});
var pluginExpanded = true;
var grid = Ext.create('Ext.grid.Panel', {
width: 500,
height: 250,
title: 'Array Grid',
store: store,
selModel: sm,
loadMask: true,
viewConfig: {
id: 'gv',
trackOver: false,
stripeRows: false
},
columns: [{
id: 'gridid',
text: "ID",
dataIndex: 'ID',
hidden: true
}, {
text: 'Nome',
width: 150,
sortable: true,
dataIndex: 'Nome'
}, {
text: 'Tipo de Cliente',
width: 100,
sortable: true,
dataIndex: 'TipoDeCliente'
}, {
text: 'Email',
width: 150,
sortable: true,
dataIndex: 'Email'
}],
bbar: Ext.create('Ext.PagingToolbar', {
store: store,
displayInfo: true,
displayMsg: 'Exibindo clientes {0} - {1} of {2}',
emptyMsg: "Nenhum cliente"
}),
renderTo: 'clientes',
});
store.loadPage(1);
The store needs the total count to calculate the paging parameters and to show the total. Your server side implementation must change to add that count with your data.
Also load the data like this store.load(); instead of loadPage.
EDIT: you also have an extra comma here: renderTo: 'clientes', I would suggest running your code through JSLint.

Loading combobox with json data in ExtJS 4

Im just trying to simply load some json data into my combobox using a basic data store. Here is my json data:
{"services": [{"id": 1, "name": "dropbox"}, {"id": 2, "name": "facebook"}, {"id": 3, "name": "twitter"}]}
Here is my extjs 4 code:
Ext.onReady(function(){
Ext.define('ServiceList', {
extend: 'Ext.data.Model',
fields: [
'id', 'name'
]
});
var store = Ext.create('Ext.data.Store', {
model: 'ServiceList',
proxy: {
type: 'json',
url: '/account/service/list',
reader: {
root: 'services',
totalProperty: 'totalCount'
}
}
});
store.load();
Ext.create('Ext.panel.Panel', {
layout: 'auto',
title: 'VAC',
width: '100%',
renderTo: 'vac-app-window',
items: [{
xtype: 'tabpanel',
autoTabs:true,
activeTab: 0,
border:false,
defaults: {autoHeight:true, bodyStyle:'padding:10px'},
items: [{
title: 'Data Services',
items: [{
xtype:'combo',
store:store
}]
}]
}]
});
});
Everything is being done on localhost so no cross domain stuff. I've been going through documentation but just can't figure out what im doing wrong.
As always any tips is much appreciated!
Update:
I edited some changes to the datastore and am getting a bit farther:
Ext.define('ServiceList', {
extend: 'Ext.data.Model',
fields: [
{name:'id', type:'int'},
{name:'name', type:'string'}
]
});
var store = Ext.create('Ext.data.Store', {
model: 'ServiceList',
proxy: {
type: 'ajax',
url: '/account/service/list',
reader: {
root: 'services',
type: 'json'
}
}
});
store.load();
Now when the page loads or I attempt to click the combobox the url it is addressing is:
GET /account/service/list?_dc=1318340688155&page=1&start=0&limit=25
From my reading this looks like jsonp but I dont know where the page,start, and limit params come from?
Update2:
Thanks to the help from Molecule Man I was able to sort this out:
Ext.onReady(function(){
Ext.define('ServiceList', {
extend: 'Ext.data.Model',
fields: [
{name:'id', type:'int'},
{name:'name', type:'string'}
]
});
var store = Ext.create('Ext.data.Store', {
model: 'ServiceList',
autoLoad: true,
proxy: {
limitParam: undefined,
startParam: undefined,
paramName: undefined,
pageParam: undefined,
noCache:false,
type: 'ajax',
url: '/account/service/list',
reader: {
root: 'services'
}
}
});
Ext.create('Ext.panel.Panel', {
layout: 'auto',
title: 'VAC',
width: '100%',
renderTo: 'vac-app-window',
items: [{
xtype: 'tabpanel',
autoTabs:true,
activeTab: 0,
border:false,
defaults: {autoHeight:true, bodyStyle:'padding:10px'},
items: [{
title: 'Data Services',
items: [{
xtype:'combo',
queryMode:'local',
emptyText: 'Select Service',
store:store,
displayField: 'name',
valueField: 'id'
}]
}]
}]
});
});
Hope this helps anyone else :)
Your combobox' config doesn't contain displayField (defaults to 'text') and valueField(defaults to displayField's value) which are required:
items: [{
xtype:'combo',
displayField: 'name',
valueField: 'id',
store:store
}]