IDEMPIERE-1540 Autocomplete for field type "Search" (#79)

* IDEMPIERE-1540 Autocomplete for field type "Search"

Implement auto complete for search field

* IDEMPIERE-1540 Autocomplete for field type "Search"

Add support for isAutoComplete flag (default is off).
Add isAutoComplete to AD_UserDef_Field, AD_InfoColumn and
AD_Process_Para.
Performance improvement - reduce number of queries for autocomplete and
added some cache.

* IDEMPIERE-1540 Autocomplete for field type "Search"

add constant for auto complete query timeout
use union all to further reduce the number of queries
This commit is contained in:
hengsin 2020-05-29 19:25:24 +08:00 committed by GitHub
parent 4edd985ef8
commit e9e7486473
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 1085 additions and 361 deletions

View File

@ -0,0 +1,67 @@
SET SQLBLANKLINES ON
SET DEFINE OFF
-- IDEMPIERE-1540 Autocomplete for field type "Search"
-- May 21, 2020, 10:15:20 PM MYT
UPDATE AD_Field SET DisplayLogic='@AD_Reference_ID@=10 | @AD_Reference_ID@=17 | @AD_Reference_ID@=18 | @AD_Reference_ID@=19 | @AD_Reference_ID@=30', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2020-05-21 22:15:20','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=56279
;
-- May 22, 2020, 11:34:12 PM MYT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,Description,Help,AD_Table_ID,ColumnName,DefaultValue,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,IsHtml) VALUES (214201,0,'Autocomplete','Automatic completion for textfields','The autocompletion uses all existing values (from the same client and organization) of the field.',464,'IsAutocomplete',NULL,1,'N','N','N','N','N',0,'N',20,0,0,'Y',TO_DATE('2020-05-22 23:34:11','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2020-05-22 23:34:11','YYYY-MM-DD HH24:MI:SS'),100,53655,'Y','N','D','N','N','N','Y','1254c9c5-43a3-45a2-9dff-a80df5aa89d7','N',0,'N','N','N')
;
-- May 22, 2020, 11:34:17 PM MYT
ALTER TABLE AD_UserDef_Field ADD IsAutocomplete CHAR(1) DEFAULT NULL CHECK (IsAutocomplete IN ('Y','N'))
;
-- May 22, 2020, 11:37:48 PM MYT
INSERT INTO AD_Field (AD_Field_ID,Name,Description,Help,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLogic,DisplayLength,SeqNo,SortNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,XPosition,ColumnSpan,NumLines,IsQuickEntry,IsDefaultFocus,IsAdvancedField,IsQuickForm) VALUES (206408,'Autocomplete','Automatic completion for textfields','The autocompletion uses all existing values (from the same client and organization) of the field.',395,214201,'Y','@AD_Reference_ID@=10 | @AD_Reference_ID@=17 | @AD_Reference_ID@=18 | @AD_Reference_ID@=19 | @AD_Reference_ID@=30',0,330,0,'N','N','N','N',0,0,'Y',TO_DATE('2020-05-22 23:37:47','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2020-05-22 23:37:47','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','37df68ac-aafb-458e-878c-efb421b9a129','Y',330,2,2,1,'N','N','N','N')
;
-- May 22, 2020, 11:39:28 PM MYT
UPDATE AD_Field SET SeqNo=305, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, SeqNoGrid=305, IsToolbarButton=NULL,Updated=TO_DATE('2020-05-22 23:39:28','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=206408
;
-- May 22, 2020, 11:39:43 PM MYT
UPDATE AD_Field SET SeqNo=330, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2020-05-22 23:39:43','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=5057
;
-- May 22, 2020, 11:39:50 PM MYT
UPDATE AD_Field SET SeqNo=320, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2020-05-22 23:39:50','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=5051
;
-- May 22, 2020, 11:40:05 PM MYT
UPDATE AD_Field SET SeqNo=310, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, SeqNoGrid=310, IsToolbarButton=NULL,Updated=TO_DATE('2020-05-22 23:40:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=206408
;
-- May 22, 2020, 11:42:22 PM MYT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,Description,Help,AD_Table_ID,ColumnName,DefaultValue,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,IsHtml) VALUES (214202,0,'Autocomplete','Automatic completion for textfields','The autocompletion uses all existing values (from the same client and organization) of the field.',897,'IsAutocomplete','N',1,'N','N','Y','N','N',0,'N',20,0,0,'Y',TO_DATE('2020-05-22 23:42:21','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2020-05-22 23:42:21','YYYY-MM-DD HH24:MI:SS'),100,53655,'Y','N','D','N','N','N','Y','1fc6ddb8-4449-46ab-a54e-418260e069cf','N',0,'N','N','N')
;
-- May 22, 2020, 11:42:29 PM MYT
ALTER TABLE AD_InfoColumn ADD IsAutocomplete CHAR(1) DEFAULT 'N' CHECK (IsAutocomplete IN ('Y','N')) NOT NULL
;
-- May 22, 2020, 11:45:54 PM MYT
INSERT INTO AD_Field (AD_Field_ID,Name,Description,Help,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLogic,DisplayLength,SeqNo,SortNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,XPosition,ColumnSpan,NumLines,IsQuickEntry,IsDefaultFocus,IsAdvancedField,IsQuickForm) VALUES (206409,'Autocomplete','Automatic completion for textfields','The autocompletion uses all existing values (from the same client and organization) of the field.',844,214202,'Y','@AD_Reference_ID@=10 | @AD_Reference_ID@=17 | @AD_Reference_ID@=18 | @AD_Reference_ID@=19 | @AD_Reference_ID@=30',0,320,0,'N','N','N','N',0,0,'Y',TO_DATE('2020-05-22 23:45:54','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2020-05-22 23:45:54','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','49343858-2e9b-437b-9131-d10e069674bb','Y',320,2,2,1,'N','N','N','N')
;
-- May 22, 2020, 11:47:35 PM MYT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,Description,Help,AD_Table_ID,ColumnName,DefaultValue,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,FKConstraintType,IsHtml) VALUES (214203,0,'Autocomplete','Automatic completion for textfields','The autocompletion uses all existing values (from the same client and organization) of the field.',285,'IsAutocomplete','N',1,'N','N','Y','N','N',0,'N',20,0,0,'Y',TO_DATE('2020-05-22 23:47:35','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2020-05-22 23:47:35','YYYY-MM-DD HH24:MI:SS'),100,53655,'Y','N','D','N','N','N','Y','2594d121-f632-44b5-b79e-d630ed950a70','Y',0,'N','N','N','N')
;
-- May 22, 2020, 11:47:38 PM MYT
ALTER TABLE AD_Process_Para ADD IsAutocomplete CHAR(1) DEFAULT 'N' CHECK (IsAutocomplete IN ('Y','N')) NOT NULL
;
-- May 22, 2020, 11:49:01 PM MYT
INSERT INTO AD_Field (AD_Field_ID,Name,Description,Help,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLogic,DisplayLength,SeqNo,SortNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,XPosition,ColumnSpan,NumLines,IsQuickEntry,IsDefaultFocus,IsAdvancedField,IsQuickForm) VALUES (206410,'Autocomplete','Automatic completion for textfields','The autocompletion uses all existing values (from the same client and organization) of the field.',246,214203,'Y','@AD_Reference_ID@=10 | @AD_Reference_ID@=17 | @AD_Reference_ID@=18 | @AD_Reference_ID@=19 | @AD_Reference_ID@=30',0,300,0,'N','N','N','N',0,0,'Y',TO_DATE('2020-05-22 23:49:00','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2020-05-22 23:49:00','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','8e6fd1fe-8d03-4105-a76f-b563e8ba9637','Y',280,2,2,1,'N','N','N','N')
;
-- May 27, 2020, 10:03:39 AM MYT
UPDATE AD_Column SET AD_Reference_ID=17, AD_Reference_Value_ID=319,Updated=TO_DATE('2020-05-27 10:03:39','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=214201
;
SELECT register_migration_script('202005272300_IDEMPIERE-1540.sql') FROM dual
;

View File

@ -0,0 +1,64 @@
-- IDEMPIERE-1540 Autocomplete for field type "Search"
-- May 21, 2020, 10:15:20 PM MYT
UPDATE AD_Field SET DisplayLogic='@AD_Reference_ID@=10 | @AD_Reference_ID@=17 | @AD_Reference_ID@=18 | @AD_Reference_ID@=19 | @AD_Reference_ID@=30', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2020-05-21 22:15:20','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=56279
;
-- May 22, 2020, 11:34:12 PM MYT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,Description,Help,AD_Table_ID,ColumnName,DefaultValue,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,IsHtml) VALUES (214201,0,'Autocomplete','Automatic completion for textfields','The autocompletion uses all existing values (from the same client and organization) of the field.',464,'IsAutocomplete',NULL,1,'N','N','N','N','N',0,'N',20,0,0,'Y',TO_TIMESTAMP('2020-05-22 23:34:11','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2020-05-22 23:34:11','YYYY-MM-DD HH24:MI:SS'),100,53655,'Y','N','D','N','N','N','Y','1254c9c5-43a3-45a2-9dff-a80df5aa89d7','N',0,'N','N','N')
;
-- May 22, 2020, 11:34:17 PM MYT
ALTER TABLE AD_UserDef_Field ADD COLUMN IsAutocomplete CHAR(1) DEFAULT NULL CHECK (IsAutocomplete IN ('Y','N'))
;
-- May 22, 2020, 11:37:48 PM MYT
INSERT INTO AD_Field (AD_Field_ID,Name,Description,Help,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLogic,DisplayLength,SeqNo,SortNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,XPosition,ColumnSpan,NumLines,IsQuickEntry,IsDefaultFocus,IsAdvancedField,IsQuickForm) VALUES (206408,'Autocomplete','Automatic completion for textfields','The autocompletion uses all existing values (from the same client and organization) of the field.',395,214201,'Y','@AD_Reference_ID@=10 | @AD_Reference_ID@=17 | @AD_Reference_ID@=18 | @AD_Reference_ID@=19 | @AD_Reference_ID@=30',0,330,0,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2020-05-22 23:37:47','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2020-05-22 23:37:47','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','37df68ac-aafb-458e-878c-efb421b9a129','Y',330,2,2,1,'N','N','N','N')
;
-- May 22, 2020, 11:39:28 PM MYT
UPDATE AD_Field SET SeqNo=305, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, SeqNoGrid=305, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2020-05-22 23:39:28','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=206408
;
-- May 22, 2020, 11:39:43 PM MYT
UPDATE AD_Field SET SeqNo=330, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2020-05-22 23:39:43','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=5057
;
-- May 22, 2020, 11:39:50 PM MYT
UPDATE AD_Field SET SeqNo=320, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2020-05-22 23:39:50','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=5051
;
-- May 22, 2020, 11:40:05 PM MYT
UPDATE AD_Field SET SeqNo=310, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, SeqNoGrid=310, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2020-05-22 23:40:05','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=206408
;
-- May 22, 2020, 11:42:22 PM MYT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,Description,Help,AD_Table_ID,ColumnName,DefaultValue,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,IsHtml) VALUES (214202,0,'Autocomplete','Automatic completion for textfields','The autocompletion uses all existing values (from the same client and organization) of the field.',897,'IsAutocomplete','N',1,'N','N','Y','N','N',0,'N',20,0,0,'Y',TO_TIMESTAMP('2020-05-22 23:42:21','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2020-05-22 23:42:21','YYYY-MM-DD HH24:MI:SS'),100,53655,'Y','N','D','N','N','N','Y','1fc6ddb8-4449-46ab-a54e-418260e069cf','N',0,'N','N','N')
;
-- May 22, 2020, 11:42:29 PM MYT
ALTER TABLE AD_InfoColumn ADD COLUMN IsAutocomplete CHAR(1) DEFAULT 'N' CHECK (IsAutocomplete IN ('Y','N')) NOT NULL
;
-- May 22, 2020, 11:45:54 PM MYT
INSERT INTO AD_Field (AD_Field_ID,Name,Description,Help,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLogic,DisplayLength,SeqNo,SortNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,XPosition,ColumnSpan,NumLines,IsQuickEntry,IsDefaultFocus,IsAdvancedField,IsQuickForm) VALUES (206409,'Autocomplete','Automatic completion for textfields','The autocompletion uses all existing values (from the same client and organization) of the field.',844,214202,'Y','@AD_Reference_ID@=10 | @AD_Reference_ID@=17 | @AD_Reference_ID@=18 | @AD_Reference_ID@=19 | @AD_Reference_ID@=30',0,320,0,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2020-05-22 23:45:54','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2020-05-22 23:45:54','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','49343858-2e9b-437b-9131-d10e069674bb','Y',320,2,2,1,'N','N','N','N')
;
-- May 22, 2020, 11:47:35 PM MYT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,Description,Help,AD_Table_ID,ColumnName,DefaultValue,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,FKConstraintType,IsHtml) VALUES (214203,0,'Autocomplete','Automatic completion for textfields','The autocompletion uses all existing values (from the same client and organization) of the field.',285,'IsAutocomplete','N',1,'N','N','Y','N','N',0,'N',20,0,0,'Y',TO_TIMESTAMP('2020-05-22 23:47:35','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2020-05-22 23:47:35','YYYY-MM-DD HH24:MI:SS'),100,53655,'Y','N','D','N','N','N','Y','2594d121-f632-44b5-b79e-d630ed950a70','Y',0,'N','N','N','N')
;
-- May 22, 2020, 11:47:38 PM MYT
ALTER TABLE AD_Process_Para ADD COLUMN IsAutocomplete CHAR(1) DEFAULT 'N' CHECK (IsAutocomplete IN ('Y','N')) NOT NULL
;
-- May 22, 2020, 11:49:01 PM MYT
INSERT INTO AD_Field (AD_Field_ID,Name,Description,Help,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLogic,DisplayLength,SeqNo,SortNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,XPosition,ColumnSpan,NumLines,IsQuickEntry,IsDefaultFocus,IsAdvancedField,IsQuickForm) VALUES (206410,'Autocomplete','Automatic completion for textfields','The autocompletion uses all existing values (from the same client and organization) of the field.',246,214203,'Y','@AD_Reference_ID@=10 | @AD_Reference_ID@=17 | @AD_Reference_ID@=18 | @AD_Reference_ID@=19 | @AD_Reference_ID@=30',0,300,0,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2020-05-22 23:49:00','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2020-05-22 23:49:00','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','8e6fd1fe-8d03-4105-a76f-b563e8ba9637','Y',280,2,2,1,'N','N','N','N')
;
-- May 27, 2020, 10:03:39 AM MYT
UPDATE AD_Column SET AD_Reference_ID=17, AD_Reference_Value_ID=319,Updated=TO_TIMESTAMP('2020-05-27 10:03:39','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=214201
;
SELECT register_migration_script('202005272300_IDEMPIERE-1540.sql') FROM dual
;

View File

@ -330,6 +330,9 @@ public class GridFieldVO implements Serializable
if (userDef.getPlaceholder() != null) if (userDef.getPlaceholder() != null)
vo.Placeholder = userDef.getPlaceholder(); vo.Placeholder = userDef.getPlaceholder();
if (userDef.getIsAutocomplete() != null)
vo.IsAutocomplete = "Y".equals(userDef.getIsAutocomplete());
} }
} }
// //
@ -384,6 +387,7 @@ public class GridFieldVO implements Serializable
vo.MandatoryLogic = rs.getString("MandatoryLogic"); vo.MandatoryLogic = rs.getString("MandatoryLogic");
vo.Placeholder = rs.getString("Placeholder"); vo.Placeholder = rs.getString("Placeholder");
vo.Placeholder2 = rs.getString("Placeholder2"); vo.Placeholder2 = rs.getString("Placeholder2");
vo.IsAutocomplete = "Y".equals(rs.getString("IsAutoComplete"));
} }
catch (SQLException e) catch (SQLException e)
{ {

View File

@ -298,6 +298,19 @@ public interface I_AD_InfoColumn
*/ */
public boolean isActive(); public boolean isActive();
/** Column name IsAutocomplete */
public static final String COLUMNNAME_IsAutocomplete = "IsAutocomplete";
/** Set Autocomplete.
* Automatic completion for textfields
*/
public void setIsAutocomplete (boolean IsAutocomplete);
/** Get Autocomplete.
* Automatic completion for textfields
*/
public boolean isAutocomplete();
/** Column name IsCentrallyMaintained */ /** Column name IsCentrallyMaintained */
public static final String COLUMNNAME_IsCentrallyMaintained = "IsCentrallyMaintained"; public static final String COLUMNNAME_IsCentrallyMaintained = "IsCentrallyMaintained";

View File

@ -294,6 +294,19 @@ public interface I_AD_Process_Para
*/ */
public boolean isActive(); public boolean isActive();
/** Column name IsAutocomplete */
public static final String COLUMNNAME_IsAutocomplete = "IsAutocomplete";
/** Set Autocomplete.
* Automatic completion for textfields
*/
public void setIsAutocomplete (boolean IsAutocomplete);
/** Get Autocomplete.
* Automatic completion for textfields
*/
public boolean isAutocomplete();
/** Column name IsCentrallyMaintained */ /** Column name IsCentrallyMaintained */
public static final String COLUMNNAME_IsCentrallyMaintained = "IsCentrallyMaintained"; public static final String COLUMNNAME_IsCentrallyMaintained = "IsCentrallyMaintained";

View File

@ -303,6 +303,19 @@ public interface I_AD_UserDef_Field
*/ */
public String getIsAlwaysUpdateable(); public String getIsAlwaysUpdateable();
/** Column name IsAutocomplete */
public static final String COLUMNNAME_IsAutocomplete = "IsAutocomplete";
/** Set Autocomplete.
* Automatic completion for textfields
*/
public void setIsAutocomplete (String IsAutocomplete);
/** Get Autocomplete.
* Automatic completion for textfields
*/
public String getIsAutocomplete();
/** Column name IsDisplayed */ /** Column name IsDisplayed */
public static final String COLUMNNAME_IsDisplayed = "IsDisplayed"; public static final String COLUMNNAME_IsDisplayed = "IsDisplayed";

View File

@ -18,6 +18,7 @@ package org.compiere.model;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import javax.swing.AbstractListModel; import javax.swing.AbstractListModel;
@ -481,6 +482,21 @@ public abstract class Lookup extends AbstractListModel<Object>
return get (key); return get (key);
} // getDirect } // getDirect
/**
*
* @param keys
* @return name pair arrays
*/
public NamePair[] getDirect(Object[] keys)
{
List<NamePair> list = new ArrayList<NamePair>();
for (Object key : keys)
{
list.add(getDirect(key, false, isValidated()));
}
return list.toArray(new NamePair[0]);
}
/** /**
* Dispose - clear items w/o firing events * Dispose - clear items w/o firing events
*/ */

View File

@ -211,4 +211,25 @@ public class MInfoColumn extends X_AD_InfoColumn implements IInfoColumn
public MInfoColumn getAD_InfoColumn() { public MInfoColumn getAD_InfoColumn() {
return this; return this;
} }
@Override
public I_AD_Val_Rule getAD_Val_Rule() throws RuntimeException {
if (get_TrxName() != null)
return new MValRule(getCtx(), getAD_Val_Rule_ID(), get_TrxName());
else
return MValRule.get(getCtx(), getAD_Val_Rule_ID());
}
@Override
protected MInfoColumn clone() {
try {
MInfoColumn ic = (MInfoColumn) super.clone();
ic.m_parent = null;
return ic;
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}
} // MInfoColumn } // MInfoColumn

View File

@ -19,6 +19,7 @@ package org.compiere.model;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Properties; import java.util.Properties;
@ -188,27 +189,29 @@ public class MInfoWindow extends X_AD_InfoWindow
return null; return null;
} }
public MInfoColumn[] getInfoColumns(TableInfo[] tableInfos) { public synchronized MInfoColumn[] getInfoColumns(TableInfo[] tableInfos) {
Query query = new Query(getCtx(), MTable.get(getCtx(), I_AD_InfoColumn.Table_ID), I_AD_InfoColumn.COLUMNNAME_AD_InfoWindow_ID+"=?", get_TrxName()); getInfoColumns();
List<MInfoColumn> list = query.setParameters(getAD_InfoWindow_ID()) List<MInfoColumn> list = new ArrayList<MInfoColumn>();
.setOnlyActiveRecords(true) for(MInfoColumn ic : m_infocolumns) {
.setOrderBy("SeqNo, AD_InfoColumn_ID") if (ic.isColumnAccess(tableInfos))
.list(); list.add(ic);
for(int i = list.size() - 1; i >= 0; i--) {
MInfoColumn infoColumn = list.get(i);
if (!infoColumn.isColumnAccess(tableInfos))
list.remove(i);
} }
return list.toArray(new MInfoColumn[0]); return list.toArray(new MInfoColumn[0]);
} }
public MInfoColumn[] getInfoColumns() { public synchronized MInfoColumn[] getInfoColumns() {
Query query = new Query(getCtx(), MTable.get(getCtx(), I_AD_InfoColumn.Table_ID), I_AD_InfoColumn.COLUMNNAME_AD_InfoWindow_ID+"=?", get_TrxName()); if (m_infocolumns == null) {
List<MInfoColumn> list = query.setParameters(getAD_InfoWindow_ID()) Query query = new Query(getCtx(), MTable.get(getCtx(), I_AD_InfoColumn.Table_ID), I_AD_InfoColumn.COLUMNNAME_AD_InfoWindow_ID+"=?", get_TrxName());
.setOnlyActiveRecords(true) List<MInfoColumn> list = query.setParameters(getAD_InfoWindow_ID())
.setOrderBy("SeqNo, AD_InfoColumn_ID") .setOnlyActiveRecords(true)
.list(); .setOrderBy("SeqNo, AD_InfoColumn_ID")
return list.toArray(new MInfoColumn[0]); .list();
m_infocolumns = list.toArray(new MInfoColumn[0]);
}
if (get_TrxName() != null)
set_TrxName(m_infocolumns, get_TrxName());
return m_infocolumns;
} }
/** /**
@ -216,26 +219,22 @@ public class MInfoWindow extends X_AD_InfoWindow
*/ */
private MInfoColumn[] m_infocolumns = null; private MInfoColumn[] m_infocolumns = null;
public MInfoColumn[] getInfoColumns(boolean requery, boolean checkDisplay) { public synchronized MInfoColumn[] getInfoColumns(boolean requery, boolean checkDisplay) {
if ((this.m_infocolumns != null) && (!requery)) { if (m_infocolumns == null || requery) {
set_TrxName(this.m_infocolumns, get_TrxName()); m_infocolumns = null;
return this.m_infocolumns; getInfoColumns();
} }
if (checkDisplay) { if (checkDisplay) {
List<MInfoColumn> list = new Query(getCtx(), MInfoColumn.Table_Name, "AD_InfoWindow_ID=? AND IsDisplayed='Y'", get_TrxName()) List<MInfoColumn> list = new ArrayList<MInfoColumn>();
.setParameters(get_ID()) for(MInfoColumn ic : m_infocolumns) {
.setOrderBy("SeqNo") if (ic.isDisplayed())
.list(); list.add(ic);
this.m_infocolumns = list.toArray(new MInfoColumn[list.size()]); }
return list.toArray(new MInfoColumn[list.size()]);
} else { } else {
List<MInfoColumn> list = new Query(getCtx(), MInfoColumn.Table_Name, "AD_InfoWindow_ID=?", get_TrxName()) return m_infocolumns;
.setParameters(get_ID())
.setOrderBy("SeqNo")
.list();
this.m_infocolumns = list.toArray(new MInfoColumn[list.size()]);
} }
return this.m_infocolumns;
} }
/** /**

View File

@ -23,11 +23,15 @@ import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import java.util.logging.Level; import java.util.logging.Level;
import org.adempiere.util.ContextRunnable; import org.adempiere.util.ContextRunnable;
import org.compiere.Adempiere; import org.compiere.Adempiere;
import org.compiere.util.CCache;
import org.compiere.util.CLogMgt; import org.compiere.util.CLogMgt;
import org.compiere.util.DB; import org.compiere.util.DB;
import org.compiere.util.DisplayType; import org.compiere.util.DisplayType;
@ -129,6 +133,7 @@ public final class MLookup extends Lookup implements Serializable
private boolean m_hasShortListItems = false; // IDEMPIERE 90 private boolean m_hasShortListItems = false; // IDEMPIERE 90
private final static int MAX_NAMEPAIR_CACHE_SIZE = 1000;
/** /**
* Dispose * Dispose
*/ */
@ -540,7 +545,31 @@ public final class MLookup extends Lookup implements Serializable
} }
if (log.isLoggable(Level.FINER)) log.finer(m_info.KeyColumn + ": " + key if (log.isLoggable(Level.FINER)) log.finer(m_info.KeyColumn + ": " + key
+ ", SaveInCache=" + saveInCache + ",Local=" + cacheLocal); + ", SaveInCache=" + saveInCache + ",Local=" + cacheLocal);
String cacheKey = m_info.TableName+"|"+m_info.KeyColumn;
boolean isNumber = m_info.KeyColumn.endsWith("_ID"); boolean isNumber = m_info.KeyColumn.endsWith("_ID");
CCache<Integer, KeyNamePair> knpCache = null;
CCache<String, ValueNamePair> vnpCache = null;
if (isNumber)
{
knpCache = s_directKeyNamePairCache.get(cacheKey);
if (knpCache != null)
{
KeyNamePair knp = knpCache.get(Integer.parseInt(key.toString()));
if (knp != null)
return knp;
}
}
else
{
vnpCache = s_directValueNamePairCache.get(cacheKey);
if (vnpCache != null)
{
ValueNamePair vnp = vnpCache.get(key.toString());
if (vnp != null)
return vnp;
}
}
PreparedStatement pstmt = null; PreparedStatement pstmt = null;
ResultSet rs = null; ResultSet rs = null;
try try
@ -567,6 +596,16 @@ public final class MLookup extends Lookup implements Serializable
if (saveInCache) // save if if (saveInCache) // save if
m_lookup.put(Integer.valueOf(keyValue), p); m_lookup.put(Integer.valueOf(keyValue), p);
directValue = p; directValue = p;
if (knpCache != null)
{
knpCache.put(p.getKey(), p);
}
else
{
knpCache = new CCache<Integer, KeyNamePair>(null, "MLookup.DirectKeyNamePairCache", 100, 60, false, MAX_NAMEPAIR_CACHE_SIZE);
knpCache.put(p.getKey(), p);
s_directKeyNamePairCache.put(cacheKey, knpCache);
}
} }
else else
{ {
@ -575,6 +614,16 @@ public final class MLookup extends Lookup implements Serializable
if (saveInCache) // save if if (saveInCache) // save if
m_lookup.put(value, p); m_lookup.put(value, p);
directValue = p; directValue = p;
if (vnpCache != null)
{
vnpCache.put(p.getValue(), p);
}
else
{
vnpCache = new CCache<String, ValueNamePair>(null, "MLookup.DirectValueNamePairCache", 100, 60, false, MAX_NAMEPAIR_CACHE_SIZE);
vnpCache.put(p.getValue(), p);
s_directValueNamePairCache.put(cacheKey, vnpCache);
}
} }
if (rs.next()) if (rs.next())
log.log(Level.SEVERE, m_info.KeyColumn + ": Not unique (first returned) for " log.log(Level.SEVERE, m_info.KeyColumn + ": Not unique (first returned) for "
@ -616,6 +665,132 @@ public final class MLookup extends Lookup implements Serializable
return directValue; return directValue;
} // getDirect } // getDirect
@Override
public NamePair[] getDirect(Object[] keys)
{
List<NamePair> list = new ArrayList<NamePair>();
String cacheKey = m_info.TableName+"|"+m_info.KeyColumn;
boolean isNumber = m_info.KeyColumn.endsWith("_ID");
CCache<Integer, KeyNamePair> knpCache = null;
CCache<String, ValueNamePair> vnpCache = null;
Map<Object, Integer> notInCaches = new HashMap<Object, Integer>();
for (int i = 0; i < keys.length; i++)
{
Object key = keys[i];
if (isNumber)
{
KeyNamePair knp = null;
int id = Integer.parseInt(key.toString());
knpCache = s_directKeyNamePairCache.get(cacheKey);
if (knpCache != null)
{
knp = knpCache.get(id);
}
if (knp == null)
knp = new KeyNamePair(id, null);
list.add(knp);
notInCaches.put(id, i);
}
else
{
ValueNamePair vnp = null;
vnpCache = s_directValueNamePairCache.get(cacheKey);
if (vnpCache != null)
{
vnp = vnpCache.get(key.toString());
}
if (vnp == null)
vnp = new ValueNamePair(key.toString(), null);
list.add(vnp);
notInCaches.put(key.toString(), i);
}
}
StringBuilder builder = new StringBuilder();
for(int i = 0; i < notInCaches.size(); i++)
{
if (builder.length() > 0)
builder.append(" UNION ALL ");
builder.append(m_info.QueryDirect);
}
try (PreparedStatement pstmt = DB.prepareStatement(builder.toString(), null))
{
Set<Object> keySet = notInCaches.keySet();
int i = 0;
for(Object id : keySet)
{
i++;
if (id instanceof Integer)
{
pstmt.setInt(i, (int) id);
}
else
{
pstmt.setString(i, id.toString());
}
}
ResultSet rs = pstmt.executeQuery();
while (rs.next())
{
StringBuilder name = new StringBuilder().append(rs.getString(3));
boolean isActive = rs.getString(4).equals("Y");
if (!isActive)
{
name.insert(0, INACTIVE_S).append(INACTIVE_E);
}
if (isNumber)
{
int keyValue = rs.getInt(1);
KeyNamePair p = new KeyNamePair(keyValue, name.toString());
if (knpCache != null)
{
knpCache.put(p.getKey(), p);
}
else
{
knpCache = new CCache<Integer, KeyNamePair>(null, "MLookup.DirectKeyNamePairCache", 100, 60, false, MAX_NAMEPAIR_CACHE_SIZE);
knpCache.put(p.getKey(), p);
s_directKeyNamePairCache.put(cacheKey, knpCache);
}
Integer idx = notInCaches.get(p.getKey());
if (idx != null)
list.set(idx.intValue(), p);
}
else
{
String value = rs.getString(2);
ValueNamePair p = new ValueNamePair(value, name.toString());
if (vnpCache != null)
{
vnpCache.put(p.getValue(), p);
}
else
{
vnpCache = new CCache<String, ValueNamePair>(null, "MLookup.DirectValueNamePairCache", 100, 60, false, MAX_NAMEPAIR_CACHE_SIZE);
vnpCache.put(p.getValue(), p);
s_directValueNamePairCache.put(cacheKey, vnpCache);
}
Integer idx = notInCaches.get(p.getValue());
if (idx != null)
list.set(idx.intValue(), p);
}
}
} catch (SQLException e) {
log.log(Level.SEVERE, e.getMessage(), e);
}
for(int i = list.size()-1; i >= 0; i--)
{
NamePair np = list.get(i);
if (np.getName() == null)
list.remove(i);
}
return list.toArray(new NamePair[0]);
}
/** /**
* Get Zoom * Get Zoom
* @return Zoom AD_Window_ID * @return Zoom AD_Window_ID
@ -759,6 +934,12 @@ public final class MLookup extends Lookup implements Serializable
return m_info; return m_info;
} }
private final static CCache<String, List<KeyNamePair>> s_keyNamePairCache = new CCache<String, List<KeyNamePair>>(null, "MLookup.KeyNamePairCache", 100, 60, false, 500);
private final static CCache<String, List<ValueNamePair>> s_valueNamePairCache = new CCache<String, List<ValueNamePair>>(null, "MLookup.ValueNamePairCache", 100, 60, false, 500);
private final static CCache<String, CCache<Integer, KeyNamePair>> s_directKeyNamePairCache = new CCache<String, CCache<Integer,KeyNamePair>>(null, "", 100, 60, false, 500);
private final static CCache<String, CCache<String, ValueNamePair>> s_directValueNamePairCache = new CCache<String, CCache<String,ValueNamePair>>(null, "", 100, 60, false, 500);
/************************************************************************** /**************************************************************************
* MLookup Loader * MLookup Loader
*/ */
@ -785,8 +966,6 @@ public final class MLookup extends Lookup implements Serializable
protected void doRun() protected void doRun()
{ {
long startTime = System.currentTimeMillis(); long startTime = System.currentTimeMillis();
if (Ini.isClient())
MLookupCache.loadStart (m_info);
StringBuilder sql = new StringBuilder().append(m_info.Query); StringBuilder sql = new StringBuilder().append(m_info.Query);
// IDEMPIERE 90 // IDEMPIERE 90
@ -849,6 +1028,44 @@ public final class MLookup extends Lookup implements Serializable
// Reset // Reset
m_lookup.clear(); m_lookup.clear();
boolean isNumber = m_info.KeyColumn.endsWith("_ID"); boolean isNumber = m_info.KeyColumn.endsWith("_ID");
String cacheKey = sql.toString();
List<KeyNamePair> knpCache = null;
List<ValueNamePair> vnpCache = null;
if (isNumber)
{
knpCache = s_keyNamePairCache.get(cacheKey);
if (knpCache != null)
{
for(KeyNamePair knp : knpCache)
{
m_lookup.put(knp.getKey(), knp);
}
return;
}
else
{
knpCache = new ArrayList<KeyNamePair>();
}
}
else
{
vnpCache = s_valueNamePairCache.get(cacheKey);
if (vnpCache != null)
{
for(ValueNamePair vnp : vnpCache)
{
m_lookup.put(vnp.getValue(), vnp);
}
return;
}
else
{
vnpCache = new ArrayList<ValueNamePair>();
}
}
m_hasInactive = false; m_hasInactive = false;
int rows = 0; int rows = 0;
PreparedStatement pstmt = null; PreparedStatement pstmt = null;
@ -905,15 +1122,28 @@ public final class MLookup extends Lookup implements Serializable
int key = rs.getInt(1); int key = rs.getInt(1);
KeyNamePair p = new KeyNamePair(key, name.toString()); KeyNamePair p = new KeyNamePair(key, name.toString());
m_lookup.put(Integer.valueOf(key), p); m_lookup.put(Integer.valueOf(key), p);
knpCache.add(p);
} }
else else
{ {
String value = rs.getString(2); String value = rs.getString(2);
ValueNamePair p = new ValueNamePair(value, name.toString()); ValueNamePair p = new ValueNamePair(value, name.toString());
m_lookup.put(value, p); m_lookup.put(value, p);
vnpCache.add(p);
} }
// if (log.isLoggable(Level.FINE)) log.fine( m_info.KeyColumn + ": " + name); // if (log.isLoggable(Level.FINE)) log.fine( m_info.KeyColumn + ": " + name);
} }
if (isNumber)
{
if (knpCache.size() <= MAX_NAMEPAIR_CACHE_SIZE)
s_keyNamePairCache.put(cacheKey, knpCache);
}
else
{
if (vnpCache.size() <= MAX_NAMEPAIR_CACHE_SIZE)
s_valueNamePairCache.put(cacheKey, vnpCache);
}
} }
catch (SQLException e) catch (SQLException e)
{ {
@ -930,9 +1160,6 @@ public final class MLookup extends Lookup implements Serializable
+ " - Loader complete #" + size + " - all=" + m_allLoaded + " - Loader complete #" + size + " - all=" + m_allLoaded
+ " - ms=" + String.valueOf(System.currentTimeMillis()-m_startTime) + " - ms=" + String.valueOf(System.currentTimeMillis()-m_startTime)
+ " (" + String.valueOf(System.currentTimeMillis()-startTime) + ")"); + " (" + String.valueOf(System.currentTimeMillis()-startTime) + ")");
// if (m_allLoaded)
if (Ini.isClient())
MLookupCache.loadEnd (m_info, m_lookup);
} // run } // run
} // Loader } // Loader

