Jump to content
alexpi

Contact form with validation messages on same page

Recommended Posts

Hello all,

I am having trouble with the following:

I have created a template with contact form validation code (./site/templates/contact.php). I am using the action attribute of my form to point to this template, and the validation works, redirecting to this contact template which shows the relevant messages.

Since I am displaying the contact form in a modal kind of thing, I want the validation messages to appear inside this modal without the page refresh and redirection. I am not very familiar with ajax, and I can't achieve showing the contents of contact.php inside this modal.

I am trying to do something like this:

$('#contact_form').submit(function(e) {
$.ajax({
 type: "POST",
 url: "<?php echo $pages->get('/contact/')->url ?>",
 });
e.preventDefault();
})

but this doesn't work.

Any ideas?

Share this post


Link to post
Share on other sites

Your simplest option might be to use an iframe in the modal - that way when the form submits, it is the content in the iframe that will reload, instead of the whole page. Note that not all modal JS scripts support iframe, but lots do.

If you want to go ajax, just google: jquery ajax form submission

Good luck.

Share this post


Link to post
Share on other sites

Something I don't understand: In an ajax url parameter like in the code I sent, is it valid to echo a PW page url that contains the php validation code?

Share this post


Link to post
Share on other sites

What you have done echoing the url like that in the JS is fine, although you are missing the semi-colon at the end. Look at the page source code to confirm that the final jquery snippet looks as you expect.

Share this post


Link to post
Share on other sites

The url in the JS looks correct but does nothing. I tried the same thing with a validation.php file outside PW's folders and it works.

When using:

<form action='<?php echo $process->url ?>' method='post' id="contact_form">

the proccesing happens in the $process page (with a redirect),

but combined with:

$.ajax({
type  : 'POST',
url  : '<?php echo $pages->get("/process/")->url ?>', // the url where we want to POST
data  : formData,
dataType  : 'json'
});

nothing happens.

Share this post


Link to post
Share on other sites

Usually the problem with using a PW page for processing a form is the HTML that is included in that page. You need a way to not have this extra stuff sent when requesting the page. How you do this depends on how you structure your PW pages - are you using head.inc and foot.inc includes, or are you using a main.inc? or are you making using of the before and after includes in config.php?

You can make use of $config->ajax to see if the page was called via ajax, but then again, if it's just a form processing page, then you probably don't ever need to display it normally, so probably not relevant here.

So, call that process page directly and make sure nothing gets rendered.

Also, you mention that there is a redirect - is this coming from the process page to somewhere else? I don't think you want that when processing a form via ajax. You want the result of the processing to come back to the page on success. You can echo something back if you want.

Here's a pretty decent tutorial:

http://code.tutsplus.com/tutorials/submit-a-form-without-page-refresh-using-jquery--net-59

  • Like 1

Share this post


Link to post
Share on other sites
$.ajax({
type  : 'POST',
url  : 'path/to/contact/here '// try to put the relative path to your php page here instead of echoing
data  : formData,
dataType  : 'json'
});

I maybe wrong, but I don't think you can <?php echo $something ?> inside a Javascript object since php needs to be processed on the server rather than on the client side.

Share this post


Link to post
Share on other sites

Yes, the js is on a .php file. If I put a relative link I get a 403 Forbidden error. I can put the form processing .php file outside PW's directories, but it would be nice to use a PW template. In it, I wanted to have the various validation messages as user editable fields (for multilingual use reasons). So, if I understand correctly, it is not possible to have a PW template (that contains only php) to be called by an ajax request.

Also, thank you all for your time, I am a web designer and my php knowledge is limited, so my questions/explanations may not be very clear!

Share this post


Link to post
Share on other sites

You could always place the script outside the PW templates folder and bootstrap it to processwire so you still have access to PW pages and fields for grabbing the validation messages.

http://processwire.com/api/include/

  • Like 3

Share this post


Link to post
Share on other sites

Another thing that popped up..! Is it possible to get the page that a form action originated from, in a file outside PW's directories that has PW boostrapped in?

