Project

General

Profile

« Previous | Next » 

Revision bc5816ee

Added by Andreas Kohlbecker almost 7 years ago

ref #6612 Team and Person editor widgets implemented and integrated in reference editor

View differences:

pom.xml
455 455
       <artifactId>switch</artifactId>
456 456
       <version>3.0.0</version>
457 457
    </dependency>
458
    <dependency>
459
       <groupId>com.vaadin.addon</groupId>
460
       <artifactId>vaadin-onoffswitch</artifactId>
461
       <version>0.0.1</version>
462
    </dependency>
463 458
<!--     <dependency>
464 459
        only in the edit repo
465 460
      <groupId>org.vaadin.addons</groupId>
src/main/java/eu/etaxonomy/cdm/vaadin/AppWidgetSet.gwt.xml
43 43

  
44 44
    <inherits name="org.vaadin.teemu.switchui.SwitchComponentWidgetset" />
45 45

  
46
    <inherits name="com.vaadin.addon.onoffswitch.WidgetSet" />
46
    
47 47
</module>
src/main/java/eu/etaxonomy/cdm/vaadin/component/common/PersonField.java
1
/**
2
* Copyright (C) 2017 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.cdm.vaadin.component.common;
10

  
11
import com.vaadin.data.fieldgroup.BeanFieldGroup;
12
import com.vaadin.ui.Component;
13
import com.vaadin.ui.CssLayout;
14
import com.vaadin.ui.TextField;
15
import com.vaadin.ui.themes.ValoTheme;
16

  
17
import eu.etaxonomy.cdm.model.agent.Person;
18
import eu.etaxonomy.vaadin.component.CompositeCustomField;
19
import eu.etaxonomy.vaadin.component.SwitchButton;
20

  
21
/**
22
 * @author a.kohlbecker
23
 * @since May 11, 2017
24
 *
25
 */
26
public class PersonField extends CompositeCustomField<Person> {
27

  
28
    private static final long serialVersionUID = 8346575511284469356L;
29

  
30
    private static final String PRIMARY_STYLE = "v-person-field";
31

  
32
    private BeanFieldGroup<Person> fieldGroup = new BeanFieldGroup<>(Person.class);
33

  
34
    enum Mode {
35
        CACHE_MODE, DETAILS_MODE;
36

  
37
        public String toCssClass() {
38
            return name().toLowerCase().replace("_", "-");
39
        }
40
    }
41

  
42
    private Mode currentMode = null;
43

  
44
    private float baseWidth = 100 / 8;
45

  
46
    private CssLayout root = new CssLayout();
47
    private TextField cacheField = new TextField();
48
    private CssLayout detailsContainer = new CssLayout();
49
    private TextField firstNameField = new TextField();
50
    private TextField lastNameField = new TextField();
51
    private TextField prefixField = new TextField();
52
    private TextField suffixField = new TextField();
53
    private SwitchButton unlockSwitch = new SwitchButton();
54

  
55

  
56

  
57
    /**
58
     * @param caption
59
     */
60
    public PersonField(String caption) {
61

  
62
        this();
63
        setCaption(caption);
64
    }
65

  
66
    /**
67
     * @param caption
68
     */
69
    public PersonField() {
70

  
71
        root.setPrimaryStyleName(PRIMARY_STYLE);
72

  
73
        addStyledComponent(cacheField);
74
        addStyledComponent(firstNameField);
75
        addStyledComponent(lastNameField);
76
        addStyledComponent(prefixField);
77
        addStyledComponent(suffixField);
78
        addStyledComponent(unlockSwitch);
79

  
80
        addSizedComponent(root);
81
    }
82

  
83
    private void setMode(Mode mode){
84
        if(mode.equals(currentMode)){
85
            return;
86
        }
87
        if(currentMode != null){
88
            String removeMode = currentMode.toCssClass();
89
            root.removeStyleName(removeMode);
90
        }
91
        String newMode = mode.toCssClass();
92
        root.addStyleName(newMode);
93
        currentMode = mode;
94
    }
95

  
96

  
97
    /**
98
     * {@inheritDoc}
99
     */
100
    @Override
101
    protected Component initContent() {
102

  
103
        root.addComponent(cacheField);
104
        root.addComponent(unlockSwitch);
105

  
106
        cacheField.setWidth(100, Unit.PERCENTAGE);
107

  
108
        prefixField.setWidth(baseWidth, Unit.PERCENTAGE);
109
        prefixField.setInputPrompt("Prefix");
110

  
111
        firstNameField.setWidth(baseWidth * 3, Unit.PERCENTAGE);
112
        firstNameField.setInputPrompt("First Name");
113

  
114
        lastNameField.setWidth(baseWidth * 3, Unit.PERCENTAGE);
115
        lastNameField.setInputPrompt("Last Name");
116

  
117
        suffixField.setWidth(baseWidth, Unit.PERCENTAGE);
118
        suffixField.setInputPrompt("Suffix");
119

  
120
        detailsContainer.setStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP);
121
        detailsContainer.addComponent(prefixField);
122
        detailsContainer.addComponent(firstNameField);
123
        detailsContainer.addComponent(lastNameField);
124
        detailsContainer.addComponent(suffixField);
125
        root.addComponent(detailsContainer);
126

  
127
        unlockSwitch.addValueChangeListener(e -> {
128
            if(refreshMode()){
129
                switch (currentMode) {
130
                    case CACHE_MODE:
131
                        cacheField.focus();
132
                        break;
133
                    case DETAILS_MODE:
134
                        firstNameField.focus();
135
                        break;
136
                    default:
137
                        break;
138

  
139
                }
140
            }
141
        });
142
        unlockSwitch.setValueSetLister(e -> {
143
            refreshMode();
144
        });
145

  
146
        addDefaultStyles();
147
        setMode(Mode.DETAILS_MODE);
148

  
149
        fieldGroup.bind(cacheField, "titleCache");
150
        fieldGroup.bind(prefixField, "prefix");
151
        fieldGroup.bind(firstNameField, "firstname");
152
        fieldGroup.bind(lastNameField, "lastname");
153
        fieldGroup.bind(suffixField, "suffix");
154
        fieldGroup.bind(unlockSwitch, "protectedTitleCache");
155
        fieldGroup.setBuffered(false);
156

  
157
        return root;
158
    }
