custom jquery validation and unobtrusive JavaScript - javascript

I'm trying to write a custom validation that gives an error if html exists in the textarea when they submit a form.
I have the following -
its not working and I'm not sure why.
also I don't understand the unobtrusive part
can someone show me how to do that as I am seeing other examples on SO that have it.
text area has a class"note"
the form is called "noteform"
<script type="text/javascript" >
$(document).ready(function () {
$.validator.addMethod('nohtml', function (value, element) {
var text = $(".note").text();
if ($(text).length > 0) {
return false;
}
else {
return true;
}
}, 'Html not allowed');
// // **not sure what to do here**
// $.validator.unobtrusive.adapters.add('containsnohtml', {}, function (options) {
// options.rules['nohtml'] = false;
// options.messages['nohtml'] = options.message;
// });
$('#noteform').validate({
rules: { nohtml: "required nohtml" }
});
});
</script>

There's a couple issues here. One is you're trying to mix unobtrusive and regular jquery validation. If you want to use validate like this then you need to make sure jquery.validate.unobtrusive.js is NOT included. This is because jquery.validate.unobtrusive.js automatically parses and produces a validator for the document and the very first thing that validate does is check if there's an existing validator and exits if there is.
If you do decide to go the non-unobtrusive route, be sure not to use the $.validator.unobtrusive.adapters.add since it will cause an error without jquery.validate.unobtrusive.js.
I would recommend going with unobtrusive validation though since I think you're using MVC3.
If you're going to go with unobtrusive validation you have two choices, set the data-* attributes yourself by adding data-val="true" data-val-nohtml="Html not allowed" to your textarea as suggested by JohnnyO and including a span with data-valmsg-for="note" data-valmsg-replace="true" to show the error message. Or you can make your own DataAnnotation attribute.
Here's the code for the addMethod (needed for both kinds of validation)
<script type="text/javascript">
(function ($) {
$.validator.addMethod('nohtml', function (value, element) {
// Test 'value' for html here. 'value' is the value of the control being validated.
return true; // Return true or false depending on if it passes or fails validation, respectively.
}, 'Html not allowed');
} (jQuery));
</script>
and the javascript needed for the unobtrusive is as follows
$.validator.unobtrusive.adapters.addBool('nohtml');
Regarding how to make a custom validation attribute, since I'm not sure what language you're using, assuming you're using MVC3, or if you even need this info anymore 4 months after you asked, I'm going to simply leave these links for reference.
A brief comparision of Traditional vs Unobtrusive JavaScript Validation in MVC 3 - Mitchell Trent's Blog
ASP.NET MVC 3 Custom Validation - Microsoft Developer Network

Although I haven't tested this, I think all you're missing is to wire up the element that you want to validate with the nohtml rule. Something like this:
$('textarea.note').rules('add', {
nothml: true
});
Based on some of your description, I assume you're using ASP.NET MVC3. In that case, you would only need to use the unobtrusive adapter if you're generating the validation attributes server side on your html element (e.g. <textarea data-val="true" data-val-nohtml="Html not allowed"></textarea>). In such a case, you'll need the unobtrusive adapter to wire up the element to use your nohtml rule.

Related

Enable/Disable aspx Validator via js not holding true in code behind?

