Projet

General

Profil

How to create and config new datasource to autocomplete control?

Ajouté par Alex Chew il y a presque 12 ans

Hi,

I cannot setup autocomplete-association to retrieve data from my customized type/model, though there has a guide about this on https://becpg.fr/redmine/projects/designer/wiki/Controls.
I want to set one of my properties as title and the value of the field will be the NodeRef. Could you please show me a more detailed how-to guide? Many thanks.

Best Regards,
Alex


Réponses (11)

RE: How to create and config new datasource to autocomplete control? - Ajouté par Matthieu Laborie il y a presque 12 ans

Hi,

Sorry but I have no time for it during the next weeks. Have a look at sources code of designer we use it for property type or aspect choice.

This exemple

<appearance>
    <field id="bcpg:compoListProduct">
        <control
           template="/fr/becpg/components/form/controls/autocomplete-association.ftl">
            <control-param name="ds">becpg/autocomplete/product</control-param>
        </control>
    </field>
</appearance>

do what you need where bcpg:compoListProduct is an assoc to nodeRef of type product and becpg/autocomplete/product datasource use a java plugin for

  @Override
  public String[] getHandleSourceTypes() {
     return new String[] {"product" };
 }

  public ListValuePage suggest(String sourceType, String query, Integer pageNum, Integer pageSize, Map<String, Serializable> props) {        

                logger.debug("suggestProduct");  

        List<NodeRef> ret = //Your list of nodes;

         return new ListValuePage(ret, pageNum, pageSize, new NodeRefListValueExtractor(ContentModel.PROP_TITLE,nodeService));

   }

Which return a ListValuePage with product noderef.

Regards
Matthieu

RE: How to create and config new datasource to autocomplete control? - Ajouté par Alex Chew il y a presque 12 ans

Hi Matthieu,

I followed your guide but got below error message. It seems the plugin I created was not registered correctly. Did I miss something?

WARN  18-05 09:29:03,227 - No plugin found for sourceType :FunctionUnitDef
ERROR 18-05 09:29:03,233 - Exception from executeScript - redirecting to status
template error: 04180003 Unsupported argument 'sourcetype'. sourcetype = Functio
nUnitDef
org.springframework.extensions.webscripts.WebScriptException: 04180003 Unsupport
ed argument 'sourcetype'. sourcetype = FunctionUnitDef
        at fr.becpg.repo.listvalue.web.scripts.AutoCompleteWebScript.executeImpl
(AutoCompleteWebScript.java:143)

I defined two source-types in my plugin. Below is the detailed implementation:

package com.prophet.qbi.model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.namespace.QName;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import fr.becpg.repo.listvalue.ListValuePage;
import fr.becpg.repo.listvalue.ListValueService;
import fr.becpg.repo.listvalue.impl.AbstractBaseListValuePlugin;
import fr.becpg.repo.listvalue.impl.NodeRefListValueExtractor;

public class QbiListValuePlugin extends AbstractBaseListValuePlugin {

   Log logger = LogFactory.getLog(QbiListValuePlugin.class);

   String PKM_URI = "http://www.prophetconsulting.com.cn/model/prophetkm/1.0";
   private static String TYPE_Function_Unit = "FunctionUnitDef";
   private static String TYPE_Fault_Code = "FaultCodeDef";

   private SearchService searchService;

   public void setSearchService(SearchService searchService) {
      this.searchService = searchService;
   }

   private NodeService nodeService;

   public void setNodeService(NodeService nodeService) {
      this.nodeService = nodeService;
   }

   public String[] getHandleSourceTypes() {
      return new String[] {TYPE_Function_Unit, TYPE_Fault_Code};
   }

   public ListValuePage suggest(String sourceType, String query, Integer pageNum, Integer pageSize,
         Map<String, Serializable> props) {
      String nodeRef = (String) props.get(ListValueService.PROP_NODEREF);
      if (sourceType.equals(TYPE_Function_Unit)) {
         return getFunctionUnit(query, pageNum, pageSize);
      } else if (sourceType.equals(TYPE_Fault_Code)) {
         return getFaultCode(query, pageNum, pageSize);
      }
      return null;
   }

   public ListValuePage getFunctionUnit(String query, Integer pageNum, Integer pageSize) {
      logger.debug("retrieve pkm:FunctionUnitDef");
      NodeService.FindNodeParameters params = new NodeService.FindNodeParameters();
      List<QName> nodeTypes = new ArrayList<QName>();
      nodeTypes.add(QName.createQName(PKM_URI, TYPE_Function_Unit));
      params.setNodeTypes(nodeTypes);
      List<NodeRef> ret = nodeService.findNodes(params);
      return new ListValuePage(ret, pageNum, pageSize, new NodeRefListValueExtractor(ContentModel.PROP_TITLE,
            nodeService));
   }