159

  
160
    /**
161
     *
162
     * @return true if the mode has changed
163
     */
164
    protected boolean refreshMode() {
165
        Mode lastMode = currentMode;
166
        setMode(unlockSwitch.getValue() ? Mode.CACHE_MODE: Mode.DETAILS_MODE);
167
        return !lastMode.equals(currentMode);
168
    }
169

  
170
    /**
171
     * {@inheritDoc}
172
     */
173
    @Override
174
    public Class<? extends Person> getType() {
175
        return Person.class;
176
    }
177

  
178
    @Override
179
    public void setValue(Person person){
180
        super.setValue(person);
181
    }
182

  
183
    /**
184
     * {@inheritDoc}
185
     */
186
    @Override
187
    protected void setInternalValue(Person newValue) {
188
        super.setInternalValue(newValue);
189
        fieldGroup.setItemDataSource(newValue);
190
        // refreshMode();
191
    }
192

  
193
    @Override
194
    protected void addDefaultStyles(){
195
        cacheField.addStyleName("cache-field");
196
        detailsContainer.addStyleName("details-fields");
197
    }
198
}
src/main/java/eu/etaxonomy/cdm/vaadin/component/common/TeamOrPersonField.java
1
/**
2
* Copyright (C) 2017 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.cdm.vaadin.component.common;
10

  
11
import com.vaadin.data.fieldgroup.BeanFieldGroup;
12
import com.vaadin.data.util.BeanItem;
13
import com.vaadin.server.UserError;
14
import com.vaadin.ui.Component;
15
import com.vaadin.ui.CssLayout;
16

  
17
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
18
import eu.etaxonomy.cdm.model.agent.Person;
19
import eu.etaxonomy.cdm.model.agent.Team;
20
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
21
import eu.etaxonomy.vaadin.component.CompositeCustomField;
22
import eu.etaxonomy.vaadin.component.FieldListEditor;
23
import eu.etaxonomy.vaadin.component.SwitchableTextField;
24

  
25
/**
26
 * @author a.kohlbecker
27
 * @since May 11, 2017
28
 *
29
 */
