PDA

View Full Version : Search box with 3 triggers



manugoel2003
15 Jul 2007, 12:14 PM
Hi,

I have been working on making a search box with 3 triggers. The 1st one will be on the left of the text box and will contain a menu. The 2nd one will be to the immediate right of the text box and will act like a reset button for that search box. The 3rd one will be in the extreme right and will act like a "search" button. For further clarity please see the attachment.

978
I am facing a couple of problems.
1. As you can see in the snapshot, the 1st trigger is overlapping the text field.
2. I am not able to attach a menu to the 1st trigger. (The method I have used is wrong but it is just to highlight what I want)

Here is my code


Ext.namespace("ux");
Ext.ux.xsearch = function(config){
if (!config){return;}
};

Ext.ux.xsearch = Ext.extend(Ext.form.TriggerField, {
menu: null,
initComponent : function(){
Ext.ux.xsearch.superclass.initComponent.call(this);

this.triggerConfig = {
tag:'span', cls:'x-form-twin-triggers', cn:[
{tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.trigger2Class},
{tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.trigger3Class}
]};
},

getTrigger : function(index){
return this.triggers[index];
},

initTrigger : function(){
var ts = this.wrap.select('.x-form-trigger', true);
this.wrap.setStyle('overflow', 'hidden');
var triggerField = this;
ts.each(function(t, all, index){
t.hide = function(){
var w = triggerField.wrap.getWidth();
this.dom.style.display = 'none';
triggerField.el.setWidth(w-triggerField.trigger.getWidth());
};
t.show = function(){
var w = triggerField.wrap.getWidth();
this.dom.style.display = '';
triggerField.el.setWidth(w-triggerField.trigger.getWidth());
};
var triggerIndex = 'Trigger'+(index+1);

if(this['hide'+triggerIndex]){
t.dom.style.display = 'none';
}
t.on("click", this['on'+triggerIndex+'Click'], this, {preventDefault:true});
t.addClassOnOver('x-form-trigger-over');
t.addClassOnClick('x-form-trigger-click');
}, this);
this.triggers = ts.elements;
},

onRender : function(ct, position){
Ext.form.TriggerField.superclass.onRender.call(this, ct, position);
this.wrap = this.el.wrap({cls: "x-form-field-wrap"});
if (!Ext.isEmpty(this.menu))
{
this.menuTrigger = this.wrap.insertFirst({
tag: "img",
src: Ext.BLANK_IMAGE_URL,
cls: "x-form-trigger " + this.trigger1Class,
menu: this.menu // <------------ I was talking abt this. I want my menu here.
});
}
this.trigger = this.wrap.createChild(this.triggerConfig ||
{tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.triggerClass});
if(this.hideTrigger){
this.trigger.setDisplayed(false);
}
this.initTrigger();
if(!this.width){
var menuTriggerWidth = (this.menuTrigger) ? this.menuTrigger.getWidth() : 0;
this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth() + menuTriggerWidth);
}
},

onTrigger1Click : Ext.emptyFn,
onTrigger2Click : Ext.emptyFn,
onTrigger3Click : Ext.emptyFn
});


And my HTML code is


<input id="xs_field_01" type="text" value="manu">
<script language="JavaScript">
var mymenu = new Ext.menu.Menu({
id: 'mainMenu',
items: [
new Ext.menu.CheckItem({
text: 'I like Ext',
checked: true
}),
new Ext.menu.CheckItem({
text: 'Ext for jQuery',
checked: true
})
]
});

var trigger = new Ext.ux.xsearch({
trigger1Class: "x-form-trigger",
trigger2Class: "x-form-clear-trigger",
trigger3Class: "x-form-search-trigger",
menu: mymenu
});
trigger.onTrigger2Click = function(){
alert("trigger 1");
};
trigger.onTrigger3Click = function(){
alert("trigger 2");
};
trigger.applyTo('xs_field_01');
</script>


