Grails,通过单击 table 行中的列执行 javascript

Grails, executing a javascript by clicking on a column in a table row

我有一个包含两个列表的视图:产品和报价。您可以 select 多行,方法是选中它们上的复选框,然后单击 link,将为每个 selected 产品创建报价行。 每个报价行都有产品的 ID,我将使用它在产品列表下方的列表中列出为该产品创建的所有报价。

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

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

所以我需要有一行:

<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 部分:

        <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,我也会将 'undefined:' 作为参数。 如果我从数据中删除 id,现在是 data[],这个 'undefined:' 消失

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

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

和Jquery接受id的函数。

<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> 

您可以为每个 table 行指定 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}

问题在2点。 第一:在 main.gsp 我移动了字符串:

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

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

但是后来我无法从 "id" 获取数据进入参数。 但是通过重写行:

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

成功了。