30
public class TeamOrPersonField extends CompositeCustomField<TeamOrPersonBase<?>> {
31

  
32
    private static final long serialVersionUID = 660806402243118112L;
33

  
34
    private static final String PRIMARY_STYLE = "v-team-or-person-field";
35

  
36
    private CssLayout root = new CssLayout();
37
    private CssLayout compositeWrapper = new CssLayout();
38

  
39
    // Fields for case when value is a Person
40
    private PersonField personField = new PersonField();
41

  
42
    // Fields for case when value is a Team
43
    private SwitchableTextField titleField = new SwitchableTextField("Team (bibliographic)");
44
    private SwitchableTextField nomenclaturalTitleField = new SwitchableTextField("Team (nomenclatural)");
45
    private FieldListEditor<Person, PersonField> personsListEditor = new FieldListEditor<Person, PersonField>(Person.class, PersonField.class, "Teammembers");
46

  
47
    private BeanFieldGroup<Team> fieldGroup  = new BeanFieldGroup<>(Team.class);
48

  
49
    public TeamOrPersonField(String caption){
50

  
51
        setCaption(caption);
52

  
53
        addStyledComponent(personField);
54
        addStyledComponent(titleField);
55
        addStyledComponent(nomenclaturalTitleField);
56
        addStyledComponent(personsListEditor);
57

  
58
        addSizedComponent(root);
59
        addSizedComponent(compositeWrapper);
60
        addSizedComponent(personField);
61
        addSizedComponent(titleField);
62
        addSizedComponent(nomenclaturalTitleField);
63
        addSizedComponent(personsListEditor);
64
    }
65

  
66
    /**
67
     * {@inheritDoc}
68
     */
69
    @Override
70
    protected Component initContent() {
71
        root.setPrimaryStyleName(PRIMARY_STYLE);
72
        compositeWrapper.setStyleName("margin-wrapper");
73
        root.addComponent(compositeWrapper);
74
        return root;
75
    }
76

  
77
    /**
78
     * {@inheritDoc}
79
     */
80
    @Override
81
    public Class getType() {
82
        return TeamOrPersonBase.class;
83
    }
84

  
85
    /**
86
     * {@inheritDoc}
87
     */
88
    @Override
89
    protected void setInternalValue(TeamOrPersonBase<?> newValue) {
90

  
91
        super.setInternalValue(newValue);
92

  
93
        newValue = HibernateProxyHelper.deproxy(newValue);
94

  
95
        if(Person.class.isAssignableFrom(newValue.getClass())){
96
            // value is a Person:
97
            compositeWrapper.addComponent(personField);
98

  
99
            personField.setValue((Person) newValue);
100
        }
101
        else if(Team.class.isAssignableFrom(newValue.getClass())){
102
            // otherwise it a Team
103

  
104
            compositeWrapper.addComponents(titleField, nomenclaturalTitleField, personsListEditor);
105

  
106
            titleField.bindTo(fieldGroup, "titleCache", "protectedTitleCache");
107
            nomenclaturalTitleField.bindTo(fieldGroup, "nomenclaturalTitle", "protectedNomenclaturalTitleCache");
108
            fieldGroup.bind(personsListEditor, "teamMembers");
109

  
110
            fieldGroup.setItemDataSource(new BeanItem<Team>((Team)newValue));
111
        } else {
112
            setComponentError(new UserError("TeamOrPersonField Error: Unsupported value type: " + newValue.getClass().getName()));
113
        }
114
    }
115

  
116
    /**
117
     * {@inheritDoc}
118
     */
119
    @Override
120
    protected void addDefaultStyles() {
121
        // no default styles here
122

  
123
    }
124

  
125

  
126

  
127
}
src/main/java/eu/etaxonomy/cdm/vaadin/component/common/TimePeriodField.java
225 225
    protected void setInternalValue(TimePeriod newValue) {
226 226
        super.setInternalValue(newValue);
227 227
        fieldGroup.setItemDataSource(new BeanItem<TimePeriod>(newValue));
228

  
229 228
        updateCacheField();
230 229
    }
231 230

  
src/main/java/eu/etaxonomy/cdm/vaadin/ui/RegistrationUI.java
144 144
        Page page = Page.getCurrent();
145 145
        String fragment = page.getUriFragment();
146 146
        String state = null;
