jsRender create an template for html table , given a certain number of rows and cols

StackOverflow https://stackoverflow.com/questions/19323867

  •  30-06-2022
  •  | 
  •  

Pergunta

I need to do something like this, but using templates.

Do you know how to use counters inside a template? I ask you because I need those counters to generate the IDs for the inputs I create.

HTML Code:

<div> 
    <span>N Cols:</span>
    <input id="txtNCols" type="text" /> 
    <span>N Rows:</span>
    <input id="txtNRows" type="text" />
    <input type="button" id="btnCrearMatriz" value="Create" />
</div>

JS Code

$('#btnCrearMatriz').click(function () {
    var rows = $('#txtNRows').val(); //here's your number of rows and columns
    var cols = $('#txtNCols').val();
    var table = $('<table><tbody>');
    for (var r = 0; r < rows; r++) {
        var tr = $('<tr>');
        for (var c = 0; c < cols; c++){
             var td=$('<td>');
             var textbox="<input type='text' id='txt_r" +(r+1) + "c"+ (c+1) + "'/>";
             td.append(textbox);
             td.appendTo(tr);
        }      
        tr.appendTo(table);
    }

    table.appendTo('body');
});

Thanks in advance.

EDIT:

I've just found this . Well, it seems that getting what I need, will be much more difficult than I thought.

Anyway, I tried something like this , but apparently it doesn't support multiple levels of nesting :(

<script id="table_template" type="text/x-jsrender">
   <table>
        <tbody>
           {{range start=1 end=rows}}
                  <tr>
                   {{range start=1 end=cols}}
                        <td>
                            <input type="text"/>
                        </td>
                   {{/range}}
                  </tr>         
            {{/range}}
        </tbody>
   </table>
</script>
Foi útil?

Solução

The reason that it didn't work for you is that JsRender templates are of course data-driven. When you write {{range start=1 end=cols}} it means you are setting the end to the value of the cols as a property of the current data item. But the current data item is not your original data object, since you are in a nested template.

The way range works is either you pass it an array in which case it iterates over the array for the range you specify, or you don't pass it an array in which case it creates its own array - an array of integers from the start to the end you specify.

{{range myArray start=1 end=3}}

So your {{range}} tags are iterating over the generated arrays, and the data item within the block is the current integer from that array.

If you want to get a data-item from higher up you can either use ~root.cols (for example - to get to the cols property of the root data you passed in) or you can use ~foo=someExpression to create a helper variable that can be accessed from nested template blocks at any level.

So based on that, here are a couple of ways to address your scenario above:

Using {{range}}

<script id="myTmpl" type="text/x-jsrender">
  <table>
    <tbody>
      {{range start=1 end=rowCount ~colCount=colCount}}
        <tr>
          {{range start=1 end=~colCount ~rowNo=#index+1}}
            <td>
              <input type="text" id="{{:'r' + ~rowNo + 'c' + (#index + 1)}}" />
            </td>
          {{/range}}
        </tr>
      {{/range}}
    </tbody>
  </table>

rendered against data as follows:

$.templates("#myTmpl").render({rowCount: 10, colCount: 3)

Or Using {{for}}

  <table>
    <tbody>
      {{for rows ~cols=cols}}
        <tr>
          {{for ~cols ~rowNo=#index+1}}
            <td>
              <input type="text" id="{{:'r' + ~rowNo + 'c' + (#index + 1)}}" />
            </td>
          {{/for}}
        </tr>
      {{/for}}
    </tbody>
  </table>
</script>

rendered against data as follows:

$.templates("#myTmpl").render({rows:[1,2,3,4], cols:[1,2]})

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top