You are here

function panels_ajax_flexible_edit_add in Panels 7.3

Same name and namespace in other branches
  1. 6.3 plugins/layouts/flexible/flexible.inc \panels_ajax_flexible_edit_add()

AJAX responder to add a new row, column or region to a flexible layout.

1 string reference to 'panels_ajax_flexible_edit_add'
flexible.inc in plugins/layouts/flexible/flexible.inc
Flexible layout plugin.

File

plugins/layouts/flexible/flexible.inc, line 1262
Flexible layout plugin.

Code

function panels_ajax_flexible_edit_add($handler, $id, $location = 'left') {
  ctools_include('modal');
  ctools_include('ajax');
  $settings =& $handler->display->layout_settings;
  panels_flexible_convert_settings($settings, $handler->plugins['layout']);
  if (empty($settings['items'][$id])) {
    ctools_modal_render(t('Error'), t('Invalid item id.'));
  }
  $parent =& $settings['items'][$id];
  switch ($parent['type']) {
    case 'column':
      $title = t('Add row');

      // Create the new item with defaults.
      $item = array(
        'type' => 'row',
        'contains' => 'region',
        'children' => array(),
        'parent' => $id,
      );
      break;
    case 'row':
      switch ($parent['contains']) {
        case 'region':
          $title = $location == 'left' ? t('Add region to left') : t('Add region to right');
          $item = array(
            'type' => 'region',
            'title' => '',
            'width' => 100,
            'width_type' => '%',
            'parent' => $id,
          );
          break;
        case 'column':
          $title = $location == 'left' ? t('Add column to left') : t('Add column to right');
          $item = array(
            'type' => 'column',
            'width' => 100,
            'width_type' => '%',
            'parent' => $id,
            'children' => array(),
          );
          break;
      }

      // Create the new item with defaults.
      break;
    case 'region':

      // Cannot add items to regions.
      break;
  }
  $form_state = array(
    'display' => &$handler->display,
    'parent' => &$parent,
    'item' => &$item,
    'id' => $id,
    'settings' => &$settings,
    'ajax' => TRUE,
    'title' => $title,
    'location' => $location,
  );
  $output = ctools_modal_form_wrapper('panels_flexible_add_item_form', $form_state);
  if (!empty($form_state['executed'])) {

    // If the width type changed then other nearby items will have
    // to have their widths adjusted.
    panels_edit_cache_set($handler->cache);
    $output = array();
    $css_id = isset($handler->display->css_id) ? $handler->display->css_id : '';

    // Create a renderer object so we can render our new stuff.
    $renderer = panels_flexible_create_renderer(TRUE, $css_id, array(), $settings, $handler->display, $handler->plugins['layout'], $handler);
    $content = '';
    if ($item['type'] == 'region') {
      $handler->plugins['layout']['regions'][$form_state['key']] = $item['title'];
      $content = $handler
        ->render_region($form_state['key'], array());

      // Manually add the hidden field that our region uses to store pane info.
      $content .= '<input type="hidden" name="panel[pane][' . $form_state['key'] . ']" value="" />';
    }
    else {

      // We need to make sure the left/middle/right divs exist inside this
      // so that more stuff can be added inside it as needed.
      foreach (array(
        'left',
        'middle',
        'right',
      ) as $position) {
        if (!empty($content) || $renderer->admin) {
          $content .= '<div class="' . $renderer->base[$item['type']] . '-' . $form_state['key'] . '-' . $position . '"></div>';
        }
      }
    }

    // Render the item.
    $parent_class = $renderer->base[$parent['type']] . '-' . $id;
    $item_output = panels_flexible_render_item($renderer, $item, $content, $form_state['key'], 0, 0, $item['type'] == 'row');

    // Get all the CSS necessary for the entire row (as width adjustments may
    // have cascaded).
    $css = array();
    panels_flexible_get_css_group($css, $renderer, $parent['children'], '.' . $parent_class, $item['type'], $id);
    $position = isset($renderer->positions[$form_state['key']]) ? $renderer->positions[$form_state['key']] : 'middle';

    // If there's a nearby item, add the splitter and rewrite the width
    // of the nearby item as it probably got adjusted.
    // The blocks of code in this else look very similar but are not actually
    // duplicated because the order changes based on left or right.
    switch ($position) {
      case 'left':
        if ($location == 'left') {
          $item_output .= panels_flexible_render_splitter($renderer, $form_state['key'], $form_state['sibling']);
          $output[] = ajax_command_prepend('#panels-dnd-main .' . $parent_class . '-left', $item_output);
        }
        elseif ($location == 'right') {

          // If we are adding to the right side of the left box, there is
          // a splitter that we have to remove; then we add our box normally,
          // and then add a new splitter for just our guy.
          $output[] = ajax_command_remove('panels-flexible-splitter-for-' . $renderer->base[$item['type']] . '-' . $form_state['key']);
          $item_output = panels_flexible_render_splitter($renderer, $form_state['sibling'], $form_state['key']) . $item_output;
          $item_output .= panels_flexible_render_splitter($renderer, $form_state['key'], NULL);
          $output[] = ajax_command_append('#panels-dnd-main .' . $parent_class . '-left', $item_output);
        }
        break;
      case 'right':
        if (!empty($form_state['sibling'])) {
          $item_output = panels_flexible_render_splitter($renderer, $form_state['sibling'], $form_state['key']) . $item_output;
        }
        $output[] = ajax_command_append('#panels-dnd-main .' . $parent_class . '-right', $item_output);
        break;
      case 'middle':
        if ($location == 'left') {
          if (!empty($form_state['sibling'])) {
            $item_output .= panels_flexible_render_splitter($renderer, $form_state['key'], $form_state['sibling']);
          }
          $output[] = ajax_command_prepend('#panels-dnd-main .' . $parent_class . '-middle', $item_output);
        }
        else {
          if (!empty($form_state['sibling'])) {
            $item_output = panels_flexible_render_splitter($renderer, $form_state['sibling'], $form_state['key']) . $item_output;
          }
          $output[] = ajax_command_append('#panels-dnd-main .' . $parent_class . '-middle', $item_output);
        }
        break;
    }

    // Send our fix height command.
    $output[] = array(
      'command' => 'flexible_fix_height',
    );
    if (!empty($form_state['sibling'])) {
      $sibling_width = '#panels-dnd-main .' . $renderer->base[$item['type']] . '-' . $form_state['sibling'] . '-width';
      $output[] = array(
        'command' => 'flexible_set_width',
        'selector' => $sibling_width,
        'width' => $settings['items'][$form_state['sibling']]['width'],
      );
    }
    foreach ($css as $selector => $data) {
      $output[] = ajax_command_css($selector, $data);
    }

    // Rerender our parent item links:
    $output[] = ajax_command_replace('.flexible-links-' . $id, panels_flexible_render_item_links($renderer, $id, $parent));
    $output[] = array(
      'command' => 'flexible_fix_firstlast',
      'selector' => '.' . $parent_class . '-inside',
      'base' => 'panels-flexible-' . $item['type'],
    );
    $output[] = ctools_modal_command_dismiss();
  }
  $handler->commands = $output;
}