Can anyone help me out, I am on a very tight deadline? And btw Jack, as you must have seen, I have borrowed almost entirely from TwinTriggerField. It helped me immensely, thanx.

manugoel2003
18 Jul 2007, 12:44 AM
I will be very grateful if someone could help me out with this one..... I am really stuck here

cfulnecky
19 Jul 2007, 7:18 AM
I'm having some trouble replicating your results, I do not have any trigger elements displaying. I believe it has something to do with x-form-twin-triggers not being declared because examination of the dom shows the span and images are there.

Also I had to copy the TwinTriggerField class from a TriggerField.js I found using a google search.

Any ideas?

manugoel2003
19 Jul 2007, 9:05 AM
are you using the latest Ext 1.1 RC1??..... and also crosscheck if you have included all the files.... here is a list of files I included

1. reset-min.css
2. ext-all.css
3. ext-base.js
4. ext-all.js
5. xsearch.js (which contains the JavaScript code for subclassing the TriggerField I shared above)

manugoel2003
19 Jul 2007, 9:14 AM
and yeah.... did u include


Ext.BLANK_IMAGE_URL = "<path_to_ext_folder>/resources/images/default/s.gif";


coz, if u r disconnected from the net and u have not set this line then u will see wierd results, like only the left most trigger being visible out of the three.

cfulnecky
19 Jul 2007, 3:55 PM
are you using the latest Ext 1.1 RC1??.....
Yeap, that did the trick! Thanks!

taelons
26 Jul 2007, 3:31 AM
Hi,
I am facing a couple of problems.
1. As you can see in the snapshot, the 1st trigger is overlapping the text field.
2. I am not able to attach a menu to the 1st trigger. (The method I have used is wrong but it is just to highlight what I want)


Hello manu!

I attach a menu to triggerfield in the onTriggerClick function, I'll deep in your code later,
maybe I can get my solution depend on yours, thanks.

btw would you give me some advice on my problem:

http://extjs.com/forum/showthread.php?t=9960&highlight=triggerfield

jack.slocum
6 Aug 2007, 7:04 AM
Here are some things to try:

- In the CSS for your custom field, apply a left margin to the input.x-form-text element in your trigger field equal to the width of the first trigger.

- You will need to override onResize (take a look at TriggerField) to include both triggers.

manugoel2003
6 Aug 2007, 8:20 AM
Thanx Jack.... i'll try it out and let everyone know

manugoel2003
10 Aug 2007, 5:21 AM
Thanx Jack, I adjusted the code as you pointed out and it is working fine..... I had to a lot of changes to ur TwinTriggerField class....... the code is a mess right now, but I'll work on it later tonight

The Ext.ux.xsearch class

Ext.namespace("Ext.ux");
Ext.ux.xsearch = function(config){
if (!config){return;}
};

