 |
|
|
 |
|
 |
<html> <head> <title>IE?FireFox??textarea????</title> </head> <body> <textarea maxlength="10" onpropertychange="onmyinput(this)" oninput="return onmyinput(this)" onPaste="return onmypaste(this);" onKeyPress="return onmykeypress(this);"></textarea> //??:IE?FireFox??textarea???? //??:???? <script type="text/javascript"> function onmyinput(o) { if(o.value.length>=o.getAttribute("maxlength")) { if(o.value.length>o.getAttribute("maxlength")) o.value = o.value.substring(0,o.getAttribute("maxlength")); return false; } return true; } function mygetclipdata() { if(!document.all) { netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect'); var clip = Components.classes['@mozilla.org/widget/clipboard;1'].createInstance(Components.interfaces.nsIClipboard); var trans = Components.classes['@mozilla.org/widget/transferable;1'].createInstance(Components.interfaces.nsITransferable); trans.addDataFlavor('text/unicode'); var str = Components.classes["@mozilla.org/supports-string;1"].createInstance(Components.interfaces.nsISupportsString); clip.getData(trans,clip.kGlobalClipboard); var str=new Object(); var strLength=new Object(); trans.getTransferData("text/unicode",str,strLength); if (str) str=str.value.QueryInterface(Components.interfaces.nsISupportsString); var pastetext; if (str) pastetext=str.data.substring(0,strLength.value / 2); return pastetext; } else { return window.clipboardData.getData("Text"); } } function mysetclipdata(o) { if(!document.all) { netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect'); var clip = Components.classes['@mozilla.org/widget/clipboard;1'].createInstance(Components.interfaces.nsIClipboard); var trans = Components.classes['@mozilla.org/widget/transferable;1'].createInstance(Components.interfaces.nsITransferable); trans.addDataFlavor("text/unicode"); var str = Components.classes["@mozilla.org/supports-string;1"].createInstance(Components.interfaces.nsISupportsString); str.data=o; trans.setTransferData("text/unicode",str,o.length*2); var clipid=Components.interfaces.nsIClipboard; clip.setData(trans,null,clipid.kGlobalClipboard); } else { window.clipboardData.setData("Text",o); } } function onmypaste(o) { var nMaxLen=o.getAttribute? parseInt(o.getAttribute("maxlength")):""; if(!document.all) { alert("????????"); } else {
if(document.selection.createRange().text.length>0) { var ovalueandclipboarddata = o.value +window.clipboardData.getData("Text"); if(o.getAttribute && ovalueandclipboarddata.length-document.selection.createRange().text.length>nMaxLen) { if(window.clipboardData.getData("Text").substring(0,document.selection.createRange().text.length+nMaxLen-o.value.length)!="") window.clipboardData.setData("Text",window.clipboardData.getData("Text").substring(0,document.selection.createRange().text.length+nMaxLen-o.value.length)); else return false; } } else { var ovalueandclipboarddata = o.value +window.clipboardData.getData("Text"); if(o.getAttribute && ovalueandclipboarddata.length>nMaxLen) { if(ovalueandclipboarddata.substring(0,nMaxLen-o.value.length)!="") window.clipboardData.setData("Text",ovalueandclipboarddata.substring(0,nMaxLen-o.value.length)); else return false; } } return true; } } function onmykeypress(o) { if(!document.all) { var nMaxLen=o.getAttribute? parseInt(o.getAttribute("maxlength")):"";
if(onmykeypress.caller.arguments[0].ctrlKey == true) { if(onmykeypress.caller.arguments[0].which==118) {
if(o.selectionStart<o.selectionEnd) { var ovalueandclipboarddata = o.value + mygetclipdata(); if(o.getAttribute && (ovalueandclipboarddata.length-o.selectionEnd + o.selectionStart>nMaxLen)) { if(mygetclipdata().substring(0,o.selectionEnd - o.selectionStart+nMaxLen-o.value.length)!="") mysetclipdata(mygetclipdata().substring(0,o.selectionEnd - o.selectionStart+nMaxLen-o.value.length)); else return false; } } else { var ovalueandclipboarddata = o.value +mygetclipdata(); if(o.getAttribute && ovalueandclipboarddata.length>nMaxLen) { if(ovalueandclipboarddata.substring(0,nMaxLen-o.value.length)!="") mysetclipdata(ovalueandclipboarddata.substring(0,nMaxLen-o.value.length)); else return false; } } return true;
} }
if(onmykeypress.caller.arguments[0].which==0 || onmykeypress.caller.arguments[0].which==8) return true; if(o.value.length>=o.getAttribute("maxlength")) { if(o.selectionStart<o.selectionEnd) return true; if(o.value.length>o.getAttribute("maxlength")) o.value = o.value.substring(0,o.getAttribute("maxlength")); return false; } else return true; } else { if(document.selection.createRange().text.length>0) return true; if(o.value.length>=o.getAttribute("maxlength")) return false; else return true; } } </script> </body> </html>
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Thanx Yen It worked for me as i required alert message as well, at the time max length limit exceeds , Initially it has some Issue with IE, but it has been solved by calling the javascript functions on the .aspx page within script tag.
It's coool.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
1) The OnPaste approach cannot be cross-brower, although oninput (gecko) can emulate Onpaste (IE), by complaring previousValue and Value, and selectionStart/selectionEnd (gecko) can emulate getSelection or selection.createRange (IE), BUT NOT clipboardData(IE) due to security reasons. So theres actually no solution for Paste until some fix in the current html specification.
2) Returning False on Keypress/Keydown cannot be an approach as it will cause problem when u try to highlight some longer text and replacing with a char. U can workaround this by detecting if theres any Characters Highlighted by using selectionstart/selectionend for Chrome and FireFox and selection for IE. If the KeyCode is 13 (newline), make sure the characters highlighted is more than 1 char.
- It will also cause problem when u are using a Language Bar. U can workaround this using keypress for Normal characters, while keyUp for other foreign languages. In Firefox/IE/Chrome, Language Bar input event will not be detected by KeyPress but KeyUp or Keydown.
- It will also cause problem if u didnt check for keyCode for Tab, Backspace, arrows. (8,9,46,47,48,49 if i didnt recall wrongly)
3) Database support. Remember to use Nvarchar instead of varchar as some characters will take up 1 length in Input and store as 2 length in Database. Using RegEx in .NET Validation, one may consider the difference in the Length for newline. '/n' for Gecko based browser for newline while '/r/n' for IE, but may not be necessary as the Database will save what it see in Input. still it is a good practise.
Considering all the problems especially the PASTING constraint. There's no way to make a TextArea behaving like a Textbox. The only fleasible solution is to: - allow user to key whatever they want, while u display the "Characters Remaining: 100". For .net can use the customvalidator with regex and for javascript u can also try to catch event during KeyUp,OnFocus,OnChange,Oninput,Onpaste. - Optional to always truncate substring ur textarea on KeyUp (wont work with KeyDown/KeyPress) so the users will understand no matter how hard they try to type or copypaste, their extra characters will vanish. - Optional to prompt users during onsubmit/save. - truncate the extra characters before u save to database or files. - While we all think there's a solution, i will like to point out that even big player like Youtube also need to do ths but Youtube never catch event during Paste and ctrl-V. They can really catch it with oninput or onpaste for perfection.
modified on Friday, December 12, 2008 8:40 AM
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
This isn't fancy, but only takes a couple of minutes to drag and drop!
<asp:textbox id="txtMLTB" cssclass="tb" textmode="MultiLine" runat="server" xmlns:asp="#unknown"> <asp:regularexpressionvalidator id="regExMLTB" runat="server" controltovalidate="txtMLTB" xmlns:asp="#unknown"> Display="Dynamic" ErrorMessage="* no more than 400 chars." ValidationExpression="[\s\S]{0,400}$">
http://www.joegakenheimer.com[^]">http://www.joegakenheimer.com
|
| Sign In·View Thread·PermaLink | 3.83/5 (4 votes) |
|
|
|
 |