   public ListValuePage getFaultCode(String query, Integer pageNum, Integer pageSize) {
      logger.debug("retrieve pkm:FaultCodeDef");
      NodeService.FindNodeParameters params = new NodeService.FindNodeParameters();
      List<QName> nodeTypes = new ArrayList<QName>();
      nodeTypes.add(QName.createQName(PKM_URI, TYPE_Fault_Code));
      params.setNodeTypes(nodeTypes);
      List<NodeRef> ret = nodeService.findNodes(params);
      return new ListValuePage(ret, pageNum, pageSize, new NodeRefListValueExtractor(ContentModel.PROP_TITLE,
            nodeService));
   }
}

And I create a new Spring service context file which named qbi-services-context.xml.

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN 2.0//EN' 'http://www.springframework.org/dtd/spring-beans-2.0.dtd'>

<beans>
    <!-- List Values -->
    <bean id="designerListValuePlugin" parent="baseListValuePlugin" 
        init-method="init" class="com.prophet.qbi.model.QbiListValuePlugin">
        <property name="nodeService" ref="nodeService" />
        <property name="searchService" ref="searchService" />
    </bean>
</beans>

To ensure Alfresco will load this context file I also add below entry into application-context-highlevel.xml file.

<import resource="classpath:alfresco/qbi-services-context.xml"/>

Then I restarted Alfresco and defined a new field

          <field id="pkm:FuncUnitAsso" label="FuncUnitAsso" mandatory="false" read-only="false">
            <control template="/fr/becpg/components/form/controls/autocomplete-association.ftl">
              <control-param name="ds">becpg/autocomplete/FunctionUnitDef</control-param>
            </control>
          </field>

While I was trying to list available list values I got the "No plugin found for sourceType:FunctionUnitDef" error.

Best Regards,
Alex

RE: How to create and config new datasource to autocomplete control? - Ajouté par Alex Chew il y a presque 12 ans

Hi Matthieu,

Please ignore above message. I made a stupid mistake. I forgot to change the id of my list value plugin. I changed the id to qbiListValuePlugin and now the plugin is registered correctly.

Best Regards,
Alex

RE: How to create and config new datasource to autocomplete control? - Ajouté par Alex Chew il y a presque 12 ans

Sorry to disturb one more time.

I got a java.lang.AbstractMethodError while trying to test the plugin. I have checked the AbstractBaseListValuePlugin and ListValuePlugin. And I have added @Override notation on both getHandleSourceTypes and suggest method in QbiListValuePlugin.

It's strange to me. I can execute "mvn clean install" as normal. And there have no error tips after I convert QbiListValuePlugin to Eclipse project by using "mvn eclipse:eclipse". Do you have any ideas about it? Below is the detailed error stack.

Caused by: java.lang.AbstractMethodError: com.prophet.qbi.model.QbiListValuePlug
in.suggest(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;Ljava/util/Map
;)Lfr/becpg/repo/listvalue/ListValuePage;
        at fr.becpg.repo.listvalue.impl.ListValueServiceImpl.suggestBySourceType
(ListValueServiceImpl.java:52)
        at fr.becpg.repo.listvalue.web.scripts.AutoCompleteWebScript.executeImpl
(AutoCompleteWebScript.java:139)
        at org.springframework.extensions.webscripts.DeclarativeWebScript.execut
e(DeclarativeWebScript.java:64)
        ... 25 more

Best Regards,
Alex

RE: How to create and config new datasource to autocomplete control? - Ajouté par Alex Chew il y a presque 12 ans

Hi Matthieu,

The error was caused by different becpg designer version in my develop environment(1.4.0) and runtime environment(0.1.4). I still used the 0.1.4 version which I got by installing AMP files. The signature of suggest() method is:

   @Override
   public ListValuePage suggest(String sourceType, String query, Integer pageNum, Map<String, Serializable> props) {
      return suggest(sourceType, query, pageNum, new Integer(10), props);
   }

And now the autocomplete control works well in create-mode. I attached the screenshot to flickr at http://www.flickr.com/photos/78957907@N06/7221101506/in/photostream
But I don't know why the autocomplete control become a file-choice in edit-mode. Here is the picture on flickr http://www.flickr.com/photos/78957907@N06/7221101274/in/photostream