View File

@ -30,7 +30,7 @@ public class X_AD_InfoColumn extends PO implements I_AD_InfoColumn, I_Persistent
/** /**
* *
*/ */
private static final long serialVersionUID = 20200413L; private static final long serialVersionUID = 20200523L;
/** Standard Constructor */ /** Standard Constructor */
public X_AD_InfoColumn (Properties ctx, int AD_InfoColumn_ID, String trxName) public X_AD_InfoColumn (Properties ctx, int AD_InfoColumn_ID, String trxName)
@ -44,6 +44,8 @@ public class X_AD_InfoColumn extends PO implements I_AD_InfoColumn, I_Persistent
setColumnName (null); setColumnName (null);
setEntityType (null); setEntityType (null);
// @SQL=select get_sysconfig('DEFAULT_ENTITYTYPE','U',0,0) from dual // @SQL=select get_sysconfig('DEFAULT_ENTITYTYPE','U',0,0) from dual
setIsAutocomplete (false);
// N
setIsCentrallyMaintained (true); setIsCentrallyMaintained (true);
// Y // Y
setIsDisplayed (true); setIsDisplayed (true);
@ -417,6 +419,30 @@ public class X_AD_InfoColumn extends PO implements I_AD_InfoColumn, I_Persistent
return (String)get_Value(COLUMNNAME_InputFieldValidation); return (String)get_Value(COLUMNNAME_InputFieldValidation);
} }
/** Set Autocomplete.
@param IsAutocomplete
Automatic completion for textfields
*/
public void setIsAutocomplete (boolean IsAutocomplete)
{
set_Value (COLUMNNAME_IsAutocomplete, Boolean.valueOf(IsAutocomplete));
}
/** Get Autocomplete.
@return Automatic completion for textfields
*/
public boolean isAutocomplete ()
{
Object oo = get_Value(COLUMNNAME_IsAutocomplete);
if (oo != null)
{
if (oo instanceof Boolean)
return ((Boolean)oo).booleanValue();
return "Y".equals(oo);
}
return false;
}
/** Set Centrally maintained. /** Set Centrally maintained.
@param IsCentrallyMaintained @param IsCentrallyMaintained
Information maintained in System Element table Information maintained in System Element table

View File

@ -30,7 +30,7 @@ public class X_AD_Process_Para extends PO implements I_AD_Process_Para, I_Persis
/** /**
* *
*/ */
private static final long serialVersionUID = 20200413L; private static final long serialVersionUID = 20200523L;
/** Standard Constructor */ /** Standard Constructor */
public X_AD_Process_Para (Properties ctx, int AD_Process_Para_ID, String trxName) public X_AD_Process_Para (Properties ctx, int AD_Process_Para_ID, String trxName)
@ -45,6 +45,8 @@ public class X_AD_Process_Para extends PO implements I_AD_Process_Para, I_Persis
setEntityType (null); setEntityType (null);
// @SQL=select get_sysconfig('DEFAULT_ENTITYTYPE','U',0,0) from dual // @SQL=select get_sysconfig('DEFAULT_ENTITYTYPE','U',0,0) from dual
setFieldLength (0); setFieldLength (0);
setIsAutocomplete (false);
// N
setIsCentrallyMaintained (true); setIsCentrallyMaintained (true);
// Y // Y
setIsEncrypted (false); setIsEncrypted (false);
@ -401,6 +403,30 @@ public class X_AD_Process_Para extends PO implements I_AD_Process_Para, I_Persis
return (String)get_Value(COLUMNNAME_Help); return (String)get_Value(COLUMNNAME_Help);
} }
/** Set Autocomplete.
@param IsAutocomplete
Automatic completion for textfields
*/
public void setIsAutocomplete (boolean IsAutocomplete)
{
set_Value (COLUMNNAME_IsAutocomplete, Boolean.valueOf(IsAutocomplete));
}
/** Get Autocomplete.
@return Automatic completion for textfields
*/
public boolean isAutocomplete ()
{
Object oo = get_Value(COLUMNNAME_IsAutocomplete);
if (oo != null)
{
if (oo instanceof Boolean)
return ((Boolean)oo).booleanValue();
return "Y".equals(oo);
}
return false;
}
/** Set Centrally maintained. /** Set Centrally maintained.
@param IsCentrallyMaintained @param IsCentrallyMaintained
Information maintained in System Element table Information maintained in System Element table

View File

@ -30,7 +30,7 @@ public class X_AD_UserDef_Field extends PO implements I_AD_UserDef_Field, I_Pers
/** /**
* *
*/ */
private static final long serialVersionUID = 20200413L; private static final long serialVersionUID = 20200527L;
/** Standard Constructor */ /** Standard Constructor */
public X_AD_UserDef_Field (Properties ctx, int AD_UserDef_Field_ID, String trxName) public X_AD_UserDef_Field (Properties ctx, int AD_UserDef_Field_ID, String trxName)
@ -441,6 +441,30 @@ public class X_AD_UserDef_Field extends PO implements I_AD_UserDef_Field, I_Pers
return (String)get_Value(COLUMNNAME_IsAlwaysUpdateable); return (String)get_Value(COLUMNNAME_IsAlwaysUpdateable);
} }
/** IsAutocomplete AD_Reference_ID=319 */
public static final int ISAUTOCOMPLETE_AD_Reference_ID=319;
/** Yes = Y */
public static final String ISAUTOCOMPLETE_Yes = "Y";
/** No = N */
public static final String ISAUTOCOMPLETE_No = "N";
/** Set Autocomplete.
@param IsAutocomplete
Automatic completion for textfields
*/
public void setIsAutocomplete (String IsAutocomplete)
{
set_Value (COLUMNNAME_IsAutocomplete, IsAutocomplete);
}
/** Get Autocomplete.
@return Automatic completion for textfields
*/
public String getIsAutocomplete ()
{
return (String)get_Value(COLUMNNAME_IsAutocomplete);
}
/** IsDisplayed AD_Reference_ID=319 */ /** IsDisplayed AD_Reference_ID=319 */
public static final int ISDISPLAYED_AD_Reference_ID=319; public static final int ISDISPLAYED_AD_Reference_ID=319;
/** Yes = Y */ /** Yes = Y */

