Grails remote-pagination is refreshing entire page instead of div - grails

I am having problems with the grails plugin remote-pagination. I have created a new project and copy pasted the sample code for the plugin. There is a book class that has a list view and a template for the table. The pagination is supposed to update only the data in the div 'filteredList', but instead the page is refreshed with the layout view, _filtered.gsp, only. Below is the code :
Controller:
class BookController {
def scaffold = true
def list = {
[bookInstanceList: Book.list(max:10,offset: 0), bookInstanceTotal: Book.count()]
}
def filter = {
params.max = Math.min(params.max ? params.int('max') : 10, 100)
render(template: 'filter', model: [bookInstanceList: Book.list(params), bookInstanceTotal: Book.count()])
}
}
list.gsp - view :
<%# page import="com.intelligrape.Book" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta name="layout" content="main"/>
<g:set var="entityName" value="${message(code: 'book.label', default: 'Book')}"/>
<title><g:message code="default.list.label" args="[entityName]"/></title>
</head>
<body>
<div class="nav">
<span class="menuButton"><a class="home" href="${createLink(uri: '/')}"><g:message code="default.home.label"/></a>
</span>
<span class="menuButton"><g:link class="create" action="create"><g:message code="default.new.label" args="[entityName]"/></g:link></span>
</div>
<div class="body">
<h1><g:message code="default.list.label" args="[entityName]"/></h1>
<g:if test="${flash.message}">
<div class="message">${flash.message}</div>
</g:if>
<div id="filteredList">
<g:render template="filter"/>
</div>
</div>
</body>
</html>
_filtered.gsp - template for table of books
<div>
<div class="list">
<table>
<thead>
<tr>
<util:remoteSortableColumn property="id" title="${message(code: 'book.id.label', default: 'Id')}" update="filteredList" action="filter"/>
<util:remoteSortableColumn property="author" title="${message(code: 'book.author.label', default: 'Author')}" update="filteredList" action="filter"/>
<util:remoteSortableColumn property="name" title="${message(code: 'book.name.label', default: 'Name')}" update="filteredList" action="filter" max="5"/>
<util:remoteSortableColumn property="price" title="${message(code: 'book.price.label', default: 'Price')}" update="filteredList" action="filter"/>
</tr>
</thead>
<tbody>
<g:each in="${bookInstanceList}" status="i" var="bookInstance">
<tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
<td><g:link action="show" id="${bookInstance.id}">${fieldValue(bean: bookInstance, field: "id")}</g:link></td>
<td>${fieldValue(bean: bookInstance, field: "author")}</td>
<td>${fieldValue(bean: bookInstance, field: "name")}</td>
<td>${fieldValue(bean: bookInstance, field: "price")}</td>
</tr>
</g:each>
</tbody>
</table>
</div>
<div class="paginateButtons">
<util:remotePaginate total="${bookInstanceTotal}" update="filteredList" action="filter" pageSizes="[5: '5 on Page',10:'10 on Page',15:'15 on Page']" max="5" />
</div>
</div>

I just had to add the javascript library tag in the header section of the list.gsp page :
<g:javascript library="jquery" />

Related

Grails Parent Child Form not saving child data

