Hi.

Here is a solution using a patch of the standard checkbox component
that accepts any Object that can be ValueEncoder encoded. I created
stand-in objects and make the assumption that documentFieldDN is
unique and can be used in a set of all documentFieldDN.

You could persist the set as query parameters, or in the browser
cookie or whatever but I'm just sticking the set into the session.

Enjoy!

Josh


********************************************
********** Checkbox.java ****************
********************************************

package com.joshcanfield.tapestry.common.components;

import org.apache.tapestry5.ComponentResources;
import org.apache.tapestry5.MarkupWriter;
import org.apache.tapestry5.ValidationTracker;
import org.apache.tapestry5.ValueEncoder;
import org.apache.tapestry5.annotations.*;
import org.apache.tapestry5.corelib.base.AbstractField;
import org.apache.tapestry5.corelib.mixins.RenderDisabled;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.services.ComponentDefaultProvider;
import org.apache.tapestry5.services.Request;

/**
 * A Checkbox component is simply a <input type="checkbox">.
 *
 */
public class Checkbox extends AbstractField {
    private static final String NULL_TOKEN = "::null::";

    /**
     * The value to be read or updated. If not bound, the Checkbox
will attempt to edit a property of its container
     * whose name matches the component's id.
     */
    @Parameter(required = true, autoconnect = true)
    private Object value;

    @Parameter(autoconnect = true)
    private boolean checked;

    /**
     * Value encoder for the value, usually determined automatically
from the type of the property bound to the value
     * parameter.
     */
    @Parameter(required = true)
    private ValueEncoder<Object> encoder;

    @Inject
    private Request request;

    @SuppressWarnings("unused")
    @Mixin
    private RenderDisabled renderDisabled;

    @Inject
    private ComponentResources resources;

    @Inject
    private ComponentDefaultProvider defaultProvider;
    @Environmental
    private ValidationTracker tracker;

    ValueEncoder defaultEncoder() {
        return defaultProvider.defaultValueEncoder("value", resources);
    }

    @BeginRender
    void begin(MarkupWriter writer) {
        final boolean isBoolean = value != null && value instanceof Boolean;
        // Available only when there is an error in the form
        final String asSubmitted = tracker.getInput(this);

        boolean isChecked = false;

        if (asSubmitted != null) {
            // This is true when there is a form error.
            isChecked = isBoolean ? Boolean.parseBoolean(asSubmitted)
: !asSubmitted.equals(NULL_TOKEN);
        } else if (resources.isBound("checked")) {
            isChecked = checked;
        } else if (isBoolean) {
            isChecked = (Boolean) value;
        }

        writer.element("input", "type", "checkbox",
                "name", getControlName(),
                "id", getClientId(),
                // For non-boolean values we always grab the value
from the bound parameter because
                // we can't reconstitute it from a form post
                "value", isBoolean ? null : encoder.toClient(value),
                "checked", isChecked ? "checked" : null);

        resources.renderInformalParameters(writer);

        decorateInsideField();
    }

    @AfterRender
    void after(MarkupWriter writer) {
        writer.end(); // input
    }

    @Override
    protected void processSubmission(String elementName) {
        // if the value wasn't submitted then it will be null
        final String postedValue = request.getParameter(elementName);

        value = encoder.toValue(postedValue);

        // Stick a null token in there so we know when there was an
error in the form and can skip other checks.
        tracker.recordInput(this, postedValue == null ? NULL_TOKEN :
postedValue);
    }
}

********************************************
********** CheckboxTest.java ***********
********************************************

package usr.joshcan.tapestry.pages;

import com.joshcanfield.tapestry.common.components.Checkbox;
import org.apache.tapestry5.annotations.Component;
import org.apache.tapestry5.annotations.PageLoaded;
import org.apache.tapestry5.annotations.Persist;
import org.apache.tapestry5.annotations.Property;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * User: joshcanfield
 * Date: Apr 9, 2010
 */
public class CheckboxTest {

    private List<ProcessType> _processTypes;


    @Property
    private ProcessType _processType;