I'd like to know what I'm missing regarding disabling these via js only, and not having to add repeat code in the code behind.
I'm using this code to disable / enable Validators:
validator: {
enable: function (id) {
console.log('enable',id);
var validator = document.getElementById(id);
ValidatorEnable(validator, true);
},
disable: function (id) {
console.log('disable',id);
var validator = document.getElementById(id);
ValidatorEnable(validator, false);
}
},
It works great, until i make a postback to save some data, ... where these disabled validators are not disabled.
So i have to run some repeated code within the OnLoad() if IsPostBack is true to disable the validators I've disabled via js already.
Edit: Removed any code as it wasn't required to achieve an answer. Answer: Server side must also disable the elements, can't be done explicitly for these reasons: found here, thanks to #ConnersFan: https://msdn.microsoft.com/en-us/library/aa479045.aspx
Some validation controls may not support client scripting. A good example: if you are using a CustomValidator with a server validation function but no client validation function.
Security considerations. Someone can very easily take a page with script and disable or change it. You should not rely on script to stop bad data getting into to your system, only to provide more immediate feedback to your users. For this reason, if you are using a CustomValidator, you should not provide a client validation function without a corresponding server validation function.
As you can see in ASP.NET Validation in Depth, the prefered method to enable/disable a validator on the client side is to use ValidatorEnable:
var validator = document.getElementById(id);
ValidatorEnable(validator, false);
On the server side, you must also enable/disable the validator explicitely (I don't think you can avoid that):
validator.Enabled = false;
This change will be preserved in client code, unlike the change in Javascript code which is not preserved on postback.

How to find the URL of an external site's Javascript submit

I will do my best to try to explain this.
I am scraping a website for it's elements to then output in a different format. The problem that I am experiencing is the way that this site directs the user throughout the site is through a Javascript redirect.
When checking the 'a href' tag, this is the Javascript that shows up
javascript:doParamSubmit(2100, document.forms['studentFilteredListForm'], 'SSC000001MU9lI')
The SSC000001MU9lI changes for each element that it redirects to.
Is it possible to find a URL using this Javascript, so that I can reach the HTML page externally?
EDIT: Here is the doParamSubmit and doSubmit classes:
function doParamSubmit(event, form, parameter) {
form.userParam.value = parameter;
doSubmit(event, form);
}
function doSubmit(event, form)
{
// Make sure if something fails that the form can be resubmitted
try
{
// If this form has not been submitted yet... (except for IE)
if (allowSubmit == true && form != null && (submitted == false || isInternetExplorer6() || isInternetExplorer7()))
{
submitted = true;
form.userEvent.value = event;
// Fix for IE bug in which userEvent becomes a property array.
if (form.userEvent.length)
{
form.userEvent[0].value = event;
}
// Disable the form so the user can't accidentally resubmit the page
// (NOTE: this doesn't disable links (e.g. <a href="javascript:...">)
disableForm(form);
// If there is a populate form function, call it. If there are spell check fields on the
// page, populateForm is used to set hidden field values.
if (this.populateForm)
{
populateForm();
}
saveScrollCoordinates();
// resetSessionTimeout();
try
{
form.submit();
}
catch(e)
{
// Exceptions thrown here are only caused by canceling the submit in onbeforeunload, so ignore.
submitted = false;
}
}
if (allowSubmit == false)
{
alert(grabResource("message.pageLoading"));
}
}
catch(e)
{
submitted = false;
throw e;
}
}
I see 2 approaches.
You use a javascript enabled browser such as http://nrabinowitz.github.io/pjscrape/. I am not sure if you intend to just follow the links or instead grab the URL for some other use so your mileage may vary.
Find the doParamSumit() function in their page/scripts and analyze it to understand how it gets the URL - the one you have as an example looks like it grabs the action from a form perhaps? Once you know how the function work you might be able to harness that info in your scraping by using some regex to find URLs that match the doParamSubmit pattern and going from there. It's hard to say without seeing the function itself as well as the other links like it though.
Regardless of which method you choose I would begin by understanding the function - look for it in the code or loaded js files (you can also you things like javascript debuggers on most browsers to help you find it) and see what happens - it might be super obvious.
Also keep in mind that this might be a POST for a form - in which case the result of you following that link may not work if it expects valid form data.
Edit I see that you posted the function. It simply submits the form listed in the second parameter i.e. 'studentFilteredListForm'. While I don't think your scraping will go to far chasing forms you can still get the URL either with javascript if your scraper lets you (something like $('form[name=studentFilteredListForm]').attr('action') or using whatever language your are using for the scraper i.e. find the form and extract the action url (remembering that if there is no action it is probably posting back to the current URL)
But again... you might first manually get the URL of the form and see where that gets you. You might just get a page with form errors :)

Jquery validation before form submits to php

