.on('submit', '#application-form', function(e) {

    var form = $(this),
        formData = new FormData(form[0]),
        msgBox = form.find('.msg-box'),
        submitBtn = form.find('.submit'),
        loader = submitBtn.find('.fa');

    submitBtn.prop('disabled', true);
    loader.css('display', 'inline-block');

    formData.append('attachment[]', form.find('#resume')[0].files[0]);
    formData.append('attachment[]', form.find('#portfolio')[0].files[0]);

        url: '/',
        type: 'post',
        data: formData,
        dataType: 'json',
        contentType: false,
        processData: false,
        success: function(data) {
            msgBox.fadeOut(function() {
                if(data.success) {
                    $(this).text( 'Your application has been submitted!').removeClass('error');
                } else {
                    $(this).text('An error occurred. Please try again.').addClass('error');




<form id="application-form" class="content-block-lg" method="post" action="" accept-charset="utf-8" enctype="multipart/form-data">
    <div class="grid-container">
        <div class="grid-parent grid-sm-90 prefix-sm-5">
            {{ getCsrfInput() }}
            <input type="hidden" name="action" value="contactForm/sendMessage">
            <input type="hidden" name="fromEmail" value="no-reply@example.com">
            <input type="hidden" name="subject" value="Application Form">

            <input type="text" id="address" name="address">
            <div class="grid-sm-50 content-block">
                <input type="text" name="message[Name]" placeholder="Name">
            <div class="grid-sm-50 content-block">
                <input type="text" name="message[EmailOrPhone]" placeholder="Email or Phone">
            <div class="grid-sm-100 content-block">
                <textarea name="message[body]" rows="3" placeholder="Tell us about you"></textarea>
            <div class="grid-sm-100 content-block">
                <input type="text" name="message[LinkToOnlinePortfolio]" placeholder="link to online portfolio">
            <div class="grid-sm-100 stripe-md actions">
                <span>Upload a pdf of...</span>
                <input id="resume" type="file" placeholder="resume">
                <input id="portfolio" type="file" placeholder="portfolio">
                    <a class="btn-file" href="#resume">resume</a>
                    <a class="btn-file" href="#portfolio">portfolio</a>
            <div class="grid-sm-100 text-right actions">
                <button class="submit" type="submit">send <i class="fa fa-spinner fa-pulse"></i></button>
                <div class="msg-box"></div>

The problem I am getting is that, with the code above, submitting the form, I get a response of the entire Homepage html. I've tried using the url set in the action hidden input, but that just gives me a 404 response. It's like it can't see the "Action" being passed in because it's in FormData?

  • 2
    Would you mind streamlining these code examples a little bit (ie: removing extraneous classes and DOM elements), and perhaps add a few sentences describing what kind of behavior you're seeing vs. what you're expecting? That would greatly help others to hone in on what the problem may be.
    – Lindsey D
    Sep 10, 2016 at 3:59

2 Answers 2


I have it working now using this:

$('#Form').submit(function(ev) {
// Prevent the form from actually submitting

var formData = new FormData($(this)[0]);

// Send it to the server
$.ajax('/', {    
  url:  '/',
  data: formData,
  type: 'POST',
  async: false,
  cache: false,
  contentType: false,
  processData: false,
  success: function(response) {
    if (response.success) {
      alert('Thank You. Your message has been sent');
    } else {
            // response.error will be an object containing any validation errors that occurred, indexed by field name
            // e.g. response.error.fromName => ['From Name is required']
            alert('An error occurred. Please try again.');

Here's my article about building AJAX-based contact form for Craft CMS that uses formData:


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.