質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

2回答

8861閲覧

Javascriptによるテーブル内の任意のセル内テキストの編集

smiley-_-smiley

総合スコア26

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

0クリップ

投稿2015/10/24 06:57

編集2015/10/24 23:05

HTMLとJavascriptで、テーブルのセル内のテキストをモーダルウィンドウ内で編集し、
編集後の内容を元のテキストと置き換えるスクリプトを作成しています。

・テーブル内の任意のセル内をクリックするとモーダルウィンドウが表示される
・モーダルウィンドウ内でテキストを編集し確定ボタンを押下すると、元のセルの内容を置換する
・モーダルウィンドウ内でキャンセルボタンを押下すると、ウィンドウを閉じる
・セルにIDを振ることはできない
・テーブルの行、列は任意に増やすことができる

以下のように作成したところ、編集を繰り返すごとに、それまで編集したセルが
すべて置き換わってしまいました。
セルをクリックする度に、対象のセルが累積していく様子です。

原因としては、テーブルセルのclickイベント内に保存ボタンのイベント処理が
あることだと思うのですが、外に出した場合、クリック元のセルを取得する方法が分かりません。

どなたか助けていただけないでしょうか。
jquery-1.7.2.js

javascript

1$(function(){ 2 3 //テーブルセル押下で編集モード 4 $('[id^=edit-table] > tbody > tr > td').on('click', function(){ 5 var targetCell = $(this); 6 7 //disable-editorクラスがある場合は編集させない 8 if(!$('[id^=edit-table]').hasClass('disable-editor')){ 9 html = targetCell.html(); 10 //エディタ起動 11 var target = '#td_editor_modal'; //モーダルウィンドウのID 12 activateTdEditor(target, html); //モーダルウィンドウ表示 13 14 //エディタウィンドウの保存ボタン 15 $('#do-save').on('click',function(){ 16 //エディタ内のコンテンツを取得 17 //本来はエディタからの戻り値が入る 18 var content = 'ほげほげ' 19 //モーダルウィンドウを閉じる 20 modalClose('#td_editor_modal'); 21 //元のセルの内容を置換 22 $(targetCell).html(content); 23 }); 24 25 //エディタウィンドウを閉じる 26 $('#modal-close').on('click', function(){ 27 modalClose('#td_editor_modal'); 28 }); 29 30 } 31 32 }); 33});

HTML

1<div id="table-edit-area"> 2 <table id="edit-table-hoihoi" class="table table-bordered"> 3 <tbody> 4 <tr> 5 <td>見出し1</td> 6 <td>見出し2</td> 7 <td>見出し3</td> 8 </tr> 9 <tr> 10 <td>1-1</td> 11 <td>1-2</td> 12 <td>1-3</td> 13 </tr> 14 <tr> 15 <td>2-1</td> 16 <td>2-2</td> 17 <td>2-3</td> 18 </tr> 19 <tr> 20 <td>3-1</td> 21 <td>3-2</td> 22 <td>3-3</td> 23 </tr> 24 </tbody> 25 </table> 26</div> 27 28<!-- セル内編集用ののモーダルウィンドウ --> 29<div id="modal-overlay"></div> 30<div id="td_editor_modal"> 31 <div id="edit_box"></div> 32 33 <div class="btn-control"> 34 <button id="do-save" class="btn btn-primary">保存</button> 35 <button id="modal-close" class="btn btn-primary">キャンセル</button> 36 </div> 37</div> 38

以下を追記いたしました。

javascript

1/*------------------------- 2* エディタ起動 3---------------------------*/ 4function activateTdEditor(target, html){ 5 //モーダルウィンドウ表示位置調整 6 centeringModalPosition(target); 7 //モーダルウィンドウ表示 8 modalOpen(target); 9 10 //エディタ起動 11 $('#edit_box').html(html); 12 //ダミーとして編集したことにする 13 $('#edit_box').append('ああああああ'); 14} 15/*------------------------- 16* モーダルウィンドウを開く 17---------------------------*/ 18function modalOpen(modalId){ 19 $(modalId).css('display', 'block'); 20 $('#modal-overlay').css('display', 'block'); 21} 22 23/*------------------------- 24* モーダルウィンドウを閉じる 25---------------------------*/ 26function modalClose(modalId){ 27 $('#modal-overlay').css('display', 'none'); 28 $(modalId).css('display', 'none'); 29} 30 31/*------------------------- 32* モーダルウィンドウの表示位置調整 33---------------------------*/ 34function centeringModalPosition(modalId){ 35 //画面幅取得 36 var w = $(window).width(); 37 //画面高さ取得 38 var h = $(window).height(); 39 40 //モーダルウィンドウの幅取得 41 var cw = $(modalId).outerWidth(true); 42 //モーダルウィンドウの高さ取得 43 var ch = $(modalId).outerHeight(true); 44 45 46 //モーダルウィンドウの横位置計算 47 var pxleft = ((w - cw)/2); 48 //モーダルウィンドウの縦位置計算 49 var pxtop = ((h - ch)/2); 50 51 $(modalId).css({"left": pxleft + "px"}); 52 $(modalId).css({"top": pxtop + "px"}); 53 54} 55 56function debugPrintIndex(e){ 57 //行番号取得 58 var row = $(e.target).closest('tr').index(); 59 //列番号取得 60 var col = e.target.cellIndex; 61 62 console.log('行:列 = ' + row + ':' + col); 63}

activateTdEditorも自由に変更可能です。
記載したソースではダミーの処理をしていますが、実際のコードでもさほど変わらず、エディタにセル内の値を食わせてエディタ起動しているだけです。

以下動作サンプルです。
●エディタなし版
http://amicolo.net/make-table/index4.html

●エディタあり版
http://amicolo.net/make-table/index5.html

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Lhankor_Mhy

2015/10/24 08:59

activateTdEditor を変更するのが一番簡単だと思うんですが、そちらは可能ですか?
smiley-_-smiley

2015/10/24 23:14 編集

誤って返信のつもりで記載してしまいました。削除できないようなので、本文中に追記します
guest

回答2

0

自己解決

自己解決しました。
クリックイベントを入れ子にした場合に、それまで操作したセルが全部処理される現象は
謎のままですが、とりあえず以下の方法で対応しました。

・クリックしたセルの座標を取得
・モーダルウィンドウ内の非表示要素に座標を文字列として格納
・保存時にウィンドウ内から座標文字列を取得し、対象セルの座標として指定

javascript

1$(function(){ 2 //テーブルセル押下で編集モード 3 $('[id^=edit-table] > tbody > tr > td').on('click', function(e){ 4 var targetCell, html, x, y, selector; 5 6 console.log(targetCell); 7 //disable-editorクラスがある場合は編集させない 8 if(!$('[id^=edit-table]').hasClass('disable-editor')){ 9 html = $(this).html(); 10 console.log('セル内のHTML:'+html); 11 12 //対象セル取得 13 targetCell = getCurentCell(e); 14 15 //エディタ起動 16 var target = '#td_editor_modal'; 17 activateTdEditor(target, html, targetCell); 18 } 19 20 }); 21 22 //エディタウィンドウの保存ボタン 23 $('#do-save').on('click',function(){ 24 25 //エディタ内のコンテンツを取得 26 //本来はエディタからの戻り値が入る 27 var content = $('#edit_box').elrte('val'); 28 console.log('戻り値:'+content); 29 30 //モーダルウィンドウを閉じる 31 modalClose('#td_editor_modal'); 32 33 //対象セルを取得 34 var targetCell = $('#targetCell').text(); // x-y で帰ってくる 35 tmp = targetCell.split('-'); 36 var x = tmp[0]; 37 var y = tmp[1]; 38 selector = '[id^=edit-table] > tbody > tr:eq(' + x + ') > td:eq(' + y + ')'; 39 40 //元のセルの内容を置換 41 $(selector).html(content); 42 }); 43 44 //エディタウィンドウを閉じる 45 $('#modal-close').on('click', function(){ 46 modalClose('#td_editor_modal'); 47 }); 48 49 50}); 51 52/*------------------------- 53* エディタ起動 54---------------------------*/ 55function activateTdEditor(target, html, targetCell){ 56 //モーダルウィンドウ表示位置調整 57 centeringModalPosition(target); 58 //モーダルウィンドウ表示 59 modalOpen(target); 60 //クリックしたセルの座標を格納 61 $('#targetCell').text(targetCell); 62 63 //エディタ起動 64 $('#edit_box').elrte(opts); 65 $('#edit_box').elrte('val', html); 66} 67 68/*------------------------- 69* モーダルウィンドウを開く 70---------------------------*/ 71function modalOpen(modalId){ 72 $(modalId).css('display', 'block'); 73 $('#modal-overlay').css('display', 'block'); 74} 75 76/*------------------------- 77* モーダルウィンドウを閉じる 78---------------------------*/ 79function modalClose(modalId){ 80 $('#modal-overlay').css('display', 'none'); 81 $(modalId).css('display', 'none'); 82} 83 84/*------------------------- 85* モーダルウィンドウの表示位置調整 86---------------------------*/ 87function centeringModalPosition(modalId){ 88 //画面幅取得 89 var w = $(window).width(); 90 //画面高さ取得 91 var h = $(window).height(); 92 93 //モーダルウィンドウの幅取得 94 var cw = $(modalId).outerWidth(true); 95 //モーダルウィンドウの高さ取得 96 var ch = $(modalId).outerHeight(true); 97 98 //モーダルウィンドウの横位置計算 99 var pxleft = ((w - cw)/2); 100 //モーダルウィンドウの縦位置計算 101 var pxtop = (((h - ch)/2))/2; 102 103 $(modalId).css({"left": pxleft + "px"}); 104 $(modalId).css({"top": pxtop + "px"}); 105 106} 107/*------------------------- 108* 対象セルの座標取得 109---------------------------*/ 110function getCurentCell(e){ 111 var row = e.target.parentNode.rowIndex; 112 var col = e.target.cellIndex; 113 var targetCell = row + '-' + col; 114 return targetCell; 115} 116 117 118 119function debugPrintIndex(e){ 120 //行番号取得 121 var row = $(e.target).closest('tr').index(); 122 //列番号取得 123 var col = e.target.cellIndex; 124 125 console.log('行:列 = ' + row + ':' + col); 126 127 var targetCell = [row, col]; 128 return targetCell; 129 130}

HTML

1<div id="table-edit-area"> 2 <table id="edit-table-hoihoi" class="table table-bordered"> 3 <tbody> 4 <tr> 5 <td>見出し1</td> 6 <td>見出し2</td> 7 <td>見出し3</td> 8 </tr> 9 <tr> 10 <td>1-1</td> 11 <td>1-2</td> 12 <td>1-3</td> 13 </tr> 14 <tr> 15 <td>2-1</td> 16 <td>2-2</td> 17 <td>2-3</td> 18 </tr> 19 <tr> 20 <td>3-1</td> 21 <td>3-2</td> 22 <td>3-3</td> 23 </tr> 24 </tbody> 25 </table> 26</div> 27 28<!-- セル内編集用ののモーダルウィンドウ --> 29 30<div id="modal-overlay"></div> 31<div id="td_editor_modal"> 32 <div id="edit_box"></div> 33 34 <div id="targetCell" style="display: none;"></div><!-- ←セルの座標を格納 --> 35 <div class="btn-control"> 36 <button id="do-save" class="btn btn-primary">保存</button> 37 <button id="modal-close" class="btn btn-primary">キャンセル</button> 38 </div> 39</div> 40

投稿2015/10/25 12:08

smiley-_-smiley

総合スコア26

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

moredeep

2015/10/26 01:50

解決済みのようですが。。。 テーブルセルのonclick内で#do-saveのonclickを定義しているのが問題です。 $('hoge').on('click',function(){hogehoge}); 上記のように定義した場合、onclickイベントが"追加"されます。 そのため、いままで定義した全てのonclickイベントが走ってしまっていたのでしょう。 回避方法は、 $(‘hoge’).unbind(‘click’); のように、一度イベントをクリアしてあげればいいはずです。
smiley-_-smiley

2015/10/26 05:56

ありがとうございます。onclikcイベントの入れ子が原因なのはわかっていましたが、回避方法が分かりませんでした。 ご提示いただいたunbindを試してみたのですが、入れる場所の検討がつきませんでした。 解決済みですので、別の質問を上げさせていただきます。
guest

0

Jqueryでクリックされたテーブルの位置(X行X列目)を取得する事ができるようですが、これで解決できますでしょうか?

投稿2015/10/24 11:49

Ken.sakanakana

総合スコア1768

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

smiley-_-smiley

2015/10/24 23:14

操作したセルのインデックスを取得して強制的に書き戻すセルを指定することを試してみましたが、編集→確定を繰り返すと、それまでに操作したセルがすべて反映してしまうようです。 本文中に動作サンプルのURLを記載しました。コンソール上にエディタの編集内容を反映したセルの位置を「行:列 = 0:3」のように出力するようにしています。 操作したエレメントは配列に格納されていくんでしょうか?ループで処理したように動作しています。
Ken.sakanakana

2015/10/25 05:16

jQueryのselectorで eq()を用いてセルの特定が出来ますが、 これで値を変えるというのは如何でしょうか? モーダルウインドウへは x, y の値さえ渡してしまえば、 モーダルウインドウから selector指定は可能かと思いますので。 (試してません・・・) ーーー <script> $(function(){  $('[id=edit-table-hoihoi] > tbody > tr > td').on('click',function(){   y = this.parentNode.rowIndex;   x = this.cellIndex;   selector = "table tr:eq(" + y + ") td:eq(" + x + ")"   $(selector).text("change");  }); }); </script> ーーー $('[id^=edit-table] の所ですが、 $('[id=edit-table-hoihoi] では ないのでしょうか? 例に上げて頂いている中に、#edit-table が ありませんでしたので・・・
smiley-_-smiley

2015/10/25 09:51

ありがとうございます。 >jQueryのselectorで eq()を用いてセルの特定が出来ますが、 >これで値を変えるというのは如何でしょうか? すでに試してみたのですが、だめでした。確かに指定したセルは書き換わるのですが、それまでに操作したセルもすべて書き換わってしまいます。 本文中の動作サンプルでお試しいただくとわかるのですが、以下のような現象が発生します。 1.座標0-0をクリック→編集せずにキャンセル 2.座標2-1をクリック→編集せずにキャンセル 3.座標3-2をクリック→編集して確定 4.3の編集内容が、座標0-0 2-1 3-2 に反映される キャンセルではなく都度確定した場合でも同様に、それまで操作したセルが最後に編集した内容にすべて書き換わってしまいます。 >$('[id^=edit-table] の所ですが、 $('[id=edit-table-hoihoi] では >ないのでしょうか? 例に上げて頂いている中に、#edit-table が >ありませんでしたので・・・ すみません。特に特記することでもないかと思って記載していませんでした。 もともと複数のテーブルが存在しており、テーブルのIDはすべてedit-table-***というIDが振られています。 そのため、セレクタを「edit-tableから始まる」としています。 念のために、$('[id=edit-table-hoihoi] として動作確認してみましたが、状況は変わりませんでした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問