cancel
Showing results for 
Search instead for 
Did you mean: 

How to extends customer search cscockpit with a new field?

Former Member
0 Kudos

Hi there,

I'm actually trying to modify the customer search panel in the cscockpit. I already had a small success (new field will be displayed) but the search is still not working...

So what did I do yet:

  1. I created my own CustomerSearchWidgetRenderer, which I think is working. The new field is displayed...

  2. Then I created my own CustomerSearchQueryBuilder and added the new field to the flexible search query.

Thats all steps which I did it yet. But I guess that some steps are missing... For example the DefaultCsTextSearchCommand in the CustomerSearchQueryBuilder. I think that I had to modify the DefaultCsTextSearchCommand, but I don't know how. In the Wiki I found a question which is about the same problem, but the solution I think is out of date....

https://wiki.hybris.com/display/forum/Customising+CSCockpit?focusedCommentId=89525926#comment-895259...

Does anybody know what I'm doing wrong?

MyCustomerSearchQueryBuilder:

 public class MyCustomerSearchQueryBuilder extends AbstractCsFlexibleSearchQueryBuilder<DefaultCsTextSearchCommand> {
 
     public MyCustomerSearchQueryBuilder() {
     }
 
     protected FlexibleSearchQuery buildFlexibleSearchQuery(DefaultCsTextSearchCommand command) {
         String name = command.getText(MyCustomerSearchQueryBuilder.TextField.Name);
         String postcode = command.getTextMyCustomerSearchQueryBuilder.TextField.Postcode);
         String username = command.getText(MyCustomerSearchQueryBuilder.TextField.Username);
         boolean searchName = StringUtils.isNotEmpty(name);
         boolean searchPostcode = StringUtils.isNotEmpty(postcode);
         boolean searchUsername = StringUtils.isNotEmpty(username);
         StringBuilder query = new StringBuilder(300);
         query.append("SELECT DISTINCT {c:pk}, {c:name}, {c:uid} ");
         query.append("FROM {Customer AS c ");
         if(searchPostcode) {
             query.append("LEFT JOIN Address AS a ON {c:pk}={a:owner} ");
         }
 
         query.append("} ");
         query.append("WHERE ({c:name}!=\'anonymous\' OR {c:name} IS NULL) ");
         if(searchName) {
             if(this.isCaseInsensitive()) {
                 query.append("AND LOWER({c:name}) LIKE LOWER(?customerName) ");
             } else {
                 query.append("AND {c:name} LIKE ?customerName ");
             }
         }
 
         if(searchPostcode) {
             if(this.isCaseInsensitive()) {
                 query.append("AND LOWER({a:postalcode}) LIKE LOWER(?postcode) ");
             } else {
                 query.append("AND {a:postalcode} LIKE ?postcode ");
             }
         }
 
         if(searchUsername) {
             if(this.isCaseInsensitive()) {
                 query.append("AND LOWER({c:uid}) LIKE LOWER(?username) ");
             } else {
                 query.append("AND {c:uid} LIKE ?username ");
             }
         }
 
         query.append("ORDER BY {c:name}, {c:uid} ");
         FlexibleSearchQuery searchQuery = new FlexibleSearchQuery(query.toString());
         if(searchName) {
             searchQuery.addQueryParameter("customerName", "%" + name.trim() + "%");
         }
 
         if(searchPostcode) {
             searchQuery.addQueryParameter("postcode", "%" + postcode.trim() + "%");
         }
 
         if(searchUsername) {
             searchQuery.addQueryParameter("username", "%" + username.trim() + "%");
         }
 
         return searchQuery;
     }
 
     public static enum TextField {
         Name,
         Postcode,
         Username;
 
         private TextField() {
         }
     }
 }