|
 |
I really like the custom control and had it working perfectly until ... I put my gridviews into separate AJAX update panels. Now I get JS errors. Any ideas?
Thanks.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Not trying to make you feel silly or anything but did you adjust your script to handle the INamingContainer that the update panel implements? (i.e. if the textbox id was myTextBox and the update panel id was myUpdatePanel then the final client id outputted to the browser would be myUpdatePanel_myTextBox)
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
 |
I think I've cracked the Firefox issues.
function doKeypress(controlId, e){
var charCode; if(window.ActiveXObject) { charCode = (event.charCode) ? event.charCode : ((event.keyCode) ? event.keyCode : ((event.which) ? event.which : 0)); } else { charCode = (e.charCode) ? e.charCode : ((e.keyCode) ? e.keyCode : ((e.which) ? e.which : 0)); } if (charCode != 8 && charCode !=46) { var control = document.getElementById(controlId); maxLength = control.attributes["maxLength"].value; value = control.value; if(maxLength) { maxLength = parseInt(maxLength); if(value.length > maxLength-1){ return false; } } } return true; }
function doBeforePaste(controlId){ var control = document.getElementById(controlId); maxLength = control.attributes["maxLength"].value; if(maxLength) { return false; } }
function doPaste(controlId){ var control = document.getElementById(controlId); maxLength = control.attributes["maxLength"].value; value = control.value; if(maxLength){
maxLength = parseInt(maxLength); var oTR = control.document.selection.createRange(); var iInsertLength = maxLength - value.length + oTR.text.length; var sData = window.clipboardData.getData("Text").substr(0,iInsertLength); oTR.text = sData; return false; } }
and
Attributes.Add("onkeypress", string.Format("return doKeypress('{0}', event);", ClientID)); Attributes.Add("onbeforepaste", string.Format("return doBeforePaste('{0}', event);", ClientID)); Attributes.Add("onpaste", string.Format("return doPaste('{0}', event);", ClientID)); Attributes.Add("maxLength", this.MaxLength.ToString());
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
 |
