Skip to content

Instantly share code, notes, and snippets.

@sergio1990
Created August 18, 2017 09:27
Show Gist options
  • Save sergio1990/ca839062f321010e519ceea61598d840 to your computer and use it in GitHub Desktop.
Save sergio1990/ca839062f321010e519ceea61598d840 to your computer and use it in GitHub Desktop.
Custom editor for CMS Cockpit of the Hybris Platform
package com.mycompany.cms2components.data;
public class ItemOption {
private Integer id;
private String title;
private String description;
private String thumbUrl;
public ItemOption()
{
}
public void setId(final Integer id)
{
this.id = id;
}
public Integer getId()
{
return id;
}
public void setTitle(final String title)
{
this.title = title;
}
public String getTitle()
{
return title;
}
@Override
public String toString() {
return this.getTitle();
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getThumbUrl() {
return thumbUrl;
}
public void setThumbUrl(String thumbUrl) {
this.thumbUrl = thumbUrl;
}
}
package com.mycompany.cms2components.service;
import com.mycompany.cms2components.data.ItemOption;
import java.util.List;
public interface ItemSelectDataSource {
List<ItemOption> doSearch(String term, String locale);
List<ItemOption> getByIds(List<String> ids);
}
package com.mycompany.cms2components.editor;
import com.mycompany.cms2components.data.ItemOption;
import com.mycompany.cms2components.editor.model.ItemSelectUIEditorModel;
import com.mycompany.cms2components.service.ItemSelectDataSource;
import de.hybris.platform.cockpit.model.editor.EditorListener;
import de.hybris.platform.cockpit.model.editor.ListUIEditor;
import de.hybris.platform.cockpit.model.editor.impl.AbstractUIEditor;
import de.hybris.platform.cockpit.services.values.ObjectValueContainer;
import de.hybris.platform.core.Registry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ReflectionUtils;
import org.zkoss.zk.ui.HtmlBasedComponent;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.event.InputEvent;
import org.zkoss.zul.Combobox;
import org.zkoss.zul.Comboitem;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
public class ItemSelectUIEditor extends AbstractUIEditor implements ListUIEditor {
private static final Logger LOG = LoggerFactory.getLogger(ItemSelectUIEditor.class);
private Combobox editorView;
private ItemSelectDataSource dataSource;
private ItemSelectUIEditorModel model;
public ItemSelectUIEditor() {
LOG.info("ItemSelectUIEditor initialization started!");
this.dataSource = this.getDataSourceBean();
this.model = this.getModelBean();
this.editorView = new Combobox();
this.setupEditorViewDefaultBehaviour();
}
@Override
public HtmlBasedComponent createViewComponent(Object initialValue, Map<String, ? extends Object> parameters, EditorListener listener) {
this.setInitialSelection(initialValue);
this.setupEditorViewEvents(listener);
return this.getEditorView();
}
private void setInitialSelection(Object initialValue) {
if (initialValue == null) { return; }
List<ItemOption> options = dataSource.getByIds(Collections.singletonList(initialValue.toString()));
this.model.setAutocompleteResult(options);
this.updateAutoCompleteItemList();
this.getEditorView().setSelectedIndex(0);
}
private void setupEditorViewDefaultBehaviour() {
this.getEditorView().setAutocomplete(true);
this.getEditorView().setAutodrop(true);
this.getEditorView().setButtonVisible(false);
}
private void setupEditorViewEvents(EditorListener listener) {
this.getEditorView().addEventListener(Events.ON_CHANGING, event -> {
String term = ((InputEvent) event).getValue();
LOG.info("onChanging triggered with value '" + term + "'!");
Field valueHolderFields = ReflectionUtils.findField(listener.getClass(), "val$valueHolder");
ReflectionUtils.makeAccessible(valueHolderFields);
ObjectValueContainer.ObjectValueHolder valueHolder = (ObjectValueContainer.ObjectValueHolder) ReflectionUtils.getField(valueHolderFields, listener);
String locale = valueHolder.getLanguageIso();
ItemSelectUIEditor.this.updateAutocomplete(term, locale);
});
this.getEditorView().addEventListener(Events.ON_CHANGE, event -> {
LOG.info("onChange triggered!");
this.onSavingEvent(listener);
});
}
private void updateAutocomplete(String term, String locale) {
if (term.length() < 3) {
this.model.setAutocompleteResult(new ArrayList<>());
}else{
List<ItemOption> options = dataSource.doSearch(term, locale);
this.model.setAutocompleteResult(options);
}
this.updateAutoCompleteItemList();
}
private void updateAutoCompleteItemList() {
this.getEditorView().getItems().clear();
for (Comboitem comboitem : this.model.getAutocompleteComboitems()) {
this.getEditorView().appendChild(comboitem);
}
}
private void onSavingEvent(EditorListener listener) {
LOG.info("onSavingEvent called!");
if(this.getEditorView().getSelectedItem() == null) { return; }
Comboitem selectedOption = this.getEditorView().getSelectedItem();
this.setValue(selectedOption.getValue());
listener.valueChanged(this.getValue());
}
@Override
public boolean isInline() {
return true;
}
@Override
public String getEditorType() {
return "INTEGER";
}
@Override
public void setAvailableValues(List<? extends Object> list) {
}
@Override
public List<ItemOption> getAvailableValues() {
return null;
}
public void setFocus(HtmlBasedComponent rootEditorComponent, boolean selectAll) {
Combobox element = (Combobox)((CancelButtonContainer)rootEditorComponent).getContent();
element.setFocus(true);
if(this.initialInputString != null) {
element.setText(this.initialInputString);
}
}
protected Combobox getEditorView() {
return editorView;
}
private ItemSelectDataSource getDataSourceBean() {
return Registry.getApplicationContext().getBean("defaultItemSelectDataSource", ItemSelectDataSource.class);
}
private ItemSelectUIEditorModel getModelBean() {
return Registry.getApplicationContext().getBean("defaultItemSelectUIEditorModel", ItemSelectUIEditorModel.class);
}
}
package com.mycompany.cms2components.editor.model;
import com.mycompany.cms2components.data.ItemOption;
import org.zkoss.zul.Comboitem;
import java.util.List;
public interface ItemSelectUIEditorModel {
List<ItemOption> getAutocompleteResult();
void setAutocompleteResult(List<ItemOption> options);
List<Comboitem> getAutocompleteComboitems();
}
<?xml version="1.0" encoding="UTF-8"?>
<wizard-config showPrefilledValues="false" selectMode="true" createMode="true" displaySubtypes="true">
<displayed-properties>
<group qualifier="General" visible="true" initially-opened="true">
<label key="cockpit.config.label.General" />
<property qualifier="MyComponent.name"/>
</group>
<group qualifier="Properties" visible="true" initially-opened="true">
<label key="config.wizardConfig.properties" />
<property qualifier="contentId" editorCode="contentItemSelectAutocomplete"/>
</group>
</displayed-properties>
</wizard-config>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"
default-autowire="byName">
<!-- Allows Additional PropertyEditorDescriptor to be added for all cockpits -->
<bean id="LookupEditorFactory" class="de.hybris.platform.cockpit.model.meta.LookupEditorFactory" init-method="init" lazy-init="false">
<property name="editorFactory" ref="EditorFactory"></property>
</bean>
<bean id="myCompanyIntegerEditors" class="de.hybris.platform.cockpit.model.meta.DefaultPropertyEditorDescriptor">
<property name="editorType" value="INTEGER"/>
<property name="defaultEditor" value="de.hybris.platform.cockpit.model.editor.impl.DefaultIntegerUIEditor" />
<property name="defaultMode" value="single"/>
<property name="editors">
<map>
<entry key="contentItemSelectAutocomplete" value="com.mycompany.cms2components.editor.ItemSelectUIEditor"/>
</map>
</property>
<property name="label" value="myCompanyIntegerEditors"/>
</bean>
</beans>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment