Search code examples
javascripthtmljqueryarrayshighlight

Highlight div based on highest number


I am trying to highlight a value in a div that is the lowest value in an array.

When the user completes each input row (design outlet and actual outlet) the outletIndex() function is called which calculates the percentage and pushes the value into an array. This part I have working.

Then what I am trying to do is find the lowest number in that array and highlight the div (proportion). I want this to be dynamic so as the user completes each input row the percentage is calculated and the lowest index value is highlighted progressively.

I am using querySelectorAll() to match the div class value to the lowest index value but Im not sure if I need to parse a nodeList to match the value of the indexArray?

I am also wondering that if a mistake is typed into the fields and added to the Index array and it happens to be the lowest index it wont match the index values that are shown on the HTML and not call the function.

  document.querySelector('#outlet_actual_1').addEventListener('keypress', function(e) {
     
    if (e.key === 'Enter') {
        let actual = document.getElementById("outlet_actual_1").valueAsNumber || 0;
        let design = document.getElementById("outlet_design_1").valueAsNumber || 0;
        let result1 = outletIndex(actual, design);
         if (!isNaN(result1)) {
            document.getElementById("percentage").textContent = `${result1.toFixed(1)}%`;
        }  
    }   
});
document.querySelector('#outlet_actual_2').addEventListener('keypress', function(e) {
   
    if (e.key === 'Enter') {
        let actual = document.getElementById("outlet_actual_2").valueAsNumber || 0;
        let design = document.getElementById("outlet_design_2").valueAsNumber || 0;
        let result1 = outletIndex(actual, design);
         if (!isNaN(result1)) {
            document.getElementById("percentage2").textContent = `${result1.toFixed(1)}%`;
        }  
    }   
});
document.querySelector('#outlet_actual_3').addEventListener('keypress', function(e) {
    
    if (e.key === 'Enter') {
        let actual = document.getElementById("outlet_actual_3").valueAsNumber || 0;
        let design = document.getElementById("outlet_design_3").valueAsNumber || 0;
        let result1 = outletIndex(actual, design);
         if (!isNaN(result1)) {
            document.getElementById("percentage3").textContent = `${result1.toFixed(1)}%`;
        }  
    }   
});
const indexArray = [];
function outletIndex(a, b) {    
    let result = a / b * 100;    
   if (!isNaN(result)) {
        indexArray.push(+result.toFixed(2));
        indexFindandHighlight();  
    } 
    console.log(indexArray, result);
    return result; 
}

function indexFindandHighlight(){
    const lowestIndex = Math.min(...indexArray);
    const indexCheck = document.querySelectorAll('.proportion').valueAsNumber || 0;
    console.log(lowestIndex);
    if (lowestIndex == indexCheck) {
        $(document).ready(function() {

            $("#outlet_actual_1", "#outlet_actual_2", "#outlet_actual_3").onchange(function(){
               $(".proportion").effect( "highlight", {color:"#669966"}, 3000 );
            });
         });
    } 
}; 
    <table>
      <tr>
        <div class="form-group row 1" id="outlets1">
          <td><label
            >Outlet Design</label>
            <input
              name = "outlet 1 design"
              class="form-control design_1"
              id="outlet_design_1"
              type="number"
              placeholder="Outlet 1 Design"
              onkeydown="outletIndex();"
            />
          </td>
          <td><label
            >Outlet Actual</label>
            <input
            name="outlet 1 actual"
              class="form-control actual_1"
              id="outlet_actual_1"
              type="number"
              placeholder="Outlet 1 Actual"
              onkeydown="outletIndex();"
            />
          </td>
          <td><label
            >Outlet Balance</label>
            <input
              name="outlet_balance"
              class="form-control"
              input value=""
              id="outlet_balance_1"
              type="text" 
              placeholder="Outlet 1 Balance"        
            />
          </td><td>
            <div class="proportion" id="percentage">

            </div>
          </td>
        </div>
      </tr>
      <tr>
      <div class="form-group row 2" id="outlets2">
        <td>
          <input
            name="outlet_design"
            class="form-control design_2"
            id="outlet_design_2"
            type="number"
            placeholder="Outlet 2 Design"
            onkeydown="outletIndex();"
          />
        </td>
        <td>
          <input
            name="outlet_actual"
            class="form-control actual_2"
            id="outlet_actual_2"
            type="number"
            placeholder="Outlet 2 Actual"
            onkeydown="outletIndex();"
          />
        </td>
        <td>
          <input
            name="outlet_balance"
            class="form-control"
            id="outlet_balance_2"
            type="number" 
            placeholder="Outlet 2 Balance"        
          />
        </td><td>
          <div class="proportion" id="percentage2">

          </div>
        </td>
      </div></tr>
        <tr>
            <div class="form-group row 3" id="outlets3">
              <td>
                <input
                  name="outlet_design"
                  class="form-control design_3"
                  id="outlet_design_3"
                  type="number"
                  placeholder="Outlet 3 Design"
                  onkeydown="outletIndex();"
                />
              </td>
              <td>
                <input
                  name="outlet_actual"
                  class="form-control actual_3"
                  id="outlet_actual_3"
                  type="number"
                  placeholder="Outlet 3 Actual"
                  onkeydown="outletIndex();"
                />
              </td>
              <td>
                <input
                  name="outlet_balance"
                  class="form-control"
                  id="outlet_balance_3"
                  type="number" 
                  placeholder="Outlet 3 Balance"        
                />
              </td><td>
                <div class="proportion" id="percentage3">
      
                </div>
              </td>
            </div></tr>
      </div>
    </table>
  </fieldset>