View File

@ -209,7 +209,7 @@ public class ProcessParameterPanel extends Panel implements
+ "p.FieldLength, p.IsMandatory, p.IsRange, p.ColumnName, " + "p.FieldLength, p.IsMandatory, p.IsRange, p.ColumnName, "
+ "p.DefaultValue, p.DefaultValue2, p.VFormat, p.ValueMin, p.ValueMax, " + "p.DefaultValue, p.DefaultValue2, p.VFormat, p.ValueMin, p.ValueMax, "
+ "p.SeqNo, p.AD_Reference_Value_ID, vr.Code AS ValidationCode, " + "p.SeqNo, p.AD_Reference_Value_ID, vr.Code AS ValidationCode, "
+ "p.ReadOnlyLogic, p.DisplayLogic, p.IsEncrypted, NULL AS FormatPattern, p.MandatoryLogic, p.Placeholder, p.Placeholder2 " + "p.ReadOnlyLogic, p.DisplayLogic, p.IsEncrypted, NULL AS FormatPattern, p.MandatoryLogic, p.Placeholder, p.Placeholder2, p.isAutoComplete "
+ "FROM AD_Process_Para p" + "FROM AD_Process_Para p"
+ " LEFT OUTER JOIN AD_Val_Rule vr ON (p.AD_Val_Rule_ID=vr.AD_Val_Rule_ID) " + " LEFT OUTER JOIN AD_Val_Rule vr ON (p.AD_Val_Rule_ID=vr.AD_Val_Rule_ID) "
+ "WHERE p.AD_Process_ID=?" // 1 + "WHERE p.AD_Process_ID=?" // 1
@ -220,7 +220,7 @@ public class ProcessParameterPanel extends Panel implements
+ "p.FieldLength, p.IsMandatory, p.IsRange, p.ColumnName, " + "p.FieldLength, p.IsMandatory, p.IsRange, p.ColumnName, "
+ "p.DefaultValue, p.DefaultValue2, p.VFormat, p.ValueMin, p.ValueMax, " + "p.DefaultValue, p.DefaultValue2, p.VFormat, p.ValueMin, p.ValueMax, "
+ "p.SeqNo, p.AD_Reference_Value_ID, vr.Code AS ValidationCode, " + "p.SeqNo, p.AD_Reference_Value_ID, vr.Code AS ValidationCode, "
+ "p.ReadOnlyLogic, p.DisplayLogic, p.IsEncrypted, NULL AS FormatPattern,p.MandatoryLogic, t.Placeholder, t.Placeholder2 " + "p.ReadOnlyLogic, p.DisplayLogic, p.IsEncrypted, NULL AS FormatPattern,p.MandatoryLogic, t.Placeholder, t.Placeholder2, p.isAutoComplete "
+ "FROM AD_Process_Para p" + "FROM AD_Process_Para p"
+ " INNER JOIN AD_Process_Para_Trl t ON (p.AD_Process_Para_ID=t.AD_Process_Para_ID)" + " INNER JOIN AD_Process_Para_Trl t ON (p.AD_Process_Para_ID=t.AD_Process_Para_ID)"
+ " LEFT OUTER JOIN AD_Val_Rule vr ON (p.AD_Val_Rule_ID=vr.AD_Val_Rule_ID) " + " LEFT OUTER JOIN AD_Val_Rule vr ON (p.AD_Val_Rule_ID=vr.AD_Val_Rule_ID) "

