Advertisement

Textarea with numbered lines

Moderator: Calcifer

Textarea with numbered lines

Postby ANMMark » Tue Jul 04, 2006 10:26 pm

In many cases, when presenting code or online text editing, it is necessary to show line numbers.

It would be nice to have a widget or dhtml/javascript module that we can simply specify a textarea name and it adds a numbered list/div/td to the left, etc.
ANMMark
 
Posts: 8
Joined: Fri Mar 24, 2006 8:30 am

Postby ANMMark » Fri Jul 21, 2006 5:47 pm

I noticed that this thread may have been overlooked.

So, I found a screenshot to make it a little more clear what I'd like to accomplish, and quite possibly inspire dhtmlgoodies to include...

Image
ANMMark
 
Posts: 8
Joined: Fri Mar 24, 2006 8:30 am

Postby ANMMark » Fri Jul 21, 2006 6:13 pm

Sorry to keep posting to this, but..

I was thinking this through and thought that a possible method of doing this might be to create a vertically numbered image with the GD library and PHP, and then use that image as the background for the textarea.
ANMMark
 
Posts: 8
Joined: Fri Mar 24, 2006 8:30 am

Postby Batalf » Fri Jul 21, 2006 8:16 pm

Hello

Yes, a combination of background image and left padding might be a good idea.

I have played with this idea for some minutes now and you can probably also accomplish what you want with pure JS.

Here's an example:

Code: Select all
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
   <head>
   <style type="text/css">
   #codeTextarea{
      width:500px;
      height:510px;
   }
   .textAreaWithLines{
      font-family:courier;      
      border:1px solid #F00;
      
   }
   .textAreaWithLines textarea,.textAreaWithLines div{
      border:0px;
      line-height:120%;
      font-size:12px;
   }
   .lineObj{
      color:red;
   }
   </style>
   
   <script type="text/javascript">
   
   var lineObjOffsetTop = 2;
   
   function createTextAreaWithLines(id)
   {
      var el = document.createElement('DIV');
      var ta = document.getElementById(id);
      ta.parentNode.insertBefore(el,ta);
      el.appendChild(ta);
      
      el.className='textAreaWithLines';
      el.style.width = (ta.offsetWidth + 30) + 'px';
      ta.style.position = 'absolute';
      ta.style.left = '30px';
      el.style.height = (ta.offsetHeight + 2) + 'px';
      el.style.overflow='hidden';
      el.style.position = 'relative';
      el.style.width = (ta.offsetWidth + 30) + 'px';
      var lineObj = document.createElement('DIV');
      lineObj.style.position = 'absolute';
      lineObj.style.top = lineObjOffsetTop + 'px';
      lineObj.style.left = '0px';
      lineObj.style.width = '27px';
      el.insertBefore(lineObj,ta);
      lineObj.style.textAlign = 'right';
      lineObj.className='lineObj';
      var string = '';
      for(var no=1;no<200;no++){
         if(string.length>0)string = string + '<br>';
         string = string + no;
      }
      
      ta.onkeydown = function() { positionLineObj(lineObj,ta); };
      ta.onmousedown = function() { positionLineObj(lineObj,ta); };
      ta.onscroll = function() { positionLineObj(lineObj,ta); };
      ta.onblur = function() { positionLineObj(lineObj,ta); };
      ta.onfocus = function() { positionLineObj(lineObj,ta); };
      ta.onmouseover = function() { positionLineObj(lineObj,ta); };
      lineObj.innerHTML = string;
      
   }
   
   function positionLineObj(obj,ta)
   {
      obj.style.top = (ta.scrollTop * -1 + lineObjOffsetTop) + 'px';   
   
      
   }
   
   </script>
   
   </head>   
   <body>
   <form>
   <textarea id="codeTextarea">
   
   
   </textarea>
   </form>
   <script type="text/javascript">
   createTextAreaWithLines('codeTextarea');
   </script>
   </body>
</html>
Batalf
Site Admin
 
Posts: 2160
Joined: Sat Oct 22, 2005 9:38 pm

Postby ANMMark » Sat Jul 22, 2006 6:10 am

WOW.

That is a very nice and simple method indeed.

