I wonder why the component Checkbox doesn't have the parameter validate like
most of the other fields.

I have the following security use case: Even when some fields are not
rendered to UI (or only rendered disabled) because the user doesn't have the
required permission/role, I need to make sure these fields don't get changed
through HTTP Post data manipulation.
A new validator checking the permissions works fine for fields with validate
(for instance a TextField). However, the Checkbox can't be validated.

I think the parameter validate would also be useful for any other
unpredictable reasons.

There was a related topic in 2008:
http://tapestry.1045711.n5.nabble.com/T5-checkbox-component-and-validation-td2420125.html

In T5 the fields RadioGroup and Palette were extended with this parameter:
https://issues.apache.org/jira/browse/TAP5-166
https://issues.apache.org/jira/browse/TAP5-868


Although I managed to solve the scenario the next way, with validate it
would be much simpler.
1) New validatable Checkbox
/**
 * Checkbox with validate parameter. (/Note:/ {@link
org.apache.tapestry5.corelib.components.Checkbox} components
 * can not be validated.)
 * 
 * @author ferengra
 */
public class ValidatableCheckbox extends AbstractTextField
{

    @Inject
    private Request request;

    @Environmental
    private ValidationTracker tracker;

    @Override
    protected void writeFieldTag(MarkupWriter writer, String value)
    {
        writer.element("input", "type", "checkbox",
            "name", getControlName(),
            "id", getClientId(),
            "checked", Boolean.parseBoolean(value) ? "checked" : null);
    }

    final void afterRender(MarkupWriter writer)
    {
        writer.end(); // input
    }

    @Override
    protected void processSubmission(String controlName)
    {
        super.processSubmission(controlName);
        String postedValue = request.getParameter(controlName);
        // Record as "true" or "false"
        tracker.recordInput(this, Boolean.toString(postedValue != null));
    }
}

2) Add a new translator.
/**
 * Performs boolean translation between server-side and client-side
representations.
 * 
 * @author ferengra
 */
public class BooleanTranslator extends AbstractTranslator<Boolean>
{

    /**
     * Constructor.
     */
    public BooleanTranslator()
    {
        super("boolean", Boolean.class, "a-boolean-is-a-boolean");
    }

    @Override
    public void render(Field field, String message, MarkupWriter writer,
FormSupport formSupport)
    {
        // Does nothing
    }

    @Override
    public Boolean parseClient(Field field, String clientValue, String
message)
    {
        return "on".equalsIgnoreCase(clientValue) ||
Boolean.TRUE.toString().equalsIgnoreCase(clientValue);
    }

    @Override
    public String toClient(Boolean value)
    {
        return String.valueOf(value);
    }
}

3) Add a null field strategy for handling the unchecked checkbox value
/**
 * Treats nulls to or from the client as if they were false.
 * 
 * @author ferengra
 */
public class FalseNullFieldStrategy implements NullFieldStrategy
{

    @Override
    public Object replaceToClient()
    {
        return Boolean.FALSE;
    }

    @Override
    public String replaceFromClient()
    {
        return Boolean.FALSE.toString();
    }
}

4) Contribute the above two.
    public void contributeTranslatorSource(MappedConfiguration<Class,
Translator&lt;?>> translator)
    {
        translator.add(Boolean.class, new BooleanTranslator());
    }

    public static void
contributeNullFieldStrategySource(MappedConfiguration<String,
NullFieldStrategy> configuration)
    {
        configuration.add("false", new FalseNullFieldStrategy());
    }

5) Add the new checkbox with validation and null field strategy.
    @SuppressWarnings("unused")
    @Component(parameters = {"value=dto.valueBoolean"
        "validate=permission=PERMISSION_UPDATE", "nulls=false"})
    private ValidatableCheckbox valueBoolean;




--
View this message in context: 
http://tapestry.1045711.n5.nabble.com/T5-checkbox-and-validate-tp5717169.html
Sent from the Tapestry - User mailing list archive at Nabble.com.

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

Reply via email to