【问题标题】:Grails, executing a javascript by clicking on a column in a table rowGrails,通过单击表格行中的列来执行 javascript
【发布时间】:2017-08-23 07:39:19
【问题描述】:

我有一个包含两个列表的视图:产品和优惠。您可以通过选中它们上的复选框来选择多行,然后单击链接,将为每个选定的产品创建报价行。 每个报价行都有产品的 ID,我将使用该 ID 在产品列表下方的列表中列出为该产品创建的所有报价。

我试图通过使用 javascript 来解决这个问题,当您单击产品列表中的链接或字段时,它应该被激活。 该脚本向控制器发送一条消息,该控制器为此产品创建报价列表,然后在此视图中呈现模板。

我可以只使用一个链接并调用控制器,然后将呈现模板,但当然不会呈现视图的其余部分。

所以我需要有一行:

<td><g:link action="listOffers" id="${pb.id}">${pb.volumeOffered}</g:link></td>

替换为可以调用我的javascript函数的更好的东西。 我在某处读到您可以在 g:link 标记中添加 -onclick="javascript-function" 但它不起作用。

下面是本例中控制器和gsp最重要的部分。

在 List.gsp 中:

    <script type="text/javascript">
        function listOffers(id){
        $.ajax({
                url:'${g.createLink( controller:'ordersAndStore', action:'listOffers' )}',
        data: [id],
        type: 'get'
        }).success( function ( data ) { $( '#offerList' ).html( data ); });
        }
    </script>    
.....
.....
    <g:render template="ListOffers" model="[offerDetails:offerDetails]"/>

在模板_AvailableProductData.gsp中:

    <g:each in="${prodBuffer}" status="i" var="pb"> 
  <tr class="${ (i % 2) == 0 ? 'even': 'odd'}">
                <td><a onclick="listOffers(${pb.id})">${pb.volumeOffered}</a></td> 

在模板_ListOffers.gsp:

<div id="offerList">
    <g:set var="entityName" value='Offers' />
    <div id="list-offers" class="content scaffold-list" role="main">
        <h1><g:message code="default.list.label" args="[entityName]" /></h1>
        <table style="width:100%">
            <thead>
                <tr>
                    <g:sortableColumn property="product" title='Product' />
                    <g:sortableColumn property="volumeOffered" title='Volume' />
                </tr>
            </thead>
            <tbody>
                <g:each in="${offerDetails}" status="i" var="od">
                    <tr class="${ (i % 2) == 0 ? 'even': 'odd'}">
                        <td><g:link class="edit" action="edit" resource="offerDetail" id="${od?.id}"> ${od.product?.encodeAsHTML()}</g:link></td>
                        <td>${od?.volumeOffered}</td>
                    </tr>
                </g:each>
            </tbody>
        </table>
        <div class="pagination">
            <g:paginate total="${offersCount ?: 0}" />
        </div>
    </div>
</div>

在控制器中:

def listOffers(){
    def List<OfferDetail> offerDetails = getOfferList()
    render(template:"ListOffers", model:[offerDetails: offerDetails])
}

添加了打印输出以查看参数包含的内容:

def listOffers(){
    System.out.println("#--#"+params)
    def List<OfferDetail> offerDetails = getOfferList()
    render(template:"ListOffers", model:[offerDetails: offerDetails])
}

打印输出是:

#--#[undefined:, controller:ordersAndStore, format:null, action:listOffers]

以下是完整的 javascript 部分,第一个运行良好,但随后出现响应并调用控制器但无法发送 id 的 onclick 版本。然后是你的版本和另一个简单但没有一个工作的版本。

    <script type="text/javascript">
        function availableProducts(){
            $.ajax({
                url:'${g.createLink( controller:'ordersAndStore', action:'availableProducts' )}',
                    data: [sawMill],
                    type: 'get'
            }).success( function ( data ) { $( '#divToUpdate' ).html( data ); });
        }

        function listOffers(){
            $.ajax({
                url:'${g.createLink( controller:'ordersAndStore', action:'listOffers' )}',
                data: [],
                type: 'get'
            }).success( function ( data ) { $( '#offerList' ).html( data ); });
        }

        $( document ).ready( function() {
            $( '.offers' ).click( function ( event ){
                alert('HEJ')
                $.ajax({
                    url:'${g.createLink( controller:'ordersAndStore', action:'listOffers' )}',
                    data: [this.id],
                    type: 'get'
                }).success( function ( data ) { $( '#offerList' ).html( data ); });
            });
        });
        $( document ).ready( function() {
            $('.test1').bind('click', function (){
            alert('KLICKED');
            });
        });

    </script>    

