mjones.udri mjones.udri - 7 months ago 40
HTML Question

Creating HTML table from Java, check if TD already has a TD to the right of it

I am using the Gagawa (https://code.google.com/archive/p/gagawa/) library to dynamically create an HTML table to display school courses on a weekly schedule. The problem is that, because I'm using rowspan to increase the size of a cell based on the course's duration, when I try to, for example add a course that meets on MWF, the typical layout for the row would be

<td>...content...</td> <td></td> <td>...content...</td> <td></td> <td>...content...</td>


But, if 2 courses overlap in time but are on different days, inserting the blank
<td>
element is forced to the right, because
<td>
for the other course already exists in the next column. See the attached screenshot for more clarification (I've drawn arrows on it in red to show what the correct layout should be; ANT210.101 should be on MWF, but I'm trying to insert a blank
<td>
where the bottom half of the first ANT220.102 block it, so it gets put to the right of it).

Screenshot

I either need a way to dynamically detect whether or not to put in the blank
<td>
or a way to make it to that instead of getting shifted right, it gets shifted down (maybe there's a way to do this in CSS?).

Below is my code to dynamically generate the HTML table:

public String generateHTMLScheduleTable(Schedule s){
Table scheduleTable=new Table();
scheduleTable.setCSSClass("scheduleTable");
Tr dayRow=new Tr();
Th time=new Th(); time.appendText("Time");
Th mon=new Th(); mon.appendText("Monday");
Th tue=new Th(); tue.appendText("Tuesday");
Th wed=new Th(); wed.appendText("Wednesday");
Th th=new Th(); th.appendText("Thursday");
Th fri=new Th(); th.appendText("Friday");
dayRow.appendChild(time, mon, tue, wed, th, fri);
TreeMap<Integer, String> colors=mapCoursesToColors(s);

String[] days={"m", "t", "w", "r", "f"};

for(int j=8; j<=22; j++){
int timeInt=j%12;
if(timeInt==0){
timeInt=12;
}
String timeHr="" + timeInt;

//System.out.println(timeHr);

String amPm;
if(j>11){
amPm="PM";
}
else{
amPm="AM";
}
for(int k=0; k<2; k++){
String timeMin="";
if(k==0){
timeMin="00";

}
else{
timeMin="30";
}
Tr currRow=new Tr();
Td currCell=new Td();
currCell.appendText(timeHr + ":" + timeMin + amPm);
currRow.appendChild(currCell);

for(int i=0; i<days.length; i++){
Td newCell=new Td();
for(Course c : s.getCourses()){
if((c.getTime().substring(0, c.getTime().indexOf(':')).equals(timeHr) || c.getTime().substring(0, c.getTime().indexOf(':')).equals("0" + timeHr)) && c.getTime().substring(0, c.getTime().indexOf('-')).contains(timeMin) && c.getTime().substring(0, c.getTime().indexOf('-')).contains(amPm)){
if(c.getDays().toLowerCase().contains(days[i])){
String currentColor=colors.get(c.getCRN());
String timeLastHalf=c.getTime().substring(c.getTime().indexOf('-')+1);
int startHr=Integer.parseInt(timeHr);
int endHr=Integer.parseInt(timeLastHalf.substring(0, timeLastHalf.indexOf(':')));
int numCells=endHr-startHr;
numCells=numCells*2;
if(!c.getTime().substring(0, c.getTime().indexOf('-')).contains("00")){
if(timeLastHalf.contains("00")){
numCells=numCells-1;
}
}
else{
if(!timeLastHalf.contains("00")){
numCells=numCells+1;
}
}
if(numCells<2){
numCells=2;
}
newCell.setBgcolor(currentColor);
newCell.setRowspan("" + numCells);
newCell.appendText(c.getTitle());
newCell.appendChild(new Br());
newCell.appendText(c.getCourseAndSection());
newCell.appendChild(new Br());
newCell.appendText(c.getTime());
Input submit=new Input();
submit.setType("submit");
submit.setCSSClass("btn");
submit.setName("" + c.getCRN());
submit.setValue("Remove");
Input moreInfo=new Input();
moreInfo.setType("submit");
moreInfo.setCSSClass("btn");
moreInfo.setName(c.getCRN() + "View");
moreInfo.setValue("More Info");
newCell.appendChild(new Br());
newCell.appendChild(submit);
newCell.appendChild(moreInfo);
}
}
}
currRow.appendChild(newCell);
}
scheduleTable.appendChild(currRow);
}
}
String html=scheduleTable.write();
System.out.println(html);

return html;
}

Answer

Logic (Asked the OP if its ok he need only pseudocode)

It is wrong approach to check if TD already has a TD to the right of it

Right Approach is to prevent a empty td where there is a rowspan occupation above it so preventing the pushing out of next inserted td. "To simply put always keep the number td always correct"

Your coding is fine all you need to do is add a counter for each day if five counters(because you said that in your example in Q) and then use this counter to walkover occupied space due to above lying rowspan allotment and track it when it ends and only then apply a empty td under that column

Column_count is variable used to track current position of the column inside a row

Next is 5 Overlow indicators which is used to indicated 5 columns and their overflow status.And since you said each row means 30 minutes then your logic for finding if a hour has to be started in a tr is find if the starting time is equal counter of the time associated with each row change causing 30 minute increment

In explanation Overflow_X is used isntead of each individual var name

  1. First of all we need to know before hand how many rows are there gonna be for the outer for loop finding it is left to u
  2. Now with logic First we use switch statement for each day
  3. Now first inside the case we check to see if Overflow_X count is greater than zero this is to understand if there is a need to insert Class details or greater than zero means that it was allocated by above rowspan its default value will be -1.which I am gonna explain why
  4. The default value of overflow variables are set to -1 because each time a rowspan 2 or its multiple depending upon is added a td is added and its value incremented by 2.So in next iteration of for it is checked and if less than zero it does not insert a new td it goes to else case and decrement the value
  5. By this we are bypassing the chance of adding a blank td and causing the pushing of td to the right
  6. So here we only insert a blank td when there is no rowspan allocation above
  7. Overlow_X is checked to see if its zero then its set to -1 as 2n-1 rowspan has been covered

Overflow variables use so during an iteration if it shows that say thursday has Overflow_Th is incremented by 2.So while inserting next row when switch enters case 4 that is for tuesday it checks to see if there was overflow if yes then Overflow_Th is decremented .So here the blank td insertion is avoided which in future will prevent the td from breaking the flow Demo here

td{
  
  border:1px solid black;

}
.pushedOut{
  background:red;
  
}
.bully{
  background:blue;
    color:white
}
<label>Here the value of Overlow_Col2=1(-1+2)</label>
<table>
<tr>
  <td>Data</td>
  <td class="bully " rowspan="2">Pushing</td>
</tr>

<tr>
  <td>Data</td>
 
</tr>
</table>
<label>Here the value of Overlow_Col2=- after decrementing and finding it zero there for resseting to -1 so back to normal but if was no such variable for tracking it then it would have resulted in this following  <span style="color:red">situation</span> </label>
<table>
<tr>
  <td>Data</td>
  <td class="bully " rowspan="2">Pushing</td>
</tr>

<tr>
  <td>Data</td>
   <td class="pushedOut">pushed out becuase of no means of tracking td of previous row</td>
</tr>
</table>

Pseudocode

var column_count=0
Overflow_M=-1,Overflow_Tu=-1,Overflow_W=-1,Overflow_Th=-1,Overflow_Fri=-1

For each number of rows 

for (int column_count=0 ;column_count<5;column_count++)
    {
            switch(column_count){

                  case 0: 
                  if(Overflow_M<0)  {
                         if (content needs to be inserted)
                             {
                             add td and insert content 
                             Overflow_M=Overflow_M+2;
                }else{

                                     Add Blank td

                     }else{

                           Overflow_M=Overflow_M-1;
                           if (Overflow_M==0){
                                     Overflow_M=-1
                                           }

                     }

                  }   

                 case 1: 
                      if(Overflow_Tu<0)  {
                             if (content needs to be inserted)
                                 {
                                 add td and insert content 
                                 Overflow_M=Overflow_M+2;

                              }else{

                                         Add Blank td

                         }else{

                               Overflow_Tu=Overflow_Tu-1;
                                     if (Overflow_M==0){
                                         Overflow_M=-1
                                           }

                         }

                      }  


                     ....
                     ....
                 similarly 2 cases for wed and thurday




  case 4: 
                          if(Overflow_F<0)  {
                                 if (content needs to be inserted)
                                     {
                                     add td and insert content 
                                     Overflow_M=Overflow_M+2;



                                  }else{

                                             Add Blank td

                             }else{

                                   Overflow_F=Overflow_F-1;
                                        if (Overflow_M==0){
                                            Overflow_M=-1
                                           }

                             }

                          } 


                }
         }

If you do not know before hand how many classes are there then you should first iterate through classes and build data base or csv file or json file with data regarding that

 var trcounter = 1;
 var O1 = -1,
   O2 = -1,
   O3 = -1,
   O4 = -1,
   O5 = -1,
   O6 = -1;

 $("#sbt").click(function() {


   var YN = $('#YorN').val();
   //$('#Schedule').append("<td rowspan=" + person + "><p>Cult Anthropology</P</td>");


   if (YN == 'Y' || YN == 'y') {
     var person = prompt("Please enter the rowspan size in multiples of two", "2");
    // alert("y");
   // alert($('#Schedule tr:last td').length);


     /*    if ($('#Schedule tr:last td').length < 6) {

           $('#Schedule tr:last ').append('<td class="red" rowspan="' + person + '"><p>Cult Anthropology</P</td>');

         } else {

           $('#Schedule').append("<tr> </tr>");
           $('#Schedule tr:last').append('<td class="red" rowspan="' + person + '"><p>Cult Anthropology</P</td>');

         }*/





     switch (trcounter) {
       case 1:
         if (O1 < 0) {
      
           if (trcounter < 7) {

             $('#Schedule tr:last ').append('<td class="red" rowspan="' + person + '"><p>Cult Anthropology</P</td>');

           } else {
             $('#Schedule').append("<tr> </tr>");
             $('#Schedule tr:last').append('<td class="red" rowspan="' + person + '"><p>Cult Anthropology</P</td>');
           }
           O1 = O1 + parseInt(person);
          // alert(O1);
         } else {
            alert("This TimeSlot on Monday is occupied");
           O1 = O1 - 1;
           if (O1 == 0) {
             O1 = -1;
           }
         }
         break;

       case 2:
         if (O2 < 0) {
      
           if (trcounter < 7) {

             $('#Schedule tr:last ').append('<td class="red" rowspan="' + person + '"><p>Cult Anthropology</P</td>');

           } else {
             $('#Schedule').append("<tr> </tr>");
             $('#Schedule tr:last').append('<td class="red" rowspan="' + person + '"><p>Cult Anthropology</P</td>');
           }
           O2 = O2 + parseInt(person);
           //alert(O1);
         } else {
           alert("This TimeSlot on Tuesday is occupied");
           O2 = O2 - 1;
           if (O2 == 0) {
             O2 = -1;
           }
         }
         break;
       case 3:
          if (O3 < 0) {
      
           if (trcounter < 7) {

             $('#Schedule tr:last ').append('<td class="red" rowspan="' + person + '"><p>Cult Anthropology</P</td>');

           } else {
             $('#Schedule').append("<tr> </tr>");
             $('#Schedule tr:last').append('<td class="red" rowspan="' + person + '"><p>Cult Anthropology</P</td>');
           }
           O3 = O3 + parseInt(person);
         //  alert(O1);
         } else {
           alert("This TimeSlot on Wednesday is occupied");
           O3 = O3 - 1;
           if (O3 == 0) {
             O3 = -1;
           }
         }
         break;
       case 4:
           if (O4 < 0) {
      
           if (trcounter < 7) {

             $('#Schedule tr:last ').append('<td class="red" rowspan="' + person + '"><p>Cult Anthropology</P</td>');

           } else {
             $('#Schedule').append("<tr> </tr>");
             $('#Schedule tr:last').append('<td class="red" rowspan="' + person + '"><p>Cult Anthropology</P</td>');
           }
           O4 = O4 + parseInt(person);
         //  alert(O1);
         } else {
           alert("This TimeSlot on Wednesday is occupied");
           O4 = O4 - 1;
           if (O4 == 0) {
             O4 = -1;
           }
         }
         break;
       case 5:
         if (O5 < 0) {
      
           if (trcounter < 7) {

             $('#Schedule tr:last ').append('<td class="red" rowspan="' + person + '"><p>Cult Anthropology</P</td>');

           } else {
             $('#Schedule').append("<tr> </tr>");
             $('#Schedule tr:last').append('<td class="red" rowspan="' + person + '"><p>Cult Anthropology</P</td>');
           }
           O5 = O5 + parseInt(person);
         //  alert(O1);
         } else {
           alert("This TimeSlot on Wednesday is occupied");
           O5 = O5 - 1;
           if (O5 == 0) {
             O5 = -1;
           }
         }
         break;
       case 6:
         if (O6 < 0) {
      
           if (trcounter < 7) {

             $('#Schedule tr:last ').append('<td class="red" rowspan="' + person + '"><p>Cult Anthropology</P</td>');

           } else {
             $('#Schedule').append("<tr> </tr>");
             $('#Schedule tr:last').append('<td class="red" rowspan="' + person + '"><p>Cult Anthropology</P</td>');
           }
           O6 = O6 + parseInt(person);
          // alert(O1);
         } else {
           alert("This TimeSlot on Wednesday is occupied");
           O6 = O6 - 1;
           if (O6 == 0) {
             O6 = -1;
           }
         }
         break;

     }
     if (trcounter == 7) {
       trcounter = 1;
        $('#Schedule').append("<tr> </tr>");
       $('#Status').html("REACHED SATURDAY MOVING ON TO NEXT TIME SLOT");
     } else {
       trcounter++;

     }
   } else if(YN == 'N' || YN == 'n') {


     /* if (O1 > 0)) {
       O1--;
     } else if (O1 == 0) {
       O1 = -1;
     }
     if ($('#Schedule tr:last td').length < 6) {

       $('#Schedule tr:last ').append("<td ></td>");

     } else {
       $('#Schedule').append("<tr> </tr>");
       $('#Schedule tr:last').append("<td ></td>");
     }*/
     switch (trcounter) {
       case 1:
        //  alert("trcounter"+trcounter+"O1"+O1);
         if (O1 < 0) {
           if (trcounter < 7) {

             $('#Schedule tr:last ').append("<td ></td>");

           } else {
           //  $('#Schedule').append("<tr> </tr>");
             $('#Schedule tr:last').append("<td ></td>");
           }
          
         } else {
           O1 = O1 - 1;
          // alert(O1);
           if (O1 == 0) {
             O1 = -1;
           }
             $('#Status').html("Empty Node Cannot be inserted here becuase previous rowspan allocation is taking up the space");
         }
         break;
   
       case 2:
         if (O2 < 0) {
           if (trcounter < 7) {

             $('#Schedule tr:last ').append("<td ></td>");

           } else {
           //  $('#Schedule').append("<tr> </tr>");
             $('#Schedule tr:last').append("<td ></td>");
           }
          
         } else {
           O2 = O2 - 1;
          // alert(O1);
           if (O2 == 0) {
             O2 = -1;
           }
                        $('#Status').html("Empty Node Cannot be inserted here becuase previous rowspan allocation is taking up the space");
         }
         break;
       case 3:
         if (O3 < 0) {
           if (trcounter < 7) {

             $('#Schedule tr:last ').append("<td ></td>");

           } else {
           //  $('#Schedule').append("<tr> </tr>");
             $('#Schedule tr:last').append("<td ></td>");
           }
          
         } else {
           O3 = O3 - 1;
          // alert(O1);
           if (O3 == 0) {
             O3 = -1;
           }
                      $('#Status').html("Empty Node Cannot be inserted here becuase previous rowspan allocation is taking up the space");
         }
         break;
       case 4:
        if (O4 < 0) {
           if (trcounter < 7) {

             $('#Schedule tr:last ').append("<td ></td>");

           } else {
           //  $('#Schedule').append("<tr> </tr>");
             $('#Schedule tr:last').append("<td ></td>");
           }
          
         } else {
           O4 = O4 - 1;
          // alert(O1);
           if (O4 == 0) {
             O4 = -1;
           }
                        $('#Status').html("Empty Node Cannot be inserted here becuase previous rowspan allocation is taking up the space");
         }
         break;
       case 5:
         if (O5 < 0) {
           if (trcounter < 7) {

             $('#Schedule tr:last ').append("<td ></td>");

           } else {
           //  $('#Schedule').append("<tr> </tr>");
             $('#Schedule tr:last').append("<td ></td>");
           }
          
         } else {
           O5 = O5 - 1;
          // alert(O1);
           if (O5 == 0) {
             O5 = -1;
           }
                          $('#Status').html("Empty Node Cannot be inserted here becuase previous rowspan allocation is taking up the space");
         }
         break;
       case 6:
         if (O6 < 0) {
           if (trcounter < 7) {

             $('#Schedule tr:last ').append("<td ></td>");

           } else {
           //  $('#Schedule').append("<tr> </tr>");
             $('#Schedule tr:last').append("<td ></td>");
           }
          
         } else {
           O6 = O6 - 1;
          // alert(O1);
           if (O6 == 0) {
             O6 = -1;
           }
                       $('#Status').html("Empty Node Cannot be inserted here becuase previous rowspan allocation is taking up the space");
         }
         break;

     }
     if (trcounter == 7) {
       trcounter = 1;
        $('#Schedule').append("<tr> </tr>");
       $('#Status').html("REACHED SATURDAY MOVING ON TO NEXT TIME SLOT");
     } else {
       trcounter++;
     }


   }else{
    alert("Either Enter Y or N (Y-->Allocate td with class N--> Go to Next day)");
   }


 });
td {
  border: 1px solid black;
  width:20%;
}
table,tr{width:100%;}

.pushedOut {
  background: red;
}
.head{
  background:magenta;
}

.bully {
  background: blue;
  color: white
}
<label>Here the value of Overlow_Col2=1(-1+2)</label>
<table>
  <tr class="head">
    <th>Monday</th>
    <th>Tuesday</th>
    <th>Wednesday</th>
    <th>Thursday</th>a
    <th>Friday</th>
  </tr><tr>
    <td>Overlow_M</td>
     <td>Overlow_TU</td>
      <td>Overlow_W</td>
       <td>Overlow_Th</td>
       <td>Overlow_F</td>
       </tr>
 
 
   

  <tr>
   <td class="bully " rowspan="2">Pushing</td>

      <td>Data</td>
    <td class="bully " rowspan="4">Pushing</td>
      <td>Data</td>
       <td>Data</td>
       
         

  </tr>
  
    <tr>
     
    
      <td>Data</td>
       <td>Data</td>
    <td class="bully " rowspan="2">Pushing</td>
  </tr>
      <tr>
     
     <td>Data</td>
      <td>Data</td>

      <td>Data</td>
  </tr>
        <tr>
     
     <td>Data</td>
      <td>Data</td>
    <td>Data</td>
      <td>Data</td>
  </tr>
  <tr class="head">
    <td>Overlow_M</td>
     <td>Overlow_TU</td>
      <td>Overlow_W</td>
       <td>Overlow_Th</td>
       <td>Overlow_F</td>
       </tr>
</table>
Iteration1
Overflow_M Overflow_W with each decrement it is reduced till it becomes zero and upon which it reset to-1 and during next iteration a empty td is put under it and incase of Overflow_W empty td is never put under it  .
In case of Overflow_F td is no put from iteration bumber 2-3 and during iteration number 4 again rows are added to the bottom of it


<!-- begin snippet: js hide: false -->

Comments