diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml
index 38a28237c2..d2f1fa8a3c 100644
--- a/.rubocop_todo.yml
+++ b/.rubocop_todo.yml
@@ -131,6 +131,8 @@ Lint/UnneededSplatExpansion:
# ExcludedMethods: refine
Metrics/BlockLength:
Max: 1081
+ Exclude:
+ - 'spec/integration/actions/index_spec.rb'
# Offense count: 7
Naming/AccessorMethodName:
diff --git a/app/assets/javascripts/rails_admin/ra.filter-box.js b/app/assets/javascripts/rails_admin/ra.filter-box.js
index c6a41f2462..7ddd32976c 100644
--- a/app/assets/javascripts/rails_admin/ra.filter-box.js
+++ b/app/assets/javascripts/rails_admin/ra.filter-box.js
@@ -11,6 +11,7 @@
var field_value = options['value'];
var field_operator = options['operator'];
var select_options = options['select_options'];
+ var required = options['required'];
var index = options['index'];
var value_name = 'f[' + field_name + '][' + index + '][v]';
var operator_name = 'f[' + field_name + '][' + index + '][o]';
@@ -24,9 +25,13 @@
.append('')
.append($('').prop('selected', field_value == "true").text(RailsAdmin.I18n.t("true")))
.append($('').prop('selected', field_value == "false").text(RailsAdmin.I18n.t("false")))
- .append('')
- .append($('').prop('selected', field_value == "_present").text(RailsAdmin.I18n.t("is_present")))
- .append($('').prop('selected', field_value == "_blank").text(RailsAdmin.I18n.t("is_blank")));
+ if (!required) {
+ control.append([
+ '',
+ $('').prop('selected', field_value == "_present").text(RailsAdmin.I18n.t("is_present")),
+ $('').prop('selected', field_value == "_blank").text(RailsAdmin.I18n.t("is_blank"))
+ ])
+ }
break;
case 'date':
additional_control =
@@ -56,9 +61,13 @@
.append($('').prop('selected', field_operator == "yesterday").text(RailsAdmin.I18n.t("yesterday")))
.append($('').prop('selected', field_operator == "this_week").text(RailsAdmin.I18n.t("this_week")))
.append($('').prop('selected', field_operator == "last_week").text(RailsAdmin.I18n.t("last_week")))
- .append('')
- .append($('').prop('selected', field_operator == "_not_null").text(RailsAdmin.I18n.t("is_present")))
- .append($('').prop('selected', field_operator == "_null").text(RailsAdmin.I18n.t("is_blank")));
+ if (!required) {
+ control.append([
+ '',
+ $('').prop('selected', field_operator == "_not_null").text(RailsAdmin.I18n.t("is_present")),
+ $('').prop('selected', field_operator == "_null").text(RailsAdmin.I18n.t("is_blank"))
+ ])
+ }
additional_control = additional_control ||
$('')
.css('display', (!field_operator || field_operator == "default") ? 'inline-block' : 'none')
@@ -84,10 +93,14 @@
.prop('name', multiple_values ? undefined : value_name)
.data('name', value_name)
.append('')
- .append($('').prop('selected', field_value == "_present").text(RailsAdmin.I18n.t("is_present")))
- .append($('').prop('selected', field_value == "_blank").text(RailsAdmin.I18n.t("is_blank")))
- .append('')
- .append(select_options)
+ if (!required) {
+ control.append([
+ $('').prop('selected', field_value == "_present").text(RailsAdmin.I18n.t("is_present")),
+ $('').prop('selected', field_value == "_blank").text(RailsAdmin.I18n.t("is_blank")),
+ ''
+ ])
+ }
+ control.append(select_options)
.add(
$('')
.css('display', multiple_values ? 'inline-block' : 'none')
@@ -111,9 +124,13 @@
.append($('').prop('selected', field_operator == "is").text(RailsAdmin.I18n.t("is_exactly")))
.append($('').prop('selected', field_operator == "starts_with").text(RailsAdmin.I18n.t("starts_with")))
.append($('').prop('selected', field_operator == "ends_with").text(RailsAdmin.I18n.t("ends_with")))
- .append('')
- .append($('').prop('selected', field_operator == "_present").text(RailsAdmin.I18n.t("is_present")))
- .append($('').prop('selected', field_operator == "_blank").text(RailsAdmin.I18n.t("is_blank")));
+ if (!required) {
+ control.append([
+ '',
+ $('').prop('selected', field_operator == "_present").text(RailsAdmin.I18n.t("is_present")),
+ $('').prop('selected', field_operator == "_blank").text(RailsAdmin.I18n.t("is_blank"))
+ ])
+ }
additional_control = $('')
.css('display', field_operator == "_present" || field_operator == "_blank" ? 'none' : 'inline-block')
.prop('name', value_name)
@@ -126,9 +143,13 @@
.prop('name', operator_name)
.append($('').prop('selected', field_operator == "default").text(RailsAdmin.I18n.t("number")))
.append($('').prop('selected', field_operator == "between").text(RailsAdmin.I18n.t("between_and_")))
- .append('')
- .append($('').prop('selected', field_operator == "_not_null").text(RailsAdmin.I18n.t("is_present")))
- .append($('').prop('selected', field_operator == "_null").text(RailsAdmin.I18n.t("is_blank")));
+ if (!required) {
+ control.append([
+ '',
+ $('').prop('selected', field_operator == "_not_null").text(RailsAdmin.I18n.t("is_present")),
+ $('').prop('selected', field_operator == "_null").text(RailsAdmin.I18n.t("is_blank"))
+ ])
+ }
additional_control =
$('')
.css('display', (!field_operator || field_operator == "default") ? 'inline-block' : 'none')
@@ -193,6 +214,7 @@
value: $(this).data('field-value'),
operator: $(this).data('field-operator'),
select_options: $(this).data('field-options'),
+ required: $(this).data('field-required'),
index: $.now().toString().slice(6,11),
datetimepicker_format: $(this).data('field-datetimepicker-format')
});
diff --git a/app/helpers/rails_admin/main_helper.rb b/app/helpers/rails_admin/main_helper.rb
index a6162c9b1f..402797ea0a 100644
--- a/app/helpers/rails_admin/main_helper.rb
+++ b/app/helpers/rails_admin/main_helper.rb
@@ -77,6 +77,7 @@ def ordered_filter_options
options[:value] = filter_hash['v']
options[:label] = field.label
options[:operator] = filter_hash['o']
+ options[:required] = field.required
options
end if ordered_filters
end
diff --git a/app/views/rails_admin/main/index.html.haml b/app/views/rails_admin/main/index.html.haml
index df1f5f420c..5e7597ff4f 100644
--- a/app/views/rails_admin/main/index.html.haml
+++ b/app/views/rails_admin/main/index.html.haml
@@ -35,7 +35,7 @@
- else
- ''
%li
- %a{href: '#', :"data-field-label" => field.label, :"data-field-name" => field.name, :"data-field-options" => field_options.html_safe, :"data-field-type" => field.type, :"data-field-value" => "", :"data-field-datetimepicker-format" => (field.try(:parser) && field.parser.to_momentjs)}= capitalize_first_letter(field.label)
+ %a{href: '#', :"data-field-label" => field.label, :"data-field-name" => field.name, :"data-field-options" => field_options.html_safe, :"data-field-required" => field.required.to_s, :"data-field-type" => field.type, :"data-field-value" => "", :"data-field-datetimepicker-format" => (field.try(:parser) && field.parser.to_momentjs)}= capitalize_first_letter(field.label)
%style
- properties.select{ |p| p.column_width.present? }.each do |property|
diff --git a/spec/integration/actions/index_spec.rb b/spec/integration/actions/index_spec.rb
index 4eadf32979..19f2331d37 100644
--- a/spec/integration/actions/index_spec.rb
+++ b/spec/integration/actions/index_spec.rb
@@ -59,6 +59,27 @@
@comment = FactoryBot.create(:comment, commentable: @players[2])
end
+ it 'hides redundant filter options for required fields', js: true do
+ RailsAdmin.config Player do
+ list do
+ field :name do
+ required true
+ end
+ field :team
+ end
+ end
+
+ visit index_path(model_name: 'player', f: {name: {'1' => {v: ''}}, team: {'2' => {v: ''}}})
+
+ within(:select, name: 'f[name][1][o]') do
+ expect(page.all('option').map(&:value)).to_not include('_present', '_blank')
+ end
+
+ within(:select, name: 'f[team][2][o]') do
+ expect(page.all('option').map(&:value)).to include('_present', '_blank')
+ end
+ end
+
it 'allows to query on any attribute' do
RailsAdmin.config Player do
list do
@@ -294,6 +315,7 @@
type: 'string',
value: '',
operator: nil,
+ required: true,
},
{
index: 2,
@@ -302,6 +324,7 @@
type: 'belongs_to_association',
value: '',
operator: nil,
+ required: false,
},
]
end