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)
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.Placeholder = rs.getString("Placeholder");
vo.Placeholder2 = rs.getString("Placeholder2");
vo.IsAutocomplete = "Y".equals(rs.getString("IsAutoComplete"));
}
catch (SQLException e)
{

View File

@ -298,6 +298,19 @@ public interface I_AD_InfoColumn
*/
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 */
public static final String COLUMNNAME_IsCentrallyMaintained = "IsCentrallyMaintained";

View File

@ -294,6 +294,19 @@ public interface I_AD_Process_Para
*/
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 */
public static final String COLUMNNAME_IsCentrallyMaintained = "IsCentrallyMaintained";

View File

@ -303,6 +303,19 @@ public interface I_AD_UserDef_Field
*/
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 */
public static final String COLUMNNAME_IsDisplayed = "IsDisplayed";

View File

@ -18,6 +18,7 @@ package org.compiere.model;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import javax.swing.AbstractListModel;
@ -481,6 +482,21 @@ public abstract class Lookup extends AbstractListModel<Object>
return get (key);
} // 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
*/

View File

@ -211,4 +211,25 @@ public class MInfoColumn extends X_AD_InfoColumn implements IInfoColumn
public MInfoColumn getAD_InfoColumn() {
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

View File

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

View File

@ -23,11 +23,15 @@ import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Future;
import java.util.logging.Level;
import org.adempiere.util.ContextRunnable;
import org.compiere.Adempiere;
import org.compiere.util.CCache;
import org.compiere.util.CLogMgt;
import org.compiere.util.DB;
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 final static int MAX_NAMEPAIR_CACHE_SIZE = 1000;
/**
* Dispose
*/
@ -540,7 +545,31 @@ public final class MLookup extends Lookup implements Serializable
}
if (log.isLoggable(Level.FINER)) log.finer(m_info.KeyColumn + ": " + key
+ ", SaveInCache=" + saveInCache + ",Local=" + cacheLocal);
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;
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;
ResultSet rs = null;
try
@ -567,6 +596,16 @@ public final class MLookup extends Lookup implements Serializable
if (saveInCache) // save if
m_lookup.put(Integer.valueOf(keyValue), 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
{
@ -575,6 +614,16 @@ public final class MLookup extends Lookup implements Serializable
if (saveInCache) // save if
m_lookup.put(value, 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())
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;
} // 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
* @return Zoom AD_Window_ID
@ -759,6 +934,12 @@ public final class MLookup extends Lookup implements Serializable
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
*/
@ -785,8 +966,6 @@ public final class MLookup extends Lookup implements Serializable
protected void doRun()
{
long startTime = System.currentTimeMillis();
if (Ini.isClient())
MLookupCache.loadStart (m_info);
StringBuilder sql = new StringBuilder().append(m_info.Query);
// IDEMPIERE 90
@ -849,6 +1028,44 @@ public final class MLookup extends Lookup implements Serializable
// Reset
m_lookup.clear();
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;
int rows = 0;
PreparedStatement pstmt = null;
@ -905,15 +1122,28 @@ public final class MLookup extends Lookup implements Serializable
int key = rs.getInt(1);
KeyNamePair p = new KeyNamePair(key, name.toString());
m_lookup.put(Integer.valueOf(key), p);
knpCache.add(p);
}
else
{
String value = rs.getString(2);
ValueNamePair p = new ValueNamePair(value, name.toString());
m_lookup.put(value, p);
vnpCache.add(p);
}
// 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)
{
@ -930,9 +1160,6 @@ public final class MLookup extends Lookup implements Serializable
+ " - Loader complete #" + size + " - all=" + m_allLoaded
+ " - ms=" + String.valueOf(System.currentTimeMillis()-m_startTime)
+ " (" + String.valueOf(System.currentTimeMillis()-startTime) + ")");
// if (m_allLoaded)
if (Ini.isClient())
MLookupCache.loadEnd (m_info, m_lookup);
} // run
} // 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 */
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);
setEntityType (null);
// @SQL=select get_sysconfig('DEFAULT_ENTITYTYPE','U',0,0) from dual
setIsAutocomplete (false);
// N
setIsCentrallyMaintained (true);
// Y
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);
}
/** 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.
@param IsCentrallyMaintained
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 */
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);
// @SQL=select get_sysconfig('DEFAULT_ENTITYTYPE','U',0,0) from dual
setFieldLength (0);
setIsAutocomplete (false);
// N
setIsCentrallyMaintained (true);
// Y
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);
}
/** 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.
@param IsCentrallyMaintained
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 */
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);
}
/** 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 */
public static final int ISDISPLAYED_AD_Reference_ID=319;
/** Yes = Y */

