I am using ExtJs4.I have a form in my web application in which there is text box.The scenario is to provide an AJAX like search(like Google) when any key is pressed in the text box.Search will look into a web service and display the result(JSON object) in drop drown.Similar to Google search.
Is there any idea,link or tutorial for doing this?
Thanks
You could use ComboBox for this. With trigger or without one (that looks like a TextBox).
Sencha provides good examples:
http://docs.sencha.com/ext-js/4-0/#!/example/form/combos.html
http://docs.sencha.com/ext-js/4-0/#!/example/form/forum-search.html
This is a simple example:
{
xtype: 'combo',
id: 'myCombo',
store: Ext.create('Ext.data.ArrayStore', {
model: Ext.define('ComboModel', {
extend: 'Ext.data.Model',
fields: ['id','data1','data2']
}),
proxy: {
type: 'ajax',
url : 'data.json',
reader: {
type: 'array'
}
}
}),
triggerAction: 'query',
minChars: 2,
fieldLabel: 'Search',
displayField: 'data1',
msgTarget: 'side',
triggerCls : 'x-form-search-trigger', // Search Icon For Instance
listConfig: {
getInnerTpl: function() {
return '<div>{data1}</div><div>{data2}</div>';
}
}
}
And JSON file:
[
['1','data1-1','data2-1'],
['2','data1-2','data2-2'],
['3','data1-3','data2-3'],
['4','data1-4','data2-4'],
['5','data1-5','data2-5']
]
Try this example: http://docs.sencha.com/ext-js/4-0/#!/example/form/forum-search.html
I think this example http://docs.sencha.com/ext-js/4-1/#!/example/form/forum-search.html will be interesting for you. This realization use standard combobox control. In your case you need to set minChars property = 1, in this case store binded to Combobox will generate standard READ query with filter param to server. You can generate results there.
Related
I want to realize the functionality that we can search the users' name by typing in the first character of their names. I need to use Javascript to create a custom html.
Is there anyone who has done this before could help me?
In the example from this repository, a user combobox Rally.ui.combobox.UserComboBox searches for matching values dynamically based on the first couple of characters.
This default functionality displays the expected values after the second character is entered.
var u = Ext.create('Rally.ui.combobox.UserComboBox',{
id: 'u',
project: project,
fieldLabel: 'select user',
listeners:{
ready: function(combobox){
this._onUserSelected(combobox.getRecord());
},
select: function(combobox){
this._onUserSelected(combobox.getRecord());
},
scope: this
}
});
this.add(u);
},
If you want to load all users (do not limit the selection to team members and editors of a specific project) you may use Rally.ui.combobox.Combobox instead of Rally.ui.combobox.UserComboBox, and set the model to User. But to workaround a default behavior where only the current user populates the combobox, use a filter that would filter in all users. In the example below ObjectID > 0 is used. This combobox will be populated by all users independently of the project picker. This fragment is not a part of a custom app example above:
{
xtype: 'rallycombobox',
fieldLabel: 'select project',
storeConfig: {
autoLoad: true,
model: 'User',
filters:[
{
property: 'ObjectID',
operator: '>',
value: 0
}
],
sorters: [
{
property: 'UserName',
direction: 'ASC'
}
]
}
}
You'll want to use the Web Services API. Here's how I would do it...
The API doesn't allow you to specify a placement of a character in the filter, but you can require that it exists somewhere in the name, that filter would look like:
[{
property : "FirstName",
operator : "contains",
value : "A" //Whatever letter you're looking to start with
}]
Now, once the store is loaded, use a second function to filter the records to only those which start with your character:
store.filterBy(function(item) {
return item.get("FirstName")[0] === "A";
});
Hope this helps :)
I am using extjs 4.0.7. I have a requirement wherein I have two combo boxes in the edit mode of a grid and I need to change the data in the second based on the value selected in the first one.
I am using MVC architecture for extjs and a java code that returns json string to populate data in the combo boxes. The code for my first combo box is:
view file:
items: [{
id: 'country',
header: 'Countries',
field: {
xtype: 'combo',
store: [
["USA","USA"],
["India","India"],
],
editable: false,
allowBlank: false,
listeners: {
select: function(combo, records, eOpts){
contactTypeGrid = combo.getValue();
myGrid.fireEvent('LoadStateOnSelect');
}
}
}
},
{
id: 'states',
header: 'Sates',
dataIndex: 'states',
field: {
xtype: 'combo',
store: 'StateStore',
valueField: 'stateDesc',
displayField: 'stateText',
}
}, ....
]
controller:
LoadStateOnSelect: function(){
contactTypeGrid = contactTypeGrid.toLowerCase();
var stateStore = this.getStateStoreStore();
stateStore.getProxy().url = "myURL.do";
stateStore.getProxy().extraParams.act = contactTypeGrid;
stateStore.load();
},
However, when I run this code, the data in the second store changes in the background but a Loading mask continues to appear in front due to which I cannot select any value.
How should I resolve the issue of connditional data load? Any help will be much appreciated.
Have you tried clearing the selected value in the combobox before reloading the store? You could try calling the clearValue() method on the combo.
I have a temporary fix for this. However, I am still looking for a solution that is more stable and workable.
Solution:
Whenever changing the data in the dependant store you could expand the combo box which loads the new data correctly.
LoadStateOnSelect: function(){
contactTypeGrid = contactTypeGrid.toLowerCase();
var stateStore = this.getStateStoreStore();
stateStore.getProxy().url = "myURL.do";
stateStore.getProxy().extraParams.act = contactTypeGrid;
statesCombo.expand(); //Here I am assuming that "statesCombo" has a
//reference to the dependant combo box.
stateStore.load();
},
This might save somebody else's time however, In case somebody finds a more viable solution, please let me know as well.
carStore- any store for main combo
carModelStore - store, the content of which should be depended on selection in the carStore
Consider more general and useful example when data is getting from server.
var carModelStore = new Ext.data.Store({
reader: new Ext.data.JsonReader({
fields: ['id', 'car-model'],
root: 'rows'
}),
storeId: 'car-model-store',
proxy: new Ext.data.HttpProxy({
url: 'carmodeldataprovider.json?car-name=lamborghini'
}),
autoLoad: true
});
{ xtype: 'combo', name: 'car-name', fieldLabel: 'Car', mode: 'local', store: carStore, triggerAction: 'all',
listeners: {
select: function(combo, records, eOpts){
var carName = records.get('car-name');
var carModelStore = Ext.StoreMgr.lookup("car-model-store");
carModelStore.proxy.setUrl('carmodeldataprovider.json?car-name=' + carName, false);
carModelStore.reload();
}
}
}
I have an itemselecor inside a grid, and i have an combobox that should reload only the store inside the itemselector( the value fields should remain intact)
Here is the itemselector
var grid = Ext.widget('form', {
id: 'grid',
title: '',
width: 600,
bodyPadding: 10,
renderTo: 'itemselectorproduto',
items: [{
xtype: 'itemselector',
name: 'itemselector',
id: 'itemsel',
anchor: '100%',
imagePath: '/ux/images/',
store: store,
displayField: 'Nome',
valueField: 'ID',
value: vitrine,
allowBlank: true,
msgTarget: 'side'
}]
});
I tried to call the normal store.load(), but it have no effect and it shows no error on the console
If needed i will post more of the code, but i think just this should be enough
Thanks,
Looking through the code if ItemSelector it doesn't look like it supports any changes in the store once it's been binded. It basically creates local copies of the data. And if you call bindStore method to assign different store - it will erase your selection.
You can always improve code in ItemSelector to allow such behavior. It should not be a problem. You can subscribe to datachanged or load event of the store when binding to it, and then handle situation when store data is changed.
Actually i think the best way to do such thing is using ItemSelector`s "populateFromStore". Sure except of extending item selector. In case of extending you should look on the "onBindStore" function of the ItemSelector.
onBindStore: function(store, initial) {
var me = this;
if (me.fromField) {
me.fromField.store.removeAll()
me.toField.store.removeAll();
// Add everything to the from field as soon as the Store is loaded
if (store.getCount()) {
me.populateFromStore(store);
} else {
me.store.on('load', me.populateFromStore, me);
}
}
}
So as you see in case of the empty store it hooks to the load event. And it should be like this:
onBindStore: function(store, initial) {
var me = this;
if (me.fromField) {
me.fromField.store.removeAll()
me.toField.store.removeAll();
me.store.on('load', me.populateFromStore, me);
// Add everything to the from field as soon as the Store is loaded
if (store.getCount()) {
me.populateFromStore(store);
}
}
}
New to sencha touch here. I've checked out quite a few tutorials online. I am having an issue trying to get the value of a text field. The error I am getting when I click my login button is Uncaught TypeError: Cannot call method 'getValue' of undefined. Does that mean my Ext.getCmp is undefined then? I have this panel wrapped in the regular Ext.setup....onReady:.....
var login = new Ext.Panel({
height:'auto',
scroll:'vertical',
layout:{
type:'vbox',
align:'center'
},
items:[
{
cls:'launchscreen',
html:logo,
padding:10
},
new Ext.form.FormPanel({
width:300,
cls:'loginform',
items:[
{
xtype: 'fieldset',
title: 'Login',
items: [
{
xtype: 'textfield',
name : 'username',
label: 'Username',
labelWidth: 85
},
{
xtype: 'passwordfield',
name : 'password',
label: 'Password',
labelWidth: 85
}
]
},
{
xtype: 'button',
text: 'Submit',
ui: 'confirm',
handler:function()
{
alert(Ext.getCmp('username').getValue());
}
}
]
})
]
});
EDIT: I was able to get the value if I set the id property on the text field. I've seen some example where the id isn't set and they get the value based off the name property. So I guess my question now is am I supposed to get the value based off id or name?
Using Ext.getCmp() you have to provide the ID of the element whose value you want. See Sencha API doc's for this:
getCmp( String id )
This is shorthand reference to Ext.ComponentManager.get. Looks up an existing Component by id
Parameters
id : String
The component id
You can also find the element by name, but I think it is faster by ID but perhaps also a bit expensive for the browser's engine. Can't say anything about that really.
Anyway, finding field by name is possible by using findField() method. With this method you should provide the id or name of the field that you want. See API doc: http://docs.sencha.com/ext-js/4-0/#!/api/Ext.form.Basic-method-findField
Example:
var fieldValue= Ext.getCmp("YourFormID").getForm().findField("FieldName").getValue();
I can use the setOptions method to successfully specify the options of a select field as follows:
setOptions(
[ {text: 'First Option', value: 'first'},
{text: 'Second Option', value: 'second'},
{text: 'Third Option', value: 'third'}
])
However, I would instead like setOptions to work with a loaded data store rather than hard coding the text/value array like above.
The store has one item type in it 'vehicle' and the json response from the server which loads it is of the form {'vehicle' :'mercedes'}, {'vehicle' 'jaguar'} (ignore if I have the json syntax wrong, am typing this from memory. And finally, I would be fine with having the value field being the same as the text field for setOptions.
However, I am stumped how to accomplish this. Many thanks to anyone who can help me.
Use this:
{ id: 'theSelect',
name: 'vechicleSelect',
xtype: 'selectfield',
store: storeObejct,
displayField: 'vehicle',
valueField: 'vehicle'
}
Read the whole API here Sencha Touch selectfield
You could cycle through the store and push the data into an array then use the array as the argument for setOptions.
To add to warmachine's answer...
In your view:
{
xtype: 'selectfield',
id: 'NameId',
label: 'Name',
labelWrap: true,
placeHolder: 'name'
},
Controller or initialize function in your view:
initialize: function(){
var me = this;
me.callParent(arguments);
var sto= Ext.getStore('Persons');
sto.load();
var options = [];
sto.each(function(record){
options.push({
value: record.get('displayname'),
text: record.get('displayname')
});
});
var box = Ext.ComponentQuery.query('#NameId')[0];
box.setOptions(options);
},