CiviCRM 5.26.2 Ominpay version of PayPal payments CiviDiscount

We apply the 100% discount code and the payment form is hidden. There is no register button.

Using the browser inspection tool, there is inline script that always hides the buttons. I can't see this in the CiviCRM source code am unsure where it comes from.

CRM.$(function($) {
  $('.crm-submit-buttons', $('#billing-payment-block').closest('form')).hide();

We suspect that this is a PayPal related feature as the PayPal 'off site' workflow is different.


1 Answer 1


This is what we did to get the payment buttons to display when the payment value is $0.

The logic is borrowed from CiviDiscount

CiviDiscount apply button refreshes the page, there are 2 processes

  • Person fills out the form and applies the code. The page is refreshed and we check the state to determine whether the register button is shown
  • The code is applied before the form is filled out completely. We wait for a form valid state.

The conditions to show the buttons are

  • If payment form is hidden
  • The value is $0
  • A discount code is specified
  • The form is valid

In conclusion the following is the code. The apply discount button does a page refresh so we can check the value and whether a discount has been applied on page load.There is a watch on this as the inline script that hides the buttons runs after the other scripts. There is also an observer to check whether the form is valid.

CRM.$(function ($) {
'use strict';

function interlatedIsTotalZero() {
 var zero = false;
 $('.price-set-option-content input').each(function () {
  var currentTotal = $(this).data('amount').replace(/[^\/\d]/g, '');
  if ($(this).is(':checked') && Number(currentTotal) === 0) {
    zero = true;
 return zero;

function interlatedCheckFormValid() {
  var form = $('#billing-payment-block').closest('form');
  return form.valid();

// The whole page is reloaded on discount code
function interlatedShowSubmitButtons() {
  // Is the payment form shown?
  var paymentInformation = document.getElementById('payment_information');
  var paymentInformationShown = paymentInformation.style.display;
  var submitButtons = $('.crm-submit-buttons', $('#billing-payment-block').closest('form'));
  if (interlatedCheckFormValid() && paymentInformationShown === 'none' && $('#discountcode').length > 0 && interlatedIsTotalZero()) {
    return true;

// Form is not valid or similar.
  return false;

// Discount code reloads the whole page. Not a mutation.

// Timing of the jquery to hide the buttons is unpredictable
const buttonsDetectShow = function (mutationsList, observer) {
  for (let mutation of mutationsList) {
    if (mutation.type !== 'attributes') {
    var buttonsBlockShown = mutation.target.style.display;
    if (buttonsBlockShown === 'none') {

function addObserverIfButtonsAvailable() {
  var buttonsEl = $('.crm-submit-buttons', $('#billing-payment-block').closest('form'))[0];
  if (!buttonsEl) {
    window.setTimeout(addObserverIfButtonsAvailable, 500);
  observerButtons.observe(buttonsEl, {attributes: true});

const observerButtons = new MutationObserver(buttonsDetectShow);
var recentMutation = new Date().getTime();

// What happens if we show the button but then the form becomes invalid
const formErrorsDetect = function (mutationsList, observer) {
  var now = new Date().getTime();
  if ((now - recentMutation) < 200) {
  recentMutation = now;
  var mutation = mutationsList[0];
  if (mutation.type !== 'childList') {
  if (mutation.target.classList.contains("error")) {
    // Show or hide the buttons depending on whether the form is valid

function addObserverFormErrors() {
$('.crm-profile .crm-section .content  ', $('#billing-payment-block').closest('form')).each(function () {
  var formEl = $(this)[0];
  observerFormErrors.observe(formEl, {childList: true, subtree: true});

const observerFormErrors = new MutationObserver(formErrorsDetect);


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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