View File

@ -0,0 +1,192 @@
/***********************************************************************
* This file is part of iDempiere ERP Open Source *
* http://www.idempiere.org *
* *
* Copyright (C) Contributors *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* 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., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301, USA. *
* *
* Contributors: *
* - hengsin *
**********************************************************************/
package org.adempiere.webui.component;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import org.adempiere.webui.LayoutUtils;
import org.adempiere.webui.util.ZKUpdateUtil;
import org.compiere.util.ValueNamePair;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zul.Comboitem;
import org.zkoss.zul.ComboitemRenderer;
import org.zkoss.zul.Div;
/**
* @author Low Heng Sin
*/
public class ComboEditorBox extends Div {
/**
*
*/
private static final long serialVersionUID = 4187563277424346012L;
protected PropertyChangeSupport m_propertyChangeListeners = new PropertyChangeSupport(
this);
protected Combobox txt;
protected Button btn;
public ComboEditorBox() {
initComponents();
}
/**
* @param text
*/
public ComboEditorBox(String text) {
initComponents();
setText(text);
}
/**
* @param imageSrc
*/
public void setButtonImage(String imageSrc) {
btn.setImage(imageSrc);
}
private void initComponents() {
txt = new Combobox();
txt.setButtonVisible(false);
txt.setSclass("editor-input");
txt.setAutocomplete(true);
txt.setAutodrop(true);
txt.setSubmitByEnter(true);
txt.setInstantSelect(false);
ZKUpdateUtil.setHflex(txt, "0");
appendChild(txt);
btn = new Button();
btn.setTabindex(-1);
ZKUpdateUtil.setHflex(btn, "0");
btn.setSclass("editor-button");
appendChild(btn);
LayoutUtils.addSclass("editor-box", this);
setTableEditorMode(false);
txt.setItemRenderer(new ComboitemRenderer<ValueNamePair>() {
public void render(Comboitem item, ValueNamePair data, int index){
item.setValue(data);
item.setLabel(data.getName());
}
});
}
/**
* @return combobox component
*/
public Combobox getCombobox() {
return txt;
}
/**
* @param value
*/
public void setText(String value) {
txt.setText(value);
}
/**
* @return text
*/
public String getText() {
return txt.getText();
}
/**
* @param enabled
*/
public void setEnabled(boolean enabled) {
txt.setReadonly(!enabled);
btn.setEnabled(enabled);
btn.setVisible(enabled);
if (enabled) {
if (btn.getParent() != txt.getParent())
btn.setParent(txt.getParent());
} else {
if (btn.getParent() != null)
btn.detach();
}
if (enabled) {
LayoutUtils.removeSclass("editor-input-disd", txt);
} else {
LayoutUtils.addSclass("editor-input-disd", txt);
}
}
/**
* @return boolean
*/
public boolean isEnabled() {
return btn.isEnabled();
}
/**
* @param evtnm
* @param listener
*/
public boolean addEventListener(String evtnm, EventListener<?> listener) {
if (Events.ON_CLICK.equals(evtnm)) {
return btn.addEventListener(evtnm, listener);
} else {
return txt.addEventListener(evtnm, listener);
}
}
/**
* @param l
*/
public synchronized void addPropertyChangeListener(PropertyChangeListener l) {
m_propertyChangeListeners.addPropertyChangeListener(l);
}
/**
* @param tooltiptext
*/
public void setToolTipText(String tooltiptext) {
txt.setTooltiptext(tooltiptext);
}
/**
* @return Button
*/
public Button getButton() {
return btn;
}
public void setTableEditorMode(boolean flag) {
if (flag) {
ZKUpdateUtil.setHflex(this, "0");
LayoutUtils.addSclass("grid-editor-input", txt);
LayoutUtils.addSclass("grid-editor-button", btn);
} else {
ZKUpdateUtil.setHflex(this, "1");
LayoutUtils.removeSclass("grid-editor-input", txt);
LayoutUtils.removeSclass("grid-editor-button", btn);
}
}
}