View File

@ -209,7 +209,7 @@ public class ProcessParameterPanel extends Panel implements
+ "p.FieldLength, p.IsMandatory, p.IsRange, p.ColumnName, "
+ "p.DefaultValue, p.DefaultValue2, p.VFormat, p.ValueMin, p.ValueMax, "
+ "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"
+ " LEFT OUTER JOIN AD_Val_Rule vr ON (p.AD_Val_Rule_ID=vr.AD_Val_Rule_ID) "
+ "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.DefaultValue, p.DefaultValue2, p.VFormat, p.ValueMin, p.ValueMax, "
+ "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"
+ " 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) "

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;
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.List;
import java.util.Properties;
import java.util.Set;
import java.util.logging.Level;
@ -40,11 +35,11 @@ import org.adempiere.webui.theme.ThemeManager;
import org.adempiere.webui.window.WFieldRecordInfo;
import org.compiere.model.GridField;
import org.compiere.model.Lookup;
import org.compiere.model.MColumn;
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.util.CLogger;
import org.compiere.util.DB;
import org.compiere.util.Env;
import org.compiere.util.Util;
import org.compiere.util.ValueNamePair;
@ -71,9 +66,11 @@ public class WChosenboxSearchEditor extends WEditor implements ContextMenuListen
private String value;
private InfoPanel infoPanel = null;
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 int MAX_AUTO_COMPLETE_ROWS = 50;
private boolean onselecting;
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);
getComponent().getButton().setImage(imageUrl);
setTableAndKeyColumn();
subModel = new InfoListSubModel(lookup, gridField, m_tableName, m_keyColumnName);
getComponent().getChosenbox().setModel(model);
addChangeLogMenu(popupMenu);
@ -422,7 +422,7 @@ public class WChosenboxSearchEditor extends WEditor implements ContextMenuListen
String whereClause = getWhereClause();
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);
if (ip != null)
@ -466,228 +466,37 @@ public class WChosenboxSearchEditor extends WEditor implements ContextMenuListen
}
/**
* Generate Access SQL for Search.
* 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 ...
* Sets m_tableName and m_keyColumnName
*/
private String getDirectAccessSQL (String text)
{
String m_columnName = getColumnName();
StringBuffer sql = new StringBuffer();
m_tableName = m_columnName.substring(0, m_columnName.length()-3);
m_keyColumnName = m_columnName;
if (m_columnName.equals("M_Product_ID"))
{
private void setTableAndKeyColumn() {
if (lookup != null && lookup instanceof MLookup) {
// foreign table defined in lookup
m_keyColumnName = ((MLookup)lookup).getColumnName();
if (m_keyColumnName.contains(".")) {
m_tableName = m_keyColumnName.substring(0, m_keyColumnName.indexOf("."));
m_keyColumnName = m_keyColumnName.substring(m_keyColumnName.indexOf(".")+1);
} else {
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
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_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()
{
String whereClause = "";
@ -756,35 +565,8 @@ public class WChosenboxSearchEditor extends WEditor implements ContextMenuListen
@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();
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;
}
}
}
}
}
subModel.setWhereClause(getWhereClause());
ListModel<ValueNamePair> model = subModel.getSubModel(value, MAX_AUTO_COMPLETE_ROWS);
getComponent().getChosenbox().setSubListModel(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.QuickGridTabRowRenderer;
import org.adempiere.webui.apps.AEnv;
import org.adempiere.webui.component.ComboEditorBox;
import org.adempiere.webui.component.Searchbox;
import org.adempiere.webui.event.ContextMenuEvent;
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.DisplayType;
import org.compiere.util.Env;
import org.compiere.util.Util;
import org.zkoss.zk.au.out.AuScript;
import org.zkoss.zk.ui.Component;
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.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.event.InputEvent;
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
{
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};
public static final String ATTRIBUTE_IS_INFO_PANEL_OPEN = "ATTRIBUTE_IS_INFO_PANEL_OPEN";
private Lookup lookup;
@ -82,6 +87,7 @@ public class WSearchEditor extends WEditor implements ContextMenuListener, Value
private Object value;
private InfoPanel infoPanel = null;
private String imageUrl;
private InfoListSubModel listModel = null;
private static final CLogger log = CLogger.getCLogger(WSearchEditor.class);
@ -104,8 +110,8 @@ public class WSearchEditor extends WEditor implements ContextMenuListener, Value
@Override
public Searchbox getComponent() {
return (Searchbox) super.getComponent();
public ComboEditorBox getComponent() {
return (ComboEditorBox) super.getComponent();
}
@Override
@ -201,7 +207,35 @@ public class WSearchEditor extends WEditor implements ContextMenuListener, Value
addChangeLogMenu(popupMenu);
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;
}
@ -401,7 +435,7 @@ public class WSearchEditor extends WEditor implements ContextMenuListener, Value
focusNext();
//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 +
"').$n(); if (jq(':focus').size() == 0) e.focus();} catch(error){}}, 100);";
Clients.response(new AuScript(script));
@ -614,12 +648,12 @@ public class WSearchEditor extends WEditor implements ContextMenuListener, Value
getComponent().setText("");
actionCombo(null);
}
getComponent().getTextbox().focus();
getComponent().getCombobox().focus();
}
else
{
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);
}
}
@ -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
@ -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){}";
if (ThemeManager.isUseFontIconForImage()) {
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){}");
} else {
getTextbox().setWidgetListener("onChange", "try{"+w+"btn.setImage(\""
getCombobox().setWidgetListener("onChange", "try{"+w+"btn.setImage(\""
+ Executions.getCurrent().encodeURL(IN_PROGRESS_IMAGE)+"\");"
+ "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 TableInfo[] tableInfos;
protected MInfoColumn[] infoColumns;
protected String queryValue;
protected WQuickEntry vqe;
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,
boolean multipleSelection, String whereClause, int AD_InfoWindow_ID, boolean lookup, GridField field) {
super(WindowNo, tableName, keyColumn, multipleSelection, whereClause,
lookup, AD_InfoWindow_ID);
lookup, AD_InfoWindow_ID, queryValue);
this.m_gridfield = field;
this.queryValue = queryValue;
//Xolali IDEMPIERE-1045
contentPanel.addActionListener(new EventListener<Event>() {
@ -242,8 +241,10 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
if (haveProcess)
p_multipleSelection = true;
}
loadInfoRelatedTabs();
if (!isAutoComplete)
loadInfoRelatedTabs();
if (loadedOK()) {
if (isLookup()) {
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
initExport();
if (!isAutoComplete)
initExport();
}
/**
@ -505,6 +506,9 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
isQueryByUser = true;
for (int i = 0; i < identifiers.size(); i++) {
WEditor editor = identifiers.get(i);
if (isAutoComplete && i > 0) {
break;
}
try{
editor.setValue(queryValue);
}catch(Exception ex){
@ -520,17 +524,19 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
}
boolean splitValue = false;
if (m_count <= 0) {
String separator = MSysConfig.getValue(MSysConfig.IDENTIFIER_SEPARATOR, "_", Env.getAD_Client_ID(Env.getCtx()));
String[] values = queryValue.split("[" + separator.trim()+"]");
if (values.length == 2) {
splitValue = true;
for(int i = 0; i < values.length && i < identifiers.size(); i++) {
WEditor editor = identifiers.get(i);
editor.setValue(values[i].trim());
}
testCount(false);
}
if (!isAutoComplete) {
if (m_count <= 0) {
String separator = MSysConfig.getValue(MSysConfig.IDENTIFIER_SEPARATOR, "_", Env.getAD_Client_ID(Env.getCtx()));
String[] values = queryValue.split("[" + separator.trim()+"]");
if (values.length == 2) {
splitValue = true;
for(int i = 0; i < values.length && i < identifiers.size(); i++) {
WEditor editor = identifiers.get(i);
editor.setValue(values[i].trim());
}
testCount(false);
}
}
}
if (m_count > 0) {
@ -605,6 +611,7 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
String help = infoColumn.get_Translation("Help");
vo.Help = help != null ? help : "";
vo.AD_FieldStyle_ID = infoColumn.getAD_FieldStyle_ID();
vo.IsAutocomplete = infoColumn.isAutocomplete();
GridField gridField = new GridField(vo);
gridFields.add(gridField);
}
@ -1445,10 +1452,12 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
row.appendChild(checkAND);
}
}
evalDisplayLogic();
if (!isAutoComplete)
evalDisplayLogic();
if (!update)
initParameters();
dynamicDisplay(null);
if (!isAutoComplete)
dynamicDisplay(null);
}
protected void evalDisplayLogic() {
@ -1927,6 +1936,8 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
try
{
pstmt = DB.prepareStatement(countSql, null);
if (queryTimeout > 0)
pstmt.setQueryTimeout(queryTimeout);
setParameters (pstmt, true);
rs = pstmt.executeQuery();
@ -2122,6 +2133,9 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
@Override
protected boolean hasNew() {
if (isAutoComplete)
return false;
boolean hasNew = getADWindowID () > 0;
if (hasNew && vqe == null && hasRightQuickEntry){
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)
{
super(windowNo, tableName, keyColumn, false,whereClause, lookup);
super(windowNo, tableName, keyColumn, false, whereClause, lookup, 0, queryValue);
setTitle(Msg.getMsg(Env.getCtx(), "Info"));
@ -112,26 +112,7 @@ public class InfoGeneralPanel extends InfoPanel implements EventListener<Event>
p_loadedOK = initInfo ();
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 (m_count <= 0)
{
txt1.setValue(queryValue);
}
}
processQueryValue();
}
catch (Exception e)
{
@ -146,22 +127,25 @@ public class InfoGeneralPanel extends InfoPanel implements EventListener<Event>
if (queryValue != null && queryValue.length() > 0)
{
MTable table = MTable.get(Env.getCtx(), p_tableName);
if ( table.getIdentifierColumns().length > 1
&& !p_tableName.startsWith("AD_")) // 32 AD tables with identifiers containing _
if (!isAutoComplete)
{
String separator = I_C_ElementValue.Table_Name.equalsIgnoreCase(p_tableName) ? "-" : "_";
if (txt2.isVisible())
MTable table = MTable.get(Env.getCtx(), p_tableName);
if ( table.getIdentifierColumns().length > 1
&& !p_tableName.startsWith("AD_")) // 32 AD tables with identifiers containing _
{
String[] values = queryValue.split("["+separator+"]");
if (values != null && values.length == 2)
String separator = I_C_ElementValue.Table_Name.equalsIgnoreCase(p_tableName) ? "-" : "_";
if (txt2.isVisible())
{
txt1.setValue(values[0]);
txt2.setValue(values[1]);
String[] values = queryValue.split("["+separator+"]");
if (values != null && values.length == 2)
{
txt1.setValue(values[0]);
txt2.setValue(values[1]);
}
}
}
}
}
}
executeQuery();
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()
{
Grid grid = GridFactory.newGridLayout();

View File

@ -87,6 +87,7 @@ import org.compiere.util.Env;
import org.compiere.util.KeyNamePair;
import org.compiere.util.Msg;
import org.compiere.util.Trx;
import org.compiere.util.Util;
import org.compiere.util.ValueNamePair;
import org.zkoss.zk.au.out.AuEcho;
import org.zkoss.zk.ui.Page;
@ -221,17 +222,26 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
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
* @param WindowNo WindowNo
* @param tableName tableName
* @param keyColumn keyColumn
* @param whereClause whereClause
* @param queryValue
*/
protected InfoPanel (int WindowNo,
String tableName, String keyColumn,boolean multipleSelection,
String whereClause, boolean lookup, int ADInfoWindowID)
{
String whereClause, boolean lookup, int ADInfoWindowID, String queryValue)
{
if (WindowNo <= 0) {
p_WindowNo = SessionManager.getAppDesktop().registerWindow(this);
} else {
@ -243,6 +253,12 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
this.m_infoWindowID = ADInfoWindowID;
p_keyColumn = keyColumn;
this.queryValue = queryValue;
if (queryValue != null && queryValue.trim().length() > 0)
{
parseQueryValue();
}
p_multipleSelection = multipleSelection;
m_lookup = lookup;
loadInfoWindowData();
@ -275,6 +291,38 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
} // 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()
{
if (isLookup())
@ -409,6 +457,13 @@ public abstract class InfoPanel extends Window implements EventListener<Event>,
* IDEMPIERE-1979
*/
protected boolean isQueryByUser = false;
protected boolean isAutoComplete = false;
protected int queryTimeout = 0;
protected String queryValue;
/**
* 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.setDisplayName(getClass().getName()+"_readLine");
m_pstmt = DB.prepareStatement(dataSql, trxName);
if (queryTimeout > 0)
m_pstmt.setQueryTimeout(queryTimeout);
setParameters (m_pstmt, false); // no count
if (log.isLoggable(Level.FINE))
log.fine("Start query - " + (System.currentTimeMillis()-startTime) + "ms");