0

I'm building a site in WordPress that uses the donation plugin Charitable. On the donation page, there are two sections with two sets of radio buttons for donation values. The plugin does not have a feature that I want to include, and they will not support the feature that I am trying to build.

I want to display some content when a user selects a donation amount. I've been trying to use Code Snippets, which is a separate plugin supported by Charitable, but I've only made limited progress. My limited coding knowledge is holding me back.

I have two code snippets: one in PHP and one in JavaScript. The PHP snippet adds the custom content in the desired location, and the JavaScript snippet controls which div is displayed when a radio button (donation amount) is clicked.

My problem is that when I click a donation amount, it only displays the content in the single donation HTML section, but not in the recurring donation HTML section. I've tried targeting the radio buttons in other ways, but I'm falling short.

PHP snippet

add_action('charitable_donation_form_after_donation_amounts', 'add_custom_content');
function add_custom_content(){
    echo '<div class="sgl-content sgl5 once">Single £5 is selected</div>
    <div class="sgl-content sgl10 once">Single £10 is selected</div>
    <div class="sgl-content sgl25 once">Single £25 is selected</div>
    <div class="sgl-content sgl50 once">Single £50 is selected</div>
    <div class="sgl-content sglcustom once">Single Custom amount is selected</div>';
}

add_action('charitable_recurring_donation_form_after_donation_amounts', 'add_custom_content_rec');
function add_custom_content_rec() {
    echo '<div class="rec-content rec5 month">Recurring £5 is selected</div>
    <div class="rec-content rec10 month">Recurring £10 is selected</div>
    <div class="rec-content rec25 month">Recurring £25 is selected</div>
    <div class="rec-content recrecurring-custom month">Recurring Custom amount is selected</div>';
}

jQuery(function($) {
  var sglAmountSection = document.getElementsByName('donation_amount');

  for (var i = 0; i < sglAmountSection.length; i++) {
    sglAmountSection[i].onclick = function() {
      $(".sgl-content").css('display', 'none'); // Hide all sgl divs
      $(".sgl" + this.value).css('display', 'block'); // Show the selected div
    }
  }
});

