実現したいこと
テーブル上で動作するコンテキストメニューを用いて、右クリックされたテーブル行に対し「行追加」,「行削除」の機能を実現したいです。
発生している問題・分からないこと
以下サンプルの一部を修正し、もとからある行に対する「行追加」,「行削除」の機能は実現できたのですが、動的に生成された行に対してはコンテキストメニューが動作せず、「行追加」,「行削除」ができない状態です。
動的に生成された行に対しても、本機能を実現するための修正方針等、ご教示お願いいたします。
サンプル:https://jsfiddle.net/dmitry_far/cgqft4k3/
該当のソースコード
index.html
1<!DOCTYPE html> 2<html> 3<head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6</head> 7<style> 8 table { 9 border-collapse: collapse; 10 } 11 th,td { 12 border: solid 1px; 13 width: 300px; 14 height: 80px; 15 } 16 ul { 17 width: 120px; 18 height: 60px; 19 background-color: rgb(97, 97, 224); 20 list-style: none; 21 } 22</style> 23<body> 24 <table id="myTable" class="table table-hover"> 25 <thead> 26 <tr> 27 <th>#</th> 28 <th>First Name</th> 29 <th>Last Name</th> 30 </tr> 31 </thead> 32 <tbody> 33 <tr> 34 <td>1</td> 35 <td>Mark</td> 36 <td>Otto</td> 37 </tr> 38 <tr> 39 <td>2</td> 40 <td>Jacob</td> 41 <td>Thornton</td> 42 </tr> 43 <tr> 44 <td>3</td> 45 <td>Larry</td> 46 <td>the Bird</td> 47 </tr> 48 </tbody> 49 </table> 50 <ul id="contextMenu" class="dropdown-menu" role="menu" style="display:none" > 51 <li><a tabindex="-1" href="#" value="menu1:action-1">Add Row</a></li> 52 <li><a tabindex="-1" href="#" value="menu1:action-2">Delete Row</a></li> 53 </ul> 54 <script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script> 55 <script> 56 (function ($, window) { 57 var menus = {}; 58 $.fn.contextMenu = function (settings) { 59 var $menu = $(settings.menuSelector); 60 $menu.data("menuSelector", settings.menuSelector); 61 if ($menu.length === 0) return; 62 63 menus[settings.menuSelector] = {$menu: $menu, settings: settings}; 64 65 //make sure menu closes on any click 66 $(document).click(function (e) { 67 hideAll(); 68 }); 69 $(document).on("contextmenu", function (e) { 70 var $ul = $(e.target).closest("ul"); 71 if ($ul.length === 0 || !$ul.data("menuSelector")) { 72 hideAll(); 73 } 74 }); 75 76 // Open context menu 77 (function(element, menuSelector){ 78 element.on("contextmenu", function (e) { 79 // return native menu if pressing control 80 if (e.ctrlKey) return; 81 82 hideAll(); 83 var menu = getMenu(menuSelector); 84 85 //open menu 86 menu.$menu 87 .data("invokedOn", $(e.target)) 88 .show() 89 .css({ 90 position: "absolute", 91 left: getMenuPosition(e.clientX, 'width', 'scrollLeft'), 92 top: getMenuPosition(e.clientY, 'height', 'scrollTop') 93 }) 94 .off('click') 95 .on('click', 'a', function (e) { 96 menu.$menu.hide(); 97 98 var $invokedOn = menu.$menu.data("invokedOn"); 99 var $selectedMenu = $(e.target); 100 101 callOnMenuHide(menu); 102 menu.settings.menuSelected.call(this, $invokedOn, $selectedMenu); 103 }); 104 105 callOnMenuShow(menu); 106 return false; 107 }); 108 })($(this), settings.menuSelector); 109 110 function getMenu(menuSelector) { 111 var menu = null; 112 $.each( menus, function( i_menuSelector, i_menu ){ 113 if (i_menuSelector == menuSelector) { 114 menu = i_menu 115 return false; 116 } 117 }); 118 return menu; 119 } 120 function hideAll() { 121 $.each( menus, function( menuSelector, menu ){ 122 menu.$menu.hide(); 123 callOnMenuHide(menu); 124 }); 125 } 126 127 function callOnMenuShow(menu) { 128 var $invokedOn = menu.$menu.data("invokedOn"); 129 if ($invokedOn && menu.settings.onMenuShow) { 130 menu.settings.onMenuShow.call(this, $invokedOn); 131 } 132 } 133 function callOnMenuHide(menu) { 134 var $invokedOn = menu.$menu.data("invokedOn"); 135 menu.$menu.data("invokedOn", null); 136 if ($invokedOn && menu.settings.onMenuHide) { 137 menu.settings.onMenuHide.call(this, $invokedOn); 138 } 139 } 140 141 function getMenuPosition(mouse, direction, scrollDir) { 142 var win = $(window)[direction](), 143 scroll = $(window)[scrollDir](), 144 menu = $(settings.menuSelector)[direction](), 145 position = mouse + scroll; 146 147 // opening menu would pass the side of the page 148 if (mouse + menu > win && menu < mouse) { 149 position -= menu; 150 } 151 152 return position; 153 } 154 return this; 155 }; 156 })(jQuery, window); 157 158 $("#myTable tbody tr").contextMenu({ 159 menuSelector: "#contextMenu", 160 menuSelected: function ($invokedOn, $selectedMenu) { 161 if($selectedMenu.text() === "Add Row"){ 162 var targetRow = $invokedOn.parent("tr"); 163 var newRow = "<tr><td>#</td><td>(First Name)</td><td>(Last Name)</td></tr>" 164 $(newRow).insertAfter(targetRow); 165 }else if($selectedMenu.text() === "Delete Row"){ 166 var targetRow = $invokedOn.parent("tr"); 167 $(targetRow).remove(); 168 } 169 }, 170 onMenuShow: function($invokedOn) { 171 var tr = $invokedOn.closest("tr"); 172 $(tr).addClass("warning"); 173 }, 174 onMenuHide: function($invokedOn) { 175 var tr = $invokedOn.closest("tr"); 176 $(tr).removeClass("warning"); 177 } 178 }); 179 </script> 180</body> 181</html>
試したこと・調べたこと
- teratailやGoogle等で検索した
- ソースコードを自分なりに変更した
- 知人に聞いた
- その他
上記の詳細・結果
以下サンプルに対して主に修正した箇所です。
if($selectedMenu.text() === "Add Row"){ var targetRow = $invokedOn.parent("tr"); var newRow = "<tr><td>#</td><td>(First Name)</td><td>(Last Name)</td></tr>" $(newRow).insertAfter(targetRow); }else if($selectedMenu.text() === "Delete Row"){ var targetRow = $invokedOn.parent("tr"); $(targetRow).remove(); }
補足
特になし

回答2件
あなたの回答
tips
プレビュー