Problem creating 3 cells per row in table

Hi,
I have an object called subs which contains objects. I am trying to get each object into a cell and have three cells per row. But the code is not creating a new row every three cells, as I would have expected. The code is just adding a new cell to the row, but the fourth cell should be on a new row.
x is the column number where the item will be, which is either 0, 1 or 2.

            var table = "";
    var end;
    var x;
    table = document.getElementById('examTables');
    var row = document.createElement("tr");    
    var cell = document.createElement("td");
    for(var item in subs)
    {
        x = subs[item].columns;
        var text = document.createTextNode(" " + item + " ");
        cell.appendChild(text);
        row.appendChild(cell);
        if(x < 2)//add three cells to row. x is only 0, 1 or 2.
        {
            console.log("x less than 2: " + x)
            end = false;
        }else{
            console.log("x == " + x)
            end = true;
            table.appendChild(row);//if at third cell add row to table
        }
    }
    if(!end)//if finished iterating through subs and not at the end of a row, add incomplete row to table
    {
        table.appendChild(row);
    }

Perhaps this is not the correct way to do this or I am missing something.
Thanks

Move these lines inside the loop

Thanks, interesting when i do that it clears the first two cells in each row and only has one cell, the last cell in each row. But at least i can now get a new row.

    var table = "";
    var end;
    var x;
    table = document.getElementById('examTables');
    var row = document.createElement("tr");    
    var cell = document.createElement("td");
    for(var item in subs)
    {
        var row = document.createElement("tr");    
        var cell = document.createElement("td");
        x = subs[item].columns;
        var text = document.createTextNode(" " + item + " ");
        cell.appendChild(text);
        row.appendChild(cell);
        if(x < 2)//add three cells to row. x is only 0, 1 or 2.
        {
            console.log("x less than 2: " + x + " in the if ")
            end = false;
        }else{
            console.log("x == " + x + " in the else ")
            end = true;
            table.appendChild(row);//if at third cell add row to table
        }
    }
    if(!end)//if finished iterating through subs and not at the end of a row, add incomplete row to table
    {
        console.log(" end of iteration ");
        table.appendChild(row);
    }

Thanks

I get it.

  1. Move that line back to outside the loop:

    var row = document.createElement(“tr”);

  2. And also add the same line right after:

    table.appendChild(row);//if at third cell add row to table

Hi there ofeyofey,

here is a possible solution…

[code]

