Grails: getting object/model from AJAX response - ajax

I'm new to Grails and now I'm trying to retrieve objects/model from a controller to a template using AJAX. I want to make it so that sms properties would accessible to messageBox template, but this would always return me a null value. Could anyone help me with this? Any answer would be appreciated, here's my current code.
On my client
<g:form>
<label for="id">Sms ID </label>
<g:textField name="id" />
<g:submitToRemote value="search" update="msgBox"
url="[controller:'sms', action:'send']"/>
</g:form>
<g:render template="messageBox" model="${[sms:sms]}/>
My controller
SmsController{
def send = {
def sms = new Sms(...)
//assume properties have been set
...
...
render(template: messageBox, model:[sms:sms])
}
}
and my _messageBox.gsp
<div id="msgBox">
<span>Sms Property 1: ${sms?.property1}</span>
<span>Sms Property 2: ${sms?.property2}</span>
<span>Sms Property 3: ${sms?.property3}</span>
</div>

There seems to be a few logistical errors here
First, you seem to be rending the messageBox template twice. In your 'client' gsp you are calling...
<g:render template="messageBox" model="${[sms:sms]}/>
On page load 'sms' will always be null unless you are provided one on the page load. Then you also seem to be calling it again in your controller...
render(template: messageBox, model:[sms:sms])
Also, I would move the div:'msgBox' outside of the template and into your client something like...
<g:form>
<label for="id">Sms ID </label>
<g:textField name="id" />
<g:submitToRemote value="search" update="msgBox"
url="[controller:'sms', action:'send']"/>
</g:form>
<div id="msgBox">Waiting for some AJAX!</div>
Lastly, make sure you have a javascript library in your header like prototype or jquery. I'm not sure this will solve your problems but it will be a good start. Let me know!

Related

How to show flash.message in Grails after AJAX call

I want to show some flash message after completion of AJAX call. I am doing like this ..
Controller Action --
def subscribe()
{
def subscribe = new Subscriber()
subscribe.email = params.subscribe
if (subscribe.save())
{
flash.message = "Thanks for your subscribtion"
}
}
View Part --
Subscribe :
<g:formRemote onSuccess="document.getElementById('subscribeField').value='';" url="[controller: 'TekEvent', action: 'subscribe']" update="confirm" name="updateForm">
<g:textField name="subscribe" placeholder="Enter your Email" id="subscribeField" />
<g:submitButton name="Submit" />
</g:formRemote >
<div id="confirm">
<g:if test="${flash.message}">
<div class="message" style="display: block">${flash.message}</div>
</g:if>
</div>
My AJAX working fine but it is not showing me flash.message. After refresh page it displaying message. How to solve it ?
When you use ajax your page content isn't re-parsed, so your code:
<g:if test="${flash.message}">
<div class="message" style="display: block">${flash.message}</div>
</g:if>
will not run again.
So I agree with #James comment, flash is not the better option to you.
If you need to update your view, go with JSON. Grails already have a converter that can be used to this:
if (subscribe.save()) {
render ([message: "Thanks for your subscribtion"] as JSON)
}
And your view:
<g:formRemote onSuccess="update(data)" url="[controller: 'TekEvent', action: 'subscribe']" name="updateForm">
<g:textField name="subscribe" placeholder="Enter your Email" id="subscribeField" />
<g:submitButton name="Submit" />
</g:formRemote >
<script type='text/javascript'>
function update(data) {
$('#subscribeField').val('');
$('#confirm').html(data.message);
}
</script>
You have couple options,
First you can try to return the message from your controller in a form of json or a map and render it on the screen your self using javascript libraries, which is a bit different if you want to use Grails ajax tags.
The other option is using a plugin like one-time-data , which
Summary A safe replacement for "flash" scope where you stash data in
the session which can only be read once, but at any point in the
future of the session provided you have the "id" required.
Description
This plugin provides a multi-window safe alternative to flash scope
that makes it possible to defer accessing the data until any future
request (so long as the session is preserved).
more
Hope it helps

Load Dojo form from ajax call