I have tried and tried with this and don't seem to be getting anywhere, so thought I would put it out there. I have a form full of data provided by the user that I have thus far been able to validate with js/jQuery without problem before sending it to php for further processing. I am achieving this like so:
form.submit(function(){
if(validateUserName() & validateEmail1() & validateEmail2() & validatePass1() & validatePass2() & acceptTerms()){
return true;
} else {
return false;
}
});
The form itself uses the following attributes:
<form id="signup" action="registration.php" method="post">
The problem function is acceptTerms(), which simply has to check that a checkbox is selected does not seem to work as it should (or as the rest of the validation functions do).
var termscons = $('input:checkbox[name=termscons]');
termscons.change(acceptTerms);
function acceptTerms(){
if($(termscons).is(':checked')) {
termsconsInfo.text("");
return true;
} else {
termsconsInfo.text("In order to join, you must accept these terms and conditions.");
return false;
}
}
I have integrated the termscons.change listener and termsconsInfo.text(""); to ensure that my selectors are pointing at the right thing, and that the function is being fired correctly (which it appears to, by changing the termsconsInfo.text when its state changes). When I try to submit the form however it appears to return false, since it does not submit. It should in fact be returning true, and posting my form over to my php script.
Am I going about this the right way? Is there something I have been missing when dealing with a checkbox as opposed to a textinput?
Please excuse my ignorance, this is all still very new to me.
First problem is that you are using & in your if statement. It needs to be &&.
Second problem is with acceptTerms (as you guessed):
var termscons = $('input:checkbox[name=termscons]');
termscons.change(acceptTerms);
function acceptTerms(){
if(termscons.is(':checked')) { // <-- termscons is already a jQuery object
termsconsInfo.text("");
return true;
} else {
termsconsInfo.text("In order to join, you must accept these terms and conditions.");
return false;
}
}
There might be more, but that is what I see for now.
i say forget reinventing the wheel and use something already tested for instance jQuery validate

jQuery Validate Plugin - Trigger validation of single field

I've got a form that can optionally be pre-populated via facebook connect. Once a user connects, their name and email are automatically filled in. The problem is that this doesn't trigger the remote validation to check if the email already exists.
Is there a way I could call the validation on that field alone? Something like:
$('#email-field-only').validate()
would be idea. Searched through the docs with no luck.
This method seems to do what you want:
$('#email-field-only').valid();
Edit
API has changed, see Paul's answer.
Use Validator.element():
Validates a single element, returns true if it is valid, false
otherwise.
Here is the example shown in the API:
var validator = $( "#myform" ).validate();
validator.element( "#myselect" );
.valid() validates the entire form, as others have pointed out. The API says:
Checks whether the selected form is valid or whether all selected
elements are valid.
$("#FormId").validate().element('#FieldId');
For some reason, some of the other methods don't work until the field has been focused/blured/changed, or a submit has been attempted... this works for me.
$("#formid").data('validator').element('#element').valid();
Had to dig through the jquery.validate script to find it...
If you want to validate individual form field, but don't want for UI to be triggered and display any validation errors, you may consider to use Validator.check() method which returns if given field passes validation or not.
Here is example
var validator = $("#form").data('validator');
if(validator.check('#element')){
/*field is valid*/
}else{
/*field is not valid (but no errors will be displayed)*/
}
When you set up your validation, you should be saving the validator object. you can use this to validate individual fields.
<script type="text/javascript">
var _validator;
$(function () {
_validator = $("#form").validate();
});
function doSomething() {
_validator.element($('#someElement'));
}
</script>
-- cross posted with this similar question
in case u wanna do the validation for "some elements" (not all element) on your form.You can use this method:
$('input[name="element-one"], input[name="element-two"], input[name="element-three"]').valid();
Hope it help everybody :)
EDITED
$("#element").validate().valid()

using reCAPTCHA with ajax....javascript loading problem

