iT邦幫忙

0

已刪文30

froce iT邦大師 1 級 ‧ 2023-07-21 11:28:27 檢舉
說真的,看了很煩,你能不能把你關鍵要改的地方列出,然後把目前執行結果也列出來?問問題簡化的能力很重要。
好~目前關鍵要改動的
```
createdCell: function (td, cellData, rowData, row, col) {
var switchId = 'customSwitch_' + rowData.id; // Assuming you have an 'id' field in your data
var switchElement = $(td).find('#' + switchId);
var previousArgpValue = rowData.argp; // 先記錄下之前的 argp 值
switchElement.change(function () {
if ($(this).is(':checked')) {
rowData.argp = true;
} else {
rowData.argp = false;
}
var selectedRows = tablefor4.rows({ selected: true }).data();
var newSelectedData = selectedRows.filter(function(row) {
return row.argp === true && !old_data.some(function(prevRow) {
return prevRow.id === row.id;
});
}).map(function(row) {
return { id: row.id, enable: true };
});
old_data = selectedRows.toArray(); // 更新之前勾選的資料
new_edit_data.data = new_edit_data.data.concat(newSelectedData); // 合併新的勾選資料
new_edit_data.length = new_edit_data.data.filter(function(row) {
return row.enable === true;
}).length;
```
目前執行結果
```
{
"draw": 1,
"length": 0,
"server": "argp",
"data": [
{
"0": {
"id": 4923,
"enable": true
},
"1": {
"id": 4920,
"enable": true
},
"2": {
"id": 4919,
"enable": true
},
"context": [
{
"oFeatures": {
"bAutoWidth": true,
"bDeferRender": false,
"bFilter": true,
"bInfo": true,
"bLengthChange": true,
"bPaginate": true,
"bProcessing": false,
"bServerSide": false,
"bSort": true,
"bSortMulti": true,
"bSortClasses": true,
"bStateSave": null
},
"oScroll": {
"bCollapse": false,
"iBarWidth": 17,
"sX": "",
"sXInner": "",
"sY": ""
},
"oLanguage": {
"fnInfoCallback": null,
"oAria": {
"sSortAscending": ": activate to sort column ascending",
"sSortDescending": ": activate to sort column descending",
"_hungarianMap": {
"sortAscending": "sSortAscending",
"sortDescending": "sSortDescending"
}
},
"oPaginate": {
"sFirst": "First",
"sLast": "Last",
"sNext": "Next",
"sPrevious": "Previous",
"_hungarianMap": {
"first": "sFirst",
"last": "sLast",
"next": "sNext",
"previous": "sPrevious"
}
},
"sEmptyTable": "No data available in table",
"sInfo": "Showing _START_ to _END_ of _TOTAL_ entries",
"sInfoEmpty"
....
```
(會有其他多餘的結果,跟length 長度不對)
我有稍微修改過了,再給@froce 大神看看
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
1
greenriver
iT邦研究生 5 級 ‧ 2023-07-21 13:21:21
最佳解答

是不是要列出有更改的資料?
如果是的話,每個index都給予一個變數isChanged,代表有沒有被更改過

let getData = data.map(obj=>{
    let result = JSON.parse(JSON.stringify(obj))
    result['isChanged'] = false //給予變數
    return result
})

const switchBtn = (index)=>{
    getData[index]['enable'] = !getData[index]['enable']
    getData[index]['isChanged'] = !getData[index]['isChanged']
}

當按下儲存時,去搜尋 isChanged==true 的資料,就可以了

看更多先前的回應...收起先前的回應...
greenriver iT邦研究生 5 級 ‧ 2023-07-21 13:24:45 檢舉

缺點是,儲存時data裡的資料都要遍立一次。
資料不多時,可以這樣做。
如果資料3000~5000筆時,就另外寫吧

小弟搞懂哥的意思了

const switchBtn = (index)=>{
    getData[index]['enable'] = !getData[index]['enable']
    getData[index]['isChanged'] = !getData[index]['isChanged']
}

這個要放在"Selected" 選項上

點Save Change 得時候去找 isChanged==true 的資料

抱歉,我還很菜

