SitePoint Sponsor

User Tag List

Results 1 to 7 of 7
  1. #1
    SitePoint Evangelist
    Join Date
    Jun 2005
    Posts
    436
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Partially Restricting a TextArea

    I need to partially restrict a textarea.

    I currently have something that says "Please start your answer with 'The answer to life is...'" and there is a textarea underneath. Unfortunately, people aren't reading my directions and constantly try to submit my form without the proper starting phrase. I have a PHP string check in place to stop the submission, but I've had tons of complaints about the form so I want a better way.

    I want my textarea to have the text already inside, and I want to restrict a user from editing that portion of the textarea.

    So, when a user comes to my textarea, it will be partially filled in saying "The answer to life is " and then the user must continue from there.

    One of my ideas is to check after each keypress if the starting string is still in place, and if not put it back in place. I'm a little worried about lag, though.

    What are your ideas for pulling this off? No need for code, just ideas.

    Thanks,
    e39m5

  2. #2
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,718
    Mentioned
    103 Post(s)
    Tagged
    4 Thread(s)
    You could check the position of the insertion point and not allow it to pass into the area where the protected wording occurs.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  3. #3
    SitePoint Evangelist
    Join Date
    Jun 2005
    Posts
    436
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    This has been fun. I have one quirk, I'm going to post a code snippet when I get home, hoepfully somebody can help out. Surprisingly, it's the same issue in FF and IE, and I have a feeling the solution will be the same for both.

    e39m5

  4. #4
    SitePoint Evangelist
    Join Date
    Jun 2005
    Posts
    436
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Code HTML4Strict:
    <html>
    <head>
    <script type='text/javascript'>
    Code JavaScript:
    var valCache = new Array();
    valCache["answers"] = "Hello my n";
    function restrictTextarea(textarea,restrictPoint,startVal){
     
    	//Ahh, our starting string was changed somehow.  Lets undo
    	if(textarea.value.substr(0,restrictPoint) == startVal){
     
    		valCache[textarea.id] = textarea.value;
     
    	} else {
     
    		textarea.value = valCache[textarea.id];
    		return false;
     
    	}
     
    	var startPoint = 0;
    	var endPoint = 0;
    	var selected_text = "";
     
    	var IE = 0;
     
        if(textarea != null) {
     
            //First, find the start and end points and the selection
            if(textarea.createTextRange) {
            	IE = 1;
    			//Thanks to [url]http://linebyline.blogspot.com/2006/11/textarea-cursor-position-in-internet.html[/url]
    			var selection_range = document.selection.createRange().duplicate();
     
    			if (selection_range.parentElement() == textarea) {    // Check that the selection is actually in our textarea
     
    				// Create three ranges, one containing all the text before the selection,
    				// one containing all the text in the selection (this already exists), and one containing all
    				// the text after the selection.
    				var before_range = document.body.createTextRange();
    				before_range.moveToElementText(textarea);                    // Selects all the text
    				before_range.setEndPoint("EndToStart", selection_range);     // Moves the end where we need it
     
    				var after_range = document.body.createTextRange();
    				after_range.moveToElementText(textarea);                     // Selects all the text
    				after_range.setEndPoint("StartToEnd", selection_range);      // Moves the start where we need it
     
    				var before_finished = false, selection_finished = false, after_finished = false;
    				var before_text, untrimmed_before_text, selection_text, untrimmed_selection_text, after_text, untrimmed_after_text;
     
    				// Load the text values we need to compare
    				before_text = untrimmed_before_text = before_range.text;
    				selection_text = untrimmed_selection_text = selection_range.text;
    				after_text = untrimmed_after_text = after_range.text;
     
    				// Check each range for trimmed newlines by shrinking the range by 1 character and seeing
    				// if the text property has changed.  If it has not changed then we know that IE has trimmed
    				// a \r\n from the end.
    				do {
    				  if (!before_finished) {
    					  if (before_range.compareEndPoints("StartToEnd", before_range) == 0) {
    						  before_finished = true;
    					  } else {
    						  before_range.moveEnd("character", -1)
    						  if (before_range.text == before_text) {
    							  untrimmed_before_text += "\r\n";
    						  } else {
    							  before_finished = true;
    						  }
    					  }
    				  }
    				  if (!selection_finished) {
    					  if (selection_range.compareEndPoints("StartToEnd", selection_range) == 0) {
    						  selection_finished = true;
    					  } else {
    						  selection_range.moveEnd("character", -1)
    						  if (selection_range.text == selection_text) {
    							  untrimmed_selection_text += "\r\n";
    						  } else {
    							  selection_finished = true;
    						  }
    					  }
    				  }
    				  if (!after_finished) {
    					  if (after_range.compareEndPoints("StartToEnd", after_range) == 0) {
    						  after_finished = true;
    					  } else {
    						  after_range.moveEnd("character", -1)
    						  if (after_range.text == after_text) {
    							  untrimmed_after_text += "\r\n";
    						  } else {
    							  after_finished = true;
    						  }
    					  }
    				  }
     
    				} while ((!before_finished || !selection_finished || !after_finished));
     
    				// Untrimmed success test to make sure our results match what is actually in the textarea
    				// This can be removed once you're confident it's working correctly
    				var untrimmed_text = untrimmed_before_text + untrimmed_selection_text + untrimmed_after_text;
    				var untrimmed_successful = false;
    				if (textarea.value == untrimmed_text) {
    				  untrimmed_successful = true;
    				}
    				// ** END Untrimmed success test
     
    				startPoint = untrimmed_before_text.length;
    				endPoint = startPoint + untrimmed_selection_text.length;
    				selected_text = untrimmed_selection_text;
     
    			}
     
            } else {
     
            	startPoint = textarea.selectionStart;
            	endPoint = textarea.selectionEnd;
            	selected_text = textarea.innerHTML.substr(startPoint,(endPoint-startPoint));
     
            }
     
    		if(selected_text == ""){ //Was a selection made, or just the cursor moved?
     
    			//Just a cursor move, lets make sure its after our restrict point
    			if(startPoint<restrictPoint){
     
    				if(IE == 1){
    					var newrange = textarea.createTextRange();
    					newrange.move("character", restrictPoint);
    					newrange.select();
    				} else {
    					textarea.setSelectionRange(restrictPoint, restrictPoint);
    				}
     
    			}
     
    		} else {
     
    			//Just a cursor move, lets make sure its after our restrict point
    			if(startPoint<restrictPoint){
     
    				if(IE == 1){
    					var newrange = textarea.createTextRange();
    					newrange.moveStart("character", restrictPoint);
    					newrange.select();
    				} else {
    					textarea.setSelectionRange(restrictPoint, endPoint);
    				}
     
    			}
     
    		}
     
            //document.getElementById('current').innerHTML = ("Start Index: " + startPoint + "<br>End Index: " + endPoint + "<br>Selected Text\n'" + selected_text + "'");
        }
     
    }
    Code HTML4Strict:
    </script>
    </head>
    <body>
     
    <textarea id='answer'
    	onFocus='restrictTextarea(this,10,"Hello my n");'
    	onKeyPress='restrictTextarea(this,10,"Hello my n");'
    	onMouseUp='restrictTextarea(this,10,"Hello my n");'
    	onKeyUp='restrictTextarea(this,10,"Hello my n");'
    	onSelect='restrictTextarea(this,10,"Hello my n");'>Hello my name is </textarea>
    </body>
    <html>

    Try and get it to not say "Hello my n"

    It almost works 100%, I've only noticed one problem. If you highlight text you can drag it into the restricted area without automatically undo-ing. Any ideas to fix this?

    Thanks,
    e39m5

  5. #5
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,718
    Mentioned
    103 Post(s)
    Tagged
    4 Thread(s)
    You could do something about that if you use a setTimeout function to regularly monitor the text field.
    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 2005
    Posts
    436
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Is there way to reduce the number of times the event fires? It seems liek it fires more than once on each event ( I threw some tracking in there)

    Is setTimeout the only solution? No event fires after a drag and drop?

    e39m5

  7. #7
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,718
    Mentioned
    103 Post(s)
    Tagged
    4 Thread(s)
    No, there isn't that fine-grained control of the web browser.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript


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
  •