-
FEATURED COMPONENTS
First time here? Check out the FAQ!
Greetings,
I want to add code to a textarea so that it shows on the side a label with a counter showing how many caracters are typed and how many there are available max.
Ex: 210/500 caracters
Did someone do that already? Either with OnChanging or event or even better with a full JS solution ?
Regards
Found it, there could be some issues with it cause it's some prototype what's actually never used.
package be.mil.web.components;
import org.zkoss.zk.ui.ext.AfterCompose;
import org.zkoss.zk.ui.ext.BeforeCompose;
import org.zkoss.zul.Div;
import org.zkoss.zul.Label;
import org.zkoss.zul.Space;
import org.zkoss.zul.Textbox;
/**
*
* @author chillworld
*/
//Add ZK bind only when we put this in lang-addon.xml, because databinding could be lost then.
public class CharTextbox extends Textbox implements BeforeCompose, AfterCompose {
private final Div div = new Div();
private Label label;
private final Space space = new Space(); // stub for calculating the textbox with hflex="1" correct, otherwise our label is under the textbox.
private static final String SCRIPT = "var remaining = this._maxlength - this.getInputNode().value.length;"
+ "this.nextSibling.setValue(remaining);"
+ "zUtl.fireSized(this.parent);"; // if number of digit's go up or down => space will increase or decrease.
private static final String[] EVENTS = {"onKeyDown", "onKeyUp", "onKeyPress"};
@Override
public void beforeCompose() {
div.setVflex("min");
getParent().insertBefore(div, this);
this.setParent(div);
}
@Override
public void afterCompose() {
initMaxLenghtLabel(); // when maxLength is set before value the value could be incorrect.
}
@Override
public void setMaxlength(int maxlength) {
super.setMaxlength(maxlength);
initMaxLenghtLabel();
}
private void initMaxLenghtLabel() {
if (getMaxlength() > 0 && label == null) {
label = new Label(String.valueOf(getMaxlength() - getRawText().length()));
div.appendChild(label);
div.appendChild(space);
div.setStyle("background:#ffcc66;");
setEventListeners(SCRIPT);
} else if (getMaxlength() <= 0 && label != null) {
div.removeChild(label);
div.removeChild(space);
div.setStyle("background:");
setEventListeners("");
label = null;
} else if (label != null) {
label.setValue(String.valueOf(getMaxlength() - getRawText().length()));
}
}
private void setEventListeners(String script) {
for (String event : EVENTS) {
setWidgetListener(event, script);
}
}
@Override
public String getHflex() {
return div.getHflex();
}
@Override
public void setHflex(String hflex) {
super.setHflex("max".equals(hflex) ? "1" : hflex);// if max => label rendered under textbox.
div.setHflex(hflex);
}
}
Chill.
I ended up adding a javascript listener to avoid server call. My custom textarea component contains a textarea and 2 labels in a hlayout.
<textbox id="content" multiline="true" rows="3" />
<hlayout id="textareaCounter" sclass="textarea-counter">
<label id="counter" />
<label id="remaining" />
</hlayout>
In java, I initiate the remaining when setting maxLength with :
remaining.setValue(Labels.getLabel("field.textarea.counter", new Object[] { maxLength }));
The label being :
field.textarea.counter= character(s) / {0} remaining
And by default and on setValue, I update the counter label.
counter.setValue(String.valueOf(StringUtils.defaultString(value).length()));
Then I add a listener on the widget size :
content.setWidgetListener(Events.ON_CHANGING, "this.nextSibling.firstChild.setValue(event.data.value.length)");
Asked: 2016-10-17 16:43:37 +0800
Seen: 42 times
Last updated: Oct 24 '16
Full JS will be the best solution, otherwise to much network traffic and counter update might be delayed
chillworld ( 2016-10-18 07:28:41 +0800 )editYup, was hoping someone had already done it though ;)
WilliamB ( 2016-10-18 07:36:53 +0800 )edit