I am trying to create a parent child form with Author and Book domain classes. The view works fine and lets me enter books when I creating a new Author. However, when I add a new author and the books and check the database (dbconsole), I see a new record in the Author table but no records are added to the Book table. Can you please let me know what I am missing or doing wrong here?
Here are my domain classes:
AUTHOR:
package bookauthor1tomany
import org.apache.common.collections.list.*
import org.apache.commons.collections.ListUtils.*
class Author {
static constraints = {
}
String name
String category
List<Book> books = new ArrayList<>()
static hasMany = [ books:Book ]
static mapping = {
books cascade:"all-delete-orphan"
}
def getExpandableBookList() {
return LazyList.decorate(books, FactoryUtils.instantiateFactory(Book.class))
}
String toString(){
return "${name}" - "${category}"
}
}
BOOK
package bookauthor1tomany
class Book {
static constraints = {
}
String title
boolean _deleted
static transients = [ '_deleted' ]
static belongsTo = [ author:Author ]
def String toString() {
return title
}
}
AuthorController
I haven't changed anything with the controller. This is the default generated save method for the Author controller.
#Transactional
def save(Author authorInstance) {
if (authorInstance == null) {
notFound()
return
}
if (authorInstance.hasErrors()) {
respond authorInstance.errors, view:'create'
return
}
authorInstance.save flush:true
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.created.message', args: [message(code: 'author.label', default: 'Author'), authorInstance.id])
redirect authorInstance
}
'*' { respond authorInstance, [status: CREATED] }
}
}
GSPs
create.gsp
<!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.create.label" args="[entityName]" /></title>
</head>
<body>
<g:message code="default.link.skip.label" default="Skip to content…"/>
<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="list" action="index"><g:message code="default.list.label" args="[entityName]" /></g:link></li>
</ul>
</div>
<div id="create-author" class="content scaffold-create" role="main">
<h1><g:message code="default.create.label" args="[entityName]" /></h1>
<g:if test="${flash.message}">
<div class="message" role="status">${flash.message}</div>
</g:if>
<g:hasErrors bean="${authorInstance}">
<ul class="errors" role="alert">
<g:eachError bean="${authorInstance}" var="error">
<li <g:if test="${error in org.springframework.validation.FieldError}">data-field-id="${error.field}"</g:if>><g:message error="${error}"/></li>
</g:eachError>
</ul>
</g:hasErrors>
<g:form url="[resource:authorInstance, action:'save']" >
<fieldset class="form">
<g:render template="authortemp"/>
</fieldset>
<fieldset class="buttons">
<g:submitButton name="create" class="save" value="${message(code: 'default.button.create.label', default: 'Create')}" />
</fieldset>
</g:form>
</div>
</body>
</html>
_form.gsp
<%# page import="BookAuthor1ToMany" %>
<div class="fieldcontain ${hasErrors(bean: authorInstance, field: 'books', 'error')} ">
<label for="books">
<g:message code="author.books.label" default="Books" />
</label>
<ul class="one-to-many">
<g:each in="${authorInstance?.books?}" var="b">
<li><g:link controller="book" action="show" id="${b.id}">${b?.encodeAsHTML()}</g:link></li>
</g:each>
<li class="add">
<g:link controller="book" action="create" params="['author.id': authorInstance?.id]">${message(code: 'default.add.label', args: [message(code: 'book.label', default: 'Book')])}</g:link>
</li>
</ul>
</div>
<div class="fieldcontain ${hasErrors(bean: authorInstance, field: 'name', 'error')} required">
<label for="name">
<g:message code="author.name.label" default="Name" />
<span class="required-indicator">*</span>
</label>
<g:textField name="name" required="" value="${authorInstance?.name}"/>
</div>
_authortemp.gsp
<div class="dialog">
<table>
<tbody>
<tr class="prop">
<td valign="top" class="name"><label for="name">Name:</label></td>
<td valign="top" class="value ${hasErrors(bean:authorInstance,field:'name','errors')}">
<input type="text" id="name" name="name" value="${fieldValue(bean:authorInstance,field:'name')}"/>
</td>
</tr>
<tr class="prop">
<td valign="top" class="name"><label for="category">Category:</label></td>
<td valign="top" class="value ${hasErrors(bean:authorInstance,field:'category','errors')}">
<input type="text" id="category" name="category" value="${fieldValue(bean:authorInstance,field:'category')}"/>
</td>
</tr>
<tr class="prop">
<td valign="top" class="name"><label for="books">Books:</label></td>
<td valign="top" class="value ${hasErrors(bean:authorInstance,field:'books','errors')}">
<g:render template="books" model="['authorInstance':authorInstance]" />
</td>
</tr>
</tbody>
</table>
</div>
_books.gsp
<script type="text/javascript">
var childCount = ${authorInstance?.books.size()} + 0;
function addChild() {
var htmlId = "book" + childCount;
var deleteIcon = "${resource(dir:'images/skin', file:'database_delete.png')}";
var templateHtml = "<div id='" + htmlId + "' name='" + htmlId + "'>\n";
templateHtml += "<input type='text' id='expandableBookList[" + childCount + "].title' name='expandableBookList[" + childCount + "].title' />\n";
templateHtml += "<span onClick='$(\"#" + htmlId + "\").remove();'><img src='" + deleteIcon + "' /></span>\n";
templateHtml += "</div>\n";
$("#childList").append(templateHtml);
childCount++;
}
</script>
<div id="childList">
<g:each var="book" in="${authorInstance.books}" status="i">
<g:render template='book' model="['book':book,'i':i]"/>
</g:each>
</div>
<input type="button" value="Add Book" onclick="addChild();" />
_book.gsp
<div id="book${i}">
<g:hiddenField name='expandableBookList[${i}].id' value='${book.id}'/>
<g:textField name='expandableBookList[${i}].title' value='${book.title}'/>
<input type="hidden" name='expandableBookList[${i}]._deleted' id='expandableBookList[${i}]._deleted' value='false'/>
<span onClick="$('#expandableBookList\\[${i}\\]\\._deleted').val('true'); $('#expandableBookList${i}').hide()">Delete</span>
</div>
You don't need the
List<Book> books = new ArrayList<>()
in your domain. The hasMany will give you a books collection by default. That might be causing some issues. Also, have you debugged in your controller to make sure that the books collection is populated when the save occurs.

