/****************************************************************************** * Product: Adempiere ERP & CRM Smart Business Solution * * Copyright (C) 2009 SC ARHIPAC SERVICE SRL. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * * under the terms version 2 of the GNU General Public License as published * * by the Free Software Foundation. This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * * with this program; if not, write to the Free Software Foundation, Inc., * * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * *****************************************************************************/ package org.adempiere.webui.window; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import org.adempiere.exceptions.DBException; import org.adempiere.webui.component.AutoComplete; import org.compiere.grid.ed.CityVO; import org.compiere.model.MSysConfig; import org.compiere.util.DB; import org.compiere.util.Env; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.Events; import org.zkoss.zk.ui.event.InputEvent; import org.zkoss.zul.Timer; /** * @author Cristina Ghita - www.arhipac.ro * */ public class WAutoCompleterCity extends AutoComplete implements EventListener { /** * */ private static final long serialVersionUID = 318310285903469314L; private static final int PopupDelayMillis = 500; private final Timer timer = new Timer(PopupDelayMillis); private CityVO m_city = null; private ArrayList<CityVO> m_cities = new ArrayList<CityVO>(); private ArrayList<CityVO> m_citiesShow = new ArrayList<CityVO>(); private final int m_maxRows = MSysConfig.getIntValue("LOCATION_MAX_CITY_ROWS", 7); public static final CityVO ITEM_More = new CityVO(-1, "...", -1, ""); private final int m_windowNo; public WAutoCompleterCity(int m_windowNo) { super(); this.m_windowNo = m_windowNo; this.addEventListener(Events.ON_SELECT, this); } private void showPopupDelayed() { timer.setRepeats(false); timer.start(); } @Override public void onChanging(InputEvent evt) { showPopupDelayed(); refreshData(evt.getValue()); super.onChanging(evt); } public void refreshData(String val) { String search = val; if (m_city != null && m_city.CityName.compareTo(search) != 0) { setCity(null); } m_citiesShow.clear(); this.removeAllItems(); this.setDict(null); this.setDescription(null); boolean truncated = false; search = search.toUpperCase(); int i = 0; for (CityVO vo : m_cities) { if (vo.CityName.toUpperCase().startsWith(search)) { if (i > 0 && i == m_maxRows+1) { m_citiesShow.add(ITEM_More); truncated = true; break; } m_citiesShow.add(vo); i++; } } //if there is no city on the list return false, to not show the popup if (m_citiesShow.isEmpty()) { return; } else { CityVO city = (CityVO) m_citiesShow.get(0); if (city.CityName.equalsIgnoreCase(search)) { m_city = city; return; } } //if the list has only one item, but that item is not equals with m_city //return false to not show any popup if (!truncated && m_citiesShow.size() == 1 && m_city != null && m_citiesShow.get(0).equals(this.m_city)) { return; } String[] cityValues = new String[m_citiesShow.size()]; String[] cityDesc = new String[m_citiesShow.size()]; i = 0; for (CityVO vo : m_citiesShow) { cityValues[i] = vo.CityName; cityDesc[i] = vo.RegionName; i++; } // this.removeAllItems(); this.setDict(cityValues); this.setDescription(cityDesc); } public void fillList() { // Carlos Ruiz - globalqss - improve to avoid going to the database on every keystroke m_cities.clear(); m_citiesShow.clear(); ArrayList<Object> params = new ArrayList<Object>(); final StringBuffer sql = new StringBuffer( "SELECT cy.C_City_ID, cy.Name, cy.C_Region_ID, r.Name" +" FROM C_City cy" +" LEFT OUTER JOIN C_Region r ON (r.C_Region_ID=cy.C_Region_ID)" +" WHERE cy.AD_Client_ID IN (0,?)"); params.add(getAD_Client_ID()); if (getC_Region_ID() > 0) { sql.append(" AND cy.C_Region_ID=?"); params.add(getC_Region_ID()); } if (getC_Country_ID() > 0) { sql.append(" AND cy.C_Country_ID=?"); params.add(getC_Country_ID()); } sql.append(" ORDER BY cy.Name, r.Name"); PreparedStatement pstmt = null; ResultSet rs = null; try { pstmt = DB.prepareStatement(sql.toString(), null); DB.setParameters(pstmt, params); rs = pstmt.executeQuery(); int i = 0; while(rs.next()) { CityVO vo = new CityVO(rs.getInt(1), rs.getString(2), rs.getInt(3), rs.getString(4)); m_cities.add(vo); if (i <= m_maxRows) { m_citiesShow.add(vo); } else if (i == m_maxRows + 1 && i > 0) { m_citiesShow.add(ITEM_More); } i++; } } catch (SQLException e) { throw new DBException(e, sql.toString()); } finally { DB.close(rs, pstmt); rs = null; pstmt = null; } refreshData(""); } private void setCity(CityVO vo) { m_city = vo; } public int getC_City_ID() { return m_city != null ? m_city.C_City_ID : -1; } public int getAD_Client_ID() { return Env.getAD_Client_ID(Env.getCtx()); } public int getC_Country_ID() { return Env.getContextAsInt(Env.getCtx(), m_windowNo, Env.TAB_INFO, "C_Country_ID"); } public int getC_Region_ID() { return Env.getContextAsInt(Env.getCtx(), m_windowNo, Env.TAB_INFO, "C_Region_ID"); } public void onEvent(Event event) throws Exception { System.out.println("Event: " + event.getName()); event.toString(); int index = this.getSelectedIndex(); System.out.println("Index = " +index ); if (index>=0) { CityVO city = (CityVO) m_citiesShow.get(index); if(event == null || city.equals(ITEM_More)) { setCity(null); return; } setCity(city); Env.setContext(Env.getCtx(), m_windowNo, Env.TAB_INFO, "C_Region_ID", String.valueOf(city.C_Region_ID)); this.setText(city.CityName); } } }