Grails Remote Function and Ajax - grails

I am trying to list addresses and onChange event I send the address ID and return a list of users.
<g:select name="AddressID" from="${address}" optionKey="id" optionValue="address"
onchange="${ remoteFunction(
action:'testMe',
params:'\'id=\' + this.value' ,
update:'show' )}">
</g:select>
I call this div "show".
<div id="show">
<g:each in="${users}" status="i" var="C">
<h3>${C}</h3>
</g:each>
</div>
However, when I click the item on the list box I get the following error:
description The requested resource (/MyTest/WEB-INF/grails-app/views/test/testMe.jsp) is not available.
My understanding of an update attribute inside a remoteFunction is that it is the name of the div which gets refreshed after the remoteFunction call is compeleted.
Thanks.

I would reorganize your code a little to get the Ajax working:
Move your div contents into a partial template, called, say, _remoteResponse.gsp:
<g:each in="${users}" status="i" var="C">
<h3>${C}</h3>
</g:each>
Modify your controller's testMe action to render the response to a template, something like:
render (template:'remoteResponse', model:[users:['mike,tim']])
Make sure you have an ajax library setup in main.gsp, like:
<g:javascript library="prototype" />

Related

Grails form not submitting

Here is my Grails (2.3.6) controller:
class WidgetController {
def index() {
render(
view: "createNew",
model:[
]
)
}
def execute() {
println "Executing form submission!"
redirect(action: "listAll")
}
def listAll() {
// Does some stuff
}
}
The index URL is, say, http://localhost:8080/myapp/widget. The idea is that when someone goes to this URL, they are presented with an HTML form. When they fill out the form, they are sent (on the server side) to the execute() method, which does some heavy duty stuff and then redirects them to the listAll() method which does some final stuff and renders a web page for them to see.
Here is the HTML form on the createNew.gsp (rendered from the index() method:
<g:form name="create-new-form" url="[action:'execute',controller:'widget']">
<table class="pure-table pure-table-bordered">
<tr>
<td class="row-header">Fizz:</td>
<td><g:textField id="app-fizz" name="fizz" /></td>
</tr>
<tr>
<td class="row-header">Buzz:</td>
<td><g:textField id="app-buzz" name="buzz" /></td>
</tr>
</table>
<g:actionSubmit value="Create" />
</g:form>
When I go to this URL and submit the form (clicking the Create button) I get redirected to http://localhost/myapp/widget/execute which displays one of my customized error pages (basically a "Sorry this page is unavailable"-type error.
Additionally, in the log outputs, my println stating "Executing form submission!" is not firing. This tells me that I don't have something wired correctly: Grails is trying to redirect to an /execute URL but somehow isn't linking that URL with my controller's execute() method. Ideas?
Try with:
<g:actionSubmit action="execute" value="Create" />
If you specify only value for g:actionSubmit it creates button with this label and also redirect to action based on this value. If action name is different than button label you should specify action and value attributes. Take a look at documentation.
Note that if you use g:actionSubmit then action attribute of g:form will be ignored (which you specified btw.). You'll find more info where it may be useful in docs linked above.
use plain <input type="submit" value="go"/>. thus the form is submitted to the URI defined in <g:form> tag
g.actionSubmit or g.submitButton are needed, if you want to submit your form somewhere ELSE.

How can I use g:render with my g:each variable from a Map collection?

I have a def statusMap = HashMap<String, List<MyItem>>() that gets passed into my gsp page.
In my gsp page I have the following:
<g:each var="myList" in="${statusMap}">
<div id="pending_list" class="onTop">
<g:render template="/list" model="['list':"${myList.value}", 'listSize':"${myList.value.size()}"]" />
</div>
</g:each>
But I can't seem to correctly pass myList.value and myList.value.size() into my template. I think my quotes are wrong somehow but I'm not sure.
How can I correctly pass myList.value and myList.value.size() into the list template through the model?
Since you are using a map your itteration is based on keys within that Map. So the basic syntax looks like this:
<g:each in=${yourCoolMap.entrySet()}" var="entry">
${entry.key} = ${entry.value}
</g:each>
Thus, your code will look something like this:
<g:each var="myList" in="${statusMap.entrySet()}">
<div id="pending_list" class="onTop">
<g:render template="/list" model="['list': myList.value, 'listSize': myList.value.size()]" />
</div>
</g:each>

Using scriptlet or EL inside an attribute of a tag (Grails UI Plugin)

I want to trigger the same dialog on different ids in my gsp.
So here is the code:
<div class="yui3-widget-bd">
<g:each in="deployments" status="index" var="workflow">
<% def id = "reloadFile"+index %>
<gui:dialog title="Reload File" form="true" modal="true"
controller="admin" action="reloadFile"
triggers="[show:[id:'${id}', on:'click']]">
<p>To reload the file, please...</p><br />
<input type="file" id="deploymentFile" name="deploymentFile" />
</gui:dialog>
</g:each>
</div>
The problem is that the scriptlet code :
triggers="[show:[id:'<%=id %>', on:'click']]"
is not getting evaluated.
The Javascript part that listens for events in the source of the generated html looks like this:
YAHOO.util.Event.addListener("${id}", "click", GRAILSUI.gui_e0100d149e0a7b531017e0decaee9fce.show, GRAILSUI.gui_e0100d149e0a7b531017e0decaee9fce, true);
So how can i manage that the source looks like this ? :
YAHOO.util.Event.addListener("reloadFile1", "click", GRAILSUI.gui_e0100d149e0a7b531017e0decaee9fce.show, GRAILSUI.gui_e0100d149e0a7b531017e0decaee9fce, true);
Thank you.
Same as jsps:
If you want to execute some code
<% def something = true %>
If you want to use the return of the execution
<%= something ? "This is a truth statement" : "This is false" %>
Beware that this is probably code smell and the code should be in a domain, controller or taglib 99.9% of cases.
Here's the reference documentation for more info.

grails select with remoteFunction, can it update a g:textField?

I need to update the value of a textField, using a value on the server, based on the value the user chooses in a g:select. In code:
<g:select name="description" from="${momentum.MoneyTransType.prodList}" value="${moneyInstance?.description}"
noSelection="['':'-Select Description-']" onChange="${remoteFunction(action:'setHowMuch', update:[success:'howMuch', failure:'failure'],
params:'\'selection=\' + this.value', options=[asynchronous:false])}"/>
<g:textField id="howMuch" name="howMuch" value="${moneyInstance?.howMuch}"/>
It's not working. If I give the "update:[success:" a div id, all is good, but that's not what I want. I need to allow the user to enter in a free flow description (which I'll have in another textfield), and a free flow amount. I guess I could hide a div and then listen for changes to that div via jQuery, and then update the amount textField. Should I be able to update a textField using the remoteFunction "update" capability or using another grails capability?
Strangely, putting in a temporary 'toHide' div with a jQuery change function isn't working to update the textField, i.e. the following alert, etc, isn't firing:
$('#toHide').change(function() {
alert(" I got changed, value:");
$("#howMuch").text($(this).val());
});
Well, after writing all the below, I reread your question and see you stated you know it works with a div. So the rest of my answer might not be helpful, but what's wrong with using a div? An empty div won't display anything, so you don't need to hide it. So FWIW:
Put your <g:textField ...> in a template.
Add a div where where you want the template to be rendered. In other
words, replace the current <g:textField ..> with <div id=updateme name=updateme></div>
In your setHowMuch action, render the template.
For example, I do:
In view:
<g:select class='setTagtypeValue-class'
name='tagtype-${i}-header'
from="${org.maflt.ibidem.Tagtype.list(sort:'tagtype').groupBy{it.tagtype}.keySet()}"
value="${setTagtypeValue?.tagtype?.tagtype}"
valueMessagePrefix="tagtype"
noSelection="${['null':'Select One...']}"
onchange="${remoteFunction(action:'options', update:'tagtype-options-${i}',
params:'\'tagtype=\' + this.value +\'&i=${i}\'' )}" />
Controller action:
def options = {
def i = params.i ?: 0
def tagtypes = Tagtype.findAllByTagtype(params.tagtype)
render(template:"tagtypeList", model:[tagtypes:tagtypes,i:i])
}
tagypeList Template:
<table>
<tr>
<th></th>
<th><g:message code="tagtype.lookup"
default="Lookup Table" /></th>
<th><g:message code="tagtype.regexpression"
default="Field Rule" /></th>
<th><g:message code="tagtype.uicomponent"
default="UI Component" /></th>
</tr>
<g:each in="${tagtypes}" var="tagtype" status="j">
<tr>
<td><g:radio name="setTagtypesList[${i}].tagtype.id" value="${tagtype.id}"
checked="${(setTagtypeValue?.tagtype?.id == tagtype.id ||
(!setTagtypeValue?.tagtype?.id && j==0))}"></g:radio></td>
<td>${tagtype.lookupTable}</td>
<td>${tagtype.regexpression}</td>
<td><g:message code="${'uicomponent.' + tagtype.uicomponent.id}"
default="${tagtype.uicomponent.uicomponent}" />
</td>
</tr>
</g:each>
</table>
This code is from the metadataset (called field set in the UI) screen in http://www.maflt.org/products/Ibidem.

