I would like some help to style a Ctools modal pop-up. I have added a theme and views template but it has no effect so it looks as though I am missing some fundamental point.

Here is a picture of the default style and the styled box, as per the article above.

You can see the pop-up in its current state here. Just click the link on the single Views record.

I am moving into an area in which I am inexperienced so I hope someone can give some guidance as I think a fully styled pop-up is a useful web design asset !

One specific point that might explain the issue here relates to the placement of the code in the function hook_preprocess_views_view_fields - does this go in the module or a theme file ?

I apologise for the length of this post but I thought it might help to give full details of the code.

Background
This post concluded with a post by Supriya which opened a Ctools modal pop-up. Her work used this article, which moves from the default Ctools style to custom styling - i.e. setting the size and background color of the box.

Here is the code....

../sites/all/modules

mm196.info

name = mm196
description = Modal pop-up.
core = 7.x

mm196.module

<?php

function mm196_menu()
{
  $items['modal/%ctools_js/%'] = array(
      'title' => 'Title of Modal',
      'page arguments' => array(1,2), //Pass whether to use AJAX or JS and the nid
      'page callback' => '_custom_page_callback', //User defined function called when the link is clicked
      'access callback' => TRUE,
      'type' => MENU_NORMAL_ITEM, //Internal path menu, not a menu tab
  );
  return $items;
}
function _custom_page_callback($js = NULL, $nid = NULL)
{
  if($nid == NULL)
   return 'No content to display.';
   
  //Include ctools iff path contains 'nojs' to work, else render page normally
  if($js)
  {
    ctools_include('modal');
    ctools_include('ajax');
    ctools_modal_add_js(); //Default CTools JS. This is a must if custom javascript is not available.
  }
  
  //Load the node object
  $node = node_load($nid);
  
  //Render content in 'Teaser' view mode
  $nodeContent = node_view($node, 'teaser', NULL); //To prevent strict warning that only variables can be passed by reference
  $contents = render($nodeContent);
  return ctools_modal_render($node->title, $contents) ;
}

/**
 * inside happy.module
 * Implements hook_views_pre_render()
 */
function mm196_views_pre_render(&$views) {
  // The View name I set up prior is "view1"
  if ($views->name == 'view1') {
      // Include the CTools tools that we need.
      ctools_include('ajax');
      ctools_include('modal');

      // Add CTools' javascript to the page.
      ctools_modal_add_js();

      // Create our own javascript that will be used to theme a modal.
      $mm196_style = array(
        'mm196-modal-style' => array(
          'modalSize' => array(
            'type' => 'fixed',
            'width' => 600,
            'height' => 240,
            'addWidth' => 10,
            'addHeight' => 10,
            'contentRight' => 0,
            'contentBottom' => 0,
          ),
          'modalOptions' => array(
            'opacity' => .6,
            'background-color' => '#684C31',
          ),
          'animation' => 'fadeIn',
          'modalTheme' => 'mm196_modal',
          // Customize the AJAX throbber like so:
          // This function assumes the images are inside the module directory's "images"
          // directory:
          // ctools_image_path($image, $module = 'ctools', $dir = 'images')
          'throbber' => theme('image', array('path' => ctools_image_path('ajax-loader.gif', 'mm196'), 'alt' => t('Loading...'), 'title' => t('Loading'))),
          'closeImage' => theme('image', array('path' => ctools_image_path('modal-close.png', 'mm196'), 'alt' => t('Close window'), 'title' => t('Close window'))),
        ),
      );
    // Add the settings array defined above to Drupal 7's JS settings:
    drupal_add_js($mm196_style, 'setting');
    // The function below assumes the happy.js file resides in [module_dir]/js
    ctools_add_js('mm196', 'mm196');
    // The function below assumes the happy.css file resides in [module_dir]/css
    ctools_add_css('mm196', 'mm196');
  }
}


/**
* Implements hook_theme().
*/
function mm196_theme() {
  return array(
    'views_view_fields__mm196' => array(
      'variables' => array('view' => NULL, 'options' => NULL, 'row' => NULL),
      'template' => 'views-view-fields--mm196',
      'base hook' => 'views_view_fields',
      // I am defining another directory inside the happy module dir called 'theme'
      'path' => drupal_get_path('module', 'mm196') . '/theme',
    ),
  );
}

/*
 * Implements hook_preprocess_view()
 */
function mm196_preprocess_views_view_fields(&$vars) {
  if ($vars['view']->name == 'view1') {
    // Include the CTools tools that we need.
    ctools_include('ajax');
    ctools_include('modal');
    // The view has two fields, title (not linked and no styles added), and NID (again,
    // no style added. They are available here as $vars['fields']->title and 
    // $vars['fields']->nid.
    $name = $vars['fields']['title']->content;
    // Create a path for the url that is like our hook_menu() declaration above.
    $href = 'mm196/nojs/' . $vars['fields']['nid']->content;
    // Here's the ctools function that generates the trigger inside the link
    // ctools_modal_text_button($text, $dest, $alt, $class = '')
    // http://api.drupalize.me/api/drupal/function/ctools_modal_text_button/7
    // IMPORTANT: Include ctools-modal-[your declared style name] as a class so 
    // Ctools knows what Javascript settings to use in generating the modal:
    $vars['ctools_link'] = ctools_modal_text_button($name, $href, t('View node content for @name', array('@name' => $name)), 'ctools-modal-mm196-modal-style');
  }
}

