1

Display a label showing how much caractres available are left for a textarea

asked 2016-10-17 16:43:37 +0800

WilliamB gravatar image WilliamB
1609 1 6

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

delete flag offensive retag edit

Comments

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 )edit

Yup, was hoping someone had already done it though ;)

WilliamB ( 2016-10-18 07:36:53 +0800 )edit

2 Answers

Sort by ยป oldest newest most voted
1

answered 2016-10-18 08:05:28 +0800

chillworld gravatar image chillworld flag of Belgium
5357 4 9
https://github.com/chillw...

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.

link publish delete flag offensive edit

Comments

Thanks, ended up doing a bit different but thanks for the help

WilliamB ( 2016-10-20 12:34:35 +0800 )edit

you can also put your solution here ;). I'll upvote it.

chillworld ( 2016-10-20 13:00:03 +0800 )edit
1

answered 2016-10-24 07:58:03 +0800

WilliamB gravatar image WilliamB
1609 1 6

updated 2016-10-24 07:59:40 +0800

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)");
link publish delete flag offensive edit
Your answer
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

[hide preview]

Question tools

Follow
1 follower

RSS

Stats

Asked: 2016-10-17 16:43:37 +0800

Seen: 42 times

Last updated: Oct 24 '16

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More