Ext.ux.xsearch = Ext.extend(Ext.form.TriggerField, {
defaultTrigger1: { cls: "", click: Ext.emptyFn },
defaultTrigger2: { cls: "x-form-clear-trigger", click: Ext.emptyFn },
defaultTrigger3: { cls: "x-form-search-trigger", click: Ext.emptyFn },

initComponent : function(){
Ext.ux.xsearch.superclass.initComponent.call(this);

if (!this.trigger1){ this.trigger1 = {}; }
if (!this.trigger2){ this.trigger2 = {}; }
if (!this.trigger3){ this.trigger3 = {}; }

Ext.applyIf(this.trigger1, this.defaultTrigger1);
Ext.applyIf(this.trigger2, this.defaultTrigger2);
Ext.applyIf(this.trigger3, this.defaultTrigger3);
},

getTrigger : function(index){
return this.triggers[index];
},

initTrigger : function(){
var ts = this.wrap.select('.x-form-trigger', true);
this.wrap.setStyle('overflow', 'hidden');
var triggerField = this;
ts.each(function(t, all, index){
t.hide = function(){
var w = triggerField.wrap.getWidth();
this.dom.style.display = 'none';
triggerField.el.setWidth(w-triggerField.trigger.getWidth()-triggerField.menuTrigger.getWidth());
if (index == 0)
{
triggerField.getEl().dom.style.marginLeft = "0px";
triggerField.el.setWidth(triggerField.el.getWidth()-1);
}
};
t.show = function(){
var w = triggerField.wrap.getWidth();
this.dom.style.display = '';
triggerField.el.setWidth(w-triggerField.trigger.getWidth()-triggerField.menuTrigger.getWidth());
if (index == 0)
{
triggerField.getEl().dom.style.marginLeft = "16px";
}
};
var triggerIndex = 'trigger'+(index+1);

t.on("click", function(){
if (this[triggerIndex].click.createDelegate(this)() != false && this[triggerIndex].menu)
{
this[triggerIndex].menu.showAt([t.getLeft(), t.getBottom()]);
}
}, this, {preventDefault:true});
t.addClassOnOver('x-form-trigger-over');
t.addClassOnClick('x-form-trigger-click');
}, this);

this.triggers = ts.elements;
this.getEl().dom.style.marginLeft = "16px";
},

onRender : function(ct, position){
Ext.form.TriggerField.superclass.onRender.call(this, ct, position);
this.wrap = this.el.wrap({cls: "x-form-field-wrap xsearch"});

this.menuTrigger = this.wrap.insertFirst({
tag: "img",
src: Ext.BLANK_IMAGE_URL,
cls: "x-form-trigger " + this.trigger1.cls
});
this.trigger = this.wrap.createChild(
this.triggerConfig ||
{
tag:'span',
cls:'x-form-twin-triggers',
cn:[
{tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.trigger2.cls},
{tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.trigger3.cls}
]
}
);

this.initTrigger();
if(!this.width){
var menuTriggerWidth = (this.menuTrigger) ? this.menuTrigger.getWidth() : 0;
this.wrap.setWidth(this.el.getWidth() + this.trigger.getWidth() + menuTriggerWidth);
}

if(this.hideTriggers){
this.triggers[0].hide();
this.triggers[1].hide();
this.triggers[2].hide();
}
if(this.hideTrigger1){ this.triggers[0].hide(); }
if(this.hideTrigger2){ this.triggers[1].hide(); }
if(this.hideTrigger3){ this.triggers[2].hide(); }
},

onResize : function(w, h){
Ext.form.TriggerField.superclass.onResize.apply(this, arguments);
if(typeof w == 'number'){
this.el.setWidth(this.adjustWidth('input', w - this.trigger.getWidth() - this.menuTrigger.getWidth()));
}
}
});

The HTML code

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<link rel="stylesheet" type="text/css" href="/library/ext-1.1/resources/css/reset-min.css" />
<link rel="stylesheet" type="text/css" href="/library/ext-1.1/resources/css/ext-all.css" />
<link rel="stylesheet" type="text/css" href="/library/ext-1.1/resources/css/xtheme-gray.css" />

<script language="JavaScript" src="/library/ext-1.1/adapter/ext/ext-base.js"></script>
<script language="JavaScript" src="/library/ext-1.1/ext-all.js"></script>
<script language="JavaScript" src="xsearch.js"></script>
</head>

<body>
<input id="xs_field_01" type="text" value="">
<script language="JavaScript">
var mymenu = new Ext.menu.Menu({
id: 'mainMenu',
items: [
new Ext.menu.CheckItem({
text: 'I like Ext',
checked: true
}),
new Ext.menu.CheckItem({
text: 'Ext for jQuery',
checked: true
})
]
});

var trigger = new Ext.ux.xsearch({
trigger1: {
menu: mymenu
},
trigger2: {
click: function(){
this.reset();
}
},
trigger3: {
click: function(){
alert("Here comes the code for searching");
}
}
});
trigger.applyTo('xs_field_01');
</script>
</body>
</html>