Using JavaScript to MergeTwo HTML Rows

2019-07-25 05:10发布

I'm giving support to a classic asp WEB application, and I came across the need of building a scheduling board that shows, at the headers, the lines and at the rows the time of the scheduling. What I do is: I verify it there is something schedule for today. If there is, I get the starting and ending time of that schedule, and then, for each of them, I call the function that will write the line:

DIM todayDate: todayDate = year(now()) & "-" & month(now()) &  "-" & day(now())
                        sql = "SELECT schedule_startingHour, schedule_endingHour, line_id FROM tbl_schedule WHERE Convert(date, schedule_startingHour) = '" & todayDate & "';"
                        SET recordSet = conn.execute(sql)
                        DIM starting_hours(18)
                        DIM ending_hours(18)

                        WHILE NOT recordSet.EOF
                            IF recordSet("line_id") <> 0 THEN
                                starting_hours(recordSet("line_id")) = recordSet("schedule_startingHour")
                                ending_hours(recordSet("line_id")) = recordSet("schedule_endingHour")
                            END IF
                            CALL populate_time(starting_hours(recordSet("line_id")), ending_hours(recordSet("line_id")))
                            recordSet.MOVENEXT
                        WEND

That function, populate_time, will then get the information I need from the database, see the differente between the ending and starting time and write one <td> for each hour I have in between and the last time precisely. So the whole algorythm is:

FUNCTION populate_time(startingHour, endingHour)

    sql = "SELECT schedule_id, family_mdt, line_id FROM tbl_schedule AS schedule INNER JOIN tbl_family AS family ON schedule.family_id = family.family_id WHERE schedule_startingHour  = '"&startingHour&"' AND schedule_endingHour = '"&endingHour&"';"
    SET rs = conn.execute(sql)
    DIM scheduled_time(18)
    DIM hoursAmount(18)

    WHILE NOT rs.EOF
        scheduled_time(rs("line_id")) = rs("family_mdt")
        difference = "SELECT DATEDIFF(hour, '"&starting_hours(recordSet("line_id"))&"', '"&ending_hours(recordSet("line_id"))&"') AS difference;"
        SET rs_diff = conn.execute(difference)
        hoursAmount(rs("line_id")) = (rs_diff("difference")+1)
        IF hoursAmount(rs("line_id")) <= 1 THEN
            hoursAmount(rs("line_id")) = 2
        END IF
        timeEmpty = timeEmpty+1
        rs.MOVENEXT
    WEND

    IF timeEmpty = 0 THEN
        'That specific time has nothing scheduled in none of the gold lines.
        ELSE

            'Styling the hours to be shown
            quebra = Chr(32)
            ate = InStr(startingHour, quebra)
            startingHour = Right(startingHour, (ate+1))
            startingHour = Left(startingHour, 2)
            startingHour = Replace(startingHour, ":", ".")
            startingHour = Replace(startingHour, quebra, "")

            IF LEN(startingHour) = 1 THEN
                startingHour = "0"&startingHour&".00"
                ELSE 
                    IF LEN(startingHour) = 2 THEN
                        startingHour = startingHour&".00"
                    END IF
            END IF

            ate = InStr(endingHour, quebra)
            endingHour = Right(endingHour, (ate+1))
            endingHour = Left(endingHour, 5)
            endingHour = Replace(endingHour, ":", ".")
            endingHour = Replace(endingHour, quebra, "")



            'Creates the line of the current time
            FOR r = 1 TO 18 
                FOR i = 1 TO hoursAmount(r) 
                    response.write("<tr class='item'>")
                    IF i=1 THEN
                        response.write("<td>"&startingHour&"</td>")
                        CALL write_time(Array(scheduled_time(1), scheduled_time(2), scheduled_time(3), scheduled_time(4), scheduled_time(5), scheduled_time(6), scheduled_time(7), scheduled_time(8), scheduled_time(9), scheduled_time(10), scheduled_time(11), scheduled_time(12), scheduled_time(13), scheduled_time(14),scheduled_time(15), scheduled_time(16), scheduled_time(17),scheduled_time(18)))
                        ELSE
                            IF i = hoursAmount(r) THEN
                                response.write("<td>"&endingHour&"</td>")
                                CALL write_time(Array(scheduled_time(1), scheduled_time(2), scheduled_time(3), scheduled_time(4), scheduled_time(5), scheduled_time(6), scheduled_time(7), scheduled_time(8), scheduled_time(9), scheduled_time(10), scheduled_time(11), scheduled_time(12), scheduled_time(13), scheduled_time(14),scheduled_time(15), scheduled_time(16), scheduled_time(17),scheduled_time(18)))
                                ELSE
                                    hours = startingHour+(i-1)
                                        IF LEN(hours) = 1 THEN
                                            hours = "0"&hours&".00"
                                            ELSE 
                                        IF LEN(hours) = 2 THEN
                                            hours = hours&".00"
                                            END IF
                                        END IF
                                    response.write("<td>"&hours&"</td>")
                                    CALL write_time(Array(scheduled_time(1), scheduled_time(2), scheduled_time(3), scheduled_time(4), scheduled_time(5), scheduled_time(6), scheduled_time(7), scheduled_time(8), scheduled_time(9), scheduled_time(10), scheduled_time(11), scheduled_time(12), scheduled_time(13), scheduled_time(14),scheduled_time(15), scheduled_time(16), scheduled_time(17),scheduled_time(18)))
                            END IF
                    END IF
                    response.write("</tr>")
                NEXT
            NEXT

    END IF       
