How to create a hash of an html table

1

Good morning, my doubt arises on an html table in which I am storing the payroll payments of a company, however different models participate in this view, my question is mainly on how to send the tr and td generated in my table to the controller to later be able to separate the different hashes and save them in their corresponding model.

My table is this:

<table id = "mytable">
      <thead>
        <tr>
          <th>Week</th>
          <th>Employee</th>
          <th>Department</th>
          <th>obra</th>
          <th class:'totaldias' style="display: true;" id= "jueves">Jueves</th>
          <th class:'totaldias' id= "viernes">Viernes</th>
          <th class:'totaldias' id= "sabado">Sabado</th>
          <th class:'totaldias' id= "domingo">Domingo</th>
          <th class:'totaldias' id= "lunes">Lunes</th>
          <th class:'totaldias' id= "martes">Martes</th>
          <th class:'totaldias' id= "miercoles">Miercoles</th>
          <th class:'totaldias' id= "total-dias">Dias trabajados</th>
          <th class:'totaldias' id= "vacaciones">Dias vacaciones</th>
          <th class:'totaldias' id= "faltas">Faltas</th>
          <th><%= link_to "Total Sueldo Bruto","#", id: "mostrarDias", remote: true%></th><!-- 13 -->
          <th>Bonos</th>
          <th>Flete</th>
          <th>Incapacidad</th>
          <th>Vacaciones</th>
          <th>Finiquito</th>
          <th>Total percepciones</th><!-- 19 -->
          <th>Caja de Ahorro</th>
          <th>Prestamo Aporta</th>
          <th>Prestamo</th>
          <th>Comida</th>
          <th>Uniforme</th>
          <th>Pensión Alimenticia</th>
          <th>Infonavit</th>
          <th>Fonacot</th>
          <th>Total retenciones</th><!-- 28 -->
          <th>Sueldo fiscal</th>
          <th>Total sueldo neto</th>
          <th colspan="3"></th>
        </tr>
      </thead>


      <tbody>
        <% @payroll.each do |payroll| %>

            <div style= "display: none"><%= ad = ad(payroll.id) %></div>
          <tr>
            <th><%= payroll.week_id %></th>
            <th><%= payroll.employee.fullname %></th>
            <th><%= payroll.department.name %></th>
            <th><%= payroll.employee_wd.construction_work.name rescue 'base' %></th>
            <td class:'totaldias' contenteditable= true onblur=sumDias(getRowIndex(this)) ><%= payroll.employee_wd.jueves rescue 0 %></td>
            <td class:'totaldias' contenteditable= true onblur=sumDias(getRowIndex(this)) ><%= payroll.employee_wd.viernes rescue 0%></td>
            <td class:'totaldias' contenteditable= true onblur=sumDias(getRowIndex(this)) ><%= payroll.employee_wd.sabado rescue 0 %></td>
            <td class:'totaldias' contenteditable= true onblur=sumDias(getRowIndex(this)) ><%= payroll.employee_wd.domingo rescue 0 %></td>
            <td class:'totaldias' contenteditable= true onblur=sumDias(getRowIndex(this)) ><%= payroll.employee_wd.lunes rescue 0 %></td>
            <td class:'totaldias' contenteditable= true onblur=sumDias(getRowIndex(this)) ><%= payroll.employee_wd.martes rescue 0 %></td>
            <td class:'totaldias' contenteditable= true onblur=sumDias(getRowIndex(this)) ><%= payroll.employee_wd.miercoles rescue 0 %></td>
            <th class:'totaldias'><%= payroll.dias_trabajados %></th><!-- Dias Trabajados    -->
            <th class:'totaldias'><%= payroll.dias_vacaciones %></th><!-- Dias de Vacaciones    -->
            <td class:'totaldias' contenteditable= true ><%= payroll.faltas %></th><!-- Faltas    -->
            <th class:'totaldias'><%= payroll.total_sueldo_bruto %></th><!-- total sueldo bruto    -->


            <td contenteditable= true onblur=adSum(getRowIndex(this))><%= ad[0] %></td>
            <td contenteditable= true onblur=adSum(getRowIndex(this))><%= ad[1] %></td>
            <td contenteditable= true onblur=adSum(getRowIndex(this))><%= ad[2] %></td>
            <td contenteditable= true onblur=adSum(getRowIndex(this))><%= ad[3] %></td>
            <td contenteditable= true onblur=adSum(getRowIndex(this))><%= ad[4] %></td>
            <th><%= payroll.total_percepciones%></th><!--  Total Percepciones   -->
            <td contenteditable= true onblur=adRest(getRowIndex(this))><%= ad[5] %></td>
            <td contenteditable= true onblur=adRest(getRowIndex(this))><%= ad[6] %></td>
            <td contenteditable= true onblur=adRest(getRowIndex(this))><%= ad[7] %></td>
            <td contenteditable= true onblur=adRest(getRowIndex(this))><%= ad[8] %></td>
            <td contenteditable= true onblur=adRest(getRowIndex(this))><%= ad[9] %></td>
            <td contenteditable= true onblur=adRest(getRowIndex(this))><%= ad[10] %></td>
            <td contenteditable= true onblur=adRest(getRowIndex(this))><%= ad[11] %></td>
            <td contenteditable= true onblur=adRest(getRowIndex(this))><%= ad[12] %></td>
            <th><%= payroll.total_retenciones %></th><!-- total retenciones   -->
            <th><%= payroll.sueldo_fiscal %></th><!-- Sueldo fiscal    -->
            <th><%= payroll.total_sueldo_neto %></th><!--total sueldo neto   -->
            <td>
            <input type="Submit" />
          </tr>
        <% end %>
      </tbody>
    </table>

