Robust JavaScript

To make a more robust solution, pass the actual client ids that Tapestry assigned to the 2 fields. There are situations in which the client id can be a surprise, particularly within a Loop or a Zone.
References: getClientId(), Tapestry JavaScript, JavaScriptSupport, RequireJS, jQuery API.

Home


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!-- We need a doctype to allow us to use special characters like &nbsp; 
     We use a "strict" DTD to make IE follow the alignment rules. -->
     
<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd">
<body class="container">
    <h3>Robust JavaScript</h3>

    <noscript class="js-required">
        ${message:javascript_required}
    </noscript>     

    To make a more robust solution, pass the <em>actual</em> client ids that Tapestry assigned to the 2 fields. 
    There are situations in which the client id can be a surprise, particularly within a Loop or a Zone.
    
    <div class="eg">
        <t:form class="form-inline" autofocus="false">
            <div class="form-group">
                <t:textfield t:id="firstName"/>
            </div>
            <div class="form-group">
                <t:textfield t:id="lastName"/>
            </div>
        </t:form>
    </div>

    References: 
    <a href="http://tapestry.apache.org/5.4/apidocs/org/apache/tapestry5/corelib/base/AbstractField.html#getClientId()">getClientId()</a>, 
    <a href="http://tapestry.apache.org/javascript.html">Tapestry JavaScript</a>, 
    <a href="http://tapestry.apache.org/5.4/apidocs/org/apache/tapestry5/services/javascript/JavaScriptSupport.html">JavaScriptSupport</a>, 
    <a href="http://requirejs.org">RequireJS</a>, 
    <a href="http://api.jquery.com">jQuery API</a>.<br/><br/> 
    
    <t:pagelink page="Index">Home</t:pagelink><br/><br/>
    
    <t:tabgroup>
        <t:sourcecodetab src="/web/src/main/java/jumpstart/web/pages/examples/javascript/RobustJavaScript.tml"/>
        <t:sourcecodetab src="/web/src/main/java/jumpstart/web/pages/examples/javascript/RobustJavaScript.java"/>
        <t:sourcecodetab src="/web/src/main/resources/META-INF/modules/textbox-hint.js"/>
        <t:sourcecodetab src="/web/src/main/resources/META-INF/assets/css/examples/js.css"/>
    </t:tabgroup>
</body>
</html>


package jumpstart.web.pages.examples.javascript;

import org.apache.tapestry5.annotations.Import;
import org.apache.tapestry5.annotations.InjectComponent;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.corelib.components.TextField;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.services.javascript.JavaScriptSupport;

@Import(stylesheet = "css/examples/js.css")
public class RobustJavaScript {

    // Screen fields

    @Property
    private String firstName;

    @Property
    private String lastName;

    // Generally useful bits and pieces

    @Inject
    private JavaScriptSupport javaScriptSupport;

    @InjectComponent("firstName")
    private TextField firstNameField;

    @InjectComponent("lastName")
    private TextField lastNameField;

    // The code

    public void afterRender() {

        // Give "textbox hints" to the first name and last name fields.

        javaScriptSupport.require("textbox-hint").with(firstNameField.getClientId(), "Enter First Name", "#808080");
        javaScriptSupport.require("textbox-hint").with(lastNameField.getClientId(), "Enter Last Name", "#808080");
    }

}


// This module observes a field, giving it a "textbox hint" when it is empty and does not have focus.
// Beware: it is flawed because it won't allow the user to submit text that is the same as the hint!

define(["jquery"], function($) {

    return function(textboxId, hintText, hintColor) {
        var $textbox = $("#" + textboxId);

        var normalColor = $textbox.css("color");

        $textbox.on("focus submit", doClearHint);
        $textbox.on("blur change", doCheckHint);

        $textbox.blur();

        function doClearHint() {
            var $field = $(this);
            
            if ($field.val() == hintText) {
                $field.val("");
            }

            $field.css("color", normalColor);
        }

        function doCheckHint() {
            var $field = $(this);

            // If $field is empty, put the hintText in it and set its color to
            // hintColor

            if ($field.val() == "") {
                $field.val(hintText);
                $field.css("color", hintColor);
            }

            // Else if $field contains hintText, set its color to hintColor

            else if ($field.val() == hintText) {
                $field.css("color", hintColor);
            }

            // Else, set the $field's color to its normal color

            else {
                $field.css("color", normalColor);
            }
        }

    }

})


.eg {
                margin: 20px 0;
                padding: 14px;
                color: #888;
                border: 1px solid #ddd;
                border-radius: 6px;
                -webkit-border-radius: 6px;
                -mox-border-radius: 6px;
}

.js-required {
                color: red;
                display: block;
                margin-bottom: 14px;
}

.js-recommended {
                color: red;
                display: block;
                margin-bottom: 14px;
}