Search code examples
javascriptdynamicdynamic-data

Accessing a dynamically created variable in a dynamic way


This may take a bit of explaining, so please bear with me.

I'm trying to create X number of tables, each of a varying length (columns) Y, with 4 rows each, X and Y being determined by the user. This part I have solved.

The problem is that every cell in every table must contain it's own text box, which will contain numbers derived from a database. If the user changes the number in the text box, the change must then be reflected in the database.

Given that the number of tables and the length of the tables are unknown, I can't set up the names of the text boxes ahead of time and must do so dynamically.

I ran across this code:

var pageNumber = 1;
eval("var text" + pageNumber + "=123;");
alert(text1);
//alert shows '123'

Which (with modification), I believe would allow me to dynamically create a unique name for each text box. What I am having trouble with is how do I then access this new text box since I don't know what it's called(after the table has been created)?

I plan on using a 3d array to hold the numbers that I want displayed in each cell in the table and plan to use this array to name the cell.

As an example the array could be array[i][j][k], and lets say i=1, j=2, k=3, which would hold the number 8. The dynamically created text box name would be something like: textBox123

How do I associate that cell in the array (containing 8) with that new text box and then retrieve and store a new value when I don't know it's name ahead of time?

The way I'm thinking of it, how do I write something like

 <input type="text" name="textBox123" value=array[i][j][k]> 

to the html?

Then again, maybe I'm over thinking this and there is a better way of doing it. If so, please let me know.


Solution

  • HTML:

    <div id="tables"></div>
    

    JavaScript:

    var tables = [
            // Table #1
            [
                [111, 112, 113], // Row #1
                [121, 122, 123]  // Row #2
            ],
            // Table #2
            [
                [211, 212, 213, 214], // Row #1
                [221, 222, 223, 224], // Row #2
                [231, 232, 233, 234]  // Row #3
            ],
            // Table #3 (empty!)
            []
        ],
        nr, nc, i, j, k,
        name, value, textBox, cell, row, table,
        $tables = $("#tables");
    
    for (i = 0; i < tables.length; ++i) {
        nr = tables[i].length;
        nc = nr > 0 ? tables[i][0].length : 0;
        table = "<table>";
        for (j = 0; j < nr; ++j) {
            row = "<tr>";
            for (k = 0; k < nc; ++k) {
                name = "textBox" + (i + 1) + (j + 1) + (k + 1);
                value = tables[i][j][k];
                textBox = "<input type='text' name='" + name + "' value='" + value + "'>";
                cell = "<td>" + textBox + "</td>";
                row += cell;
            }
            row += "</tr>\n";
            table += row;
        }
        table += "</table>\n";
        $tables.append(table);
    }
    

    See the jsfiddle. The 3rd, empty table will be inserted as an empty table tag, but this is not necessary.

    I would like to mention that since you need to connect these tables to a database, an elegant solution would be using a client-side MVC framework, like Backbone.js. Here you find a good intro book. The View could use a code similar to the one above to render the tables. The tables array could be stored in a Collection.