END FUNCTION    

'Write_Time will write the content for each line for that especific time
FUNCTION write_time(line)
    DIM x
    FOR EACH x IN line
        IF x <> "" THEN
            response.write("<td><a class="&"line-schedule"&" href="&"/asplearning/act/schedule-line.asp"&">"& x &"</a></td>")
        ELSE
            response.write("<td class="&"line-schedule-stopped"&" href="&"/asplearning/act/schedule-line.asp"&">PARADA</td>")
        END IF
    NEXT
END FUNCTION

And at the end I have this result:

enter image description here

Because I want to have precisely the amount of time and the finishing hour, I decided to treat them individually, which for me is just fine, but now I have to merge the rows where the time is the same. I am already using W3 School JavaScript to sort the rows increasing the time. Can anyone help with JavaScript merging these rows? I don't now if rowspan applies.

1条回答
Lonely孤独者°
2楼-- · 2019-07-25 05:55

This is some very messy code, in the end, but what you're trying to do here is quite a bit more complicated than it seems, and I'm afraid I don't have time to give a well coded answer.

What we're essentially doing here is going through each row of the table, and checking it against the previous row. If the first cells of each row are equal, then we'll merge them.

Merging them is slightly complicated, as we need to be able to filter out those cells which contain 'PARADA', else they'll simply overwrite the cells without 'PARADA' from the previous row.

This is all slightly hacky, and could be done better. You could, for instance, split this out into smaller functions, or create the new cell objects containing 'PARADA' properly, rather than just a fake element with only the textContent property.

That being said, I believe this will work for you:

const getMergedRow = (rowOne, rowTwo) => {
  const noParadaOne = _.mapValues(rowOne.cells, x =>
    x.innerHTML.indexOf('PARADA') === -1 ? x : null)
    
  const noParadaTwo = _.mapValues(rowTwo.cells, x =>
    x.innerHTML.indexOf('PARADA') === -1 ? x : null)
  
  return _.mapValues(noParadaOne, (x, i) => {
    return x ? x : (noParadaTwo[i] ? noParadaTwo[i] : {textContent: 'PARADA'})
  })
};

const mergeRows = tableElement => {
  const rows = tableElement.rows;
  
  let previousLabel = undefined;
  let previousRow = undefined;
  
  for (let i = 0; i < rows.length; i++) {
      const x = rows[i];
      const rowLabel = x.cells[0].innerHTML;
      
      if (rowLabel === previousLabel) {
        const newRow = getMergedRow(x, previousRow);
        
        tableElement.deleteRow(i);
        tableElement.deleteRow(i-1);
        
        const insertedRow = tableElement.insertRow(i-1);
        
        Object.values(newRow)
          .forEach((cell, i) => {
            const newCell = insertedRow.insertCell();
            const newText = document.createTextNode(cell.textContent)
            newCell.append(newText)
          })
          
        i--;
      }
      
      
      
      previousLabel = rowLabel;
      previousRow = x;
  }

}

mergeRows(document.getElementById('t'))
body {
  font-family: arial;
}

td {
  padding: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

<table id='t'>
  <tr>
    <td></td>
    <td>GL1</td>
    <td>GL1</td>
    <td>GL3</td>
  </tr>
  <tr>
    <td>08.00</td>
    <td>PARADA</td>
    <td>PARADA</td>
    <td><a href="#">PARADA</a></td>
  </tr>
  <tr>
    <td>09.00</td>
    <td><a href="#">VEGAS14INTEL</a></td>
    <td>PARADA</td>
    <td>PARADA</td>
  </tr>

  <tr>
    <td>09.00</td>
    <td>PARADA</td>
    <td>LOCIL14</td>
    <td>PARADA</td>
  </tr>
  <tr>
    <td>10.00</td>
    <td>PARADA</td>
    <td>PARADA</td>
    <td>PARADA</td>
  </tr>
  <tr>
    <td>10.00</td>
    <td>PARADA</td>
    <td>Test</td>
    <td>PARADA</td>
  </tr>
  <tr>
    <td>10.00</td>
    <td>Another test</td>
    <td>Test</td>
    <td>PARADA</td>
  </tr>
  <tr>
    <td>11.00</td>
    <td>x</td>
    <td>y</td>
    <td>z</td>
  </tr>
</table>

查看更多
登录 后发表回答