1

Hi I'm trying to create a custom component that extends UIInput. In that component I generate one html input, one html submit button and one line of text. The codes are as below:

@Override
public void decode(FacesContext context) {
    Map requestMap = context.getExternalContext().getRequestParameterMap();
    String clientId = getClientId(context);
    char sep = UINamingContainer.getSeparatorChar(context);
    String symbol = ((String) requestMap.get(clientId + sep + "inputfield"));
    setSubmittedValue(symbol);
}

@Override
public void encodeEnd(FacesContext context) throws IOException {
    String clientId = getClientId(context);
    char sep = UINamingContainer.getSeparatorChar(context);
    //-----------------------this generates an html input-------------------------
    encodeInputField(context, clientId + sep + "inputfield");
    //Now if I uncomment the next line it generates another html, whose value always stays the same as the first one
    //encodeInputField(context, clientId + sep + "inputfield2");
    encodeSubmitButton(context, clientId + sep + "submit");
    encodeOutputField(context);
}

private void encodeInputField(FacesContext context, String clientId) throws IOException {
    // Render a standard HTML input field
    ResponseWriter writer = context.getResponseWriter();
    writer.startElement("input", this);
    writer.writeAttribute("type", "text", null);
    writer.writeAttribute("name", clientId, "clientId");
    Object value = getValue();
    if (value != null) {
        writer.writeAttribute("value", value.toString(), "value");
    }
    writer.writeAttribute("size", "6", null);
    writer.endElement("input");
}

private void encodeSubmitButton(FacesContext context, String clientId) throws IOException {
    // render a submit button
    ResponseWriter writer = context.getResponseWriter();
    writer.startElement("input", this);
    writer.writeAttribute("type", "Submit", null);
    writer.writeAttribute("name", clientId, "clientId");
    writer.writeAttribute("value", "Click Me!", null);
    writer.endElement("input");
}

private void encodeOutputField(FacesContext context) throws IOException {
    ResponseWriter writer = context.getResponseWriter();
    //----------------weird value that comes out of nowhere-----------------------
    String hellomsg = (String) getAttributes().get("value");
    writer.startElement("p", this);
    writer.writeText("You entered: " + hellomsg, null);
    writer.endElement("p");
}

Now everything works fine but I don't understand where the value attribute in String hellomsg = (String) getAttributes().get("value"); comes. I tried to debug this program and the getAttributes() hashmap also contains weird entries and I couldn't find any entry whose key is "value".

Finally if I generate two html input then the second input's value always stays the same as the first one.

I also noticed that I can include a value in the tag, e.g. <mycc:cinput value="yes"> and when the page loads, the value of the html input generated is set to yes.

My doubt is: is every UIInput has a default value attribute? If so, is that attribute value always linked to whatever html input's value attribute? If so, is it always linked to the value attribute of the first html input generated?

Thanks in advance for reading such a long question. If possible can you guys let me know where I can find answers to issues like this? Im getting a headache browsing random google search results@_@

Thanks a lot!

Wang Sheng
  • 780
  • 1
  • 6
  • 18

1 Answers1

1

Now everything works fine but I don't understand where the value attribute in String hellomsg = (String) getAttributes().get("value"); comes. I tried to debug this program and the getAttributes() hashmap also contains weird entries and I couldn't find any entry whose key is "value".

Read the javadoc of UIComponent#getAttributes(). To the point, it's really an abstract map. The get("value") doesn't really return an entry from the map, but it basically obtains the value property of the component itself by invoking its getValue() method, if any available (and it is, in case of UIInput). But if you're already sitting in the component itself, you don't need to invoke getAttributes().get("value"), you can just invoke the getValue() method directly.

Note thus that if you intend to put a custom attribute in the attribute map, then you should be using a different name, or, better, to make use of StateHelper.

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555