I guess there has an option for this but I didn't find that. Could you please show me the light? Many thanks.

Best Regards,
Alex

RE: How to create and config new datasource to autocomplete control? - Ajouté par Matthieu Laborie il y a presque 12 ans

Hi Alex!

I'm in Holiday until tomorrow I will have a closer look monday.
Anyway in datalist view edit form should have id "datalist" to be effectif.

Best regards
Matthieu

RE: How to create and config new datasource to autocomplete control? - Ajouté par Alex Chew il y a presque 12 ans

Hi Matthieu,

Thanks for your reply. I moved a step forward. Now I can list all values from any backend models in both create-mode and edit-mode. So please ignore previous questions. But there still have two questions remained.
1,The initial value of the auto-complete control was wrongly populated. In the edit-mode the nodeRef ID was populated but not the Title.
2,I cannot filter on the list value while I input something in the text box

Could you please show me the light? Thanks a lot.

Best Regards,
Alex

RE: How to create and config new datasource to autocomplete control? - Ajouté par Matthieu Laborie il y a presque 12 ans

Alex Chew a écrit :

Hi Matthieu,

Thanks for your reply. I moved a step forward. Now I can list all values from any backend models in both create-mode and edit-mode. So please ignore previous questions. But there still have two questions remained.
1,The initial value of the auto-complete control was wrongly populated. In the edit-mode the nodeRef ID was populated but not the Title.

Are you using autocomplete.ftl or autocomplete-association.ftl? If you use autocomplete you should provide field.control.params.saveTitle=true in your form config to have it save the title instead of the nodeRef.

2,I cannot filter on the list value while I input something in the text box

The filter should be implement in your java class with the query param.

Could you please show me the light? Thanks a lot.

Best Regards,
Alex

RE: How to create and config new datasource to autocomplete control? - Ajouté par Alex Chew il y a presque 12 ans

Hi Matthieu,

Thanks for the information. The second question now is done. But the first one is still open.

I am using autocomplete-association.ftl. And I also steped into the source code of it. And I found below codes:

                      <input id="${fieldHtmlId}" type="text" name="-" tabindex="0" 
                             <#if field.description?exists>title="${field.description}"</#if>
                             <#if field.control.params.maxLength?exists>maxlength="${field.control.params.maxLength}"</#if> 
                             <#if field.control.params.size?exists>size="${field.control.params.size}"</#if> 
                             <#if field.disabled>disabled="true"</#if> 
                             class="yui-ac-input<#if field.endpointMany> multi-assoc</#if>" <#if !field.endpointMany>value="${field.value}" </#if>>
                       </input>

It seems the initial value was assigned by
<#if !field.endpointMany>value="${field.value}" </#if>

What can I do to keep the value but populate title?

Best Regards,
Alex

RE: How to create and config new datasource to autocomplete control? - Ajouté par Matteo Cremolini il y a presque 12 ans

Hi,

i wish write my custom plugin for autocomplete.
- the version becpg-contribs-20120327-1212-distribution.tar.gz is not aligned to repository source so the suggest method has a differnt signature (less parameters)
- i can't build the current repository version through maven.Above my error.

Can you help me?
The project is extremely interesting

regards
Matteo