This is a decent example but there is one huge problem using this validation when working with databases. In IE your validation will work fine and limit the text to the desired length; however, in Firefox you can potentially get up to two times the desired length. If you insert a new line by hitting the enter key, then the counter will jump by two digits in Internet Explorer and only one in Mozilla Firefox. The newline character for textarea fields are generally represented by "\n\r". This poses a problem with database security and validation when making sure that the value of the textarea does not exceed the allocated space for the corresponding field in the database. The database reads "\n\r" as two characters. The fix for this is to make sure all new line characters are counted the same using javascript. I'm sure there's a better way but here's my solution:
function FixNewLine(foo) { if(foo.indexOf('\r\n') != -1) { } else if(foo.indexOf('\r') != -1) { foo = foo.replace(/\r/g, "\r\n"); } else if(foo.indexOf('\n') != -1) { foo = foo.replace(/\n/g, "\r\n"); } else { } return foo.length; }
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
 |
That's cool, but I think the problem will come in non-ie browsers when they try to paste with the mouse. If I recall, they don't all support onpaste event so you'll probably have to be a little obtrusive and cut off the end or something if they pasted something too long and then the text area loses focus or onmousedown/up.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
 |
Is there any reason why this control doesn't work when I wrap a GridView and DetailsView in an UpdatePanel? Outside of that, this works great, but since I have a fair amount of UpdatePanels, I can't use it.
-j
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hi, your work was very helpfull, but i'm trying to make it work and have problems with the paste part.
The function doBeforePaste gets the maxLength attribute and asks:
if(maxLength)
That will allways be true because our limit will allways be > 0 and this will allways cancel the paste event. So what is supposed to be controled here and why you have double checks for the paste event? (I mean doBeforePaste and doPaste as the 'paste' event)
Maybe this function (doBeforePaste) have to be replaced by doPaste. Is that the way it is? Thanks!
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
 |
|
|
 |
|
 |
Iterations are generally a slow approach and this will read all the textboxes un-necessarily.
In our case, we just need to add a line in WEB.CONFIG and use
Yen
|
| Sign In·View Thread·PermaLink | 1.00/5 (1 vote) |
|
|
|
 |
|
 |
Well, each solution has its pro and cons. The solution I mentioned above, lets you exactly mention the multi-line Text-Box you want to length-check without any iteration. You could also specify just the Detail-View control and would only iterate through few textboxes... Also I don't know how much more effective custom controls are for each multi-line control, if there are many. Again, this is matter of taste, and as I wrote, I liked your article and it surely has its applications.
++ life is cool!
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
This article was very good. However, how would it be, if the textbox can have a property called, email and clicking on the textbox should result in opening the default email-client(say outlook) on the client side.
Thanks, Chakri
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
I liked the solution . Just one thing. This thing will not work on FireFox or Safari, since it does not use standard JavaScript. In all your JavaScript functions, you accept a reference to the control. While it works under IE (such a good browser ) it doesn't work on other browsers (bad animals )
You can send the control ID in the JavaScript functions and in the function, you can do something like
function myFunction(controlID) { myControl = document.getElementById(controlID) }
and then use myControl for further operations.
Deobrat Singh
Software Engineer, HCL Technologies Ltd. Mumbai, India
Education is what survives when what has been learned has been forgotten. - B. F. Skinner
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Even with this enhancement it's still not working. Seems that "event.returnValue = false" does nothing. I tried
var browser=navigator.appName if( browser == "Microsoft Internet Explorer" ) event.returnValue = false; else return false;
and no luck.
You can't have everything...Where would you put it?
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Maybe you could try something like this:
function doKeypress(controlID, evt){ control = document.getElementById(controlID); maxLength = control.attributes["maxLength"].value; value = control.value; if(maxLength && value.length > maxLength-1){ if (typeof event != "undefined") evt.returnValue = false; else if ((evt.keyCode != 8 && evt.keyCode != 46)) evt.preventDefault(); maxLength = parseInt(maxLength); } }
Also add the event parameter:
Attributes.Add("onkeypress", "doKeypress('" + this.ClientID + "', event);"); Attributes.Add("onbeforepaste", "doBeforePaste('" + this.ClientID + "', event);"); Attributes.Add("onpaste", "doPaste('" + this.ClientID + "', event);");
|
| Sign In·View Thread·PermaLink | 5.00/5 (2 votes) |
|
|
|
 |