Dropdown list in grails

In my program, which is a project tracker, I have a table with rows corresponding to the projects, and columns corresponding to the different information about the project (name, due date, status etc.). The last column should be 'More' column, that should display a dropdown list of additional attributes of the project whenever you press it. How do I do that in Grails?
Below is my list.gsp:
<calendar:resources lang="en"/>
<!doctype html>
<html>
<head>
<meta name="layout" content="layoutMain"/>
<g:set var="entityName" value="${message(code: 'project.label', default: 'Project')}" />
<title><g:message code="default.list.label" args="[entityName]" /></title>
</head>
<body>
<div class="nav" role="navigation">
<ul>
<li><g:link class="create" action="create"><button>New Project</button></g:link></li>
</ul>
</div>
<div id="list-project" 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>
<thead>
<tr>
<g:sortableColumn property="name" title="${message(code: 'project.name.label', default: 'Name')}" />
<g:sortableColumn property="dueDate" title="${message(code: 'project.dueDate.label', default: 'Due Date')}" />
<g:sortableColumn property="startDate" title="${message(code: 'project.startDate.label', default: 'Start Date')}" />
<g:sortableColumn property="status" title="${message(code: 'project.name.label', default: 'Status')}" />
<g:sortableColumn property="requirements" title="${message(code: 'project.name.label', default: 'Requirements')}" />
<g:sortableColumn property="design" title="${message(code: 'project.name.label', default: 'Design')}" />
<g:sortableColumn property="development" title="${message(code: 'project.name.label', default: 'Development')}" />
<g:sortableColumn property="qa" title="${message(code: 'project.name.label', default: 'QA')}" />
<g:sortableColumn property="ua" title="${message(code: 'project.name.label', default: 'UA')}" />
<g:sortableColumn property="delivery" title="${message(code: 'project.name.label', default: 'Delivery')}" />
<g:sortableColumn property="more" title="${message(code: 'project.name.label', default: 'More')}" />
</tr>
</thead>
<tbody>
<g:each in="${projectInstanceList}" status="i" var="projectInstance">
<tr class="${(i % 2) == 0 ? 'even' : 'odd'}">
<td><g:link action="show" id="${projectInstance.id}">${fieldValue(bean: projectInstance, field: "name")}</g:link></td>
<td><g:formatDate date="${projectInstance.dueDate}" /></td>
<td><g:formatDate date="${projectInstance.startDate}" /></td>
<td><g:link action="show" id="${projectInstance.id}">${fieldValue(bean: projectInstance, field: "status.name")}</g:link></td>
<td><g:link action="show" id="${projectInstance.id}">${fieldValue(bean: projectInstance, field: "requirements.name")}</g:link></td>
<td><g:link action="show" id="${projectInstance.id}">${fieldValue(bean: projectInstance, field: "design.name")}</g:link></td>
<td><g:link action="show" id="${projectInstance.id}">${fieldValue(bean: projectInstance, field: "development.name")}</g:link></td>
<td><g:link action="show" id="${projectInstance.id}">${fieldValue(bean: projectInstance, field: "qa.name")}</g:link></td>
<td><g:link action="show" id="${projectInstance.id}">${fieldValue(bean: projectInstance, field: "ua.name")}</g:link></td>
<td><g:link action="show" id="${projectInstance.id}">${fieldValue(bean: projectInstance, field: "delivery.name")}</g:link></td>
<td><g:link action="show" id="${projectInstance.id}">${fieldValue(bean: projectInstance, field: "delivery.name")}</g:link></td>
</tr>
</g:each>
</tbody>
</table>
<div class="pagination">
<g:paginate total="${projectInstanceTotal}" />
</div>
</div>
</body>
</html>
If you want to use standard Grails you can create a dropdown in Grails using a g:select tag. A prettier solution might be to use jQuery (or similar) to show hide a block of HTML.
If your project domain looks something like:
class Project {
String name
...
// more info
String attr1
int attr2
boolean isAttr3
}
You can add a convenience method to your domain to aggregate the fields into a list (or possibly another object) that can be used for a drop down box. E.g.
// utility getter to aggregate the fields into an array
def getMoreInfo() {
[attr1, attr2, isAttr3]
}
Then you can use the following in your GSP:
<td><g:select name="more" from="${projectInstance.moreInfo}" /></td>
On the click of more column you can send an Ajax request to some action which can bring you JSON of two arrays:
{extraColumns:{c1,c2}, columnValues:{{v11,v12}, {v21,v22}}}
In the response of Ajax you can parse the JSON and create additional columns for headers and additional column values for rows.