The only thing I found that put a minor wrench in the works is that it's slightly buggy in Firefox (you must click on a line to get the left number column to adjust), and of course in Opera the number column doesn't adjust at all (I'm surprised Opera can display web pages at all lol ).

All I can say is, when I pasted the code and saved it, then displayed it in IE, I was blown away! Very good work indeed.

I just wish there was some way to get it to be more compatible with Opera and Firefox.
ANMMark
 
Posts: 8
Joined: Fri Mar 24, 2006 8:30 am

TextArea with Line Numbers

Postby straightPete » Sat Jul 29, 2006 10:27 pm

Hello - I reworked Batalf's idea a bit. Made a thin textarea that pops in next to the main textarea so font and line-height etc is same in both. Mouse etc events trigger scrollbar reset and reposition. The repositioning means user can change font size via ctrl+scroll or view>text size and elements will realign. Works pretty fine in IE6 and Firefox1.5, not in Opera8 (all on WinXP). One could fiddle the events to get better behaviour but be careful of overload. Could also play with textarea sizes in relative ems. Fixed size with flexible font works for me.
Anyway, here it is ( the whole page):


Code: Select all
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
  <title>TextArea Line Numbers Demo</title>
    <style>
      html {font:normal 76% verdana, arial, san serif;}
      body {padding:2em;}
      h2 {font-size:1.8em; padding:0.5em; background:#44aaff;}
      textarea {font-size:100%;}
      #editContent{
          margin-left:30px;
          padding-left:3px;
          width:600px;
          height:200px;
          border:1px solid #666;
      }
     .textAreaWithLines{
         display:block;
         margin:0;
         border:1px solid #666;
         border-right:none;
         background:#aaa;
      }
    </style>
    <script type="text/javascript">
    function createTextAreaWithLines(id)
    {
      var el = document.createElement('TEXTAREA');
      var ta = document.getElementById(id);
      var string = '';
        for(var no=1;no<300;no++){
          if(string.length>0)string += '\n';
          string += no;
        }
      el.className      = 'textAreaWithLines';
      el.style.height   = (ta.offsetHeight-3) + "px";
      el.style.width    = "25px";
      el.style.position = "absolute";
      el.style.overflow = 'hidden';
      el.style.textAlign = 'right';
      el.style.paddingRight = '0.2em';
      el.innerHTML      = string;  //Firefox renders \n linebreak
      el.innerText      = string; //IE6 renders \n line break
      el.style.zIndex   = 0;
      ta.style.zIndex   = 1;
      ta.style.position = "relative";
      ta.parentNode.insertBefore(el, ta.nextSibling);
      setLine();
      ta.focus();
 
      ta.onkeydown    = function() { setLine(); }
      ta.onmousedown  = function() { setLine(); }
      ta.onscroll     = function() { setLine(); }
      ta.onblur       = function() { setLine(); }
      ta.onfocus      = function() { setLine(); }
      ta.onmouseover  = function() { setLine(); }
      ta.onmouseup    = function() { setLine(); }
           
     function setLine(){
       el.scrollTop   = ta.scrollTop;
       el.style.top   = (ta.offsetTop) + "px";
        el.style.left  = (ta.offsetLeft - 27) + "px";
     }
    }

    </script>
</head>
<body>
  <h2>TextArea Line Numbers Demo</h2>
  <form name=form1 id=form1 action='' method=post>
    <textarea name="editContent" id="editContent">
     aaaaaaaaa aaaaa aaaaaaa
        BBBBBBB
        cccc
        DDDDDDD
        eeeeee
        FFFFFFF
        ggggggg
        HH HHHHHH  hhHHHH hhhhh HHHH
        IIII iiiiiiii iii iiiii IIIIIIIIIII
        JJJJJJ jjjjjjj JJJJJJJJJJJ jjjjjjjjjjj
      aaaaaa www w qqqqqqqqqq aaa
  </textarea>
   <script type="text/javascript">createTextAreaWithLines('editContent');</script>
  </form>
</body>
</html>
straightPete
 
Posts: 3
Joined: Sat Jul 29, 2006 9:27 pm

TextArea with Line Numbers

Postby straightPete » Sun Jul 30, 2006 11:29 am

For script above you also need to set 'wrap=off' in the main html textarea tag. CSS 'white-space' doesn't seem to work for this.
straightPete
 
Posts: 3
Joined: Sat Jul 29, 2006 9:27 pm

Postby Batalf » Sun Jul 30, 2006 11:56 am

Hello Pete :)

I just want to say thank you for sharing your code. Keep it comming :D
Batalf
Site Admin
 
Posts: 2160
Joined: Sat Oct 22, 2005 9:38 pm

Postby straightPete » Thu Aug 03, 2006 10:43 am

A pleasure. Haven't fiddled with javascript for a few years so nice to catch up on all the new methods available.
straightPete
 
Posts: 3
Joined: Sat Jul 29, 2006 9:27 pm

Postby angrycamel » Fri Aug 04, 2006 4:07 pm

Great bit of code guys. I really like the second one that was posted, however I made a slight modification to make the scrolling of the line numbers be active as you scroll.

One thing that is really missing is support forthe mouse's scroll wheel. I have been unsuccessful in getting the scroll wheel to trigger any of the events.

You only really need four of the events as far as I can tell.
Code: Select all

        ta.onkeydown    = function() { setLine(); }
        ta.onmousedown  = function() { setLine(); move=true; }
        ta.onmouseup    = function() { setLine(); move=false; }
        ta.onmousemove  = function() { if(move){setLine();} }

