Add inline widget to product display I am trying to integrate our Drupal 7 Commerce install with Digital River's where-to-buy widget.

All I need to do is add a little JS to the product page, with a script variable set to the product sku.  On page load, this inline JS runs and adds a button that when clicked will pop-up a lightbox with where-to-buy information.  This script has a variable that requires a SKU to be entered.  If I add the snippet to my node-template it works fine.

HOWEVER, I have several products on each product display, and I have 2 product attributes that can be selected.  This, of course, refreshes the node/entity field values in my page, like the title, a product image and so forth.  This will not refresh the sku parameter of my javascript snippet though, so my WTB button does not update.  IE, if I did something like this:

&lt;script type="text/javascript"&gt;
          pswtb.loader.show({
            widgetConfigurationId: "3a4acc53-216e-48da-8e92-bfaeb58168a7", 
            sku: "US_&lt;?php print trim($content['product:sku']['#markup']) ?&gt;" 
          }); 
        &lt;/script&gt;


I discovered that it would initially load but the product:sku wouldn't change as I selected a new attribute.

So, I also discovered that my values would update if they were displayed via the render() function.  So, if I just did this:

&lt;?php print render($content['product:sku']) ?&gt;


I would get an element that updates 'properly' when a product attribute is selected.  It does, however come with a lot of div's wrapping it, so I can't use it as a parameter in my script,and I didn't want to override the 'sku' field template because I need that sku elsewhere on the page, and even overriding the template, I would still get a wrapper around it.

Ok, so my next attempt was to create a 'virtual' field, using the virtual_field module.  This just lets you have a dummy field that doesn't get stored anywhere but still lets you create custom templates and specify display formatters.  I created a dummy field that just contains the product sku.

Using this, I created a custom field template (field--field-product-wtb.tpl.php) for this virtual field like so:

this will update: &lt;?php print render($item); ?&gt;
but this gets stripped out:
&lt;script type="text/javascript"&gt;
   pswtb.loader.show({
     widgetConfigurationId: "3a4acc53-216e-48da-8e92-bfaeb58168a7", 
     sku: "US_&lt;?php print render($item); ?&gt;" 
   }); 
&lt;/script&gt;


And then in my node template, I just do this:

&lt;?php print render($content['product:field_product_wtb']) ?&gt;


It works on initial load, and when a product attribute is selected, the sku does change (the 'this will update' part) but the entire script tag gets stripped out and my button disappears.  I guess because it gets filtered via some xss protection, but I haven't tracked it down.  As near as I can tell, this is because when content on a page is updated via ajax, the HTML returned from a tpl file is sanitized and things like script tags are filtered out.

Now I'm at a loss as to how to get this to work.
You could probably do something like this:


Add hidden form element with product SKU
Read the SKU in a JavaScript Drupal.behavior


The key is making the SKU available in the DOM and using Drupal.behaviors to read it, as they run / are reattached after the AJAX form update.

i.e: 

/**
 * Implements hook_form_FORM_ID_alter
 */
function MYMODULE_form_commerce_cart_add_to_cart_form_alter(&amp;$form, &amp;$form_state){

  // Add a hidden SKU element to the add to cart form
  if (isset($form_state['default_product']-&gt;sku)){
    $form['product_sku'] = array(
      '#type' =&gt; 'hidden',
      '#value' =&gt; $form_state['default_product']-&gt;sku,
    );
  }

}


Then in your JS file

(function ($) {

  Drupal.behaviors.pswtb_loader = {
    attach: function (context, settings) {
     if($('input[name=product_sku]').length &gt; 0){
       pswtb.loader.show({
         widgetConfigurationId: "3a4acc53-216e-48da-8e92-bfaeb58168a7", 
         sku: "US_" +  $('input[name=product_sku]').val();
       }); 
     }
    }
  };

})(jQuery);