0

I have 3 tables with two columns each (image). I want to make the table editable (edit row, add rows, delete rows) and I'm a little lost. Each table row has an edit button, and at the end of each table there is an "add" button.

  1. If I want the modal title to either say edit or add would I need to make 2 different modals or is there a way to do this in JS?

  2. How would I do about making the table editable? I tried putting together some JS (see below)

Modal:

<div class="modal" id="modal">
        <div class="modal-header">
          <div class="modal-titel">Edit Account</div>
          <button data-close-button class="close-button">&times;</button>
        </div>
        <div class="modal-body"><input type="text" id="new_acc" placeholder="Name"><br><br><input type="text" id="new_balance" placeholder="Currency"><br><br><input type="text" placeholder="Balance"></div>
        <div class="modal-actionbox">
          <input type="button" class="modal-action" value="">
          <input type="button" class="modal-action" value="⌫">
        </div>
      </div>

Tables:

<div class="Accounts">
      <br><br><button type="button" class="collapsible"><h3 id="Accounts">&nbsp;Fiat Accounts</h3></button>
       <div class="content" id="acc_list"><table class="acc_table" id="acc_table">
         <tr id=acc_row1><td id="acc_name1" class="accname">Cash</td><td id="acc_balance1" class="accbal">$5322.54<button class="edit_account" data-modal-target="#modal" id="editaccounts">✎</button></td></tr>
         <tr id=acc_row2><td id="acc_name2" class="accname">Credit Card</td><td id=acc_balance2 class="accbal">$1362.21<button class="edit_account" data-modal-target="#modal" id="editaccounts">✎</button></td></tr>
         <tr id=acc_row3><td id="acc_name3" class="accname">Checking Account</td><td id=acc_balance3 class="accbal">$4322.50<button class="edit_account" data-modal-target="#modal" id="editaccounts">✎</button></td></tr>
         <tr id=acc_row4><td id="acc_name4" class="accname">Savings Account</td><td id=acc_balance4 class="accbal">$12322.50<button class="edit_account" data-modal-target="#modal" id="editaccounts">✎</button></td></tr>
    </table><div><h4 id="acc">&nbsp<button data-modal-target="#modal" class="add_account" id="editaccounts">+</button></h4></div></div>
    <div class="Stocks & Commodeties">
      <br><button type="button" class="collapsible"><h3>&nbsp;Stocks & Commodeties</h3></button>
      <div class="content" id="acc_list"><table class="acc_table" id="acc_table">
        <tr id=acc_row1><td id="acc_name1" class="accname">DOW JONES 50 TITANS</td><td id="acc_balance1" class="accbal">$5322.54<button class="edit_account" data-modal-target="#modal" id="editaccounts">✎</button></td></tr>
        <tr id=acc_row2><td id="acc_name2" class="accname">Oil Certificates</td><td id=acc_balance2 class="accbal">$1362.21<button class="edit_account" data-modal-target="#modal" id="editaccounts">✎</button></td></tr>
        <tr id=acc_row3><td id="acc_name3" class="accname">AAPL</td><td id=acc_balance3 class="accbal">$4322.50<button class="edit_account" data-modal-target="#modal" id="editaccounts">✎</button></td></tr>
        <tr id=acc_row4><td id="acc_name4" class="accname">Physical Gold</td><td id=acc_balance4 class="accbal">$12322.50<button class="edit_account" data-modal-target="#modal" id="editaccounts">✎</button></td></tr>
   </table><div><h4 id="acc">&nbsp<button data-modal-target="#modal" class="add_account" id="editaccounts">+</button></h4></div></div>
    </div>
    <div class="Digital Currencies">
      <br><button type="button" class="collapsible"><h3>&nbsp;Digital Currencies</h3></button>
      <div class="content" id="acc_list"><table class="acc_table" id="acc_table">
        <tr id=acc_row1><td id="acc_name1" class="accname">Bitcoin</td><td id="acc_balance1" class="accbal">$5322.54<button class="edit_account" data-modal-target="#modal" id="editaccounts">✎</button></td></tr>
        <tr id=acc_row2><td id="acc_name2" class="accname">Ethereum</td><td id=acc_balance2 class="accbal">$1362.21<button class="edit_account" data-modal-target="#modal" id="editaccounts">✎</button></td></tr>
        <tr id=acc_row3><td id="acc_name3" class="accname">Chainlink</td><td id=acc_balance3 class="accbal">$4322.50<button class="edit_account" data-modal-target="#modal" id="editaccounts">✎</button></td></tr>
        <tr id=acc_row4><td id="acc_name4" class="accname">DAI</td><td id=acc_balance4 class="accbal">$12322.50<button class="edit_account" data-modal-target="#modal" id="editaccounts">✎</button></td></tr>
      </table><div><h4 id="acc">&nbsp<button data-modal-target="#modal" class="add_account" id="editaccounts">+</button></h4></div></div>
   </div>
    </div>