Or if there is a gem that can be used to perform this action, I am new to rails and I really have no idea how to perform this action.

I thank you in advance for your help.

  

Edited:

In this case, what I want is to send the data contained in the td contained in the tbody, in this case I do not know how to send this information, it had occurred to me to make a form_for per row and a for_form that contains all of them with the submit that sends the information, but the truth I do not know what is the best way to do it. In itself what I want is to send the data that is entered into the table and in turn the information contained in the variable payroll.

And I mean with the hash of hashes that I want to send all the lines contained in the tbody with a single click on 'save', since each row would be a record to be made of payroll.

  

Edited

Modify my table as follows:

          <tbody>
        <%form_tag({controller: "payrolls", action: "create"}, method: "post", class: "nifty_form", remote: true) do%>
          <% @payroll.each do |payroll| %>

              <div style= "display: none"><%= ad = ad(payroll.id) %></div>
            <tr>
              <td><%=(:week_id,  payroll.week_id) %></th>
              <td><%= text_field_tag(:employee_name, payroll.employee.fullname) %></th>
              <td><%=text_field_tag(:department_name,  payroll.department.name) %></th>

              <td onblur=sumDias(getRowIndex(this)) ><%= text_field_tag(:jueves, payroll.employee_wd.jueves)%></td>
              <td onblur=sumDias(getRowIndex(this)) ><%= text_field_tag(:viernes, payroll.employee_wd.viernes)%></td>
              <td onblur=sumDias(getRowIndex(this)) ><%= text_field_tag(:sabado, payroll.employee_wd.sabado) %></td>
              <td onblur=sumDias(getRowIndex(this)) ><%=text_field_tag(:domingo, payroll.employee_wd.domingo) %></td>
              <td onblur=sumDias(getRowIndex(this)) ><%= text_field_tag(:lunes,payroll.employee_wd.lunes) %></td>
              <td onblur=sumDias(getRowIndex(this)) ><%= text_field_tag(:martes, payroll.employee_wd.martes)%></td>
              <td onblur=sumDias(getRowIndex(this)) ><%= text_field_tag(:miercoles, payroll.employee_wd.miercoles) %></td>
              <th><%= text_field_tag(:dias_trabajados, payroll.dias_trabajados) %></th><!-- Dias Trabajados    -->
              <th><%=text_field_tag(:dias_vacaciones,  payroll.dias_vacaciones) %></th><!-- Dias de Vacaciones    -->
              <td><%=text_field_tag(:faltas,  payroll.faltas) %></th><!-- Faltas    -->
              <th><%= text_field_tag(:total_sueldo_bruto, payroll.total_sueldo_bruto) %></th><!-- total sueldo bruto    -->

              <td onblur=adSum(getRowIndex(this))><%=text_field_tag(:bonos,  ad[0]) %></td>
              <td onblur=adSum(getRowIndex(this))><%=text_field_tag(:fletes,  ad[1])%></td>
              <td onblur=adSum(getRowIndex(this))><%=text_field_tag(:jueves,  ad[2] )%></td>
              <td onblur=adSum(getRowIndex(this))><%=text_field_tag(:incapacidad,  ad[3]) %></td>
              <td onblur=adSum(getRowIndex(this))><%=text_field_tag(:finiquito,  ad[4]) %></td>
              <td><%=text_field_tag(:total_percepciones,  payroll.total_percepciones)%></th><!--  Total Percepciones   -->

              <td onblur=adRest(getRowIndex(this))><%=text_field_tag(:caja_ahorro,  ad[5]) %></td>
              <td onblur=adRest(getRowIndex(this))><%=text_field_tag(:prestamo_aporta,  ad[6]) %></td>
              <td onblur=adRest(getRowIndex(this))><%=text_field_tag(:prestamo,  ad[7] )%></td>
              <td onblur=adRest(getRowIndex(this))><%=text_field_tag(:comida,  ad[8]) %></td>
              <td onblur=adRest(getRowIndex(this))><%= text_field_tag(:uniforme, ad[9]) %></td>
              <td onblur=adRest(getRowIndex(this))><%= text_field_tag(:pension_alimenticia, ad[10] )%></td>
              <td onblur=adRest(getRowIndex(this))><%= text_field_tag(:infonavit, ad[11]) %></td>
              <td onblur=adRest(getRowIndex(this))><%= text_field_tag(:fonacot, ad[12]) %></td>
              <td><%=text_field_tag(:total_retenciones,  payroll.total_retenciones) %></th><!-- total retenciones   -->

              <td><%=text_field_tag(:sueldo_fiscal,  payroll.sueldo_fiscal) %></th><!-- Sueldo fiscal    -->
              <td><%= text_field_tag(:total_sueldo_neto, payroll.total_sueldo_neto) %></th><!--total sueldo neto   -->
          <% end %>
          <%= submit_tag("guardar") %>
        <% end %>
      </tbody>

