Upgrade Your Drupal Skills

We trained 1,000+ Drupal Developers over the last decade.

See Advanced Courses NAH, I know Enough
Aug 19 2013
Aug 19

The taxation rules that come with Drupal Commerce out of the box calculate VAT or sales tax for each line item without any conditions, so every item in the order is taxed. This works for many situations but if you have items which need to be tax exempt you're in trouble. But there is a relatively painless way around it using some rules and fields.

To start with create a new field on your product entity called Tax Exempt. Set it to be a Boolean, single on/off checkbox.

Create a field called Tax Exempt

Make sure the default value is not checked, we don't want things to be tax exempt by default. Also remember to hide this field in the Manage Display settings.

Now we have to set up the taxation rules to handle this. Make sure the Tax and Tax UI modules are turned on. Two tax types will be enabled by default: VAT and Sales tax. We're going to start by setting up a generic sales tax. Right now we're going to charge this sales tax for everything. Realistically in the United States, you need to only collect sales tax in the state you're doing business in. For more on this topic check out another post in our Drupal Commerce Tax Series, Conditional State Sales Tax.

Create a new tax, we'll call it Generic Sales Tax. Give it a rate of .07, this translates to 7%.

Create a new generic tax rate

We can click configure component and add our conditions. First we need to bring the Tax Exempt field into scope. In Rules you have to check for a field before you can query it. Our first rule will be to get to the Product entity.

Condition: Entity has field.

Data selector: commerce-line-item
Field: commerce_product

Rule condition: entity has field commerce-product

This gives us access to the product through rules. Our next rule will give us access to the Tax Exempt field.

Condition: Entity has field

Data selector: commerce-line-item:commerce-product
Field: field_tax_exempt (or whatever you called your field)

Rule condition: entity has field Tax Exempt

Now that we have access to our Tax Exempt field we can make sure tax exempt items are not taxed.

Condition: Data to compare

Data selector: commerce-line-item:commerce-product:field-tax-exempt
Operator: Equals
Data value: (checked)
What this does is create a NOT Data comparison. So as long as the product does not have the Tax Exempt field checked tax will be calculated.

Rule condition: field Tax Exempt is not checked

With these conditions taken into account when calculating sales tax from a line item creating tax exempt products is as easy as checking a box. Here are all of the tax exempt conditions together.

All conditions for exempting products from taxation

For information on how to handle sales tax by state see our article Handling Sales Tax Based on Order Address with Drupal Commerce.

Feb 28 2013
Feb 28

Episode Number: 


The Drupal 7 jQuery SelectBox module is a simple module that makes HTML select boxes easier to style. It replaces the HTML form select element with easier to style HTML markup.

In this episode you will learn:

  • How to download and install the jQuery SelectBox module
  • What the jQuery SelectBox module is doing in the background to make the select boxes on the site continue to work correctly

Thanks to Drupalize.me for sponsoring this episode.

DDoD Video: 

Feb 07 2013
Feb 07

Episode Number: 


The Drupal 7 Conditional Fields module makes it easy to build dynamic and complex forms with Drupal 7 Fields. Any Drupal entity that has fields can pretty much be built into a dynamic and conditional form. The Conditional Fields module essentially lets you set conditions for how specific fields act based on another dependent field on the form. The simplest example is that this module can hide or show a field based on the value of another field. If you are still confused at what this module can do, watch the video to find out more!

In this episode you will learn:

  • The basic Drupal conditional fields terminology
  • How to hide and show Drupal fields based on the values of other form fields
  • How to get the module to work with nested field conditions

Thanks to Drupalize.me for sponsoring this episode!

DDoD Video: 

Feb 13 2012
Feb 13

Need a simpler UI to let administrators manage fields? We recently created a new contributed module called Simple Field. This module simplifies the UI for creating fields and adding them to content types and entities. It also provides granular permissions, so you're not stuck with a single catch-all permission for managing fields. You can see a demo of the module in action at simplefield-demo.ewdev.ca (login: demo/demo).

Why do I need Simple Field?

Imagine you're creating a Drupal site and you want to let your users create fields, but you don't want to give them the 'Manage Fields UI'. The Manage Fields UI is very powerful, but it also provides a lot of settings and configuration that can be confusing for non-technical users. Giving users permission to manage fields allows them to delete fields, and you might want more granular permissions to prevent users from deleting data on the site.

Simple Field Types

The Simple Field module includes a set of Field Types. Instead of a long list of cryptic types which can intimidate non-technical users, field types are things like 'Multiple Choice' or 'Yes/No'.

List of built-in Simple Field types

Simple Field types include a core field type, plus some field widget settings. For example, rather than choosing 'Boolean', users can choose 'Yes/No', which is a Boolean field with pre-configured options for yes or no. The user adding the Simple Field will not see the 'Options' field and won't be able to change the option values.

Of course, we can't anticipate all the Simple Field types that other sites will need, so the module is extensible and allows developers to define additional Simple Field types in code.

Creating Fields is as Easy as Pie

With pre-defined field settings, creating fields becomes much easier for users. Users just need to enter the label, whether the field is required, and help text. Some Simple Field types, such as 'Multiple Choice', have an options field, but that's it.

Creating a 'Yes or No' Simple Field

Attaching Simple Fields to Content Types

You can enable Simple Field on a per content type basis, which provides a nice UI for managing the Simple Fields for that content type. The module uses modals to keep the UI concise. You can create and attach files from the same page.

UI for attaching Simple Fields to a Customer content type

An Alternative UI for Creating Fields

