SitePoint Sponsor

User Tag List

Page 1 of 2 12 LastLast
Results 1 to 25 of 50
  1. #1
    SitePoint Evangelist
    Join Date
    Jun 2010
    Posts
    453
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

    referencing function parameters

    I have this JS function:
    Code JavaScript:
    var maxAmount = 250;
    function textCounter(textField, showCountField) {
        if (textField.value.length > maxAmount) {
            textField.value = textField.value.substring(0, maxAmount);
    } else { 
            showCountField.value = maxAmount - textField.value.length;
    }
    }

    I also have a form in which I need ti use the fuction:
    Code JavaScript:
    <body>
    <form>
    <textarea name="ta" rows="6" style="width:340px;" onKeyDown="textCounter(???????,???????);" onKeyUp="textCounter(???????,???????);"></textarea>
    <br>
    <input readonly id="ta2"type="text" name="countDisplay" size="3" maxlength="3" value="250"> Characters Remaining
    </form>
    </body>

    How do I reference my the parameters of my function from the form?

  2. #2
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,705
    Mentioned
    101 Post(s)
    Tagged
    4 Thread(s)
    The two values of the function are textField and showCountField

    For the first parameter, the this keyword is going to be the textarea field.
    For the second parameter, you could use this.form.elements.countDisplay to refer to the display field.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  3. #3
    dooby dooby doo silver trophybronze trophy
    spikeZ's Avatar
    Join Date
    Aug 2004
    Location
    Manchester UK
    Posts
    13,806
    Mentioned
    158 Post(s)
    Tagged
    3 Thread(s)
    or.....
    Code JavaScript:
    <form>
    <textarea name="ta" rows="6" style="width:340px;" onKeyDown="textCounter(this,countDisplay);" onKeyUp="textCounter(this,countDisplay);"></textarea>
    <br />
    <input id="ta2" type="text" name="countDisplay" size="3" maxlength="3" value="250" readonly /> Characters Remaining
    </form>

    (but Paul is way better at this voodoo than me!)
    Mike Swiffin - Community Team Advisor
    Only a woman can read between the lines of a one word answer.....

  4. #4
    SitePoint Evangelist
    Join Date
    Jun 2010
    Posts
    453
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    Code JavaScript:
    onKeyDown="textCounter(this,this.form.elements.countDisplay);" onKeyUp="textCounter(this,this.form.elements.countDisplay);"></textarea>

    was unsuccessful. Did i misunderstand?

  5. #5
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,705
    Mentioned
    101 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by nichemtktg View Post
    was unsuccessful. Did i misunderstand?
    It works for me. Is there something else that's causing the problem?
    If you link us through to a test page, we can find out.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  6. #6
    SitePoint Evangelist
    Join Date
    Jun 2010
    Posts
    453
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

  7. #7
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,705
    Mentioned
    101 Post(s)
    Tagged
    4 Thread(s)
    Now the problem is clear as day. The code you claim to have used in post #4 is different from what you actually used.
    Can you see the problem?
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  8. #8
    SitePoint Evangelist
    Join Date
    Jun 2010
    Posts
    453
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    I see the difference. Sorry about that. I've been played with it too much. I made the change and it works.

    I found that this also works:
    Code JavaScript:
    onKeyDown="textCounter(this,document.getElementById('ta2'));" onKeyUp="textCounter(this,document.getElementById('ta2'));"

    It makes sense to me though I had to give <input> an id.

    I'm real fuzzy in the use of "this" and I'm unsure how you came-up with "this.form.elements".

    1. I've already spoken to my fuzziness with "this"

    2. I believe the "form" comes from the HTML DOM Form Object. If so, that makes sense, but please confirm.

    3. I'm unclear where the "elements" came form the HTML DOM Form Object talks about "elements[]" if they're the same why drop the "[]"?

    My uncertainty about how to use "this" really bugs me because it seems important based on what I've read, but I haven't found clear general ref for how to use it. any suggestions (other than asking too many questions)?

  9. #9
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,705
    Mentioned
    101 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by nichemtktg View Post
    I'm real fuzzy in the use of "this" and I I'm unsure how you came-up with "this.form.elements.

    1. I've already spoken to my fuzziness with "this"
    The this keyword is a reference to the context within which the function was executed.

    Quote Originally Posted by nichemtktg View Post
    2. I believe the "form" comes from the HTML DOM Form Object. If so, that makes sense, but please confirm.
    All form fields contain a property called form, that refers to the form element that the field is contain within.

    Quote Originally Posted by nichemtktg View Post
    3. I'm unclear where the "elements" came form the HTML DOM Form Object talks about "elements[]" if they're the same why drop the "[]"?
    Using the array index notation could be used as well, but typically it's not used in preference to object notation.
    this.form.elements['username'] is the same as this.form.elements.username

    But the same goes with any property reference:
    this['form']['elements']['username'] is the same too, though less readable.

    Typically the only reason to use the array notation is when you want to make it clear that actual indexed arrays are used, or when characters occur in the name (a dash for example) that aren't usable as a property notation.

    Quote Originally Posted by nichemtktg View Post
    My uncertainty about how to use "this" really bugs me because it seems important based on what I've read, but I haven't found clear general ref for how to use it. any suggestions (other than asking too many questions)?
    What do you think of the information at the page about the this keyword
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  10. #10
    SitePoint Evangelist
    Join Date
    Jun 2010
    Posts
    453
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    regarding who owns the textCounter function, in my script I think its a method of the window object, because it hasn't been copied to a different object, therefore a simple "this" is enough. Please confirm.

  11. #11
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,705
    Mentioned
    101 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by nichemtktg View Post
    regarding who owns the textCounter function, in my script I think its a method of the window object, because it hasn't been copied to a different object, therefore a simple "this" is enough. Please confirm.
    The textCounter function is not copied to the event handler, so the function will not have an appropriate this keyword reference to the element that triggered the event.

    There are three different techniques that can be used to deal with that problem.

    1. Use traditional event assignment instead, so that the this keyword is available from within the function.
    2. Pass the this keyword separately to the function as an additional function parameter.
    3. Call the function using the this keyword to assign the context from which the function will be called.

    Traditional Event Assignment

    When using this first technique, the HTML code for the form field is much simpler, where a unique identifier is placed on the form to allow scripting to access the form elements:

    Code:
    <form id="countedText">
        <textarea name="ta" rows="6" style="width:340px;"
            onKeyDown="textCounter(this, this.form.elements.countDisplay);"
            onKeyUp="textCounter(this, this.form.elements.countDisplay);">
    </textarea>
    </form>
    so that scripting is used to perform the event assignment instead.
    There are a couple of ways to handle things here.

    One way, the way that I typically prefer, is to store a reference to the display area as a property directly on the textarea field itself:

    Code javascript:
    function countDisplay() {
        var textField = this,
        showCountField = textField.countDisplay;
        ...
    }
    var form = document.getElementById('countedText'),
        textarea = form.elements.ta;
     
    textarea.countDisplay = form.elements.countDisplay;
    textarea.onkeydown = textCounter;
    textarea.onkeyup = textCounter;

    Another way is to pass the count display as a property to the function, but then you cannot use a direct assignment of the function to the event, you have you use an anonymous function so that you can invoke the countDisplay function with the appropriate argument, and pass the this context along to the function as well:

    Code javascript:
    function countDisplay(countDisplay) {
        var textField = this;
        ...
    }
    var form = document.getElementById('countedText'),
        textarea = form.elements.ta,
        countDisplay = form.elements.countDisplay;
    textarea.onkeydown = function () {
        textCounter.call(this, countDisplay);
    };
    textarea.onkeyup = function () {
        textCounter.call(this, countDisplay);
    };

    It can be preferred though to combine those identical functions in to a single event handler function instead:

    Code javascript:
    function countDisplay(countDisplay) {
        var textField = this;
        ...
    }
    function textareaHandler(countDisplay) {
        return function () {
            textCounter.call(this, countDisplay);
        };
    }
    var form = document.getElementById('countedText'),
        textarea = form.elements.ta,
        countDisplay = form.elements.countDisplay;
    textarea.onkeydown = textareaHandler(countDisplay);
    textarea.onkeyup = textareaHandler(countDisplay);

    That gets a bit complicated though, and it why I prefer to use the first example where the field property to store the reference. It's a good technique that only needs to be moved away from if you're concerned about other code over-writing the property.

    Inline Event Attribute

    You are currently using the second technique, which forces you to use an extra parameter in your function to receive a reference to the element. Examples of which are in the previous posts above.

    Pass the Inline Context to the Function

    This third technique is where the call method is used to call the function with an appropriate context, simulating that which scripting automatically does in the first technique:

    Code:
    <textarea name="ta" rows="6" style="width:340px;"
        onKeyDown="textCounter.call(this, this.form.elements.countDisplay);"
        onKeyUp="textCounter.call(this, this.form.elements.countDisplay);"[/color][/s]>
    </textarea>
    where the function still has only the one parameter:

    Code javascript:
    function countDisplay(countDisplay) {
        var textField = this;
        ...
    }

    This technique is disliked though, due to it being another inline event attribute technique, along with .call() to help confuse things.
    Last edited by paul_wilkins; Jul 7, 2011 at 21:43.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  12. #12
    SitePoint Evangelist
    Join Date
    Jun 2010
    Posts
    453
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    On second thought, "this" must be referring to the <textarea> because that's where the input is coming from. without the <textarea> input there's nothing for the function to do. Right now for the right reason?

  13. #13
    SitePoint Evangelist
    Join Date
    Jun 2010
    Posts
    453
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    Thanks for all the work you put into your last post.

    At this point, I need to confirm an understanding that I've formed based on this topic. Please confirm that the this keyword refers to the owner of of the input which in this case is HTML DOM Textarea Object.

    Also, would it be safe to say, that to establish ownership, I need to establish the source of an input as in source = owner?

  14. #14
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,705
    Mentioned
    101 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by nichemtktg View Post
    Please confirm that the this keyword refers to the owner of of the input which in this case is HTML DOM Textarea Object.
    The this keyword refers to the execution context. With your current code, the this keyword refers to the element on which the event is triggered.

    Quote Originally Posted by nichemtktg View Post
    Also, would it be safe to say, that to establish ownership, I need to establish the source of an input as in source = owner?
    I don't follow what you mean there. Can you provide a small example of what you mean there?
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  15. #15
    SitePoint Evangelist
    Join Date
    Jun 2010
    Posts
    453
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    "the this keyword refers to the element on which the event is triggered."

    which is the HTML DOM Textarea Object, right?

    Javascript - The this keyword talks the owner of the function. Since th onkeyup/down is being called from <textarea> the Textarea Object owns that function therefore this refers to the <textarea> input. Correct?

  16. #16
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,705
    Mentioned
    101 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by nichemtktg View Post
    "the this keyword refers to the element on which the event is triggered."

    which is the HTML DOM Textarea Object, right?
    When using an inline event attribute, here is what happens.

    Code html4strict:
    <textarea onkeyup="doSomething();">

    The following anonymous function gets assigned to the onkeyup event:

    Code javascript:
    function () {
        doSomething();
    }

    So it is only inside of that function that the this keyword refers to the textarea object. When the doSomething function is called, inside of that doSomething function the this keyword refers to the default global context, that being the window object.

    Quote Originally Posted by nichemtktg View Post
    Javascript - The this keyword talks the owner of the function. Since th onkeyup/down is being called from <textarea> the Textarea Object owns that function therefore this refers to the <textarea> input. Correct?
    It doesn't own the doSomething() function from the above example. It only owns the outer function that is assigned to the event, that being the anonymous function.

    That's why you can pass the this keyword as a function parameter.

    Once you move on from using horrible inline event attributes to using traditional event associations instead, the problem of dealing with the this keyword is largely reduced.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  17. #17
    SitePoint Evangelist
    Join Date
    Jun 2010
    Posts
    453
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    How would you change this script to Traditional Event Assignment. I think you were hinting around in post #11, but I wasn't catching on (obviously)
    Code JavaScript:
    <html>
    <head>
    <script language="javascript" type="text/javascript"> 
    var maxAmount = 250;
    function textCounter(textField, showCountField) {
        if (textField.value.length > maxAmount) {
            textField.value = textField.value.substring(0, maxAmount);
    } else { 
            showCountField.value = maxAmount - textField.value.length;
    }
    }
    </script>
    </head>
    <body>
    <form>
    <textarea name="ta" rows="6" style="width:340px;" onKeyDown="textCounter(this,this.form.elements.countDisplay);" onKeyUp="textCounter(this,this.form.elements.countDisplay);"></textarea>
    <br>
    <input readonly id="ta2" type="text" name="countDisplay" size="3" maxlength="3" value="250"> Characters Remaining
    </form>
    </body>
    </html>
    .

  18. #18
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,705
    Mentioned
    101 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by nichemtktg View Post
    How would you change this script to Traditional Event Assignment. I think you were hinting around in post #11, but I wasn't catching on (obviously)
    When using traditional event assignment, scripting is used to associate a function to the event of an element.

    With the scripting currently in the head, at the time that the script runs, none of the web page yet exists, so the head script cannot work with elements on the page until later on once they exist. It's possible to keep the script in the head and use some kind of onload event to delay the running of your code until the page exists, but that's introducing more complexity that you can do without.

    The solution to all of this is to not put your script in the head. A technique to speed up the loading of your web page is to put your script at the bottom, just before the </body> tag.

    You can move your script from the head to the end of the body \without affecting how your code works, and it opens up the benefit of being able to easily work with elements on the page directly from your script without having to wait until some later point in time.

    Once you've done that, you can gain a reference to the form, and from there to the textarea element, so that you can assign a function to certain events.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  19. #19
    SitePoint Evangelist
    Join Date
    Jun 2010
    Posts
    453
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by paul_wilkins View Post
    Once you've done that, you can gain a reference to the form, and from there to the textarea element, so that you can assign a function to certain events.
    Please be more specific . I've moved the <script> tag to the end and need to be clearer about what's intended.

  20. #20
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,705
    Mentioned
    101 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by nichemtktg View Post
    Please be more specific . I've moved the <script> tag to the end and need to be clearer about what's intended.
    To be more specific, here is a copy/paste from post #11

    Quote Originally Posted by paul_wilkins View Post
    Traditional Event Assignment

    When using this first technique, the HTML code for the form field is much simpler, where a unique identifier is placed on the form to allow scripting to access the form elements:

    Code:
    <form id="countedText">
        <textarea name="ta" rows="6" style="width:340px;"
            onKeyDown="textCounter(this, this.form.elements.countDisplay);"
            onKeyUp="textCounter(this, this.form.elements.countDisplay);">
    </textarea>
    </form>
    so that scripting is used to perform the event assignment instead.
    There are a couple of ways to handle things here.

    One way, the way that I typically prefer, is to store a reference to the display area as a property directly on the textarea field itself:

    Code javascript:
    function countDisplay() {
        var textField = this,
        showCountField = textField.countDisplay;
        ...
    }
    var form = document.getElementById('countedText'),
        textarea = form.elements.ta;
     
    textarea.countDisplay = form.elements.countDisplay;
    textarea.onkeydown = textCounter;
    textarea.onkeyup = textCounter;
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  21. #21
    SitePoint Evangelist
    Join Date
    Jun 2010
    Posts
    453
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    I'd like to try to write it with your help. Here's how far I've got, but I don't understand how typing in the <textarea> is going to trigger my function.
    HTML Code:
    <!doctype html>
    <html> <head> <title> Counter </title> 
    <script type="text/javascript">  
    var maxChar = 251;
    var currentNum = 0;
    var calcCharacters = document.getElementById('ta');
    function calcCharacters2 () {
    calculation of the number of characters in <textarea>;
    } 
    </script>  
    </head> <body>
    <form>
        <textarea name="ta" rows="6" style="width:340px;"> </textarea>
    	<br>
        <input type="text" name="countDisplay" size="3" maxlength="3" value="250"> Characters Remaining
    </form>
    </body> </html>

  22. #22
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,705
    Mentioned
    101 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by nichemtktg View Post
    I'd like to try to write it with your help. Here's how far I've got, but I don't understand how typing in the <textarea> is going to trigger my function.
    HTML Code:
    <!doctype html>
    <html> <head> <title> Counter </title> 
    <script type="text/javascript">  
    var maxChar = 251;
    var currentNum = 0;
    var calcCharacters = document.getElementById('ta');
    function calcCharacters2 () {
    calculation of the number of characters in <textarea>;
    } 
    </script>  
    First of all, when that script runs, nothing else below it will exist at the time.
    Move the script to the end of the body, just before the </body> tag, and the calcCharacters will change from being undefined, to being a reference to the textarea element.

    Once you've done that, you can use scripting to assign to one of the textarea events the function.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  23. #23
    SitePoint Evangelist
    Join Date
    Jun 2010
    Posts
    453
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    you can use scripting to assign to one of the textarea events the function.
    I think i'm close, but having trouble about how to think of your quote

    my script so far:
    Code JavaScript:
    <!doctype html>
    <html> <head> <title> Counter </title> 
     
    </head> <body>
    <form>
        <textarea name="ta" rows="6" style="width:340px;"> </textarea>
    	<br>
        <input type="text" name="countDisplay" size="3" maxlength="3" value="250"> Characters Remaining
    </form>
    <script type="text/javascript">  
     
    var maxChar = 251;
    var currentNum = 0;
    var calcCharacters = document.getElementById('ta');
    calcCharacters.onkeydown = calcCharacters2;
    function calcCharacters2 () {
    alert( "I'm gonna count those chars in ta!" );
         //calculation of the number of characters in <textarea>;
    } 
     
    </script>  
    </body> </html>

  24. #24
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,705
    Mentioned
    101 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by nichemtktg View Post
    I think i'm close, but having trouble about how to think of your quote
    You are doing that part of the technique correctly.

    The problem now is that you are using getElementById to retrieve a reference to the textarea, but the textarea has no id.

    It's best-practice to use a form id, so that you can then use the form elements collection to access the named elements of the form.

    For example:

    Code html4strict:
    <form id="descriptiveIdentifierForTheFormContents">

    Code javascript:
    var form = document.getElementById('descriptiveIdentifierForTheFormContents');
    var textarea = form.elements.ta;

    Of course, do not use anything as large as "descriptiveIdentifierForTheFormContents" for the identifier. Just ensure that it appropriately indicates what the form contains. Something like "countableText" or "textCounter" would be appropriate.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  25. #25
    SitePoint Evangelist
    Join Date
    Jun 2010
    Posts
    453
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    was missing the id in the <textarea> which I added and got access to the function.

    So, I tested the value of calcCharacters thinking it might be a value, but the alert said calcCharacters is a html object.

    How do I need to think about making the calculations in the function. Here's the work so far:
    Code JavaScript:
    <!doctype html>
    <html> <head> <title> Counter </title> 
     
    </head> <body>
    <form>
        <textarea id="ta" name="ta" rows="6" style="width:340px;"> </textarea>
    	<br>
        <input type="text" name="countDisplay" size="3" maxlength="3" value="250"> Characters Remaining
    </form>
    <script type="text/javascript">  
     
    var maxChar = 251;
    var currentNum = 0;
    var calcCharacters = document.getElementById('ta');
    calcCharacters.onkeydown = calcCharacters2;
    function calcCharacters2 () {
    alert( "I'm gonna count those chars in ta!" + calcCharacters );
         //calculation of the number of characters in <textarea>;
    } 
     
    </script>  
    </body> </html>


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •