You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Nillehammer <ta...@winfonet.eu> on 2011/06/11 21:05:13 UTC

[Snippet] T5: A mixin to rewrite the markup of element

Tapestry's Submit component renders out as <input type="submit">. Since 
HTML 4.0 a submit button can be written as <button type="submit">. I 
prefer this approach, because it makes it easier to distinguish between 
real input elements (especially textfields) and buttons. I have created 
a JIRA request for this: https://issues.apache.org/jira/browse/TAP5-1545
Hopefully it will get implemented in future Tapestry versions.

In the meanwhile I have helped myself out with a mixin that is able to 
change the markup of the element (element name and attributes) it is 
attached to. In case someone else finds this usefull this is the code:

import java.util.Collection;
import java.util.List;

import org.apache.tapestry5.BindingConstants;
import org.apache.tapestry5.MarkupWriter;
import org.apache.tapestry5.annotations.AfterRender;
import org.apache.tapestry5.annotations.BeforeRenderTemplate;
import org.apache.tapestry5.annotations.Parameter;
import org.apache.tapestry5.dom.Attribute;
import org.apache.tapestry5.dom.Element;
import org.apache.tapestry5.dom.Node;

/**
  * Mixin that changes the markup of an element to desired values.
  */
public final class MarkupChanger {

     /**
      * The desired new name for the element.
      */
     @Parameter(required = true, allowNull = false, defaultPrefix = 
BindingConstants.LITERAL)
     private String newElemName;

     /**
      * A string containing pairs of attribute names and values 
separated by ",".
      */
     @Parameter(allowNull = false, defaultPrefix = BindingConstants.LITERAL)
     private String newAttribs;

     /**
      * The {@link Element} to change the markup.
      */
     private Element originalElem;

     /**
      * In this render phase we can easily get the element that this 
mixin is
      * placed into by calling writer.getElement.
      *
      * @param writer
      *          {@link MarkupWriter} injected by Tapestry.
      */
     @BeforeRenderTemplate
     final void determineOriginalElem(final MarkupWriter writer ) {

         this.originalElem = writer.getElement();
     }

     /**
      * We do all the rewriting of markup in the final phase not to 
interfere with
      * the render phases of the original element.
      *
      * @param writer
      *          {@link MarkupWriter} injected by Tapestry.
      */
     @AfterRender
     final void changeMarkup(final MarkupWriter writer ) {

         // Create a new element with the desired new name.
         final Element newElem = writer.element(this.newElemName);

         // Add all original attributes to the newly created element.
         final Collection<Attribute> attribs = 
this.originalElem.getAttributes();

         for (final Attribute attrib : attribs) {

             newElem.attribute(attrib.getName(), attrib.getValue());
         }

         // Add new attributes to the new element, possibly overwriting 
original ones.
         if (this.newAttribs != null && !this.newAttribs.isEmpty()) {

             final String[] attribArr = this.newAttribs.split(",");

             // parse null-String to null.
             for (int i = 0; i < attribArr.length; i++) {

                 if ("null".equals(attribArr[i])) {

                     attribArr[i] = null;
                 }
             }

             newElem.forceAttributes(attribArr);
         }

         // Get children from the original element and add them to the 
new one.
         final List<Node> children = this.originalElem.getChildren();

         for (final Node node : children) {

             node.moveToBottom(newElem);
         }

         // End tag for new element.
         writer.end();

         // Remove the original element from DOM.
         this.originalElem.remove();
     }
}

Cheers nillehammer

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: [Snippet] T5: A mixin to rewrite the markup of element

Posted by Michael Gentry <mg...@masslight.net>.
In the past, I had trouble with IE6 and multiple buttons in a FORM.  You
couldn't distinguish which button was clicked on.  I don't know if this
issue still exists in IE7+ because I just stopped using BUTTON.  Just
something you may want to keep in mind if you have to support older versions
of IE and have multiple buttons.

mrg


On Sat, Jun 11, 2011 at 3:05 PM, Nillehammer <
tapestry.nillehammer@winfonet.eu> wrote:

> Tapestry's Submit component renders out as <input type="submit">. Since
> HTML 4.0 a submit button can be written as <button type="submit">. I prefer
> this approach, because it makes it easier to distinguish between real input
> elements (especially textfields) and buttons. I have created a JIRA request
> for this: https://issues.apache.org/jira/browse/TAP5-1545
> Hopefully it will get implemented in future Tapestry versions.
>
> In the meanwhile I have helped myself out with a mixin that is able to
> change the markup of the element (element name and attributes) it is
> attached to. In case someone else finds this usefull this is the code:
>
> import java.util.Collection;
> import java.util.List;
>
> import org.apache.tapestry5.BindingConstants;
> import org.apache.tapestry5.MarkupWriter;
> import org.apache.tapestry5.annotations.AfterRender;
> import org.apache.tapestry5.annotations.BeforeRenderTemplate;
> import org.apache.tapestry5.annotations.Parameter;
> import org.apache.tapestry5.dom.Attribute;
> import org.apache.tapestry5.dom.Element;
> import org.apache.tapestry5.dom.Node;
>
> /**
>  * Mixin that changes the markup of an element to desired values.
>  */
> public final class MarkupChanger {
>
>    /**
>     * The desired new name for the element.
>     */
>    @Parameter(required = true, allowNull = false, defaultPrefix =
> BindingConstants.LITERAL)
>    private String newElemName;
>
>    /**
>     * A string containing pairs of attribute names and values separated by
> ",".
>     */
>    @Parameter(allowNull = false, defaultPrefix = BindingConstants.LITERAL)
>    private String newAttribs;
>
>    /**
>     * The {@link Element} to change the markup.
>     */
>    private Element originalElem;
>
>    /**
>     * In this render phase we can easily get the element that this mixin is
>     * placed into by calling writer.getElement.
>     *
>     * @param writer
>     *          {@link MarkupWriter} injected by Tapestry.
>     */
>    @BeforeRenderTemplate
>    final void determineOriginalElem(final MarkupWriter writer ) {
>
>        this.originalElem = writer.getElement();
>    }
>
>    /**
>     * We do all the rewriting of markup in the final phase not to interfere
> with
>     * the render phases of the original element.
>     *
>     * @param writer
>     *          {@link MarkupWriter} injected by Tapestry.
>     */
>    @AfterRender
>    final void changeMarkup(final MarkupWriter writer ) {
>
>        // Create a new element with the desired new name.
>        final Element newElem = writer.element(this.newElemName);
>
>        // Add all original attributes to the newly created element.
>        final Collection<Attribute> attribs =
> this.originalElem.getAttributes();
>
>        for (final Attribute attrib : attribs) {
>
>            newElem.attribute(attrib.getName(), attrib.getValue());
>        }
>
>        // Add new attributes to the new element, possibly overwriting
> original ones.
>        if (this.newAttribs != null && !this.newAttribs.isEmpty()) {
>
>            final String[] attribArr = this.newAttribs.split(",");
>
>            // parse null-String to null.
>            for (int i = 0; i < attribArr.length; i++) {
>
>                if ("null".equals(attribArr[i])) {
>
>                    attribArr[i] = null;
>                }
>            }
>
>            newElem.forceAttributes(attribArr);
>        }
>
>        // Get children from the original element and add them to the new
> one.
>        final List<Node> children = this.originalElem.getChildren();
>
>        for (final Node node : children) {
>
>            node.moveToBottom(newElem);
>        }
>
>        // End tag for new element.
>        writer.end();
>
>        // Remove the original element from DOM.
>        this.originalElem.remove();
>    }
> }
>
> Cheers nillehammer
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>