However, it shows me the page with no data or form to fill out, only the headings of the table since those are outside the. I hope you can help me.

    
asked by Daniel Romero 18.05.2017 в 23:28
source

2 answers

1

I think I understand what you want. The best thing is to create a unique form and nest your associations within it instead of doing forms for each row (unless you really need it). If you do not know how to make nested forms, the Rails documentation shows the changes you should make. Now regarding the problem itself, the options I see are:

  • If you use contenteditable in the td, that can not be reached and sent in a form. You must create hidden type inputs for each of your editable td and use js to be able to copy the content. Do something like:

    function copyContent () {
        document.getElementById("tuInputOculto").value =  
            document.getElementById("tuTdEditable").innerHTML;
        return true;
    }
    
    
    <form action='whatever' onsubmit='return copyContent()'>
    
  • Instead of using <td contenteditable= true>...</td> , simply use <td><input/></td> within your table and with css adjust the style of the input to make it seem more part of the table and not an input.

  • Use a js library that creates you editable tables. I could not recommend it, since I've never used one, but you could review any of these or just googlear .

If you ask me, I would go for option two since it is easier to implement within what is the ecosystem rails. Option 3 I "think" that libraries should be very similar to option one regarding what bookstores do underneath, but made it easy, although of course, there is the learning curve of using a new library, but it can reach be a good option if you look good. I see it quite cumbersome to create N inputs for editable td that exists and then handle it with js, but it is still an option if you want to continue in the line that you started.

    
answered by 19.05.2017 / 18:31
source
1

You could use javascript / jQuery to read the values in the table, save them in a form (in input type hidden ) and send that form.

Check the following example, for which I use a reduced and simplified version of your table.

Table

First we must make sure that we can clearly identify what payroll belongs to each record, and we can do this by adding the attribute name in each td :

<table id="mytable">
  <tbody>
    <% @payroll.each do |payroll| %>
      <tr>
        <td name="<%= payroll.id %>" class='totaldias' contenteditable='true'><%= payroll.employee_wd.jueves rescue 0 %></td>
        <td name="<%= payroll.id %>" class='totaldias' contenteditable='true'><%= payroll.employee_wd.viernes rescue 0 %></td>
        <td name="<%= payroll.id %>" class='totaldias' contenteditable='true'><%= payroll.employee_wd.sabado rescue 0 %></td>
        <td name="<%= payroll.id %>" class='totaldias'><%= payroll.dias_trabajados %></td>
        <td name="<%= payroll.id %>" class='totaldias'><%= payroll.dias_vacaciones %></td>
        <td name="<%= payroll.id %>" class='totaldias' contenteditable='true'><%= payroll.faltas %></td>
        <td name="<%= payroll.id %>" class='totaldias'><%= payroll.total_sueldo_bruto %></td>
      </tr>
    <% end %>
  </tbody>
</table>

Form

We need to generate a form that contains a input type hidden for each of the payroll available, therefore it should also be dynamic 1 :

<form id="my-form" action="/tu_accion" method="post">
  <% @payroll.each do |payroll| %>
    <input type="hidden" id="table_<%= payroll.id %>" name="table[<%= payroll.id %>]">
  <% end %>

  <%= hidden_field_tag :authenticity_token, form_authenticity_token %>
  <input type="button" id="envia-forma" value="Enviar" />
</form>

The id attribute in the input helps us identify the appropriate input when grouping the data; the attribute that name serves us to be able to recognize the group in the controller (through params[payroll.id] )

Script

Finally we add the script (I use jQuery in this example) to be able to assign the values in the form and send it:

<script type="text/javascript">
  $(document).ready(function() {
    $("#envia-forma").click(function(){
      $("td.totaldias").each( function() {
        let name  = $(this).attr('name');
        let value = $(this).html();

        $("#table_" + name).val($("#table_" + name).val() + value + ",")
      });

    $("#my-form").submit();
    });
  });
</script>

Finally, in your controller you can find the values of td in params , which you will receive separated by comma and grouped by payroll.id ; for example (for a payroll with p1 as a value of id :

values = params[:p1].chomp(",").split(",")
#=> ["valortd1", "valortd2", ...]

And values will have an array with the values of each td belonging to payroll with p1 .

    
answered by 19.05.2017 в 18:43