drupal javascript API & form set error - javascript

1.is there a way to do form_set_error in client side so if there is error in javascript validate it will set error and wont let user process the other steps? js can be disabled so i want to take extra caution...
where is a complete list of drupal javascript function reference like Drupal.t and stuff?
how can i change the error messages of form set error (the default errors like { fieldname... field is required } ?
how can i do errors that will show below/above/inline the field ?

JavaScript in Drupal, Covers the Drupal JavaScript API, AHAH forms, and the kind of stuff your looking for. The Quick start Guide is pretty good.
As for validation, you're right, Javascript can be turned off. JavaScript validation is mostly done for usability, since the user doesn't have to wait to POST his form in order to receive an error message. JavaScript lets him know in real time if for example, his password is too weak, or email invalid, before submitting the form.
JavaScript validation however is not good for security. That's where you will need to do server-side validation. form_set_error will take care of the server-side validation.
So if you have a form that looks like:
function form_foo($form_state) {
$form['foo'] = array(
'#type' => 'textfield',
'#title' => t('bar'),
'#default_value' => $object['foo'],
'#size' => 60,
'#maxlength' => 64,
'#description' => t('baz'),
);
return $form;
}
The server-side validation would look like:
function form_foo_validate($form, &$form_state) {
if (empty($form_state['values']['foo'])) {
form_set_error('foo', t('Foo cannot be empty.'));
}
}
If the bar textfield in the form is indeed empty, when the user submits the form bar will be highlighted, the 'Foo cannot be empty' error message will appear, and the form _submit hook won't be called.
For JavaScript functionality, the Overview of Drupal JavaScript API document has most of the information you will need.

Related

POST request using Mechanize to pull GUID from .aspx website

there is a website called https://www.guidgenerator.com/online-guid-generator.aspx which generates a global unique identifier. I'm trying to use perl's Mechanize to post to the site to pull that guid. I realize that this is based on javascript but was wondering if I could issue the proper post to pull the number. I trace it from my browser and I've got the headers all in the request but the returned html doesn't contain the guid.
This is from a successful run:
<textarea name="txtResults" rows="2" cols="20" id="txtResults" style="font-family:Courier New,Courier,monospace;font-size:Larger;font-weight:bold;height:152px;width:421px;">qk5DF22bhkm4C2AwZ5OcZw==</textarea>
and this is from my script:
<textarea name="txtResults" rows="2" cols="20" id="txtResults" style="font-family:Courier New,Courier,monospace;font-size:Larger;font-weight:bold;height:152px;width:421px;"></textarea>
This is the form within the page:
In my script I dump out the form and the input fields required with the following:
my #forms = $mech->forms;
foreach my $form (#forms) {
my #inputfields = $form->param;
print Dumper \#inputfields;
}
resulting in
$VAR1 = [
'__EVENTTARGET',
'__EVENTARGUMENT',
'__LASTFOCUS',
'__VIEWSTATE',
'__VIEWSTATEGENERATOR',
'__EVENTVALIDATION',
'txtCount',
'chkUppercase',
'chkBrackets',
'chkHypens',
'chkBase64',
'chkRFC7515',
'chkURL',
'LocalTimestampValue',
'btnGenerate',
'txtResults'
];
and this is the post
my $mainpage = "https://www.guidgenerator.com/online-guid-generator.aspx";
$mech->post( "$mainpage",
fields => {
'txtCount' => "1",
'chkBase64' => "on",
'LocalTimestampValue' => "Date%28%29.getTime%28%29",
'btnGenerate' => "Generate+some+GUIDs%21",
'txtResults' => "",
'__EVENTTARGET' => 'on',
'__EVENTARGUMENT', => 'on',
'__LASTFOCUS', => 'on',
'__VIEWSTATEGENERATOR' => "247C709F",
'__VIEWSTATE' => 'on',
'__EVENTVALIDATION' => 'on',
'chkUppercase' => 'off',
'chkBrackets' => 'off',
'chkHypens' => 'off',
'chkRFC7515' => 'off',
'chkURL' => 'off',
},
);
When I do the trace on the website I get the headers but there is another tab called Payload. That contains most of the fields listed above. I try to input these fields into the POST but not sure if I should be doing this differently or it doesn't matter because its javascript?
I know this is a lot of information. I'm not even sure that perl's mechanize can pull this information. Any help would be appreciated. Please let me know any other data you want me to post here.
You can use Mech's built-in stuff to do this. There is no need to submit any extra fields or headers.
use strict;
use warnings;
use feature 'say';
use WWW::Mechanize;
my $mech = WWW::Mechanize->new;
$mech->get('https://www.guidgenerator.com/online-guid-generator.aspx');
$mech->field( txtCount => 10 );
$mech->click;
say $mech->value('txtResults');
This will output something like:
$ perl mech.pl
211b3cad1665483ca303360bdbda0c61
ecc3348d83cb4bb5bdcb11c6148c5ae1
0a3f2fe5748946a1888a4a5bde8ef2e6
acb26deb9fda4411aa64638cdd1ec5f1
2afe609c355b4a10b6a0ae8c74d3aef1
30fd89ab170147cfb24f131346a203e3
2301d258e1d045aa8f0682f2ea14464c
f064507ca3e14a4eb860b0a30ba096ed
9a42b15d5c79420c921dcc07c306459b
5bea2e345f75453caaf795681963866a
The crux here was that you cannot use $mech->submit as that wouldn't submit the value of the submit button. That's a bit annoying. So instead, you have to use $mech->click, which pretends the default form's default submit button was clicked, hence submitting that value as well. That's just how buttons work on forms, and in this case the backend checks the value to see which one was clicked.
You can then use $mech->value to get the field value out. You'd probably want to split it to process it further.
The JavaScript in this page is actually completely irrelevant to the functionality. All it does is save and restore the settings you've chosen in a cookie, so that when you come back the same checkboxes will be ticked. That's nice, but nowadays probably better done with local storage on the frontend side. However you don't have to deal with the JS at all to crawl this page. The main functionality is backend side.
You might also be interested in $mech->dump_forms, which is a nice debugging aid that prints out all the forms with fields and values. Another good debugging aid when working with Mech (or any LWP based class) is LWP::ConsoleLogger::Everywhere. That's what I used to compare my program's request with my browser's one to find the missing button form field.
Disclaimer: I am a maintainer of WWW::Mechanize and I wrote LWP::ConsoleLogger::Everywhere.

Showing serverside validation errors in extjs

For the form fields, we can use validator and validation functions to validate and show the errors in extjs. How can I show the similar errors for the server side validation? i.e. Validation happens in backend and errors should be displayed if a certain condition is satisfied.
I have tried using markInvalid("message"), but this only highlights the field and doesn't show the message and also the highlighting goes away when user clicks out of the field.
Any suggestions are appreciated. Thanks.
markInvalid in fact is the official way to go. By default, the message is shown in the tooltip, you can change that through msgTarget: 'under'.
If you want to preserve the error message, then you have to ask yourself, until when. For example, when I change the value in the field, it should no longer show the error message.
To keep the server's message until the value is changed, you have to add to the field a custom validator:
validator: function(val) {
if(this.invalidValue && val==this.invalidValue) return this.invalidMsg;
return true;
}
and then, when the msg comes back from the server, call:
field.invalidValue = field.getValue();
field.invalidMsg = msg;
field.validate();

JS/JQuery/PHP - How to echo errors on form validate failure, and jump to div on success?

I have a fixed-position form that can be scrolled out onto the document and filled out anywhere on the page. If they fail to fill out the form properly, the errors are currently echod out onto the form, which is the intended design for that aspect. What I don't currently know how to do is, if the form is completed and $errors[] is empty, to use jQuery scrollTop() to jump down to the bottom.
Could anyone help me out with this? Current javascript involved is:
$("#A_FORM_submit_button").click(function() {
$("#FORM_A").submit( function () {
$.post(
'ajax/FORM_A_processing.php',
$(this).serialize(),
function(data){
$("#A_errors_").html(data);
}
);
return false;
});
});
The PHP involved is simply
if (!empty($errors)){
// echo errors
} else { // echo success message} <-- would like to jump to div as well
edit-- for clarity: not looking to make the page jump happen in the php file, so much as return a value for the jq $.post function to check and then perform an if/else
I might be jumping the gun here but I believe your design is wrong which is why you are running into this problem.
The ideal way of handling form validation is to validate forms via Javascript and when users enter in their information you immediately show some indicator to ask them to correct it. As long as the validation is incorrect, you should not be accepting a form request or making any AJAX calls.
In the off-chance that they do successfully send the data, you should be doing a validation check via PHP as well which, if failed, would redirect to the original page with the form. From there you could do whatever error handling you want but ideally you would retain the information they entered and indicate why it was wrong (Javascript should catch this but I guess if it gets here the user might have JS off or your validation logic might be wrong)
If I understand correctly, it seems like you are doing your error handling with Javascript (that's fine) but showing the error via PHP. As Hydra IO said don't confuse client-side and server side. Make them handle what they need to handle.
Hope this helps.
#aug described the scenario very clearly.
In code it translates in something like this
$('form').submit(function(){
form_data = $(this).serialize();
if(!validate(form_data))
{
// deal with validation, show error messages
return false;
}
else
{
// Submit form, either via Ajax $.post() or by just returning TRUE
}
});
The validate() function is up to you to work out.

How to init invalid email and show in input(type="email")?

I have a signup form built with AngularJS using frontend and backend (with Express.js) input verification. Whenever a user enters an invalid email address, like qwidjq&/%, I'd like to show an error message and send the form back to the user. The email input field should contain the invalid email as the value.
The problem is that I cannot init input(type="email") fields with invalid email values. Only input(type="text") works. Here is an example.
Any ideas how to work around this restriction? I don't want to use input(type="text") and a custom directive. I'd like to keep input(type="email") as it changes keyboard layout on mobile devices.
Thanks in advance!
Perhaps display the bad text NEXT to the input element, e.g.
<input type="email" /><span id="emailerror">qidjq&/% is not a valid address</span>
You can initialise your input by initialising your model with data.
Example: http://plnkr.co/edit/TUJ6lv?p=preview
Unfortunately initializing a model to display invalid data would require patching AngularJS. In fact if you initialize any validated field with invalid data, it will appear blank.
Here is the code that is causing the email input to display blank without a valid email:
https://github.com/angular/angular.js/blob/master/src/ng/directive/input.js
(line 622)
var emailValidator = function(value) {
if (ctrl.$isEmpty(value) || EMAIL_REGEXP.test(value)) {
ctrl.$setValidity('email', true);
return value;
} else {
ctrl.$setValidity('email', false);
return undefined;
}
};
Forgive me if I'm being stupid but can't you just disable the button on your form while the inputs are invalid. Alternatively, don't leave the form until you have had a positive response to your ajax request. If you get a negative response then show an error message. The data will still be in the form. I'm not familiar with Express.js so perhaps that is forcing you to refresh the form. I thought the whole point of using frameworks like Angular is to give you total control of the UI.

jQuery already submitted vs. being submitted

I'm working on a jQuery function that forwards form data to page without interfering with the normal submission. I can do it without any issues as long as I capture the submit using .submit(), but I would have to run my own validation on the data because it operates independently of the regular submission. Is there a way for jQuery (or any Javascript) to detect that form data has been posted and validated?
cheers,
Mike
Edit:
Workflow looks like this:
1. User enters data
2. Clicks submit
3. Site runs validation and accepts input
4. Submits data to new page
5. jQuery function detects new data was submitted and accepted so it runs.
More Edits for Clarity
I think you guys are missing the issue. I know how to detect a form is being submited (which is fine and dandy)
This is NOT what I want:
$(this).each(function(){
$(this).submit(function(){
*** Code ***
}
}
Suppose I have a validation script running independent of the code I am currently writing. How can I detect that this ran, and then go to the submit code above?
Use onsubmit="" on your <form> element, but return false. i.e.:
<form action="?" method="post" onsubmit="validate_and_submit(this);return false;">
The return false prevents the form from actually submitting so you can do stuff with AJAX.
Hope this helps!
What you need is AJAX here . So make a XHR request that goes to your server and posts data . The server's response would now go to a callback function ( your jquery function ) . If the data was validated and fine , you proceed further , else you stop .
What you are trying to do is not possible via the normal HTTP POST request .
EDIT: for the original clarification
If you want the server to only received validated data, then just make sure its not submitted to prior to the client-side validation occuring. You can do this with selectively calling event.preventDefault() based on the result of the validation.
$("#form").submit(function(event) {
//some stuff
if (validate(formdata) == false) {
event.preventDefault();
}
});
If you want a server to do the validation and submit to itself or another service, you should make that part of the server-side workflow. So it'd be like
1.) client submits to Service1
2.) Service1 validates
3.) Services1 submits to Service2 (such that service2 never receives code from elsewhere)

Categories