<script>
function modalTable() {
  console.log("TABLE MODAL");
  const getToken = localStorage.getItem("token");
  var apple = { // 新增一個物件來存儲資料
    draw: 1,
    length: 0, // 初始化為 0
    server: "argp",
    data: []
  };

  var getData; // Define getData in the outer scope

  var tablefor4 = $("#example_04").DataTable({
    ajax: {
      url: "http://192.168.03.30:8000/api/ipc/all",   // fake api
      headers: {
        'Authorization': 'Bearer ' + getToken
      },
      dataSrc: function (response) {
        console.log("DATA MODAL TABLE", response.data);
        getData = response.data.map(obj => {
          let result = JSON.parse(JSON.stringify(obj))
          result['isChanged'] = false //給予變數
          return result
        })

        console.log('DATA CHANGe', getData)

        return getData;
      },
    },
    destroy: true,
    columns: [
      { data: "sf", title: "sf" },
      { data: "code", title: "code" },
      { data: "subcode", title: "subcode" },
      { data: "msgtext", title: "msgtext" },
      { data: "description", title: "description" },
      {
        data: null,
        title: "Alarm/Event Setting",
        render: function (data, type, row) {
          var switchId = 'customSwitch_' + row.id; // Assuming you have an 'id' field in your data
          var switchHTML = '<div class="custom-control custom-switch">';
          var isChecked = row.argp ? 'checked' : ''; // 檢查 rowData.argp 是否為 true,如果是,則添加 checked 屬性
          switchHTML += '<input type="checkbox" class="custom-control-input" id="' + switchId + '" ' + isChecked + '>';
          switchHTML += '<label class="custom-control-label" for="' + switchId + '">Selected</label>';
          switchHTML += '</div>';
          return switchHTML;
        },
        createdCell: function (td, cellData, rowData, row, col) {
          var switchId = 'customSwitch_' + rowData.id; // Assuming you have an 'id' field in your data
          var switchElement = $(td).find('#' + switchId);
          switchElement.change(function () {
            if ($(this).is(':checked')) {
              rowData.argp = true;
            } else {
              rowData.argp = false;
            }
            var selectedRows = tablefor4.rows({ selected: true }).data();
            apple.data = selectedRows.filter(function (row) { // 只保留新勾選的資料
              return row.argp === true;
            }).map(function (row) {
              return { id: row.id, enable: row.argp };
            });
            apple.length = apple.data.length; // 更新 length
            console.log("Selected Rows:", apple);
            
            // Find data where isChanged is true
            var changedData = getData.filter(item => item.isChanged === true);
            console.log("Changed Data:", changedData);
          });
        }
      },
    ]
  });

  tablefor4.draw();
}
</script>

這樣改寫,有確保每個資料在一開始都加上{isChanged: false}

但我的console.log("Changed Data:", changedData)好像還是木有出成我想要的捏

謝謝,我改好了
祝各位大神好人一生平安

<script>
  function modalTable() {
    console.log("TABLE MODAL");
    const getToken = localStorage.getItem("token");
    var apple = { // 新增一個物件來存儲資料
      draw: 1,
      length: 0, // 初始化為 0
      server: "argp",
      data: []
    };

    var getData; // Define getData in the outer scope

    var tablefor4 = $("#example_04").DataTable({
      ajax: {
        url: "http://192.168.03.30:8000/api/ipc/all",   // fake api
        headers: {
          'Authorization': 'Bearer ' + getToken
        },
        dataSrc: function (response) {
          console.log("DATA MODAL TABLE", response.data);
          getData = response.data.map(obj => {
            let result = JSON.parse(JSON.stringify(obj))
            result['isChanged'] = false //給予變數
            return result
          })

          console.log('DATA CHANGe', getData)

          return getData;
        },
      },
      destroy: true,
      columns: [
        { data: "sf", title: "sf" },
        { data: "code", title: "code" },
        { data: "subcode", title: "subcode" },
        { data: "msgtext", title: "msgtext" },
        { data: "description", title: "description" },
        {
          data: null,
          title: "Alarm/Event Setting",
          render: function (data, type, row) {
            var switchId = 'customSwitch_' + row.id; // Assuming you have an 'id' field in your data
            var switchHTML = '<div class="custom-control custom-switch">';
            var isChecked = row.argp ? 'checked' : ''; // 檢查 rowData.argp 是否為 true,如果是,則添加 checked 屬性
            switchHTML += '<input type="checkbox" class="custom-control-input" id="' + switchId + '" ' + isChecked + '>';
            switchHTML += '<label class="custom-control-label" for="' + switchId + '">Selected</label>';
            switchHTML += '</div>';
            return switchHTML;
          },
          createdCell: function (td, cellData, rowData, row, col) {
            var switchId = 'customSwitch_' + rowData.id; // Assuming you have an 'id' field in your data
            var switchElement = $(td).find('#' + switchId);
            switchElement.change(function () {
              if ($(this).is(':checked')) {
                rowData.argp = true;
                rowData.isChanged = true; // Update isChanged to true when "Selected" is checked
                // Find data where isChanged is true
                var changedData = getData.filter(item => item.isChanged === true);
                console.log("Changed Data:", changedData);
              } else {
                rowData.argp = false;
              }
              var selectedRows = tablefor4.rows({ selected: true }).data();
              apple.data = selectedRows.filter(function (row) { // 只保留新勾選的資料
                return row.argp === true;
              }).map(function (row) {
                return { id: row.id, enable: row.argp };
              });
              apple.length = apple.data.length; // 更新 length
              console.log("Selected Rows:", apple);
              var changedData = getData.filter(item => item.isChanged === true);
              console.log("Changed Data:", changedData);
            });
          }
        },
      ]
    });

    tablefor4.draw();
  }