Code: Select all
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
  <title>TextArea Line Numbers Demo</title>
    <style>
      html {font:normal 76% verdana, arial, san serif;}
      body {padding:2em;}
      h2 {font-size:1.8em; padding:0.5em; background:#44aaff;}
      textarea {font-size:100%;}
      #editContent{
          margin-left:30px;
          padding-left:3px;
          width:600px;
          height:200px;
          border:1px solid #666;
      }
     .textAreaWithLines{
         display:block;
         margin:0;
         border:1px solid #666;
         border-right:none;
         background:#aaa;
      }
    </style>
    <script type="text/javascript">
       var move = false;
      function createTextAreaWithLines(id)
      {
        var el = document.createElement('TEXTAREA');
        var ta = document.getElementById(id);
       
        var string = '';
        for(var no=1;no<300;no++){
          if(string.length>0)string += '\n';
          string += no;
        }
       
        el.className      = 'textAreaWithLines';
        el.style.height   = (ta.offsetHeight-3) + "px";
        el.style.width    = "25px";
        el.style.position = "absolute";
        el.style.overflow = 'hidden';
        el.style.textAlign = 'right';
        el.style.paddingRight = '0.2em';
        el.innerHTML      = string;  //Firefox renders \n linebreak
        el.innerText      = string; //IE6 renders \n line break
        el.style.zIndex   = 0;
        ta.style.zIndex   = 1;
        ta.style.position = "relative";
        ta.parentNode.insertBefore(el, ta.nextSibling);
        setLine();
        ta.focus();
       
        ta.onkeydown    = function() { setLine(); }
        ta.onmousedown  = function() { setLine(); move=true; }
        ta.onmouseup    = function() { setLine(); move=false; }
        ta.onmousemove  = function() { if(move){setLine();} }
             
        function setLine(){
          el.scrollTop   = ta.scrollTop;
          el.style.top   = (ta.offsetTop) + "px";
          el.style.left  = (ta.offsetLeft - 27) + "px";
        }
      }
    </script>
</head>
<body>
  <h2>TextArea Line Numbers Demo</h2>
  <form name=form1 id=form1 action='' method=post>
    <textarea name="editContent" id="editContent">
       aaaaaaaaa aaaaa aaaaaaa
        BBBBBBB
        cccc
        DDDDDDD
        eeeeee
        FFFFFFF
        ggggggg
        HH HHHHHH  hhHHHH hhhhh HHHH
        IIII iiiiiiii iii iiiii IIIIIIIIIII
        JJJJJJ jjjjjjj JJJJJJJJJJJ jjjjjjjjjjj
      aaaaaa www w qqqqqqqqqq aaa
      ad
      fdfg
      d
      fgsdfgsdfgsdf
      gsdfgsdfgds
      gsdfgsdfgsdfg
      sdfgsdfgsdf
      gsdfgsdfgsdf
      gsdfgsdfgsd
      sdgfsdgsd
      gsdfg
      sdfg
      sdfgsdf
      gsdf
      gsd
      fg
      sdgfsdfgsd
      gsdfg 
  </textarea>
   <script type="text/javascript">createTextAreaWithLines('editContent');</script>
  </form>
</body>
</html>
angrycamel
 
Posts: 1
Joined: Fri Aug 04, 2006 4:04 pm
Location: projectmimesis.com

Postby ejunker » Thu Sep 14, 2006 8:01 pm

I need to have my textarea in a table. When I try this code with the textarea in a table it works in Firefox but not in IE. Is there an easy way to fix it?
ejunker
 
Posts: 3
Joined: Thu Sep 14, 2006 8:00 pm

Postby Batalf » Thu Sep 14, 2006 8:25 pm

If you call the function which init the script before </table>, MOVE it after the </table>

i.e.

NOT

Code: Select all
<script type="text/javascript">createTextAreaWithLines('editContent');</script>
</TABLE>


but

Code: Select all
</TABLE>
<script type="text/javascript">createTextAreaWithLines('editContent');</script>
Batalf
Site Admin
 
Posts: 2160
Joined: Sat Oct 22, 2005 9:38 pm

Postby ejunker » Thu Sep 14, 2006 8:33 pm

Batalf wrote:If you call the function which init the script before </table>, MOVE it after the </table>


Thanks! Now it works fine in IE
ejunker
 
Posts: 3
Joined: Thu Sep 14, 2006 8:00 pm

Postby ejunker » Wed Sep 27, 2006 10:35 pm

Thought some of you might find this example useful. They use a background image instead of a textarea to create line numbers.

http://syntaxhighlighting.blogspot.com/index.html
ejunker
 
Posts: 3
Joined: Thu Sep 14, 2006 8:00 pm

Postby mezich » Fri Aug 10, 2007 8:41 pm

angrycamel wrote:One thing that is really missing is support forthe mouse's scroll wheel. I have been unsuccessful in getting the scroll wheel to trigger any of the events.


Add ta.onscroll = function() { setLine(); }
But it will works only in IE
mezich
 
Posts: 1
Joined: Fri Aug 10, 2007 8:39 pm

Next

Return to Request/Suggest a script by posting in this thread

Who is online

Users browsing this forum: No registered users and 1 guest

cron