Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
214 lines (174 sloc) 6.88 KB
<?php namespace ProcessWire;
/**
* ProcessWire InputfieldDependentCheckboxes
*
* Handles the display of dependent Checkboxes.
*
* This file is licensed under the MIT license
* https://processwire.com/about/license/mit/
*
* ProcessWire 3.x, Copyright 2016 by gebeer
* https://processwire.com
*
*/
class InputfieldDependentCheckboxes extends InputfieldCheckboxes implements Module {
/**
* getModuleInfo is a module required by all modules to tell ProcessWire about them
*
* @return array
*
*/
public static function getModuleInfo() {
return array(
'title' => 'InputfieldDependentCheckboxes',
'version' => 100,
'summary' => 'Handles the display of dependent Checkboxes',
'href' => '',
'autoload' => 'template-admin',
'requires' => array(
'ProcessWire>=3.0.0'
)
);
}
/**
* Set defaults
*
*/
public function __construct() {
parent::__construct();
$this->set('targetField', '');
$this->set('targetFieldTemplate', '');
}
/**
* Hook this and return an array with whatever extended attributes you need.
*
*/
public function ___extendAttributes($id)
{
/**
* Either hook this method to do what you want or implement things directly if this
* is the only use of this Inputfield.
* For your example you'd grab the fields you want from your page and put into data
* attributes...
*/
$atts = array();
$targets = array();
$selector = "template={$this->targetFieldTemplate}, {$this->name}={$id}";
$deps = wire('pages')->find($selector);
foreach ($deps as $d) {
$targets[] = $d->id;
}
$atts['data-idcbtargets'] = json_encode($targets);
return $atts;
}
public function ___render()
{
// set template name of target field
$targetField = ($this->fields->get($this->targetField));
$targetFieldTemplate = $this->templates->get($targetField->data['template_id']);
$this->set('targetFieldTemplate', $targetFieldTemplate->name);
// build JS config data array
$idcbData = array();
$idcbData[$this->name]["idcbActorName"] = $this->name;
$idcbData[$this->name]["idcbTargetName"] = $this->targetField;
// merge config data with that from other fields
if($this->config->js("idcbData")) {
$idcbData = array_merge($idcbData, json_decode($this->config->js("idcbData"), true));
}
$this->config->js("idcbData", json_encode($idcbData));
$this->checkDefaultValue();
$out = '';
$table = null;
$columns = (int) $this->optionColumns;
$inline = $columns === 1 || $columns > 10;
$liAttr = '';
$ulClass = '';
$entityEncode = $this->getSetting('entityEncodeText') === false ? false : true;
if($this->table) {
/** @var MarkupAdminDataTable $table */
$table = $this->modules->get("MarkupAdminDataTable");
$table->setEncodeEntities(false);
$table->addClass('pw-no-select');
if($this->thead) $table->headerRow(explode('|', htmlspecialchars($this->thead, ENT_QUOTES, 'UTF-8')));
} else if($columns) {
if($inline) {
$ulClass = 'InputfieldCheckboxesFloated';
} else {
$liWidth = round(100 / $columns)-1; // 1% padding-right added from stylesheet
$liAttr = " style='width: {$liWidth}%;'";
$ulClass = 'InputfieldCheckboxesColumns';
}
$classes = InputfieldWrapper::getClasses();
$ulClass .= " " . $classes['list_clearfix'];
} else {
$ulClass = 'InputfieldCheckboxesStacked';
}
if(!$table) $out = "<ul class='$ulClass'>";
foreach($this->getOptions() as $key => $value) {
$checked = '';
if($this->isOptionSelected($key)) $checked = " checked='checked'";
$id = $this->id . "_" . $this->wire('sanitizer')->name($key);
$attrs = $this->getOptionAttributes($key);
$disabled = empty($attrs['disabled']) ? '' : " disabled='disabled'";
unset($attrs['checked'], $attrs['selected'], $attrs['disabled']);
// get custom data-attribute
$extra_attrs = $this->extendAttributes($key);
$attrs = array_merge($attrs, $extra_attrs);
$attrs = $this->getOptionAttributesString($attrs);
if($attrs) $attrs = ' ' . $attrs;
if($entityEncode) $value = $this->entityEncode($value, true);
$input =
"<label$attrs>" .
"<input$checked$disabled " .
"type='checkbox' " .
"name='{$this->name}[]' " .
"id='$id' " .
"value='" . htmlspecialchars($key, ENT_QUOTES, 'UTF-8') . "' />";
if($table) {
$value = explode("|", nl2br($value));
$value[0] = "$input<span class='pw-no-select'>$value[0]</span></label>";
$table->row($value);
} else {
$out .= "<li$liAttr>$input<span class='pw-no-select'>$value</span></label></li>";
}
}
if($table) $out .= $table->render();
else $out .= "</ul>";
return $out;
}
/**
* Get all Inputfields of type checkbox that can be chosen as target field
*
* @return array
*
*/
public function getInputfieldCheckboxes() {
$array = array();
$fields = $this->wire('fields');
foreach($fields as $field) {
if(($field->inputfield != 'InputfieldCheckboxes' && $field->inputfield != 'InputfieldDependentCheckboxes') || $this->pages->get($field->parent_id)->template->name == 'admin' || $field->name == $this->name) continue;
$name = $field->name;
$label = $name;
$array[$field->name] = array(
'label' => $label,
'single' => $label === $name,
);
}
return $array;
}
public function ___getConfigInputfields()
{
$inputfields = parent::___getConfigInputfields();
$modules = $this->wire('modules');
$options = $this->getInputfieldCheckboxes();
$f = $modules->get('InputfieldSelect');
$f->attr('name', 'targetField');
$f->set('label', $this->_('Choose the target checkboxes field'));
$f->set('description', $this->_('The field that has checkboxes which depend on this field\'s checkboxes'));
// $f->set('notes', $this->_('Types indicated with an asterisk are for multiple field selection.'));
foreach ($options as $fieldName => $prop) $f->addOption($fieldName, $prop['label']);
$f->attr('value', $this->targetField);
$inputfields->add($f);
return $inputfields;
}
}