0

I'm pretty junior, so I'm unsure on if I worded the question properly.

I'm looking to create a textbox in HTML where the user can input the amount of columns and rows for the table. From there I need to use Javascript/Jquery to create the table when the button is clicked.

So far I have been able to create the text boxes. I capture the inputed numbers into variables, and created two for loops.

It doesn't work... :/

<body>

        Set Rows:<br>
        <input type="text" id="setRows">
        <br>
        Set Columns:<br>
        <input type="text" id="setColumns">

    <button type='button' onclick='myForm()'>Create Table</button>
    <p id = "demo1"></p>
    <p id = "demo2"></p>

</body>

function myForm()
{
    var setRows = document.getElementById("setRows").value;
    //document.getElementById("demo1").innerHTML = setRows;

    var setColumns = document.getElementById("setColumns").value;
    //document.getElementById("demo2").innerHTML = setColumns;


}

$(document).ready(function()
    {
    $("button").click(function()
    {
        $("<table></table>").insertAfter("p:last");

        for (i = 0; i < setRows; i++)
        {
            $("<tr></tr>").appendTo("table");
        }

        for (i = 0; i < setColumns; i++)
        {
            $("<td>column</td>").appendTo("tr");
        }
    });

});
2
  • Sidenote: I find it odd that you're using plain JS in your myForm() function but jQuery everywhere else. Also, for tables, it should be a pair of nested for loops, not two separate ones. Right now, it will add x number of <tr></tr> elements, followed by x number of <td>...</td> elements. Commented Mar 30, 2015 at 19:26
  • The problem is var setRows defines a variable in the scope of myForm which isn't accessible anywhere else. Why bother setting the onclick handler in HTML anyway? You're defining the click handler in the $("button").click call. Just call myForm() there. Move the var declarations outside the function definition. Commented Mar 30, 2015 at 19:31

5 Answers 5

1

The main problem is that you're setting the variables setRows and setColumns in a different function from the one that uses them. You should do everything in one function -- either bind it with the onclick attribute or with $("button").click() -- rather than splitting it into separate functions.

I also think it would be clearer to use nested loops to make it more obvious that you're adding cells to each row. appendTo() will automatically clone the object being appended if there are multiple targets, but this is an obscure feature (I'm very experienced with jQuery and didn't know about it until now) that isn't so obvious. It will also make the code easier to extend if you need to put different values in each cell (e.g. filling them from an array of data, or initializing with something like "row I col J").

