├── _config.php ├── _config └── config.yml ├── templates ├── DropdownAttributesField.ss ├── CheckboxSetField.ss └── BootstrapCheckboxSetField.ss ├── .editorconfig ├── composer.json ├── code ├── DropdownAttributesField.php └── FormFieldAttributesExtension.php └── README.md /_config.php: -------------------------------------------------------------------------------- 1 | 2 | <% loop $Options %> 3 | 4 | <% end_loop %> 5 | 6 | -------------------------------------------------------------------------------- /templates/CheckboxSetField.ss: -------------------------------------------------------------------------------- 1 | 13 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # For more information about the properties used in this file, 2 | # please see the EditorConfig documentation: 3 | # http://editorconfig.org 4 | 5 | [*] 6 | charset = utf-8 7 | end_of_line = lf 8 | indent_size = 4 9 | indent_style = space 10 | insert_final_newline = true 11 | trim_trailing_whitespace = true 12 | 13 | [{*.yml,package.json}] 14 | indent_size = 2 15 | 16 | # The indent size used in the package.json file cannot be changed: 17 | # https://github.com/npm/npm/pull/3180#issuecomment-16336516 18 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "exadium/extra-attributes-field", 3 | "description": "Extension of SilverStripe form fields to allow attributes for child elements on dropdown (option) and checkboxset (checkbox) fields.", 4 | "type": "silverstripe-module", 5 | "homepage": "https://github.com/marijnkampf/silverstripe-dropdown-attributes-field", 6 | "keywords": ["silverstripe", "module", "dropdownfield", "dropdown", "field"], 7 | "authors": [ 8 | {"name": "Marijn Kampf", "email": "info@exadium.com" } 9 | ], 10 | "support": { 11 | "issues": "https://github.com/marijnkampf/silverstripe-dropdown-attributes-field/issues" 12 | }, 13 | "require": { 14 | "silverstripe/cms": "~3.1", 15 | "silverstripe/framework": "~3.1" 16 | }, 17 | "extra": { 18 | "installer-name": "extra-attributes-field" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /templates/BootstrapCheckboxSetField.ss: -------------------------------------------------------------------------------- 1 | <% if $Options.Count %> 2 | <% if $HasColumns %> 3 |
4 |
5 | <% loop $Options %> 6 |
7 | 11 |
12 | <% if $Up.HasColumns && $MultipleOf($Up.PerColumn) %>
<% end_if %> 13 | <% end_loop %> 14 |
15 |
16 | <% else %> 17 | <% loop $Options %> 18 |
19 | 23 |
24 | <% end_loop %> 25 | <% end_if %> 26 | <% else %> 27 |
No options available
28 | <% end_if %> 29 | -------------------------------------------------------------------------------- /code/DropdownAttributesField.php: -------------------------------------------------------------------------------- 1 | getSource(); 13 | $options = array(); 14 | if ($source) { 15 | // SQLMap needs this to add an empty value to the options 16 | if (is_object($source) && $this->emptyString) { 17 | $options[] = new ArrayData(array( 18 | 'Value' => '', 19 | 'Title' => $this->emptyString, 20 | )); 21 | } 22 | 23 | foreach ($source as $value => $title) { 24 | $selected = false; 25 | if ($value === '' && ($this->value === '' || $this->value === null)) { 26 | $selected = true; 27 | } else { 28 | // check against value, fallback to a type check comparison when !value 29 | if ($value) { 30 | $selected = ($value == $this->value); 31 | } else { 32 | $selected = ($value === $this->value) || (((string) $value) === ((string) $this->value)); 33 | } 34 | 35 | $this->isSelected = $selected; 36 | } 37 | 38 | $disabled = false; 39 | if (in_array($value, $this->disabledItems) && $title != $this->emptyString) { 40 | $disabled = 'disabled'; 41 | } 42 | 43 | $optionsAttributes = $this->getOptionAttributes($value); 44 | 45 | $options[] = new ArrayData(array_merge( 46 | array( 47 | 'Title' => $title, 48 | 'Value' => $value, 49 | 'Selected' => $selected, 50 | 'Disabled' => $disabled, 51 | 'OptionAttributesHTML' => $this->getOptionAttributesHTML($optionsAttributes) 52 | ), 53 | $optionsAttributes 54 | )); 55 | } 56 | } 57 | 58 | $properties = array_merge($properties, array('Options' => new ArrayList($options))); 59 | return $properties; 60 | } 61 | 62 | public function Field($properties = array()) 63 | { 64 | $properties = $this->getOptionsAttributes($properties); 65 | 66 | $obj = ($properties) ? $this->customise($properties) : $this; 67 | $this->extend('onBeforeRender', $this); 68 | return $obj->renderWith($this->getTemplates()); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Extra Attributes Field module 2 | ================================ 3 | 4 | Description 5 | ----------- 6 | Extension of SilverStripe form fields to allow adding attributes to child elements on dropdown and checkboxset fields. 7 | 8 | Maintainer Contact 9 | ------------------ 10 | Marijn Kampf 11 | 12 | 13 | Sponsored by 14 | ------------ 15 | Exadium Web Development and Online Marketing. Visit http://www.exadium.com for more information. 16 | 17 | Installation 18 | ------------ 19 | ```` 20 | composer require "exadium/extra-attributes-field":"*" 21 | ```` 22 | 23 | The module should work out of the box on a standard installation of SilverStripe. If you have Bootstrap Forms module installed by 24 | 25 | \extra-attributes-field\templates\ 26 | \themes\bootstrap\templates 27 | 28 | Usage 29 | ----- 30 | ```` 31 | public function getCMSFields() { 32 | $fields = parent::getCMSFields(); 33 | 34 | $count = array('1' => 'One', '2' => 'Two', '3' => 'Three'); 35 | $batties = array('1' => 'Batty', '2' => 'Batty batty', '3' => 'Batty batty batty'); 36 | 37 | $fields->push( 38 | DropdownAttributesField::create('DropdownAttributesCount', 'DropdownAttributesField Count', $count) 39 | ->setOptionsAttributes('data-bats', $batties) 40 | ); 41 | 42 | $fields->push( 43 | CheckboxSetField::create('CheckCount', 'CheckboxSetField Count', $count) 44 | ->setOptionsAttributes('data-bats', $batties) 45 | ); 46 | 47 | return $fields; 48 | } 49 | ```` 50 | 51 | Generates code like 52 | ```` 53 | 63 | 64 |
65 | 66 |
67 |
    68 |
  • 69 | 70 | 71 |
  • 72 |
  • 73 | 74 | 75 |
  • 76 |
  • 77 | 78 | 79 |
  • 80 |
81 |
82 |
83 | ```` 84 | 85 | Or you can load from a database field map. Also shows adding multiple options. 86 | ```` 87 | $fields->push( 88 | DropdownAttributesField::create('Members', 'Members', Member::get()->map('ID', 'Name')) 89 | ->setOptionsAttributes('data-email', Member::get()->map('ID', 'Email')) 90 | ->setOptionsAttributes('data-firstname', Member::get()->map('ID', 'FirstName')) 91 | ); 92 | ```` 93 | 94 | Notes 95 | ----- 96 | If you use [silverstripe-bootstrap-forms](https://github.com/unclecheese/silverstripe-bootstrap-forms) copy BootstrapCheckboxSetField.ss to your templates folder. If you use your own custom Field templates add 97 | ```` 98 | $OptionAttributesHTML 99 | ```` 100 | 101 | to your input/option/checkbox/... 102 | 103 | Requirements 104 | ------------ 105 | SilverStripe 3.1 -------------------------------------------------------------------------------- /code/FormFieldAttributesExtension.php: -------------------------------------------------------------------------------- 1 | $value) { 21 | $this->setOptionAttribute($key, $name, $value); 22 | } 23 | return $this->owner; 24 | } 25 | 26 | /** 27 | * Set attribute for single dropdown option. Assumes that object values are unique. 28 | * 29 | * @param string $key ID of the option 30 | * @param string $name Name of the attribute 31 | * @param string $value Select option by its value 32 | */ 33 | public function setOptionAttribute($key, $name, $value) 34 | { 35 | if (!isset($this->optionsAttributes[$key])) { 36 | $this->optionsAttributes[$key] = array(); 37 | } 38 | $this->optionsAttributes[$key][$name] = $value; 39 | return $this->owner; 40 | } 41 | 42 | /** 43 | * Get attribute(s) for single dropdown option. 44 | * 45 | * @param string $key ID of the option to return 46 | */ 47 | public function getOptionAttributes($key) 48 | { 49 | if (isset($this->optionsAttributes[$key])) { 50 | return $this->optionsAttributes[$key]; 51 | } else { 52 | return array(); 53 | } 54 | } 55 | 56 | public function updateGetOptions($options) 57 | { 58 | foreach ($options as $option) { 59 | if ($option->hasField("Value") && isset($this->optionsAttributes[$option->getField("Value")])) { 60 | foreach ($this->optionsAttributes[$option->getField("Value")] as $key => $value) { 61 | $option->setField($key, $value); 62 | } 63 | $option->setField('OptionAttributesHTML', $this->getOptionAttributesHTML($this->optionsAttributes[$option->getField("Value")])); 64 | } 65 | } 66 | } 67 | 68 | /** 69 | * Get an HTML attribute added through {@link setOptionAttribute()}. 70 | * 71 | * @return string 72 | */ 73 | /* public function getOptionAttribute($name, $value) { 74 | Debug::Show($name); 75 | $optionAttrs = $this->owner->getOptionsAttributes(); 76 | if(isset($optionAttrs[$name])) return $optionAttrs[$name]; 77 | }*/ 78 | 79 | /** 80 | * Get a HTML attributes added through {@link setOptionAttribute()}. 81 | * 82 | * @return string 83 | */ 84 | /* public function getOptionAttributes($name) { 85 | $optionAttrs = $this->owner->getOptionsAttributes(); 86 | if(isset($optionAttrs[$name])) return $optionAttrs[$name]; 87 | }*/ 88 | 89 | /** 90 | * @param Array Custom attributes to process. Falls back to {@link getOptionsAttributes()}. 91 | * If at least one argument is passed as a string, all arguments act as excludes by name. 92 | * @return string HTML attributes, ready for insertion into an HTML tag 93 | */ 94 | public function getOptionAttributesHTML($attrs = null) 95 | { 96 | $exclude = (is_string($attrs)) ? func_get_args() : null; 97 | 98 | // Remove empty 99 | $attrs = array_filter((array)$attrs, function ($v) { 100 | return ($v || $v === 0 || $v === '0'); 101 | }); 102 | 103 | // Remove excluded 104 | if ($exclude) { 105 | $attrs = array_diff_key($attrs, array_flip($exclude)); 106 | } 107 | 108 | // Create markkup 109 | $parts = array(); 110 | foreach ($attrs as $name => $value) { 111 | $parts[] = ($value === true) ? "{$name}=\"{$name}\"" : "{$name}=\"" . Convert::raw2att($value) . "\""; 112 | } 113 | 114 | return implode(' ', $parts); 115 | } 116 | } 117 | --------------------------------------------------------------------------------