Modal JS:

const openModalButtons = document.querySelectorAll("[data-modal-target]");
const closeModalButtons = document.querySelectorAll("[data-close-button]");
const overlay = document.getElementById("overlay");

openModalButtons.forEach(button => {
  button.addEventListener("click", () => {
    const modal = document.querySelector(button.dataset.modalTarget)
    openModal(modal)
  })
})

overlay.addEventListener("click", () =>{
  const modals = document.querySelectorAll(".modal.active")
  modals.forEach(modal => {
    closeModal(modal)
  })
})

closeModalButtons.forEach(button => {
  button.addEventListener("click", () => {
    const modal = button.closest(".modal")
    closeModal(modal)
  })
})

function openModal(modal) {
  if (modal == null) return
  modal.classList.add("active");
  overlay.classList.add("active");
}
function closeModal(modal) {
  if (modal == null) return
  modal.classList.remove("active");
  overlay.classList.remove("active");
}

My attempt at making the table editable JS:

function edit_account(no)
{
 var accountname=document.getElementById("acc"+no);
 var accountbalance=document.getElementById("balance"+no);

 var accountname_data=accname.innerHTML;
 var accountbalance_data=accbalance.innerHTML;

 accname.innerHTML="<input type='text' id='accname_text"+no+"' value='"+accname_data+"'>";    
 accbalance.innerHTML="<input type='text' id='accbalance_text"+no+"' value='"+accbalance_data+"'>";
}

function save_account(no)
{
 var name_val=document.getElementById("accname_text"+no).value;
 var balance_val=document.getElementById("accbalance_text"+no).value;

 document.getElementById("acc"+no).innerHTML=name_val;
 document.getElementById("balance"+no).innerHTML=balance_val;
}

function delete_account(no)
{
 document.getElementById("acc"+no+"").outerHTML="";
}

function add_account()
{
 var new_acc=document.getElementById("new_acc").value;
 var new_balance=document.getElementById("new_balance").value;
 
 var list=document.getElementById("acc_list");
 var list_len=(table.rows.length)-1;
 var row = table.insertRow(table_len).outerHTML="<tr id='row"+table_len+"'><td id='acc_name"+table_len+"'>"+new_acc+"</td><td id='acc_balance"+table_len+"'>"+new_balance+"</td></tr>";

 document.getElementById("new_acc").value="";
 document.getElementById("new_balance").value="";
}
schinken82
  • 43
  • 9
  • 1
    1. For the modal title, give it an ID and set the text with jquery when you show the modal and you can make it say edit or add as you want. No need for separate modals – Phaelax z Sep 30 '20 at 13:22
  • 1
    As for editable tables, there's all kinds of jquery plugins. If you wish to use your own, you could try contentEditable attribute, though if I recall that may have some issues with tables. Another option is to make the cells text fields; with CSS you could make them look like normal cells. – Phaelax z Sep 30 '20 at 13:29
  • thanks for the reply. I'll def try the advice from your first comment. Regarding editing the table, I want the table to be editable through the modal, not directly. How would I go about that? – schinken82 Sep 30 '20 at 13:42
  • 1
    So I understand, your modal would be like a form or something and then update particular cells in the table? I thought you meant the table would be in the modal itself. If you assign an ID to each row (TR), when you open the modal you can grab the data from that row to prepopulate the modal and upon confirmation copy that data into the cells of the corresponding row. Are you using bootstrap for your modals? – Phaelax z Sep 30 '20 at 14:29
  • Yeah grabbing the data from the table for the input field on the modal is what I mean. I'm not using bootstrap. It's just html and js (3rd bit of code in my Question). – schinken82 Sep 30 '20 at 15:24