Grails params.max returns a map

I am new to grails and have just started developing applications in work. The first thing that i wanted to do is create a gsp with two tables, each table having pagination functionality. With a research I found that there is a plugin called remotePagination that uses ajax to update a tables pagination. The problem that i am having is that the 'params.max' and 'params.offset' value is a map of two strings rather than just a string value. On opening the page the 'list' closure is called and with the correct values set for the max and offset, lets say 10. On the second call, when the ajax closure is called the max and offset values are each held within a map as follows:
params.max = [10,10]
params.offset = [10,10]
The code I am using is as follows:
Controller:
def list = {
params.max = Math.min(params.int('max') ?: 10, 100)
[bookInstanceList: Book.list(params), bookInstanceTotal: Book.count()]
}
def ajaxListBooks = {
params.max = Math.min(params.int('max') ?: 10, 100)
render(template: "bookList", model:[bookInstanceList: Book.list(params), bookInstanceTotal: Book.count()])
}
list.gsp
<%# page import="com.intelligrape.Book" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta name="layout" content="main"/>
<g:set var="entityName" value="${message(code: 'book.label', default: 'Book')}"/>
<title><g:message code="default.list.label" args="[entityName]"/></title>
<g:javascript library="prototype"/>
</head>
<body>
<div class="nav">
<span class="menuButton"><a class="home" href="${createLink(uri: '/')}"><g:message code="default.home.label"/></a>
</span>
<span class="menuButton"><g:link class="create" action="create"><g:message code="default.new.label" args="[entityName]"/></g:link></span>
</div>
<div class="body">
<h1><g:message code="default.list.label" args="[entityName]"/></h1>
<g:if test="${flash.message}">
<div class="message">${flash.message}</div>
</g:if>
<div id="repoList">
<g:render template="bookList"/>
</div>
</div>
</body>
</html>
_listBooks.gsp
<%# page import="com.nmi.uk.sw.subzero.Book" %>
<div>
<table>
<thead>
<tr>
<util:remoteSortableColumn property="author" title="${message(code: 'book.author.label', default: 'Author')}" update="repoList" action="ajaxListBooks"/>
<util:remoteSortableColumn property="name" title="${message(code: 'book.name.label', default: 'Name')}" update="repoList" action="ajaxListBooks"/>
<util:remoteSortableColumn property="price" title="${message(code: 'book.price.label', default: 'Price')}" update="repoList" action="ajaxListBooks"/>
</tr>
</thead>
<tbody>
<g:each in="${bookInstanceList}" status="i" var="bookInstance">
<tr class="${(i % 2) == 0 ? 'even' : 'odd'}">
<td><g:link action="show" id="${bookInstance.id}">${fieldValue(bean: bookInstance, field: "author")}</g:link></td>
<td>${fieldValue(bean: bookInstance, field: "name")}</td>
<td>${fieldValue(bean: bookInstance, field: "price")}</td>
</tr>
</g:each>
</tbody>
</table>
<div class="paginateButtons">
<util:remotePaginate total="${bookInstanceTotal}" update="repoList"
action="ajaxListBooks"
pageSizes="[10,20,30,40,50,60,70,80,90,100]" />
</div>
</div>
The above code is based on the sample application for the remotePagination tutorial. It isn't that different. I created it just to see if the plugin would work before I integrated it into my application.
I would like to know if any one else has come across this problem and if there is a solution to it. Many thanks.
In your _bookList.gsp, there is an error in <util:remotePaginate tag:
pageSizes="[10,20,30,40,50,60,70,80,90,100]"
pageSizes should be a map, not a list, like:
pageSizes="[10:'10 Per Page', 20: '20 Per Page', 50:'50 Per Page',100:'100 Per Page']"