create DOM table body { font-family:verdana,arial,helvetica,sans-serif; font-size:100%; background-color:#f0f0f0; } #newtable{ border:2px solid #999; margin:auto; background-color:#fff; box-shadow:5px 5px 5px #999; } #newtable td{ padding:10px; border:1px solid #000; border-radius:5px; font-size:75%; text-align:center; background-color:#f0f0ff; box-shadow:inset 0 0 10px #999; }
[/code]

coothead

[quote=“megazoid, post:4, topic:199319”]

  1. Move that line back to outside the loop:

var row = document.createElement(“tr”);

  1. And also add the same line right after:

    table.appendChild(row);//if at third cell add row to table
    [/quote]

    Thanks but no luck with that.

    var table = “”;
    var end;
    var x;
    var cell;
    var row;
    table = document.getElementById(‘examTables’);
    row = document.createElement(“tr”);
    //cell = document.createElement(“td”);
    table.appendChild(row);
    for(var item in subs)
    {
    //row = document.createElement(“tr”);
    cell = document.createElement(“td”);
    x = subs[item].columns;
    var text = document.createTextNode(" " + item + " ");
    cell.appendChild(text);
    row.appendChild(cell);
    if(x < 2)//add three cells to row. x is only 0, 1 or 2.
    {
    console.log("x less than 2: " + x + " in the if ");
    end = false;
    //table.appendChild(row);
    }else{
    console.log("x == " + x + " in the else “);
    end = true;
    table.appendChild(row);//if at third cell add row to table
    }
    }
    if(!end)//if finished iterating through subs and not at the end of a row, add incomplete row to table
    {
    console.log(” end of iteration ");
    table.appendChild(row);
    }

I have also tried every combination of cell, row outside with cell, row inside.

Coothead I’ve still to study this.
Thanks

This is my latest attempt but it doesn’t work.

var table = document.getElementById('examTables');
var tblBody = document.createElement("table");
for(var item in subs)
{
    //console.log("subjects: " + item + " rows: " + subs[item].rows + " columns: " + subs[item].columns + " result: " + subs[item].vals);
    if(subs[item].columns == 0)
    {
        var row = document.createElement("tr");
    }
    var cell = document.createElement("td");
    var text = document.createTextNode(" " + item + " ");
    cell.appendChild(text);
    row.appendChild(cell);
    if(subs[item].columns == 2)
    {
        tblBody.appendChild(row);
    }
}
table.appendChild(tblBody);   

Thanks

I think this may work; declaring the row variable outside the loop so that it can be used while looping until a new row is created. This is assuming I’m understanding your ‘subs’ array correctly (each item has a columns property of 0,1,2,0,1,2,etc.).

var row;
var cell;
var text;
var x;

for(var item in subs)
{
    x = subs[item].columns;
    cell = document.createElement('td');
    text = document.createTextNode(" " + item + " ");

    cell.appendChild(text);

    // if at columns 0, create a new row. Otherwise continue using created row;
    if(x === 0) {
        row = document.createElement('tr');
    }

    row.appendChild(cell);

    // if at columns 2, append the row to the table.
    if(x === 2) {
        tblBody.appendChild(row);
    }
    
}
table.appendChild(tblBody);

Yes that is correct, the 1st, 2nd and 3rd items have column numbers 0, 1 and 2 respectively and the 4th, 5th and 6th would be also 0, 1, and 2 respectively and so on.
I took out the tablBody element because it already exists in the table. So this was trying to create another tblBody element outside the already existing one. So I put the id on the already existing tblBody and built rows in that. This works well.
Creating the table is now correct only problem now is sometimes if I uncheck a subject, which will result in an item being removed from the subs object, strange things happen. But everytime the an exam type is checked or unchecked the entire subs object is recreated. So I have yet to figure out why that isn’t working.
Here is my code so far.

<!DOCTYPE html>
<?php     
    include_once $_SERVER['DOCUMENT_ROOT'] . '/cuislegibney/includes/func.inc.php'; 
    include_once $_SERVER['DOCUMENT_ROOT'] . '/cuislegibney/includes/helpers.inc.php'; 
    include $_SERVER['DOCUMENT_ROOT'] . '/cuislegibney/includes/arraybuilder.inc.php'; 
?>
<html lang="en">
      <head>
        <!-- <script src="/cuislegibney/js/searchJavaScript.js"></script> -->
        <link type="text/css" rel="stylesheet" href="/cuislegibney/css/stylesheet.css"/>
        <meta charset="utf-8">
        <title>Search</title>
      </head>
      <body>
      <link rel="icon" type="image/x-icon" href="http://www.cuislegibney.com/cuislegibney/images/favicon.ico"/>
      <header>
      <h1>Results archive</h1>
      </header>
        <div class="input">
            <p><a href="/cuislegibney">Return to Main Menu</a></p>
              <!-- <form action="?<?php htmlout($action);?>" method="post"> -->
              <form action="?" method="post">
                  <input type="hidden" name="action" value="search">
                  <input type="submit" value="<?php htmlout($button); ?>"> 
                <fieldset>
                    <legend>Search</legend>
                    <table>
                        <tbody id ="examTables">
                        <tr>
                            <td>
                                <table class="inner" id="searchTable">
                                     <th>Exam Type:</th>                        
                                      <?php foreach($examSearch as $searchExam): ?>
                                           <tr><td class="left"><input type="checkbox" class="year" id="<?php htmlout($searchExam['name']); ?>" name="exams[]" value="<?php htmlout($searchExam['name']); ?>">
                                        <?php htmlout($searchExam['name']); ?></td></tr>
                                      <?php endforeach; ?>
                                </table>
                            </td>
                            <td>        
                            <td>
                            </td>
                        </tr>
                    </tbody>
                    </table>
                </fieldset>
            </form>
        </div>
        <script language="javascript" type="text/javascript">

var pos = {};
var state = {};
var exist = {};
var subjects = {};
var subs = {};
<?php foreach($exams as $element): ?>
type = <?php echo json_encode($element); ?>;
state[type] = false;
exist[type] = false;
<?php endforeach; ?>

function examTables(){
var genTable;
var genRows;
var type;
var exam = this.value;
var horz, vert;

if(!state[exam]){//if exam is checked or unchecked state must be changed
    state[exam] = true;
}else if(state[exam]){
    state[exam] = false;
    exist[exam];//if exam is not checked it might as well not exist
    //this means there will be no situation where the item is unchecked and exists
}

for(var item in state)//iterate through state to create exist[]
{
    if(state[item]){//only concerned with the states that are true
        <?php foreach($exams as $element): ?>
            other = <?php echo json_encode($element);?>;
            if(item  == other) 
            {
                <?php if(!empty($subs[$element])): ?>
                    exist[item] = true;
                <?php endif; ?>;
                //the test for exist needs to be state true first so no if else needed here
            }
        <?php endforeach; ?>;
    }else{
        exist[item] = false;
    }
}

function position(){/*assigns position of row and column to the subjects*/
    var pos = {}, i = 0, j = 0;
        for(var prop in state){
            if(exist[prop])
            {
                pos[prop] = {r:i, c:j};
                if(j%3 == 2)
                {
                    i++;
                    j=0;
                } else {
                    j++;
                }
            }
        }
    return pos;
}

function result(){ /*get subjects in DB for checked states, for those that exist*/
    var resultArray = [];
    var subjects = [];
    var value, other;
    for(var prop in state){
        if(exist[prop])/*populates the resultArray for each exam type*/
        {
            <?php foreach($exams as $element): ?>
            other = <?php echo json_encode($element);?>;
            if(prop  == other) 
            {
                resultArray[prop] = <?php echo json_encode($subs[$element], JSON_PRETTY_PRINT); ?>;//
            }
            <?php endforeach; ?>;

        /*next get the value for each resultArray and make an array of values only*/
        var keys1 = Object.keys(resultArray[prop]);
        keys1.forEach(function(item1){
            var keys2 = Object.keys(resultArray[prop][item1]);
            //console.log(item1);
            keys2.forEach(function(items2){
                value = resultArray[prop][item1][items2];
                //subjects is an array of the subjects in the DB for each exam type which is checked and exists in the DB
                var newSubjects = subjects.push(value);
            });
        });        
        x = position();
        subs[prop] = {vals: subjects, rows: x[prop].r, columns: x[prop].c};
        //clear this array each time
        subjects = [];
        }else{
            //if an exam in unchecked it is deleted from the objuect subs{}
            delete subs[prop];
        }
    }    
}
result();

var countRows = document.getElementById('examTables').rows.length;

for(var i=countRows-1; i>0; i--)
{
    console.log("cleared");
    //deletes all rows except row 0 each time
    document.getElementById('examTables').deleteRow(i);
}
//console.log("subjects: " + item + " rows: " + subs[item].rows + " columns: " + subs[item].columns + " result: " + subs[item].vals);
var tblBody = document.getElementById('examTables');
//var tblBody = document.createElement("table");
for(var item in subs)
{
    //console.log(item);
    //console.log("subjects: " + item + " rows: " + subs[item].rows + " columns: " + subs[item].columns + " result: " + subs[item].vals);
    var cols = subs[item].columns;
    if(cols == 0)
    {
        console.log("neither 0 nor 2, col: " + cols);
        var row = document.createElement("tr");
    }
    console.log("subjects: " + item + " rows: " + subs[item].rows + " columns: " + subs[item].columns + " result: " + subs[item].vals);
    var cell = document.createElement("td");
    var text = document.createTextNode(" " + item + " ");
    cell.appendChild(text);
    row.appendChild(cell);
    console.log(document.getElementById('examTables').rows.length);
    if(cols == 2)
    {
        console.log("end a row, col: " + cols);
         tblBody.appendChild(row);
    }
}
    var row = document.createElement("tr");
    tblBody.appendChild(row);        
console.log("");
//subs[item].vals.length
//console.log(Object.keys(subs).length);//can get length
}

function yearTable(){
    var exam = this.value; 
    var table = document.getElementById("searchYear");
    var row = document.createElement("tr");    
    var cell = document.createElement("td");
    if (this.checked){
       var empty = document.createTextNode(exam);
    }
    cell.appendChild(empty);
    row.appendChild(cell);
    table.appendChild(row); 
}

var checkboxes = document.getElementsByClassName('year');
    for(var index in checkboxes){
        //bind event to each checkbox
        checkboxes[index].onchange = examTables;
    }
    </script>
    </body>
</html>

Thanks

I think declared and undeclaref row variable is messing things up here. Need to look at this more closely.
Thanks

You have almost right code in post #6
but you missed that:

  1. Take you code from post #6

  2. Add

    row = document.createElement(“tr”);

right after

table.appendChild(row);//if at third cell add row to table

That means you will start new row before loop (first row) and after each 3rd cell (next rows)

But there are times when there may only be 1 or 2 cells in a row. So a row is not necessarily finished only after the 3rd cell.
It is working fine now except when I uncheck a few boxes and items should be removed from the subs object. The items in subs no longer are in the order of
(row, column)
(0,0), (0,1),(0,2),(1,0),(1,1),(1,2),(2,0)…etc.
The subs object can end up like this,

subjects: AS rows: 0 columns: 0 result: Geography,Mathematics search:399:2
subjects: GCSE rows: 0 columns: 2 result: gcseBiology search:399:2
subjects: A2 rows: 0 columns: 1 result: Further Mathematics

This causes problems having 0,2 before 0,1.
Either I can go back and try to see where and why this disordering takes place or I could try to write a function that will create a new object from subs called orderedSubs{} which will have the rows and columns in the correct order.
Paul_Wilkins did warn me in another thread about the order of the array.
There’s another problem that you’re going to have, and that is the
properties of an object can not be guaranteed to always be processed in
the same order.

I think that is coming back to haunt me now.
Thanks

I am trying to reorder the subs array

subsOrdered = {};
i = 0;
j = 0;
for(var item in subs)
{
    subsOrdered[item] = {rows:i, columns:j, vals:subs[item].vals};
    j++;
    if(j>2){
        i++;
        j = 0;
    }
}

I think it is working now when I check and uncheck exam types in any order using the new subsOrdered object.

subsOrdered = {};
i = 0;
j = 0;
for(var item in subs)
{
    subsOrdered[item] = {rows:i, columns:j, vals:subs[item].vals};
    j++;
    if(j>2){
        i++;
        j = 0;
    }
//need a new object here subsOrdered{} which is a reordering of subs in the order row 0 cells 1 to 2 and then row 1 cells 0 to 2 etc.
//console.log("subsOrdered:  subjects: " + item + " rows: " + subsOrdered[item].rows + " columns: " + subsOrdered[item].columns + " result: " + subsOrdered[item].vals);
}
for(var i=countRows-1; i>0; i--)
{
    //console.log("cleared");
    //deletes all rows except row 0 each time
    document.getElementById('examTables').deleteRow(i);
}
//console.log("subjects: " + item + " rows: " + subs[item].rows + " columns: " + subs[item].columns + " result: " + subs[item].vals);
var tblBody = document.getElementById('examTables');
//var tblBody = document.createElement("table");
row = "";//clear the row variable
row = document.createElement("tr");
position();
for(var item in subsOrdered)
{
    //console.log(item);
    //console.log("subjects: " + item + " rows: " + subs[item].rows + " columns: " + subs[item].columns + " result: " + subs[item].vals);
    var cols = subsOrdered[item].columns;
    if(cols == 0)
    {
        //console.log("neither 0 nor 2, col: " + cols);
        row = document.createElement("tr");
    }
    //console.log("subs:  subjects: " + item + " rows: " + subs[item].rows + " columns: " + subs[item].columns + " result: " + subs[item].vals);
    //console.log("subsOrdered:  subjects: " + item + " rows: " + subsOrdered[item].rows + " columns: " + subsOrdered[item].columns + " result: " + subsOrdered[item].vals);
    var cell = document.createElement("td");
    var text = document.createTextNode(" " + item + " ");
    cell.appendChild(text);
    row.appendChild(cell);
    //console.log("Rows in current table: " + document.getElementById('examTables').rows.length);
    if(cols == 2)
    {
        //var row = document.createElement("tr");
        //console.log("end a row, col: " + cols);
        tblBody.appendChild(row);
    }
}
//var row = document.createElement("tr");
tblBody.appendChild(row);        
console.log("End of subs iteration");
//subs[item].vals.length
//console.log(Object.keys(subs).length);//can get length
}

Thanks for all your help

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.