MyCustomerSearchWidgetRenderer:

 public class MyCustomerSearchWidgetRenderer extends AbstractSearcherWidgetRenderer {
     protected static final String COCKPIT_ID_SEARCHFORCUSTOMERS_CUSTOMERNAME_INPUT = "SearchForCustomers_CustomerName_input";
     protected static final String COCKPIT_ID_SEARCHFORCUSTOMER_CUSTOMERPOSTCODE_INPUT = "SearchForCustomer_CustomerPostcode_input";
     protected static final String COCKPIT_ID_SEARCHFORCUSTOMER_CUSTOMERUSERNAME_INPUT = "SearchForCustomer_CustomerUsername_input";
     protected static final String COCKPIT_ID_SEARCHFORCUSTOMER_SEARCH_BUTTON = "SearchForCustomer_Search_button";
     protected static final String COCKPIT_ID_SEARCHFORCUSTOMERS_ACTIONS_SELECT_BUTTON = "SearchForCustomers_Actions_Select_button";
 
     public MyCustomerSearchWidgetRenderer() {
     }
 
     protected HtmlBasedComponent createSearchPane(ListboxWidget<TextSearchWidgetModel, SearchCommandController<DefaultCsTextSearchCommand>> widget) {
         Div searchPane = new Div();
         Textbox searchNameInput = this.createNameField(widget, searchPane);
         Textbox searchPostcodeInput = this.createPostcodeField(widget, searchPane);
         Textbox searchUsernameInput = this.createUsernameField(widget, searchPane);
         Button searchBtn = this.createSearchButton(widget, searchPane);
         this.attachSearchEventListener(widget, this.createSearchEventListener(widget, searchNameInput, searchPostcodeInput,searchUsernameInput), new AbstractComponent[]{searchNameInput, searchPostcodeInput, searchBtn});
         return searchPane;
     }
 
     protected EventListener createSearchEventListener(ListboxWidget<TextSearchWidgetModel, SearchCommandController<DefaultCsTextSearchCommand>> widget, InputElement nameInput, InputElement postcodeInput, InputElement usernameInput) {
         return new MyCustomerSearchWidgetRenderer.MySearchEventListener(widget, nameInput, postcodeInput, usernameInput);
     }
 
     protected Textbox createNameField(ListboxWidget<TextSearchWidgetModel, SearchCommandController<DefaultCsTextSearchCommand>> widget, Div parent) {
         return this.createSearchTextField(widget, parent, "name", TextField.Name, "SearchForCustomers_CustomerName_input");
     }
 
     protected Textbox createPostcodeField(ListboxWidget<TextSearchWidgetModel, SearchCommandController<DefaultCsTextSearchCommand>> widget, Div parent) {
         return this.createSearchTextField(widget, parent, "postcode", TextField.Postcode, "SearchForCustomer_CustomerPostcode_input");
     }
 
     protected Textbox createUsernameField(ListboxWidget<TextSearchWidgetModel, SearchCommandController<DefaultCsTextSearchCommand>> widget, Div parent) {
         return this.createSearchTextField(widget, parent, "username", TextField.Username, "SearchForCustomer_CustomerUsername_input");
     }
 
     protected Button createSearchButton(ListboxWidget<TextSearchWidgetModel, SearchCommandController<DefaultCsTextSearchCommand>> widget, Div parent) {
         return this.createButton(widget, parent, "searchBtn", "SearchForCustomer_Search_button");
     }
 
     protected String buildSelectItemButtonTestID(ListboxWidget<TextSearchWidgetModel, SearchCommandController<DefaultCsTextSearchCommand>> widget, TypedObject item) {
         return "SearchForCustomers_Actions_Select_button_" + ((ItemModel)item.getObject()).getPk();
     }
 
     protected class MySearchEventListener extends AbstractSearchEventListener {
         private final transient ListboxWidget<TextSearchWidgetModel, SearchCommandController<DefaultCsTextSearchCommand>> widget;
         private final transient InputElement customerNameInput;
         private final transient InputElement customerPostcodeInput;
         private final transient InputElement customerUsernameInput;
 
         public MySearchEventListener(ListboxWidget<TextSearchWidgetModel, SearchCommandController<DefaultCsTextSearchCommand>> widget, InputElement customerNameInput, InputElement customerPostcodeInput, InputElement customerUsernameInput){
             super(widget);
             this.customerNameInput = customerNameInput;
             this.customerPostcodeInput = customerPostcodeInput;
             this.customerUsernameInput = customerUsernameInput;
             this.widget =widget;
         }
 
         protected void fillSearchCommand(DefaultCsTextSearchCommand command) {
             if(this.customerNameInput != null) {
                 command.setText(DefaultCustomerSearchQueryBuilder.TextField.Name, this.customerNameInput.getText());
             }
 
             if(this.customerPostcodeInput != null) {
                 command.setText(DefaultCustomerSearchQueryBuilder.TextField.Postcode, this.customerPostcodeInput.getText());
             }
 
         }
     }
 }

