Grails, submit form in modal with ajax - ajax

Right now I can render a signup form in a twitter bootstrap modal, enter data into it, if the data doesn't pass constraints, the form will render correctly and say that the constraints don't pass (via error messages).
But the problem is, the formRemote that I'm using ends up "passing" even though the constraints aren't validated and the view I get contains the error message.
Essentially, I create a modal, then have it's data-remote set to the gsp containing this code:
<%# page import="security.User" %>
<html>
<head>
<r:layoutResources />
<g:set var="entityName" value="${message(code: 'user.label', default: 'User')}" />
<title><g:message code="default.create.label" args="[entityName]" /></title>
</head>
<body>
<g:hasErrors bean="${userInstance}">
<ul class="errors" role="alert">
<g:eachError bean="${userInstance}" 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:formRemote name="ajaxSignupForm" url="[action:'save',controller:'user']" update="signupModal .modal-body">
<div class="fieldcontain ${hasErrors(bean: userInstance, field: 'username', 'error')} required">
<label for="username">
<g:message code="user.username.label" default="Username" />
<span class="required-indicator">*</span>
</label>
<g:textField name="username" required="" value="${userInstance?.username}"/>
</div>
<div class="fieldcontain ${hasErrors(bean: userInstance, field: 'password', 'error')} required">
<label for="password">
<g:message code="user.password.label" default="Password" />
<span class="required-indicator">*</span>
</label>
<g:passwordField name="password" required="" value="${userInstance?.password}"/>
</div>
<div class="fieldcontain ${hasErrors(bean: userInstance, field: 'confirmPassword', 'error')} required">
<label for="confirmPassword">
<g:message code="user.confirmPassword.label" default="Confirm Password" />
<span class="required-indicator">*</span>
</label>
<g:passwordField name="confirmPassword" required="" value="${userInstance?.confirmPassword}"/>
</div>
<g:submitButton name="create" class="btn btn-success" value="Create Account" />
</g:formRemote>
<div style='display: none; text-align: left;' id='signupMessage'></div>
<r:layoutResources />
</body>
</html>
The update="signupModal .modal-body" chunk is what is updating the modal that this gsp is contained in. I understand that this is some nasty logic, so what can I do to make this better and actually perform correctly?

I prefer to enclose your formRemote inside a div. and then set the update="formParent".
E.g.
<div id="formParent" ... update="signupModal">
<g:formRemote
...
</div>

Related

Wget post data with text box that has randomly generated value?

I'm trying to use Wget to log in to my router and make a complete mirror of all the pages. The problem is, the router login page does not use the traditional "user" & "pass" ID for the text fields. It has a 'Password' and 'VmWpsPin' field. The ID for the 'Password' field is randomly generated every time the page is loaded/refreshed/requested. Below is the source code of the relevant part of the router page:
<body lang="en" class="superhubGUI" onload="javascript:Init()">
<div class="globalHeader">
<div id="nav">
<div id="logo">
<h1 id="header">Super Hub</h1>
</div>
<div id="buttons">Router Status
</div>
</div>
</div>
<div id="content">
<div id="container">
<div id="main">
<div class="panel noTitle" style="*padding:38px 30px 0px 30px">
<div id="login" class="inner">
<div class="inner-section">
<h2>Welcome to your Virgin Media Super Hub 2ac</h2>
<div id="signInForm">
<form action="/cgi-bin/VmLoginCgi" method="POST" name="signIn1" id="signIn">
<h2 id="loginTitle">Sign in to view and change your settings</h2>
<div class="field formField noHint username clearfix">
<label for="username"></label>
</div>
<div style="position:relative;top:-20px;" class="field formField noHint password clearfix">
<label for="password">Settings Password</label>
<input type="password" autocomplete="off" value="" maxlength="15" class="name required onefiftyPX inactive" name="KsCAqiihZb" id="password" onkeypress="handleKeyPress(event)" />
<div style="position:relative;left:-10px;" class="tooltip">
<img style="position:absolute; top:10px;" src="../images/toolTipButton.png"><span>Password can be found on the base of your Super Hub</span>
</div>
</div>
<div style="position:relative;top:-25px;" class="field formField noHint password clearfix">
<label for="password">WPS PIN</label>
<input type="text" autocomplete="off" value="" maxlength="15" class="name required onefiftyPX inactive" name="VmWpsPin" id="WpsPin" onkeypress="handleKeyPress(event)" />
<div style="position:relative;left:-10px;" class="tooltip">
<img style="position:absolute; top:10px;" src="../images/toolTipButton.png"><span>WPS PIN can be found on the base of your Super Hub</span>
</div>
</div>
<div>
Sign In
</div>
</form>
<p>
<span style="font-weight:bold;">Don't know your password?</span>
<br/>You'll find your default password on the bottom of your Super Hub.
</p>
</div>
</div>
</div><span class="pFoot"> </span>
</div>
</div>
My question is, how can I use Wget to login to the router when the ID changes at every request, is there somehow a way to request the page, parse the value out and then submit the form using something like --keep-session?
Or is there an alternative solution outside of Wget to automate the process? Any help is much appreciated.

