iT邦幫忙

0

關於表格內的拖拉問題

  • 分享至 

  • xImage

https://ithelp.ithome.com.tw/upload/images/20190614/201101327K16UYFUmA.jpg

這是我的排班表,功能是能把名單中的名字拖拉到排班中的格子裡
目前我已經可以拖拉進去,也可以移除,但有一個小瑕疵

https://ithelp.ithome.com.tw/upload/images/20190614/20110132WT6s0TKy7U.jpg

就是拖進去後格子大小會改變,想請問這個部分該如何修改呢?

這是我的HTML

<div class="container-fluid">
    <div class="row">
        <!--床位排程資訊-->
        <div class="col-md-10 panel-right panel-20 cal">
            <div class="box box-primary ">
                <div class="box-header">
                </div><!-- /.box-header -->
                <div class="box-body ">
                    <div id="schTable">
                        <table id="dataTable" class="table table-bordered table-hover caltable" style="margin: 0px 0px;" ondrop="drop(event)" ondragover="allowDrop(event)">
                            <tbody id="dataTbody">
                                @foreach (string[] row in DateForHelper.getMonthArray(@Model.Year, 5))
                                {
                                    <tr>
                                        <th class="sch-left-th"></th>
                                        @foreach (string text in row)
                                        {
                                            if (!String.IsNullOrEmpty(text))
                                            {
                                                <th colspan="3" class="th-weekday"><span class="th-date">@text</span></th>
                                            }
                                            else
                                            {
                                                <th colspan="3" rowspan="3" class="th-weekday"></th>
                                            }
                                        }
                                    </tr>
                                    <tr>
                                        <th class="sch-left-th">時段</th>
                                        @foreach (string text in row)
                                        {
                                            if (!String.IsNullOrEmpty(text))
                                            {
                                                <th>早</th>
                                                <th>午</th>
                                                <th>晚</th>
                                            }
                                        }
                                    </tr>
                                    <tr>
                                        <th class="sch-left-th">排班</th>
                                        @foreach (string text in row)
                                        {
                                            if (!String.IsNullOrEmpty(text))
                                            {
                                                <td id="spell-1"></td>
                                                <td id="spell-2"></td>
                                                <td id="spell-3"></td>
                                            }
                                        }
                                    </tr>
                                }
                            </tbody>
                        </table>
                    </div>
                </div>
                <!-- /.box-body -->
            </div>
            <!-- /.box -->
        </div>
        <!--醫師資訊-->
        <div class="col-md-2 panel-right panel-20 doc">
            <div class="box box-primary">
                <div class="box-header">
                </div><!-- /.box-header -->
                <div class="box-body">
                    <div class="lstdiv">
                        <table id="NameTable" class="table table-bordered table-striped table-hover">
                            <thead>
                                <tr>
                                    <th>名單</th>
                                </tr>
                            </thead>
                            <tbody id="NameTbody">
                                @if (Model.DrEmp.Count > 0)
                                {
                                    foreach (var item in Model.DrEmp)
                                    {
                                        <tr>
                                            <td class="fn-item td-draggable name" id="@item.DR_EMPNO" data name="@item.EMP_NAME" draggable="true" ondragstart="drag(event)">@item.EMP_NAME</td>
                                        </tr>
                                    }
                                }
                            </tbody>
                        </table>
                    </div>
                </div>
                <!-- /.box-body -->
            </div><!-- /.box -->
        </div>  <!-- /.col -->
    </div>
</div>

JS

    function allowDrop(ev) {
        ev.preventDefault();
    }
    function drag(ev) {
        ev.dataTransfer.setData("Text", ev.target.id);
    }

    function drop(ev) {
        ev.preventDefault();
        var data = ev.dataTransfer.getData("Text");
        var item = document.getElementById(data).cloneNode(true);
        ev.target.appendChild(item);
    }
    $('td[id^="spell-"]').click(function () {  
        $(this).empty();        
    })
我不太確定
可能要從css下手,設定固定欄寬。
不明
【**此則訊息已被站方移除**】
原來英文關鍵字,要這樣打。
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

0
dragonH
iT邦超人 5 級 ‧ 2019-06-14 16:10:16
最佳解答

codepen

你確定你真的是要 clone 整個 element 到表格裡嗎

還是說你只是需要他的text

如果只需要text的話

可以改成這樣


function drag(ev) {
    console.log(ev);
    // ev.dataTransfer.setData("Text", ev.target.id);
    ev.dataTransfer.setData("Text", ev.target.textContent);
}
function drop(ev) {
    ...
  // var item = document.getElementById(data).cloneNode(true);
  const item = document.createTextNode(data);
}

表格變形的話

你可能要從css下手

我目前看到可以用

word-wrap:break-word

然後調整 td size

不確定有什麼副作用就是

看更多先前的回應...收起先前的回應...
tenno081 iT邦研究生 4 級 ‧ 2019-06-14 16:13:57 檢舉

只要文字就好,像是我想拖拉222,我就只要222這個字就好

dragonH iT邦超人 5 級 ‧ 2019-06-14 16:19:32 檢舉

你的 code 我剛實測

會把整個 element clone過去唷

我上面的改法可以參考一下

tenno081 iT邦研究生 4 級 ‧ 2019-06-14 16:30:52 檢舉

可是我用你的方法反而不行耶?這還真奇怪

dragonH iT邦超人 5 級 ‧ 2019-06-14 16:31:56 檢舉

哪個部份不行/images/emoticon/emoticon16.gif

我是用你的code改的說XD

tenno081 iT邦研究生 4 級 ‧ 2019-06-14 16:39:06 檢舉

沒事,是我的問題,我後來仔細看有幾個地方沒注意到

