Parsley Custom Validator with JS Promise - javascript

I have reached out in several place and the help has been good but hasn't managed to make it work for me.
Hopefully you guys can help me here.
I am using JS inside a template page of a Flask application. I am using parsley validation to verify a web form. I have also created a custom validator which should ajax call with axios to the back end to determine if an email address is already registered.
My Flask Backend returns a boolean string to my html page. All of this looks right. I am getting back the right value. However when I return out of my ".then" function in my axios function the Parsley validator doesn't work/respond.
If i remove the axios POST call. and just simply say "return false" or "return true" the function works. The validation message is returned to the screen.
So there appears to be an issue with putting the return statment inside my .axios .then function?
Could some one see if I am doing anything wrong here? I cannot for the life of me work out why it doesn't work.
Thanks.
Tim.
I have included the FAILING JS Code here.
<script type="text/javascript">
window.Parsley.addValidator('existingEmail', {
validateString: function(value) {
// Performing a POST request
var promise = axios.post('/api/v1.0/existingEmailCheck', {email : value})
.then(function(response){
var result = (response.data.toLowerCase() === "true");
console.log(result)
return result
});
console.log(promise)
return promise
},
messages: {
en: "This email address has already been registered.",
}
});
</script>
I have also included a slightly modified (without axios call) code that works here.
<script type="text/javascript">
window.Parsley.addValidator('existingEmail', {
validateString: function(value) {
var string = "false" //This Simulates the Incoming Data.
var result = (string.toLowerCase() === "true");
console.log(result)
return result //Always returns false (due to hard coding)
//However this means that it triggers the error message and validation fails
//When you change the string to "true" it works as expected and validates
},
messages: {
en: "This email address has already been registered.",
}
});
</script>
The example works as expected. Which leads me to believe the error in the first code example is somewhere between the call and the IF ELSE that returns the False or True
Any help people can give me would be awesome!

I think you need to return a jQuery promise instead of whatever axios returns (native promise?).
FWIW, it looks like you could use the builtin remote validator.

