2

I have a really weird and confusing error.

Here is my code:

{if="$pjax === false"}{include="header"}{/if}
<script type="text/javascript">
    $(document).ready(function() {
        function clickclear(thisfield, defaulttext) {
            if (thisfield.value == defaulttext) {
                thisfield.value = "";
            }
        }
        function clickrecall(thisfield, defaulttext) {
            if (thisfield.value == "") {
                thisfield.value = defaulttext;
            }
        }
    });
</script>
<form action='./login' method='post' name='form'>
<ul class="form">
    <li><input type="text" name="username" value="Username" id="username" onclick="clickclear(this, 'Username')" onblur="clickrecall(this,'Username')"  /></li>
    <li><input type="password" name="password" value="Password" id="password" onclick="clickclear(this, 'Password')" onblur="clickrecall(this,'Password')" /></li>
    <li><span style='display:block;height:27px;float:left;line-height:27px;'>Remember Me</span> <div id='itoggle' style='float:right;'><input type="checkbox" id="remember" class='itoggle' /></div><div class='clearfix'></div></li>
</ul>
</form>
<a href="javascript: form.submit()" class="button white">Login</a>
{if="$pjax === false"}{include="footer"}{/if}

You can see there are two functions, clickclear and clickrecall. These get called from the form inputs on onClick and onBlur. However, when I run them, I get these javascript errors:

Uncaught ReferenceError: clickclear is not defined

Uncaught ReferenceError: clickrecall is not defined

Any ideas? I know it's probably something really simple, but I can't see it.

4
  • 2
    There's no reason to wrap your functions inside document.ready. Commented May 23, 2012 at 18:40
  • It's because the functions are ONLY available inside the .ready() function: they're private functions to that function. Commented May 23, 2012 at 18:43
  • It still gave the same error when i didnt use document.ready Commented May 23, 2012 at 18:50
  • please restrict your code to what the browser gets - not the templated source! Commented May 24, 2012 at 18:44

1 Answer 1

5

It's because your functions are in the .ready() callback. These are not visible from the global scope (which is good).

It's better using jQuery's event attachment methods like .on():

$(document).ready(function(){

    //your code
    function clickclear(){...}
    function clickrecall(){...}

    //the handlers
    $('#username').on('click',function(){ //bind click handler
        clickclear(this,'Username');      //things to do on click
    }).on('blur',function(){              //chain blur handler
        clickrecall(this,'Username');     //things to do on blur
    });

    $('#password').on('click',function(){ //bind click handler
        clickclear(this,'Password');      //things to do on click
    }).on('blur',function(){              //chain blur handler
        clickrecall(this,'Password');     //things to do on blur
    });

    ...other handlers...

});

And a side note, there is a placeholder attribute for Chrome, which acts like placeholder text:

<input type="text" placeholder="username" />
<input type="password" placeholder="password" />
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks! this works. but it seems like quite a large quantitiy of code for such a small feature, this is for a mobile website so i want to restrict as much code as possible. I think i may be able to impliment this idea into a smaller code for all the inputs. Thank you very much! :D
And yeah i know about placeholder :P but although its a mobile site, i like to keep code similar to work in IE and such
@DanSpiteri you can minify your code for production and it is better to do it this way because of "separation of concerns" (separate HTML, CSS and JS from each other) for clean code.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.