Example usage for com.liferay.portal.kernel.xml Element attributeIterator

List of usage examples for com.liferay.portal.kernel.xml Element attributeIterator

Introduction

In this page you can find the example usage for com.liferay.portal.kernel.xml Element attributeIterator.

Prototype

public Iterator<Attribute> attributeIterator();

Source Link

Usage

From source file:com.liferay.faces.portal.component.inputsearch.internal.InputSearchRenderer.java

License:Open Source License

@Override
protected StringBuilder getMarkup(UIComponent uiComponent, StringBuilder markup) throws Exception {

    //J-//from   w w  w.  ja  v a2  s .  c  o m
    // NOTE: The specified markup looks like the following (HTML comments added for clarity):
    //
    // <!-- Opening <div> rendered by html/taglib/ui/input_search/page.jsp -->
    // <div class="input-append">
    //
    //    <!-- Input text field rendered by html/taglib/ui/input_search/page.jsp -->
    //    <input class="search-query span9" id="...:jid42" name="..." placeholder="" type="text" value="" />
    //
    //    <!-- Search button rendered by html/taglib/ui/input_search/page.jsp -->
    //    <button class="btn" type="submit">Search</button>
    //
    //    <!-- HtmlInputText (dynamically added JSF child component) -->
    //    <input type="text" name="...:htmlInputText" />
    //
    //    <!-- HtmlCommandButton (dynamically added JSF child component) -->
    //    <input type="submit" name="...:htmlCommandButton" value="" />
    //
    // <!-- Closing </div> rendered by html/taglib/ui/input_search/page.jsp -->
    // </div>
    //J+

    // Parse the generated markup as an XML document.
    InputSearch inputSearch = cast(uiComponent);
    Document document = SAXReaderUtil.read(markup.toString());
    Element rootElement = document.getRootElement();

    // Locate the first/main input element in the XML document. This is the one that will contain contain the value
    // that will be submitted in the postback and received by the decode(FacesContext, UIComponent) method).
    String xpathInput = "//input[contains(@id, '" + uiComponent.getClientId() + "')]";
    Element mainInputElement = (Element) rootElement.selectSingleNode(xpathInput);

    if (mainInputElement != null) {

        // Copy the value attribute of the InputSearch component to the first input element in the XML document.
        mainInputElement.attribute("value").setValue((String) inputSearch.getValue());

        // Locate the dynamically added HtmlInputText and HtmlCommandButton child components.
        String xpathInputs = "//input[@type='text']";
        List<Node> inputElements = rootElement.selectNodes(xpathInputs);

        if ((inputElements != null) && (inputElements.size() == 2)) {

            // Copy each "on" attribute name/value pairs from the HtmlInputText to the first input element in
            // the XML document. This will enable all of the AjaxBehavior events like keyup/keydown to work.
            Element htmlInputTextElement = (Element) inputElements.get(1);
            Iterator<Attribute> attributeIterator = htmlInputTextElement.attributeIterator();

            while (attributeIterator.hasNext()) {
                Attribute attribute = attributeIterator.next();
                String attributeName = attribute.getName();

                if (attributeName.startsWith("on")) {
                    mainInputElement.addAttribute(attributeName, attribute.getValue());
                }
            }

            // Remove the HtmlInputText <input> from the XML document so that only one text field is rendered.
            htmlInputTextElement.getParent().remove(htmlInputTextElement);
        }
    }

    // Locate the HtmlCommandButton in the XML document.
    List<UIComponent> children = uiComponent.getChildren();
    HtmlCommandButton htmlCommandButton = (HtmlCommandButton) children.get(1);
    String htmlCommandButtonClientId = htmlCommandButton.getClientId();

    // Note that if there is an AjaxBehavior, then the rendered HtmlCommandButton can be located in the XML document
    // via the name attribute. Otherwise it can be located in the XML document via the id attribute.
    String htmlCommandButtonXPath = "//input[contains(@name,'" + htmlCommandButtonClientId
            + "') and @type='submit']";
    Element htmlCommandButtonElement = (Element) rootElement.selectSingleNode(htmlCommandButtonXPath);

    if (htmlCommandButtonElement == null) {
        htmlCommandButtonXPath = "//input[contains(@id,'" + htmlCommandButtonClientId
                + "') and @type='submit']";
        htmlCommandButtonElement = (Element) rootElement.selectSingleNode(htmlCommandButtonXPath);
    }

    if (htmlCommandButtonElement != null) {

        // Locate the <button> element in the XML document that was rendered by page.jsp
        Element buttonElement = (Element) rootElement.selectSingleNode("//button[@type='submit']");

        if (buttonElement != null) {

            // Copy attributes found on the HtmlCommandButton <input> element to the <button> element that was
            // rendered by page.jsp
            Attribute onClickAttr = htmlCommandButtonElement.attribute("onclick");

            if (onClickAttr != null) {
                buttonElement.addAttribute("onclick", onClickAttr.getValue());
            }

            Attribute nameAttr = htmlCommandButtonElement.attribute("name");

            if (nameAttr != null) {
                buttonElement.addAttribute("name", nameAttr.getValue());
            }

            Attribute idAttr = htmlCommandButtonElement.attribute("id");

            if (idAttr != null) {
                buttonElement.addAttribute("id", idAttr.getValue());
            }

            // Remove the HtmlCommandButton <input> from the XML document so that only one button is rendered.
            htmlCommandButtonElement.getParent().remove(htmlCommandButtonElement);
        }
    }

    // Returned the modified verson of the specified markup.
    return new StringBuilder(rootElement.asXML());
}