skip to Main Content

I am trying to find a solution to where the row cannot be added unless the required fields are filled out. I also tried to do a couple validators for the modals but the ones that seemed like they should have worked, would submit the form for the row but then restart the initial form from the top and not put a new row in.
(There are two tables and modals but just putting one up for spacial reasons BUT can post the second if necessary)

The Table in the main form

<!--Task Table-->
<div class="tasks-section">
  <h2>Tasks</h2>
  <table >
    <thead>
      <tr>
        <th>Scheduled Date/Time</th>
        <th>Location</th>
        <th>Tasks</th>
        <th>UOM</th>
        <th>Estimated Qty</th>
        <th>Task Notes</th>
        <th>Remaining Qty</th>
        <th>Estimated Revenue</th>
        <th>Assigned Crew Lead</th>
        <th>Assigned Field Crew(s)</th>
      </tr>
    </thead>
    <tbody id="myTable">
    <!-- Task Rows will be dynamically added here -->
    </tbody>
  </table>
  <!-- Trigger/Open The modal -->
  <button class="modal-button" href="#mymodal1">+ Add New</button>
</div><br>

The modal to insert a row:

<div id="myModal1" class="modal">   <!-- The Modal     -->
  <div class="modal-content">       <!-- Modal content -->
    <div class="modal-header">
      <span class="close">&times;</span>
      <h2>Add New Task</h2>
      <form id="new-task-form">
        <label for="scheduled-datetime-1">Scheduled Date/Time:</label>
        <input type="datetime-local" id="scheduled-datetime-1" name="scheduled-datetime-1" min="" required>

        <label for="location">Location:</label>
        <input type="text" id="location" name="location" required>

        <label for="task">Task:</label>
        <select id="task" name="task" required>
          <!-- Options for tasks will be dynamically populated -->
          <option value="" disabled selected>-Select-</option>
          <!-- Placeholder option -->
          <option value="Choice 1">Choice 1</option>
        </select>

        <label for="uom">UOM:</label>
        <input type="text" id="uom" name="uom">

        <label for="estimated-qty">Estimated Qty:</label>
        <input type="number" id="estimated-qty" name="estimated-qty" placeholder="#######" required>

        <label for="task-notes">Task Notes:</label>
        <textarea id="task-notes" name="task-notes"></textarea>

        <label for="remaining-qty">Remaining Qty:</label>
        <input type="number" id="remaining-qty" name="remaining-qty">

        <label for="estimated-revenue">Estimated Revenue:</label>
        <input type="number" id="estimated-revenue" name="estimated-revenue" placeholder="#,###,###.##">

        <label for="assigned-crew-lead">Assigned Crew Lead:</label>
        <select id="assigned-crew-lead" name="assigned-crew-lead">
          <!-- Options for crew leads will be dynamically populated -->
          <option value="" disabled selected>-Select-</option>
          <!-- Placeholder option -->
          <option value="Choice 1">Choice 1</option>
        </select>

        <label for="assigned-field-crew">Assigned Field Crew(s):</label>
        <select id="assigned-field-crew" name="assigned-field-crew">
          <!-- Options for field crews will be dynamically populated -->
          <option value="" disabled selected>-Select-</option>
          <!-- Placeholder option -->
          <option value="Choice 1">Choice 1</option>
        </select>
        <br><br><br>
        <input type="submit" id="add-task-done" value="Done" onclick="myFunction();">
      </form>
    </div>
    <br><br><br>

The function:

function myFunction() {
  var table = document.getElementById("myTable");
  
  var scheduled_datetime_1 = document.getElementById("scheduled-datetime-1").value;
  var Location             = document.getElementById("location").value;
  var Tasks                = document.getElementById("task").value;
  var UOM                  = document.getElementById("uom").value;
  var Estimated_Qty        = document.getElementById("estimated-qty").value;
  var Task_Notes           = document.getElementById("task-notes").value;
  var Remaining_Qty        = document.getElementById("remaining-qty").value;
  var Estimated_Revenue    = document.getElementById("estimated-revenue").value;
  var Assigned_Crew_Lead   = document.getElementById("assigned-crew-lead").value;
  var Assigned_Field_Crew  = document.getElementById("assigned-field-crew").value;
  
  var row    = table.insertRow(0);
  var cell1  = row.insertCell(0);
  var cell2  = row.insertCell(1);
  var cell3  = row.insertCell(2);
  var cell4  = row.insertCell(3);
  var cell5  = row.insertCell(4);
  var cell6  = row.insertCell(5);
  var cell7  = row.insertCell(6);
  var cell8  = row.insertCell(7);
  var cell9  = row.insertCell(8);
  var cell10 = row.insertCell(9);
  
  cell1 .innerHTML = scheduled_datetime_1 + "<input type='hidden' name='test[]' class='scheduled_datetime_1' value='"+scheduled_datetime_1+"'>";
  cell2 .innerHTML = Location             + "<input type='hidden' name='test[]' class='Location1' value='"+Location+"'>";
  cell3 .innerHTML = Tasks                + "<input type='hidden' name='test[]' class='Tasks1' value='"+Tasks+"'>";
  cell4 .innerHTML = UOM                  + "<input type='hidden' name='test[]' class='UOM1' value='"+UOM+"'>";
  cell5 .innerHTML = Estimated_Qty        + "<input type='hidden' name='test[]' class='Estimated_Qty1' value='"+Estimated_Qty+"'>";
  cell6 .innerHTML = Task_Notes           + "<input type='hidden' name='test[]' class='Task_Notes1' value='"+Task_Notes+"'>";
  cell7 .innerHTML = Remaining_Qty        + "<input type='hidden' name='test[]' class='Remaining_Qty1' value='"+Remaining_Qty+"'>";
  cell8 .innerHTML = Estimated_Revenue    + "<input type='hidden' name='test[]' class='Estimated_Revenue1' value='"+Estimated_Revenue+"'>";
  cell9 .innerHTML = Assigned_Crew_Lead   + "<input type='hidden' name='test[]' class='Assigned_Crew_Lead1' value='"+Assigned_Crew_Lead+"'>";
  cell10.innerHTML = Assigned_Field_Crew  + "<input type='hidden' name='test[]' class='Assigned_Field_Crew1' value='"+Assigned_Field_Crew+"'>";

  modal.style.display = "none";
}

The Validator
when it was in the code I set it as
onclick="validateForm(); MyFunction();"