1 Answers1

2

ID values should always be unique.

Sorry, when I wrote this I was thinking you were using jquery. Still, it should get you onto the right path.

    $(function () {
    // add click action to your edit buttons
    $('.edit_account').on('click', function(e){
        // get the parent table row
        row = $(e.target).parent().parent();
        
        // get cell data
        c = row.children();
        name = c[0].textContent;
        amount = c[1].textContent;
        
        // populate modal with data from selected table row
        $('#modal_type').val(name);
        $('#modal_price').val(amount);
        
        // pass table row ID to the modal
        $('#row_num').val(row.attr('id'));
        
    });
    
    // On modal save
    $('#save').on('click', function(){
        // get the table row ID that was passed to the modal
        row_id = $('#row_num').val();
        // get the table row to update
        row = $('#'+row_id);
        
        // update the table row's cells with data from the modal fields
        c = row.children();
        $(c[0]).text($('#modal_type').val()); // name
        $(c[1]).text($('#modal_price').val()); // price
    });
    
});

The fields in your modal would be something like this:

<input type="hidden" id="row_num" value=""/>
<input id="modal_type" type="text" value=""><br/>
<input id="modal_price" type="text" value="">

Without jquery:

$(function () {
    // add click action to your edit buttons
    $('.edit_account').on('click', function(e){
        // get the parent table row
        row = e.target.parentElement.parentElement;
        
        // get cell data
        c = row.childNodes;
        name = c[0].textContent;
        amount = c[1].textContent;
        
        // populate modal with data from selected table row
        document.getElementById('modal_type').value = name;
        document.getElementById('modal_price').value = amount;
        
        // pass table row ID to the modal
        document.getElementById('row_num').value = row.getAttribute('id');
    });
    
    // On modal save
    document.getElementById('save').addEventListener('click', function(){
        // get the table row ID that was passed to the modal
        //row_id = $('#row_num').val();
        row_id = document.getElementById('row_num').value;
        
        // get the table row to update
        //row = $('#'+row_id);
        row = document.getElementById(row_id);
        
        // update the table row's cells with data from the modal fields
        //c = row.children();
        c = row.childNodes;
        
        c[0].textContent = document.getElementById('modal_type').value;  // name
        c[1].textContent = document.getElementById('modal_price').value; // price
        
    });
    
});
Phaelax z
  • 1,814
  • 1
  • 7
  • 19
  • Thanks for taking the time! I figured out how to change the title and am going to try this next. – schinken82 Sep 30 '20 at 16:41
  • Good news is it works! The text is showing up in the modal. I can't quite get the saving to work though. I have a save button in the modal, but it doesn't do anything. ``` ``` Do I need to add an ID to match the JS? – schinken82 Sep 30 '20 at 16:55
  • 1
    The modal save was using jquery for the event. You need to add an event listener to the button. document.getElementById("save").addEventListener("click", function() { // add logic here (the modal save) }); – Phaelax z Sep 30 '20 at 17:21
  • Awesome, thanks mate! Editing and saving works. Last challenge is how would I go about writing an "add new row" function? – schinken82 Sep 30 '20 at 17:58
  • 1
    https://stackoverflow.com/questions/46385850/creating-a-new-element-with-javascript – Phaelax z Sep 30 '20 at 18:50