以及模板中的gsp-part:

        <g:each in="${prodBuffer}" status="i" var="pb"> 
            <tr id="{$pb.id}" class="offers" class=" ${ (i % 2) == 0 ? 'even': 'odd'}">
                <td><g:checkBox name="toOffer" value="${pb.id}" checked="false"  /></td>
                <td><g:link action="edit_prodbuffer" id="${pb.id}">${pb.id}</g:link></td>
                <td>${pb.sawMill}</td>
                <td>${pb.product}</td>
                <td>${pb.length}</td>
                <td>${pb.volumeAvailable}</td>
                <td><a  onclick='listOffers()' > ${pb.volumeOffered}</a></td>

================================================ ===

我采用了一个旧的测试项目,我清理并修改了这个仍然不起作用的简单示例:

<!DOCTYPE html>
<html>
    <head>
        <meta name="layout" content="main" />
        <g:set var="entityName" value="${message(code: 'author.label', default: 'Author')}" />
        <title><g:message code="default.list.label" args="[entityName]" /></title>
        <script type="text/javascript">
            $( document ).ready( function() {
                $( '.off1' ).click( function ( event ){
                    alert('HEJ');
                });
            });
        </script>    
    </head>
    <body>
        <a href="#list-author" class="skip" tabindex="-1"><g:message code="default.link.skip.label" default="Skip to content&hellip;"/></a>
        <div class="nav" role="navigation">
            <ul>
                <li><a class="home" href="${createLink(uri: '/')}"><g:message code="default.home.label"/></a></li>
                <li><g:link class="create" action="create"><g:message code="default.new.label" args="[entityName]" /></g:link></li>
            </ul>
        </div>
        <div id="list-author" class="content scaffold-list" role="main">
            <h1><g:message code="default.list.label" args="[entityName]" /></h1>
            <g:if test="${flash.message}">
                <div class="message" role="status">${flash.message}</div>
            </g:if>
            <table>
                <th></th>
                <tbody
                    <g:each in="${authorList}" status='i' var='a'>
                        <tr id="${a.id}" class="off1">
                            <td><g:field  type="text" name="author" value="${a?.name}"/> </td>
                        </tr>
                    </g:each>
            <div class="pagination">
                <g:paginate total="${authorCount ?: 0}" />
            </div>
        </div>
    </body>
</html>

