├── .editorconfig ├── .scrutinizer.yml ├── README.md ├── _config.php ├── code ├── AdvancedDropdownField.php └── AdvancedGroupedDropdownField.php ├── composer.json └── templates └── DNA └── AdvancedDropdowns └── AdvancedDropdownField.ss /.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 | -------------------------------------------------------------------------------- /.scrutinizer.yml: -------------------------------------------------------------------------------- 1 | inherit: true 2 | 3 | checks: 4 | php: 5 | verify_property_names: true 6 | verify_argument_usable_as_reference: true 7 | verify_access_scope_valid: true 8 | useless_calls: true 9 | use_statement_alias_conflict: true 10 | variable_existence: true 11 | unused_variables: true 12 | unused_properties: true 13 | unused_parameters: true 14 | unused_methods: true 15 | unreachable_code: true 16 | too_many_arguments: true 17 | sql_injection_vulnerabilities: true 18 | simplify_boolean_return: true 19 | side_effects_or_types: true 20 | security_vulnerabilities: true 21 | return_doc_comments: true 22 | return_doc_comment_if_not_inferrable: true 23 | require_scope_for_properties: true 24 | require_scope_for_methods: true 25 | require_php_tag_first: true 26 | psr2_switch_declaration: true 27 | psr2_class_declaration: true 28 | property_assignments: true 29 | prefer_while_loop_over_for_loop: true 30 | precedence_mistakes: true 31 | precedence_in_conditions: true 32 | phpunit_assertions: true 33 | php5_style_constructor: true 34 | parse_doc_comments: true 35 | parameter_non_unique: true 36 | parameter_doc_comments: true 37 | param_doc_comment_if_not_inferrable: true 38 | optional_parameters_at_the_end: true 39 | one_class_per_file: true 40 | no_unnecessary_if: true 41 | no_trailing_whitespace: true 42 | no_property_on_interface: true 43 | no_non_implemented_abstract_methods: true 44 | no_error_suppression: true 45 | no_duplicate_arguments: true 46 | no_commented_out_code: true 47 | newline_at_end_of_file: true 48 | missing_arguments: true 49 | method_calls_on_non_object: true 50 | instanceof_class_exists: true 51 | foreach_traversable: true 52 | fix_line_ending: true 53 | fix_doc_comments: true 54 | duplication: true 55 | deprecated_code_usage: true 56 | deadlock_detection_in_loops: true 57 | code_rating: true 58 | closure_use_not_conflicting: true 59 | catch_class_exists: true 60 | blank_line_after_namespace_declaration: false 61 | avoid_multiple_statements_on_same_line: true 62 | avoid_duplicate_types: true 63 | avoid_conflicting_incrementers: true 64 | avoid_closing_tag: true 65 | assignment_of_null_return: true 66 | argument_type_checks: true 67 | 68 | filter: 69 | paths: [code/*, tests/*] 70 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AdvancedDropdowns 2 | 3 | ## Introduction 4 | 5 | DropdownField and GroupedDropdownField that allows the use of data-attributes on each option tag. 6 | Very useful for third party dropdown styling such as (http://silviomoreto.github.io/bootstrap-select/) which rely on data-attributes on options. 7 | 8 | Please note this module is a work in progress and has no tests. 9 | 10 | ## AdvandedDropdownField 11 | 12 | Set up your AdvandedDropdownField's as follows: 13 | 14 | ```php 15 | new AdvancedDropdownField('AdvancedDropdown', 'DropdownField with option attributes', array( 16 | 'value1' => array( 17 | 'Title' => 'Option 1', 18 | 'Attributes' => array( 19 | 'data-myattribute' => 'This is an attribute value' 20 | ) 21 | ), 22 | 'value2' => array( 23 | 'Title' => 'Option 2', 24 | 'Attributes' => array( 25 | 'data-myattribute' => 'This is an attribute value' 26 | 'data-myattribute2' => 'This is a second attribute value' 27 | ) 28 | ) 29 | )); 30 | ``` 31 | 32 | ## AdvandedGroupedDropdownField 33 | 34 | Set up your AdvandedGroupedDropdownField's as follows: 35 | 36 | ```php 37 | new AdvancedGroupedDropdownField('AdvancedGroupedDropdown', 'Advanced grouped dropdown', array( 38 | 'value1' => array( 39 | 'Title' => 'Ungrouped option', 40 | 'Attributes' => array( 41 | 'data-myattribute' => 'This is an attribute value' 42 | ) 43 | ), 44 | 'Option group 1' => array( 45 | 'value2' => array( 46 | 'Title' => 'Option 2', 47 | 'Attributes' => array( 48 | 'data-myattribute' => 'This is an attribute value' 49 | ) 50 | ), 51 | 'value3' => array( 52 | 'Title' => 'Option 3', 53 | 'Attributes' => array( 54 | 'data-myattribute' => 'This is an attribute value' 55 | ) 56 | ) 57 | ), 58 | 'Option group 2' => array( 59 | 'value4' => array( 60 | 'Title' => 'Option 4', 61 | 'Attributes' => array( 62 | 'data-myattribute' => 'This is an attribute value' 63 | ) 64 | ), 65 | 'value5' => array( 66 | 'Title' => 'Option 5', 67 | 'Attributes' => array( 68 | 'data-myattribute' => 'This is an attribute value' 69 | 'data-myattribute2' => 'This is a second attribute value' 70 | ) 71 | ) 72 | ) 73 | )); 74 | ``` 75 | 76 | ## Maintainer Contact 77 | 78 | * James ayers (james.ayers@dna.co.nz) 79 | 80 | ## Requirements 81 | 82 | * SilverStripe 3.x 83 | 84 | ## License 85 | 86 | BSD-3-Clause. See LICENSE. -------------------------------------------------------------------------------- /_config.php: -------------------------------------------------------------------------------- 1 | getSource(); 20 | $options = array(); 21 | 22 | if ($this->getHasEmptyDefault()) { 23 | $selected = ($this->value === '' || $this->value === null); 24 | $disabled = (in_array('', $this->disabledItems, true)) ? 'disabled' : false; 25 | $empty = $this->getEmptyString(); 26 | $options[] = new ArrayData(array( 27 | 'Value' => '', 28 | 'Title' => $empty, 29 | 'Selected' => $selected, 30 | 'Disabled' => $disabled, 31 | 'Attributes' => $this->createOptionAttributes($empty) 32 | )); 33 | } 34 | 35 | if($source) { 36 | foreach($source as $value => $params) { 37 | 38 | 39 | $selected = false; 40 | if($value === '' && ($this->value === '' || $this->value === null)) { 41 | $selected = true; 42 | } else { 43 | // check against value, fallback to a type check comparison when !value 44 | if($value) { 45 | $selected = ($value == $this->value); 46 | } else { 47 | $selected = ($value === $this->value) || (((string) $value) === ((string) $this->value)); 48 | } 49 | 50 | $this->isSelected = $selected; 51 | } 52 | 53 | $disabled = false; 54 | if(in_array($value, $this->disabledItems) && $params['Title'] != $this->emptyString ){ 55 | $disabled = 'disabled'; 56 | } 57 | 58 | $options[] = new ArrayData(array( 59 | 'Title' => $params['Title'], 60 | 'Value' => $value, 61 | 'Selected' => $selected, 62 | 'Disabled' => $disabled, 63 | 'Attributes' => $this->createOptionAttributes($params) 64 | )); 65 | } 66 | } 67 | 68 | $properties = array_merge($properties, array('Options' => new ArrayList($options))); 69 | 70 | return FormField::Field($properties); 71 | } 72 | 73 | 74 | public function createOptionAttributes($params) { 75 | $attributes = new ArrayList(); 76 | if(isset($params['Attributes'])) { 77 | if($params['Attributes'] instanceOf ArrayList) { 78 | $attributes = $params['Attributes']; 79 | } else { 80 | foreach($params['Attributes'] as $k => $v) { 81 | $attributes->push(new ArrayData(array( 82 | 'Name' => $k, 83 | 'Value' => $v 84 | ))); 85 | } 86 | } 87 | } 88 | return $attributes; 89 | } 90 | 91 | } 92 | 93 | 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /code/AdvancedGroupedDropdownField.php: -------------------------------------------------------------------------------- 1 | getSource() as $value => $params) { 17 | if(is_array($params) && !array_key_exists('Title', $params)) { 18 | $options .= ""; 19 | foreach($params as $value2 => $params2) { 20 | 21 | $disabled = ''; 22 | if( array_key_exists($value, $this->disabledItems) 23 | && is_array($this->disabledItems[$value]) 24 | && in_array($value2, $this->disabledItems[$value]) ){ 25 | $disabled = 'disabled="disabled"'; 26 | } 27 | $selected = $value2 == $this->value ? " selected=\"selected\"" : ""; 28 | $optionTitle = $params2['Title']; 29 | $attributes = $this->createOptionAttributes($params2); 30 | $optionAttributes = ''; 31 | foreach($attributes as $attribute) { 32 | $optionAttributes .= " $attribute->Name=\"$attribute->Value\""; 33 | } 34 | $options .= "$optionTitle"; 35 | } 36 | $options .= ""; 37 | } else { // Fall back to the standard dropdown field 38 | $disabled = ''; 39 | if( in_array($value, $this->disabledItems) ){ 40 | $disabled = 'disabled="disabled"'; 41 | } 42 | $selected = $value == $this->value ? " selected=\"selected\"" : ""; 43 | $optionTitle = $params['Title']; 44 | $attributes = $this->createOptionAttributes($params); 45 | $optionAttributes = ''; 46 | foreach($attributes as $attribute) { 47 | $optionAttributes .= " $attribute->Name=\"$attribute->Value\""; 48 | } 49 | 50 | $options .= "$optionTitle"; 51 | } 52 | } 53 | 54 | return FormField::create_tag('select', $this->getAttributes(), $options); 55 | } 56 | 57 | public function Type() { 58 | return 'groupeddropdown dropdown'; 59 | } 60 | 61 | public function createOptionAttributes($params) { 62 | $attributes = new ArrayList(); 63 | if(isset($params['Attributes'])) { 64 | if($params['Attributes'] instanceOf ArrayList) { 65 | $attributes = $params['Attributes']; 66 | } else { 67 | foreach($params['Attributes'] as $k => $v) { 68 | $attributes->push(new ArrayData(array( 69 | 'Name' => $k, 70 | 'Value' => $v 71 | ))); 72 | } 73 | } 74 | } 75 | return $attributes; 76 | } 77 | 78 | 79 | } -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dnadesign/silverstripe-advanceddropdowns", 3 | "description": "DropdownField and GroupedDropdownField that allows the use of data-attributes on each option tag", 4 | "type": "silverstripe-vendormodule", 5 | "keywords": ["silverstripe", "dropdown", "select"], 6 | "license": "BSD-3-Clause", 7 | "authors": [ 8 | { 9 | "name": "james Ayers", 10 | "email": "james.ayers@dna.co.nz" 11 | } 12 | ], 13 | "require": { 14 | "silverstripe/framework": "^4.0" 15 | }, 16 | "extra": { 17 | "installer-name": "advanceddropdowns" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /templates/DNA/AdvancedDropdowns/AdvancedDropdownField.ss: -------------------------------------------------------------------------------- 1 | 6 | 7 | --------------------------------------------------------------------------------