Subversion Repositories web.creative

Rev

Blame | Last modification | View Log | Download

<?php namespace ProcessWire;

/**
 * A Page List Selector for selecting a single page
 * 
 * @property int|bool $usePageEdit
 *
 */
class InputfieldAsmSelect extends InputfieldSelectMultiple implements InputfieldHasArrayValue, InputfieldHasSortableValue {
  
  /**
   * Module info
   *
   * @return array
   *
   */
  public static function getModuleInfo() {
    return array(
      'title' => __('asmSelect', __FILE__),
      'version' => 202,
      'summary' => __('Multiple selection, progressive enhancement to select multiple', __FILE__), // Module Summary
      'permanent' => true,
    );
  }


  /**
   * Custom defined AsmSelect options
   * 
   * @var array
   * 
   */
  protected $asmOptions = array();

  /**
   * Options as specified at init() state (common to all instances)
   * 
   * @var array
   * 
   */
  protected $asmDefaults = array();

  /**
   * Construct
   * 
   */
  public function __construct() {
    $this->set('usePageEdit', 0);
    parent::__construct();
  }

  /**
   * Init
   * 
   */
  public function init() {

    // asmSelect requires jQuery UI, so we enforce it being loaded here
    $this->wire('modules')->get('JqueryCore'); // required by jQuery UI
    $this->wire('modules')->get('JqueryUI'); 

    parent::init(); 

    $this->setAsmSelectOption('sortable', true);
    $this->setAsmSelectOption('fieldset', false); 

    // an optional edit or detail link where items can be modified or viewed
    // i.e. /path/to/page/?id={value} where {value} is replaced with option value
    $this->setAsmSelectOption('editLink', '');
    $this->setAsmSelectOption('editLabel', "<i class='fa fa-fw fa-edit asmIcon'></i>"); 

    // only applicable if editLink is set. set to false if you don't want edit link to be modal
    $this->setAsmSelectOption('editLinkModal', true);

    if($this->wire('adminTheme')) {
      // replace jquery ui icon default with a font-awesome icon
      $this->setAsmSelectOption('removeLabel', "<i class='fa fa-trash'></i>");

      // replace jquery ui icon default with a font-awesome icon
      $this->setAsmSelectOption('sortLabel', "<i class='fa fa-fw fa-arrows'></i>");
    }
      
    // cancel the 'size' attribute used by select multiple
    $this->set('size', null); 
    
    $this->config->js('InputfieldAsmSelect', $this->asmOptions);
    $this->asmDefaults = $this->asmOptions;
  }

  /**
   * Set custom option for AsmSelect
   * 
   * @param string $key
   * @param string|bool $value
   * 
   */
  public function setAsmSelectOption($key, $value) {
    $this->asmOptions[$key] = $value; 
  }
  
  /**
   * Called before render()
   *
   * @param Inputfield $parent
   * @param bool $renderValueMode
   * @return bool
   *
   */
  public function renderReady(Inputfield $parent = null, $renderValueMode = false) {
    
    if(!empty($this->asmOptions['editLink'])) {
      $this->wire('modules')->get('JqueryUI')->use('modal');
    }

    if($this->hasFieldtype == 'FieldtypePage' && $this->usePageEdit && empty($this->asmOptions['editLink'])) {
      $this->setAsmSelectOption('editLink', $this->wire('config')->urls->admin . 'page/edit/?id={value}');
      $this->setAsmSelectOption('editLinkOnlySelected', false);
      $this->setAsmSelectOption('editLinkButtonSelector', ".InputfieldSubmit button.ui-button:visible");
      $this->setAsmSelectOption('editLinkModal', true);
    }

    // require javascript and css
    $class = $this->className();
    $info = self::getModuleInfo();
    $ver = $info['version'];
    $jsfile = $this->wire('config')->debug ? 'jquery.asmselect.js' : 'jquery.asmselect.min.js';

    $this->config->scripts->add($this->config->urls->$class . "asmselect/$jsfile?v=$ver");
    $this->config->styles->add($this->config->urls->$class . "$class.css?v=$ver");
    $this->config->styles->add($this->config->urls->$class . "asmselect/jquery.asmselect.css?v=$ver");
    
    // $this->config->js($this->id, $this->asmOptions); // deprecated/legacy
    
    return parent::renderReady($parent, $renderValueMode);
  }

  /**
   * Render
   * 
   * @return string
   * 
   */
  public function ___render() {
  
    // compile settings unique to this instance into a JSON encoded data-asmopt attribute
    $settings = array();
    foreach($this->asmOptions as $key => $value) {
      if(!isset($this->asmDefaults[$key]) || $this->asmDefaults[$key] != $value) {
        $settings[$key] = $value;
      }
    }
    $this->attr('data-asmopt', json_encode($settings));

    // ensure selected options are placed as last in the AsmSelect select output
    $selectedOptions = $this->attr('value'); 
    foreach($selectedOptions as $id) {
      if(!isset($this->options[$id])) continue; 
      $label = $this->options[$id]; 
      unset($this->options[$id]);   
      $this->addOption($id, $label); 
    }

    return parent::___render();
  }

  /**
   * Field config
   * 
   * @return InputfieldWrapper
   * 
   */
  public function ___getConfigInputfields() {
    $inputfields = parent::___getConfigInputfields();
    if($this->hasFieldtype != 'FieldtypePage' || !$this->hasField) return $inputfields;
    $f = $this->wire('modules')->get('InputfieldRadios');
    $f->attr('name', 'usePageEdit');
    $f->label = $this->_('Link selected pages to page editor?');
    $f->description = $this->_('When enabled, the selected label(s) will link to edit the selected page.');
    $f->addOption(0, $this->_('No'));
    $f->addOption(1, 
      $this->_('Yes') . ' ' . 
      $this->_('(in modal window)')
    );
    $f->attr('value', $this->usePageEdit);
    $f->optionColumns = 1;
    $f->collapsed = Inputfield::collapsedBlank;
    $inputfields->add($f);
    return $inputfields;
  }
}