Grails file upload Kendoui

can someone please tell me a running example of upload file in kendoui?
As I have tried to upload file and its uploading in view page but when I click on save button I can't find that file in show page.I searched on it on internet then I found some problem of server.So someone please tell me how to use server in my case.I'm working on a grails project
Code That I have Used.:--
<tr class="prop">
<td valign="top" class="name">
<label>File Upload</label>
<input name="photos[]" id="photos" type="file" /><script>$(document).ready(function ()$("#photos").kendoUpload({
autoUpload:true,
upload: onUpload,
error: onError
});
function onError(e) {
// Array with information about the uploaded files
var files = e.files;
if (e.operation == "upload") {
alert("Failed to uploaded " + files.length + " files");
}
// Suppress the default error message
e.preventDefault();
},
function onUpload(e) {
var files = e.files;
if (e.operation == "upload") {
alert("Successfully uploaded " + files.length + " files");
}
});</script>
</td>
</tr>
i'm ading the view file :- create.gsp
<%# page import="ten.SkeletonBill"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="layout" content="billing" />
<get var="entityName"
value="${message(code: 'skeletonBill.label', default: 'SkeletonBill')}" />
<title><g:message code="default.create.label"
args="[entityName]" /></title>
<script src="source/kendo.all.js"></script>
<link href="styles/kendo.common.css" rel="stylesheet" />
<link href="styles/kendo.default.css" rel="stylesheet" />
</head>
<body>
<content tag="menu-function">
<li><span class="k-link"><a href="#"
onclick="SkeletonBillForm.submit();return false;"><i
class="icon-plus-sign"></i>
<g:message code="default.button.save.label" /></a></span></li>
</content>
<div class="body">
<h1>
<g:message code="default.create.label" args="[entityName]" />
</h1>
<g:if test="${flash.message}">
<div class="message">
${flash.message}
</div>
</g:if>
<g:hasErrors bean="${skeletonBillInstance}">
<div class="alert alert-error">
<a class="close" data-dismiss="alert">Ă—</a>
<g:renderErrors bean="${skeletonBillInstance}" as="list" />
</div>
</g:hasErrors>
<g:uploadForm name="SkeletonBillForm" action="save" method="post">
<div class="dialog">
<table>
<tbody>
<tr class="prop">
<td valign="top" class="name"><label for="bones"><g:message
code="skeletonBill.bones.label" default="Bones" /></label></td>
<td valign="top"
class="value ${hasErrors(bean: skeletonBillInstance, field: 'bones', 'errors')}">
<g:textField name="bones"
value="${fieldValue(bean: skeletonBillInstance, field: 'bones')}" />
</td>
</tr>
<tr class="prop">
<td valign="top" class="name"><label for="dateOfBirth"><g:message
code="skeletonBill.dateOfBirth.label" default="Date Of Birth" /></label>
</td>
<td valign="top"
class="value ${hasErrors(bean: skeletonBillInstance, field: 'dateOfBirth', 'errors')}">
<g:textField name="dateOfBirth"
value="${skeletonBillInstance?.dateOfBirth}" /> <script>$(document).ready(function () {$("#dateOfBirth").kendoDatePicker({format:"yyyy-MM-dd"})});</script>
</td>
</tr>
<tr class="prop">
<td valign="top" class="name">
<label>File Upload</label>
<input name="excelSheet" id="excelSheet" type="file" />
<script>
$(document).ready(function() {
$("#excelSheet").kendoUpload();
},
function onError(e) {
// Array with information about the uploaded files
var files = e.files;
if (e.operation == "upload") {
alert("Failed to uploaded " + files.length + " files");
}
// Suppress the default error message
e.preventDefault();
},
function onUpload(e) {
var files = e.files;
if (e.operation == "upload") {
alert("Successfully uploaded " + files.length + " files");
}
});
</script>
</td>
</tr>
</tbody>
</table>
</div>
</g:uploadForm>
</div>
</body>
</html>
And Also Controller.gsp
def save = {
def skeletonBillInstance = new SkeletonBill(params)
if(!skeletonBillInstance.empty){
println "Name: ${skeletonBill.bones}"
flash.message = "${message(code: 'default.created.message', args: [message(code: 'skeletonBill.label', default: 'SkeletonBill'), skeletonBillInstance.id])}"
redirect(action: "show", id: skeletonBillInstance.id)
}
} else {
render(view: "create", model: [skeletonBillInstance: skeletonBillInstance])
}
}
Couple of things
1) If you want to use KendoUI, I wouldn't use the gsp tags. Please use the normal form tags to define your form, if you do this grails resorts to using the prototype plugin for.
2) I will not mix the script code with the tags.
3) If you are using grails 2.0, you can use the KendoUI plugin, you can find more information at http://grails.org/plugin/kendo-ui
Hope that helps.

