Merge branch 'master' of https://github.com/jgoodman/Freeside
[freeside.git] / rt / share / html / NoAuth / js / combobox.js
1 %# BEGIN BPS TAGGED BLOCK {{{
2 %#
3 %# COPYRIGHT:
4 %#
5 %# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
6 %#                                          <sales@bestpractical.com>
7 %#
8 %# (Except where explicitly superseded by other copyright notices)
9 %#
10 %#
11 %# LICENSE:
12 %#
13 %# This work is made available to you under the terms of Version 2 of
14 %# the GNU General Public License. A copy of that license should have
15 %# been provided with this software, but in any event can be snarfed
16 %# from www.gnu.org.
17 %#
18 %# This work is distributed in the hope that it will be useful, but
19 %# WITHOUT ANY WARRANTY; without even the implied warranty of
20 %# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21 %# General Public License for more details.
22 %#
23 %# You should have received a copy of the GNU General Public License
24 %# along with this program; if not, write to the Free Software
25 %# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 %# 02110-1301 or visit their web page on the internet at
27 %# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
28 %#
29 %#
30 %# CONTRIBUTION SUBMISSION POLICY:
31 %#
32 %# (The following paragraph is not intended to limit the rights granted
33 %# to you to modify and distribute this software under the terms of
34 %# the GNU General Public License and is only of importance to you if
35 %# you choose to contribute your changes and enhancements to the
36 %# community by submitting them to Best Practical Solutions, LLC.)
37 %#
38 %# By intentionally submitting any modifications, corrections or
39 %# derivatives to this work, or any other work intended for use with
40 %# Request Tracker, to Best Practical Solutions, LLC, you confirm that
41 %# you are the copyright holder for those contributions and you grant
42 %# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
43 %# royalty-free, perpetual, license to use, copy, create derivative
44 %# works based on those contributions, and sublicense and distribute
45 %# those contributions and any derivatives thereof.
46 %#
47 %# END BPS TAGGED BLOCK }}}
48 function ComboBox_InitWith(n) {
49     if ( typeof( window.addEventListener ) != "undefined" ) {
50         window.addEventListener("load", ComboBox_Init(n), false);
51     } else if ( typeof( window.attachEvent ) != "undefined" ) {
52         window.attachEvent("onload", ComboBox_Init(n));
53     } else {
54         ComboBox_Init(n)();
55     }
56 }
57 function ComboBox_Init(n) {
58     return function () {
59         if ( ComboBox_UplevelBrowser( n ) ) {
60             ComboBox_Load( n );
61         }
62     }
63 }
64 function ComboBox_UplevelBrowser( n ) {
65     if( typeof( document.getElementById ) == "undefined" ) return false;
66     var combo = document.getElementById( n + "_Container" );
67     if( combo == null || typeof( combo ) == "undefined" ) return false;
68     if( typeof( combo.style ) == "undefined" ) return false;
69     if( typeof( combo.innerHTML ) == "undefined" ) return false;
70     return true;
71 }
72 function ComboBox_Load( comboId ) {
73     var combo  = document.getElementById( comboId + "_Container" );
74     var button = document.getElementById( comboId + "_Button" );
75     var list   = document.getElementById( comboId + "_List" );
76     var text   = document.getElementById( comboId );
77     
78     
79     combo.List = list;
80     combo.Button = button;
81     combo.Text = text;
82     
83     button.Container = combo;
84     button.Toggle = ComboBox_ToggleList;
85     button.onclick = button.Toggle;
86     button.onmouseover = function(e) { this.Container.List.DisableBlur(e); };
87     button.onmouseout = function(e) { this.Container.List.EnableBlur(e); };
88     button.onselectstart = function(e){ return false; };
89     button.style.height = ( list.offsetHeight - 4 ) + "px";
90     
91     text.Container = combo;
92     text.TypeDown = ComboBox_TextTypeDown;
93     text.KeyAccess = ComboBox_TextKeyAccess;
94     text.onkeyup = function(e) { this.KeyAccess(e); this.TypeDown(e); };
95     
96     list.Container = combo;
97     list.Show = ComboBox_ShowList;
98     list.Hide = ComboBox_HideList;
99     list.EnableBlur = ComboBox_ListEnableBlur;
100     list.DisableBlur = ComboBox_ListDisableBlur;
101     list.Select = ComboBox_ListItemSelect;
102     list.ClearSelection = ComboBox_ListClearSelection;
103     list.KeyAccess = ComboBox_ListKeyAccess;
104     list.FireTextChange = ComboBox_ListFireTextChange;
105     list.onchange = null;
106     list.onclick = function(e){ this.Select(e); this.ClearSelection(); this.FireTextChange(); };
107     list.onkeyup = function(e) { this.KeyAccess(e); };
108     list.EnableBlur(null);
109     list.style.position = "absolute";
110     list.size = ComboBox_GetListSize( list );
111     list.IsShowing = true;
112     list.Hide();
113     
114 }
115 function ComboBox_InitEvent( e ) {
116     if( typeof( e ) == "undefined" && typeof( window.event ) != "undefined" ) e = window.event;
117     if( e == null ) e = new Object();
118     return e;
119 }
120 function ComboBox_ListClearSelection() {
121             if ( typeof( this.Container.Text.createTextRange ) == "undefined" ) return;
122     var rNew = this.Container.Text.createTextRange();
123     rNew.moveStart('character', this.Container.Text.value.length) ;
124     rNew.select();
125 }
126 function ComboBox_GetListSize( theList ) {
127     ComboBox_EnsureListSize( theList );
128     return theList.listSize;
129 }
130 function ComboBox_EnsureListSize( theList ) {
131     if ( typeof( theList.listSize ) == "undefined" ) {
132         if( typeof( theList.getAttribute ) != "undefined" ) {
133             if( theList.getAttribute( "size" ) != null && theList.getAttribute( "size" ) != "" ) {
134                 theList.listSize = theList.getAttribute( "size" );
135                 return;
136             }
137         }
138         if( theList.options.length > 0 ) {
139             theList.listSize = theList.options.length;
140             return;
141         }
142         theList.listSize = 4;
143     }
144 }
145 function ComboBox_ListKeyAccess(e) { //Make enter/space and escape do the right thing :)
146     e = ComboBox_InitEvent( e );
147     if( e.keyCode == 13 || e.keyCode == 32 ) {
148         this.Select();
149         return;
150     }
151     if( e.keyCode == 27 ) {
152         this.Hide();
153         this.Container.Text.focus();
154         return;
155     }
156 }
157 function ComboBox_TextKeyAccess(e) { //Make alt+arrow expand the list
158     e = ComboBox_InitEvent( e );
159     if( e.altKey && (e.keyCode == 38 || e.keyCode == 40) ) {
160             this.Container.List.Show();
161     }
162 }
163 function ComboBox_TextTypeDown(e) { //Make the textbox do a type-down on the list
164     e = ComboBox_InitEvent( e );
165     var items = this.Container.List.options;
166     if( this.value == "" ) return;
167     var ctrlKeys = Array( 8, 46, 37, 38, 39, 40, 33, 34, 35, 36, 45, 16, 20 );
168     for( var i = 0; i < ctrlKeys.length; i++ ) {
169         if( e.keyCode == ctrlKeys[i] ) return;
170     }
171     for( var i = 0; i < items.length; i++ ) {
172         var item = items[i];
173         if( item.text.toLowerCase().indexOf( this.value.toLowerCase() ) == 0 ) {
174             this.Container.List.selectedIndex = i;
175             if ( typeof( this.Container.Text.createTextRange ) != "undefined" ) {
176                                     this.Container.List.Select();
177                             }
178             break;
179         }
180     }
181 }
182 function ComboBox_ListFireTextChange() {
183     var textOnChange = this.Container.Text.onchange;
184             if ( textOnChange != null && typeof(textOnChange) == "function" ) {
185                     textOnChange();
186             }
187 }
188 function ComboBox_ListEnableBlur(e) {
189     this.onblur = this.Hide;
190 }
191 function ComboBox_ListDisableBlur(e) {
192     this.onblur = null;
193 }
194 function ComboBox_ListItemSelect(e) {
195     if( this.options.length > 0 ) {
196         var text = this.Container.Text;
197         var oldValue = text.value;
198         var newValue = this.options[ this.selectedIndex ].text;
199         text.value = newValue;
200         if ( typeof( text.createTextRange ) != "undefined" ) {
201             if (newValue != oldValue) {
202                 var rNew = text.createTextRange();
203                 rNew.moveStart('character', oldValue.length) ;
204                 rNew.select();
205             }
206         }
207     }
208     this.Hide();
209     this.Container.Text.focus();
210 }
211 function ComboBox_ToggleList(e) {
212     if( this.Container.List.IsShowing == true ) {
213         this.Container.List.Hide();
214     } else {
215         this.Container.List.Show();
216     }
217 }
218 function ComboBox_ShowList(e) {
219     if ( !this.IsShowing && !this.disabled ) {
220         this.style.top = '1.2em';//( this.Container.offsetHeight + ComboBox_RecursiveOffsetTop(this.Container,true) ) + "px";
221         this.style.left = '0px';// ( ComboBox_RecursiveOffsetLeft(this.Container,true) + 1 ) + "px";
222         ComboBox_SetVisibility(this,true);
223         this.focus();
224         this.IsShowing = true;
225     }
226 }
227 function ComboBox_HideList(e) {
228     if( this.IsShowing ) {
229                     ComboBox_SetVisibility(this,false);
230         this.IsShowing = false;
231     }
232 }
233 function ComboBox_SetVisibility(theList, isVisible) {
234     setVisibility(theList, isVisible);
235 }
236 function ComboBox_RecursiveOffsetTop(thisObject,isFirst) {
237     if(thisObject.offsetParent) {
238         if ( thisObject.style.position == "absolute" && !isFirst && typeof(document.designMode) != "undefined" ) {
239             return 0;
240         }
241         return (thisObject.offsetTop + ComboBox_RecursiveOffsetTop(thisObject.offsetParent,false));
242     } else {
243         return thisObject.offsetTop;
244     }
245 }
246 function ComboBox_RecursiveOffsetLeft(thisObject,isFirst) {
247     if(thisObject.offsetParent) {
248         if ( thisObject.style.position == "absolute" && !isFirst && typeof(document.designMode) != "undefined" ) {
249             return 0;
250         }
251         return (thisObject.offsetLeft + ComboBox_RecursiveOffsetLeft(thisObject.offsetParent,false));
252     } else {
253         return thisObject.offsetLeft;
254     }
255 }
256 function ComboBox_SimpleAttach(selectElement,textElement) {
257     textElement.value = selectElement.options[ selectElement.options.selectedIndex ].text;
258     var textOnChange = textElement.onchange;
259     if ( textOnChange != null && typeof( textOnChange ) == "function" ) {
260         textOnChange();
261     }
262 }