Kendo UI - Validator message overwrite and empty errors array

I'm running into a problem with a Kendo validator. Three fields are set up for validation. Tabbing through them, the first name and last name fields show the expected message, but after tabbing through the from date field, the first name and last name messages get replaced with the from date message. Then, upon calling the validate() method, the errors array is empty even though validation fails. Also, if the save button is clicked without tabbing through the fields, the errors for the fields are not displayed at all.
Another strange thing is that if the spans for the messages are removed, all messages appear next to the first name field - they aren't displayed next to the corresponding input.
Any insight as to get this working properly would be appreciated.
the Script and HTML:
$(document).ready(function() {
$("#fn").kendoMaskedTextBox();
$("#ln").kendoMaskedTextBox();
$("#from").kendoDatePicker({
format: "MM/dd/yyyy"
});
$("#thru").kendoDatePicker({
format: "MM/dd/yyyy"
});
$("#btnSave").kendoButton({
icon: "tick",
click: function() {
if (!vld.validate())
alert(vld.errors.length);
}
});
var vld = $("#myForm").kendoValidator().data('kendoValidator');
})
<div id="myForm">
<p>
<label for="fn" class="myLabel">First Name:</label>
<input id="fn" required validationMessage="{0} Required" />
<span class="k-invalid-msg" data-for="fn"></span>
</p>
<p>
<label for="ln" class="myLabel">Last Name:</label>
<input id="ln" required validationMessage="{0} Required" />
<span class="k-invalid-msg" data-for="ln"></span>
</p>
<p>
<label for="from" class="myLabel">Period:</label>
<input id="from" required validationMessage="From date is required" />
<span> - </span>
<input id="thru" />
<span class="k-invalid-msg" data-for="from"></span>
</p>
<p>
<label class="myLabel"></label>
<button id="btnSave" class="btn">Save</button>
</p>
</div>
jsFiddle link: http://jsfiddle.net/artrfkmw/1/
Okay, it seems a/the trick to make this work is to set the values of the data-for attributes of the message spans to the name attribute of the input tag, not the id tag. So in the above example, adding name tags to the input elements is the quick fix:
<div id="myForm">
<p>
<label for="fn" class="myLabel">First Name:</label>
<input id="fn" name="fn" required validationMessage="{0} Required" />
<span class="k-invalid-msg" data-for="fn"></span>
</p>
<p>
<label for="ln" class="myLabel">Last Name:</label>
<input id="ln" name="ln" required validationMessage="{0} Required" />
<span class="k-invalid-msg" data-for="ln"></span>
</p>
<p>
<label for="from" name="from" class="myLabel">Period:</label>
<input id="from" required validationMessage="From date is required" />
<span> - </span>
<input id="thru" />
<span class="k-invalid-msg" data-for="from"></span>
</p>
<p>
<label class="myLabel"></label>
<button id="btnSave" class="btn" >Save</button>
</p>
</div>

Google Recaptcha incorrect-captcha-sol