147
        if(fragment.startsWith("!")){
147
        if(fragment != null && fragment.startsWith("!")){
148 148
            state = fragment.substring(1, fragment.length());
149 149
        }
150 150
        return state;
src/main/java/eu/etaxonomy/cdm/vaadin/view/reference/ReferencePopupEditor.java
22 22

  
23 23
import eu.etaxonomy.cdm.model.reference.Reference;
24 24
import eu.etaxonomy.cdm.model.reference.ReferenceType;
25
import eu.etaxonomy.cdm.vaadin.component.common.TeamOrPersonField;
25 26
import eu.etaxonomy.cdm.vaadin.component.common.TimePeriodField;
26 27
import eu.etaxonomy.cdm.vaadin.security.AccessRestrictedView;
27 28
import eu.etaxonomy.vaadin.mvp.AbstractCdmPopupEditor;
......
42 43

  
43 44
    private final static int GRID_COLS = 4;
44 45

  
45
    private final static int GRID_ROWS = 9;
46
    private final static int GRID_ROWS = 10;
46 47

  
47 48
    /**
48 49
     * @param layout
......
91 92
        addSwitchableTextField("Abbrev. cache", "abbrevTitleCache", "protectedAbbrevTitleCache", 0, row, GRID_COLS-1, row).setWidth(100, Unit.PERCENTAGE);
92 93
        row++;
93 94
        titleField = addTextField("Title", "title", 0, row, GRID_COLS-1, row);
94
        titleField.setRequired(true);
95 95
        titleField.setWidth(100, Unit.PERCENTAGE);
96 96
        row++;
97 97
        addTextField("NomenclaturalTitle", "abbrevTitle", 0, row, GRID_COLS-1, row).setWidth(100, Unit.PERCENTAGE);
98 98
        row++;
99
        // addTextField("Author(s)", "authorship", 0, 4, 1, 4)).setRequired(true);
100
        addTextField("Editor", "editor", 2, row, 3, row).setWidth(100, Unit.PERCENTAGE);
99
        TeamOrPersonField authorshipField = new TeamOrPersonField("Author(s)");
100
        authorshipField.setWidth(100,  Unit.PERCENTAGE);
101
        addField(authorshipField, "authorship", 0, row, 3, row);
101 102
        row++;
102 103
        addTextField("Series", "seriesPart", 0, row);
103 104
        addTextField("Volume", "volume", 1, row);
104 105
        addTextField("Pages", "pages", 2, row);
106
        addTextField("Editor", "editor", 3, row).setWidth(100, Unit.PERCENTAGE);
105 107
        row++;
106 108
        addTextField("Place published", "placePublished", 0, row, 1, row).setWidth(100, Unit.PERCENTAGE);
107 109
        TextField publisherField = addTextField("Publisher", "publisher", 2, row, 3, row);
108
        publisherField.setRequired(true);
109 110
        publisherField.setWidth(100, Unit.PERCENTAGE);
110 111
        TimePeriodField timePeriodField = new TimePeriodField("Date published");
111 112
        addField(timePeriodField, "datePublished");
112 113
        row++;
113
        // TODO implement a TimePeriod component
114 114
        addTextField("ISSN", "issn", 0, row);
115 115
        addTextField("ISBN", "isbn", 1, row);
116 116
        addTextField("DOI", "doi", 2, row);
117 117
        addTextField("Uri", "uri", 3, row);
118 118

  
119
//        titleField.setRequired(true);
120
//        publisherField.setRequired(true);
121

  
119 122
    }
120 123

  
121 124
    /**
src/main/java/eu/etaxonomy/cdm/vaadin/view/registration/RegistrationWorkflowPresenter.java
16 16
import org.springframework.beans.factory.annotation.Autowired;
17 17
import org.springframework.beans.factory.annotation.Qualifier;
18 18
import org.springframework.context.event.EventListener;
19
import org.springframework.transaction.TransactionStatus;
19 20

  
20 21
import com.vaadin.server.SystemError;
21 22
import com.vaadin.spring.annotation.SpringComponent;
......
122 123

  
123 124
    @EventListener(condition = "#event.type ==T(eu.etaxonomy.cdm.vaadin.event.AbstractEditorAction.Type).EDIT")
124 125
    public void onReferenceEditEvent(ReferenceEditorAction event) {
126
        TransactionStatus tx = getRepo().startTransaction(false);
125 127
        Reference reference = getRepo().getReferenceService().find(event.getEntityId());
126 128
        ReferencePopupEditor popup = getNavigationManager().showInPopup(ReferencePopupEditor.class);
127 129
        popup.showInEditor(reference);
130
        getRepo().commitTransaction(tx);
128 131
    }
129 132

  
130 133

  
src/main/java/eu/etaxonomy/vaadin/component/CompositeCustomField.java
1
/**
2
* Copyright (C) 2017 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.vaadin.component;
10

  
11
import java.util.ArrayList;
12
import java.util.Arrays;
13
import java.util.List;
14

  
15
import com.vaadin.ui.Component;
16
import com.vaadin.ui.CustomField;
17

  
18
/**
19
 * TODO implement height methods for full component size support
20
 *
21
 * @author a.kohlbecker
22
 * @since May 12, 2017
23
 *
24
 */
25
@SuppressWarnings("serial")
26
public abstract class CompositeCustomField<T> extends CustomField<T> {
27

  
28
    private List<Component> styledComponents = new ArrayList<>();
29

  
30
    private List<Component> sizedComponents = new ArrayList<>();
31

  
32
    protected List<Component> getStyledComponents() {
33
        if(styledComponents == null){
34
            styledComponents = new ArrayList<>();
35
        }
36
        return styledComponents;
37
    }
38

  
39
    /**
40
     * Implementations preferably call this method in the constructor
41
     *
42
     * @param component
43
     * @return
44
     */
45
    protected boolean addStyledComponent(Component component){
46
        applyCurrentStyleNames(component);
47
        return styledComponents.add(component);
48
    }
49

  
50
    /**
51
     * Implementations preferably call this method in the constructor
52
     *
53
     * @param component
54
     * @return
55
     */
56
    protected boolean addStyledComponents(Component ... component){
57
        List<Component> componentList = Arrays.asList(component);
58
        componentList.forEach(c -> applyCurrentStyleNames(c));
59
        return styledComponents.addAll(componentList);
60
    }
61

  
62
    protected List<Component> getSizedComponents() {
63
        if(sizedComponents == null){
64
            sizedComponents = new ArrayList<>();
65
        }
66
        return sizedComponents;
67
    }
68

  
69
    /**
70
     * Implementations preferably call this method in the constructor
71
     *
72
     * @param component
73
     * @return
74
     */
75
    protected boolean addSizedComponent(Component component){
76
        applyCurrentSize(component);
77
        return sizedComponents.add(component);
78
    }
79

  
80
    /**
81
     * Implementations preferably call this method in the constructor
82
     *
83
     * @param component
84
     * @return
85
     */
86
    protected boolean addSizedComponents(Component ... component){
87
        List<Component> componentList = Arrays.asList(component);
88
        componentList.forEach(c -> applyCurrentSize(c));
89
        return sizedComponents.addAll(componentList);
90
    }
91

  
92
    @Override
93
    public void setWidth(String width) {
94
        super.setWidth(width);
95
        getSizedComponents().forEach(c -> {if(c != null) {c.setWidth(width);}});
96
    }
97

  
98
    @Override
99
    public void setWidth(float width, Unit unit){
100
        super.setWidth(width, unit);
101
        getSizedComponents().forEach(c -> {if(c != null) {c.setWidth(width, unit);}});
102
    }
103

  
104
    @Override
105
    public void setWidthUndefined() {
106
        super.setWidthUndefined();
107
        getSizedComponents().forEach(c -> {if(c != null) {c.setWidthUndefined();}});
108
    }
109

  
110
    @Override
111
    public void setStyleName(String style) {
112
        super.setStyleName(style);
113
        getStyledComponents().forEach(c -> c.setStyleName(style));
114
        addDefaultStyles();
115
    }
116

  
117
    @Override
118
    public void addStyleName(String style) {
119
        super.addStyleName(style);
120
        getStyledComponents().forEach(c -> c.addStyleName(style));
121
    }
122

  
123
    protected void applyCurrentStyleNames(Component newSubComponent){
124
        newSubComponent.setStyleName(getStyleName());
125
    }
126

  
127
    protected void applyCurrentSize(Component newSubComponent){
128
        newSubComponent.setWidth(this.getWidth(), this.getWidthUnits());
129
    }
130

  
131
    /**
132
     * Implementations can may apply default styles to components added to <code>StyledComponents</code>
133
     * to prevent these styles from being overwritten when setStyleName() id called on the composite field.
134
     */
135
    protected abstract void addDefaultStyles();
136

  
137
}
src/main/java/eu/etaxonomy/vaadin/component/FieldListEditor.java
1
/**
2
* Copyright (C) 2017 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.vaadin.component;
10

  
11
import java.util.List;
12

  
13
import com.vaadin.data.util.BeanItemContainer;
14
import com.vaadin.server.FontAwesome;
15
import com.vaadin.ui.AbstractField;
16
import com.vaadin.ui.Button;
17
import com.vaadin.ui.Component;
18
import com.vaadin.ui.CssLayout;
19
import com.vaadin.ui.GridLayout;
20
import com.vaadin.ui.themes.ValoTheme;
21

  
22
/**
23
 * @author a.kohlbecker
24
 * @since May 11, 2017
25
 *
26
 */
27
public class FieldListEditor<V extends Object, F extends AbstractField<V>>  extends CompositeCustomField<List<V>> {
28

  
29
    private static final long serialVersionUID = 4670707714503199599L;
30

  
31
    private Class<F> fieldType;
32

  
33
    private Class<V> itemType;
34

  
35
    //NOTE: Managing the item
36
    //      IDs makes BeanContainer more complex to use, but it is necessary in some cases where the
37
    //      equals() or hashCode() methods have been reimplemented in the bean.
38
    //      TODO CdmBase an a reimplemented equals method, do we need to use the BeanContainer instead?
39
    private BeanItemContainer<V> beans;
40

  
41
   //private LinkedList<V> itemList = new LinkedList<>();
42

  
43
    private int GRID_COLS = 2;
44

  
45
    private GridLayout grid = new GridLayout(GRID_COLS,1);
46

  
47
    public  FieldListEditor(Class<V> itemType, Class<F> fieldType, String caption){
48
        this.fieldType = fieldType;
49
        this.itemType = itemType;
50
        setCaption(caption);
51
        beans = new BeanItemContainer<V>(itemType);
52
    }
53

  
54
    private Component buttonGroup(){
55
        Button add = new Button(FontAwesome.PLUS);
56
        Button remove = new Button(FontAwesome.MINUS);
57
        Button moveUp = new Button(FontAwesome.ARROW_UP);
58
        Button moveDown = new Button(FontAwesome.ARROW_DOWN);
59
        CssLayout buttonGroup = new CssLayout(add, remove, moveUp, moveDown);
60
        buttonGroup.setStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP);
61

  
62
        addStyledComponents(add, remove, moveUp, moveDown);
63

  
64
        return buttonGroup;
65
    }
66

  
67
    /**
68
     * {@inheritDoc}
69
     */
70
    @Override
71
    protected Component initContent() {
72
        grid.setColumnExpandRatio(0, 1.0f);
73
        return grid;
74
    }
75

  
76
    /**
77
     * {@inheritDoc}
78
     */
79
    @Override
80
    public Class getType() {
81
        return List.class;
82
    }
83

  
84
    /**
85
     * {@inheritDoc}
86
     */
87
    @Override
88
    protected void setInternalValue(List<V> newValue) {
89
        super.setInternalValue(newValue);
90

  
91
        beans.addAll(newValue);
92

  
93
        grid.setRows(newValue.size());
94
        int row = 0;
95
        for(V val : newValue){
96
            try {
97
                F field = fieldType.newInstance();
98
                addStyledComponent(field);
99
                field.setWidth(100, Unit.PERCENTAGE);
100
                field.setValue(val);
101
                grid.addComponent(field, 0, row);
102
                grid.addComponent(buttonGroup(), 1, row);
103
                row++;
104
            } catch (InstantiationException e) {
105
                // TODO Auto-generated catch block
106
                e.printStackTrace();
107
            } catch (IllegalAccessException e) {
108
                // TODO Auto-generated catch block
109
                e.printStackTrace();
110
            }
111
        }
112
    }
113

  
114
    /**
115
     * {@inheritDoc}
116
     */
117
    @Override
118
    public void setWidth(String width) {
119
        super.setWidth(width);
120
        grid.setWidth(width);
121
    }
122

  
123
    @Override
124
    public void setWidth(float width, Unit unit){
125
        super.setWidth(width, unit);
126
        if(grid != null){
127
            grid.setWidth(width, unit);
128
        }
129
    }
130

  
131
    /**
132
     * {@inheritDoc}
133
     */
134
    @Override
135
    protected void addDefaultStyles() {
136
        // no default styles
137
    }
138

  
139

  
140

  
141

  
142

  
143

  
144

  
145

  
146
}
src/main/java/eu/etaxonomy/vaadin/component/SwitchButton.java
1
/**
2
* Copyright (C) 2017 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.vaadin.component;
10

  
11
import org.vaadin.teemu.switchui.Switch;
12

  
13
/**
14
 * @author a.kohlbecker
15
 * @since May 11, 2017
16
 *
17
 */
