So I am attempting to create a search field that will filter contacts on the fly. So I have the main results being displayed in a template (Contact/list.gsp):
<%# page import="contactmanager.Contact" %>
<!doctype html>
<html>
<head>
<meta name="layout" content="main">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<g:set var="entityName" value="${message(code: 'contact.label', default: 'Contact')}" />
<title><g:message code="default.list.label" args="[entityName]" /></title>
</head>
<body>
<div id="list-contact" class="mainContent-contact" 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 id="searchBox">
Instant Search: <g:remoteField name="q" update="searchResults" paramName="q" url="[controller:'contact', action:'search']"/>
</div>
<g:render template="searchResults"/>
<div class="pagination">
<g:paginate total="${contactInstanceTotal}" />
</div>
</div>
</body>
Here is my template (_searchResults.gsp):
<%# page import="contactmanager.Contact" %>
<div id = "searchResultsDiv">
<table>
<thead>
<tr>
<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')}" />
</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>
So currently, when I enter my text, nothing is happening. I added a printout in my search method and that's not being called at all. It's almost as if my remoteField is stagnant and is not active.
Am I missing a pre-requisite to this tag? I looked at the official API online, but didn't see anything at all indicating such. Is there something new to 2.0.0?
I am using the searchable plugin to pull results in the Controller, just FYI.
Thank you all for the help!
Update: So I added the javascript library call explicitly in my main.gsp and I seem to be getting some response back from the server, which is great news (missingPropertyException):
I had to add the plugin definition to the library call of jQuery (library = jquery and plugin= query)
First, thank you to those with the advice. I was able to figure out Firebug was a useful tool and that output pointed me to my library calls.
So I am now seeing action from my server using the correct jQuery library call. My last problem was that I was referencing the template name in the update of the remoteField, not the name of the main div within the template.
Once I fixed those, I am working. Thanks for all advice!
Related
I've search all evening to find a solution but the few I found does not stick with the newer version of grails that I use.
I know that it was limited to 6 fields before but now I can see 7. But I need a lot more columns, no matter that the page will be cluttered.
I have also checked the code that the f:table tag constructs and can not see that there is any limitation there.
I do not know what to do, I need to have this application ready tomorrow morning so I'm desperate finding a solution.
Please help..
I use GRAILS-3.2.3.
I can take any domain just it have more than 7 fields the 8th and upwards will not be displayed.
I use the grails command: ("generate-all" domain) to create controllers and views. And without doing anything more I get this problem.
Therefore I didn't think I needed to bring any code to show - anyone trying to this should get the same problem.
Below is the template for index.gsp -- Can anyone explain where the limitation of number of columns is made here?
<!DOCTYPE html>
<html>
<head>
<meta name="layout" content="main" />
<g:set var="entityName" value="\${message(code: '${propertyName}.label', default: '${className}')}" />
<title><g:message code="default.list.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="create" action="create"><g:message code="default.new.label" args="[entityName]" /></g:link></li>
</ul>
</div>
<div id="list-${propertyName}" 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>
<f:table collection="\${${propertyName}List}" />
<div class="pagination">
<g:paginate total="\${${propertyName}Count ?: 0}" />
</div>
</div>
</body>
</html>
I've made my last trial tonight, I'll continue tomorrow morning again because I think I need to hard code everything to get ready.
It was a nice advice to have a look at that "Anorak-Girl" report, but the source of the f:table-tag didn't show any limitation - so where can it be?
Thanks a lot but there's still a lot to do....I'll come back and good night.
Below is the code of _table.gsp or f:table-tag.
<table>
<thead>
<tr>
<g:each in="${domainProperties}" var="p" status="i">
<g:set var="propTitle">${domainClass.propertyName}.${p.name}.label</g:set>
<g:sortableColumn property="${p.name}" title="${message(code: propTitle, default: p.naturalName)}" />
</g:each>
</tr>
</thead>
<tbody>
<g:each in="${collection}" var="bean" status="i">
<tr class="${(i % 2) == 0 ? 'even' : 'odd'}">
<g:each in="${domainProperties}" var="p" status="j">
<g:if test="${j==0}">
<td><g:link method="GET" resource="${bean}"><f:display bean="${bean}" property="${p.name}" displayStyle="${displayStyle?:'table'}" /></g:link></td>
</g:if>
<g:else>
<td><f:display bean="${bean}" property="${p.name}" displayStyle="${displayStyle?:'table'}" /></td>
</g:else>
</g:each>
</tr>
</g:each>
</tbody>
</table>
possibly a limitation around f:table. Having had a look around:
http://blog.anorakgirl.co.uk/2016/01/what-the-f-is-ftable/
Finally… how to customise the f:table tag:
Place a file called _table.gsp in /grails-app/views/templates/_fields/
To do this manually:
An example and here you can iterate through your own property manually.
so in your case
<g:each in="\${${propertyName}List}" var="myDom">
<tr><td>${myDom.id}</td><td>${myDom.name}</td><td>and so on</td></tr>
</g:each>
In Grails 5, naming the properties explicitly in the f:table in the index.gsp view was the first way I got it to work for me, e.g.:
<f:table collection="${companyList}"
properties="name,url,hqLocation,area,yearFounded,revenue,fundsRaised,founder,product"/>
Alternatively, instead of naming the properties explicitly, you can set the attribute maxProperties (default 7) to a higher number, or to zero to display all properties.
<f:table collection="${companyList}" maxProperties="0"/>
To make this the default when creating future list views, install the templates and edit the index.gsp template file
grails install-templates
vi src/main/templates/scaffolding/index.gsp
and make the same change there.
I am trying to use template to apply to my scaffolding of f:table. However I do not know how to access the information of each line of my table in order to properly write my template. For simple fields, I have bean, property,label, and such but I cannot find any documentation pointing out how to access information for f:table. Please help me out guys !
Grails 3.1.x
See, if this sample below can provide you some hint.
<table>
<thead>
<tr>
<g:each in="${domainProperties}" var="p" status="i">
<g:set var="propTitle">
${domainClass.propertyName}.${p.name}.label
</g:set>
<g:sortableColumn property="${p.name}"
title="${message(code: propTitle, default: p.naturalName)}" />
</g:each>
</tr>
</thead>
<tbody>
<g:each in="${collection}" var="bean" status="i">
<tr class="${(i % 2) == 0 ? 'even' : 'odd'}">
<g:each in="${domainProperties}" var="p" status="j">
<g:if test="${j==0}">
<td>
<g:link method="GET" resource="${bean}">
<f:display bean="${bean}"
property="${p.name}"
displayStyle="${displayStyle?:'table'}" />
</g:link>
</td>
</g:if>
<g:else>
<td>
<f:display bean="${bean}"
property="${p.name}"
displayStyle="${displayStyle?:'table'}"/>
</td>
</g:else>
</g:each>
</tr>
</g:each>
</tbody>
</table>
Taken from the Github page.
The documentation for this plugin is a bit sketchy. The part you are looking for is in section Customizing Field Rendering.
The particular table you are looking for (containing value, bean, etc. parameters) is called Template parameters.
This is my first development using Grails. I have a requirement to create a questionnaire. This is my GSP page in which the questions are listed, possible answers for each question is listed and depending upon the type of answer a checkbox or radio button is displayed.It works fine till here
<div class="body">
<h1><g:message code="default.edit.label" args="[entityName]" /></h1>
<g:if test="${message}">
<div class="message">${message}</div>
</g:if>
<g:form action="createDonation" >
<div class="dialog">
<table>
<tbody>
<g:each in="${questionList}" status="i" var="questionInstance">
<tr>
<td>${fieldValue(bean: questionInstance, field: "text")}</td>
</tr>
<tr>
<g:each in="${questionInstance?.answers?}" status="j" var="a">
<td >
<g:if test="${fieldValue(bean: a, field: 'ansType.name') == 'Multiple'}"><g:checkBox name="myGroup" value="${false}" /></g:if>
<g:if test="${fieldValue(bean: a, field: 'ansType.name') == 'Single'}"><g:radio name="myGroup" value="1"/></g:if>
</td>
<td >${fieldValue(bean: a, field: "text")}</td>
</g:each>
</tr>
</g:each>
</tbody>
</table>
</div>
<div class="buttons">
<span class="button"><g:submitButton name="return" class="save" value="${message(code: 'default.button.backtodonorlogin.label', default: 'Back')}" /></span>
<span class="button"><g:submitButton name="submit" class="save" value="${message(code: 'default.button.saveandcontinue.label', default: 'Create')}" /></span>
</div>
</g:form>
</div>
</body>
Now i want to save the response of the user i.e what is the answer selected by each user for each question. For Multiple choice multiple answers can be selected. I am having a hard time to figure out how to create a model for that.
Help is requested.
Thanks
how about this: you create a QuestionResponse entity with the following properties:
question (linking to the question being answered)
response (answer given by user)
responder (responding user)
You can find out about the current user by using spring security for instance.
You can determine the question being responded from the hidden ID in your form.
I'm having a GSP page like below. The requirement is like a list of reports will be shown - the user has the option to select one report and can export the report to excel.
How to read the selected radio button and pass the selected value as "params" ?
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="layout" content="main" />
</head>
<body>
<div class="nav">
<span class="menuButton"><g:link class="create"
action="excelExport" params="['id':{ radId.value}]">Export To Excel</g:link>
</span>
</div>
<div class="body">
<div class="message">Select the report and click 'Excel Export'</div>
</div>
<g:form method="post">
<g:render template="displayUploadedReportsTemplate"
model="['uploadedReports':uploadedReports]" />
</g:form>
</body>
</html>
where displayUploadedReportsTemplate is:
<tbody>
<g:each in="${uploadedReports}" var="bbkRat">
<tr>
<td valign="top"><g:radio name="radId"
value="${fieldValue(bean:bbkRat,field:'id')}" /></td>
<td valign="top"><label> ${fieldValue(bean:bbkRat,field:'cmpName')}
</label></td>
<td valign="top"><label> ${fieldValue(bean:bbkRat,field:'reportCreationDate')}
</label></td>
<%--<td valign="top">
<label> ${fieldValue(bean:bbkRat,field:'cmpName')}
</label>
</td>
--%>
<tr>
</g:each>
</tbody>
How should the params value be below??
<g:link class="create"
action="excelExport" params="['id':{ radId.value}]">
i would recommand to use a radio button group. instead of using g:readio tag you can replace it with plain html input tag within you each tag, e.g.
<input type="radio" name="myGroup" value="1" checked="checked" />
<input type="radio" name="myGroup" value="2" />
<input type="radio" name="myGroup" value="3" />
you have already defined a form around your displayUploadedReportsTemplate. so you need to add a submit button to this form and a action where the params should be tramsitted, e.g.
<g:form method="post" action="test">
within test action you can print your params.myGroup and you will recieve to selected report.
<g:link is processed on server-side, so you can't use it on client side, you have to use javascript instead.
It would be like:
<a href="#" class="excelExport" onclick="doExport(); return false">
<script type="text/javascript">
function doExport() {
var id= $('input:radio[name=radId]:checked').val();
window.location = '${g.createLink(action:'excelReport')}?id=' + id;
}
</script>
ps I assume that you are using jQuery
This is the GSP code generated by Grails for the view of the edit action for a Person domain object which is part of my model, and also happens to be the primary class for authentication by the ACEGI security plug-in. I have snipped out a bunch of properties to keep it short. The file resides in the standard location, grails-app/views/person/edit.gsp
<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: 'person.label', default: 'Person')}" />
<title><g:message code="default.edit.label" args="[entityName]" /></title>
</head>
<body>
<div class="nav">
<span class="menuButton"><a class="home" href="${createLink(uri: '/')}">Home</a></span>
<span class="menuButton"><g:link class="list" action="list"><g:message code="default.list.label" args="[entityName]" /></g:link></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.edit.label" args="[entityName]" /></h1>
<g:if test="${flash.message}">
<div class="message">${flash.message}</div>
</g:if>
<g:hasErrors bean="${personInstance}">
<div class="errors">
<g:renderErrors bean="${personInstance}" as="list" />
</div>
</g:hasErrors>
<g:form method="post" >
<g:hiddenField name="id" value="${personInstance?.id}" />
<g:hiddenField name="version" value="${personInstance?.version}" />
<div class="dialog">
<table>
<tbody>
<tr class="prop">
<td valign="top" class="name">
<label for="username"><g:message code="person.username.label" default="Username" /></label>
</td>
<td valign="top" class="value ${hasErrors(bean: personInstance, field: 'username', 'errors')}">
<g:textField name="username" value="${personInstance?.username}" />
</td>
</tr>
...SNIP...
a bunch of props
</tbody>
</table>
</div>
<div class="buttons">
<span class="button"><g:actionSubmit class="save" action="update" value="${message(code: 'default.button.update.label', default: 'Update')}" /></span>
<span class="button"><g:actionSubmit class="delete" action="delete" value="${message(code: 'default.button.delete.label', default: 'Delete')}" onclick="return confirm('${message(code: 'default.button.delete.confirm.message', default: 'Are you sure?')}');" /></span>
</div>
</g:form>
</div>
</body>
</html>
My question is, how does the field personInstance get set up and populated?
I suspect this is a basic question which belies a fundamental lack of understanding on my part about how Grails works, but I need to know nonetheless.
This stems from the desire to create my own composite pages which access a Person object and its associated data, which is the heart of my app. I was expecting to be able to create a new page alongside this one, let's call it map.gsp, and get at the personInstance in some magic way. I can't figure out how to do that in spite of trying the obvious, and I think I have a gap right at the centre of my understanding.
PersonInstance will be populated on the controller.
When you submit your form, the associated controller will receive a map containing the fields present on your form.
So, in your controller you'll find a command like
personInstance.properties = params
where params is a map containing the fields submited for the controller, which the keys are the names of the input elements you defined on your gsp file.