From 2b281cc82278157481e4c16e540a66f067605f8e Mon Sep 17 00:00:00 2001 From: Toxix Date: Sat, 21 Mar 2015 14:07:01 +0100 Subject: [PATCH 1/9] store required for hidden fields --- vendor/assets/javascripts/dependent-fields.js.coffee | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vendor/assets/javascripts/dependent-fields.js.coffee b/vendor/assets/javascripts/dependent-fields.js.coffee index 3b27350..331d484 100644 --- a/vendor/assets/javascripts/dependent-fields.js.coffee +++ b/vendor/assets/javascripts/dependent-fields.js.coffee @@ -10,6 +10,7 @@ toggle = ($parent, showOrHide, method, duration) -> $parent.find('input,textarea,select,button,.btn').removeAttr('disabled') $parent.find('.select2').select2('enable') if $.fn.select2 else + $parent.find('input[data-dependent-fields-required],textarea[data-dependent-fields-required],select[data-dependent-fields-required]').attr('required', 'required') $parent.show(duration) else if method == 'disable' @@ -17,6 +18,7 @@ toggle = ($parent, showOrHide, method, duration) -> $parent.find('input,textarea,select,button,.btn').attr('disabled', 'disabled') $parent.find('.select2').select2('disable') if $.fn.select2 else + $parent.find('input[required],textarea[required],select[required]').removeAttr('required').attr('data-dependent-fields-required', 'required') $parent.hide(duration) From 79cdbf2d8d5a1faa8de7cf7e593d0e8158916d33 Mon Sep 17 00:00:00 2001 From: Toxix Date: Sat, 21 Mar 2015 14:30:04 +0100 Subject: [PATCH 2/9] new default is hide and disable --- README.md | 1 + vendor/assets/javascripts/dependent-fields.js.coffee | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 58f7240..e5c56f5 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,7 @@ You can also specify multiple option values by seperating them with `|`. For exa Add `data-method='disable'` to the js-dependent-fields div. +**Note:** The default is now hide and disable the fields and enable them on again when showing. This is to prevent the hidden dependent fields from being submitted. The old behavior can be archived when add `data-method='hide'` to the js-dependent-fields div. Minimal Demo diff --git a/vendor/assets/javascripts/dependent-fields.js.coffee b/vendor/assets/javascripts/dependent-fields.js.coffee index 331d484..02ef45c 100644 --- a/vendor/assets/javascripts/dependent-fields.js.coffee +++ b/vendor/assets/javascripts/dependent-fields.js.coffee @@ -5,19 +5,19 @@ toggle = ($parent, showOrHide, method, duration) -> if showOrHide - if method == 'disable' + if method != 'hide' # disable or default # use attr instead of prop, because prop does not work with twitter bootstrap button $parent.find('input,textarea,select,button,.btn').removeAttr('disabled') $parent.find('.select2').select2('enable') if $.fn.select2 - else + if method != 'disable' # hide or default $parent.find('input[data-dependent-fields-required],textarea[data-dependent-fields-required],select[data-dependent-fields-required]').attr('required', 'required') $parent.show(duration) else - if method == 'disable' + if method != 'hide' # disable or default # use attr instead of prop, because prop does not work with twitter bootstrap button $parent.find('input,textarea,select,button,.btn').attr('disabled', 'disabled') $parent.find('.select2').select2('disable') if $.fn.select2 - else + if method != 'disable' # hide or default $parent.find('input[required],textarea[required],select[required]').removeAttr('required').attr('data-dependent-fields-required', 'required') $parent.hide(duration) From ea41598201115b183f1ea164a9e10d4fc1baede0 Mon Sep 17 00:00:00 2001 From: Toxix Date: Sat, 21 Mar 2015 18:34:11 +0100 Subject: [PATCH 3/9] support for recrusive dependent-fields and code dedublication --- .../assets/javascripts/dependent-fields.js.coffee | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/vendor/assets/javascripts/dependent-fields.js.coffee b/vendor/assets/javascripts/dependent-fields.js.coffee index 02ef45c..a824328 100644 --- a/vendor/assets/javascripts/dependent-fields.js.coffee +++ b/vendor/assets/javascripts/dependent-fields.js.coffee @@ -4,21 +4,24 @@ toggle = ($parent, showOrHide, method, duration) -> + fieldsSelector = 'input,textarea,select' + fieldsAndBtnsSelector = 'input,textarea,select,button,.btn' if showOrHide + $parentVisible = $parent.find(':not(.js-dependent-fields:hidden)') if method != 'hide' # disable or default # use attr instead of prop, because prop does not work with twitter bootstrap button - $parent.find('input,textarea,select,button,.btn').removeAttr('disabled') - $parent.find('.select2').select2('enable') if $.fn.select2 + $parentVisible.find(fieldsAndBtnsSelector).removeAttr('disabled') + $parentVisible.find('.select2').select2('enable') if $.fn.select2 if method != 'disable' # hide or default - $parent.find('input[data-dependent-fields-required],textarea[data-dependent-fields-required],select[data-dependent-fields-required]').attr('required', 'required') + $parentVisible.find(fieldsSelector).filter('[data-dependent-fields-required]').attr('required', 'required') $parent.show(duration) else if method != 'hide' # disable or default # use attr instead of prop, because prop does not work with twitter bootstrap button - $parent.find('input,textarea,select,button,.btn').attr('disabled', 'disabled') + $parent.find(fieldsAndBtnsSelector).attr('disabled', 'disabled') $parent.find('.select2').select2('disable') if $.fn.select2 if method != 'disable' # hide or default - $parent.find('input[required],textarea[required],select[required]').removeAttr('required').attr('data-dependent-fields-required', 'required') + $parent.find(fieldsSelector).filter('[required]').removeAttr('required').attr('data-dependent-fields-required', 'required') $parent.hide(duration) From ad16b2def2ceb7e0409d3c880139854726642159 Mon Sep 17 00:00:00 2001 From: Toxix Date: Sat, 21 Mar 2015 19:25:03 +0100 Subject: [PATCH 4/9] store disabled status --- .../javascripts/dependent-fields.js.coffee | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/vendor/assets/javascripts/dependent-fields.js.coffee b/vendor/assets/javascripts/dependent-fields.js.coffee index a824328..d560be0 100644 --- a/vendor/assets/javascripts/dependent-fields.js.coffee +++ b/vendor/assets/javascripts/dependent-fields.js.coffee @@ -6,17 +6,30 @@ toggle = ($parent, showOrHide, method, duration) -> fieldsSelector = 'input,textarea,select' fieldsAndBtnsSelector = 'input,textarea,select,button,.btn' + parentVisibleSelector = ':not(.js-dependent-fields-hidden)' if showOrHide - $parentVisible = $parent.find(':not(.js-dependent-fields:hidden)') + $parent.removeClass 'js-dependent-fields-hidden' + $parentVisible = $parent.find(parentVisibleSelector) if method != 'hide' # disable or default # use attr instead of prop, because prop does not work with twitter bootstrap button - $parentVisible.find(fieldsAndBtnsSelector).removeAttr('disabled') - $parentVisible.find('.select2').select2('enable') if $.fn.select2 + $fieldsAndBtns = $parentVisible.find(fieldsAndBtnsSelector) + $fieldsAndBtns.filter('[data-dependent-fields-disabled=no]').removeAttr('disabled') + $fieldsAndBtns.removeAttr('data-dependent-fields-disabled') + if $.fn.select2 + $select2 = $parentVisible.find('.select2') + $select2.filter('[data-dependent-fields-disabled=no]').select2('enable') + $select2.removeAttr('data-dependent-fields-disabled') if method != 'disable' # hide or default $parentVisible.find(fieldsSelector).filter('[data-dependent-fields-required]').attr('required', 'required') $parent.show(duration) else + $parent.addClass 'js-dependent-fields-hidden' if method != 'hide' # disable or default + # store the disabled state + $fieldsAndBtns = $parent.find(fieldsAndBtnsSelector+',.select2').not('[data-dependent-fields-disabled]') + $fieldsAndBtns.filter('[disabled]').attr('data-dependent-fields-disabled', 'yes') + $fieldsAndBtns.not('[disabled]').attr('data-dependent-fields-disabled', 'no') + # disable things # use attr instead of prop, because prop does not work with twitter bootstrap button $parent.find(fieldsAndBtnsSelector).attr('disabled', 'disabled') $parent.find('.select2').select2('disable') if $.fn.select2 From 1f32e9fb5fa7998b1f61c9e93a1681097923bccd Mon Sep 17 00:00:00 2001 From: Toxix Date: Sat, 21 Mar 2015 19:26:48 +0100 Subject: [PATCH 5/9] clean up --- vendor/assets/javascripts/dependent-fields.js.coffee | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/vendor/assets/javascripts/dependent-fields.js.coffee b/vendor/assets/javascripts/dependent-fields.js.coffee index d560be0..a9650e1 100644 --- a/vendor/assets/javascripts/dependent-fields.js.coffee +++ b/vendor/assets/javascripts/dependent-fields.js.coffee @@ -77,21 +77,15 @@ showOrHideDependentFieldsRadio = (duration = 'fast') -> bind = -> $selects = $('select') - $selects.not('[data-important]').each _.partial(showOrHideDependentFieldsSelect, 0) - $selects.filter('[data-important]').each _.partial(showOrHideDependentFieldsSelect, 0) - + $selects.each _.partial(showOrHideDependentFieldsSelect, 0) $selects.change showOrHideDependentFieldsSelect $inputs = $('input[type=checkbox]') - $inputs.not('[data-important]').each _.partial(showOrHideDependentFieldsCheckbox, 0) - $inputs.filter('[data-important]').each _.partial(showOrHideDependentFieldsCheckbox, 0) - + $inputs.each _.partial(showOrHideDependentFieldsCheckbox, 0) $inputs.change showOrHideDependentFieldsCheckbox $radios = $('input[type=radio]') - $radios.not('[data-important]').each _.partial(showOrHideDependentFieldsRadio, 0) - $radios.filter('[data-important]').each _.partial(showOrHideDependentFieldsRadio, 0) - + $radios.each _.partial(showOrHideDependentFieldsRadio, 0) $radios.change showOrHideDependentFieldsRadio From 1532dfa3c26b8e13ba8cd416c588a732e3c1cb89 Mon Sep 17 00:00:00 2001 From: Toxix Date: Wed, 8 Apr 2015 18:42:27 +0200 Subject: [PATCH 6/9] fix: the cleanup of the attribute hapens too early. --- vendor/assets/javascripts/dependent-fields.js.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/assets/javascripts/dependent-fields.js.coffee b/vendor/assets/javascripts/dependent-fields.js.coffee index a9650e1..67535b8 100644 --- a/vendor/assets/javascripts/dependent-fields.js.coffee +++ b/vendor/assets/javascripts/dependent-fields.js.coffee @@ -14,11 +14,11 @@ toggle = ($parent, showOrHide, method, duration) -> # use attr instead of prop, because prop does not work with twitter bootstrap button $fieldsAndBtns = $parentVisible.find(fieldsAndBtnsSelector) $fieldsAndBtns.filter('[data-dependent-fields-disabled=no]').removeAttr('disabled') - $fieldsAndBtns.removeAttr('data-dependent-fields-disabled') if $.fn.select2 $select2 = $parentVisible.find('.select2') $select2.filter('[data-dependent-fields-disabled=no]').select2('enable') $select2.removeAttr('data-dependent-fields-disabled') + $fieldsAndBtns.removeAttr('data-dependent-fields-disabled') if method != 'disable' # hide or default $parentVisible.find(fieldsSelector).filter('[data-dependent-fields-required]').attr('required', 'required') $parent.show(duration) From c6a394f944335720a47a86d5a0ac2448da04b76b Mon Sep 17 00:00:00 2001 From: Toxix Date: Wed, 6 Jan 2016 16:23:55 +0100 Subject: [PATCH 7/9] fix do not disable/enable select2 if it was not used on this field --- vendor/assets/javascripts/dependent-fields.js.coffee | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/vendor/assets/javascripts/dependent-fields.js.coffee b/vendor/assets/javascripts/dependent-fields.js.coffee index 67535b8..c8120e5 100644 --- a/vendor/assets/javascripts/dependent-fields.js.coffee +++ b/vendor/assets/javascripts/dependent-fields.js.coffee @@ -16,7 +16,8 @@ toggle = ($parent, showOrHide, method, duration) -> $fieldsAndBtns.filter('[data-dependent-fields-disabled=no]').removeAttr('disabled') if $.fn.select2 $select2 = $parentVisible.find('.select2') - $select2.filter('[data-dependent-fields-disabled=no]').select2('enable') + $select2disabled = $select2.filter('[data-dependent-fields-disabled=no]') + $select2disabled.select2('enable') if $select2disabled.length > 0 $select2.removeAttr('data-dependent-fields-disabled') $fieldsAndBtns.removeAttr('data-dependent-fields-disabled') if method != 'disable' # hide or default @@ -32,7 +33,9 @@ toggle = ($parent, showOrHide, method, duration) -> # disable things # use attr instead of prop, because prop does not work with twitter bootstrap button $parent.find(fieldsAndBtnsSelector).attr('disabled', 'disabled') - $parent.find('.select2').select2('disable') if $.fn.select2 + if $.fn.select2 + $select2enabled = $parent.find('.select2') + $select2enabled.select2('disable') if $select2enabled.length > 0 if method != 'disable' # hide or default $parent.find(fieldsSelector).filter('[required]').removeAttr('required').attr('data-dependent-fields-required', 'required') $parent.hide(duration) From cc1bdc2809746f2d5a18beb24cbcfa9e5c1acddb Mon Sep 17 00:00:00 2001 From: Toxix Date: Wed, 6 Jan 2016 19:15:52 +0100 Subject: [PATCH 8/9] updates needet for the newest version of select2 --- vendor/assets/javascripts/dependent-fields.js.coffee | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/vendor/assets/javascripts/dependent-fields.js.coffee b/vendor/assets/javascripts/dependent-fields.js.coffee index c8120e5..79effe5 100644 --- a/vendor/assets/javascripts/dependent-fields.js.coffee +++ b/vendor/assets/javascripts/dependent-fields.js.coffee @@ -16,8 +16,7 @@ toggle = ($parent, showOrHide, method, duration) -> $fieldsAndBtns.filter('[data-dependent-fields-disabled=no]').removeAttr('disabled') if $.fn.select2 $select2 = $parentVisible.find('.select2') - $select2disabled = $select2.filter('[data-dependent-fields-disabled=no]') - $select2disabled.select2('enable') if $select2disabled.length > 0 + $select2.filter('[data-dependent-fields-disabled=no]').prop('disabled', false) $select2.removeAttr('data-dependent-fields-disabled') $fieldsAndBtns.removeAttr('data-dependent-fields-disabled') if method != 'disable' # hide or default @@ -33,9 +32,7 @@ toggle = ($parent, showOrHide, method, duration) -> # disable things # use attr instead of prop, because prop does not work with twitter bootstrap button $parent.find(fieldsAndBtnsSelector).attr('disabled', 'disabled') - if $.fn.select2 - $select2enabled = $parent.find('.select2') - $select2enabled.select2('disable') if $select2enabled.length > 0 + $parent.find('.select2').prop('disabled', 'disabled') if $.fn.select2 if method != 'disable' # hide or default $parent.find(fieldsSelector).filter('[required]').removeAttr('required').attr('data-dependent-fields-required', 'required') $parent.hide(duration) From 0a8a750e1c5da49c102b618b8333226fdf38d3a0 Mon Sep 17 00:00:00 2001 From: Toxix Date: Sat, 9 Jan 2016 01:43:57 +0100 Subject: [PATCH 9/9] clean up for select2 version 4.1 --- .../javascripts/dependent-fields.js.coffee | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/vendor/assets/javascripts/dependent-fields.js.coffee b/vendor/assets/javascripts/dependent-fields.js.coffee index 79effe5..4c6c5e4 100644 --- a/vendor/assets/javascripts/dependent-fields.js.coffee +++ b/vendor/assets/javascripts/dependent-fields.js.coffee @@ -5,20 +5,20 @@ toggle = ($parent, showOrHide, method, duration) -> fieldsSelector = 'input,textarea,select' - fieldsAndBtnsSelector = 'input,textarea,select,button,.btn' + fieldsAndBtnsSelector = fieldsSelector+',button' parentVisibleSelector = ':not(.js-dependent-fields-hidden)' if showOrHide $parent.removeClass 'js-dependent-fields-hidden' $parentVisible = $parent.find(parentVisibleSelector) if method != 'hide' # disable or default - # use attr instead of prop, because prop does not work with twitter bootstrap button $fieldsAndBtns = $parentVisible.find(fieldsAndBtnsSelector) - $fieldsAndBtns.filter('[data-dependent-fields-disabled=no]').removeAttr('disabled') - if $.fn.select2 - $select2 = $parentVisible.find('.select2') - $select2.filter('[data-dependent-fields-disabled=no]').prop('disabled', false) - $select2.removeAttr('data-dependent-fields-disabled') + # only enable if it was enabled before hiding + $fieldsAndBtns.filter("[data-dependent-fields-disabled='no']").prop('disabled', false) $fieldsAndBtns.removeAttr('data-dependent-fields-disabled') + # use attr instead of prop, because prop does not work with twitter bootstrap button + $parentVisible.find(".btn[data-dependent-fields-disabled='no']").removeAttr('disabled') + # remove the disabled state + $parentVisible.find('[data-dependent-fields-disabled]').removeAttr('data-dependent-fields-disabled') if method != 'disable' # hide or default $parentVisible.find(fieldsSelector).filter('[data-dependent-fields-required]').attr('required', 'required') $parent.show(duration) @@ -26,13 +26,13 @@ toggle = ($parent, showOrHide, method, duration) -> $parent.addClass 'js-dependent-fields-hidden' if method != 'hide' # disable or default # store the disabled state - $fieldsAndBtns = $parent.find(fieldsAndBtnsSelector+',.select2').not('[data-dependent-fields-disabled]') - $fieldsAndBtns.filter('[disabled]').attr('data-dependent-fields-disabled', 'yes') - $fieldsAndBtns.not('[disabled]').attr('data-dependent-fields-disabled', 'no') + $fieldsAndBtns = $parent.find(fieldsAndBtnsSelector + ', .btn').not('[data-dependent-fields-disabled]') + $fieldsAndBtns.filter(':disabled').attr('data-dependent-fields-disabled', 'yes') + $fieldsAndBtns.not(':disabled').attr('data-dependent-fields-disabled', 'no') # disable things + $fieldsAndBtns.filter(fieldsAndBtnsSelector).prop('disabled', true) # use attr instead of prop, because prop does not work with twitter bootstrap button - $parent.find(fieldsAndBtnsSelector).attr('disabled', 'disabled') - $parent.find('.select2').prop('disabled', 'disabled') if $.fn.select2 + $fieldsAndBtns.not(fieldsAndBtnsSelector).attr('disabled', 'disabled') if method != 'disable' # hide or default $parent.find(fieldsSelector).filter('[required]').removeAttr('required').attr('data-dependent-fields-required', 'required') $parent.hide(duration)