/*---------------- FILE HEADER --------------------------------------- This file is part of Geoide. Copyright (C) 2005-2006 by: IDgis B.V. http://www.idgis.nl This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Contact: Herman Assink IDgis bv P.O. Box 15 7450 AA Holten The Netherlands E-Mail: herman.assink@idgis.nl * @version 1.4.0 * @author IDgis team * ------------------------------------------------------------------------*/ import mx.controls.ComboBox; class nl.idgis.giclient.framework.IDComboBox extends ComboBox { private var m_lastFoundIndex:Number = -1; private var isOpen:Boolean = false; private var itemSelected:Boolean = false; private var m_caseSensitive:Boolean = false; private var boxWidth:Number = 100; private var minWidth:Number = 100; private var maxWidth:Number = 300; private var maxListWidth:Number = 350; function IDComboBox () { super(); } private var m_className:String = "nl.idgis.giclient.framework.IDComboBox"; public function get className():String { return m_className; } function onLoad():Void { this.addEventListener("open", onOpenComboBox); this.addEventListener("close", onCloseComboBox); this.addEventListener("change", onChangeComboBox); this.addEventListener("enter", onChangeComboBox); //unselect item if lastFoundIndex has not been set, NB onLoad() executes asynchronously if (m_lastFoundIndex == -1) selectedIndex = null; } public function getCaseSensitive():Boolean { return this.m_caseSensitive; } public function setCaseSensitive(caseSens:Boolean):Void { this.m_caseSensitive = caseSens; } public function getLastFoundIndex():Number { return this.m_lastFoundIndex; } public function setLastFoundIndex(index:Number):Void { this.m_lastFoundIndex = index; } public function setMinimumWidth(width:Number):Void { this.minWidth = width; } public function setMaximumWidth(width:Number):Void { this.maxWidth = width; } public function setMaximumListWidth(width:Number):Void { this.maxListWidth = width; } public function resize():Void { var longestString:String = ""; var currentString:String = ""; var dataValue; var textFormat:TextFormat = new TextFormat(); textFormat.font = textField.getStyle("fontFamily"); textFormat.size = textField.getStyle("fontSize"); var textExtent:Object = null; var textWidth:Number = 0; var maxTextWidth:Number = 0; for (var i:Number = 0; i < dataProvider.length; i++) { dataValue = dataProvider.getItemAt(i); if (!(dataValue instanceof Object)) { dataValue = dataValue; //item is string } else { if (dataValue.label != undefined) { dataValue = dataValue.label; } //first test for labelFunction, because labelField is also defined in this case (=label) else if (labelFunction != undefined) { dataValue = labelFunction.call(dataValue, dataValue); } else if (labelField != undefined) { dataValue = dataValue[labelField]; } } currentString = dataValue; textWidth = textFormat.getTextExtent(currentString).textFieldWidth; if (maxTextWidth < textWidth) { maxTextWidth = textWidth; } } textExtent = textFormat.getTextExtent(longestString); var buttonWidth:Number = 18; var margin:Number = 14; textWidth = maxTextWidth; var listWidth:Number = textWidth + buttonWidth + margin; if (textWidth + buttonWidth + margin <= minWidth) { listWidth = minWidth; boxWidth = minWidth; }else if (textWidth + buttonWidth + margin >= maxWidth) { boxWidth = maxWidth; } else { boxWidth = textWidth + buttonWidth + margin; } setSize(boxWidth, this.height); if (listWidth >= maxListWidth){ listWidth = maxListWidth; } dropdownWidth = listWidth; } function getWidth():Number{ return boxWidth; } private function onOpenComboBox(eventObject:Object):Void { //trace("onOpenComboBox, selectedIndex: " + selectedIndex + " m_lastFoundIndex: " + m_lastFoundIndex); isOpen = true; } private function onCloseComboBox(eventObject:Object):Void { //trace("onCloseComboBox, selectedIndex: " + selectedIndex + " m_lastFoundIndex: " + m_lastFoundIndex); //trigger a change event only when the last found item has been clicked or is typed isOpen = false; if (selectedIndex == m_lastFoundIndex) { //NB undefined == null!!?? dispatchEvent({type:"change", target:this}); } } private function onChangeComboBox(eventObject:Object):Void { var boxValue:String = value.toString(); if (!m_caseSensitive) boxValue = boxValue.toUpperCase(); var boxText:String = text; var caseValue:String = ""; var dataValue; var valueFound:Boolean = false; if (selectedIndex > -1) { if (!(selectedItem instanceof Object)) { text = String(selectedItem); } else if (selectedItem.label != undefined) { text = String(selectedItem.label); } else if (labelFunction != undefined) { text = String(labelFunction.call(selectedItem, selectedItem)); } else if (labelField != undefined) { text = selectedItem[labelField]; } dispatchEvent({type:"select", target:this}); itemSelected = true; return; } else { m_lastFoundIndex = -1; if (!isOpen) { open(); //is delayed isOpen = true; } if (boxValue != "") { for (var i:Number = 0; i < dataProvider.length; i++) { dataValue = dataProvider.getItemAt(i); if (!(dataValue instanceof Object)) { dataValue = dataValue; //item is string } else { if (dataValue.label != undefined) { dataValue = dataValue.label; } //first test for labelFunction, because labelField is also defined in this case (=label) else if (labelFunction != undefined) { dataValue = labelFunction.call(dataValue, dataValue); } else if (labelField != undefined) { dataValue = dataValue[labelField]; } } if (m_caseSensitive) caseValue = dataValue; else caseValue = dataValue.toUpperCase(); if (caseValue.indexOf(boxValue) == 0) { valueFound = true; m_lastFoundIndex = i; selectedIndex = i; close(); //is delayed, ignored if followed by open() isOpen = false; open(); //is delayed isOpen = true; if (boxValue != caseValue) { text = boxText; if (itemSelected) { dispatchEvent({type:"unselect", target:this}); itemSelected = false; } } break; } } } if (!valueFound) { selectedIndex = null; text = boxText; } } } }