I am trying to implement something like this.
http://app.maqetta.org/mixloginstatic/LoginWindow.html
I want the login page to load but if you click the signup button then an ajax will replace the login form with the signup form.
I have got this to work using this code
dojo.xhrGet({
// The URL of the request
url: "'.$url.'",
// The success callback with result from server
load: function(newContent) {
dojo.byId("'.$contentNode.'").innerHTML = newContent;
},
// The error handler
error: function() {
// Do nothing -- keep old content there
}
});'
the only problem is the new form just loads up as a normal form, not a dojo form. I have tried to return some script with the phaser but it doesnt do anything.
<div id="loginBox"><div class="instructionBox">Please enter your details below and click <a><strong>signup</strong>
</a> to have an activation email sent to you.</div>
<form enctype="application/x-www-form-urlencoded" class="site-form login-form" action="/user/signup" method="post"><div>
<dt id="emailaddress-label"><label for="emailaddress" class="required">Email address</label></dt>
<dd>
<input 0="Errors" id="emailaddress" name="emailaddress" value="" type="text"></dd>
<dt id="password-label"><label for="password" class="required">Password</label></dt>
<dd>
<input 0="Errors" id="password" name="password" value="" type="password"></dd>
<dt id="captcha-input-label"><label for="captcha-input" class="required">Captcha Code</label></dt>
<dd id="captcha-element">
<img width="200" height="50" alt="" src="/captcha/d7849e6f0b95cad032db35e1a853c8f6.png">
<input type="hidden" name="captcha[id]" value="d7849e6f0b95cad032db35e1a853c8f6" id="captcha-id">
<input type="text" name="captcha[input]" id="captcha-input" value="">
<p class="description">Enter the characters shown into the field.</p></dd>
<dt id="submitButton-label"> </dt><dd id="submitButton-element">
<input id="submitButton" name="submitButton" value="Signup" type="submit"></dd>
<dt id="cancelButton-label"> </dt><dd id="cancelButton-element">
<button name="cancelButton" id="cancelButton" type="button">Cancel</button></dd>
</div></form>
<script type="text/javascript">
$(document).ready(function() {
var widget = dijit.byId("signup");
if (widget) {
widget.destroyRecursive(true);
}
dojo.parser.instantiate([dojo.byId("loginBox")]);
dojo.parser.parse(dojo.byId("loginBox"));
});
</script></div>
any advice on how i can get this to load as a dojo form. by the way i am using Zend_Dojo_Form, if i run the code directly then everything works find but through ajax it doesnt work. thanks.
update
I have discovered that if I load the form in my action and run the __toString() on it it works when i load the form from ajax. It must do preparation in __toString()
Firstly; You need to run the dojo parser on html, for it to accept the data-dojo-type (fka dojoType) attributes, like so:
dojo.parser.parse( dojo.byId("'.$contentNode.'") )
This will of course only instantiate dijits where the dojo type is set to something, for instance (for html5 1.7+ syntax) <form data-dojo-type="dijit.form.Form" action="index.php"> ... <button type="submit" data-dojo-type="dijit.form.Button">Send</button> ... </form>.
So you need to change the ajax contents which is set to innerHTML, so that the parser reckognizes the form of the type dijit.form.Form. That said, I urge people into using a complete set of dijit.form.* Elements as input fields.
In regards to:
$(document).ready(function() {});
This function will never get called. The document, youre adding innerHTML to, was ready perhaps a long time a go.
About Zend in this issue:
Youre most likely rendering the above output form from a Zend_ Dojo type form. If the renderer is set as programmatic, you will see above html a script containing a registry for ID=>dojoType mappings. The behavior when inserting <script> as an innerHTML attribute value, the script is not run under most circumstances (!).
You should try something similar to this pseudo for your form controller:
if request is ajax dojoHelper set layout declarative
else dojoHelper set layout programmatic

How to pre populate my custom form in magento

I've created a custom form, similar to a customer registration form, in Magento.
i want to prepopulate this form when an error messages arises.
Does anyone know how I can prepopulate a custom form in Magento?
Without seeing you code it is hard to say which method will method will work, but one of these method should work.
Using JavaScript Validation - client side validate, only post if all require info is correct
<form name="my-form" id="my-form" method="post">
<label for="username">
< ?php echo $this->__("User name") ?> <span>*</span></label><br />
<input type="text" id="username" name="username" class="input-text required-entry"/>
.....
</form>
<script type=”text/javascript”>
//< ![CDATA[
var customForm = new VarienForm('my-form');
//]]>
</script>
See a list of all the validation class name
Repopulate field
To get a list of all the post variable information that the customer fill out
Mage::app()->getRequest()->getPost();
To get a form field (eg. <input type='text' name='firstname' ... />)
Mage::app()->getRequest()->getPost('firstname');
So in you .phtml try (this will not work if you doing a redirect on error)
<input type='text' name='firstname' value="<?php echo Mage::app()->getRequest()->getPost('firstname');?>" />
If the above doesnt work then you need the save the post info into a session.
In your controller if validation fail save the information to customer session
Mage::getSingleton( 'customer/session' )->setData( 'yourFormName', Mage::app()->getRequest()->getPost() );
In your phtml template, print the data if 'yourFormName' variable session exist.

