且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

在按钮上单击从Grails模板添加表格行

更新时间:2023-10-19 11:15:46

一种可能的解决方案。您需要更改您的模板,以便进行循环:

GSP:

 < table id =myTable> 
< tbody>
< g:render template =tableRowsmodel =[loopCount:loopCount,moreData:moreData]/>
< / tbody>
< / table>

模板:

 < g:each in =$ {loopCount}var =idx> 
< tr>
< td> .....< / td>
......
< / tr>
< / g:每个>

JavaScript:

  e.preventDefault(); 
$ .get(/ controller / someAction,function (html){
$(#myTable> tbody)。append(html);
});
});

控制器:

  def someAction = {
//逻辑
渲染模板:tableRows,model =[loopCount:5,moreData:moreData]
}

您也可以每次将表中的所有数据提交给服务器,并刷新整个页面,将逻辑添加到循环中在一些可变数量的行上。但您需要收集服务器上的所有数据,并确保将其放回请求中。



可能有十几种方法可以做到这一点,所以不要如果你得到那么多答案会感到惊讶。 :o)

So, the _form.gsp template associated with my create.gsp creates an initial table from a template for the row as follows:

<table id="myTable">
<!-- define table headers here -->
<g:each var="i" in="${1..5}">
    <g:render template="tableRow" model="['i': i]" />
</g:each>
</table>

What I'd like to do is add a button or a link underneath that table that let's you add five more rows, while keeping all the data you've entered in the form so far.

I can see how that's possible in "pure" javascript, but I'd basically have to repeat the _myTable.gsp HTML in my javascript file. I'd like to avoid that (DRY, etc.).

How can I do that?

Edit So, I tried Gregg's solution (below). Here's what I came up with.

The Controller has an action:

def addMoreRows() {
    println params
    def i = params.rowNumber + 1
    def j = i+5
    println "i is set to " + i
    render(template: "foapRow", bean:i, var:i, model: ['rowStart': i, 'rowEnd': j])
    }

The create.gsp page calls the _form.gsp as normal, adding a rowStart and a rowEnd to the model.

create.gsp

<g:render template="form" model="['userId':userId, 'rowStart':1, 'rowEnd':5]"/>

*_form.gsp*, in turn, passes those parameters on to the row template, and creates a link to call the above controller action. It also has the javascript Gregg recommended:

<script type="text/javascript">
    $("#addRowsLink").on("click", function(e) {
        e.preventDefault();
            $.get("/Controller/addMoreRows", function(html) {
                $("#theTableInQuestion>tbody").append(html);
            });
        });
    </script>
    <table>
    ...
        <g:render template="tableRow" model="['rowStart':1, 'rowEnd':5]"/>
    </table>
    <g:remoteLink id="addRowsLink" action="addMoreRows" update="theTableInQuestion" onSuccess="addRows(#theTableInQuestion, data, textStatus)" params="['rowNumber':data]">Add More Rows</g:remoteLink>

The *_tableRow.gsp* begins and ends with:

<g:each var="i" in="${rowStart..rowEnd}">
    <tr>
    ...
    </tr>
</g:each>

From a previous attempt, I have this function in my included javascript file:

function addRows(tableId, rowCode, status) {
    $(tableId + ' tr:last').after(rowCode);
}

Right now, when I click the "Add More Rows" link, I still get taken to a new page, and it only has one row on it.

One possible solution. You're going to need to change your template so it does the looping:

GSP:

<table id="myTable">
<tbody>
    <g:render template="tableRows" model="[loopCount:loopCount, moreData:moreData]" />
</tbody>
</table>

Template:

<g:each in="${loopCount}" var="idx">
  <tr>
     <td>.....</td>
     ......
  </tr>
</g:each>

JavaScript:

$("#someButtonId").on("click", function(e) {
  e.preventDefault();
  $.get("/controller/someAction", function(html) {
    $("#myTable>tbody").append(html);
  });
});

Controller:

def someAction = {
  // logic here
  render template: "tableRows", model="[loopCount: 5, moreData:moreData]"
}

You could also submit all the data in your table to the server every time and refresh the entire page, adding logic to loop over some variable number of rows. But you would need to collect all that data on the server and make sure it gets put back in the request.

There's probably a dozen ways to do this so don't be surprised if you get that many answers. :o)