JSFiddle - React, Tailwind, and code Playground

by Norelys Rumbos

HTML

<div class="box-body">
  <table id="transactional-channels" class="table table-striped table-bordered">
    <thead>
      <tr>
        <th>Canales / Transacciones</th>
        <th>Pagos de clientes</th>
        <th>Entregas a clientes</th>
        <th>Gariantías, Quejas e Información a clientes</th>
        <th>Ventas</th>
        <th>Otras Transacciones</th>
        <th>Total</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>Web</td>
        <td>
          <input id="transactional_channel_payment_web" class="form-control percentage" type="number" name="transactional_channel[payment][web]" min="0" step="0.01" data-channel="web" value="">
        </td>
        <td>
          <input id="transactional_channel_delivery_web" class="form-control percentage" type="number" name="transactional_channel[delivery][web]" min="0" step="0.01" data-channel="web" value="">
        </td>
        <td>
          <input id="transactional_channel_information_web" class="form-control percentage" type="number" name="transactional_channel[information][web]" min="0" step="0.01" data-channel="web" value="">
        </td>
        <td>
          <input id="transactional_channel_sales_web" class="form-control percentage" type="number" name="transactional_channel[sales][web]" min="0" step="0.01" data-channel="web" value="">
        </td>
        <td>
          <input id="transactional_channel_other_web" class="form-control percentage" type="number" name="transactional_channel[other][web]" min="0" step="0.01" data-channel="web" value="">
        </td>
        <td>
          <input id="transactional_channel_total_web" class="form-control percentage-total" type="number" name="transactional_channel[total][web]" min="0" step="0.01" value="">
        </td>
      </tr>
      <tr>
        <td>Móvil</td>
        <td>
          <input id="transactional_channel_payment_mobile" class="form-control percentage" type="number" name="transactional_channel[payment][mobile]" min="0" step="0.01"...

JavaScript

// Porcentaje restante del presupuesto de cada canal
  var channels = {
    "web": 100,
    "mobile": 100,
    "social_networks": 100,
    "online_banks": 100,
    "offline_banks": 100,
    "call_centers": 100,
    "retail": 100,
    "delivery": 100,
    "sales_agents": 100,
    "maintenance": 100
  };

  // Porcentaje que queda del presupuesto a distribuir entre todos los canales.
  var total = 100;

  // Funcion:
  //  Una vez cargada la pagina actualiza las variables channels y total
  function calculate_accum() {
    $.each(channels, function(key, value) {
      $("input[data-channel='" + key + "']").each(function() {
        channels[key] -= $(this).val();
      });
    });

    $(".percentage-total").each(function() {
      total -= $(this).val();
    });
  };

  // Funcion
  //  Permite obtener el valor previo de un input antes de ser cambiado
  function prev_value(elem) {
    !(elem.val()) ? elem.data('val', 0): elem.data('val', elem.val());
  };

  // Funcion
  //  Permite colocar en el input correspondiente el mayor valor posible
  function set_correct_value(elem, params) {
    var correct_val = (params["current"] > params["maximmun"]) ? params["maximmun"] : params["current"];


    if (params["current"] > params["maximmun"]) {
      elem.val(correct_val);
      alert(params["message"]);
    };

    return correct_val;
  }



  calculate_accum();
  alert("hola 4");

  $(".percentage, .percentage-total").on("focusin", function() {
    alert("hola 3");
    prev_value($(this));
  });

  $(".percentage").on("change", function() {
    var elem = $(this);
    var this_channel = elem.attr("data-channel");
    channels[this_channel] += elem.data('val');

    var params {
      "current": elem.val(),
      "maximmun": channels[this_channel],
      "message": "Recuerda que el presupuesto para las transaccones de cada canal no puede exceder del 100%",
    };
    alert("hola 1");

    channels[this_channel] -= set_correct_value(elem, params);
  });

 ...