    @Property
    private DocumentType _documentType;

    @Property
    private DocumentField _documentField;

    @Component
    private Checkbox _checkbox;

    @Persist
    private Set<String> _checked;

    /*
     * Page Life cycle methods
     */
    @PageLoaded
    void createObjects() {
        // Runs once when the page
        _processTypes = new ArrayList<ProcessType>();


        for (String ptName : new String[]{"processType One",
"processType Two", "processType Three"}) {

            List<DocumentType> docTypes = new ArrayList<DocumentType>();
            for (String dtName : new String[]{"dt1", "dt2", "dt3"}) {
                List<DocumentField> fields = new ArrayList<DocumentField>();
                for (String documentField : new String[]{"df1", "df2", "df3"}) {
                    // creating a documentFieldDN that uniquely identifies it.
                    final String documentFieldDN =
String.format("%s.%s.%s", ptName, dtName, documentField);
                    fields.add(new DocumentField(documentFieldDN));
                }

                docTypes.add(new DocumentType(dtName, fields));
            }
            _processTypes.add(new ProcessType(ptName, docTypes));
        }
    }

    /**
     * Always start with a fresh set since the new values are being posted
     */
    void onPrepareForSubmit() {
        _checked = new HashSet<String>();
    }

    /**
     * When rendering for the first time there won't be a _checked set
in the session.
     */
    void onPrepareForRender() {
        if (_checked == null) _checked = new HashSet<String>();
    }

    public List<ProcessType> getProcessTypes() {
        return _processTypes;
    }

    public String getDocumentFieldDN() {
        // Returns the current loop value
        return _documentField.getDocumentFieldDN();
    }

    public void setDocumentFieldDN(String value) {
        // unchecked boxes are set as null, we just ignore the null values.
        if (value != null) _checked.add(value);
    }

    public boolean getDocumentFieldIsChecked() {
        return _checked.contains(_documentField.getDocumentFieldDN());
    }

    /*
    * Faked up classes
    */

    public class ProcessType {
        private List<DocumentType> _documentTypes;
        private String _name;

        public ProcessType(String name, List<DocumentType> documentTypes) {
            _documentTypes = documentTypes;
            _name = name;
        }

        public String getName() {
            return _name;
        }

        public void setName(String name) {
            _name = name;
        }

        public List<DocumentType> getDocumentTypes() {
            return _documentTypes;
        }

        public void setDocumentTypes(List<DocumentType> documentTypes) {
            _documentTypes = documentTypes;
        }
    }

    public class DocumentType {
        private List<DocumentField> _documentFields;
        private String _name;

        public DocumentType(String name, List<DocumentField> documentFields) {
            _name = name;
            _documentFields = documentFields;
        }

        public String getName() {
            return _name;
        }

        public void setName(String name) {
            _name = name;
        }

        public List<DocumentField> getDocumentFields() {
            return _documentFields;
        }

        public void setDocumentFields(List<DocumentField> documentFields) {
            _documentFields = documentFields;
        }
    }

    public class DocumentField {
        private String _documentFieldDN;

        public DocumentField(String documentFieldDN) {
            _documentFieldDN = documentFieldDN;
        }

        public String getDocumentFieldDN() {
            return _documentFieldDN;
        }

        public void setDocumentFieldDN(String documentFieldDN) {
            _documentFieldDN = documentFieldDN;
        }
    }
}

********************************************
********** CheckboxTest.tml ************
********************************************

<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd";>

<head><title>Checkbox test</title></head>
<body>
<t:form>
    <ul>
        <t:loop t:source="processTypes" t:value="processType" formState="none">
            <li>${processType.name}</li>
            <ul>

                <t:loop t:source="processType.documentTypes"
t:value="documentType" formState="none">
                    <li>${documentType.name}</li>
                    <ul>
                        <t:loop t:source="documentType.documentFields"
t:value="documentField" formState="none">

                            <li>
                                <t:checkbox t:id="checkbox"
t:value="documentFieldDN"
                                            t:checked="documentFieldIsChecked"/>
                                <label