Grails filterPane plugin to fit page layout

I would like to have the filterPane to be inserted in my own div in order to fit my page layout. Basically I want to get rid of the default pop-up behavior and harmonize filterPane with the other elements of the application.
this is my gsp
<div class="filter">
<p>
<filterpane:isFiltered>
<filterpane:currentCriteria domainBean="demoracer.Pilot" />
</filterpane:isFiltered>
</p>
<g:formRemote method="post" name="form_search" url="${[action:'list']}" update="listContainer" >
<filterpane:filterPane customForm="true" formName="form_search" domainBean="demoracer.Pilot"
filterProperties="name," id="filterpaneContainer" />
<g:actionSubmit value="Apply Filter From Outside Filter Pane" action="list" />
</g:formRemote>
</div>
but the pane do not show up.
Thanks
Since the filterpane generates its own div, can't you just use the div it generates and restyle it to fit your layout? You can specify the id, class, and style attributes of the container div it generates. That should be more than enough to restyle it any way you'd like.
it doesn't seems possible since the html is statically created by the taglib
def output = """\
<div id="${containerId}"
class="filterPane ${containerClass ?: ''}"
style="display:none;${containerStyle}">
<h2>${title}</h2>
${openFormTag}
<input type="hidden" name="filterProperties" value="${propsStr}" />
<table cellspacing="0" cellpadding="0" class="filterTable">
"""

Resources