1

I'm having a hard time deciding on how to develop the following functionality in my upcoming module:

I'm developing a module which should eventually be able to create "event" type nodes. Which extend the nodes functionality to have:

  1. One or multiple plannings which consist out of...
  2. ... timespaces, which has the following properties, per timespace:
    • from (datetime)
    • to (datetime)
    • limit of subscribers (int)
    • And other stuff (not related to the question)
  3. The website visitors should be able to subscribe to each timespace with a form, filling out their information. But if, and only if the limit of subscribers has not been reached yet for this timespace.
  4. After subscription, the visitor should get an automatic mail with a PDF (ticket) attached to it.
  5. Our customer should be able to export all the data, at any time to an Excel sheet...
  6. ... and (preferably) quick-review all the subscriptions at all time.

Well, the plannings and the timespaces won't be a problem, I'll manage that. But I would absolutely LOVE to incorporate Webforms into this. Since, point 3 through 6 all address functionality that already exists in Webforms... It'll save my butt a lot of time developing this thing.

My question is... Does anyone have any experience developing a module, incorporating Webforms? If so, how did you combine the two? I was thinking about something in the lines of:

  • Developing a new Field widget which would make it possible for the moderators to create the event's plannings and timespaces.
  • Somehow, (and this is the part where I'm not sure how to do this) creating a field for "webform" that would fetch the possibilities from the field.

I'm not sure.. I don't think this is the right way to go... I wonder what you guys think about this and if I simply should develop my own form + all the functionalities with it. Or maybe know a contrib module that does all of this...

1 Answer 1

1

I've found the solution today myself. I've been developing Webform components. I've found this way to be the best solution without altering any database structures and still getting the full functionality I wanted to get.

Instantiating - The base of your webform component

hook_webform_component_info - will be your friend in defining your components base structure. Since I needed the planning which would consist out of more timespaces (could've done better here on the termonology ;) ), I added a component named "planning" and gave it a "feature": group. This way I can extend the component "planning" with the "timespace" component.

Values - Add a limit of subscriptions and other parameters for your timespace

_webform_edit_component - Makes it possible to alter the edit form of your component. Make sure you at least add an "limit_subscription" (adjust naming to your liking) field so we can check against it.

_webform_defaults_component - Will be needed to inject the defaults to your edit form, which you have created with the function here above.

Cosmetics and security - Make sure you get the checkbox and disable it when full

_webform_render_component - Arranges all the cosmetics on your webform component. So make sure you edit your timespace component to get the checkbox you want so people can check a timespace. Also, you can (ofcourse) add some additional markup to your liking.

Security, checking the limit

This is also the right place to check for your limits and disabling the checkbox when full. (see the function webform_events_check_timespace_limit($component), use that to set #disabled on your element. Also make sure you give your element the right validation, something like this, so they can't screw around by simply enabling the checkbox:

'#element_validate' => array('_webform_validate_timespace'),

Then check against the database in your validation function for the limits, this is how I got it done:

/**
 * Validation for timespace elements
 */
function _webform_validate_timespace ($element, &$form_state) {
    // If checked, make sure this timespace has some space left.
    if ($element['#value'] === 1) {
        $remaining_subscriptions = webform_events_check_timespace_limit($element['#webform_component']);
        if ($remaining_subscriptions === -1) form_error($element, t('The timespace that you\'ve chosen is already full!'));
    }
}

/** 
 * Check if the limit has been reached, returns remaining count to the limit, or -1 when full, or FALSE when no limit is set
 */
function webform_events_check_timespace_limit ($component) {
    $limit_subscriptions = $component['extra']['timespace_properties']['limit_subscriptions'];
    if (!empty($limit_subscriptions)) {
        $count_subscriptions = webform_events_get_timespace_count($component['nid'], $component['cid']);
        if ($count_subscriptions >= $limit_subscriptions) return -1;
        else return $limit_subscriptions - $count_subscriptions;
    }
    return FALSE;
}

/**
 * Get the count of the current timespace subscriptions
 */
function webform_events_get_timespace_count ($nid, $cid) {
    $select = db_query('SELECT count(*) FROM {webform_submitted_data} WHERE nid = :nid AND cid = :cid AND data = 1', array(':cid' => $cid, ':nid' => $nid));
    return $select->fetchColumn();
}

Backoffice - Exporting, table views, analysis..

For this you need the following functions, I'm not writing out these, I could go publish a book if I would:

Exporting (CSV, Excel):

Submission view (The page you get at individual submissions)

Table view

Analysis view

More help

Since I've just outlined the basics of this thing, I'd recommend you check out some good examples.

I've managed to figure this all out and fix get somewhat of the following (of course; early beta screenshots)

Submission view Submission view

Analysis view Analysis view

A simple export Export

Front-end example Front end

Table view Table

Setting up a event Setup

Your Answer

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

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