1

In CiviCRM webform, you can 'enable tag and groups'. Configuring those allows you to create option elements in the webform.

This creates one 'widget', one dropdown or set of checkboxes. I have two field instances where I want the user to select a group - say for example

  • which mailing lists do you want to receive (a,b,c)
  • what food are you interested in (d,e,f)

a,b,c,d,e and f are all groups. I can not change that.

How could I do that ?

commonpike
  • 10,499
  • 4
  • 65
  • 58
  • the groups are just examples. i cant change them, but wouldn't want to if i could - they are semantically both groups, just different sorts of groups. – commonpike Feb 20 '15 at 10:16

2 Answers2

2

A technical suggestion below, but first, I'd suggest that your real solution is to not use groups for the second question. Groups are set up nicely to handle mailing lists, but if it's to track interests, you'd be better off setting those up as custom fields. It'll solve this immediate issue, and it'll make it easier to deal with tandem searches and so forth (on list b and likes food d).

Now if you must have them as groups, you can create a fake field and move checkboxes into it using jQuery. Create the fake field with one option that you don't care about, but label it "What food are you interested in", or equivalent. Then, edit the Groups field that CiviCRM generated: label it more specifically as "which mailing lists...", and choose Static Options so it doesn't start offering up just any group for someone to choose.

Now, add the following javascript:

// first remove the dummy checkboxes in your fake field
$('#yourdummyfield .form-item').each( function() { $(this).remove(); });

// now move things into the dummy field
$('#yourdummyfield').append( $('#groupsfield .form-item-d');
$('#yourdummyfield').append( $('#groupsfield .form-item-e');
$('#yourdummyfield').append( $('#groupsfield .form-item-f');

From the form processing perspective, they'll all be evaluated as the "groups" field. However, they'll look separate. For better or worse, this will have to be adjusted as you add new groups fields.

Andie Hunt
  • 705
  • 3
  • 8
  • Thanks for the suggestion. I've used this for a while, but wasn't happy as the mailinglists and food interests (as per the example) were changing, and required me to update the jQuery code to match... – commonpike Nov 02 '15 at 13:18
0

After using Andrew Hunts suggestion for a while, I finally solved this on the server side, in a custom module, using webform logic as described here http://www.webomelette.com/drupal-webform-submission-presave-hook

Basicly, on presave, I look for 2 custom fields containing group ids (mailing and food in the example). Then I add these to the CiviCRM groups field.

I'll add the code below, which has some more logic:

  • to make it flexible, I use one hidden field to contain the fieldkey of the civicrm groups selector to add the other fields in. that field is called 'the_groups_element' (but its not the groups element, it contains the key of the groups element)
  • there is only one foods group allowed, so before it adds you to a food group, it removes all other food groups from the groups selector.

You could probably make it even more generic, but since I had different logic for the different groups, this was suitable for me.

function getFoodGroups() {
    // return foodgroups
}
function getMailGroups() {
    // return mailgroups
}

function MYMODULE_webform_submission_presave($node, &$submission) {



    $groupselm      = '';
    $groups_cid     = false;
    $foods_cid  = false;
    $mailings_cid = false;

    // http://www.webomelette.com/drupal-webform-submission-presave-hook
    foreach($node->webform['components'] as $cid=>$comp) {
        if ($comp['form_key']=='the_groups_element') {
            $groupselm = $comp['value'];
            break;
        }
    }


    if ($groupselm) {

        foreach($node->webform['components'] as $cid=>$comp) {
            if ($comp['form_key']==$groupselm) $groups_cid = $comp['cid'];
            if ($comp['form_key']=='the_foods') $foods_cid = $comp['cid'];
            if ($comp['form_key']=='the_mailings') $mailings_cid = $comp['cid'];
        }

        $group_gids = $submission->data[$groups_cid];
        if (!$group_gids) $group_gids=array();




        if ($foods_cid!==false && $submission->data[$foods_cid]) {

            // remove all current foods
            foreach ($group_gids as $gidx=>$group_gid) {
                foreach (getFoodGroups() as $foodgroup) {
                    if ($group_gid==$foodgroup['gid']) {
                        if ($debug) drupal_set_message('removing foodgroup '.$foodgroup['gid']);
                        unset($group_gids[$gidx]);
                    }
                }
            }

            // validate and add submitted regions
            $foodsgids = $submission->data[$foods_cid];
            if (!is_array($foodsgids)) $foodsgids = array($foodsgids);
            foreach ($foodsgids as $foodsgid) {
                foreach (getFoodGroups() as $foodgroup) {
                    if ($foodsgid==$foodgroup['gid']) {
                        $group_gids[]=$foodsgid;
                        break; // only one food allowed
                    }
                }
            }
        }

        if ($mailings_cid!==false && $submission->data[$mailings_cid]) {

            // just add submitted mailings, dont remove any
            $mailinggids = $submission->data[$mailings_cid];
            if (!is_array($mailinggids)) $mailinggids = array($mailinggids);
            foreach ($mailinggids as $mailinggid) {
                foreach (getMailGroups() as $mailing) {
                    if ($mailinggid==$mailing['gid']) {
                        if ($debug) drupal_set_message('adding mailing '.$mailing['gid']);
                        $group_gids[]=$mailinggid;
                    }
                }
            }
        }

        $submission->data[$groups_cid] = array_unique($group_gids);

    }
commonpike
  • 10,499
  • 4
  • 65
  • 58