The Simple Field module provides an alternative UI for creating fields, which only exposes some of the field settings to users. Other administrative roles can still be given access to all of the more advanced settings through the Manage Fields UI. The fields are stored in the database in exactly the same way, so everything like Views integration still works. All settings and weights are synchronized between the two interfaces.

Simple Fields appear in the Manage Fields UI

Granular Permissions for Fields

Permissions for the Simple Field module are very granular. You can control which roles have access to which field types and whether users can delete fields or remove fields from a particular content type or entity. For example, you can configure your site so that the users with the 'service rep' role can add Yes/No, Multiple Choice, and Short Answer simple fields to the customer content type. This way, service reps can add fields on-the-fly if they realize that collecting a particular piece of information from customers is valuable.

Simple Field Permissions

Adding Simple Fields to Entities: Fields as Content

While the Simple Field module can be used to add fields to bundles (i.e. content types) it can also be used for adding fields to entities. This opens up a ton of new possibilities. For example, you can create a survey entity and allow users to attach fields to each individual entity. Used this way, the Simple Field module is kind of like an alternative to the Webform module, allowing you to add fields to pieces of content.

Presentation at DrupalCamp NJ

Alex Dergachev presented a case study at Drupal Camp NJ on February 4, 2012 and included a demo of the Simple Field module. The case study shows our original use case for the module in the context of a Drupal project for a university.


For information on creating new types, among other things, take a look at the documentation.

Nov 04 2011
Nov 04

When working on a new Drupal 7 site I noticed it was missing a feature from the old D6 CCK days that allows you to remove a single item from a field that has unlimited values. Unfortunately, this is not built into Drupal 7's fields, and though there are a couple of threads on drupal discussing this issue, it is considered a feature request for D8 by the core developers.

In a D7 unlimited field, you 'delete' an item by emptying all of its values and saving the form. This works fine in practice but is highly unintuitive for a standard Drupal user (ie: clients) so I set out to make a simple hack-module.

This module creates a configuration page with a list of all your site's unlimited fields, allowing you to select which fields you want to apply this module to.

Functionally, the new remove button just hides the field and uses some brute force jQuery to empty the field's values. I'm not claiming it's pretty, but it gets the job done for my purposes.

Here is a link for the module.

And so there are no surprises, I've included the code below. My plan is to continue working on this by making it more drupal-like, and contributing it as real Drupal module.

Edit: Added module as a sandbox project on drupal.org here.

Module Code /* * hook_menu() */ function unlimitedfield_remove_menu(){ $items = array(); $items['admin/config/unlimitedfield_remove'] = array( 'title' => t('UnlimitedField Remove Settings'), 'page callback' => 'drupal_get_form', 'page arguments' => array('unlimitedfield_remove_admin_form'), 'access arguments' => array('administer modules'), 'type' => MENU_NORMAL_ITEM, ); return $items; } /* * hook_field_widget_form_alter() */ function unlimitedfield_remove_field_widget_form_alter(&$element, &$form_state, $context) { // some elements are buried, so we have to look for them $found = false; if(isset($element['#field_name'])){ $details = $element; $found = true; } else { // look deeper foreach($element as $key => $value){ if(isset($value['#field_name'])){ $found = true; $details = $value; break; } } } // make sure we want to apply changes to this field if($found && variable_get('unlimitedfield_remove_'.$details['#field_name'],0) == 1) { // add our js drupal_add_js(drupal_get_path('module','unlimitedfield_remove').'/unlimitedfield_remove.js'); // add our remove link $remove_button = array( '#name' => $details['#field_name'].'_'.$details['#delta'].'_remove_button', '#type' => 'markup', '#value' => t('Remove'), '#validate' => array(), '#markup' => '


', '#weight' => -99, ); $element['remove_button'] = $remove_button; } } /* * Admin settings form */ function unlimitedfield_remove_admin_form($form, &$form_state){ $fields = field_info_fields(); $form['description'] = array( '#markup' => '

Check each unlimited field you would like to add a Remove button to.

', ); foreach($fields as $key => $field){ if($field['cardinality'] == -1){ $form[$key] = array( '#type' => 'checkbox', '#title' => $key, '#default_value' => variable_get('unlimitedfield_remove_'.$key, 0), ); } } $form['submit'] = array( '#type' => 'submit', '#value' => t('Save Settings'), ); return $form; } /* * Submit functon for our settings form */ function unlimitedfield_remove_admin_form_submit($form, &$form_state){ foreach($form_state['values'] as $key => $value){ if($value == 1 || $value == 0){ variable_set('unlimitedfield_remove_'.$key, $value); } } drupal_set_message('Your settings have been saved.', 'status'); } jQuery('document').ready(function(){ jQuery('div.form-wrapper').delegate('.unlimitedfield_remove_button', 'click', function(){ // get parent table row var row = jQuery(this).closest('td').parent('tr'); // hide and empty values jQuery(row).hide(); jQuery(row).find('input').val(''); jQuery(row).find('select').val(''); jQuery(row).find('textarea').text(''); jQuery(row).find('checkbox').removeAttr('checked'); jQuery(row).find('options').removeAttr('selected'); // fix table row classes var table_id = jQuery(row).parent('tbody').parent('table').attr('id'); jQuery('#'+table_id+' tr.draggable:visible').each(function(index, element){ jQuery(element).removeClass('odd').removeClass('even'); if((index%2) == 0){ jQuery(element).addClass('odd'); } else { jQuery(element).addClass('even'); } }); }); });

About Drupal Sun

Drupal Sun is an Evolving Web project. It allows you to:

  • Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
  • Facet based on tags, author, or feed
  • Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
  • View the entire article text inline, or in the context of the site where it was created

See the blog post at Evolving Web

Evolving Web