Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I was just trying to make an alternate Ajax watermark from "insert date" (first mode) to "mm/dd/yyyy" (second mode).

After some trial and error, I succefully implemented a solution using JavaScript.

JavaScript:

<!-- language: lang-js -->


var original = "insert date";
var alternate = "mmddyyyy";
var countalerted = 0;
var txt = "";
var intird = 0;
if (intird == 0) {
    intrId = setInterval(function () { alterWaterMarkForDateTBX() }, 1000);
}
function SetIntervalTBX() {
    setInterval(function () { alterWaterMarkForDateTBX() }, 1000);
}

function alterWaterMarkForDateTBX() {
    var d = new Date();
    var t = d.toLocaleTimeString();

    if (countalerted < 4) {
        if (countalerted % 2 == 0) {
            document.forms["form1"].elements["TBXinsertDate"].value = original;
        }
        else {
            document.forms["form1"].elements["TBXinsertDate"].value = alternate;
        }
        countalerted++;
    }
    else {
        window.status = intrId;
        clearInterval(intrId);
//        document.forms["form1"].elements["TBXinsertDate"].value = original;
    }
}


var wasFocused = false;var wasBlur = false;
function Focus(objname, waterMarkText) {
    wasFocused = true;
    if (wasBlur == false) {
        obj = document.getElementById(objname);
        if (obj.value == waterMarkText) {
            obj.value = "";
            obj.className = "NormalTextBox";
            if (obj.value == original || obj.value == alternate || obj.value == "" || obj.value == null) {
                obj.style.color = "black";
            }
        }
    }
}

//i added "__/__/____" for the value of the ajax MaskEdit

function Blur(objname, waterMarkText) {
    wasBlur = true;
    var alternateWM1 = "insert date";
    var alternateWM2 = "mm/dd/yyyy";
    obj = document.getElementById(objname);
    if (obj.value == "" || obj.value == "__/__/____") {
        obj.value = waterMarkText;
        obj.className = "WaterMarkedTextBox";

    }
    else {
        obj.className = "NormalTextBox";
    }

    if (obj.value == original || obj.value == alternate || obj.value == "" || obj.value == null || obj.value == "__/__/____") {
        obj.style.color = "gray";
        if (wasFocused == true) {
            SetIntervalTBX();
        }
    }
}

ASPX / HTML

<!-- language: lang-html -->

<form id="form1" runat="server">
    <asp:TextBox ID="TBXinsertDate" runat="server"
     ToolTip="date Box"  Width="79px" 
     onfocus="Focus(this.id, this.value)"
     onblur="Blur(this.id, this.value)" >
    </asp:TextBox>
 </form>


Question:
How can I improve this script functionality?

Playing with it will give you a better clue on how it behaves!

share|improve this question

2 Answers 2

up vote 3 down vote accepted
+50

