Using only jQuery and CiviCRM to create Members Only Pricing

Published
2012-02-13 19:44
Written by

There have been several hook() or Drupal module based solutions for "members only" pricing for events or for other 'discounts' related to memberships.

 

I take a different approach by using only jQuery and blocks in Drupal 6.  For those who use Drupal 7 you can adapt this code with Drupal 7's new javascript namespace and Joomla folks could even make use of this in custom TPL files.

 

The whole concept of this code is that any 'member only' fee label must contain a specific word or phrase, in my example this word is "Member".  Staff must be trained to do this - it is relatively simple to do so.

 

How it works:

1. Place this code in a block, selecting "full HTML" or "unfiltered" input type, and assign the block to an inconspicuous region in your theme

2. Show the block only on certain pages, such as: civicrm/event/register

3. Show the block only to anonymous users in the block visibility settings

 

That's it!  Fee levels containing the word "Member" will be hidden.

<script>
cj(document).ready(function() {
    cj("input[name=amount]").each(function() {
      var thisPrice = cj(this).attr('id');
      cj("label[for='"+thisPrice+"']:contains('Member')").hide();
      cj("label[for='"+thisPrice+"']:contains('Member')").prev("#"+thisPrice).hide();
    });
});
</script>

Ways you can customize and enhance this

1. Change the word "Member" to a phrase of your choosing

2. Hide only the radio button, not the label, to 'entice' people to join. Delete the first line with hide() at the end

3. Activate this code only on certain pages by placing the unique id of the page in the if() statement near the top. That would look like this:

<script>
cj(document).ready(function() {
// add the id numbers of the pages you want below
if ( 
  document.location.href.indexOf('id=1') > 0 ||
  document.location.href.indexOf('id=2') > 0 ) {	
    cj("input[name=amount]").each(function() {
      var thisPrice = cj(this).attr('id');
      cj("label[for='"+thisPrice+"']:contains('Member')").hide();
      cj("label[for='"+thisPrice+"']:contains('Member')").prev("#"+thisPrice).hide();
    });
  }
});
</script>

4. Show the member pricing not simply to authenticated users, but to only users who are memembers

  • Activate the CiviMember > Roles Sync script
  • Change the visibility settings of the first block to be seen by all, thus hiding member pricing for everyone
  • Make a second block with visibility settings only for your exclusive Member > Roles
  • Copy and paste the same code, but change hide() to show(), thus re-showing member prices only to members
  • Place this second block just below the first block

Comments

For me, it's easy D7 support... I have yet to find something I can use as a non-coder. All the options I've seen are for D6.

I'd use the code above, but I don't have the chops to convert the above code D7 compatible... maybe someone would perform that small act of kindness for me and others?

 

 

 

Modified code for Drupal 6 and CiviCRM 4.1.2. The above code did not work for some reason. Note, it only works right now with radio and checkbox fields.

 

Block 1 has visibility for anonymous users. It removes all pricing options with word 'Member' in them. In effect, anonymous people don't get member pricing.

 

<script>
cj(document).ready(function() {
       //Find all labels containing the text 'Member' that are descendants of the element with id 'priceset'
     cj("#priceset").find("label:contains('Member')").each(function() {
               //Get the value of this labels for attribute. 
               var id = cj(this).attr('for');
               //If it has a value, this is one we want to remove
               if (id) {
                       //Remove the previous element which we know is an input
                   cj(this).prev().remove();        
                   //Remove this element as well
                   cj(this).remove();
       }
       });
});
 
</script>
 
Block 2 has visibility for Members (Members Role, sycned to Drupal user from CiviCRM). It hides all options that don't have word "Member" present. This in effect shows only Member-pricing for Members. The opposite of Block 1.
 
<script>
 
cj(document).ready(function() {
       //Find all labels containing the text 'Member' that are descendants of the element with id 'priceset'
      cj("#priceset").find("label:not(:contains('Member'))").each(function() {
               //Get the value of this labels for attribute. 
               var id = cj(this).attr('for');
               //If it has a value, this is one we want to remove
               if (id) {
                       //Remove the previous element which we know is an input
                   cj(this).prev().remove();        
                   //Remove this element as well
                   cj(this).remove();
       }
       });
});
 
</script>
 
Also, for those new to CiviCRM and jQuery, cj is a renamed jQuery object so it does not conflict with Drupal's jQuery. 
 
This code was developed by Corey Sunwold, http://coreysunwold.com/

 

Here's the code for the anonymous block modifided for Drupal 7. I added in a bit to remind users to login to get their member price

<script type="text/javascript">

    (function($) {

    $(document).ready(function() {


//This is our custom jQuery code

   

$("#priceset").find("label:contains('Members')").each(function(){

            var id = $(this).attr('for');

            if (id) {

                $(this).prev().remove();

                $(this).remove();

                    }

            });

    $("#priceset").prepend("<h3>If you are a member, log in for member prices</h3>");

//This is the end of our custom jQuery code

  }); 

  }) (jQuery);

</script>