function validateForm() {
  var scheduled_datetime_1 = document.getElementById("scheduled-datetime-1").value;
  var Location             = document.getElementById("location").value;
  var Estimated_Revenue    = document.getElementById("estimated-revenue").value;

  if ( scheduled_datetime_1 === "" 
    || Location === "" 
    || Estimated_Revenue === "") {
    alert("Must fill out Scheduled Date/Time, Location and Estimated QTY");
    return false; // Prevent form submission and myFunctionN execution
  }
...  

Initially, they were submit and onsubmit buttons but either use would make all of the buttons stop working on both modals for the addition of a new row; along with the main button to submit the entire form.
I also have tried to make a few different versions of a validator (with and without it automatically submitting so it would with the standing functions) but was not able to come to a point where the rows of the table were just inserted without the resetting of the form.

2

Answers


  1. So much easier to code with <dialog> element…

    const
      cNames = 
        [ 'scheduled-datetime-1', 'location', 'task', 'uom'
        , 'estimated-qty', 'task-notes', 'remaining-qty'
        , 'estimated-revenue', 'assigned-crew-lead', 'assigned-field-crew'
        ] 
    , myTable_tBody = document.querySelector('#my-table tbody')
    , BtOpenDial    = document.querySelector('#bt-open-modal')
    , modalDialog   = document.querySelector('#modal-dialog')
    , modalForm     = modalDialog.querySelector('form')
    , btExitDial    = modalDialog.querySelector('span.exit')
      ;
    btExitDial.onclick =_=> modalDialog.close('exit')
      ;
    BtOpenDial.onclick =_=> 
      { 
      modalForm.reset(); 
      modalDialog.showModal(); 
      }
    modalDialog.onclose =_=>
      {
      if (modalDialog.returnValue === 'exit' ) return
        ;
      let 
        vals   = Object.fromEntries(new FormData(modalForm)) 
      , newRow = myTable_tBody.insertRow()
        ;
      cNames.forEach(name => newRow.insertCell().textContent = vals[name] || '' ); 
      }
    body {
      font-family     : Arial, Helvetica, sans-serif;
      font-size       : 14px;
      }
    table {
      background      : darkblue;
      border-collapse : separate;
      border-spacing  : 1px;
      margin-bottom   : .8em;
      }
    table caption {
      font-size   : 1.4rem;
      font-weight : bold;
      padding     : .4em 0;
      }
    th {
      background-color : #7fccff;
      padding          : .4em .6em ;
      }
    td {
      background-color : whitesmoke;
      padding          : .8em .4em;
      text-align       : right;
      }
    label { 
      margin     : .6rem;  
      display    : block;
      font-size  : 0.8rem;
      }
    label * {
      box-sizing : border-box;
      display    : block;
      font-size  : 1rem;
      width      : 16rem;
      padding    : .2rem .3rem;
      }
    select {
      font-style: italic;
      }
    select:focus {
      font-style: normal;
      }
    dialog {
      position      : relative;
      border        : 1px solid black;
      border-radius : .4rem;
      padding       : 0.4rem 0.8rem 0.8rem 0.8rem;
      }
    dialog h2 {
      margin-top    : 0;
      padding-left  : .5rem; 
      }
    dialog button {
      width       : 10rem;
      float       : right;
      margin-top  : .2rem;
      font-weight : bold;
      }
    dialog::backdrop {
      background: #051f68a1;
      }
    dialog span.exit {
      position    : absolute;
      top         : -12px;
      right       : 1px;
      font-size   : 3rem;
      cursor      : pointer;
      color       : #333333;
      caret-color : transparent;
      }
    dialog span.exit:hover {
      transform : scale(1.1);
      color     : #dd0505;
      }
    <table id="my-table">
      <caption> Tasks </caption>
      <thead>
        <tr>
          <th>Scheduled Date/Time</th>
          <th>Location</th>
          <th>Tasks</th>
          <th>UOM</th>
          <th>Estimated Qty</th>
          <th>Task Notes</th>
          <th>Remaining Qty</th>
          <th>Estimated Revenue</th>
          <th>Assigned Crew Lead</th>
          <th>Assigned Field Crew(s)</th>
        </tr>
      </thead>
      <tbody> <!-- Task Rows will be dynamically added here -->
      </tbody>
    </table>
    
    <button id="bt-open-modal">+ Add New</button><!-- Trigger/Open The modal -->
    
    <dialog id="modal-dialog">
      <span class="exit">&times;</span>
      <h2>Add New Task</h2>
      <form method="dialog">
        <label>
          Scheduled Date/Time:
          <input name="scheduled-datetime-1" type="datetime-local" min="" required>
        </label>
        <label>
          Location:
          <input name="location" type="text" required>
        </label>
        <label>
          Task:
          <select name="task" required><!-- tasks will be dynamically populated -->
            <option value="" disabled selected>-Select-</option>  <!-- Placeholder  -->
            <option value="Choice_1">Choice 1</option>
            <option value="Choice_2">Choice 2</option>
            <option value="Choice_3">Choice 3</option>
          </select>
        </label>
        <label>
          UOM:
          <input name="uom" type="text">          
        </label>
        <label>
          Estimated Qty:
          <input name="estimated-qty" type="number" placeholder="#######" required>
        </label>
        <label>
          Task Notes:
          <textarea name="task-notes"></textarea>
        </label>
        <label>
          Remaining Qty:
          <input name="remaining-qty" type="number">
        </label>
        <label>
          Estimated Revenue:
          <input name="estimated-revenue" type="number" placeholder="#,###,###.##">
        </label>
        <label>
          Assigned Crew Lead:
          <select name="assigned-crew-lead">
            <option value="" disabled selected>-Select-</option><!-- crew leads options will be dynamically populated -->
            <option value="Choice_1">Choice 1</option>
            <option value="Choice_2">Choice 2</option>
            <option value="Choice_3">Choice 3</option>
          </select>
        </label>
        <label>
          Assigned Field Crew(s):
          <select name="assigned-field-crew">
            <!-- Options for field crews will be dynamically populated -->
            <option value="" disabled selected>-Select-</option>
            <!-- Placeholder option -->
            <option value="Choice_1">Choice 1</option>
            <option value="Choice_2">Choice 2</option>
            <option value="Choice_3">Choice 3</option>
          </select>
        </label>
        <button type="submit" > Done </button>
      </form>
    </dialog>
    Login or Signup to reply.
  2. Change your submit button to:

    <input type="button" id="add-task-done" value="Done" onclick="validateForm() && myFunction();">
    

    Using type="button" prevents the button from submitting the form. You can also put action="#" in the <form> tag so that submitting it doesn’t have any effect.

    validateForm() && myFunction(); is a conditional construct, because of the way && does short-circuiting. It only calls myFunction() when validateForm() returns a truthy value. So when validation fails you never call myFunction(), and the new row is not added.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search