Would it be possible to create a new field type with a select list widget that is dynamically populated? This field type could then be used in Drupal Commerce under line items. More details over here: https://drupalcommerce.org/questions/30968/dynamic-field-type-line-items...

Any comments or pointers in the right direction would be appreciated?

Comments

bander2’s picture

I don't think you are going to find a module for this, it's pretty specific.

The way you get options to show up on the add to cart form is to add them to the line item type, so I would start there. Add fields to the line item for size and color. I'm not sure whether it would be better to set those as select fields (with no options because we will populate them later) or text fields. Drupal might apply some validation that will get in the way with a select field, but it is conceptually closer to what you want the final product to be, so I'd try it first.

Figure out a way to add the possible values for those fields on the product. I think you should pick whatever you think makes the admin experience nice. Maybe a simple text field with unlimited values.

Then, you need a module that implements hook_form_alter and alters the add to cart form to populate it with the possible values from the product.

That's just a general sketch of how I would tackle it. Maybe someone else has a better idea.

- Brendan

9802008’s picture

Hi Brendan

Thank you for your response and ideas - will give hook_form_alter on a select field, and see how Drupal handles new select items, and if this ties in with line items in Drupal Commerce.

Kind Regards

James

9802008’s picture

Thanks to Brendan for the direction.

Here is the solution we implemented using Drupal Commerce:

1) on product display type added 2x fields of type 'long text' (plain text):
'Colour Codes' Machine name field_colour_codes
'Ribbon Width' Machine name field_ribbon_width_options

When the client adds a new product, they add in the Colour Codes and Ribbon Width codes one line below each other eg:
col1
col2
col3

These values are later dynamically added to the drop downs for the 'line item' add to cart

2) 'Add a product line item type' (admin/commerce/config/line-items)

We created a new line item type called 'Product Size and Colour' with two additional fields:
Colour field_dynamic_colour Type: List (text)
Width field_dynamic_width Type: List (text)

For both of the above fields set:
Required field: checked
Include this field on Add to Cart forms for line items of this type: checked
Allowed values list: na|na (we will over write this later)

3) Create a custom module, add the following function to the module, enable the module

The field variables may need to change if different values where used from our example.

function MYMODULE_form_commerce_cart_add_to_cart_form_alter (&$form, &$form_state, $form_id) {
/* 	to determine the function name for hook_form_alter inspect the code which contains the 'add to cart' button
	and look for the form ID eg: id="commerce-cart-add-to-cart-form-567", we then use function name
	MODULENAME_form_commerce_cart_add_to_cart_form_alter to make changes to the form */
	
	/* Load display node to for text field containing new select list items */
	
	$nid = $form ['line_item_fields']['#entity']->data['context']['entity']['entity_id'];
	
	$n = node_load ($nid);

    /* Override the default value for line item 'dynamic_colour' select */
    
	if (isset($n->field_colour_codes['und'][0]['safe_value']) && is_string($n->field_colour_codes['und'][0]['safe_value'])) {
		
		/* $n->field_colour_codes['und'][0]['safe_value'] is a text area (on the display node) which contains a list of colour options, one option per line */
		
		$options = explode("\n", $n->field_colour_codes['und'][0]['safe_value']);
		
		/* check case where colour text area contains only one line (one item) */
		if (!(is_array ($options) )) {
			$new_options [$options] = str_replace(PHP_EOL, "", trim ($options));
		}else {
			/* build new options array for select list */
			foreach ($options as $option) {
				/* remove any new lines / white space from the colour options */
				$option = trim ($option);
				$option = str_replace ("\n", "", $option);
				$option = str_replace ("\r", "", $option);
				$option = str_replace ("\r\n", "", $option);
				$new_options [$option] = str_replace(PHP_EOL, "", trim ($option));
			}
		}
		
		$form['line_item_fields']['field_dynamic_colour']['und']['#options'] = $new_options;
	}

	 /* handy when debugging to see form structure: */
	 //drupal_set_message("<pre>".print_r($form, TRUE)."</pre>");
	
	/* Override the default value for line item 'dynamic_width' select */
	
	if (isset($n->field_ribbon_width_options['und'][0]['safe_value']) && is_string($n->field_ribbon_width_options['und'][0]['safe_value'])) {
		$new_options = array ();
		
		/* $n->field_colour_codes['und'][0]['safe_value'] is a text area which contains a list of colour options */
		
		$options = explode("\n", $n->field_ribbon_width_options['und'][0]['safe_value']);
		
		/* check case where width text area contains only one line (one item) */
		if (!(is_array ($options) )) {
			$new_options [$options] = str_replace(PHP_EOL, "", trim ($options));
		}else {
			/* build new options array for select list */
			foreach ($options as $option) {
				/* remove any new lines / white space from the colour options */
				$option = trim ($option);
				$option = str_replace ("\n", "", $option);
				$option = str_replace ("\r", "", $option);
				$option = str_replace ("\r\n", "", $option);
				$new_options [$option] = str_replace(PHP_EOL, "", trim ($option));
			}
		}
		$form['line_item_fields']['field_dynamic_width']['und']['#options'] = $new_options;
	}
	$form ['#validated'] = TRUE;
}

This code will then change the line item 'drop downs' above the 'add to cart' button with the dynamic value, per product display. As we are using a 'line item type', a customer can add different colours/widths/quantities to their cart and each item will appear as an individual line item in the cart.