Just attempted to use Axios myself (Wanted to do away with jQuery and it's huge library). Ended up creating a AsyncValidator (uses Ajax behind the scenes).
In your HTML just import jQuery and Parsley
<script src="/js/jquery-3.3.1.min.js"></script>
<script src="/js/parsley.min.js"></script>
Define your DOM element to support remote validators
<input id="id" class="form-control" name="id" type="text" data-parsley-remote data-parsley-remote-validator='checkExists' placeholder="Username / ID" data-parsley-checkExists="" data-parsley-minlength="5" data-parsley-required-message="Please enter username / id" required>
In your index.js file, add you Async validator.
Parsley.addAsyncValidator('checkExists', function (xhr) {
return false === xhr.responseJSON;
}, '/data-management/verify-data?filter=signup');
The resulting Ajax request being made is /data-management/verify-data?filter=signup&id=value value being the value of the input field.
That ended up working for me. Let me know if you need help.

Related

JS variable is displayed as undefined when using HTML

I am working on a project on Google Apps Script. I have a JS function that returns a date (as a text). I also have an HTML document to display a form with several inputs. I would like to prefill one input with the date returned by the JS funtion. It almost works, except it displays "undefined" instead of the date, even though I know the js funtion is working fine.
Here are some code to better understand :
The input where I call the script (don't mind the onmousemove, i just didn"t find anotherway to call the script).
<input type="text" id="deliveryDate" name="deliveryDate" onmousemove="displayActiveDate()">
So it calls the folowing script.
<script>
function displayActiveDate(){
var activeDate = google.script.run.getActiveDate();
document.getElementById("deliveryDate").value = activeDate;
}
</script>
Which in turn calls getActiveDate() which is the separate JS function that returns the date.
If you have any idea on how to solve this, I will be very thankful.
google.script.run.serverSideFunction() returns undefined. In order to get the actual response value from your serverSideFunction() you need to use the withSuccessHandler() method with a callback like so:
google.script.run.withSuccessHandler(onSuccess).serverSideFunction();
function onSuccess(data) {
// do something with the data returned by the serverSideFunction()
}
Also note that you also have withFailureHandler(err) to handle any errors you server-side functions may return.
Here is the full reference
Instead of writing document.getElementById("deliveryDate").value = activeDate; type document.getElementById("deliveryDate").innerHTML= activeDate; in your script

JQuery validate custom error message is not showing up

Following is the form validation javascript in my application:
$('#EmploymentHistoryForm').validate({
ignore: ':hidden, [readonly=readonly]',
rules: {
'MemberJob.Phone': {
PhoneFieldValidation: true
}
},
messages: {
'MemberJob.Phone': {
PhoneFieldValidation: $.viewUrl.url.invaliedPhoneMessage
}
},
showErrors: function (errorMap, errorList) {
ShowErrors(errorMap, errorList, this.validElements());
},
submitHandler: function (form, event) {
event.preventDefault();
return false;
}
});
Here, $.viewUrl.url.invaliedPhoneMessage is set at the cshtml page (in ASP.NET MVC), and while debugging the javascript I can see proper value in that variable when $('...').validate function gets hit.
I have registered a new validator "PhoneFieldValidation" in JQuery validators collection:
$.validator.addMethod("PhoneFieldValidation", ValidatePhoneAndAltPhone);
Following is the rendered HTML for the input control for which I have added this validation rule:
<input class="PhoneFieldValidation" id="MemberJob_Phone" name="MemberJob.Phone" type="text" required="required" aria-required="true">
I can see the validation getting fired correctly. That means, "ValidatePhoneAndAltPhone" method is getting called, and returning a boolean result based on the input.
However, the error message is not getting displayed properly. It displays "Warning: No message defined for MemberJob.Phone" instead of "Invalid Phone Number".
While debugging through customMessage function of jquery.validate.js, I could see "this.settings.messages" collection is not having the message for "MemberJob.Phone" field, and that looks to be the root cause of this issue.
Any idea of how to resolve this issue?
I know we can add "data-msg-[rulename]" attribute in the HTML tag which will fix the issue. But I am sure the current approach I am following is also correct. Seems I am missing something.
Any help on this will be much appreciated.
Thanks
You never mentioned where $.viewUrl.url.invaliedPhoneMessage comes from.
If there is already a message defined in your custom PhoneFieldValidation method, then you would not define a message within the messages object.
Otherwise, you cannot use a JavaScript variable within the messages object without a function.
The whole problem is being caused by the Unobtrusive plugin which is automatically constructing the .validate() method call. You cannot call .validate() more than once on the same form; and all subsequent calls are ignored. Instead, you can simply define the custom message for PhoneFieldValidation within its .addMethod() method.
$.validator.addMethod("PhoneFieldValidation", function(value, element) {
// your custom method function here;
}, "This is your custom validation error message");

How to use HTML form.checkValidity()?

Reading a website's source code that uses MVC, I struggled trying to understand some of it.
Code snippet of the view:
function submitForm (action) {
var forms = document.getElementById('form')
forms.action = action
if (forms.checkValidity()) {
forms.submit()
} else {
alert('There is still an empty field')
}
}
I want to execute some code if the form is missing certain inputs.
checkValidity() is a HTML5 method and
When the checkValidity() method is invoked, if the element is a candidate for constraint validation and does not satisfy its constraints, the user agent must fire a simple event named invalid that is cancelable (but in this case has no default action) at the element and return false. Otherwise, it must only return true without doing anything else.
Please learn more about how to use form validation constraints here.
There are number of useful methods you can use, customize and even build custom validation methods.
You also can find basic explanation and examples in w3schools.
Hope this helps.
For Me this works in jQuery
$('#formSection')[0].checkValidity();
just use a required
Example
<input type"text" id="id" required>
if you press the submit button there an alert text saying PLEASE FILL OUT THIS FIELD

jQuery injecting data in ajax global event

I'm trying to inject data in my ajax requests, but it fails and I don't know why. I tried to look at the jQuery source code, but still can't find why it doesn't work, Any help appreciated. Here is the code :
$('#someElement').ajaxSend(function(e, req, options) {
options.data += (options.data.length > 0 ? '&' : '') + '__token=' + $('input#requestToken').val();
}).ajaxSuccess(function(e, req, options, data) {
if (data.nextToken) {
$('input#requestToken').val(data.nextToken);
delete data.nextToken;
}
});
The response looks like this :
{
"response":
{
"code":0,
// ...
},
"nextToken":"4ded26352b3d44"
}
A typical request would be, for example :
$.getJSON(url, {something:'value'}, function(data) {
if (data.response.code != 0) {
// handle code
}
});
The problem is that, the data sent is "something=value"; the modified data is not sent.
** EDIT **
The current request data is
something: value
and should be
something: value
__token: 4ded288eec1f56
In the ajaxSend event callback, if I print the value of options.data after modifying it, the value is "something=value&__token=4ded288eec1f56", but "__token=4ded288eec1f56" is not sent. Why isn't it sent in the request?
But more specifically, how to "fix" this, if even possible?
I think the problem is that by the time jQuery decides to call the "ajaxSend" callback, the parameters have already been used to prepare the request. Thus, changing them in that handler has no effect.
edit — given the answer from #mikermcneil I'm not sure this is right. The jQuery "ajax" method is, to say the least, complicated. His sample page certainly seems to work, which confuses me but probably should just help me realize how little I know about jQuery internals :-)
-edit
Update-- the trouble is with getJSON.
It looks like, while jQuery does fire the ajaxSend event in both cases, it doesn't actually use the changed data variable with getJSON like it does with post.
Replace getJSON with $.post to solve your problem (that's what I'm doing in the example I linked to below).
-edit-
Well, I set up a version of it here:
http://abolition.me/toys/View/attachAjax.html
(see the console)
I'm having the server send back whatever it got and it's saying:
__token: "toketoketoke"
key: "val1"
key2: "val2"
So it looks like modifying the request data is working-- what does your handler look like server-side?
I'm looking into it-- first and foremost though (and I mistake I made as I tried to replicate the problem), have you checked that you're assigning your event after the document is ready? ($(function(){ });)
I am not sure that your JSON response is correct:
{
"response":
{
"code":0, <-- this is not valid
},
"nextToken":"4ded26352b3d44"
}
valid should be:
{
"response":
{
"code":0
},
"nextToken":"4ded26352b3d44"
}
To validate your JSON response you can use:
The JSON Validator
You are only passing data within the second parameter in your getJSON call {something:'value'}. Any data you want to send to the server must be included there. Thus, the __token must be included in that parameter.
The third parameter in the getJSON call is the call back function. The parameter passed to that function is the response from the server.
$.getJSON(
url,
{
something:'value',
__token: 'token value'
,
function(response) {
if (response.response.code != 0) {
// handle code
}
}
);

JQuery "get" failure (using Google App Engine on the back-end)

What I am trying to do is pretty simple: yet something has clearly gone awry.
On the Front-End:
function eval() {
var x = 'Unchanged X'
$.get("/", { entry: document.getElementById('entry').value },
function(data){
x = data;
}
);
$("#result").html(x);
}
On the Back-End:
class MainHandler(webapp.RequestHandler):
def get(self):
path = os.path.join(os.path.dirname(__file__), 'index.html')
if self.request.get('entry') != '':
#self.response.out.write({'evalresult': self.request.get('entry')})
self.response.out.write(request.get('entry'))
else:
self.response.out.write(template.render(path, {'result': 'Welcome!!'}))
def main():
application = webapp.WSGIApplication([('/', MainHandler)],
debug=True)
wsgiref.handlers.CGIHandler().run(application)
Yet, apparently the function is never being called and #result gets set to 'Unchanged X'. What am I missing?
NOTE: The callback is NOT being called. I have verified this by placing an alert("Test") within the callback function. Any ideas anyone?
$("#result").html(x); goes in the get() callback
If the callback is not running you can try changing the $.get into a $.ajax() call, and adding an error callback, to see if the server is returning an error.
Or better yet, check in the "net" panel in firebug to see what the server response is, which might help you track down what the issue is on the back end.
Also once the issue is fixed, you might want to replace the $.get with a simple $().load which would take the data and place it into the div automatically:
$('#result').load('/', { entry: document.getElementById('entry').value });
EDIT: I suppose the following would be a more jQueryish way of writing it:
$('#result').load('/', { entry: $('#entry').val() });
First we have the silly mistake:
<font size="3" face="Trebuchet MS">Speak Your Mind: </font><input type="text"
size="60" id="entry"/> <img valign="bottom" src='/assets/cognifyup.png'
onMouseOver="over()" onMouseOut="out()" onMouseDown="out(); evaluate();"
onMouseUp="over()"><br><br>
Semicolons are required after the calls to over() and out() (roger that? --- sorry couldn't resist)
Secondly (the much more subtle problem):
If we ever need intend to translate the get() into a getJSON() call, (which you might have noted was my original intent from the commented python code that returns a dict), then we need to wrap a str() call around self.request.get('entry'). Hence,
self.response.out.write({'evalresult': self.request.get('entry')})
becomes:
self.response.out.write({'evalresult': str(self.request.get('entry'))})
As strings from an HTML field translate to unicode text in Python, at the back-end, we apparently need to convert it to a Python string (as getJSON() apparently doesn't like Python's representation of a unicode string -- any ideas why this this is the case anyone?).
At any rate, the original problem has been solved. In conclusion: any JSON object with a Python unicode string will not be accepted as a valid JSON object and will fail silently -- a nasty gotcha that I can see biting anyone using JQuery with Python on the server-side.

Categories