Failed to execute goal org.apache.maven.plugins:maven-assembly-plugin:2.2.2:single (distro-assembly) on project becpg-contribs-distribution: Failed to create assembly: Unable to resolve dependencies for assembly 'distribution': Failed to resolve dependencies for assembly: Missing:
[ERROR] ----------
[ERROR] 1) fr.becpg:becpg-controls-core:amp:1.4.0
[ERROR]
[ERROR] Try downloading the file manually from the project website.
[ERROR]
[ERROR] Then, install it using the command:
[ERROR] mvn install:install-file DgroupId=fr.becpg -DartifactId=becpg-controls-core -Dversion=1.4.0 -Dpackaging=amp -Dfile=/path/to/file
[ERROR]
[ERROR] Alternatively, if you host your own repository you can deploy the file there:
[ERROR] mvn deploy:deploy-file -DgroupId=fr.becpg -DartifactId=becpg-controls-core -Dversion=1.4.0 -Dpackaging=amp -Dfile=/path/to/file -Durl=[url] -DrepositoryId=[id]
[ERROR]
[ERROR] Path to dependency:
[ERROR] 1) fr.becpg:becpg-contribs-distribution:pom:1.4.0
[ERROR] 2) fr.becpg:becpg-controls-core:amp:1.4.0
[ERROR]
[ERROR] 2) fr.becpg:becpg-designer-share:amp:1.4.0
[ERROR]
[ERROR] Try downloading the file manually from the project website.
[ERROR]
[ERROR] Then, install it using the command:
[ERROR] mvn install:install-file -DgroupId=fr.becpg -DartifactId=becpg-designer-share -Dversion=1.4.0 -Dpackaging=amp -Dfile=/path/to/file
[ERROR]
[ERROR] Alternatively, if you host your own repository you can deploy the file there:
[ERROR] mvn deploy:deploy-file -DgroupId=fr.becpg -DartifactId=becpg-designer-share -Dversion=1.4.0 -Dpackaging=amp -Dfile=/path/to/file -Durl=[url] -DrepositoryId=[id]
[ERROR]
[ERROR] Path to dependency:
[ERROR] 1) fr.becpg:becpg-contribs-distribution:pom:1.4.0
[ERROR] 2) fr.becpg:becpg-designer-share:amp:1.4.0
[ERROR]
[ERROR] 3) fr.becpg:becpg-designer-core:amp:1.4.0
[ERROR]
[ERROR] Try downloading the file manually from the project website.
[ERROR]
[ERROR] Then, install it using the command:
[ERROR] mvn install:install-file -DgroupId=fr.becpg -DartifactId=becpg-designer-core -Dversion=1.4.0 -Dpackaging=amp -Dfile=/path/to/file
[ERROR]
[ERROR] Alternatively, if you host your own repository you can deploy the file there:
[ERROR] mvn deploy:deploy-file -DgroupId=fr.becpg -DartifactId=becpg-designer-core -Dversion=1.4.0 -Dpackaging=amp -Dfile=/path/to/file -Durl=[url] -DrepositoryId=[id]
[ERROR]
[ERROR] Path to dependency:
[ERROR] 1) fr.becpg:becpg-contribs-distribution:pom:1.4.0
[ERROR] 2) fr.becpg:becpg-designer-core:amp:1.4.0
[ERROR]
[ERROR] 4) fr.becpg:becpg-controls-share:amp:1.4.0
[ERROR]
[ERROR] Try downloading the file manually from the project website.
[ERROR]
[ERROR] Then, install it using the command:
[ERROR] mvn install:install-file -DgroupId=fr.becpg -DartifactId=becpg-controls-share -Dversion=1.4.0 -Dpackaging=amp -Dfile=/path/to/file
[ERROR]
[ERROR] Alternatively, if you host your own repository you can deploy the file there:
[ERROR] mvn deploy:deploy-file -DgroupId=fr.becpg -DartifactId=becpg-controls-share -Dversion=1.4.0 -Dpackaging=amp -Dfile=/path/to/file -Durl=[url] -DrepositoryId=[id]
[ERROR]
[ERROR] Path to dependency:
[ERROR] 1) fr.becpg:becpg-contribs-distribution:pom:1.4.0
[ERROR] 2) fr.becpg:becpg-controls-share:amp:1.4.0
[ERROR]
[ERROR] ---------

[ERROR] 4 required artifacts are missing.
[ERROR]
[ERROR] for artifact:
[ERROR] fr.becpg:becpg-contribs-distribution:pom:1.4.0
[ERROR]
[ERROR] from the specified remote repositories:
[ERROR] alfresco-public-snapshots (http://maven.alfresco.com/nexus/content/groups/public-snapshots, releases=true, snapshots=true),
[ERROR] alfresco-public (http://maven.alfresco.com/nexus/content/groups/public, releases=true, snapshots=true),
[ERROR] central (http://repo1.maven.org/maven2, releases=true, snapshots=false)
[ERROR] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException

RE: How to create and config new datasource to autocomplete control? - Ajouté par Matthieu Laborie il y a presque 12 ans

Hi,

You should first install required artifacts, there is bash script for it under linux (maven-sdk-install-files.sh) or make your own under windows (please contribute it).
Here are the steps to build amps (README):

0 - Setup project
------------------

Copy common.sh.sample to common.sh
and change properties

1 - Install Maven artifacts
-----------------------------

To install becpg artifacts download alfresco sdk and alfresco server
Configure common.sh
Then run maven-sdk-install-files.sh

2 - Run project
----------------

Run Junit test :

(adapt pom.xml to your test DB)
mvn clean test

Package AMP :

mvn clean package -Dmaven.test.skip=true

Will package the distribution


You can also use a previous source revision that match the released build:

https://becpg.fr/redmine/projects/designer/repository/revisions/fe9f880c3955

hg update -r fe9f880c3955

    (1-11/11)