</script>

@greenriver大神, 我這有個問題的延伸您可能感興趣 discussion問題

1
froce
iT邦大師 1 級 ‧ 2023-07-21 14:24:19

有點懶得寫code,幾個發現的問題點:

  1. 你有去看你的 selectedRows,這真的是你要的嗎?他出來的是 dataTable的api物件...
var selectedRows = tablefor4.rows({ selected: true }).data();

所以你才會說多了一堆多餘的結果,因為這根本就不是你想要的

  1. 因為第一個錯了,所以下面的filter也搜尋不到,你的new_edit_data.data裡面根本就沒有enable的屬性。所以不管你怎麼更新,length永遠為0
new_edit_data.length = new_edit_data.data.filter(function(row) {
            return row.enable === true;
          }).length;
  1. 設計最好能簡單一點...
    像這個要我設計的話,在接到ajax時候就會複製一份起來,點擊的時候去和原始的資料比對就好。
    不要每次點擊就去算一次。
    甚至就點擊切換開關的時候,直接送ajax去改變伺服器內的資料

  2. 然後像功能性比較複雜的網站,建議去學vue,用vue會好寫很多很多...

對的,一開始我原本有考慮要不要用vue, 但我就有被建議說可以先從普通的jquery, datatable 套 boostrap,學點基本的打個基礎

謝謝哥1到3的回應,我會去研究看看

obarisk iT邦研究生 2 級 ‧ 2023-07-22 08:55:23 檢舉

學 vue ?不一定吧

重點在 binding 跟 reactive

1
alien663
iT邦研究生 5 級 ‧ 2023-07-21 14:57:01

感覺你在做一些奇怪的事情,我懶得說明了,直接放Code,這樣不是比較直覺一點嗎?
我一個寫後端為主的人,隨便寫出這樣的範例只需要15分鐘ㄟ......

<button onclick="handleButton()">Click Me to show table</button>
<div id="demo"></div>

<script>
    let data = [
        {
            "ID": 1,
            "Name": "AAAA",
            "Description": "I belive I can fly",
            "isSelect": false
        },
        {
            "ID": 2,
            "Name": "AAAA",
            "Description": "I belive I can fly",
            "isSelect": false
        },
        {
            "ID": 3,
            "Name": "AAAA",
            "Description": "I belive I can fly",
            "isSelect": false
        },
        {
            "ID": 4,
            "Name": "AAAA",
            "Description": "I belive I can fly",
            "isSelect": false
        },
        {
            "ID": 5,
            "Name": "AAAA",
            "Description": "I belive I can fly",
            "isSelect": false
        }
    ]

    const handleCheckbox = (id) => {
        console.log(id)
        data.find(item => item.ID === id).isSelect = !(data.find(item => item.ID === id).isSelect)
        console.log(data)
    }

    const handleButton =() => {
        document.getElementById("demo").innerHTML = ``
        let temp = `<table>
            <thead>
                <tr>
                    <td>ID</td>
                    <td>Name</td>
                    <td>Description</td>
                    <td>isSelected</td>
                </tr>
            </thead>
            <tbody>`

            for(let item of data){
                temp += `<tr>
                    <td>${item["ID"]}</td>
                    <td>${item["Name"]}</td>
                    <td>${item["Description"]}</td>
                    <td>
                        <input type='checkbox' selected=${item["isSelect"]} onclick='handleCheckbox(${item["ID"]})' />
                    </td>
                    </tr>`
            }
            temp += ` </tbody></table>`
        document.getElementById("demo").innerHTML = temp
    }
</script>
froce iT邦大師 1 級 ‧ 2023-07-21 15:35:09 檢舉

dataTable能做到的事很多,說真的需求有點不一樣。
說不定他就還是需要前端篩選、排序等一堆其他的功能。
用別人寫好的套件和自己搞也不太相同。

alien663 iT邦研究生 5 級 ‧ 2023-07-24 08:59:37 檢舉

我的意思是,每一個select的onChange直接去改動到原始資料的true/false,然後再根據需求去選出來就好,而不是另外去儲存一個"有勾選的資料"。

每一個row的操作行為,應該去針對Source Data去改變,這也要同時更動到前端表格的顯示(對御三家來說算是基本功能),然後你需要新的格式,等到需要的時候再來組就好,不用每個row操作都去做。

我要發表回答

立即登入回答