jQuery(function($) {
  var recAmountSection = document.getElementsByName('donation_amount');

  for (var i = 0; i < recAmountSection.length; i++) {
    recAmountSection[i].onclick = function() {
      $(".rec-content").css('display', 'none'); // Hide all rec divs
      $(".rec" + this.value).css('display', 'block'); // Show the selected div
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<fieldset class="charitable-fieldset odd">
  <p class="minimum-donation-amount-text">The minimum donation for this campaign is £5.</p>
  <div class="charitable-form-header">Your Donation</div>

  <div id="charitable-donation-options-693037511dbd3">
    <ul class="recurring-donation recurring-donation-options">
      <li class="one-time-donation recurring-donation-option">
        <label for="recurring-form-693037511dbd3-once">
            <input id="recurring-form-693037511dbd3-once" type="radio" data-form_id="693037511dbd3" name="recurring_donation" value="once" checked="checked" class="selected">One Time</label>
      </li>
      <li class="monthly-donation recurring-donation-option selected">
        <label for="recurring-form-693037511dbd3-recurring">
            <input id="recurring-form-693037511dbd3-recurring" type="radio" data-form_id="693037511dbd3" name="recurring_donation" value="month">Monthly</label>
      </li>
    </ul>

    <div class="charitable-donation-options charitable-recurring-donation-options active" style="">
      <noscript>
            <div class="charitable-form-subheader">Your monthly Donation</div>
         </noscript>
      <ul class="recurring-donation-amounts donation-amounts">
        <li class="donation-amount suggested-donation-amount">
          <label for="recurring-form-693037511dbd3-field-5">
               <input id="recurring-form-693037511dbd3-field-5" type="radio" name="donation_amount" data-recurring="true" data-value="5" value="5">
               <span class="amount">£5 <span class="recurring-details"> / month</span></span> <span class="description"></span>
               </label>
        </li>
        <li class="donation-amount suggested-donation-amount">
          <label for="recurring-form-693037511dbd3-field-10">
               <input id="recurring-form-693037511dbd3-field-10" type="radio" name="donation_amount" data-recurring="true" data-value="10" value="10">
               <span class="amount">£10 <span class="recurring-details"> / month</span></span> <span class="description"></span>
               </label>
        </li>
        <li class="donation-amount suggested-donation-amount">
          <label for="recurring-form-693037511dbd3-field-25">
               <input id="recurring-form-693037511dbd3-field-25" type="radio" name="donation_amount" data-recurring="true" data-value="25" value="25">
               <span class="amount">£25 <span class="recurring-details"> / month</span></span> <span class="description"></span>                
               </label>
        </li>
        <li class="donation-amount custom-donation-amount">
          <span class="custom-donation-amount-wrapper">
               <label for="recurring-form-693037511dbd3-field-custom-recurring-amount">
               <input id="recurring-form-693037511dbd3-field-custom-recurring-amount" type="radio" name="donation_amount" value="recurring-custom">
               <span class="description">Custom amount</span>
          </label>
          <input type="text" class="custom-donation-input" name="custom_recurring_donation_amount" value="">
          </span>
        </li>
      </ul>

      <!-- .donation-amounts -->
      <div class="rec-content rec5 month" style="display: block;">Recurring £5 is selected</div>
      <div class="rec-content rec10 month" style="display: none;">Recurring £10 is selected</div>
      <div class="rec-content rec25 month" style="display: none;">Recurring £25 is selected</div>
      <div class="rec-content recrecurring-custom month" style="display: none;">Recurring Custom amount is selected</div>
    </div>
    <!-- .charitable-donation-options -->
    <div class="charitable-donation-options" style="display: none;">
      <noscript>
            <div class="charitable-form-subheader show-if-no-js">Your One-Time Donation</div>
         </noscript>
      <ul class="donation-amounts has-suggested-amounts donation-amounts-count-4">
        <li class="donation-amount suggested-donation-amount selected">
          <label for="form-693037511dbd3-field-5">
               <input id="form-693037511dbd3-field-5" type="radio" name="donation_amount" value="5">
               <span class="amount">£5</span> <span class="description"></span>
               </label>
        </li>
        <li class="donation-amount suggested-donation-amount">
          <label for="form-693037511dbd3-field-10">
               <input id="form-693037511dbd3-field-10" type="radio" name="donation_amount" value="10">
               <span class="amount">£10</span> <span class="description"></span>
               </label>
        </li>
        <li class="donation-amount suggested-donation-amount">
          <label for="form-693037511dbd3-field-25">
               <input id="form-693037511dbd3-field-25" type="radio" name="donation_amount" value="25">
               <span class="amount">£25</span> <span class="description"></span>
               </label>
        </li>
        <li class="donation-amount suggested-donation-amount">
          <label for="form-693037511dbd3-field-50">
               <input id="form-693037511dbd3-field-50" type="radio" name="donation_amount" value="50">
               <span class="amount">£50</span> <span class="description"></span>
               </label>
        </li>
      </ul>
      <ul class="donation-amounts donation-suggested-amount">
        <li class="donation-amount custom-donation-amount">
          <span class="custom-donation-amount-wrapper">
               <label for="form-693037511dbd3-field-custom-amount">
               <input id="form-693037511dbd3-field-custom-amount" type="radio" name="donation_amount" value="custom"><span class="description">Custom amount</span>
          </label>
          <input type="text" class="custom-donation-input" name="custom_donation_amount" placeholder="Enter donation amount" value="">
          </span>
        </li>
      </ul>
      <!-- .donation-amounts -->
      <div class="sgl-content sgl5 once" style="display: block;">Single £5 is selected</div>
      <div class="sgl-content sgl10 once" style="display: none;">Single £10 is selected</div>
      <div class="sgl-content sgl25 once" style="display: none;">Single £25 is selected</div>
      <div class="sgl-content sgl50 once" style="display: none;">Single £50 is selected</div>
      <div class="sgl-content sglcustom once" style="display: none;">Single Custom amount is selected</div>
    </div>
    <!-- .charitable-donation-options -->
  </div>
  <!-- charitable-donation-options-693037511dbd3 -->
</fieldset>

3 Answers 3

1

By looking at the produced HTML, you seem to think way too complicated. You do not need two form element blocks that contain the same type of inputs, you only need them once and then generate the message you display to the user based on the selected fields. I might be wrong, but I'm honestly left with the impression that you think you need two different forms because of the message you want to display. The HTML in my code is therefor stripped down a lot from what you've posted. Please also note that I changed the input for a custom amount from type="text" to type="number" as well as adding relevant attributes to it, so a visitor is only allowed to input numeric values instead of freeform text.

Below is a working JS snippet that does create a fitting message based on the selected form fields. I added extensive comments to it, so you can understand what happens step by step. I intentionally did not use jQuery (except jQuery(function () { ... }), since it's unclear if the JS runs inside <head> or <body>) in it to avoid further complexity (for what you want to do you don't need jQuery anymore) for you by having to look up different documentations. If you want a jQuery based example script, please leave a comment and I'm happy to update the answer.

jQuery(function () {

  var $donationTypes = Array.from(document.querySelectorAll('[name="donation_type"]'));     // get all type radios as array
  var $donationAmounts = Array.from(document.querySelectorAll('[name="donation_amount"]')); // get all amount radios as array
  var $customAmount = document.querySelector('[name="custom_donation_amount"]');            // get custom amount input
  var $message = document.querySelector('.message');                                        // get the message div
  
  function displayMessage() {
    var type = $donationTypes.find(el => el.checked);                                       // get checked type radio
    var amount = $donationAmounts.find(el => el.checked);                                   // get checked amount radio
    var amountValue = amount.value === 'custom'                                             // custom amount? then...
      ? $customAmount.value                                                                 // ... get value from custom amount input
      : amount.value;                                                                       // ... otherwise use selected radio amount
      
    if (type.value === 'once') {                                                            // one time donation? then...
      $message.textContent = `Single £${amountValue} is selected`;                          // ... show one time message
    } else {
      $message.textContent = `£${amountValue} per month is selected`;                       // ... otherwise show the recurring message
    }
  }
  
  $donationTypes.forEach(el => {                                                            // add eventlisteners to the radios
    el.addEventListener('change', displayMessage);
  });
  $donationAmounts.forEach(el => {
    el.addEventListener('change', displayMessage);
  });
  $customAmount.addEventListener('input', displayMessage);                                                            // add an eventlistener to the custom amount input as well!
  displayMessage();                                                                         // show the initial message

});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<fieldset class="charitable-fieldset odd">
   <p class="minimum-donation-amount-text">The minimum donation for this campaign is £5.</p>
   <div class="charitable-form-header">Your Donation</div>

   <div id="charitable-donation-options-693037511dbd3">
      <ul class="donation donation-options">
         <li class="donation-options-item">
            <label for="form-693037511dbd3-once">
            <input id="form-693037511dbd3-once" type="radio" data-form_id="693037511dbd3" name="donation_type" value="once" checked="checked">One Time</label>
         </li>
         <li class="donation-options-item">
            <label for="form-693037511dbd3-recurring">
            <input id="form-693037511dbd3-recurring" type="radio" data-form_id="693037511dbd3" name="donation_type" value="monthly">Monthly</label>
         </li>
      </ul>

      <div class="charitable-donation-options">
         <ul class="donation-amounts">
            <li class="donation-amounts-item">
               <label for="form-693037511dbd3-field-5">
               <input id="form-693037511dbd3-field-5" type="radio" name="donation_amount" value="5" checked="checked">
               <span class="amount">£5</span>
               </label>
            </li>
            <li class="donation-amounts-item">
               <label for="form-693037511dbd3-field-10">
               <input id="form-693037511dbd3-field-10" type="radio" name="donation_amount" value="10">
               <span class="amount">£10</span>
               </label>
            </li>
            <li class="donation-amounts-item">
               <label for="form-693037511dbd3-field-25">
               <input id="form-693037511dbd3-field-25" type="radio" name="donation_amount" value="25">
               <span class="amount">£25</span>
               </label>
            </li>
            <li class="donation-amounts-item">
               <span class="custom-donation-amount-wrapper">
               <label for="form-693037511dbd3-field-custom-amount">
               <input id="form-693037511dbd3-field-custom-amount" type="radio" name="donation_amount" value="custom">
               <span class="description">Custom amount</span>
               </label>
               <input type="number" class="custom-donation-input" name="custom_donation_amount" min="5" step="1" value="5">
               </span>
            </li>
         </ul>

         <!-- .donation-amounts -->
         <div class="message"></div>
      </div>
   </div>
   <!-- charitable-donation-options-693037511dbd3 -->
</fieldset>

Sign up to request clarification or add additional context in comments.

7 Comments

Thank you for your answer. Unfortunately I'll be adding an image and some text to the show/hide divs so it will be more complicated to have the html inside the script like this. The text that is there for now is just placeholder text.
" ... it will be more complicated to have the html inside the script like this." - There's no HTML inside my script, just text. However, even if you think it does not solve the problem for you as it is right now, I hope it still communicated the message that you (most certainly) don't need the complicated HTML <fieldset> structure from your question. And: Instead of producing textual messages, you could produce a selector of the corresponding element that you then show while hiding all others.
Would you mind telling me at what you're hinting here? If you want to say that it would've been better if my answer included a templating library just to create a simple text message, I think that's way over the top. If that's not what you wanted to say, I'm sorry but I really don't get it.
@Davi: No, not at all. That was meant in response to the OPs comment that changes the goalposts after getting an answer. And then again.
Thx for clarification :)
@Davi: You're welcome.
0

Looking at your code, I can see the issue. Both of your JavaScript functions are targeting the same elements (getElementsByName('donation_amount')), which means they're conflicting with each other. The radio buttons for both one-time and recurring donations share the same name attribute.

Here's the solution - you need to check which donation type section is currently visible and show/hide the appropriate content divs:

jQuery(function ($) {
    // Get all radio buttons with name="donation_amount"
    var allAmountRadios = document.getElementsByName('donation_amount');
    
    for (var i = 0; i < allAmountRadios.length; i++) {
        allAmountRadios[i].onclick = function() {
            // Check if this radio button has data-recurring attribute
            var isRecurring = $(this).attr('data-recurring') === 'true';
            
            if (isRecurring) {
                // Handle recurring donation
                $(".rec-content").css('display', 'none'); // Hide all rec divs
                $(".rec" + this.value).css('display', 'block'); // Show the selected div
            } else {
                // Handle one-time donation
                $(".sgl-content").css('display', 'none'); // Hide all sgl divs
                $(".sgl" + this.value).css('display', 'block'); // Show the selected div
            }
        }
    }
    
    // Also handle the recurring/one-time toggle buttons
    $('input[name="recurring_donation"]').on('change', function() {
        if ($(this).val() === 'once') {
            // When switching to one-time, hide recurring content
            $(".rec-content").css('display', 'none');
            // Show the currently selected one-time amount (if any)
            var selectedOnce = $('.charitable-donation-options:not(.charitable-recurring-donation-options) input[name="donation_amount"]:checked');
            if (selectedOnce.length > 0) {
                $(".sgl-content").css('display', 'none');
                $(".sgl" + selectedOnce.val()).css('display', 'block');
            }
        } else if ($(this).val() === 'month') {
            // When switching to recurring, hide one-time content
            $(".sgl-content").css('display', 'none');
            // Show the currently selected recurring amount (if any)
            var selectedRecurring = $('.charitable-recurring-donation-options input[name="donation_amount"]:checked');
            if (selectedRecurring.length > 0) {
                $(".rec-content").css('display', 'none');
                $(".rec" + selectedRecurring.val()).css('display', 'block');
            }
        }
    });
});
New contributor
Mohammad Tajik is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.

5 Comments

Please do not use AI to answer questions since it is prohibited at SO
This is amazing, thank you so much Mohammad. This works great, but up to a point. I've just realised by this working that my custom amounts input fields have different names and no data-recurring attribute. I've no idea how to work that in. Would I need to have a separate JavaScript function for this?
my understanding is that jQuery(function ($) is for using $ with custom scripts in Wordpress so that it doesn't conflict with jQuery library.
hakre was talking about .data() not about $. Did you read the link?
0

jQuery(function($) {
  var sglAmountSection = document.getElementsByName('donation_amount');

  for (var i = 0; i < sglAmountSection.length; i++) {
    sglAmountSection[i].onclick = function() {
      $(".sgl-content").css('display', 'none'); // Hide all sgl divs
      $(".sgl" + this.value).css('display', 'block'); // Show the selected div
    }
  }
});

jQuery(function($) {
  var recAmountSection = document.getElementsByName('donation_amount');

  for (var i = 0; i < recAmountSection.length; i++) {
    recAmountSection[i].onclick = function() {
      $(".rec-content").css('display', 'none'); // Hide all rec divs
      $(".rec" + this.value).css('display', 'block'); // Show the selected div
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<fieldset class="charitable-fieldset odd">
  <p class="minimum-donation-amount-text">The minimum donation for this campaign is £5.</p>
  <div class="charitable-form-header">Your Donation</div>

  <div id="charitable-donation-options-693037511dbd3">
    <ul class="recurring-donation recurring-donation-options">
      <li class="one-time-donation recurring-donation-option">
        <label for="recurring-form-693037511dbd3-once">
            <input id="recurring-form-693037511dbd3-once" type="radio" data-form_id="693037511dbd3" name="recurring_donation" value="once" checked="checked" class="selected">One Time</label>
      </li>
      <li class="monthly-donation recurring-donation-option selected">
        <label for="recurring-form-693037511dbd3-recurring">
            <input id="recurring-form-693037511dbd3-recurring" type="radio" data-form_id="693037511dbd3" name="recurring_donation" value="month">Monthly</label>
      </li>
    </ul>

    <div class="charitable-donation-options charitable-recurring-donation-options active" style="">
      <noscript>
            <div class="charitable-form-subheader">Your monthly Donation</div>
         </noscript>
      <ul class="recurring-donation-amounts donation-amounts">
        <li class="donation-amount suggested-donation-amount">
          <label for="recurring-form-693037511dbd3-field-5">
               <input id="recurring-form-693037511dbd3-field-5" type="radio" name="donation_amount" data-recurring="true" data-value="5" value="5">
               <span class="amount">£5 <span class="recurring-details"> / month</span></span> <span class="description"></span>
               </label>
        </li>
        <li class="donation-amount suggested-donation-amount">
          <label for="recurring-form-693037511dbd3-field-10">
               <input id="recurring-form-693037511dbd3-field-10" type="radio" name="donation_amount" data-recurring="true" data-value="10" value="10">
               <span class="amount">£10 <span class="recurring-details"> / month</span></span> <span class="description"></span>
               </label>
        </li>
        <li class="donation-amount suggested-donation-amount">
          <label for="recurring-form-693037511dbd3-field-25">
               <input id="recurring-form-693037511dbd3-field-25" type="radio" name="donation_amount" data-recurring="true" data-value="25" value="25">
               <span class="amount">£25 <span class="recurring-details"> / month</span></span> <span class="description"></span>                
               </label>
        </li>
        <li class="donation-amount custom-donation-amount">
          <span class="custom-donation-amount-wrapper">
               <label for="recurring-form-693037511dbd3-field-custom-recurring-amount">
               <input id="recurring-form-693037511dbd3-field-custom-recurring-amount" type="radio" name="donation_amount" value="recurring-custom">
               <span class="description">Custom amount</span>
          </label>
          <input type="text" class="custom-donation-input" name="custom_recurring_donation_amount" value="">
          </span>
        </li>
      </ul>

      <!-- .donation-amounts -->
      <div class="rec-content rec5 month" style="display: block;">Recurring £5 is selected</div>
      <div class="rec-content rec10 month" style="display: none;">Recurring £10 is selected</div>
      <div class="rec-content rec25 month" style="display: none;">Recurring £25 is selected</div>
      <div class="rec-content recrecurring-custom month" style="display: none;">Recurring Custom amount is selected</div>
    </div>
    <!-- .charitable-donation-options -->
    <div class="charitable-donation-options" style="display: none;">
      <noscript>
            <div class="charitable-form-subheader show-if-no-js">Your One-Time Donation</div>
         </noscript>
      <ul class="donation-amounts has-suggested-amounts donation-amounts-count-4">
        <li class="donation-amount suggested-donation-amount selected">
          <label for="form-693037511dbd3-field-5">
               <input id="form-693037511dbd3-field-5" type="radio" name="donation_amount" value="5">
               <span class="amount">£5</span> <span class="description"></span>
               </label>
        </li>
        <li class="donation-amount suggested-donation-amount">
          <label for="form-693037511dbd3-field-10">
               <input id="form-693037511dbd3-field-10" type="radio" name="donation_amount" value="10">
               <span class="amount">£10</span> <span class="description"></span>
               </label>
        </li>
        <li class="donation-amount suggested-donation-amount">
          <label for="form-693037511dbd3-field-25">
               <input id="form-693037511dbd3-field-25" type="radio" name="donation_amount" value="25">
               <span class="amount">£25</span> <span class="description"></span>
               </label>
        </li>
        <li class="donation-amount suggested-donation-amount">
          <label for="form-693037511dbd3-field-50">
               <input id="form-693037511dbd3-field-50" type="radio" name="donation_amount" value="50">
               <span class="amount">£50</span> <span class="description"></span>
               </label>
        </li>
      </ul>
      <ul class="donation-amounts donation-suggested-amount">
        <li class="donation-amount custom-donation-amount">
          <span class="custom-donation-amount-wrapper">
               <label for="form-693037511dbd3-field-custom-amount">
               <input id="form-693037511dbd3-field-custom-amount" type="radio" name="donation_amount" value="custom"><span class="description">Custom amount</span>
          </label>
          <input type="text" class="custom-donation-input" name="custom_donation_amount" placeholder="Enter donation amount" value="">
          </span>
        </li>
      </ul>
      <!-- .donation-amounts -->
      <div class="sgl-content sgl5 once" style="display: block;">Single £5 is selected</div>
      <div class="sgl-content sgl10 once" style="display: none;">Single £10 is selected</div>
      <div class="sgl-content sgl25 once" style="display: none;">Single £25 is selected</div>
      <div class="sgl-content sgl50 once" style="display: none;">Single £50 is selected</div>
      <div class="sgl-content sglcustom once" style="display: none;">Single Custom amount is selected</div>
    </div>
    <!-- .charitable-donation-options -->
  </div>
  <!-- charitable-donation-options-693037511dbd3 -->
</fieldset>

New contributor
Adrián Bartakovics is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.

1 Comment

You're likely to get a more favourable response to your post if you take the time to explain your answer, including talking about what you've done and why you expect that it solves the problem. Just dumping code is actually not very helpful most of the time. See also How to Answer. Thanks.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.