18
public class SwitchButton extends Switch {
19

  
20
    private static final long serialVersionUID = 2557108593729214773L;
21

  
22
    private ValueChangeListener valueSetListener = null;
23

  
24
    /**
25
     * {@inheritDoc}
26
     */
27
    @Override
28
    protected void setInternalValue(Boolean newValue) {
29
        super.setInternalValue(newValue);
30
        if(valueSetListener != null){
31
            valueSetListener.valueChange(new ValueChangeEvent(this));
32
        }
33
    }
34

  
35
    public void setValueSetLister(ValueChangeListener valueSetListener){
36
        this.valueSetListener = valueSetListener;
37
    }
38

  
39
}
src/main/java/eu/etaxonomy/vaadin/component/SwitchableTextField.java
13 13
import com.vaadin.data.fieldgroup.FieldGroup;
14 14
import com.vaadin.ui.Component;
15 15
import com.vaadin.ui.CssLayout;
16
import com.vaadin.ui.CustomField;
17 16
import com.vaadin.ui.TextField;
18 17

  
19 18

  
......
22 21
 * @since May 11, 2017
23 22
 *
24 23
 */
25
public class SwitchableTextField extends CustomField<String> {
24
public class SwitchableTextField extends CompositeCustomField<String> {
26 25

  
27 26
    private static final long serialVersionUID = -4760153886584883137L;
28 27

  
......
40 39
        textField.setCaption(caption);
41 40
        unlockSwitch.addValueChangeListener(e -> {
42 41
            textField.setEnabled(unlockSwitch.getValue());
42
            textField.focus();
43 43
        });
44 44
        unlockSwitch.setValueSetLister(e -> {
45 45
            textField.setEnabled(unlockSwitch.getValue());
46 46
        });
47

  
48
        addSizedComponent(root);
49
        addSizedComponent(textField);
50

  
51
        addStyledComponent(textField);
52
        addStyledComponent(unlockSwitch);
47 53
    }
48 54

  
49 55
    /**
......
57 63
        textField.setWidth(getWidth(), getWidthUnits());
58 64
        root.addComponent(unlockSwitch);
59 65
        setPrimaryStyleName(PRIMARY_STYLE);
66

  
60 67
        return root;
61 68
    }
62 69

  
......
68 75
        return String.class;
69 76
    }
70 77

  
71
    /**
72
     * @return the serialversionuid
73
     */
74
    public static long getSerialversionuid() {
75
        return serialVersionUID;
76
    }
77

  
78 78
    /**
79 79
     * @return the textField
80 80
     */
......
99 99
     * {@inheritDoc}
100 100
     */
101 101
    @Override
102
    public void setWidthUndefined() {
103
        super.setWidthUndefined();
104
        root.setWidthUndefined();
105
        textField.setWidthUndefined();
106
    }
102
    protected void addDefaultStyles() {
103
        // no default styles
107 104

  
108
    /**
109
     * {@inheritDoc}
110
     */
111
    @Override
112
    public void setWidth(String width) {
113
        super.setWidth(width);
114
        root.setWidth(width);
115
        textField.setWidth(width);
116
    }
117

  
118
    @Override
119
    public void setWidth(float width, Unit unit){
120
        super.setWidth(width, unit);
121
        if(root != null){
122
            root.setWidth(width, unit);
123
            textField.setWidth(width, unit);
124
        }
125 105
    }
126 106

  
127
    @Override
128
    public void setStyleName(String style) {
129
        super.setStyleName(style);
130
        textField.setStyleName(style);
131
        unlockSwitch.setStyleName(style);
132
    }
133

  
134
    @Override
135
    public void addStyleName(String style) {
136
        super.addStyleName(style);
137
        textField.addStyleName(style);
138
        unlockSwitch.addStyleName(style);
139
    }
140

  
141
    private class SwitchButton extends Switch {
142

  
143
        private static final long serialVersionUID = 2557108593729214773L;
144

  
145
        private ValueChangeListener valueSetListener = null;
146

  
147
        /**
148
         * {@inheritDoc}
149
         */
150
        @Override
151
        protected void setInternalValue(Boolean newValue) {
152
            super.setInternalValue(newValue);
153
            if(valueSetListener != null){
154
                valueSetListener.valueChange(new ValueChangeEvent(this));
155
            }
156
        }
157

  
158
        public void setValueSetLister(ValueChangeListener valueSetListener){
159
            this.valueSetListener = valueSetListener;
160
        }
161

  
162

  
163

  
164
    }
165 107
}
src/main/java/eu/etaxonomy/vaadin/mvp/AbstractPopupEditor.java
75 75
        mainLayout.setWidthUndefined();
76 76

  
77 77
        fieldGroup = new BeanFieldGroup<>(dtoType);
78
        fieldGroup.setBuffered(false);
78 79
        fieldGroup.addCommitHandler(new SaveHandler());
79 80

  
80 81
        setCompositionRoot(mainLayout);
......
290 291
    protected <T extends Field> T addField(T field, String propertyId, int column1, int row1,
291 292
            int column2, int row2)
292 293
            throws OverlapsException, OutOfBoundsException {
293
        fieldGroup.bind(field, propertyId);
294
        if(propertyId != null){
295
            fieldGroup.bind(field, propertyId);
296
        }
294 297
        addComponent(field, column1, row1, column2, row2);
295 298
        return field;
296 299
    }
src/main/java/eu/etaxonomy/vaadin/ui/DevDayWidgetset.gwt.xml
17 17

  
18 18
    <inherits name="org.vaadin.teemu.switchui.SwitchComponentWidgetset" />
19 19

  
20
    <inherits name="com.vaadin.addon.onoffswitch.WidgetSet" />
20
    
21 21
</module>
src/main/webapp/VAADIN/themes/edit-valo/custom-fields.scss
1 1
// styles for custom fields
2 2

  
3
// ===================== Mixins ==============================//
4

  
5
@mixin composite-field-wrapper() {
6
  border: valo-border($border: $v-border, $color: $v-background-color, $strength: 0.7);
7
  border-radius: $v-border-radius;
8
  background-color: $v-app-background-color;
9
  padding: round($v-unit-size / 4);
10
}
11

  
12
// ===================== Styles ==============================//
13

  
3 14
body .edit-valo { // increasing specifity to allow overriding the valo default field themes
4 15
  
5 16
  // TimePeriodField
6 17
  .v-time-period-field {
7 18
      .margin-wrapper {
8
          border: valo-border($border: $v-border, $color: $v-background-color, $strength: 0.7);
9
          border-radius: $v-border-radius;
10
          background-color: $v-app-background-color;
11
          padding: round($v-unit-size / 4);
19
          @include composite-field-wrapper;
12 20
      }
13 21
      .to-label {
14 22
        padding: 0 round($v-unit-size / 2);
......
28 36
  
29 37
  // v-switchable-textfield
30 38
  .v-switchable-textfield {
39
    position: relative; // needs to be a positioned element
31 40
    height: $v-line-height * 2;
32 41
    .v-caption {
33 42
        display: block;
......
43 52
        bottom: 1px;
44 53
    }
45 54
  }
55
  
56
  // v-person-field
57
  .v-person-field {
58
    .v-caption {
59
        display: block;
60
    }
61
    .cache-field, .details-fields  {
62
        padding-right: $v-unit-size;
63
    }
64
    .v-switch {
65
        z-index: 10;
66
        width: $v-unit-size;
67
        position: absolute;
68
        right: 1px;
69
        bottom: 1px;
70
    } 
71
  }
72
  .v-person-field-cache-mode {
73
        .cache-field {
74
            display: block;
75
        }
76
        .details-fields {
77
            display: none;
78
        }
79
    }
80
   .v-person-field-details-mode {
81
        .cache-field {
82
            display: none;
83
        }
84
        .details-fields {
85
            display: block;
86
        }
87
    }
88
    
89
   // team-or-person-field
90
   .v-team-or-person-field {
91
        .margin-wrapper {
92
            @include composite-field-wrapper;
93
        }
94
    }
46 95
} 

Also available in: Unified diff