我开始绝望,无法完成这项工作,但我必须:( 我将使用一些不同的设置和输出再次列出代码。 我的代码肯定有问题,因为其他人可以让它工作,但有什么问题?

GSP 文件开始的部分,这里有两行注释。

                <g:each in="${authorList}" status='i' var='a'>
                    <tr id="${a.id}" onclick="listOffers(6)">
<!--   This line uses script B ------ <tr id="${a.id}" class="off1">-->
                        <td><g:field  type="text" name="author" value="${a?.name}"/> </td>
                    </tr>
                </g:each>

-- 控制器:

def listOffers() {
    System.out.println("### --- HEJ --- ### "+params)
}

-- 脚本 A:

    function listOffers(id){
            alert('HEJ<<<<<<<<<<<<<<'+ id);
            $.ajax({
                url:'${g.createLink( controller:'author', action:'listOffers', id:"${id}" )}',
                data: [id],
                type: 'get'
            }).success( function ( data ) { $( '#offerList' ).html( data ); });
        }

-- 脚本 B:

        $( document ).ready( function() {
            $(".off1").click( function(event){
                alert('HEJ');
            });
        });

脚本 B:从不回应 - 为什么?

使用脚本 A 从控制器输出:

### --- HEJ --- ### [undefined:, controller:author, format:null, action:listOffers, id:null]

修改脚本A——数据为空:

        function listOffers(id){
            alert('HEJ<<<<<<<<<<<<<<'+ id);
            $.ajax({
                url:'${g.createLink( controller:'author', action:'listOffers', id:"${id}" )}',
                data: [],
                type: 'get'
            }).success( function ( data ) { $( '#offerList' ).html( data ); });
        }

使用脚本 A 的修改版本从控制器输出:

### --- HEJ --- ### [controller:author, format:null, action:listOffers, id:null]

警报调用正常,我在那里得到了正确的 id 值。 正如您从控制器打印输出中看到的那样,id 为空,如果数据包含 id,我也会得到“未定义:”作为参数。 如果我从数据中删除 id,现在是 data[],这个 'undefined:' 消失

【问题讨论】:

    标签: javascript jquery grails gsp


    【解决方案1】:

    问题在于 2 点。 首先:在 main.gsp 中,我移动了字符串:

    <asset:javascript src="application.js"/>
    

    从文件末尾到靠近 css-loading 的头部。 这使得脚本做出响应。

    但后来我无法将“id”中的数据输入到参数中。 但通过重写行:

    data:[this.id] to data:{id: this.id}
    

    成功了。

    【讨论】:

      【解决方案2】:

      您可以为每个表格行提供 ID,然后在单击该行时响应事件:

      将其分解为一个简单的示例,仅使用部分来展示其工作原理。

      OrdersAndStoreController

      class OrdersAndStoreController {
      
          def index() {
              [prodBuffer: [new ProdBuffer(id: 1, volumeOffered: 100), new ProdBuffer(id: 2, volumeOffered: 200)]]
          }
      
          def listOffers() {
              render(template:"ListOffers", model:[offerDetails: [offer1: 'offer1', offer2: 'offer2']])
          }
      }
      
      class ProdBuffer{
          Integer id
          Integer volumeOffered
      }
      

      index.gsp

      <!DOCTYPE html>
      <html>
      <head>
      <meta name="layout" content="main" />
      
      <script type="text/javascript">
          $( document ).ready( function() {
              $( '.offers' ).click( function ( event ){
                  $.ajax({
                      url:'${g.createLink( controller:'ordersAndStore', action:'listOffers' )}',
                      data: [this.id],
                      type: 'get'
                  }).success( function ( data ) { $( '#offerList' ).html( data );     });
              });
          });
      </script>
      </head>
      <body>
      
      
      <table>
          <thead>
          <th>Volume offered</th>
          </thead>
          <g:each in="${prodBuffer}" status="i" var="pb">
              <tr id="${pb.id}" class="offers">
                  <td>${pb.volumeOffered}</td>
              </tr>
          </g:each>
      </table>
      
      <div id="offerList"></div>
      
      </body>
      </html>
      

      _ListOffers.gsp

      ${offerDetails}
      

      【讨论】:

      • 嗯,看起来不错,但 tr-tag 已经使用类:。我试图在 td-tag 中设置类,但 javascript 从未被触发。
      • 您可以使用多个类,我将其删除以进行演示,因此很清楚。 offer 类实际上并没有应用任何样式,我们只是将它用作 javascript 的钩子
      • 好吧,它仍然不会触发 javascript,表在模板上而不在与 javascript 相同的 gsp 文件中是否重要?
      • 尝试将 javascript 块添加到模板中。如果这不起作用,您可以将其添加到 /assets/javascripts 中的特定 javascript 文件中,请务必在 application.js 中添加一行,例如//= require myjavascriptfile
      • 我现在已经通过将脚本移动到模板进行测试,但无法正常工作,然后在asset/javascript 中创建了一个单独的文件,但无法正常工作。当我想到触发 javascript 的 onclick 版本时,它应该可以在主视图中包含脚本。该版本的问题是我没有将 id 传递给控制器​​。不管你如何转身,你总是在后面;-)
      【解决方案3】:

      你需要像这样改变你的元素

      <td><a onclick="listOffers(${pb.id})>${pb.volumeOffered}</a></td>
      

      和接受 id 的 Jquery 函数。

      <script type="text/javascript">
          function listOffers(id){
          $.ajax({
                  url:'${g.createLink( controller:'ordersAndStore', action:'listOffers' )}',
          data: [id],
          type: 'get'
          }).success( function ( data ) { $( '#offerList' ).html( data ); });
          }
      </script> 
      

      【讨论】:

      • 这是一个提升,现在调用了 javascript 和控制器。但是 id 不是在参数中发送的。我添加了一个日志打印,请参阅答案末尾的内容,以查看参数包含的内容。那就是:#--#[undefined:, controller:ordersAndStore, format:null, action:listOffers] 正如你所看到的,有一个名为 undefined 的参数,它是空的。您的回答中有一些拼写错误,gsp-line 中缺少引号,并且 gsp-line 中的 id 应该是 pb.id。
      • 我已经这样做了,并且控制器接收到参数“未定义:”它似乎无法识别 id 参数或..?
      • 您是否尝试过 listOffers('${pb.id}') 和 listOffers(${pb.id}) 两种方式? listOffers(${pb.id}) 一个对我有用。 :(
      • 奇怪,我是否加引号都没关系,都是一样的。我什至尝试在其中放置一个常量值 - 但没有其他任何事情发生。
      猜你喜欢
      相关资源
      最近更新 更多
      热门标签