XML Config:

 <alias alias="csCustomerSearchQueryBuilder" name="myCustomerSearchQueryBuilder"/>
 <bean id="myCustomerSearchQueryBuilder" parent="baseCsFlexibleSearchQueryBuilder" class="com.my.cockpits.cscockpit.service.impl.MyCustomerSearchQueryBuilder">
 </bean>

 <!-- customer search widget -->
 <alias alias="csCustomerSearchWidgetConfig" name="defaultCsCustomerSearchWidgetConfig"/>
 <bean id="defaultCsCustomerSearchWidgetConfig" parent="csBaseWidgetConfig">
     <property name="widgetTitle" value="cscockpit.widget.customer.search"/>
     <property name="widgetRenderer" ref="csCustomerSearchWidgetRenderer"/>
     <property name="widgetController" ref="csCustomerSearchController"/>
     <property name="widgetClass" value="de.hybris.platform.cockpit.widgets.impl.DefaultListboxWidget"/>
     <property name="widgetSclass" value="defaultWidgetFrame csCustomerSearchWidgetFrame"/>
     <property name="widgetModel">
         <bean class="de.hybris.platform.cscockpit.widgets.models.impl.TextSearchWidgetModel"/>
     </property>
     <property name="widgetAdapter">
         <bean class="de.hybris.platform.cscockpit.widgets.adapters.TextSearchResultAdapter">
             <property name="cockpitTypeService" ref="cockpitTypeService"/>
         </bean>
     </property>
 </bean>

 <alias alias="csCustomerSearchWidgetRenderer" name="defaultCsCustomerSearchWidgetRenderer"/>
 <bean id="defaultCsCustomerSearchWidgetRenderer" parent="abstractWidgetRenderer" class="com.my.cockpits.cscockpit.widgets.MyCustomerSearchWidgetRenderer">
     <property name="listConfigurationCode" value="customerBrowseList"/>
     <property name="listConfigurationType" value="Customer"/>
     <property name="itemAppender">
         <bean class="de.hybris.platform.cscockpit.widgets.controllers.dispatcher.impl.PopupCloseAppender">
             <property name="popupWidgetHelper" ref="popupWidgetHelper"/>
             <property name="itemAppender">
                 <bean class="de.hybris.platform.cscockpit.widgets.controllers.dispatcher.impl.CustomerAppender" parent="csBaseAppender"/>
             </property>
         </bean>
     </property>
 </bean>




Former Member
0 Kudos

Hi Dominik,

Looks like you've done all correct, at least I'v compared with what we did and couldn't find anything missing.

Have tried debugging? Does it go to de.hybris.platform.cscockpit.widgets.renderers.impl.AbstractSearcherWidgetRenderer.AbstractSearchEventListener.onEvent(Event)? And what command does it return when executing buildSearchCommand() method?

Former Member
0 Kudos

Hi Vova,

Yes I already tried to debugging. The Problem is that the searchbuilder isn't able to read the new field:

 String username = command.getText(DefaultIDB2BCustomerSearchQueryBuilder.TextField.Username);

The field is always empty.

Accepted Solutions (1)

Accepted Solutions (1)

Former Member
0 Kudos

I finally got it. It was an copy paste failure...

This part was missing in the renderer:

    protected void fillSearchCommand(DefaultCsTextSearchCommand command) {
             if(this.customerNameInput != null) {
                 command.setText(TextField.Name, this.customerNameInput.getText());
             }
 
             if(this.customerPostcodeInput != null) {
                 command.setText(TextField.Postcode, this.customerPostcodeInput.getText());
             }
 
             if(this.customerUsernameInput != null) {
                 command.setText(TextField.Username, this.customerUsernameInput.getText());
             }
 
         }

Thank you for your answer 🙂

Answers (0)