抱歉抱歉,感謝解答

tenno081 iT邦研究生 4 級 ‧ 2019-06-14 18:00:53 檢舉

不好意思,最後能否再問一個問題,我這作法能否改成JQUERY版本呢?
目前我改都暫時失敗

dragonH iT邦超人 5 級 ‧ 2019-06-14 19:25:30 檢舉

tenno081

改好了

是說改成這樣意義好像不大就是/images/emoticon/emoticon11.gif

tenno081 iT邦研究生 4 級 ‧ 2019-06-17 09:08:40 檢舉

感謝解答

tenno081 iT邦研究生 4 級 ‧ 2019-06-17 10:16:34 檢舉

起問這個是用Draggable插件嗎?
老實說我原先也有做一個這版本

   $().ready(function (e) {       
      $('.fn-item').draggable({
          helper: "clone",
          cursor: "move"
      });
      $('td[id^="spell-"]').droppable({
          drop: function (event, ui) {       
              var source = ui.draggable.clone();
              $(this).append(source);

          }
      });     
  });

不過不知道為什麼不是很靈敏,有時候拖不進去,有時候又可以

dragonH iT邦超人 5 級 ‧ 2019-06-17 10:25:02 檢舉

我也是用 jquery ui 的唷

不過我不是直接拖 <td>

我是拖 <td> 裡面的 <span>

tenno081 iT邦研究生 4 級 ‧ 2019-06-17 11:41:34 檢舉

了解,那能否在請問,現在我需要用到AJAX

如果我需要再抓id="@item.DR_EMPNO"這個值的話

那這樣大概怎麼寫呢?

我的JS最初的寫法

ev.dataTransfer.setData("Text", ev.target.id);
var item = document.getElementById(data).cloneNode(true);

是顯示ID,不過沒有抓到text,換成您的則是反過來

抱歉問題有點多

dragonH iT邦超人 5 級 ‧ 2019-06-17 11:56:23 檢舉

由於我的id是設在 <td> 上

但是我拖的是 <span>

所以要抓到 id 的話

可以在 <span> 上 設 id

然後再利用

ui.draggable.prop('id');

就可以抓到

順帶一提

js的好處就是幾乎什麼都能 console.log 出來

不知道怎麼取值或是不知道有什麼prototype能用

console.log 出來就可以知道了

tenno081 iT邦研究生 4 級 ‧ 2019-06-17 13:27:37 檢舉

原來是這樣,難怪我都抓不到,我是用

$(this).attr('id')

那最後一個問題,如果是那個原本的JS版本呢?

我想做一個比對,能否麻煩您再為我解答一下呢?謝謝

dragonH iT邦超人 5 級 ‧ 2019-06-17 13:36:01 檢舉
// js version
function allowDrop(ev) {
  ev.preventDefault();
}
function drag(ev) {
  console.log(ev);
  // ev.dataTransfer.setData("Text", ev.target.id);
  ev.dataTransfer.setData("Text", ev.target.textContent);
}
function drop(ev) {
  ev.preventDefault();
  var data = ev.dataTransfer.getData("Text");
  // var item = document.getElementById(data).cloneNode(true);
  const item = document.createTextNode(data);
  ev.target.appendChild(item);
}
$('td[id^="spell-"]').click(function () {  
  $(this).empty();        
})

你是要問哪個部份呢

你原本就是傳id不是嗎?/images/emoticon/emoticon19.gif

tenno081 iT邦研究生 4 級 ‧ 2019-06-17 14:06:03 檢舉

對,原本是傳ID,但是我不知道該怎麼取TEXT

然後換成您的做法後是取得TEXT但不知道該怎麼取ID@@

dragonH iT邦超人 5 級 ‧ 2019-06-17 14:47:39 檢舉

有點看不太懂

你是想要兩個同時都取值嗎

// set value
ev.dataTransfer.setData("ID", ev.target.id);
ev.dataTransfer.setData("Text", ev.target.textContent);

// get value
const myData = ev.dataTransfer.getData("Text");
const myId = ev.dataTransfer.getData("ID");
tenno081 iT邦研究生 4 級 ‧ 2019-06-17 16:49:17 檢舉

對,現在沒問題了,感謝,目前我應該剩AJAX部分,感謝

0

用table就有可能性這樣的問題發生。
一般來說。想要固定欄寬的情況下。你還是需要指定固定寬度處理。

這是table元件的通病,你沒招的。你只能用指定欄寬。

不過,其實一般會這樣跑掉的原因主要再於內部字元變動超過的情況。
但還有一種情況就是空元件問題。

因為這邊看不到你的html原始碼呈現的方式。不確定你是為會有如下的情況發生

<td></td>
<td></td>
<td></td>

一般像上面的情況就是說所謂的空元件。一但第一個td突然插入了一段文字或其它元件。
就會莫名的自動展開。

你可以將空字元先補上一個空白處理。如「 」
可以降低異位的情況發生。

不過這也只是降低。還是需要指定欄寬才行。

tenno081 iT邦研究生 4 級 ‧ 2019-06-14 16:12:58 檢舉

這樣喔,我是沒有空元件這個狀況發生,後來也就只好加寬欄位寬度了
能否離個題再詢問幾個問題?

1.這個拖拉的功能我也有用JQUERY的Draggable插件
可是卻很不靈敏

    $().ready(function (e) {       
      $('.fn-item').draggable({
          helper: "clone",
          cursor: "move"
      });
      $('td[id^="spell-"]').droppable({
          drop: function (event, ui) {       
              var source = ui.draggable.clone();
              $(this).append(source);

          }
      });     
  });

不知道這個疑問有沒有解?

我要發表回答

立即登入回答