• 締切済み

javaScript textareaの一行あたりの入力文字数制限につ

javaScript textareaの一行あたりの入力文字数制限について 1行あたり5文字しか入力できないtextareaを作成中です。 http://okwave.jp/qa/q1311128.html をアレンジして、自分で以下にように作ってみました。 これだと、最終行が5文字以上の場合は折り返して次以降の行に表示されるのですが、 最終行以外の途中の行に文字列を足すと、その分は、折り返して表示されません。(なくなってしまう)。 また、最終行にカーソルで移動して文字列を追加をすることはできますが、空白行(何も入力しない行)を入れることができません。 使い勝手は普通のテキストエリアと同じで、5文字入力すると自動的に改行するようなものを目指しているのですが、自分であーでもない、こーでもないといろいろやってみてもなかなかうまく行きません。。 なんとか、皆様のお知恵を拝借できないでしょうか。 なお、ブラウザはIEのみに対応でOKです。 よろしくお願いします。 ******************************************* 呼び出し元 ******************************************* (略) <tr> <td class="itemLabelBtm"> フリー入力欄 </td> <td class="display" colspan=""> <textarea cols="85" rows="4" name="memo" onkeypress="lineCheck();" style="overflow:auto" wrap="OFF"></textarea> <br> &nbsp;<font color="red">※1行には44文字まで入力できます。</font> </td> </tr> (略) ******************************************* スクリプト部分 ******************************************* function lineCheck(e){ var ta=document.getElementById("memo"); //一行に入力できる文字数 var col=5; //最後の改行をトリムする。 ta.value = ta.value.replace(/[\r\n]+$/,"") var lines=trim(ta.value).split("\r\n"); for(var i=0;i<lines.length;i++){ if(lines[i].length >col){ var temp = lines[i]; var tempLength = lines[i].length; lines[i]=lines[i].substr(0,col);//各行を指定した文字数に切り捨てる //最後の一行だけは、余った分を次の行に振り替える。 if(i==lines.length-1){ //何回振替を行えばよいか、計算する。 var furikaeNum = Math.ceil((tempLength - col)/col); var j; for(j = 1;j <= furikaeNum; j++){ lines[i + j] = temp.substring(col*j,col*(j+1)); } break; } } } ta.value=lines.join("\r\n"); } /*=================================================== 文字列両端の空文字トリミング ===================================================*/ function trim(str){ return str.replace(/^[  ]+/,"").replace(/[  ]+$/,""); }

みんなの回答

  • l27074
  • ベストアンサー率100% (5/5)
回答No.1

難しいですね。 キャレット位置の保存等必要なんでしょうね。 途中で挫折しました。 が、以下、何かの参考になれば。 呼出をonkeyupに変更してます。 onkeypressだと入力した文字がvalueに入る前に呼ばれてる?っぽいので。(IE9だからかも) <script> var before; function lineCheck(ta) { var text = ta.value; if (before == text) { return; } before = text; var col = 5; var lines = text.split('\r\n'); var result = new Array(); for (var i = 0, m = lines.length; i < m; i++) { if (lines[i].length == 0) { result.push(''); } else { for (var j = 0, n = lines[i].length; j * col < n; j++) { result.push(lines[i].substr(j * col, col)); } } } ta.value = result.join('\r\n'); } </script> <textarea cols="85" rows="4" name="memo" onkeyup="lineCheck(this)" style="overflow:auto" wrap="OFF"></textarea>

jamajamabo
質問者

お礼

ご回答ありがとうございます(泣)。 キャレット位置ですか。 うーん、けっこう複雑になりそうですね。 でもヒントになりました! コードも載せていただいてありがとうございます。 日本語変換を確定したあと、もう一回Enterキーを押さずに改行しているところとか、良いインスピレーションをいただけました。 実装フェーズまでにはもう少し時間があるので、地道にねばってみます。 本当にありがとうございました!

jamajamabo
質問者

補足

その後、参考にしたURLも載せておきます。 ■入力欄の文章を一定字数で強制改行するプログラム http://www.interq.or.jp/engineer/umechan/tips/35.htm ■文字数のお知らせ http://www.seasonsolution.jp/system/archive/08-07-31.html ■テキストボックス内のカーソル(キャレット)位置や選択範囲を,JavaScriptで取得・設定する方法 http://d.hatena.ne.jp/language_and_engineering/20090225/p1 ちなみにその後のわたしのプログラムは、以下のようになっています。 仕様を変更?妥協?して、ボタンを新たに一つ作り、それを押下すると改行するようになっています。 また、最終行だけでなく途中の行に文字列を追加しても消えずに改行するようにしました。 空白行も入ります。 まだまだなプログラムですが、l27074さんにいただいたインスピレーションのおかげで少しはすっきりしたでしょうか。 何かお知恵のある方、どうか教えてください! ******************************************* 呼び出し元 ******************************************* (略) <tr> <td class="itemLabelBtm"> フリー入力欄 </td> <td class="display" colspan=""> <textarea cols="85" rows="4" name="memo" style="overflow:auto" wrap="OFF"></textarea> <br> &nbsp;<font color="red">※1行には5文字まで入力できます。</font> <input type="button" name="test" onclick="lineCheck();showValue();" value="イメージ"> </td> </tr> (略) ******************************************* スクリプト部分 ******************************************* //イメージボタンを押下すると、alertでテキストエリアの値を表示します。 function showValue(){ var str=window.document.forms[0].memo.value; alert(str); } //イメージボタンを押下すると、テキストエリアの値を1行5文字で改行します。 function lineCheck(){ var ta = window.document.forms[0].memo; //一行の文字数指定 var col=5; var lines=ta.value.split("\r\n"); var newIndex = 0; var newValue = new Array(); for(var i=0;i<lines.length;i++){ if(lines[i].length ==0){ newValue[newIndex] = lines[i]; newIndex++; }else{ //余った分を次の行に振り替える。 //何回振替を行えばよいか、計算する。 var furikaeNum = Math.ceil((lines[i].length)/col); var j; for(j = 0;j < furikaeNum; j++){ newValue[newIndex] = lines[i].substring(col*j,col*(j+1)); newIndex++; } } } ta.value=newValue.join("\r\n"); //BLUEPIXYさんありがとう。 //l27074さんありがとう。 }

関連するQ&A