function myForm() {
  var setRows = $("#setRows").val();
  var setColumns = $("#setColumns").val();
  var table = $("<table>").insertAfter("p:last");
  for (var i = 0; i < setRows; i++) {
    var row = $("<tr>");
    for (var j = 0; j < setColumns; j++) {
      $("<td>column</td>").appendTo(row);
    }
    table.append(row);
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Set Rows:<br>
        <input type="text" id="setRows">
        <br>
        Set Columns:<br>
        <input type="text" id="setColumns">

    <button type='button' onclick='myForm()'>Create Table</button>
    <p id = "demo1"></p>
    <p id = "demo2"></p>

Sign up to request clarification or add additional context in comments.

8 Comments

Did you try it without nesting? .appendTo("tr") worked for me.
It doesn't seem like you close your </tr> or </table> - am I missing something?
@Adjit It's unnecessary when you're creating elements with jQuery.
@Adjit See api.jquery.com/jQuery/#jQuery2. When creating new elements, the closing tag is optional.
Why do you (and others) insist that "nested loop" is required. It's working just fine without a nested loop. Optimal? maybe not, but the output is the same.
|
0

jsBin demo

<button type='button'>Create Table</button>

It's quite slow to append elements inside a for loop,
instead create a HTML representation of your table, and append it only once you're done generating it:

$("button").click(function(){

  var setRows    = +$("#setRows").val();    // Value to Number using Unary +
  var setColumns = +$("#setColumns").val();

  // THE HTML STRING
  var table = "<table>";   

  // OUTER FOR LOOP : ROWS
  for (var i=0; i<setRows; i++){

        // START THE TR
        table += "<tr>";

        // INNER FOR LOOP :: CELLS INSIDE THE TR
        for (var j = 0; j < setColumns; j++) {
              table += "<td>column</td>";
        }

        // CLOSE THE TR
        table += "</tr>";
  }

  // CLOSE THE TABLE
  table += "</table>";

  // APPEND ONLY ONCE
  $("p:last").after(table);

});

As you see above I've used a for loop inside another for loop cause:

<tr>                               <!-- OUTER FOR LOOP (rows)    -->
    <td>column</td><td>column</td> <!-- INNER FOR LOOP (cells) -->
</tr>

Comments

0

This would work:

$(document).ready(function(){
    $("#myBtn").click(function(){       
        var setRows = $('#setRows').val(); // get your variables inside the click handler so they are available within the scope of your function 
        var setColumns  = $('#setColumns').val(); 
        var rows=[]; // create an array to hold the rows
        for (var r = 0; r < setRows; r++){ // run a loop creating each row
          var cols=[]; // create an array to hold the cells
          for (var c = 0; c < setColumns; c++){// run a loop creating each cell
              cols.push('<td>column</td>'); // push each cell into our array
          }
          rows.push('<tr>'+cols.join('')+'</tr>'); // join the cells array to create this row 
        }
        $('<table>'+rows.join('')+'</table>').insertAfter("p:last"); // join all of the rows, wrap in a table tag, then add to page

    });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Set Rows:<br>
        <input type="text" id="setRows" value="4"/>
        <br>
        Set Columns:<br>
        <input type="text" id="setColumns" value="5"/>

    <button type="button" id="myBtn" >Create Table</button>
    <p id = "demo1"></p>
    <p id = "demo2"></p>

Comments

0

You have to use a nested loop (as others have suggested).

Also when creating elements using jQuery - you don't have to specify both opening and closing tags - $("<elem />") works nicely..

Snippet:

$(function () {

    var go = $("#go");
    var cols = $("#columns");
    var rows = $("#rows")

    go.click(function () {

        var numRows = rows.val();
        var numCols = cols.val();
        var table = $("<table />");
        var head = $("<thead />");
        var row = $("<tr />");

        // build header
        var headRow = row.clone();
        for (var i = 0; i < numCols; i++) {
            var th = $("<th />");
            th.append(i);
            headRow.append(th);
        }

        table.append(headRow);

        // build table
        for (var j = 0; j < numRows; j++) {
            var addRow = row.clone();
            for (var k = 0; k < numCols; k++) {
                var cell = $('<td />');
                cell.css({"border":"solid 2px teal"});
                cell.append("<p>R:" + j + " |C:" + k + "</p>");
                addRow.append(cell);
            }
            table.append(addRow);
        }
        
        $('body').append(table);

    });

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<label>Rows:</label>
<input id="rows" />
<label>Columns:</label>
<input id="columns" />
<button id="go">Go!</button>

Comments

0

Your variables are created in a function (setRows and setColumns), so they are not available outside of this function. Define them globally if you want the "myForm" function to remain (it's not needed though).

Check this quick example, keeping your code intact:

var setRows = 0;
var setColumns = 0;

function myForm() {
  //setRows = document.getElementById("setRows").value;
  setRows = $('#setRows').val();
  //setColumns = document.getElementById("setColumns").value;
  setColumns = $('#setColumns').val();
}

$(document).ready(function() {
  $("button").click(function() {
    $("<table></table>").insertAfter("p:last");
    for (i = 0; i < setRows; i++) {
      $("<tr></tr>").appendTo("table");
    }
    for (i = 0; i < setColumns; i++) {
      $("<td>column</td>").appendTo("tr");
    }
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Set Rows:
<br>
<input type="text" id="setRows">
<br>Set Columns:
<br>
<input type="text" id="setColumns">

<button type='button' onclick='myForm();'>Create Table</button>
<p id="demo1"></p>
<p id="demo2"></p>

A few pointers going forward:

You can skip the "myForm" function, and instead put your variables just inside the ready-function.

You're also binding "button" to two things: to run myForm and to create your table. Removing the myForm-function, like stated above, obviously means you can remove the "onclick" event. But even if you keep the function, the call to "myForm" would be better placed inside the ready-function.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.