Skip to content

Instantly share code, notes, and snippets.

@nowakpiotrek
Last active November 12, 2020 18:13
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save nowakpiotrek/4e9def5a68e0926cb4d6780022379425 to your computer and use it in GitHub Desktop.
Save nowakpiotrek/4e9def5a68e0926cb4d6780022379425 to your computer and use it in GitHub Desktop.
CF7 Multi-Step Addon Plugin (v1.0.0) fix for checkbox validation between steps
(function ( $ ) {
"use strict";
/*
* Plugin trx_mscf_ajax provides Contact Form 7 ajax behaviour
* */
$.fn.trx_mscf_ajax = function(options) {
$.fn.trx_mscf_ajax.options = $.extend( {}, $.fn.trx_mscf_ajax.defaults, options );
return this.each(function(index, container) {
if ($($.fn.trx_mscf_ajax.options.classes.step, $(container)).length > 0){
$.fn.trx_mscf_ajax.init($(container));
}
});
};
$.fn.trx_mscf_ajax.defaults = {
ajax_url: TRX_MSCF_GLOBALS['ajax_url'],
ajax_nonce: TRX_MSCF_GLOBALS['ajax_nonce'],
classes: {
active: 'trx_mscf_active',
hidden: 'trx_hidden',
step: '.trx_mscf_step',
next: '.trx_mscf_next',
prev: '.trx_mscf_prev',
progressbar: '.trx_mscf_progressbar',
progressbar_template: 'trx_mscf_template'
}
};
$.fn.trx_mscf_ajax.init = function ($container) {
var defaults = $.fn.trx_mscf_ajax.options;
$(defaults.classes.step, $container).each(function (ind, el) {
if (ind === 0) {
$(el).addClass(defaults.classes.active);
}
$(el).attr('data-step', ++ind);
});
// Next step click action
$(defaults.classes.next, $container).stop().click(function (e) {
e.preventDefault();
var current_step_obj = $(e.target).closest(defaults.classes.step);
if(current_step_obj.length > 0) {
var current_step = parseInt( current_step_obj.attr('data-step') ),
next_step_obj = $(defaults.classes.step + '[data-step=' + (++current_step) +']',$container);
$.fn.trx_mscf_ajax.step_validate($container, current_step_obj, next_step_obj);
} else {
console.log('Cant find current step.');
}
});
// Prev step click action
$(defaults.classes.prev, $container).stop().click(function (e) {
e.preventDefault();
var current_step_obj = $(e.target).closest(defaults.classes.step);
if(current_step_obj.length > 0) {
var current_step = parseInt( current_step_obj.attr('data-step') ),
prev_step_obj = $(defaults.classes.step + '[data-step=' + (--current_step) +']',$container);
$.fn.trx_mscf_ajax.change_progressbar(current_step_obj, prev_step_obj, $container);
$.fn.trx_mscf_ajax.do_step(current_step_obj, prev_step_obj);
} else {
console.log('Cant find current step.');
}
});
};
$.fn.trx_mscf_ajax.step_validate = function ($container, current_step_obj, next_step_obj) {
var defaults = $.fn.trx_mscf_ajax.options,
$form = $('form', $container),
// This is changed (up to line 109) - logic:
// * it needs to search for inputs specifically as checkboxes are wrapped
// * it needs to only consider visible elements as otherwise conditional groups won't work
fields_to_check_names_non_unique = jQuery(current_step_obj).find(".wpcf7-form-control:visible, .wpcf7-form-control input:visible").map(function () {
if(this.type == 'checkbox') {
return this.name.replace('[]','');
} else {
return this.name;
}
}).get(),
fields_to_check_names = fields_to_check_names_non_unique.filter(function(item, index) {
if (fields_to_check_names_non_unique.indexOf(item) == index)
return item;
}),
fields_to_check_serialized = jQuery(current_step_obj).find(".wpcf7-form-control").serialize(),
checkboxes = jQuery(current_step_obj).find(".wpcf7-form-control input:checked").map(function() {
if(this.checked) {
return this.name + "=" + this.value;
} else {
return this.name.replace('[]','') + "=";
}
}).toArray(),
checkboxes_serialized = checkboxes.filter(function(item, index) {
if (checkboxes.indexOf(item) == index)
return item;
}).join('&'),
data = checkboxes_serialized
+ '&'+ fields_to_check_serialized
+ '&'+ 'action=' + 'trx_mscf_validate_fields'
+ '&'+ 'trx_form_id=' + wpcf7.getId( $('form', $container) )
+ '&'+ 'trx_fields_to_check=' + fields_to_check_names
+ '&'+ 'trx_ajax_nonce=' + defaults.ajax_nonce;
console.log(fields_to_check_names);
// Check fields validation
if (fields_to_check_names.length > 0) {
jQuery.ajax({
type : "post",
dataType : "json",
url : defaults.ajax_url,
data : data,
success: function(response) {
var json_result = '';
$.fn.trx_mscf_ajax.clear_error_messages($form, current_step_obj);
try {
json_result = (typeof response === 'object') ? response : JSON.parse(JSON.stringify(response));
if (json_result.is_valid) {
$.fn.trx_mscf_ajax.change_progressbar(current_step_obj, next_step_obj, $container);
$.fn.trx_mscf_ajax.do_step(current_step_obj, next_step_obj);
} else {
// show errors
var $message = $( '.wpcf7-response-output', $form );
$.each( json_result.invalid_fields, function(i, n) {
$(n.into, $form).each(function() {
wpcf7.notValidTip(this, n.message);
$( '.wpcf7-form-control', this ).addClass( 'wpcf7-not-valid' );
$( '[aria-invalid]', this ).attr( 'aria-invalid', 'true' );
} );
} );
$message.html('One or more fields have an error. Please check and try again.');
$message.addClass( 'wpcf7-validation-errors' );
$form.addClass( 'invalid' );
}
} catch (e) {
console.log("error: "+e);
}
}
});
} else {
// If no data to validate, just go on
$.fn.trx_mscf_ajax.change_progressbar(current_step_obj, next_step_obj, $container);
$.fn.trx_mscf_ajax.do_step(current_step_obj, next_step_obj);
}
};
$.fn.trx_mscf_ajax.do_step = function (current_step_obj, next_step_obj) {
var defaults = $.fn.trx_mscf_ajax.options;
$(current_step_obj).removeClass(defaults.classes.active).addClass(defaults.classes.hidden);
$(next_step_obj).removeClass(defaults.classes.hidden).addClass(defaults.classes.active);//.fadeIn();
};
$.fn.trx_mscf_ajax.clear_error_messages = function ($form, current_step_obj) {
$form.removeClass( 'invalid' );
$( '.wpcf7-response-output', $form ).html('').removeClass( 'wpcf7-validation-errors' );
$('.wpcf7-form-control', current_step_obj).removeClass('wpcf7-not-valid');
$('[aria-invalid]', current_step_obj).attr('aria-invalid', 'false');
$('.wpcf7-not-valid-tip', current_step_obj).remove();
};
$.fn.trx_mscf_ajax.change_progressbar = function (current_step_obj, next_step_obj, $container) {
var defaults = $.fn.trx_mscf_ajax.options;
if ($(defaults.classes.progressbar, $container).length > 0) {
var $progressbars = $(defaults.classes.progressbar, $container),
current_step = parseInt( current_step_obj.attr('data-step') ),
next_step = parseInt( next_step_obj.attr('data-step') );
current_step--;
next_step--;
$progressbars.each(function (ind, el) {
if (current_step < next_step) {
$('li', el).eq(next_step).addClass('active');
} else {
$('li', el).eq(current_step).removeClass('active');
$('li', el).eq(next_step).addClass('active');
}
});
}
};
}( jQuery ));
jQuery(document).ready(function () {
"use strict";
jQuery('.wpcf7').trx_mscf_ajax();
});
@ultrawebmarketing
Copy link

Dude... I just want to thank you for saving my butt.

@nowakpiotrek
Copy link
Author

Dude... I just want to thank you for saving my butt.

No problem. Glad it works for you. Especially that this is a fairly old fix. I contacted them to get this sorted. Shame it didn't do into the build.

@jacek606
Copy link

Piotrek thanks! Good stuff. 😎

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment