Reusable JavaScript

Here we demonstrate some reusable javascript that puts a "textbox hint" in a field. We could achieve the same effect with HTML5's placeholder attribute, but this works across more browsers.
We made it reusable by passing parameters such as the element id to it, and by putting the file in a central place (modules/).

References: 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>Reusable JavaScript</h3>

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

    Here we demonstrate some reusable javascript that puts a "textbox hint" in a field. 
    We could achieve the same effect with HTML5's <code>placeholder</code> attribute, but this works across more browsers.<br/>
    
    <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>
    
    We made it reusable by passing parameters such as the element id to it, and by putting the file in a central place (<code>modules/</code>).<br/><br/>
    
    References: 
    <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/ReusableJavaScript.tml"/>
        <t:sourcecodetab src="/web/src/main/java/jumpstart/web/pages/examples/javascript/ReusableJavaScript.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.Property;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.services.javascript.JavaScriptSupport;

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

    // Screen fields

    @Property
    private String firstName;

    @Property
    private String lastName;

    // Generally useful bits and pieces

    @Inject
    private JavaScriptSupport javaScriptSupport;

    // The code

    public void afterRender() {

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

        javaScriptSupport.require("textbox-hint").with("firstName", "Enter First Name", "#808080");
        javaScriptSupport.require("textbox-hint").with("lastName", "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;
}