How to execute code after the jquery.validate validation event?

I am using jquery.validate 1.9 and wish to execute code every time the form automatically validates (using the default behavior).
I hoped there would exist an OnValidated event I could hook into, but can not find one.
After validation executes I wish to conditionally enable other parts of the page if the form is valid, and disable otherwise.
How would one go about adding a method call following the existing validate() function?
I'm using jquery validate 1.8.1, but you should still be able to accomplish this using the valid() function.
valid() will either validate the entire form if you pass it the form ID or individual fields if you pass their respective ID's. It will then return a Boolean based on if they are all valid or not.
Something like this should work:
<script type="text/javascript">
function tab1Validation(){
if($('#field1, #field2, #field3').valid()){
//Logic if all fields valid - eg: $('#NextTab').show();
}else{
//Logic if one or more is invalid
}
}
</script>
<form id="yourform">
<div>
<input type="text" id="field1" name="field1" />
<input type="text" id="field2" name="field2" />
<input type="text" id="field3" name="field3" />
</div>
<input name="nextTab" type="button" value="Next Tab" onClick="tab1Validation();" />
</form>

Form Submit using a Javascript to invoke webflow transition, doesn't take the updated value on form

I am trying to invoke a form submit using javascript (jquery) to invoke a webflow transition. It works and the submit invokes the desired transition. But, the updated radio button values is not reflected on the model object which is posted.
Here is the code:
<form:form method="post" action="#" commandName="infoModel" name="pageForm">
<form:input type="input" path="testMsg" id="success" />
<input type="button" id="clearSelections" value="Clear Selections">
<div class="question">
<h4><c:out value="${infoModel.questionInfo.description}"/> </h4>
<form:radiobuttons path="infoModel.answerId"
itemValue="answerId" itemLabel="answerDescription" items="${infoModel.answers}" delimiter="<br/>" />
</div>
<input type="submit" name="_eventId_saveQualitativeInput" value="Save" id="save" />
$(document).ready(function() {
$('#tabs').tabs();
//Clear selections (copy is server-side)
$('#clearSelections').click(function() {
//$('input[type="radio"]').prop('checked', false);
$('input[type="radio"]').removeAttr('checked');
$('#save').trigger('click');
});
});
</form:form>
The form:radiobutton, generates the below html:
<div class="question">
<h4>Is this a general obligation of the entity representing a full faith and credit pledge? </h4>
<span>
<input type="radio" checked="checked" value="273" name="infoModel.answerId" id="infoModel.answerId1">
<label for="infoModel.answerId1">Yes</label>
</span>
<span><br>
<input type="radio" value="274" name="infoModel.answerId" id="infoModel.answerId2">
<label for="infoModel.answerId2">No</label>
</span>
<br>
<span class="error"></span>
</div>
The input id= "success" value is registered and when the control goes to the server, the value of input id= "success" is updated in the "infoModel" object. But the value of answerId is not updated on the "infoModel" object.
Thoughts if i am missing something in the form:radiobutton element or if there is something else wrong?
Thanks in advance!
EDIT:::::::
Thanks mico! that makes sense. I stripped of some of the code first time to make it precise, but i have a list which is being used for building the radio-buttons, below is the code:
<c:forEach items="${infoModel.list["index"]}" var="qa" varStatus="rowCount">
<div class="question">
<h4><c:out value="${question.questionInfo.description}"/> </h4>
<form:radiobuttons path="list["index"][${rowCount.index}].answerId" itemValue="answerId" itemLabel="answerDescription" items="${question.answers}" delimiter="<br/>" />
<br>
</div>
</c:forEach>
Could you please suggest how i could try this one out?
NOTE: The same code works on a regular form submit on click of a button of type submit. Its the javascript form submit which is not working. I also tried to do whatever i want to do in javascript and then invoke the button.trigger('click'); form got submitted but the changes made on form in my javascript didnt reflect.
With commandName inside a form:form tag you set "Name of the model attribute under which the form object is exposed" (see Spring Documentation). Then in path you should tell the continuation of the path inside the model attribute.
With this said I would only drop the extra word infoModel from path="infoModel.answerId" and have it rewritten as path="answerId" there under the form:radiobutton.

Resources