From bced4f54204c22e8b44717d7ac1da50bc3734724 Mon Sep 17 00:00:00 2001 From: nico Date: Sun, 16 Sep 2018 14:42:26 +0200 Subject: [PATCH 1/5] Updated getelement processor to support @ bindings for CHUNK, FILE and SELECT --- .../dynamicdropdowntv/docs/changelog.txt | 4 ++ .../dynamicdropdowntv/docs/readme.txt | 12 ++++- .../mgr/default/getelements.default.php | 50 ++++++++++++++++++- 3 files changed, 64 insertions(+), 2 deletions(-) diff --git a/core/components/dynamicdropdowntv/docs/changelog.txt b/core/components/dynamicdropdowntv/docs/changelog.txt index c415592..8b57a6f 100644 --- a/core/components/dynamicdropdowntv/docs/changelog.txt +++ b/core/components/dynamicdropdowntv/docs/changelog.txt @@ -1,5 +1,9 @@ Changelog ================================================================================ +- 1.3.1 + - Added support for @-bindings (@CHUNK, @FILE, @SELECT) in Input Options Values field + +- 1.3.0 - 1.2 - Checked/rewritten documentation diff --git a/core/components/dynamicdropdowntv/docs/readme.txt b/core/components/dynamicdropdowntv/docs/readme.txt index 0a61266..ec539db 100644 --- a/core/components/dynamicdropdowntv/docs/readme.txt +++ b/core/components/dynamicdropdowntv/docs/readme.txt @@ -87,13 +87,23 @@ Input Options | Input Option Values | 1::TEST1a==1a||TEST1a==1a##2::TES The names `dynamicX` and `dynamicGroup` are just examples and could be changed. -This example will add two dropdown select TVs, where you can different values. After selecting a value in the first TV dynamic0, the dropdown select of the second TV dynamic1 will show related values. If you select again a value in the first TV dynamic0 all children of this Dynamic Dropdown TV (dynamic1) will be reseted. +This example will add two dropdown select TVs, where you can select different values. After selecting a value in the first TV dynamic0, the dropdown select of the second TV dynamic1 will show related values. If you select again a value in the first TV dynamic0 all children of this Dynamic Dropdown TV (dynamic1) will be reseted. The format for the input option values is: `Parentvalue::Key==Value||…||Key==Value##Parentvalue::Key==Value||…||Key==Value` Creating a new line after the `##` is allowed. +####@bindings + +You can also use `@CHUNK`, `@SELECT` or `@FILE` bindings in the Input Option Values. +Example for the first dropdown: +`@CHUNK my_random_chunk_with_key_value_pairs` + +For the child dropdown, you can combine multiple variants: +`Parentvalue1::@CHUNK key_values_for_Parentvalue1##Parentvalue2::plain==1||text==2||..##Parentvalue3::@SELECT name,id FROM mytable` + + Example 3: Individual processor usage ················································································ diff --git a/core/components/dynamicdropdowntv/processors/mgr/default/getelements.default.php b/core/components/dynamicdropdowntv/processors/mgr/default/getelements.default.php index 84a9946..66843ee 100644 --- a/core/components/dynamicdropdowntv/processors/mgr/default/getelements.default.php +++ b/core/components/dynamicdropdowntv/processors/mgr/default/getelements.default.php @@ -37,7 +37,55 @@ $elementValues = array(); $elements = explode('##', $elements); foreach ($elements as $element) { - $element = explode('::', trim($element)); + // Check for any binding in element string + $regex = '/(.*)@(\w+)\W+(\w.+)/'; + + if(preg_match($regex,$element,$mtch)) { + $prefix = $mtch[1]; + $type = $mtch[2]; //binding type + $val = $mtch[3]; //binding value string + $el; + + switch($type) { + case 'CHUNK': + $el = $modx->parseChunk($val,array()); + break; + case 'FILE': + $el = file_get_contents($modx->config['base_path'] . $val); + break; + case 'SELECT': + $sql = 'SELECT '. $val; + + $c = new xPDOCriteria($modx,$sql); // connect to the MODX DB + $rows = array(); + if ($c->stmt && $c->stmt->execute()) + { + while ($row = $c->stmt->fetch(PDO::FETCH_ASSOC)) + { + if(count($row) > 1) { + $rows[] = $row['name']."==".$row['id']; + } else { + $rows[] = $row['id']; + } + } + $el = implode('||',$rows); + break; + } + break; + /* + case 'INLINE': + $chunk = $modx->newObject('modChunk'); + $chunk->setCacheable(false); + $elements = $chunk->process(); + break; + */ + default: + break; + } + $element = $prefix . $el; + } + + $element = explode('::', trim($element)); if (count($element) > 1) { $key = trim($element[0]); $values = explode('||', $element[1]); From b5f0d694a26a05eebe4b39d7069608329e94754b Mon Sep 17 00:00:00 2001 From: nico Date: Sun, 16 Sep 2018 14:47:05 +0200 Subject: [PATCH 2/5] Updated in accordance with readme.txt and changelog.txt --- CHANGELOG.md | 4 ++++ README.md | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c415592..8b57a6f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ Changelog ================================================================================ +- 1.3.1 + - Added support for @-bindings (@CHUNK, @FILE, @SELECT) in Input Options Values field + +- 1.3.0 - 1.2 - Checked/rewritten documentation diff --git a/README.md b/README.md index 5b186aa..b6e569b 100644 --- a/README.md +++ b/README.md @@ -92,6 +92,15 @@ The format for the input option values is: Creating a new line after the `##` is allowed. +##### @bindings + +You can also use `@CHUNK`, `@SELECT` or `@FILE` bindings in the Input Option Values. +Example for the first dropdown: +`@CHUNK my_random_chunk_with_key_value_pairs` + +For the child dropdown, you can combine multiple variants: +`Parentvalue1::@CHUNK key_values_for_Parentvalue1##Parentvalue2::plain==1||text==2||..##Parentvalue3::@SELECT name,id FROM mytable` + ### Example 3: Individual processor usage Create three Dynamic Dropdown template variables: From 62caff3c3f842efc4f21b123195238a411783207 Mon Sep 17 00:00:00 2001 From: nico Date: Tue, 18 Sep 2018 18:06:37 +0200 Subject: [PATCH 3/5] Fixes all issues https://github.com/Bruno17/DynamicDropdownTV/issues/9 - create alternative class with shorter name - fixed x-form trigger buttons - fixed connector url - fixed saving multiple values to DB - fixed load values --- .../tv/input/dynamicdropdown_mlti.class.php | 81 +++++ .../tv/input/tpl/dynamicdropdown_mlti.tpl | 148 +++++++++ .../tv/inputoptions/dynamicdropdown_mlti.php | 46 +++ .../inputoptions/tpl/dynamicdropdown_mlti.tpl | 309 ++++++++++++++++++ 4 files changed, 584 insertions(+) create mode 100644 core/components/dynamicdropdowntv/tv/input/dynamicdropdown_mlti.class.php create mode 100644 core/components/dynamicdropdowntv/tv/input/tpl/dynamicdropdown_mlti.tpl create mode 100644 core/components/dynamicdropdowntv/tv/inputoptions/dynamicdropdown_mlti.php create mode 100644 core/components/dynamicdropdowntv/tv/inputoptions/tpl/dynamicdropdown_mlti.tpl diff --git a/core/components/dynamicdropdowntv/tv/input/dynamicdropdown_mlti.class.php b/core/components/dynamicdropdowntv/tv/input/dynamicdropdown_mlti.class.php new file mode 100644 index 0000000..80eb9a3 --- /dev/null +++ b/core/components/dynamicdropdowntv/tv/input/dynamicdropdown_mlti.class.php @@ -0,0 +1,81 @@ + + * + * DynamicDropdownTV is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) any + * later version. + * + * DynamicDropdownTV is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * DynamicDropdownTV; if not, write to the Free Software Foundation, Inc., 59 + * Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * @package dynamicdropdowntv + * @subpackage input render + * + * Input Render for DynamicDropdownTV Multiple + */ +if (!class_exists('DynamicDropdownMultipleInputRender')) { + + class DynamicDropdownMultipleInputRender extends modTemplateVarInputRender { + + public function getTemplate() { + $corePath = $this->modx->getOption('dynamicdropdowntv.core_path', null, $this->modx->getOption('core_path') . 'components/dynamicdropdowntv/'); + return $corePath . 'tv/input/tpl/dynamicdropdown_mlti.tpl'; + } + + public function process($value, array $params = array()) { + $corePath = $this->modx->getOption('dynamicdropdowntv.core_path', null, $this->modx->getOption('core_path') . 'components/dynamicdropdowntv/'); + + // fetch only the tv lexicon + $this->modx->lexicon->load('tv_widget'); + $this->modx->lexicon->load('dynamicdropdowntv:inputoptions'); + $lang = $this->modx->lexicon->fetch(); + foreach ($lang as $k => $v) { + if (strpos($k, 'dynamicdropdowntv.') !== false) { + $k = str_replace('dynamicdropdowntv.', '', $k); + $k = str_replace('.', '_', $k); + } + $this->setPlaceholder('lang_' . $k, $v); + } + $this->setPlaceholder('params', $params); + + $resource = is_object($this->modx->resource) ? $this->modx->resource->toArray() : array(); + + $ddId = $this->tv->get('name'); + $groupPath = 'mgr/' . $params['group']; + $defaultPath = 'mgr/default'; + $actionPath = file_exists($corePath . 'processors/' . $groupPath) ? $groupPath . '/' : $defaultPath . '/'; + + if ($this->tv->get('elements') == '') { + $default_processor = 'getoptions.default'; + $ddProcessor = 'getoptions.' . $ddId; + } else { + $default_processor = 'getelements.default'; + $ddProcessor = 'getelements.' . $ddId; + } + + $action = file_exists($corePath . 'processors/' . $actionPath . $ddProcessor . '.php') ? $actionPath . $ddProcessor : $actionPath . $default_processor; + + $this->setPlaceholder('connector_path', "'" . $this->modx->getOption('dynamicdropdowntv.assets_path', NULL, "' + MODx.config.assets_url + 'components/dynamicdropdowntv/") . "connector.php'"); + $this->setPlaceholder('resource', $resource); + $this->setPlaceholder('object_id', $this->modx->getOption('object_id', $_REQUEST, '')); + $this->setPlaceholder('params', $params); + $this->setPlaceholder('action', $action); + $this->setPlaceholder('children', $this->modx->toJson(explode(',', $params['childs']))); + $this->setPlaceholder('parents', $this->modx->toJson(explode(',', $params['parents']))); + $this->setPlaceholder('ddId', $ddId); + } + + } + +} +return 'DynamicDropdownMultipleInputRender'; \ No newline at end of file diff --git a/core/components/dynamicdropdowntv/tv/input/tpl/dynamicdropdown_mlti.tpl b/core/components/dynamicdropdowntv/tv/input/tpl/dynamicdropdown_mlti.tpl new file mode 100644 index 0000000..1697ab4 --- /dev/null +++ b/core/components/dynamicdropdowntv/tv/input/tpl/dynamicdropdown_mlti.tpl @@ -0,0 +1,148 @@ + + +
+ +
+ + + \ No newline at end of file diff --git a/core/components/dynamicdropdowntv/tv/inputoptions/dynamicdropdown_mlti.php b/core/components/dynamicdropdowntv/tv/inputoptions/dynamicdropdown_mlti.php new file mode 100644 index 0000000..9530165 --- /dev/null +++ b/core/components/dynamicdropdowntv/tv/inputoptions/dynamicdropdown_mlti.php @@ -0,0 +1,46 @@ + + * + * DynamicDropdownTV is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) any + * later version. + * + * DynamicDropdownTV is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * DynamicDropdownTV; if not, write to the Free Software Foundation, Inc., 59 + * Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * @package dynamicdropdowntv + * @subpackage input render properties + * + * Input Render for DynamicDropdownTV Properties Multiple + */ +$modx->lexicon->load('tv_widget', 'dynamicdropdowntv:inputoptions'); +$lang = $modx->lexicon->fetch('dynamicdropdowntv.', true); + +// get list of dynamic dropdown template variables to select parent dropdown +$c = $modx->newQuery('modTemplateVar'); +$c->where(array('type:LIKE' => 'dynamicdropdown%')); +$list[] = array('', $lang['noParent']); +if ($collection = $modx->getCollection('modTemplateVar', $c)) { + foreach ($collection as $object) { + if ($_REQUEST['tv'] != $object->get('id')) { + $list[] = array($object->get('name'), $object->get('name')); + } + } +} +$list = json_encode($list); + +$modx->smarty->assign('tvlist', $list); +$modx->smarty->assign('dynamicdropdowntv', $lang); + +$corePath = $modx->getOption('dynamicdropdowntv.core_path', null, $modx->getOption('core_path') . 'components/dynamicdropdowntv/'); +return $modx->smarty->fetch($corePath . 'tv/inputoptions/tpl/dynamicdropdown_multiple.tpl'); diff --git a/core/components/dynamicdropdowntv/tv/inputoptions/tpl/dynamicdropdown_mlti.tpl b/core/components/dynamicdropdowntv/tv/inputoptions/tpl/dynamicdropdown_mlti.tpl new file mode 100644 index 0000000..886b34b --- /dev/null +++ b/core/components/dynamicdropdowntv/tv/inputoptions/tpl/dynamicdropdown_mlti.tpl @@ -0,0 +1,309 @@ +
+{literal} + + +{/literal} \ No newline at end of file From 4cdf3ccf8f3f8a0ad154dae538c24513e294610f Mon Sep 17 00:00:00 2001 From: nico Date: Thu, 20 Sep 2018 18:46:25 +0200 Subject: [PATCH 4/5] Should now work with 2 _multi fields ... --- .../mgr/default/getelements.default.php | 22 +++++++++++++++++-- .../tv/input/tpl/dynamicdropdown_mlti.tpl | 8 +++---- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/core/components/dynamicdropdowntv/processors/mgr/default/getelements.default.php b/core/components/dynamicdropdowntv/processors/mgr/default/getelements.default.php index 66843ee..5f24125 100644 --- a/core/components/dynamicdropdowntv/processors/mgr/default/getelements.default.php +++ b/core/components/dynamicdropdowntv/processors/mgr/default/getelements.default.php @@ -97,8 +97,14 @@ } $parent = $modx->getOption('parent', $inputProperties, ''); -$parentValue = ($scriptProperties[$parent] != '') ? $scriptProperties[$parent] : '#ROOT#'; -$elementValues = isset($elementValues[$parentValue]) ? $elementValues[$parentValue] : array(); +$parentValue = (isset($scriptProperties[$parent]) && $scriptProperties[$parent] != '') ? $scriptProperties[$parent] : '#ROOT#'; +$parentValue = ($parentValue == '#ROOT#') ? '#ROOT#' : explode('||', $parentValue); + +if($parentValue != '#ROOT#' && count($parentValue) >= 1) { + $elementValues = array_intersect_key( $elementValues, array_flip( $parentValue ) ); //filter the array with parent key +} else { + $elementValues = isset($elementValues[$parentValue]) ? $elementValues[$parentValue] : array(); +} $options = array(); $count = 1; @@ -106,6 +112,18 @@ $options[] = array('id' => '', 'name' => $firstText); +$flat = array(); +foreach($elementValues as $val) { + if(is_array($val)) { + foreach($val as $v) { + $flat[] = $v; + } + } else { + $flat[] = $val; + } +} +$elementValues = $flat; + $count += count($elementValues); foreach ($elementValues as $elementValue) { $elementValue = explode('==', $elementValue, 2); diff --git a/core/components/dynamicdropdowntv/tv/input/tpl/dynamicdropdown_mlti.tpl b/core/components/dynamicdropdowntv/tv/input/tpl/dynamicdropdown_mlti.tpl index 1697ab4..74a6710 100644 --- a/core/components/dynamicdropdowntv/tv/input/tpl/dynamicdropdown_mlti.tpl +++ b/core/components/dynamicdropdowntv/tv/input/tpl/dynamicdropdown_mlti.tpl @@ -76,7 +76,7 @@ MODx.combo.{/literal}{$ddId}{literal} = function(config) { ,listeners: { 'select': {fn:this.selectOption,scope:this} - ,'additem': {fn:this.selectOption,scope:this} + ,'change': {fn:this.selectOption,scope:this} ,'removeitem': {fn:this.selectOption,scope:this} ,'render': {fn:this.initSelect,scope:this} } @@ -85,9 +85,7 @@ MODx.combo.{/literal}{$ddId}{literal} = function(config) { }; Ext.extend(MODx.combo.{/literal}{$ddId}{literal},Ext.ux.form.SuperBoxSelect,{ selectOption: function() { - if(this.children.length >= 1 && typeof(Ext.getCmp('select_'+this.children[0])) != "undefined") { - this.refreshChildren(true); - } + this.refreshChildren(true); MODx.fireResourceFormChange(); } ,reload: function() { @@ -106,7 +104,7 @@ Ext.extend(MODx.combo.{/literal}{$ddId}{literal},Ext.ux.form.SuperBoxSelect,{ child = this.children[i]; ddSelect = Ext.getCmp('select_'+child); if(typeof(ddSelect) != "undefined"){ - ddSelect.baseParams.{/literal}{$ddId}{literal} = this.getValue(); + ddSelect.store.baseParams.{/literal}{$ddId}{literal} = this.getValue(); if (reload){ ddSelect.reload(); } From fc914f62a8cd76df09a1a1cf4c5026a163f77a53 Mon Sep 17 00:00:00 2001 From: nico Date: Wed, 24 Oct 2018 22:07:32 +0200 Subject: [PATCH 5/5] Fixed getoptions processor and delimiter for default processor usage --- .../processors/mgr/default/getoptions.default.php | 13 ++++++++++++- .../tv/input/tpl/dynamicdropdown_mlti.tpl | 10 ++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/core/components/dynamicdropdowntv/processors/mgr/default/getoptions.default.php b/core/components/dynamicdropdowntv/processors/mgr/default/getoptions.default.php index 1919ef1..aa9c1b2 100644 --- a/core/components/dynamicdropdowntv/processors/mgr/default/getoptions.default.php +++ b/core/components/dynamicdropdowntv/processors/mgr/default/getoptions.default.php @@ -53,6 +53,7 @@ $packageName = $modx->getOption('packagename', $inputProperties, ''); $prefix = $modx->getOption('prefix', $inputProperties, ''); $prefix = empty($prefix) ? null : $prefix; +$delimiter = $modx->getOption('valueDelimiter', $inputProperties, '||'); if (!empty($packageName)) { $packagepath = $modx->getOption('core_path') . 'components/' . $packageName . '/'; @@ -70,7 +71,17 @@ $count = 1; if (!empty($query)) { - $c->where(array($namefield . ':LIKE' => $query . '%')); + $qry = explode($delimiter, $query); + $num = true; + foreach($qry as $t) { + $num = ($num && is_numeric($t)); + } + + if($num) { + $c->where(array($idfield . ':IN' => $qry) ); + } else { + $c->where(array($namefield . ':LIKE' => $query . '%')); + } } else { $options[] = array('id' => '', 'name' => $firstText); } diff --git a/core/components/dynamicdropdowntv/tv/input/tpl/dynamicdropdown_mlti.tpl b/core/components/dynamicdropdowntv/tv/input/tpl/dynamicdropdown_mlti.tpl index 74a6710..a30eef6 100644 --- a/core/components/dynamicdropdowntv/tv/input/tpl/dynamicdropdown_mlti.tpl +++ b/core/components/dynamicdropdowntv/tv/input/tpl/dynamicdropdown_mlti.tpl @@ -48,6 +48,7 @@ MODx.combo.{/literal}{$ddId}{literal} = function(config) { ,valueField: 'id' {if $params.valueDelimiter} ,valueDelimiter: '{$params.valueDelimiter}' + ,queryValuesDelimiter: '{$params.valueDelimiter}' {/if} ,clearOnRefresh: {if $params.clearOnRefresh == 1 || $params.clearOnRefresh == 'true'}true{else}false{/if} {literal} @@ -70,7 +71,12 @@ MODx.combo.{/literal}{$ddId}{literal} = function(config) { action: '{/literal}{$action}{literal}' ,resource_id: '{/literal}{$resource.id}{literal}' ,object_id : '{/literal}{$object_id}{literal}' - ,tvname : '{/literal}{{$tv->name}}{literal}' + ,tvname : '{/literal}{{$tv->name}}{literal}' + {/literal} + {if $params.valueDelimiter} + ,valueDelimiter: '{$params.valueDelimiter}', + {/if} + {literal} } }) @@ -123,7 +129,7 @@ Ext.extend(MODx.combo.{/literal}{$ddId}{literal},Ext.ux.form.SuperBoxSelect,{ var original_values = Ext.get('{/literal}original{$ddId}{literal}').dom.value; this.setValue(original_values); - // Separate store .. won't fire ever + // .. won't fire ever this.store.load({ callback: function() { this.setValue(Ext.get('{/literal}original{$ddId}{literal}').dom.value);