Share this post


Link to post
Share on other sites

Oh yeah you can. I usually do something like:

// in JS
var pageName = <?php echo $page->id?>;
$.ajax({ 
  async: true,
  cache: 'no',  
  type: 'POST',               //Specify if POST or GET
  url: 'someurl.php', 
  data: {pgName:pageName},    //Data to be sent off to the url above
  .... more JS 

// in 'someurl.php'
$phpPageName = isset($_POST['pgName']?$_POST['pgName']:NULL); //get value of pgName

Share this post


Link to post
Share on other sites

Although bootstrapping PW on a file outside PW's directories and calling it with AJAX worked, I am not able to get multi-language field values from it.

So, I am trying to include the contact validation code in a PW template as suggested here: https://processwire.com/talk/topic/4665-accessing-pagetitlelanguage-when-bootstrapped/

The problem is that I can't find how to do that! The following is the code I am using, which works, but is not fetching the various validation messages.

<?php

	$emailTo = 'an email';
	
	$name = $input->post['name'];
	$email = $input->post['email'];
	$message = $input->post['message'];
	
	$form = array(
		'name' => $sanitizer->name($name),
		'email' => $sanitizer->email($email),
		'message' => $sanitizer->textarea($message)
	);
	
	$email = "Full name: $form[name]\n" . 
	         "Email: $form[email]\n" . 
	         "Message: $form[message]";
	
	$errors = array();
	$data = array();
	
	if (empty($form['name']))
		$errors['name'] = $out = __('Name is required');
	
	if (empty($form['email']))
		$errors['email'] = $out = __('Email is required.');
	
	if (empty($form['message']))
		$errors['message'] = $out = __('Message is required.');
	
	if ( ! empty($errors)) {
	
		$data['success'] = false;
		$data['errors']  = $errors;
	} else {
	
		mail($emailTo, "Thassos homes - Επικοινωνία", $email, "From: $form[email]");
		
		$data['success'] = true;
		$data['success_message'] = $out = __('Your message has been send! We will reply to you soon.');
	}
	
	json_encode($data);

?>

<form action='./' method='post'>
    <div>
        <input type="text" id="name" name="name" placeholder="name"  />
        <input type="email" id="email" name="email" placeholder="email" required />
        <input type="submit" name="submit" value="send" />
    </div>
    <textarea id="message" name="message" placeholder="your message" required ></textarea>
 
    <div class="contact_message"></div>
    <div class="loading hidden"></div>
</form>

<script>window.jQuery || document.write('<script src="<?php echo $root_dir ?>js/jquery-1.11.0.min.js"><\/script>')</script>
<script>
	$(document).ready(function() {
		var contact_message = $('.contact_message');
		contact_form.submit(function(event) {
		
		contact_message.innerHTML = "";
	
		var contactData = {
			'name' 		: $('input[name=name]').val(),
			'email' 	: $('input[name=email]').val(),
			'message' 	: $('textarea[name=message]').val()
		};
	
		$.ajax({
			type 		: 'POST',
			url		    : '<?php echo $page->url ?>',
			data 		: contactData,
			dataType 	: 'json'
		})
			.done(function(data) {
	
				console.log(data); 
	
				if ( ! data.success) {
				
					if (data.errors.name) {
						contact_message.text(data.errors.name);
					}
		
					if (data.errors.email) {
						contact_message.text(data.errors.email);
					}
		
					if (data.errors.message) {
						contact_message.text(data.errors.message);
					}
		
				} else {
					
					$('.contact_form div, .contact_form textarea, .loading').addClass('hidden');
					$(contact_form).append('<div class="success">' + data.success_message + '</div>');
					
					setTimeout(function(){
						contact_form.toggleClass('hidden visible');
					}, 3000);
		
					// window.location = 'index.php'; // redirect a user to another page
		
				}
			})
			
			.fail(function(data) {
	
				// show any errors
				// remove for production
				console.log(data);
			});
	
		event.preventDefault();
	});
})
	
</script>

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...