Some notes:

  1. Think about reusability. Your code integrates the field names directly into the functions. Same goes for some of your choices of function names (alterWaterMarkForDateTBX). This makes it difficult to reuse next time you need this function.

  2. You appear to be mixing ideas. You set a class name sometimes, set the text color other times. I'm not sure if this was intentional but I just changed it all to class names.

  3. You had some dead variables. Stuff like this just make it harder to edit in the future. Remove them. var d = new Date(); var t = d.toLocaleTimeString();

  4. You are checking to make sure the field had focus before it blurred (and vice versa). And then Not sure what the purpose of that is.

  5. Your focus and blur events pass in the textbox name and the textbox value (as watermarkText. Then you check the value against a couple of other values and if it matches set the textbox back to watermarkText. This will never accomplish anything and is confusing. Just pass in the textbox itself.

  6. Think about non-intrusive javascript. It is easier to maintain. Notice how I added the blur and focus events to the field through javascript instead of directly in the html.

  7. You should try to avoid global objects. Look into putting this entire code block into an object. The problem you will face is what if you have two fields on the same form that need this functionality. The changes I have made below will go a long way in helping but the global interval and global counter will conflict with one another and it will not work.

EDIT:

I was interested in this problem. So I extended my code.

  1. I moved the main work into a function object. This can now be called using a constructor which passes in the text box. This also allows for multiple textboxes using this even on the same page.

  2. I added an options object to the parameters. This will allow you to change the functionality of the script without changing the actual code. This allows for reusability without needing to modify the code (open-closed principle). This is also a common technique used in many of the JS frameworks (jQuery, mooTools, etc..)

Styles:

.NormalTextBox {
color = "black";
}
.WaterMarkedTextBox {
color = "grey";
}

Script:

    var MultiWatermark = function (obj, options) {

    var defaultOptions = {
        // These variables can be changed to alter functionality using the passed in options object
        watermarkVals: ["insert date", "mmddyyyy"], // all watermark values.
        totalIterations: 2, // how many times to go through watermark Array.
        watermarkClassName: "WaterMarkedTextBox",
        normalClassName: "NormalTextBox",
        changeDelay: 1000, // in milliseconds
        extraValsToCheck: ['', null]// 
    }

    //merge options with defaultOptions
    for (var property in defaultOptions) {
        if (!options.hasOwnProperty(property)) {
            options[property] = defaultOptions[property];
        }
    }

    // local variables (do not change)
    var textBox = obj;
    var iterationCounter = 0;
    var itemCounter = 0;
    var intrId;

    var startWatermark = function () {
        itemCounter = 0; iterationCounter = 0; // resets for after blur
        intrId = setInterval(function () { alterWaterMark() }, options.changeDelay);
    }

    var stopWatermark = function () {
        clearInterval(intrId);
    }

    var alterWaterMark = function () {

        if (iterationCounter < options.totalIterations) {

            textBox.value = options.watermarkVals[itemCounter];
            itemCounter += 1;
            if (itemCounter == options.watermarkVals.length) {
                itemCounter = 0;
                iterationCounter += 1;
            }
        }
        else {
            stopWatermark();
        }

    }

    var isWatermarkValue = function (val) {

        var i = options.watermarkVals.length;
        while (i--) {
            if (options.watermarkVals[i] === val) {
                return true;
            }
        }
        // value is not in watermark array, so check secondary values.
        i = options.extraValsToCheck.length;
        while (i--) {
            if (options.extraValsToCheck[i] === val) {
                return true;
            }
        }
    }

    var setClass = function () {
        textBox.className = isWatermarkValue(textBox.value) ? options.watermarkClassName : options.normalClassName;
    }

    var focusEvent = function () {

        stopWatermark();
        if (isWatermarkValue(textBox.value)) {
            textBox.value = "";
        }
        setClass()
    }

    var blurEvent = function () {

        if (isWatermarkValue(textBox.value)) {
            startWatermark();
        }
        setClass();

    }

    var initWatermark = function () {
        setClass();
        textBox.onfocus = focusEvent;
        textBox.onblur = blurEvent;
        startWatermark();
    }


    initWatermark();
}

Body:

<form id="form1" runat="server">
    <input ID="TBXinsertDate" ToolTip="date Box"  Width="79px" />
    <input ID="Text1" ToolTip="date Box"  Width="79px" />
 </form>

<script>


var dateOptions = {
    // These variables alter functionality, the main script will use the defaults of any options not included here 
    watermarkVals: ["insert date", "mmddyyyy", "mm/dd/yyyy"], // all watermark values.
    totalIterations: 4,
    changeDelay: 500, // in milliseconds
    extraValsToCheck: ['', null, '__/__/____', 'test']//
}
new MultiWatermark(document.forms["form1"].elements["TBXinsertDate"], dateOptions);
new MultiWatermark(document.forms["form1"].elements["Text1"], dateOptions);
</script>
</body>
</html>
share|improve this answer
    
hey nickless jscripter , i am glad to see you've changed my code . i did try b4 your new "Edit" something was wrong on blur , now i can see you've updated it again so i will check on it , i hope you'll still be around later on ! –  LoneXcoder Oct 8 '12 at 21:10
    
i checked your code , it works just fine, then i played with it (trying to perfect it even more) to make it work 1) on documentreadystate(so no need for <scrptags> at the end you would just have it layed among rest of js. 2) to send parameter for the target textbox 3) to make it as saperated js file and then just call function ondocumentready( executTheMultyWatermarkOn(tbxID);) i have the ready js without the need for Jquery i wanted to send you it's code if you like , and how do i contact you (mail ...skype)? P.S Your Js Coding Rocks ! –  LoneXcoder Oct 8 '12 at 22:59
    
1) I left that off for simplicity sake. Putting the scripts at the bottom does the same thing (although could be considered messy. You could also just put everything in a separate file and then include them at the bottom of the page. 2) That is what I am doing at the bottom of the page. new MultiWatermark({textbox}, {options}) sets up the field automatically. 3) always a good idea to move scripts to external files. Thanks for the words of encouragement. :) My contact info is in my profile. –  nickles80 Oct 9 '12 at 0:09
    
i am going to post your version but with my reconstracted version of your version (: soon i hope , cleaning up the code , meanwhile i was checking on how to avoid readystate via defer script-attribute and also how to include a .js file from a .js file (cool stuff) i hope you'll be interested although i did 'let you off the hook' you are already rewarded (L: –  LoneXcoder Oct 9 '12 at 2:26

I think you're trying to create a simple placeholder.

A placeholder adds default text to an emtpy input field.

The placeholder attribute is introduced in HTML 5.

Example 1: (DEMO)

<input type="text" placeholder="Please fill this field" />

Example 2: (DEMO)

This cross-browser example implements the functionality of the placeholder property:

Take from http://help.dottoro.com/ljgugboo.php

<head>
    <script type="text/javascript">
        function ClearPlaceHolder (input) {
            if (input.value == input.defaultValue) {
                input.value = "";
            }
        }
        function SetPlaceHolder (input) {
            if (input.value == "") {
                input.value = input.defaultValue;
            }
        }
    </script>
</head> 
<body>
    <input type="text" value="Please fill this field" onfocus="ClearPlaceHolder (this)" onblur="SetPlaceHolder (this)" /> 
</body>

Lastly, I would only have one type of placeholder text for each input element. So use insert date or mm/dd/yyyy as placeholder, but not both.

Extra Info: Try out Input type=date

share|improve this answer
    
thanks for your answer though on my server i can't implement html5. what i was asking is about this code of JavaScript as it is now , it's supported in current VS 2010 , and in current window server (2003) iis6 , the issue here is a standart watermark turned into a dual mode , one mode is presenting the value needed to insert into the text box and second mode tells you in which format., the interval(1 sec each flip) is switching between modes. i was asking if there's a known version implemented already, if not.. then how's my (not so professional javascripting) in this code doing? is it fine? –  LoneXcoder Oct 6 '12 at 22:15

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.