-
Appending Language to Menu Items in Menu Admin (Drupal 7)
If you are working with a Drupal 7 menu that contains menu items across multiple languages it is a little cumbersome to see them all on the same screen. Right now we have all of the translations in place (3 nodes per piece of content), but we haven’t translated the titles yet. It’s very hard to see which items will appear for which languages. Imagine if we add 75 more menu items!
-
Allowing Users to Cancel Their Own Commerce Licenses
UPDATE: I’ve written a contrib module called Commerce License Cancel to get the ball rolling to make this a community effort. Read on if you’d like to see how I got there.
There’s been some talk in the issue queue for Commerce License Billing about needing a way for users to cancel their own licenses. Here are some pieces and parts that I’m using to achieve this. This is a work in progress and I’m really just posting here so I can provide a clean link in the issue queue. Sorry for the lack of detailed explanations; hopefully you still find this helpful.
There’s already a method to “revoke” a user license. When you revoke a license, the recurring billing should close out automatically and the role granted (if it’s a licensed role) will be taken away from the user.
The site I’m working on has just a few “membership plans” or levels that a user can purchase. For this reason, I could hardcode a few things. It’d take a LOT more work to make this stuff ready for the masses.
-
Drupal AJAX Framework with Multiple Instances of a Form
I recently encountered a unique issue with AJAX-ified form elements in Drupal. We’re building a site that shows the same form twice on a single page. I’m rendering both forms in two separate blocks; one appears at the top of the page, and one appears at the bottom.
The Select a Location field has an ajax callback to replace the the Select a Program select list with programs available at the chosen location. Initially, the top form worked as expected, but the bottom form would never get an updated Select a Program field. The AJAX callback seemed to run, but it would not replace the select list.
After fixing (by adding a unique, unchanging identifier, both forms performed as expected; changing the Select a Location dropdown updates the Select a Program dropdown, and the two forms do not interfere with one-another.
12345678910$form['field_rif_location'][LANGUAGE_NONE]['#ajax'] = array('callback' => 'mymodule_location_callback',- 'wrapper' => 'program-replace',+ 'wrapper' => 'program-replace-' . $form['#build_id'],'event' => 'change',);- $form['field_rif_program'][LANGUAGE_NONE]['#prefix'] = '<div id="program-replace">';+ $form['field_rif_program'][LANGUAGE_NONE]['#prefix'] = "<div id='program-replace-{$form['#build_id']}'>";$form['field_rif_program'][LANGUAGE_NONE]['#options'] = _mymodule_program_options($selected_location);Originally I tried using $form['#id'] because it looked cleaner, but it didn’t work correctly. The Select a Program list would update, but it’d have the same values every time, no matter which location was chosen.
-
Overriding Image Field Attribute Forms
Another quick example for you…
Here’s what the default image field form looks like, if you have enabled alt and title attributes:
One way to modify the titles and help text (descriptions) of the Alternate text and Title attributes here is to use hook_field_widget_form_alter. Here’s what your code might look like:
1234567891011121314151617181920212223/*** Implements hook_field_widget_form_alter().*/function mymodule_field_widget_form_alter(&$element, &$form_state, $context) {// see http://drupal.stackexchange.com/a/54911 for a more "universal approach"if (isset($element['#field_name']) && $element['#field_name'] == 'field_portfolio_images') {foreach (element_children($element) as $delta) {$element[$delta]['#process'][] = 'mymodule_field_widget_process_field_portfolio_image';}}}/*** Process callback for the field_portfolio_image title attribute form changes*/function mymodule_field_widget_process_field_portfolio_image($element, &$form_state, $form) {if ($element['title']['#access']) {$element['title']['#title'] = t('My New title');$element['title']['#description'] = t('Here are my custom instructions.');}return $element;}Here’s the result:
-
Quick Tip: Adding a Reset button to a Drupal form
Using hook_form_alter or hook_form_FORM_ID_alter one can easily add a “Reset” button to a Drupal form.
In this example we’re actually trying to reset anything the user typed after the form loaded. This will not remove the default values.
Here’s a simple example (Drupal 6)
1234567891011121314/*** Implementation of hook_form_alter().*/function mymodule_form_alter(&$form, &$form_state, $form_id) {switch ($form_id) {case 'myform':$form['buttons']['reset_button'] = array('#type' => 'markup','#value' => '<input class="form-button" type="reset" value="Reset">','#weight' => 2000,);break;}}It may not be appropriate for you to put your new reset element into the buttons array. Use dpm() (part of the Devel module) to show what $form looks like. If you don’t understand this, and the code above isn’t working for you, you may try $form[‘reset_button’] = array….
Adjust the value of #weight to move the button around the form. dpm($form) will show you weights (if any) of existing elements so you can make educated decisions about the weight of your new field.
One last note about the ‘#type’ => ‘markup’ line: this is not a requirement, but I like to include it for clarity.
UPDATE:
Here’s what the field might look like for Drupal 7:
1234$form['reset'] = array('#type' => 'markup','#markup' => '<input class="form-submit" type="reset" value="Reset">',); -
Drupal Commerce Add To Cart Form Tweaks / Registration Improvements
In this example I’m showing how to improve the Add to Cart button for Drupal Commerce products to show differently based on whether or not users have already purchased a product, or whether the product is already in their cart.
I’m currently working on a site where users are registering for “programs,” which are synonymous with classes, courses, etc. I’m using the following modules (among others) in this example:
- Drupal Commerce
- Registration
- Commerce Registration
Please understand that when a user registers for a course, they are actually purchasing a product that has a referenced Registration entity.
-
Views Exposed Filter: Terms for current language only
I’ve been working on a multilingual site that has a product finder. We have 3 exposed filters that allow a user to select an Activity, IP Category, or Industry. All of these filters are Taxonomy Term filters. Some of the terms throughout those vocabularies have a specific language set, and should only show when that language is active.
The first step is to make sure the output (Views results) only shows products where the node language matches the current language. This is easy using the built in Node translation: Language = Current user’s language filter.
-
Proximity by City or Zip Code in Drupal 6 with Location and Views
The location module for Drupal 6 is a robust module. On most projects, it gives us 100 percent of what we need. Proximity searching based on zip code is built-in and fairly painless to setup. I’ve recently been tasked to also allow proximity searching based on City. As you might imagine, the request is very similar. Both methods require the use of latitude and longitude (decimals). The difference is that instead of querying the database for latitude and longitude based on zip code (it’s usually termed postal code in Views, Location, etc.), we’re asking for the coordinates of a city. You’ll find that many cities have multiple zip codes, each of which is a row in the location module’s zipcodes database table. In this example, I’m not giving a real honest attempt at solving this issue, but rather I just return the first coordinate that matches the city.
-
Webform for Campaign Monitor
Webform is an amazing module. Thankfully, you can extend it to make it even more helpful. We’ve had a lot of clients that offer a “Join Our Mailing List” type of functionality on their sites. These forms are typically one or two fields (email and name, usually) and are for anonymous users. We use Campaign Monitor for most clients.
There is a Campaign Monitor module, but I prefer the following method, for various reasons.
-
Disable Specific States in Ubercart
Here’s a quick example that illustrates how to remove a few State/Province options from the billing and shipping panes of the Ubercart checkout form, as well as the order edit/create form. Please understand there are other ways to do this (like altering the united_states_840_1.cif file and re-importing). The hook_form_alter() method seems less permanent, so I favor it.
123456789101112131415161718192021/*** Implementation of hook_form_alter().*/function mymodule_form_alter(&$form, &$form_state, $form_id) {switch ($form_id) {case 'uc_cart_checkout_form':// Disable some State/Province values in the checkout formunset($form['panes']['delivery']['delivery_zone']['#options'][21]); // Hawaiiunset($form['panes']['delivery']['delivery_zone']['#options'][49]); // Oregonunset($form['panes']['billing']['billing_zone']['#options'][21]); // Hawaiiunset($form['panes']['billing']['billing_zone']['#options'][49]); // Oregonbreak;case 'uc_order_edit_form':// Disable some State/Province values in the order edit/create formunset($form['ship_to']['delivery_zone']['#options'][21]); // Hawaiiunset($form['ship_to']['delivery_zone']['#options'][49]); // Oregonunset($form['bill_to']['billing_zone']['#options'][21]); // Hawaiiunset($form['bill_to']['billing_zone']['#options'][49]); // Oregonbreak;}}