掲載画像のように
ドラッグ&ドロップしたらその範囲が一つの範囲になるようにしたい
セル結合しているのかboderを消しているのかわからないのですが
色付けしたいです。
セル結合をやってみましたが難しいです。もっと汎用的にしたいです。
ソースとかの具体例をいただけると助かります。
<html>
<head>
<title>テーブルのセルを結合したり分割したりする</title>
<script type="text/javascript">
var colflag = 1;
var rowflag = 1;
function colspanTest()
{
var table = document.getElementById("table1")
var tr = table.getElementsByTagName("tr")[0]
var td1 = tr.getElementsByTagName("td")[0]
var td2 = tr.getElementsByTagName("td")[1]
if (colflag % 2 == 1) {
var td3 = tr.getElementsByTagName("td")[2]
}
if (colflag % 2 == 1) {
tr.removeChild(td3)
td1.colSpan = "2"
} else {
var td3 = document.createElement("td")
td3.innerHTML = "3"
tr.appendChild(td3)
td1.colSpan = "1"
}
return colflag = colflag + 1;
}
function rowspanTest()
{
var table = document.getElementById("table2")
var tr1 = table.getElementsByTagName("tr")[0]
var tr2 = table.getElementsByTagName("tr")[1]
var td1 = tr1.getElementsByTagName("td")[0]
if (rowflag % 2 == 1) {
var td2 = tr2.getElementsByTagName("td")[0]
}
if (rowflag % 2 == 1) {
tr2.removeChild(td2)
td1.rowSpan = "2"
} else {
var td2 = document.createElement("td")
td2.innerHTML = "3"
tr2.appendChild(td2)
td1.rowSpan = "1"
}
rowflag = rowflag + 1;
}
</script>
</head>
<body>
<table id="table1" border="1">
<tr><td colspan="1">1</td><td>2</td><td>3</td></tr>
<tr><td>1</td><td>2</td><td>3</td></tr>
</table>
<table id="table2" border="1">
<tr><td colspan="1">1</td><td>2</td><td>3</td></tr>
<tr><td>1</td><td>2</td><td>3</td></tr>
</table>
<input type="button" value="button" onclick="colspanTest();" />
<input type="button" value="button" onclick="rowspanTest();" />
</body>
</html>
A 回答 (3件)
- 最新から表示
- 回答順に表示
No.3
- 回答日時:
No2です
>今のままだと色だけ変わってセルの内容が1つづつ記載となりますよね
>これをまとめて1行にしたいんです。
No1に記しましたが、何をしたいのかわからないので、テキトーに設定しています。
ご質問文からは、色が変わればよいものと解釈しましたので。
>だからセル結合かなと思ったのですが。
結合したいのなら、セル範囲はわかっているので、その範囲を結合すれば宜しいでしょう。
一方で、
>まとめて1行にしたい
って、他のセルも1行に纏めるってことでしょうか?
それとも、ご提示の図(よく見えないけれど)では、1行の中で色が変わっているようなので、そもそもが1行内で処理できればいいのかな・・・
>もっと汎用的にしたいです。
とは、方向性が異なるようにも思いますけれど。
どうやら「結合」にこだわりがあるようなので・・・
「ダブルクリックしたら、1行内でテキトーに結合する」例を。
No1にも記したように、質問文に無い(質問様の頭の中にある)ことはわかりませんし、漠とした説明しかないので、テキトーに考えることしかできません。
禅問答を繰り返すつもりもありませんので、あとはよしなに。
<!DOCTYPE HTML>
<html lang="ja">
<head><title>Sample</title>
<style>
#testTable { border-collapse: collapse; font-size: 12px; font-weight: bold; }
#testTable td { padding: 0.3em; border: 1px solid gray; text-align: center; min-width:3em; }
#testTable tr:nth-child(3n) td[colspan] { background-color: palegreen; }
#testTable tr:nth-child(3n+1) td[colspan] { background-color: bisque; }
#testTable tr:nth-child(3n+2) td[colspan] { background-color: silver; }
</style>
</head>
<body>
<table id="testTable"></table>
<script>
// ** テスト用テーブル作成 **
let
tbl = document.getElementById('testTable'),
col = 'colspan', num = 1,
f = document.createDocumentFragment(),
tr = document.createElement('tr'),
td = document.createElement('td');
td.textContent = "…";
for(let i = 0; i<20; i++) tr.appendChild(td.cloneNode(true));
for(let i = 0; i<20; i++) f.appendChild(tr.cloneNode(true));
document.getElementById('testTable').appendChild(f);
// ** イベント処理 **
tbl.addEventListener('dblclick', e =>{
let t = e.target;
if(t.nodeName != 'TD') return;
let i, cells = t.parentNode.cells;
let n = t.cellIndex, c = (t.getAttribute(col) || 1) | 0;
c = Math.min(cells.length - n, c + (Math.random()*6 | 0) + 1);
for(i=1; i<c; i++) if(cells[n+i].getAttribute(col)) break;
c = c>i?i:c;
t.setAttribute(col, c);
t.textContent = '備考' + num++;
for(i=1; i<c; i++) cells[n+i].style.display = 'none';
});
</script>
</body>
</html>
No.2
- 回答日時:
No1です。
No1のスクリプト部分のみ、追加での投稿になります。
<script>
window.addEventListener('DOMContentLoaded', e => {
// ** テスト用テーブル作成 **
for(let r = 0; r<20; r++){
let tr = document.createElement('tr')
for(let c = 0; c<25; c++){
let td = document.createElement('td');
td.textContent = (r+1) + "-" + (c+1);
tr.appendChild(td);
}
document.getElementById('testTable').appendChild(tr);
}
document.body.insertAdjacentHTML('beforeend', '<div id="selectMarker"></div>');
// ** 初期設定 **
const
tbl = document.getElementById('testTable'),
marker = {
elm: document.getElementById('selectMarker'),
flag: false,
clear: function(){
this.elm.style.display = 'none';
this.flag = false;
this.cell1 = this.cell2 = null;
},
set: function(t){
this.cell2 = t;
let
rec1 = this.cell1.getBoundingClientRect(),
rec2 = t.getBoundingClientRect(),
top = Math.min(rec1.top, rec2.top),
left = Math.min(rec1.left, rec2.left),
styl = this.elm.style;
styl.width = (Math.max(rec1.right, rec2.right) - left) + 'px';
styl.height = (Math.max(rec1.bottom, rec2.bottom) - top) + 'px';
styl.left = (left + window.scrollX) + 'px';
styl.top = (top + window.scrollY) + 'px';
styl.display = 'block';
},
areaIndex: function(){
let
r1 = this.cell1.parentNode.rowIndex,
r2 = this.cell2.parentNode.rowIndex,
c1 = this.cell1.cellIndex,
c2 = this.cell2.cellIndex;
if(r1>r2) [r1, r2] = [r2, r1];
if(c1>c2) [c1, c2] = [c2, c1];
return { r1: r1, c1: c1, r2: r2, c2: c2 };
},
check: function(){
return (this.flag || !this.cell1 || !this.cell2);
}
},
getPos = (elm, tag, d, L1, L2) =>{
let r, elms = elm.querySelectorAll(tag);
for( let i=0; i<elms.length; i++){
let rec = elms[i].getBoundingClientRect();
if(rec[L1] < d && d <= rec[L2]){ r = elms[i]; break; }
}
return r;
},
getCell = e => {
let r, t = e.target;
if(t.nodeName == 'TD' || t.id == 'selectMarker') {
let x = e.pageX - window.scrollX;
let y = e.pageY - window.scrollY;
r = getPos(tbl, 'tr', y, 'top', 'bottom');
if(r) r = getPos(r, 'td', x, 'left', 'right');
}
return r;
},
// ** イベント処理 **
mouseClick = e =>{
let t = getCell(e);
if(!t) { marker.clear(); return; }
if(!marker.flag) marker.cell1= t;
marker.flag = !marker.flag;
marker.set(t);
},
mouseMove = e => {
if(!marker.flag) return;
let t = getCell(e);
if(t) marker.set(t);
},
setColor = e => {
let elms = document.querySelectorAll('#colorTable td');
let n =elms[ [...elms].indexOf(e.target)];
if(!n || marker.check()) return;
let a = marker.areaIndex();
let color = n.style.backgroundColor;
let bcolor = color=='transparent'?'gray':color;
for(let r = a.r1; r<=a.r2; r++){
let tds = tbl.rows[r].querySelectorAll('td');
for(let c = a.c1; c<=a.c2; c++){
tds[c].style.backgroundColor = color;
tds[c].style.borderColor = bcolor;
}
}
marker.clear();
},
setEvent = (elm, evt, func) =>{
elm.addEventListener(evt, e =>{ func(e); });
};
setEvent( document, 'click', mouseClick);
setEvent( document, 'mousemove', mouseMove);
setEvent(document.getElementById('colorTable'), 'click', setColor);
});
</script>
ご回答ありがとうございます。
作成していただいたコードですがイメージとしてはいいのですが
色を付けた部分を1行として備考を記載したいんですよね
今のままだと色だけ変わってセルの内容が1つづつ記載となりますよね
これをまとめて1行にしたいんです。
だからセル結合かなと思ったのですが。
ありがとうございました。
もし、上記もヒントやコード載せていただけれるようでしたお願いします。
No.1
- 回答日時:
こんばんは
>もっと汎用的にしたいです。
汎用化するのは良いですが、結合した際の他のデータはどうなるのでしょうか?
ご提示のサンプルでは分離すると復活するみたいですけれど、そうなるとバックグラウンドでテーブルをもう一つ持っておく必要がありそうな・・・
あるいは、結合セルを含む範囲を選択する場合には、包含矩形となるのかそうでないのかなど、起こり得るいろいろなケースに対して仕様を決めておく必要がありそうです。
一方で、
>セル結合しているのかboderを消しているのか
>わからないのですが色付けしたいです。
から推測して、同じ色のエリアになればよいものと解釈しました。
また、
>ドラッグ&ドロップしたらその範囲が~~
通常のブラウザの動作だと、表上でドラッグすると表示文字が選択されますが、その際カーソルをドラッグで上下移動すると、選択対象は行全体になってしまい、大変紛らわしいことになるような気がします。
まぁ、デフォルトの動作をキャンセルすればよいのかもしれませんが、「マウスダウン-ドラッグ-マウスアップ」ではなく、「クリック-ムーブ-クリック」の操作に変更して考えています。
>ソースとかの具体例をいただけると助かります。
色の指定方法が不明なので、ひとまず、テキトーなカラーテーブルを作り、「セルを選択した状態でカラーをクリックすると、選択範囲がその色になる」という単純な例として作成しています。
とは言っても、スクリプトの考え方は十人十色なので、UIは多少の参考にはなるかもしれませんが、スクリプトはあまり参考にはならないと思います。
(思い付きのまま記述しているので、整理されていませんし、必ずしも読みやすいとも思えませんので)
以下のように、勝手に読み替えています。
・click-move-clickでセル範囲を選択してから、色を指定すると該当範囲がその色になる
・セルの単位はそのままで、結合などはしない。(表示内容もそのまま)
・罫線は、まとめて背景色と同色にしています。
(外枠だけは元の色を残すようにしたほうが、効果的かもしれません)
※ 通常ならイベント発生要素からセル位置を簡単に特定できますが、選択範囲を示すdivを表示している関係で、その範囲内の(下にある)セルは同じ方法では特定できません。
ですので、全体に、セルを特定する方法としてマウス座標から計算する方法をとっています。
※ 何かの足しにでもなれば。
(全体をまとめると文字数オーバーになるため、スクリプト部分は分けて別投稿にしました。)
Chromeとfxでテストしています。
<!DOCTYPE HTML>
<html lang="ja">
<head><title>Sample</title>
<style>
#testTable { border-collapse: collapse; font-size: 10px; }
#testTable td { padding: 0.3em; border: 1px solid gray; text-align: center; min-width:4em; }
#colorTable { border-collapse: separate; border-spacing: 2px; margin: 1em; }
#colorTable, #colorTable td { border: 1px solid gray; }
#colorTable td { width: 1.5em; height:1.5em; text-align: center; }
#selectMarker {
position: absolute; box-sizing: border-box;
background-color: rgba(0, 0, 255, .05);
border: 2px dashed blue;
z-index: 10; display: none;
}
</style>
<script>
// *** この部分は別投稿になります。
</script>
</head>
<body>
<table id="colorTable"><tr>
<td style="background-color: transparent;">無</td>
<td style="background-color: silver;"></td>
<td style="background-color: pink;"></td>
<td style="background-color: bisque;"></td>
<td style="background-color: lightyellow;"></td>
<td style="background-color: yellow;"></td>
<td style="background-color: palegreen;"></td>
<td style="background-color: aquamarine;"></td>
<td style="background-color: aqua;"></td>
<td style="background-color: turquoise;"></td>
<td style="background-color: skyblue;"></td>
<td style="background-color: cornflowerblue;"></td>
<td style="background-color: plum;"></td>
<td style="background-color: hotpink;"></td>
</tr></table>
<table id="testTable"></table>
</body>
</html>
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- JavaScript EasyUIのSubGrid(jquery)におけるObjectに入れた連想配列について 1 2022/05/02 11:21
- HTML・CSS テーブルタグのセルの幅の一部だけを指定 1 2023/03/12 12:02
- AJAX JavascriptからPHPへのAjax通信でnullが返ってくる 3 2022/08/03 22:00
- Visual Basic(VBA) Selenium.ChromeDriverの使い方について 7 2022/09/22 06:43
- HTML・CSS 【CSS】:hasで可能? imgを含むtr要素を選択したい 1 2022/11/17 14:36
- HTML・CSS 自身のHPにYouTube動画を貼り付けるのが出来なくなり困ってます 1 2022/11/11 10:44
- JavaScript javascriptでテーブルに追加した項目のid追加してローカルストレージを操作したい 5 2023/01/01 15:52
- JavaScript 追加ボタンを押した際に ok ボタンを押した場合のみ入力値が追記されるようにしたいです 6 2022/05/29 09:57
- PHP htmlで複数の個数入力欄を表示させるには 1 2022/09/20 03:11
- JavaScript jQueryで同じクラス名のものを別物として扱いたい 1 2022/06/17 14:14
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ハイパーリンクを別ウインドウ...
-
jqueryで表に連番No.を追加したい
-
至急!GetElementById でtdの...
-
一覧から選択した行の行番号を...
-
プルダウンで選択すると、DBの...
-
JavaScriptで特定のtdタグにcla...
-
チェックボックスにチェックが...
-
「オブジェクトは、このプロパ...
-
テーブルで複数行をまとめて非...
-
ドラッグ&ドロップしたらその...
-
特定<table>内の<td>の色を変える
-
テーブル内に表示されている数...
-
jqueryでどうやってエスケープ?
-
IEにおけるinnerHTMLの記述ミス?
-
return trueとreturn falseの用...
-
<JavaScript>tableタグを入力不...
-
【jQuery】input nameの文字列...
-
onchangeイベントを強制的に発...
-
javascriptでASPにデータを渡す
-
プルダウン選択を変更すると、...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
ハイパーリンクを別ウインドウ...
-
プルダウンで選択すると、DBの...
-
一覧から選択した行の行番号を...
-
tableの任意行にfocusをあてる
-
特定<table>内の<td>の色を変える
-
JavaScriptで特定のtdタグにcla...
-
至急!GetElementById でtdの...
-
マウスをブラウザの外に出した...
-
【UWSC】HTML内のある部分を抽...
-
スクロールバーの表示位置を変...
-
クリックされた罫表セルの行番...
-
テーブルの変数について
-
動的なtableの値を取得したい
-
特定の文字列を挿入
-
テーブル内に表示されている数...
-
javascript クリックすると、あ...
-
テーブルの項目の値取得
-
javascriptで質問です。 displa...
-
Tablesorteを2行一組でソートする
-
\\u30ad\\u30fc\\u30dc・・・と...
おすすめ情報