【问题标题】:Grails, sorting and filtering a grid at the same time using ajaxGrails,使用ajax同时对网格进行排序和过滤
【发布时间】:2017-10-06 15:40:41
【问题描述】:

我有一个包含很多列的网格(html-table),并希望在此表上结合过滤和排序。 目前我只对一列使用过滤,但对几列进行排序。 我想用ajax来做到这一点。 我读了一篇文章[http://www.craigburke.com/2011/01/23/grails-ajax-list-with-paging-sorting-and-filtering.html] 并尝试使其适应我的 grails-3.2.6 版本。

这很难解决,现在我完全陷入困境。 如果我在过滤器中添加任何内容,则不会发生任何事情,但是当我单击列时,会进行过滤并进行排序,再次单击时,不会调用 ajax 并且会用默认值覆盖过滤器。我已经设法在一个相同的测试项目上实现它。 代码很多,也许有办法以某种方式将整个项目包含在这个问题中?

如果有帮助的话,我会尽量在这里展示大部分重要的部分。

index.gsp:

<!DOCTYPE html>
<html>
<head>
    <meta name="layout" content="main" />
    <g:set var="entityName" value="${message(code: 'person.label', default: 'Person')}" />
    <title><g:message code="default.list.label" args="[entityName]" /></title>
    <script type="text/javascript">
        $(document).ready(function() {
            setupGridAjax();
            setupFilterAjax();
        });
    </script>

    <script type="text/javascript">            
        function setupGridAjax() {
            $('#gridPersons').find('.paginateButtons a, th.sortable a').on('click', function(event) {
                event.preventDefault();
                var url = $(this).attr('href');

                var grid = $(this).parents("table.ajax");
                $(grid).html($("#spinner").html());

                $.ajax({
                    type: 'GET',
                    url: url,
                    data: [tag],
                    success: function(data) {
                        $(grid).fadeOut('fast', function() {$(this).html(data).fadeIn('slow');});
                    }
                })
            });
        }
    </script> 
    <script type="text/javascript">            

    // Turn any input changes or form submission within a filter div into an ajax call
        function setupFilterAjax(){
            alert('FILTER--Anropat');
            $('div.filters select:input').on('change',function(event) {
                var filterBox = $(this).parents("div.filters");
                filterGrid(filterBox);
            });
            $("div.filters form").submit(function() {
                var filterBox = $(this).parents("div.filters");
                alert('FILTERBOX - '+filterBox);
                filterGrid(filterBox);
                return false;
            });
        }

    // Reload grid based on selections from the filter
        function filterGrid(filterBox) {
            alert('FILTER-change detected');
            var grid = $(filterBox).next("div.gridPersons");
            $(grid).html($("#spinner").html());

            var form = $(filterBox).find("form");
            var url = $(form).attr("action");
            var data = $(form).serialize();
                alert('FILTERGRID - '+url);
            $.ajax({
                type: 'POST',
                url: '${g.createLink( controller:'person', action:'index' )}',
                data: [tag],
                success: function(data) {
                $(grid).fadeOut('fast', function() {$(this).html(data).fadeIn('slow');});
            }
        });
    }

    </script> 
</head>
<body>
    <a href="#list-person" 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-person" 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>
        <div class="filters">
            <g:form action="register">
                <div id="selectMill">
                    Select tags:
                    <g:select class="selected" name="tag" from="${tagList}" value="${filters?.tag}" noSelection = "${['':'All']}" optionValue="" optionKey="" />
                </div>
                <div id="gridPersons">
                    <g:render template="Grid_Persons" model="personList" />
                </div>
                <div class="pagination">
                    <g:paginate total="${personCount ?: 0}" />
                </div>
                <fieldset class="buttons">
                    <input class="save" type="submit" value="${message(code: 'offer.create.from.buffer.label', default: 'Create')}" />
                </fieldset>
            </g:form>
        </div>
    </div>
</body>

模板:_Grid_Persons.gsp

<table class="ajax">
<thead>
    <tr>
        <g:sortableColumn property='reg' title='Register' />
        <g:sortableColumn property="id" title='Id' params="${filters}"/>
        <g:sortableColumn property='name' title='Name' params="${filters}"/>
        <g:sortableColumn property='tag' title='Tag' params="${filters}"/>
        <g:sortableColumn property='registered' title='Registered' params="${filters}"/>
</thead>
<tbody>
    <g:each in="${personList}" status="i" var="ps"> 
        <tr  class="${ (i % 2) == 0 ? 'even': 'odd'}">
            <td><g:checkBox name="ckb" value="${ps.id}" checked="false"  /></td>
            <td><g:link action="edit" id="${ps.id}">${ps.id}</g:link></td>
            <td>${ps.name}</td>
            <td>${ps.tag}</td>
            <td>${ps.registered}</td>
            <td>
    </g:each>
</tbody>

控制器的索引部分:

    def index(Integer max) {
    params.max = Math.min(max ?: 10, 100)

    def tagList = Person.withCriteria {
        projections {
            distinct("tag")
        }
    }

    def List<Person> personList = getPersonList()
    // Paging def prodBuffer = getPaginatedList(prodBuffer, max, params.offset?.toInteger())

    def filters = [tag: params.tag, sort: params.sort, order: params.order]

    def model = [personList: personList, filters:filters, tagList:tagList]

    if (request.xhr) {
        println("AJAX-Request!!!")
        render(template:"Grid_Persons", model:model)
        prodBuffer, offerDetails:offerDetails, filters:filters])
    } else {

        offerDetails: offerDetails, millList: millList, selectedMill:false, prodBufferCount: ProdBuffer.count()]
        [personList:personList,tagList:tagList]
    }

    Person.count(), tagList:tagList]
}

def List<Person> getPersonList() {
    println("getPersonList tag: "+params.tag)
    def tag = params.tag
    def c = Person.createCriteria()
    def tempList = c.list {
        if (tag) eq("tag", tag)
        if (params.sort){
            order(params.sort, params.order)
        }
    }
    return tempList
 }

来自调试:

页面已加载:

getPersonList 标签:null

在过滤器中选择“Grails”:

getPersonList 标签:Grails AJAX 请求!!!

点击了“名称”列标题

getPersonList 标签:Grails AJAX 请求!!!

-- 现在列表已排序(升序)和过滤

再次点击栏目:

getPersonList 标签:Grails

-- 现在列表已重新排序(降序)并且过滤仍然可以,但 SELECT TAGS 现在查看“全部”

第三次点击栏目:

getPersonList 标签: AJAX 请求!!!

-- 现在列表显示所有行并重新排序(升序)

现在使用推荐的插件解决了 - 数据表。

【问题讨论】:

  • 看看 DataTables,datatables.net,它会为你做这一切,对于相对少量的数据,例如最多可以说 2000 行,您可以使用一次加载所有行的标准表,或者更多地使用服务器端处理datatables.net/examples/data_sources/server_side.html
  • 看起来很有趣,但我有点担心项目未来的扩展,你永远不知道客户未来想要什么。因此,如果可能的话,我想用当前的技术解决它。不过我以后会在测试项目中测试一下。

标签: sorting grails html-table


【解决方案1】:

如果你赶时间,你可以注入https://datatables.net/,它会添加你需要的实用程序

【讨论】:

  • 通过使用数据表插件解决。谢谢!
  • 没问题。很高兴知道你克服了挑战
猜你喜欢
  • 2019-11-04
  • 2017-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-29
  • 2018-05-13
  • 2016-11-04
相关资源
最近更新 更多