View File

@ -0,0 +1,122 @@
/***********************************************************************
* This file is part of iDempiere ERP Open Source *
* http://www.idempiere.org *
* *
* Copyright (C) Contributors *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* 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., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301, USA. *
* *
* Contributors: *
* - hengsin *
**********************************************************************/
package org.adempiere.webui.editor;
import java.util.ArrayList;
import java.util.List;
import org.adempiere.webui.factory.InfoManager;
import org.adempiere.webui.panel.InfoPanel;
import org.compiere.model.GridField;
import org.compiere.model.Lookup;
import org.compiere.util.NamePair;
import org.compiere.util.Util;
import org.compiere.util.ValueNamePair;
import org.zkoss.zul.ListModel;
import org.zkoss.zul.ListModelList;
import org.zkoss.zul.ListSubModel;
/**
*
* @author hengsin
*
*/
public class InfoListSubModel implements ListSubModel<ValueNamePair> {
private Lookup lookup;
private GridField gridField;
private String tableName;
private String keyColumnName;
private String whereClause;
/**
*
* @param lookup
* @param gridField
* @param tableName
* @param keyColumnName
*/
public InfoListSubModel(Lookup lookup, GridField gridField, String tableName, String keyColumnName) {
this.lookup = lookup;
this.gridField = gridField;
this.tableName = tableName;
this.keyColumnName = keyColumnName;
}
/**
*
* @param whereClause
*/
public void setWhereClause(String whereClause) {
this.whereClause = whereClause;
}
/**
*
* @return where clause
*/
public String getWhereClause() {
return this.whereClause;
}
@Override
public ListModel<ValueNamePair> getSubModel(Object value, int nRows) {
ListModelList<ValueNamePair> model = new ListModelList<>();
if (value != null && !Util.isEmpty(value.toString(), true)) {
String queryText = value.toString().trim();
final InfoPanel ip = InfoManager.create(lookup, gridField, tableName, keyColumnName, queryText, false, getWhereClause());
if (ip != null && ip.loadedOK()) {
int rowCount = ip.getRowCount();
if (rowCount > 0) {
List<String> added = new ArrayList<String>();
List<Integer> keys = new ArrayList<Integer>();
for(int i = 0; i < rowCount; i++) {
Integer key = ip.getRowKeyAt(i);
if (key != null && key.intValue() > 0) {
keys.add(key);
}
if (nRows > 0 && keys.size() >= nRows)
break;
}
NamePair[] namePairs = lookup.getDirect(keys.toArray());
for(NamePair np : namePairs) {
String name = np.getName();
if (added.contains(name))
continue;
else
added.add(name);
ValueNamePair pair = new ValueNamePair(np.getID(), name);
model.add(pair);
if (nRows > 0 && added.size() >= nRows)
break;
}
}
}
}
return model;
}
}

View File