../sites/all/modules/mm196/theme

views-view-fields.tpl.php

/**
 * @file
 * Default simple view template to all the fields as a row.
 *
 * - $view: The view in use.
 * - $fields: an array of $field objects. Each one contains:
 *   - $field->content: The output of the field.
 *   - $field->raw: The raw data for the field, if it exists. This is NOT output safe.
 *   - $field->class: The safe class id to use.
 *   - $field->handler: The Views field handler object controlling this field. Do not use
 *     var_export to dump this object, as it can't handle the recursion.
 *   - $field->inline: Whether or not the field should be inline.
 *   - $field->inline_html: either div or span based on the above flag.
 *   - $field->wrapper_prefix: A complete wrapper containing the inline_html to use.
 *   - $field->wrapper_suffix: The closing tag for the wrapper.
 *   - $field->separator: an optional separator that may appear before a field.
 *   - $field->label: The wrap label text to use.
 *   - $field->label_html: The full HTML of the label to use including
 *     configured element type.
 * - $row: The raw result object from the query, with all data it fetched.
 *
 * @ingroup views_templates
 */
?>
<?php foreach ($fields as $id => $field): ?>
  <?php if (!empty($field->separator)): ?>
    <?php print $field->separator; ?>
  <?php endif; ?>

  <?php print $field->wrapper_prefix; ?>
    <?php print $field->label_html; ?>
    <?php print $field->content; ?>
  <?php print $field->wrapper_suffix; ?>
  <?php print $ctools_link; ?>
<?php endforeach; ?>

../sites/all/modules/mm196/js

mm196.js

<?php
/**
* Provide the HTML to create the modal dialog.
*/
(function ($) {
Drupal.theme.prototype.happy_modal = function () {
  var html = '';
  html += '<div id="ctools-modal" class="popups-box">';
  html += '  <div class="ctools-modal-content ctools-modal-happy-modal-content">';
  html += '    <span class="popups-close"><a class="close" href="#">' + Drupal.CTools.Modal.currentSettings.closeImage + '</a></span>';
  html += '    <div class="modal-scroll"><div id="modal-content" class="modal-content popups-body"></div></div>';
  html += '  </div>';
  html += '</div>';
  return html;
}
})(jQuery);

If you got this far, thanks for reading to the end of the post !

Comments

dimaboychev’s picture

you are passing 'ctools-modal-mm196-modal-style' as the 5th parameter, it should be the 4th. Check the function once again to make sure I am right.

Also, since the 'ctools_modal_text_button' function is declared in an inc file of ctools module, AFAIK, you should be getting an "undefined function" error when calling it from you custom module? But anyway, if that's the case you will know.

This is the line of code I am referring to:

$vars['ctools_link'] = ctools_modal_text_button($name, $href, t('View node content for @name', array('@name' => $name)), 'ctools-modal-mm196-modal-style');

also in js file you have

Drupal.theme.prototype.happy_modal = function () {

it should be

Drupal.theme.prototype.mm196_modal= function () {

this comes from the $mm196_style array, the 'modalTheme' key.

peterk900’s picture

I'd put this on the 'back-burner' but your help encourages me to re-visit. All your points seem to correctly identify errors - the array key sure should be 4 not 5 and the other is careless cut and paste. Thanks again for taking the trouble to read through this long post.

Chandraveer Singh’s picture

There are some additional code required for rendering custom field in the view.

$newfield = new stdClass();
        $newfield->content = ctools_modal_text_button($name, $href, t('View node content for @name', array('@name' => $name)), 'ctools-modal-custom-modal-style');
        $newfield->label_html = '';
        $newfield->wrapper_prefix = '';
        $newfield->wrapper_suffix = '';
        $vars['fields']['ctools_link'] = $newfield;
peterk900’s picture

Please can you indicate where the code snippet you suggest should be inserted into my sample code. Sorry if I'm being dense on this but I'm not sure what you are adding/replacing.

I have investigated dimaboychev's points. His point about the index:

you are passing 'ctools-modal-mm196-modal-style' as the 5th parameter, it should be the 4th. Check the function once again to make sure I am right

is incorrect - it should be position 5. His other point is very valid but amending it does not solve the problem.

Chandraveer Singh’s picture

I have created the new field object $newfield, that have complete field info with "content", "label_html", "wrapper_prefix" and "wrapper_suffix". these are required when we create a field for render. you just need to replace following with my code:
$vars['ctools_link'] = ctools_modal_text_button($name, $href, t('View node content for @name', array('@name' => $name)), 'ctools-modal-mm196-modal-style');

peterk900’s picture

However it has no effect - the pop-up is as it has always been. And this is understandable as neither of the functions mm196_theme() or
mm196_preprocess_views_view_fields(&$vars) is firing. This is shown by the absence of the watchdog entries is the messages log.

I am now of the view that neither of these functions should be in the module but in a either a template file or in template.php . My theming knowledge is really scrappy at present, but I'm taking steps to improve this - but in the meantime can someone confirm if the location of these functions is why none of the Javascript and other magic that should style the pop-up just isn't working ?