I've got a Google recapture that refuses to accept my answers (error: incorrect-captcha-sol) yet I think I've test every step without any problems. Its on a simple HTML/CSS type site.
I can see in Firebug that the response and challenge are being sent from the contact form.
I've echoed back the fields in php and they are the same I'm sending (match firebug)
I've got a table on the same page but its not part (or in any way related) to the contact form.
HTML code:
<!-- Contact Form -->
<div class="row">
<div class="span9">
<form id="contact-form" class="contact-form" action="#">
<p class="contact-name">
<input id="contact_name" type="text" placeholder="Full Name (Required)" value="" name="name" />
</p>
<p class="contact-email">
<input id="contact_email" type="text" placeholder="Email Address (Required)" value="" name="email" />
</p>
<p class="contact-message">
<textarea id="contact_message" placeholder="Your Message (Required)" name="message" rows="15" cols="40" maxlength="150"></textarea>
</p>
<p class="contact-challenge">
<div id="recaptcha_widget" style="display:none">
<div id="recaptcha_image"></div>
<div class="recaptcha_only_if_incorrect_sol" style="color:red">Incorrect please try again</div>
<span class="recaptcha_only_if_image">Enter the words above:</span>
<span class="recaptcha_only_if_audio">Enter the numbers you hear:</span>
<input id="recaptcha_response_field" type="text" name="recaptcha_response_field" />
<div>Get another CAPTCHA</div>
<div class="recaptcha_only_if_image">Get an audio CAPTCHA</div>
<div class="recaptcha_only_if_audio">Get an image CAPTCHA</div>
<div>Help</div>
</div>
</p>
<script type="text/javascript" src="http://www.google.com/recaptcha/api/challenge?k=XXXX">
</script>
<noscript>
<iframe src="http://www.google.com/recaptcha/api/challenge?k=XXXX" height="300" width="500" frameborder="0"></iframe>
<textarea name="recaptcha_challenge_field" rows="3" cols="40"></textarea>
<input type="hidden" name="recaptcha_response_field" value="manual_challenge">
</noscript>
<p class="contact-submit">
<a id="contact-submit" class="submit" href="#">Send</a>
</p>
<div id="response">
</div>
</form>
</div>
PHP
require_once('recaptchalib.php');
$privatekey = "XXXX";
$resp = recaptcha_check_answer ($privatekey,
$_SERVER["REMOTE_ADDR"],
$details["recaptcha_challenge_field"],
$details["recaptcha_response_field"]);
if (!$resp->is_valid) {
// What happens when the CAPTCHA was entered incorrectly
$this->response_html .= '<p>The code you entered was incorrect, please try again. ' . $resp->error . '</p>';
$this->response_status = 0;
}
Thanks
I eventually figured it out I didn't initialize $resp before I used it.
So I've now got
$resp = null;
before the start of the IF statement and the code is now working correctly.
That's what I get for copy/pasting Google's code and not checking it carefully!

ruby forms in div elements

I'm having an issue where the form generated with ruby isn't included inside my #content div, is this because the form is generated after the html is read by the browser (sorry if I sound like a moron on this)
-- edit update - view source --
The code below generates with the email box and submit button outside of the content box
<div id="content">
<!-- text here -->
<form accept-charset="UTF-8" action="/password_resets" method="post">
<div style="margin:0;padding:0;display:inline">
<input name="utf8" type="hidden" value="✓" />
<input name="authenticity_token" type="hidden" value="afmtpSAc93w1uMcnouhY9XmbVTM7fE1VNFvZKnp0kMs=" />
</div>
<div class="field">
<input id="email" name="email" placeholder="email#website.com" type="text" />
</div>
<div class="actions">
<input name="commit" type="submit" value="Reset Password" />
</form> </div>
</div>
I'm not sure I got the question right, but in the html above the last </form> </div> should be </div> </form>
figured it out after visiting this link
Is it correct to use DIV inside FORM?
once I removed the div's for field and action it cleared everything up

issue while finding the xpath for span located inside div/h2 inside document

/*
Returning visitors login
<h2>
<label for="ctl00_Login2_UserName" id="ctl00_Login2_UserNameLabel">Email</label>
<br />
<input name="ctl00$Login2$UserName" type="text" value="pallavi#ensarm.com" maxlength="100" id="ctl00_Login2_UserName" class="formstyle2" style="width:150px;" />
<span id="ctl00_Login2_UserNameRequired" title="User Name is required." style="color:Red;visibility:hidden;">*</span>
<br />
<br />
<label for="ctl00_Login2_Password" id="ctl00_Login2_PasswordLabel">Password</label>
<br />
<input name="ctl00$Login2$Password" type="password" maxlength="100" id="ctl00_Login2_Password" class="formstyle2" style="width:150px;" />
<span id="ctl00_Login2_PasswordRequired" title="Password is required." style="color:Red;visibility:hidden;">*</span>
<a id="ctl00_Login2_ForgottenPasswordLink" href="ForgottenPassword.aspx">Forgotten password?</a>
</h2>
<h2 align="right">
<span id="ctl00_Login2_FailureText" style="color:Red;">Your login attempt was not successful. Please try again.</span>
<div class="button_right button_fixedwidth">
<a id="ctl00_Login2_ibnLogin" href="javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions("ctl00$Login2$ibnLogin", "", true, "Login2", "", false, true))">Login</a>
</div>
</h2>
</div>
*/
Above is my html pagesource i want xpath expression of span with id ctl00_Login2_FailureText. which is located inside div/h2
I have tried the fololowing xpath but its not working:
//span[#id='ctl00_Login2_FailureText' and contains(text(),'Your account has been temporarily locked because of a maximum number of incorrect login attempts.')]
Better try it:
(change "text()" with ".")
//div/h2/span[#id='ctl00_Login2_FailureText' and contains(.,'Your account has been temporarily locked because of a maximum number of incorrect login attempts.')]

Resources