001package gwt.material.design.client.ui;
002
003/*
004 * #%L
005 * GwtMaterial
006 * %%
007 * Copyright (C) 2015 GwtMaterialDesign
008 * %%
009 * Licensed under the Apache License, Version 2.0 (the "License");
010 * you may not use this file except in compliance with the License.
011 * You may obtain a copy of the License at
012 * 
013 *      http://www.apache.org/licenses/LICENSE-2.0
014 * 
015 * Unless required by applicable law or agreed to in writing, software
016 * distributed under the License is distributed on an "AS IS" BASIS,
017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
018 * See the License for the specific language governing permissions and
019 * limitations under the License.
020 * #L%
021 */
022
023import com.google.gwt.core.client.Scheduler;
024import com.google.gwt.core.client.Scheduler.ScheduledCommand;
025import com.google.gwt.dom.client.Element;
026import com.google.gwt.event.dom.client.BlurEvent;
027import com.google.gwt.event.dom.client.BlurHandler;
028import com.google.gwt.event.dom.client.FocusEvent;
029import com.google.gwt.event.dom.client.FocusHandler;
030import com.google.gwt.event.logical.shared.AttachEvent;
031import com.google.gwt.event.logical.shared.AttachEvent.Handler;
032import com.google.gwt.event.logical.shared.ValueChangeEvent;
033import com.google.gwt.event.logical.shared.ValueChangeHandler;
034import com.google.gwt.event.shared.HandlerRegistration;
035import com.google.gwt.user.client.ui.TextArea;
036import gwt.material.design.client.constants.InputType;
037
038import java.util.HashSet;
039import java.util.List;
040import java.util.Set;
041
042//@formatter:off
043
044/**
045 * Material Text Area represents a multiple line textbox where users can define comment, detail and etc.
046 * <h3>UiBinder Usage:</h3>
047 * <pre>
048 *{@code <m:MaterialTextArea placeholder="Your Comment" />
049 * </pre>
050 * @see <a href="http://gwt-material-demo.herokuapp.com/#forms">Material TextArea</a>
051 * @author kevzlou7979
052 * @author Ben Dol
053 * @author paulux84
054 */
055//@formatter:on
056public class MaterialTextArea extends MaterialValueBox<String> {
057
058    public enum ResizeRule {
059        NONE, AUTO, FOCUS
060    }
061
062    private ResizeRule resizeRule = ResizeRule.NONE;
063    private Set<HandlerRegistration> resizeHandlers;
064    private HandlerRegistration attachHandler;
065    private Integer originalHeight;
066
067    public MaterialTextArea() {
068        super(new TextArea());
069        setType(InputType.TEXT);
070        valueBoxBase.setStyleName("materialize-textarea");
071    }
072
073    @Override
074    public void setText(String text) {
075        super.setText(text);
076
077        if(resizeRule.equals(ResizeRule.AUTO)) {
078            triggerAutoResize();
079        }
080    }
081
082    public void triggerAutoResize() {
083        if(!valueBoxBase.isAttached()) {
084            if (attachHandler == null) {
085                attachHandler = valueBoxBase.addAttachHandler(new Handler() {
086                    @Override
087                    public void onAttachOrDetach(AttachEvent event) {
088                        if(event.isAttached()) {
089                            triggerAutoResize(valueBoxBase.getElement());
090                        }
091                    }
092                });
093            }
094        } else {
095            triggerAutoResize(valueBoxBase.getElement());
096        }
097    }
098
099    protected native void triggerAutoResize(Element element) /*-{
100        $wnd.jQuery(document).ready(function() {
101            $wnd.jQuery(element).trigger('autoresize');
102        });
103    }-*/;
104
105    public ResizeRule getResizeRule() {
106        return resizeRule;
107    }
108
109    public void setResizeRule(ResizeRule resizeRule) {
110        this.resizeRule = resizeRule;
111        if(resizeHandlers == null) {
112            resizeHandlers = new HashSet<>();
113        }
114        removeResizeHandlers();
115
116        switch(resizeRule) {
117            case AUTO:
118                resizeHandlers.add(valueBoxBase.addValueChangeHandler(new ValueChangeHandler<String>() {
119                    @Override
120                    public void onValueChange(ValueChangeEvent<String> event) {
121                        triggerAutoResize();
122                    }
123                }));
124                break;
125            case FOCUS:
126                resizeHandlers.add(addFocusHandler(new FocusHandler() {
127                    @Override
128                    public void onFocus(FocusEvent event) {
129                        if(originalHeight == null) {
130                            originalHeight = valueBoxBase.getElement().getClientHeight();
131                        }
132                        triggerAutoResize();
133                    }
134                }));
135
136                resizeHandlers.add(addBlurHandler(new BlurHandler() {
137                    @Override
138                    public void onBlur(BlurEvent event) {
139                        if(originalHeight != null) {
140                            valueBoxBase.setHeight(originalHeight + "px");
141                        }
142                    }
143                }));
144                break;
145        }
146    }
147
148    protected void removeResizeHandlers() {
149        if(resizeHandlers != null) {
150            for (HandlerRegistration handlerReg : resizeHandlers) {
151                handlerReg.removeHandler();
152            }
153        }
154    }
155}