Scott Van Vliet

Less Talk, More Rock

March 2005 - Posts

R.I.P Mitch Hedberg (1968 - 2005)

I awoke this morning to morning to a weird message from my friend Jason.  He mentioned that he'd heard a radio station announce that Mitch Hedberg died!  When I heard his message, I frantically searched the Internet for validation (or hopes that it was an April fools joke.)  I could find nothing.

Then, about 10 minutes ago, I Googled his name and found this link.
http://www.mtv.com/news/articles/1499352/20050331/hedberg_mitch.jhtml?headlines=true

It is a sad day for sure.  My good friend Warren introduced me to Mitch back in 2001.  He's witty one-liners were unforgettable, and I've shared his comedy with many of my friends.  His career had only just begun to blossom, and it's sad to say goodbye.

The cause of death is still unknown - but some say it may be drug related.  Mitch was only 37; much too young to die.  It's a sad day for all of us, indeed.

Posted: Mar 31 2005, 03:46 PM by skillet | with 24 comment(s)
Filed under:
TextArea Cursor Position with JavaScript

I’d recently searched around for some good-quality JavaScript snippets to determine the cursor position within an HTML TextArea, but haven’t had any luck.  So, like any fellow geek would do, I came up with my own solution.

 

The DOM in IE does not provide information regarding relative position in terms of characters; however, it does provide bounding and offset values for browser-rendered controls.  Thus, I used these values to determine the relative bounds of a character. Then, using the JavaScript TextRange, I created a mechanism for working with such measures to calculate the Line and Column position for fixed-width fonts within a given TextArea.

 

First, the relative bounds for the TextArea must be calculated based upon the size of the fixed-width font used.  To do this, the original value of the TextArea must be stored in a local JavaScript variable and clear the value.  Then, a TextRange is created to determine the Top and Left bounds of the TextArea.

 

var storedValue = textBox.value;

 

textBox.value = "";

textBox.select();

 

var caretPos = document.selection.createRange();

textBox.__boundingTop = caretPos.boundingTop;

textBox.__boundingLeft = caretPos.boundingLeft;

 

Next, in order to capture the bounding width of a single fixed-width character, the value of the TextArea is set to a single character, selected, and another TextRange is created.

 

textBox.value = " ";

textBox.select();

 

caretPos = document.selection.createRange();

textBox.__boundingWidth = caretPos.boundingWidth;

textBox.__boundingHeight = caretPos.boundingHeight;

 

textBox.value = storedValue;

 

The values obtained from the initialization will persist in the instance of the TextArea, textBox.  Also, in order for this initialization to occur at least once, it must be registered with the onLoad event.

 

<body onload="initPosition(document.forms[0].txtLayoutViewer)">

 

Next, the TextArea must be configured to capture the cursor position.  Mouse and keyboard activity will be captured as follows.

 

 <textarea name="txtLayoutViewer"

   onmouseup="updatePosition(this)"

   onmousedown="updatePosition(this)"

   onkeyup="updatePosition(this)"

   onkeydown="updatePosition(this)"

   onfocus="updatePosition(this)"

   rows="15"

   cols="75"></textarea>

 

When the updatePosition method is called, another TextRange is created to capture the cursor selection.  Then, using the values calculated during the initialization and those in the TextRange, the Line and Column values are calculated as follows.

 

var caretPos = document.selection.createRange();

 

var boundingTop = (caretPos.offsetTop + textBox.scrollTop) - textBox.__boundingTop;

var boundingLeft = (caretPos.offsetLeft + textBox.scrollLeft) - textBox.__boundingLeft; 

 

textBox.__Line = (boundingTop / textBox.__boundingHeight) + 1;

textBox.__Column = (boundingLeft / textBox.__boundingWidth) + 1;

 

As with the bounds captured during initialization, the Line and Column values persist in the instance of the TextArea.  They can then be used be other elements throughout the DOM. 

 

Below is the complete code listing.

 

<html>

