Hi all,

I am attempting to call and submit the "personal contact form" via AJAX.

Here is what I have so far. Please excuse my poor JS. (Description of issue below code.)

Link:
<a href="#" class="btn btn-primary user-contact-link" data-toggle="modal" data-target="#myModal" data-endpoint="contact-modal" data-arg="1">send message</a>

data-arg = User id or any argument for that matter; depends on endpoint.
data-target =Modal id
data-endpoint = Points to Drupal endpoint

Modal (uses bootstrap modals):

<div class="modal fade" id="myModal" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" style="display: none;">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
            <span aria-hidden="true">×</span>
        </button>
        <h4 class="modal-title" id="myModalLabel">Title</h4>
      </div>
      <div class="modal-body">Content</div>
      <div class="modal-footer"><button type="button" class="btn btn-default" data-dismiss="modal">Close</button></div></div></div></div>

Endpoint:

// Drupal Route
function my_contactform_menu() {
  $items['user/%user/contact/ajax'] = array(
    'page callback' => 'ajax_user_contact',
    'page arguments' => array(1),
    'access callback' => TRUE,
  );

  return $items;
}

// Render Form
function ajax_user_contact($requestee) {
  module_load_include('inc', drupal_get_path('module', 'contact') . '/contact.pages');
  $form = drupal_get_form('contact_personal_form', $requestee);
  echo drupal_render($form);
  drupal_exit();
}

Javascript:

  Drupal.behaviors.myModal = {
    attach: function(context, settings) {

      // Base AJAX using jQuery $.ajax
      function AjaxBase(e) {
        var endpoint = $(e.relatedTarget).data("endpoint");
        var arg = $(e.relatedTarget).attr("data-arg");

        this.type = "GET";
        this.url = getUrl(endpoint, arg);
        this.error = getError;
        
        // Gets url that will be used in our AJAX call
        function getUrl(endpoint, arg) {
          switch(endpoint) {        
            case 'contact-modal':
              var url = '/user/' + arg + '/contact/ajax';
              break;
          }

          return url;
        }

        // Base error message.
        function getError() {
          var errorMessage = "<div class=\"alert alert-danger alert-dismissable\">";
          errorMessage += "<button type=\"button\" class=\"close\" data-dismiss=\"alert\" aria-hidden=\"true\">×</button>";
          errorMessage += "<h2 class=\"element-invisible\">Error message</h2>";
          errorMessage += "<ul><li>There was an error loading the content. Please try again later.</li></ul></div>";

          $('#myModal .modal-body').html(errorMessage);

        }
      }
      
      // Extends Base AJAX
      function ContactModalAjax(e) {
        var ajax = new AjaxBase(e);
        this.call = $.ajax({
          type: ajax.type,
          url: ajax.url,
          success: function(data) {
            $('#myModal .modal-title').text('Send Message');
            $('#myModal .modal-body').html(data);
          },
          error: ajax.error
        });
      }
      
      // If JS replace original link with hash.
      $('a[data-toggle="modal"]').attr("href", "#");
      
      // When Bootstrap modal shows call my modal.
      $('#myModal').on('shown.bs.modal', callModal);

      // Wrapper function helps determine which modal to use.
      function callModal(e) {
        endpoint = $(e.relatedTarget).data("endpoint");

        switch(endpoint) {
          case 'contact-modal':
            var modal = new ContactModalAjax(e);
            break;
        }

        modal.call;
      }
    }
  };

When I click the link the modal gets called. The form is rendered properly. Submitting the complete form works fine. The issue is when validation fails. Upon failed validation I am redirected to the actual form endpoint at 'user/%user/contact/ajax', where an unstyled form is rendered without the Drupal page wrapper.

I have tried to add an AJAX submit button using Form API, however I was unable to. Perhaps it is my lack of knowledge with Form API AJAX. I also tried to disable the submit button until all fields are validated via JS to no avail. If anyone has done anything similar or could point me in the right direction I would really appreciate the advice. The goal is to have all the sites forms open via AJAX call. I prefer not to use ctools modals.

Comments

Jaypan’s picture

The best way is to ajaxify the submit button, as you mentioned.

This tutorial I wrote recently may help you: http://www.jaypan.com/tutorial/drupal-7-ajaxify-form-popup