Holly
Holly

Reputation: 1

How do you create a table in jQuery using html user input?

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");
        }
    });

});

Upvotes: 0

Views: 1507

Answers (5)

Barmar
Barmar

Reputation: 781935

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>

Upvotes: 1

Mackan
Mackan

Reputation: 6271

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.

Upvotes: 0

wahwahwah
wahwahwah

Reputation: 3177

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>

Upvotes: 0

Wesley Smith
Wesley Smith

Reputation: 19571

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>

Upvotes: 0

Roko C. Buljan
Roko C. Buljan

Reputation: 206477

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>

Upvotes: 0

Related Questions