<head>

    <script language="JavaScript" type="text/javascript">

    <!--

        function initPosition(textBox) {

            var storedValue = textBox.value;

            textBox.value = "";

            textBox.select();

 

            var caretPos = document.selection.createRange();

            textBox.__boundingTop = caretPos.boundingTop;

            textBox.__boundingLeft = caretPos.boundingLeft;

                    

            textBox.value = " ";

            textBox.select();

 

            caretPos = document.selection.createRange();

            textBox.__boundingWidth = caretPos.boundingWidth;

            textBox.__boundingHeight = caretPos.boundingHeight;

 

            textBox.value = storedValue;

        }

 

        function storePosition(textBox) {

            var caretPos = document.selection.createRange();

 

            var boundingTop = (caretPos.offsetTop + textBox.scrollTop) - textBox.__boundingTop;

            var boundingLeft = (caretPos.offsetLeft + textBox.scrollLeft) - textBox.__boundingLeft;

 

            textBox.__Line = (boundingTop / textBox.__boundingHeight) + 1;

            textBox.__Column = (boundingLeft / textBox.__boundingWidth) + 1;

        } 

 

        function updatePosition(textBox) {

            storePosition(textBox);

            document.forms[0].txtLine.value = textBox.__Line;

            document.forms[0].txtColumn.value = textBox.__Column;

        }

    //-->

    </script>

    <style type="text/css">

        body, td, tg, input, select {

            font-family: Verdana;

            font-size: 10px;

        }

    </style>

</head>

<body onload="initPosition(document.forms[0].txtLayoutViewer)">

    <form>

        <table cellspacing="0" cellpadding="3">

            <tr>

                <td colspan="3">

                    Change Font Size

                    <select onchange="this.form.txtLayoutViewer.style.fontSize = this.options[this.selectedIndex].value; initPosition(this.form.txtLayoutViewer);">

                        <option value="10">10px</option>

                        <option value="12">12px</option>

                        <option value="14">14px</option>

                        <option value="16">16px</option>

                        <option value="18">18px</option>

                        <option value="20">20px</option>

                        <option value="24">24px</option>

                        <option value="36">36px</option>

                    </select>

                </td>

            </tr>

            <tr>

                <td colspan="3">

                    <textarea name="txtLayoutViewer"

                        onmouseup="updatePosition(this)"

                        onmousedown="updatePosition(this)"

                        onkeyup="updatePosition(this)"

                        onkeydown="updatePosition(this)"

                        onfocus="updatePosition(this)"

                        rows="15"

                        cols="75">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec ornare aliquam quam. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Pellentesque et quam in dui consequat tempor. Etiam lorem lectus, sollicitudin laoreet, tincidunt nec, pharetra in, magna. Mauris accumsan velit et augue. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</textarea></td>

            </tr>

            <tr>

                <td width="70%">

                    &nbsp;</td>

                <td width="10%">

                    Line <input type="text" name="txtLine" style="width: 25px" readonly></td>

                <td width="20%">

                    Column <input type="text" name="txtColumn" style="width: 25px" readonly></td>

            </tr>

        </table>

    </form>

</body>

</html>

 

Please note that this has only been tested on IE 6.  As always, I welcome your feedback and constructive criticism.

UPDATE 3/29/3005:

A friend of mine filled me in on a limitation to this approach.  If the TextArea extends beyond the screen, thus requiring scrolling, the calculated values will be incorrect due to the fact that the bounds used in the calculation change when the window has scrolled.  Moreover, if the text you are working with requires that you scroll beyond the viewable portion of the TextArea, the calculated values will reverse.  In order to fix this, the scolling index of the screen and/or TextArea must be obtained to offset the calcuation.  Thus, if you plan on using this approach ensure that the requirements are such that the TextArea does not require scrolling.  Otherwise, if you feel so inclined, email with your thoughts on obtaining the offset value required when scrolling.  Thanks!

UPDATE 4/12/2005:

Thanks to Mr. Noisy, the previous bug listed (TextArea scrolling) has been fixed, and now accounts for the scrollTop and scrollLeft properties of the TextArea.  I've updated the code in this post to reflect the changes.

Picasa Rules!

I just started using Picasa (by Google) and I am hooked!  I have so many digital photos on my laptop that I need to edit and send, and this program makes it so easy.  The interfaces is beautiful, and super easy to use.  It also integrates quite nicely with Gmail.

Check it out and download for sure: http://www.picasa.com.

Posted: Mar 07 2005, 03:07 PM by skillet | with no comments
Filed under: ,
More Posts