@ -14,12 +14,7 @@
package org.adempiere.webui.editor; package org.adempiere.webui.editor;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List;
import java.util.Properties; import java.util.Properties;
import java.util.Set; import java.util.Set;
import java.util.logging.Level; import java.util.logging.Level;
@ -40,11 +35,11 @@ import org.adempiere.webui.theme.ThemeManager;
import org.adempiere.webui.window.WFieldRecordInfo; import org.adempiere.webui.window.WFieldRecordInfo;
import org.compiere.model.GridField; import org.compiere.model.GridField;
import org.compiere.model.Lookup; import org.compiere.model.Lookup;
import org.compiere.model.MColumn;
import org.compiere.model.MLookup; import org.compiere.model.MLookup;
import org.compiere.model.MRole; import org.compiere.model.MTable;
import org.compiere.model.X_AD_CtxHelp; import org.compiere.model.X_AD_CtxHelp;
import org.compiere.util.CLogger; import org.compiere.util.CLogger;
import org.compiere.util.DB;
import org.compiere.util.Env; import org.compiere.util.Env;
import org.compiere.util.Util; import org.compiere.util.Util;
import org.compiere.util.ValueNamePair; import org.compiere.util.ValueNamePair;
@ -71,9 +66,11 @@ public class WChosenboxSearchEditor extends WEditor implements ContextMenuListen
private String value; private String value;
private InfoPanel infoPanel = null; private InfoPanel infoPanel = null;
private String imageUrl; private String imageUrl;
private MyListModel model = new MyListModel(); private MyListModel model = new MyListModel();
private InfoListSubModel subModel = null;
private static final CLogger log = CLogger.getCLogger(WChosenboxSearchEditor.class); private static final CLogger log = CLogger.getCLogger(WChosenboxSearchEditor.class);
private static final int MAX_AUTO_COMPLETE_ROWS = 50;
private boolean onselecting; private boolean onselecting;
public WChosenboxSearchEditor (GridField gridField) public WChosenboxSearchEditor (GridField gridField)
@ -170,6 +167,9 @@ public class WChosenboxSearchEditor extends WEditor implements ContextMenuListen
} }
popupMenu = new WEditorPopupMenu(false, true, isShowPreference(), false, false, false, lookup); popupMenu = new WEditorPopupMenu(false, true, isShowPreference(), false, false, false, lookup);
getComponent().getButton().setImage(imageUrl); getComponent().getButton().setImage(imageUrl);
setTableAndKeyColumn();
subModel = new InfoListSubModel(lookup, gridField, m_tableName, m_keyColumnName);
getComponent().getChosenbox().setModel(model); getComponent().getChosenbox().setModel(model);
addChangeLogMenu(popupMenu); addChangeLogMenu(popupMenu);
@ -422,7 +422,7 @@ public class WChosenboxSearchEditor extends WEditor implements ContextMenuListen
String whereClause = getWhereClause(); String whereClause = getWhereClause();
if (m_tableName == null) // sets table name & key column if (m_tableName == null) // sets table name & key column
getDirectAccessSQL("*"); setTableAndKeyColumn();
final InfoPanel ip = InfoManager.create(lookup, gridField, m_tableName, m_keyColumnName, null, false, whereClause); final InfoPanel ip = InfoManager.create(lookup, gridField, m_tableName, m_keyColumnName, null, false, whereClause);
if (ip != null) if (ip != null)
@ -466,228 +466,37 @@ public class WChosenboxSearchEditor extends WEditor implements ContextMenuListen
} }
/** /**
* Generate Access SQL for Search. * Sets m_tableName and m_keyColumnName
* The SQL returns the ID of the value entered
* Also sets m_tableName and m_keyColumnName
* @param text uppercase text for LIKE comparison
* @return sql or ""
* Example
* SELECT C_Payment_ID FROM C_Payment WHERE UPPER(DocumentNo) LIKE x OR ...
*/ */
private String getDirectAccessSQL (String text) private void setTableAndKeyColumn() {
{ if (lookup != null && lookup instanceof MLookup) {
String m_columnName = getColumnName(); // foreign table defined in lookup
m_keyColumnName = ((MLookup)lookup).getColumnName();
StringBuffer sql = new StringBuffer(); if (m_keyColumnName.contains(".")) {
m_tableName = m_columnName.substring(0, m_columnName.length()-3); m_tableName = m_keyColumnName.substring(0, m_keyColumnName.indexOf("."));
m_keyColumnName = m_columnName; m_keyColumnName = m_keyColumnName.substring(m_keyColumnName.indexOf(".")+1);
} else {
if (m_columnName.equals("M_Product_ID")) m_tableName = m_keyColumnName.substring(0, m_keyColumnName.length()-3);
{ }
} else if (getGridField() != null && getGridField().getGridTab() != null && getGridField().getAD_Column_ID() > 0) {
// field - this search editor comes from a window, when it comes from process parameter it doesn't have a gridtab
MColumn column = MColumn.get(Env.getCtx(), getGridField().getAD_Column_ID());
m_tableName = column.getReferenceTableName();
MTable table = MTable.get(Env.getCtx(), m_tableName);
m_keyColumnName = table.getKeyColumns()[0];
} else {
// no field - the search editor is defined programatically
m_keyColumnName = getColumnName();
m_tableName = m_keyColumnName.substring(0, m_keyColumnName.length()-3);
}
if (m_keyColumnName.equals("M_Product_ID")) {
// Reset // Reset
Env.setContext(Env.getCtx(), lookup.getWindowNo(), Env.TAB_INFO, "M_Product_ID", "0"); Env.setContext(Env.getCtx(), lookup.getWindowNo(), Env.TAB_INFO, "M_Product_ID", "0");
Env.setContext(Env.getCtx(), lookup.getWindowNo(), Env.TAB_INFO, "M_AttributeSetInstance_ID", "0"); Env.setContext(Env.getCtx(), lookup.getWindowNo(), Env.TAB_INFO, "M_AttributeSetInstance_ID", "0");
Env.setContext(Env.getCtx(), lookup.getWindowNo(), Env.TAB_INFO, "M_Locator_ID", "0"); Env.setContext(Env.getCtx(), lookup.getWindowNo(), Env.TAB_INFO, "M_Locator_ID", "0");
sql.append("SELECT M_Product_ID FROM M_Product WHERE (UPPER(Value) LIKE ")
.append(DB.TO_STRING(text))
.append(" OR UPPER(Name) LIKE ").append(DB.TO_STRING(text))
.append(" OR UPC LIKE ").append(DB.TO_STRING(text)).append(")");
} }
else if (m_columnName.equals("C_BPartner_ID"))
{
sql.append("SELECT C_BPartner_ID FROM C_BPartner WHERE (UPPER(Value) LIKE ")
.append(DB.TO_STRING(text))
.append(" OR UPPER(Name) LIKE ").append(DB.TO_STRING(text)).append(")");
}
else if (m_columnName.equals("C_Order_ID"))
{
sql.append("SELECT C_Order_ID FROM C_Order WHERE UPPER(DocumentNo) LIKE ")
.append(DB.TO_STRING(text));
}
else if (m_columnName.equals("C_Invoice_ID"))
{
sql.append("SELECT C_Invoice_ID FROM C_Invoice WHERE UPPER(DocumentNo) LIKE ")
.append(DB.TO_STRING(text));
}
else if (m_columnName.equals("M_InOut_ID"))
{
sql.append("SELECT M_InOut_ID FROM M_InOut WHERE UPPER(DocumentNo) LIKE ")
.append(DB.TO_STRING(text));
}
else if (m_columnName.equals("C_Payment_ID"))
{
sql.append("SELECT C_Payment_ID FROM C_Payment WHERE UPPER(DocumentNo) LIKE ")
.append(DB.TO_STRING(text));
}
else if (m_columnName.equals("GL_JournalBatch_ID"))
{
sql.append("SELECT GL_JournalBatch_ID FROM GL_JournalBatch WHERE UPPER(DocumentNo) LIKE ")
.append(DB.TO_STRING(text));
}
else if (m_columnName.equals("SalesRep_ID"))
{
sql.append("SELECT AD_User_ID FROM AD_User WHERE UPPER(Name) LIKE ")
.append(DB.TO_STRING(text));
m_tableName = "AD_User";
m_keyColumnName = "AD_User_ID";
}
// Predefined
if (sql.length() > 0)
{
String wc = getWhereClause();
if (wc != null && wc.length() > 0)
sql.append(" AND ").append(wc);
sql.append(" AND IsActive='Y'");
// ***
if (log.isLoggable(Level.FINEST)) log.finest(m_columnName + " (predefined) " + sql.toString());
return MRole.getDefault().addAccessSQL(sql.toString(),
m_tableName, MRole.SQL_NOTQUALIFIED, MRole.SQL_RO);
}
// Check if it is a Table Reference
if (lookup != null && lookup instanceof MLookup)
{
int AD_Reference_ID = ((MLookup)lookup).getAD_Reference_Value_ID();
if (AD_Reference_ID != 0)
{
boolean isValueDisplayed = false;
String query = "SELECT kc.ColumnName, dc.ColumnName, t.TableName, rt.IsValueDisplayed "
+ "FROM AD_Ref_Table rt"
+ " INNER JOIN AD_Column kc ON (rt.AD_Key=kc.AD_Column_ID)"
+ " INNER JOIN AD_Column dc ON (rt.AD_Display=dc.AD_Column_ID)"
+ " INNER JOIN AD_Table t ON (rt.AD_Table_ID=t.AD_Table_ID) "
+ "WHERE rt.AD_Reference_ID=?";
String displayColumnName = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try
{
pstmt = DB.prepareStatement(query, null);
pstmt.setInt(1, AD_Reference_ID);
rs = pstmt.executeQuery();
if (rs.next())
{
m_keyColumnName = rs.getString(1);
displayColumnName = rs.getString(2);
m_tableName = rs.getString(3);
String t = rs.getString(4);
isValueDisplayed = "Y".equalsIgnoreCase(t);
}
}
catch (Exception e)
{
log.log(Level.SEVERE, query, e);
}
finally
{
DB.close(rs, pstmt);
}
if (displayColumnName != null)
{
sql = new StringBuffer();
sql.append("SELECT ").append(m_keyColumnName)
.append(" FROM ").append(m_tableName)
.append(" WHERE (UPPER(").append(displayColumnName)
.append(") LIKE ").append(DB.TO_STRING(text));
if (isValueDisplayed)
{
sql.append(" OR UPPER(").append("Value")
.append(") LIKE ").append(DB.TO_STRING(text));
}
sql.append(")");
sql.append(" AND IsActive='Y'");
String wc = getWhereClause();
if (wc != null && wc.length() > 0)
sql.append(" AND ").append(wc);
// ***
if (log.isLoggable(Level.FINEST)) log.finest(m_columnName + " (Table) " + sql.toString());
return MRole.getDefault().addAccessSQL(sql.toString(),
m_tableName, MRole.SQL_NOTQUALIFIED, MRole.SQL_RO);
}
} // Table Reference
} // MLookup
/** Check Well Known Columns of Table - assumes TableDir **/
String query = "SELECT t.TableName, c.ColumnName "
+ "FROM AD_Column c "
+ " INNER JOIN AD_Table t ON (c.AD_Table_ID=t.AD_Table_ID AND t.IsView='N') "
+ "WHERE (c.ColumnName IN ('DocumentNo', 'Value', 'Name') OR c.IsIdentifier='Y')"
+ " AND c.AD_Reference_ID IN (10,14)"
+ " AND EXISTS (SELECT * FROM AD_Column cc WHERE cc.AD_Table_ID=t.AD_Table_ID"
+ " AND cc.IsKey='Y' AND cc.ColumnName=?)";
m_keyColumnName = m_columnName;
sql = new StringBuffer();
PreparedStatement pstmt = null;
ResultSet rs = null;
try
{
pstmt = DB.prepareStatement(query, null);
pstmt.setString(1, m_keyColumnName);
rs = pstmt.executeQuery();
while (rs.next())
{
if (sql.length() != 0)
sql.append(" OR ");
m_tableName = rs.getString(1);
sql.append("UPPER(").append(rs.getString(2)).append(") LIKE ").append(DB.TO_STRING(text));
}
}
catch (SQLException ex)
{
log.log(Level.SEVERE, query, ex);
}
finally
{
DB.close(rs, pstmt);
rs = null;
pstmt = null;
}
//
if (sql.length() == 0)
{
log.log(Level.SEVERE, m_columnName + " (TableDir) - no standard/identifier columns");
return "";
}
//
StringBuffer retValue = new StringBuffer ("SELECT ")
.append(m_columnName).append(" FROM ").append(m_tableName)
.append(" WHERE ").append(sql)
.append(" AND IsActive='Y'");
String wc = getWhereClause();
if (wc != null && wc.length() > 0)
retValue.append(" AND ").append(wc);
// ***
if (log.isLoggable(Level.FINEST)) log.finest(m_columnName + " (TableDir) " + sql.toString());
return MRole.getDefault().addAccessSQL(retValue.toString(),
m_tableName, MRole.SQL_NOTQUALIFIED, MRole.SQL_RO);
} }
private String getWhereClause() private String getWhereClause()
{ {
String whereClause = ""; String whereClause = "";
@ -756,35 +565,8 @@ public class WChosenboxSearchEditor extends WEditor implements ContextMenuListen
@Override @Override
public ListModel<ValueNamePair> getSubModel(Object value, int nRows) { public ListModel<ValueNamePair> getSubModel(Object value, int nRows) {
ListModelList<ValueNamePair> model = new ListModelList<>(); subModel.setWhereClause(getWhereClause());
if (value != null && !Util.isEmpty(value.toString(), true)) { ListModel<ValueNamePair> model = subModel.getSubModel(value, MAX_AUTO_COMPLETE_ROWS);
String queryText = value.toString().trim();
if (m_tableName == null) // sets table name & key column
getDirectAccessSQL("*");
final InfoPanel ip = InfoManager.create(lookup, gridField, m_tableName, m_keyColumnName, queryText, false, getWhereClause());
if (ip != null && ip.loadedOK()) {
int rowCount = ip.getRowCount();
if (rowCount > 0) {
List<String> added = new ArrayList<String>();
for(int i = 0; i < rowCount; i++) {
Integer key = ip.getRowKeyAt(i);
if (key != null && key.intValue() > 0) {
String name = getLookup().getDisplay(key);
if (added.contains(name))
continue;
else
added.add(name);
ValueNamePair pair = new ValueNamePair(key.toString(), name);
model.add(pair);
if (added.size() == 50)
break;
}
}
}
}
}
getComponent().getChosenbox().setSubListModel(model); getComponent().getChosenbox().setSubListModel(model);
return model; return model;
} }

View File

@ -31,6 +31,7 @@ import org.adempiere.webui.adwindow.ADWindow;
import org.adempiere.webui.adwindow.ADWindowContent; import org.adempiere.webui.adwindow.ADWindowContent;
import org.adempiere.webui.adwindow.QuickGridTabRowRenderer; import org.adempiere.webui.adwindow.QuickGridTabRowRenderer;
import org.adempiere.webui.apps.AEnv; import org.adempiere.webui.apps.AEnv;
import org.adempiere.webui.component.ComboEditorBox;
import org.adempiere.webui.component.Searchbox; import org.adempiere.webui.component.Searchbox;
import org.adempiere.webui.event.ContextMenuEvent; import org.adempiere.webui.event.ContextMenuEvent;
import org.adempiere.webui.event.ContextMenuListener; import org.adempiere.webui.event.ContextMenuListener;
@ -55,6 +56,7 @@ import org.compiere.model.X_AD_CtxHelp;
import org.compiere.util.CLogger; import org.compiere.util.CLogger;
import org.compiere.util.DisplayType; import org.compiere.util.DisplayType;
import org.compiere.util.Env; import org.compiere.util.Env;
import org.compiere.util.Util;
import org.zkoss.zk.au.out.AuScript; import org.zkoss.zk.au.out.AuScript;
import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions; import org.zkoss.zk.ui.Executions;
@ -62,6 +64,7 @@ import org.zkoss.zk.ui.Page;
import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events; import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.event.InputEvent;
import org.zkoss.zk.ui.util.Clients; import org.zkoss.zk.ui.util.Clients;
/** /**
@ -73,6 +76,8 @@ import org.zkoss.zk.ui.util.Clients;
*/ */
public class WSearchEditor extends WEditor implements ContextMenuListener, ValueChangeListener, IZoomableEditor public class WSearchEditor extends WEditor implements ContextMenuListener, ValueChangeListener, IZoomableEditor
{ {
private static final int MAX_AUTO_COMPLETE_ROWS = 50;
private static final int AUTO_COMPLETE_QUERY_TIMEOUT = 1; //1 second
private static final String[] LISTENER_EVENTS = {Events.ON_CLICK, Events.ON_CHANGE, Events.ON_OK}; private static final String[] LISTENER_EVENTS = {Events.ON_CLICK, Events.ON_CHANGE, Events.ON_OK};
public static final String ATTRIBUTE_IS_INFO_PANEL_OPEN = "ATTRIBUTE_IS_INFO_PANEL_OPEN"; public static final String ATTRIBUTE_IS_INFO_PANEL_OPEN = "ATTRIBUTE_IS_INFO_PANEL_OPEN";
private Lookup lookup; private Lookup lookup;
@ -82,6 +87,7 @@ public class WSearchEditor extends WEditor implements ContextMenuListener, Value
private Object value; private Object value;
private InfoPanel infoPanel = null; private InfoPanel infoPanel = null;
private String imageUrl; private String imageUrl;
private InfoListSubModel listModel = null;
private static final CLogger log = CLogger.getCLogger(WSearchEditor.class); private static final CLogger log = CLogger.getCLogger(WSearchEditor.class);
@ -104,8 +110,8 @@ public class WSearchEditor extends WEditor implements ContextMenuListener, Value
@Override @Override
public Searchbox getComponent() { public ComboEditorBox getComponent() {
return (Searchbox) super.getComponent(); return (ComboEditorBox) super.getComponent();
} }
@Override @Override
@ -201,7 +207,35 @@ public class WSearchEditor extends WEditor implements ContextMenuListener, Value
addChangeLogMenu(popupMenu); addChangeLogMenu(popupMenu);
if (gridField != null) if (gridField != null)
getComponent().getTextbox().setPlaceholder(gridField.getPlaceholder()); getComponent().getCombobox().setPlaceholder(gridField.getPlaceholder());
if (gridField != null && gridField.isAutocomplete()) {
setTableAndKeyColumn();
listModel = new InfoListSubModel(lookup, gridField, m_tableName, m_keyColumnName);
getComponent().getCombobox().setModel(listModel.getSubModel(null, MAX_AUTO_COMPLETE_ROWS));
getComponent().getCombobox().addEventListener(Events.ON_CHANGING, (EventListener<InputEvent>)(e) -> {
if (!e.isChangingBySelectBack()) {
listModel.setWhereClause(getWhereClause());
String s = e.getValue();
if (!Util.isEmpty(s, true)) {
StringBuilder query = new StringBuilder(s);
query.append("?autocomplete={");
query.append("timeout:")
.append(AUTO_COMPLETE_QUERY_TIMEOUT)
.append(",")
.append("pagesize:")
.append(MAX_AUTO_COMPLETE_ROWS);
query.append("}");
s = query.toString();
}
getComponent().getCombobox().setModel(listModel.getSubModel(s, MAX_AUTO_COMPLETE_ROWS));
}
});
} else {
getComponent().getCombobox().setAutodrop(false);
}
return; return;
} }
@ -401,7 +435,7 @@ public class WSearchEditor extends WEditor implements ContextMenuListener, Value
focusNext(); focusNext();
//safety check: if focus is going no where, focus back to self //safety check: if focus is going no where, focus back to self
String uid = getComponent().getTextbox().getUuid(); String uid = getComponent().getCombobox().getUuid();
String script = "setTimeout(function(){try{var e = zk.Widget.$('#" + uid + String script = "setTimeout(function(){try{var e = zk.Widget.$('#" + uid +
"').$n(); if (jq(':focus').size() == 0) e.focus();} catch(error){}}, 100);"; "').$n(); if (jq(':focus').size() == 0) e.focus();} catch(error){}}, 100);";
Clients.response(new AuScript(script)); Clients.response(new AuScript(script));
@ -614,12 +648,12 @@ public class WSearchEditor extends WEditor implements ContextMenuListener, Value
getComponent().setText(""); getComponent().setText("");
actionCombo(null); actionCombo(null);
} }
getComponent().getTextbox().focus(); getComponent().getCombobox().focus();
} }
else else
{ {
if (log.isLoggable(Level.CONFIG)) log.config(getColumnName() + " - Result = null (not cancelled)"); if (log.isLoggable(Level.CONFIG)) log.config(getColumnName() + " - Result = null (not cancelled)");
getComponent().getTextbox().focus(); getComponent().getCombobox().focus();
getComponent().setAttribute(ATTRIBUTE_IS_INFO_PANEL_OPEN, false); getComponent().setAttribute(ATTRIBUTE_IS_INFO_PANEL_OPEN, false);
} }
} }
@ -780,7 +814,7 @@ public class WSearchEditor extends WEditor implements ContextMenuListener, Value
} }
static class CustomSearchBox extends Searchbox { static class CustomSearchBox extends ComboEditorBox {
/** /**
* generated serial id * generated serial id
@ -794,15 +828,15 @@ public class WSearchEditor extends WEditor implements ContextMenuListener, Value
String w = "try{var btn=jq('#'+this.parent.uuid+' @button').zk.$();}catch(err){}"; String w = "try{var btn=jq('#'+this.parent.uuid+' @button').zk.$();}catch(err){}";
if (ThemeManager.isUseFontIconForImage()) { if (ThemeManager.isUseFontIconForImage()) {
String sclass = "z-icon-spinner z-icon-spin"; String sclass = "z-icon-spinner z-icon-spin";
getTextbox().setWidgetListener("onChange", "try{"+w+"btn.setIconSclass('" + sclass + "');" getCombobox().setWidgetListener("onChange", "try{"+w+"btn.setIconSclass('" + sclass + "');"
+ "btn.setDisabled(true, {adbs: false, skip: false});}catch(err){}"); + "btn.setDisabled(true, {adbs: false, skip: false});}catch(err){}");
} else { } else {
getTextbox().setWidgetListener("onChange", "try{"+w+"btn.setImage(\"" getCombobox().setWidgetListener("onChange", "try{"+w+"btn.setImage(\""
+ Executions.getCurrent().encodeURL(IN_PROGRESS_IMAGE)+"\");" + Executions.getCurrent().encodeURL(IN_PROGRESS_IMAGE)+"\");"
+ "btn.setDisabled(true, {adbs: false, skip: false});}catch(err){}"); + "btn.setDisabled(true, {adbs: false, skip: false});}catch(err){}");
} }
} }
} }
} }
} }

View File

@ -147,7 +147,7 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
protected ColumnInfo[] columnInfos; protected ColumnInfo[] columnInfos;
protected TableInfo[] tableInfos; protected TableInfo[] tableInfos;
protected MInfoColumn[] infoColumns; protected MInfoColumn[] infoColumns;
protected String queryValue;
protected WQuickEntry vqe; protected WQuickEntry vqe;
private List<GridField> gridFields; private List<GridField> gridFields;
@ -206,9 +206,8 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
public InfoWindow(int WindowNo, String tableName, String keyColumn, String queryValue, public InfoWindow(int WindowNo, String tableName, String keyColumn, String queryValue,
boolean multipleSelection, String whereClause, int AD_InfoWindow_ID, boolean lookup, GridField field) { boolean multipleSelection, String whereClause, int AD_InfoWindow_ID, boolean lookup, GridField field) {
super(WindowNo, tableName, keyColumn, multipleSelection, whereClause, super(WindowNo, tableName, keyColumn, multipleSelection, whereClause,
lookup, AD_InfoWindow_ID); lookup, AD_InfoWindow_ID, queryValue);
this.m_gridfield = field; this.m_gridfield = field;
this.queryValue = queryValue;
//Xolali IDEMPIERE-1045 //Xolali IDEMPIERE-1045
contentPanel.addActionListener(new EventListener<Event>() { contentPanel.addActionListener(new EventListener<Event>() {
@ -242,8 +241,10 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
if (haveProcess) if (haveProcess)
p_multipleSelection = true; p_multipleSelection = true;
} }
loadInfoRelatedTabs(); if (!isAutoComplete)
loadInfoRelatedTabs();
if (loadedOK()) { if (loadedOK()) {
if (isLookup()) { if (isLookup()) {
Env.clearTabContext(Env.getCtx(), p_WindowNo, Env.TAB_INFO); Env.clearTabContext(Env.getCtx(), p_WindowNo, Env.TAB_INFO);
@ -263,8 +264,8 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
} }
// F3P: add export button // F3P: add export button
if (!isAutoComplete)
initExport(); initExport();
} }
/** /**
@ -505,6 +506,9 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
isQueryByUser = true; isQueryByUser = true;
for (int i = 0; i < identifiers.size(); i++) { for (int i = 0; i < identifiers.size(); i++) {
WEditor editor = identifiers.get(i); WEditor editor = identifiers.get(i);
if (isAutoComplete && i > 0) {
break;
}
try{ try{
editor.setValue(queryValue); editor.setValue(queryValue);
}catch(Exception ex){ }catch(Exception ex){
@ -520,17 +524,19 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
} }
boolean splitValue = false; boolean splitValue = false;
if (m_count <= 0) { if (!isAutoComplete) {
String separator = MSysConfig.getValue(MSysConfig.IDENTIFIER_SEPARATOR, "_", Env.getAD_Client_ID(Env.getCtx())); if (m_count <= 0) {
String[] values = queryValue.split("[" + separator.trim()+"]"); String separator = MSysConfig.getValue(MSysConfig.IDENTIFIER_SEPARATOR, "_", Env.getAD_Client_ID(Env.getCtx()));
if (values.length == 2) { String[] values = queryValue.split("[" + separator.trim()+"]");
splitValue = true; if (values.length == 2) {
for(int i = 0; i < values.length && i < identifiers.size(); i++) { splitValue = true;
WEditor editor = identifiers.get(i); for(int i = 0; i < values.length && i < identifiers.size(); i++) {
editor.setValue(values[i].trim()); WEditor editor = identifiers.get(i);
} editor.setValue(values[i].trim());
testCount(false); }
} testCount(false);
}
}
} }
if (m_count > 0) { if (m_count > 0) {
@ -605,6 +611,7 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
String help = infoColumn.get_Translation("Help"); String help = infoColumn.get_Translation("Help");
vo.Help = help != null ? help : ""; vo.Help = help != null ? help : "";
vo.AD_FieldStyle_ID = infoColumn.getAD_FieldStyle_ID(); vo.AD_FieldStyle_ID = infoColumn.getAD_FieldStyle_ID();
vo.IsAutocomplete = infoColumn.isAutocomplete();
GridField gridField = new GridField(vo); GridField gridField = new GridField(vo);
gridFields.add(gridField); gridFields.add(gridField);
} }
@ -1445,10 +1452,12 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
row.appendChild(checkAND); row.appendChild(checkAND);
} }
} }
evalDisplayLogic(); if (!isAutoComplete)
evalDisplayLogic();
if (!update) if (!update)
initParameters(); initParameters();
dynamicDisplay(null); if (!isAutoComplete)
dynamicDisplay(null);
} }
protected void evalDisplayLogic() { protected void evalDisplayLogic() {
@ -1927,6 +1936,8 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
try try
{ {
pstmt = DB.prepareStatement(countSql, null); pstmt = DB.prepareStatement(countSql, null);
if (queryTimeout > 0)
pstmt.setQueryTimeout(queryTimeout);
setParameters (pstmt, true); setParameters (pstmt, true);
rs = pstmt.executeQuery(); rs = pstmt.executeQuery();
@ -2122,6 +2133,9 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
@Override @Override
protected boolean hasNew() { protected boolean hasNew() {
if (isAutoComplete)
return false;
boolean hasNew = getADWindowID () > 0; boolean hasNew = getADWindowID () > 0;
if (hasNew && vqe == null && hasRightQuickEntry){ if (hasNew && vqe == null && hasRightQuickEntry){
GridWindow gridwindow = GridWindow.get(Env.getCtx(), 0, getADWindowID()); GridWindow gridwindow = GridWindow.get(Env.getCtx(), 0, getADWindowID());

View File

@ -101,7 +101,7 @@ public class InfoGeneralPanel extends InfoPanel implements EventListener<Event>
public InfoGeneralPanel(String queryValue, int windowNo,String tableName,String keyColumn, boolean isSOTrx, String whereClause, boolean lookup) public InfoGeneralPanel(String queryValue, int windowNo,String tableName,String keyColumn, boolean isSOTrx, String whereClause, boolean lookup)
{ {
super(windowNo, tableName, keyColumn, false,whereClause, lookup); super(windowNo, tableName, keyColumn, false, whereClause, lookup, 0, queryValue);
setTitle(Msg.getMsg(Env.getCtx(), "Info")); setTitle(Msg.getMsg(Env.getCtx(), "Info"));
@ -112,26 +112,7 @@ public class InfoGeneralPanel extends InfoPanel implements EventListener<Event>
p_loadedOK = initInfo (); p_loadedOK = initInfo ();
if (queryValue != null && queryValue.length() > 0) processQueryValue();
{
Textbox[] txts = new Textbox[] {txt1, txt2, txt3, txt4};
for(Textbox t : txts)
{
if (t != null && t.isVisible())
{
t.setValue(queryValue);
testCount();
if (m_count <= 0)
t.setValue(null);
else
break;
}
}
if (m_count <= 0)
{
txt1.setValue(queryValue);
}
}
} }
catch (Exception e) catch (Exception e)
{ {
@ -146,22 +127,25 @@ public class InfoGeneralPanel extends InfoPanel implements EventListener<Event>
if (queryValue != null && queryValue.length() > 0) if (queryValue != null && queryValue.length() > 0)
{ {
MTable table = MTable.get(Env.getCtx(), p_tableName); if (!isAutoComplete)
if ( table.getIdentifierColumns().length > 1
&& !p_tableName.startsWith("AD_")) // 32 AD tables with identifiers containing _
{ {
String separator = I_C_ElementValue.Table_Name.equalsIgnoreCase(p_tableName) ? "-" : "_"; MTable table = MTable.get(Env.getCtx(), p_tableName);
if (txt2.isVisible()) if ( table.getIdentifierColumns().length > 1
&& !p_tableName.startsWith("AD_")) // 32 AD tables with identifiers containing _
{ {
String[] values = queryValue.split("["+separator+"]"); String separator = I_C_ElementValue.Table_Name.equalsIgnoreCase(p_tableName) ? "-" : "_";
if (values != null && values.length == 2) if (txt2.isVisible())
{ {
txt1.setValue(values[0]); String[] values = queryValue.split("["+separator+"]");
txt2.setValue(values[1]); if (values != null && values.length == 2)
{
txt1.setValue(values[0]);
txt2.setValue(values[1]);
}
} }
}
}
} }
executeQuery(); executeQuery();
renderItems(); renderItems();
@ -172,6 +156,32 @@ public class InfoGeneralPanel extends InfoPanel implements EventListener<Event>
} }
} }
private void processQueryValue() {
if (queryValue != null && queryValue.length() > 0)
{
Textbox[] txts = new Textbox[] {txt1, txt2, txt3, txt4};
for(Textbox t : txts)
{
if (t != null && t.isVisible())
{
t.setValue(queryValue);
testCount();
if (m_count <= 0)
t.setValue(null);
else
break;
}
if (isAutoComplete)
break;
}
if (m_count <= 0)
{
txt1.setValue(queryValue);
}
}
}
private void initComponents() private void initComponents()
{ {
Grid grid = GridFactory.newGridLayout(); Grid grid = GridFactory.newGridLayout();

View File

@ -87,6 +87,7 @@ import org.compiere.util.Env;
import org.compiere.util.KeyNamePair; import org.compiere.util.KeyNamePair;
import org.compiere.util.Msg; import org.compiere.util.Msg;
import org.compiere.util.Trx; import org.compiere.util.Trx;
import org.compiere.util.Util;
import org.compiere.util.ValueNamePair; import org.compiere.util.ValueNamePair;
import org.zkoss.zk.au.out.AuEcho; import org.zkoss.zk.au.out.AuEcho;
import org.zkoss.zk.ui.Page; import org.zkoss.zk.ui.Page;
@ -221,17 +222,26 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
lookup, 0); lookup, 0);
} }
protected InfoPanel (int WindowNo,
String tableName, String keyColumn,boolean multipleSelection,
String whereClause, boolean lookup, int ADInfoWindowID)
{
this(WindowNo, tableName, keyColumn, multipleSelection,
whereClause, lookup, ADInfoWindowID, null);
}
/************************************************** /**************************************************
* Detail Constructor * Detail Constructor
* @param WindowNo WindowNo * @param WindowNo WindowNo
* @param tableName tableName * @param tableName tableName
* @param keyColumn keyColumn * @param keyColumn keyColumn
* @param whereClause whereClause * @param whereClause whereClause
* @param queryValue
*/ */
protected InfoPanel (int WindowNo, protected InfoPanel (int WindowNo,
String tableName, String keyColumn,boolean multipleSelection, String tableName, String keyColumn,boolean multipleSelection,
String whereClause, boolean lookup, int ADInfoWindowID) String whereClause, boolean lookup, int ADInfoWindowID, String queryValue)
{ {
if (WindowNo <= 0) { if (WindowNo <= 0) {
p_WindowNo = SessionManager.getAppDesktop().registerWindow(this); p_WindowNo = SessionManager.getAppDesktop().registerWindow(this);
} else { } else {
@ -243,6 +253,12 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
this.m_infoWindowID = ADInfoWindowID; this.m_infoWindowID = ADInfoWindowID;
p_keyColumn = keyColumn; p_keyColumn = keyColumn;
this.queryValue = queryValue;
if (queryValue != null && queryValue.trim().length() > 0)
{
parseQueryValue();
}
p_multipleSelection = multipleSelection; p_multipleSelection = multipleSelection;
m_lookup = lookup; m_lookup = lookup;
loadInfoWindowData(); loadInfoWindowData();
@ -275,6 +291,38 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
} // InfoPanel } // InfoPanel
protected void parseQueryValue() {
if (Util.isEmpty(queryValue, true))
return;
int start = queryValue.indexOf("?autocomplete={");
if (start > 0 && queryValue.endsWith("}")) {
this.isAutoComplete = true;
this.numPagePreLoad = 1;
String optionInput = queryValue.substring(start+"?autocomplete={".length(), queryValue.length()-1);
queryValue = queryValue.substring(0, start);
String[] options = optionInput.split("[,]");
for(String option : options) {
String[] pair = option.trim().split("[:]");
if (pair.length != 2)
continue;
if (pair[0].equalsIgnoreCase("timeout")) {
try {
int t = Integer.parseInt(pair[1]);
if (t > 0)
this.queryTimeout = t;
} catch (Exception e) {}
} else if (pair[0].equalsIgnoreCase("pagesize")) {
try {
int t = Integer.parseInt(pair[1]);
if (t > 0)
this.pageSize = t;
} catch (Exception e) {}
}
}
}
}
private void init() private void init()
{ {
if (isLookup()) if (isLookup())
@ -409,6 +457,13 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
* IDEMPIERE-1979 * IDEMPIERE-1979
*/ */
protected boolean isQueryByUser = false; protected boolean isQueryByUser = false;
protected boolean isAutoComplete = false;
protected int queryTimeout = 0;
protected String queryValue;
/** /**
* save where clause of prev requery * save where clause of prev requery
*/ */
@ -892,6 +947,8 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
trx = Trx.get(trxName, true); trx = Trx.get(trxName, true);
trx.setDisplayName(getClass().getName()+"_readLine"); trx.setDisplayName(getClass().getName()+"_readLine");
m_pstmt = DB.prepareStatement(dataSql, trxName); m_pstmt = DB.prepareStatement(dataSql, trxName);
if (queryTimeout > 0)
m_pstmt.setQueryTimeout(queryTimeout);
setParameters (m_pstmt, false); // no count setParameters (m_pstmt, false); // no count
if (log.isLoggable(Level.FINE)) if (log.isLoggable(Level.FINE))
log.fine("Start query - " + (System.currentTimeMillis()-startTime) + "ms"); log.fine("Start query - " + (System.currentTimeMillis()-startTime) + "ms");