I trying to implement reCAPTCHA in one of my forms,...but i am using ajax as the submission. (More specifically the prototype ajax.updater)
Once I submit and error check my form I try to load the reCAPCHTA widget thingy (in my updated div element) which basically just calls a javascript file like so:
<script type="text/javascript" src="http://api.recaptcha.net/challenge?k=6Le6SwUAAAAAAIWm8wCRFd8SrI-H0R1Yx4Tkw2Ks"></script>
However the JS file is not being read?...and i've tried all combination of evalScripts:true and evalJS:'force' etc. in the ajax.updater.....however i don't think I have a very good understanding of why the js file isn't processing :(
If anyone can shed some light on this issue I will be very appreciative.
Thanks, Andrew
This doesn't address your exact problem, but 'Dark Side of the Carton' has some excellent code for validating reCAPTCHA via jQuery AJAX which might help.
In summary:
Add the following Javascript:
$(function() {
function validateCaptcha() {
var challengeField = $('input#recaptcha_challenge_field').val(),
responseField = $('input#recaptcha_response_field').val();
// alert(challengeField);
// alert(responseField);
// return false;
var html = $.ajax({
type: 'POST',
url: 'ajax.recaptcha.php',
data: "recaptcha_challenge_field=" + challengeField + "&recaptcha_response_field=" + responseField,
async: false
}).responseText;
if (html.replace(/^\s+|\s+$/, '') == "success") {
$('#captchaStatus').html(' ');
// Uncomment the following line in your application
return true;
} else {
$('#captchaStatus').html(
'Your captcha is incorrect. Please try again'
);
Recaptcha.reload();
return false;
}
}
// Modified as per comments in site to handle event unobtrusively
$('#signup').submit(function() {
return validateCaptcha();
});
});
Then add the ajax.recaptcha.php file which: "outputs only the word “success” if the captcha matches and a message and the response from reCaptchta if it fails. This is important because we are looking for the word success in our validateCaptcha() function."
require_once('/inc/recaptchalib.php');
$publickey = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXX'; // you got this from the signup page
$privatekey = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXX';
$resp = recaptcha_check_answer(
$privatekey,
$_SERVER['REMOTE_ADDR'],
$_POST['recaptcha_challenge_field'],
$_POST['recaptcha_response_field']
);
if ($resp->is_valid) {
?>success< ?
} else {
die(
"The reCAPTCHA wasn't entered correctly. Go back and try it again." .
"(reCAPTCHA said: " . $resp->error . ")"
);
}
The example is in PHP, but I adapted it easily to work with Zope/Python
Be careful using any sort of client-side script, such as JavaScript, for validation. You have no control over the end-user's browser. The purpose of a CAPTCHA is to prevent automated submissions of a form. Anyone sophisticated enough to set that up isn't going to have a problem overriding your JavaScript validation and CAPTCHA checking. For example, they could set validateCaptcha() to always return true, bypassing your careful checks - or just disable JavaScript.
That being said, there's nothing wrong with performing the entire form submission with ajax and using the results of the CAPTCHA check to determine if the form gets processed or not.
The important point is that the decision of whether or not to handle the form has to be made on the server-side, not the client-side.
Why client-side validation is not enough
to answer my own question...
there is a reCAPTCHA AJAX api....which is pretty easy way to get around this problem:
link text
Also,..the documentation on the http://www.prototypejs.org/api/ajax/updater site.....talks about the evalscript option and how is only puts any javascript through the native eval() function....which kind of screws me over trying to implement error checking with WMD...but that's another story.
Andrew
If that's the literal code snippet you're using, you haven't closed the tag... so it wouldn't be evaluated.
call Recaptcha.reload(); on callback event in your Ajax code., it will reload new Recapcha every time that Ajax submitted
Hi Friend i found the answer
https://developers.google.com/recaptcha/docs/display?hl=es#AJAX
And in this how validate
http://blog.reaccionestudio.com/comprobar-recaptcha-con-ajax-usando-jquery/
Success for you
Securing AJAX calls with reCaptcha
function performAJAX() {
let captcha = $('[name=g-recaptcha-response]');
$.ajax({
url: 'ajaxHandler.html',
data: {
captcha: (captcha.length?captcha[0].value:''),
// other data fields
},
});
}
I have had similar issues with getting reCaptcha to play nicely when loaded into the page using jQuery's .load() method. Here is a page that has a novel solution: http://www.maweki.de/wp/2011/08/recaptcha-inside-a-with-jquery-ajax-or-load-dynamically-loaded-object/
Basically the reCaptcha API uses document.write method to display the reCaptcha. When you get jQuery invloved this won't work. Use this PHP code in place of loading recaptcha.js
<?php
$api = file_get_contents('http://www.google.com/recaptcha/api/js/recaptcha_ajax.js');
$api = str_replace('document.write','$("body").append',$api);
echo $api;
?>
It just does a find for document.write and replaces it with $(selector).append.
Made my implementation work.

Categories

Resources