Grails - Refreshing object list using checkbox?

So I'm diving into Grails for the first time and am trying to accomplish what I think would be an easy task, so I hope this is trivial. Time spent on it is making me feel otherwise :)
So I have a list of Contacts in a database that are tied to a boolean called isActive. I want to have a check box in my list gsp that determines whether to show inactive members or not.
I've tried using a Javascript function (which I could successfully call, but wasn't sure how to handle the passing after the call). I've also tried to add a g:if to check to see if the box's checked property was enabled, but this results in a null object (which I suspected would happen).
I've also tried attaching a remoteFunction call on the onclick of the checkbox, but I never get a response back unfortunately.
Any advice? Thanks - I appreciate it. The challenges of teaching yourself a web language for the first time :)
<html>
<head>
<meta name="layout" content="main">
<g:set var="entityName" value="${message(code: 'contact.label', default: 'Contact')}" />
<title><g:message code="default.list.label" args="[entityName]" /></title>
<g:javascript>
function updateThisPage()
{
}
</g:javascript>
</head>
<body>
<g:message code="default.link.skip.label" default="Skip to content…"/>
<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>
<li><g:checkBox name="showInactives" value="${false}" onclick="....." /></li>
</ul>
</div>
<div id="list-contact" 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>
<thead>
<tr>
<g:if test="${isActive?.checked}">
<g:sortableColumn property="firstName" title="${message(code: 'contact.firstName.label', default: 'First Name')}" />
<g:sortableColumn property="lastName" title="${message(code: 'contact.lastName.label', default: 'Last Name')}" />
<g:sortableColumn property="phone" title="${message(code: 'contact.phone.label', default: 'Phone')}" />
<g:sortableColumn property="email" title="${message(code: 'contact.email.label', default: 'Email')}" />
<g:sortableColumn property="title" title="${message(code: 'contact.title.label', default: 'Title')}" />
<g:sortableColumn property="jobFunc" title="${message(code: 'contact.jobFunc.label', default: 'Job Func')}" />
</g:if>
</tr>
</thead>
<tbody>
<g:each in="${contactInstanceList}" status="i" var="contactInstance">
<g:if test="${contactInstance.isActive}">
<tr class="${(i % 2) == 0 ? 'even' : 'odd'}">
<td><g:link action="show" id="${contactInstance.id}">${fieldValue(bean: contactInstance, field: "firstName")}</g:link></td>
<td>${fieldValue(bean: contactInstance, field: "lastName")}</td>
<td>${fieldValue(bean: contactInstance, field: "phone")}</td>
<td>${fieldValue(bean: contactInstance, field: "email")}</td>
<td>${fieldValue(bean: contactInstance, field: "title")}</td>
<td>${fieldValue(bean: contactInstance, field: "jobFunc")}</td>
</tr>
</g:if>
</g:each>
</tbody>
</table>
<div class="pagination">
<g:paginate total="${contactInstanceTotal}" />
</div>
</div>
</body>
Why don't you try JQuery & CSS combination? For example, with every field you have, add a class "Active" or "Inactive" according to their record in Database. Then when you click the button, simply add the class "Hidden" for all the elements that have "Inactive" class.
jQuery("#hideInactiveContact").click(function(){
jQuery(".Inactive").addClass("Hidden");
});
jQuery("#showInactiveContact").click(function(){
jQuery(".Inactive").removeClass("Hidden");
});
In CSS, you can do the following and all the elements of "Hidden" class will be hid:
.Hidden {
display: none;
}

Resources