</form>
</div>


Solution

  • Multiple issues:

    1. Clean up HTML
    2. Reuse code
    3. Consistency, Either use jquery or javascript
    4. Separate UI changes from data change.
    5. Consistency, Bind event listener either using HTML or javascript file.

    Please check below sample

    const number = (str) => Number(str) || 0;
    
    const bind = (id) => {
      function onBind(e) {
        let actual = number(document.querySelector(`#outlet_actual_${id}`).value);
        let design = number(document.querySelector(`#outlet_design_${id}`).value);
        let result1 = percentage(actual, design);
        if (!isNaN(result1)) {
          document.querySelector(
            `#percentage_${id}`
          ).textContent = `${result1.toFixed(1)}%`;
        }
        updateIndex(id, result1);
        highlight();
      }
      document
        .querySelector(`#outlet_actual_${id}`)
        .addEventListener("change", onBind);
      document
        .querySelector(`#outlet_design_${id}`)
        .addEventListener("change", onBind);
    };
    
    function percentage(a, b) {
      return b === 0 ? 0 : (a / b) * 100;
    }
    let percentages = [];
    function updateIndex(id, value) {
      percentages[id - 1] = value;
    }
    
    function highlight() {
      let minIndex = -1;
      let minValue = Number.MAX_SAFE_INTEGER;
      for (let index in percentages) {
        if (percentages[index] < minValue) {
          minIndex = Number(index);
          minValue = percentages[index];
        }
      }
      if (minIndex === -1) return;
    
      document.querySelector(`#percentage_${minIndex + 1}`).style.color = "red";
      setTimeout(() => {
        document.querySelector(`#percentage_${minIndex + 1}`).style.color = "black";
      }, 3000);
    }
    bind(1);
    bind(2);
    bind(3);
    <table>
          <tr>
            <div class="form-group row 1" id="outlets1">
              <td><label
                >Outlet Design</label>
                <input
                  name = "outlet 1 design"
                  class="form-control design_1"
                  id="outlet_design_1"
                  type="number"
                  placeholder="Outlet 1 Design"
                  
                />
              </td>
              <td><label
                >Outlet Actual</label>
                <input
                name="outlet 1 actual"
                  class="form-control actual_1"
                  id="outlet_actual_1"
                  type="number"
                  placeholder="Outlet 1 Actual"
                  
                />
              </td>
              <td><label
                >Outlet Balance</label>
                <input
                  name="outlet_balance"
                  class="form-control"
                  input value=""
                  id="outlet_balance_1"
                  type="text" 
                  placeholder="Outlet 1 Balance"        
                />
              </td><td>
                <div class="proportion" id="percentage_1">
    
                </div>
              </td>
            </div>
          </tr>
          <tr>
          <div class="form-group row 2" id="outlets2">
            <td>
              <input
                name="outlet_design"
                class="form-control design_2"
                id="outlet_design_2"
                type="number"
                placeholder="Outlet 2 Design"
              />
            </td>
            <td>
              <input
                name="outlet_actual"
                class="form-control actual_2"
                id="outlet_actual_2"
                type="number"
                placeholder="Outlet 2 Actual"
                
              />
            </td>
            <td>
              <input
                name="outlet_balance"
                class="form-control"
                id="outlet_balance_2"
                type="number" 
                placeholder="Outlet 2 Balance"        
              />
            </td><td>
              <div class="proportion" id="percentage_2">
    
              </div>
            </td>
          </div></tr>
            <tr>
                <div class="form-group row 3" id="outlets3">
                  <td>
                    <input
                      name="outlet_design"
                      class="form-control design_3"
                      id="outlet_design_3"
                      type="number"
                      placeholder="Outlet 3 Design"
                      
                    />
                  </td>
                  <td>
                    <input
                      name="outlet_actual"
                      class="form-control actual_3"
                      id="outlet_actual_3"
                      type="number"
                      placeholder="Outlet 3 Actual"
                      
                    />
                  </td>
                  <td>
                    <input
                      name="outlet_balance"
                      class="form-control"
                      id="outlet_balance_3"
                      type="number" 
                      placeholder="Outlet 3 Balance"        
                    />
                  </td><td>
                    <div class="proportion" id="percentage_3">
          
                    </div>
                  </td>
                </div></tr>
          </div>
        </table>
      </fieldset>
    </form>
    </div>