for="${documentFieldDN}">${documentField.documentFieldDN}</label>
                            </li>
                        </t:loop>
                    </ul>
                </t:loop>
            </ul>

        </t:loop>
    </ul>
    <t:submit/>
</t:form>

</body>
</html>

Josh

On Fri, Apr 9, 2010 at 3:54 AM, jaques robert <mondes_englou...@yahoo.fr> wrote:
> Hello,
>
>
> I've got some problemes with checkbox & T5 for a while. I'd just like to 
> display a page which could contains some checkbox, then submit this page in 
> order to treat the various item corresponding to the ticked checkbox then 
> redirect to the same page with the same checkbox ticked. It is simple with 
> JSP however seems complicated to me to realize with T5
>
>
> <t:Loop t:source="processTypes" t:value="processType"
> formState="none">
>
>     <t:Loop t:source="processType.documentTypes"
> t:value="documentType" formState="none">
>
>         <t:Loop t:source="documentType.documentFields"
> t:value="documentField" formState="values">
>
>                                                     <t:if
> test="documentField.checked">
>
>                                                         <input
> type="checkbox" name="selectedDocumentFields"
> value="${documentField.documentFieldDN}" checked="checked"/>
>
>                                                     </t:if>
>
>                                                   <!-- <input t :
> type="checkbox" t : id="checked" value="documentField.documentFieldDN"
> />-->
>
>         ...
>
>
>
> Howard Lewis Ship advise to use the http request without using t5 component 
> in this cas. That was I've done. However for the display when returning to 
> this page after submission documentField.checked is always to false
>
> Perhaps I'm missing something moreover I think I'm making a "usine à gaz".
>
>
> On the onActivate() I've got :
>
>         _exportNameForModifcation = exportNameForModification;
>
>         System.out.println("_exportNameForModifcation : " +
> _exportNameForModifcation);
>
>         documentFieldAlreadyTicked =
> getExportService().getDocumentFields(exportNameForModification);
>
>
>
>         HttpServletRequest req = requestGlobals.getHTTPServletRequest();
>
>         List<String> selectedDocumentFields = new
> LinkedList<String>();
>
>
>
> on the onSuccess() :
>
>         HttpServletRequest req = requestGlobals.getHTTPServletRequest();
>
>         String[] exportToCreate =
> req.getParameterValues("selectedDocumentFields");
>
>
>
>         System.out.println("exportToCreate : " + exportToCreate);
>
>
>         _formFieldsToCreate = Arrays.asList(exportToCreate);
>
>
>
>         getExportService().modifyExportProfil(_profilName, _language,
> _formFieldsToCreate);
>
>
>
>         //return this;
>
>         return null;
>
>
> on the getDocumentField()
>
>
>
> public ExportDocumentField getDocumentField() {
>
>         System.out.println("_documentField : " + _documentField);
>
>         if (documentFieldAlreadyTicked.contains(_documentField)) {
>
>             _documentField.setChecked("true");
>
>             System.out.println(documentFieldAlreadyTicked + " contains
> " + _documentField);
>
>         }
>
>         else {
>
>             System.out.println(documentFieldAlreadyTicked + " does not
> contains " + _documentField);
>
>             _documentField.setChecked(null);
>
>         }
>
>
>
>         return _documentField;
>
>     }
>
>
> It sux cause getDocumentField() is called much more times than the item 
> displayed. Is it the good way to go ?
>
>
> If I use a t:checkbox component I see that there isn't a selected property as 
> in T3 for knowing which one is 
> selected.http://tapestry.apache.org/tapestry5/tapestry-core/ref/org/apache/tapestry5/corelib/components/Checkbox.html)
>
>
> Can you help me resolve this case ?
>
> Regards,
> Mondes.
>
>
>
>



-- 
--
http://www.bodylabgym.com - a private, by appointment only, one-on-one
health and fitness facility.
--
http://www.ectransition.com - Quality Electronic Cigarettes at a
reasonable price!
--
TheDailyTube.com. Sign up and get the best new videos on the internet
delivered fresh to your inbox.

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

Reply via email to