Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
open-source
aoz-003
Commits
96b0c7f2
Verified
Commit
96b0c7f2
authored
Jul 16, 2018
by
Kaspar Vollenweider
👻
Browse files
refactor dropdown filter helper
parent
7dd80924
Changes
2
Hide whitespace changes
Inline
Side-by-side
app/helpers/filter_dropdown_helper.rb
View file @
96b0c7f2
module
FilterDropdownHelper
def
custom_filter_dropdown
(
name
,
*
filters
)
filter_keys
=
filters
.
map
{
|
filter
|
filter
[
:q
]
}
filter_keys
+=
filters
.
map
{
|
filter
|
filter
[
:qs
]
}
filters
=
custom_filter_dropdown_filters
(
filters
,
filter_keys
)
render_filter_dropdown
top_text:
name
+
custom_text_end
(
filters
),
all_url:
filter_keys
,
filters:
filters
end
def
custom_filter_dropdown_filters
(
filters
,
filter_keys
)
filters
.
map
do
|
filter
|
filter
[
:active
]
=
filter_active?
(
filter
[
:q
],
filter
[
:value
])
excludes
=
filter_keys
.
reject
{
|
key
|
key
==
filter
[
:q
]
}
excludes
=
excludes
.
reject
{
|
key
|
filter
[
:qs
]
&
.
include?
key
}
if
filter
[
:qs
]
&
.
any?
q_args
=
params_except
(
'page'
).
merge
(
q:
custom_filter_q_arg
(
*
filter
.
values_at
(
:q
,
:qs
,
:value
),
*
excludes
)
)
filter
.
merge
(
url:
url_for
(
q_args
),
link_class:
list_filter_link_class
(
filter
[
:active
]))
end
end
def
custom_filter_q_arg
(
filter
,
multi_qs
,
value
,
*
excludes
)
q_values
=
search_parameters
.
merge
(
multi_qs
.
map
{
|
q
|
[
q
,
value
.
to_s
]
}.
to_h
)
if
multi_qs
(
q_values
||
search_parameters
).
except
(
*
excludes
).
merge
(
"
#{
filter
}
"
:
value
.
to_s
)
end
def
list_filter_dropdown
(
attribute
,
collection
=
nil
)
filter_links
=
collection
.
map
do
|
item
|
list_filter_link
(
"
#{
attribute
}
_eq"
.
to_sym
,
item
)
attribute_q
=
"
#{
attribute
}
_eq"
.
to_sym
filters
=
collection
.
map
do
|
item
|
filter
=
{
q:
attribute_q
,
value:
item
,
active:
filter_active?
(
attribute_q
,
item
)
}
filter
.
merge
(
text:
translate_value
(
*
filter
.
values_at
(
:value
,
:q
)),
url:
filter_dropdown_url
(
*
filter
.
values_at
(
:q
,
:value
)),
link_class:
list_filter_link_class
(
*
filter
.
values_at
(
:active
,
:value
,
:q
))
)
end
dropdown_list_filter
(
attribute
,
filter_links
,
"
#{
attribute
}
_eq"
.
to_sym
)
render_filter_dropdown
top_text:
toggler_text
(
attribute
.
to_sym
,
[
attribute_q
]),
all_url:
attribute_q
,
filters:
filters
end
def
boolean_filter_dropdown
(
attribute_group
,
collection
=
nil
)
q_filters
=
collection
.
map
{
|
attribute
|
"
#{
attribute
}
_true"
.
to_sym
}
filter_links
=
q_filters
.
each_with_index
.
map
do
|
q_filter
,
index
|
list_filter_link
(
q_filter
,
collection
[
index
],
bool_filter:
true
)
def
boolean_filter_dropdown
(
attribute
,
collection
=
nil
)
filters
=
collection
.
map
do
|
filter
|
q
=
"
#{
filter
}
_true"
.
to_sym
filter
=
{
q:
q
,
active:
filter_active?
(
q
,
true
)
}
filter
.
merge
(
text:
translate_value
(
filter
,
q
),
url:
filter_dropdown_url
(
q
,
search_parameters
[
filter
],
true
),
link_class:
list_filter_link_class
(
filter
[
:active
])
)
end
dropdown_list_filter
(
attribute_group
,
filter_links
,
*
q_filters
)
render_filter_dropdown
top_text:
toggler_text
(
attribute
,
filters
.
pluck
(
:q
)),
all_url:
filters
.
pluck
(
:q
),
filters:
filters
end
# Creates a filter dropdown that filters a boolean attribute to either true or false
...
...
@@ -21,77 +61,68 @@ module FilterDropdownHelper
# on_text - text for filtering true
# off_text - text for filtering false
def
boolean_toggler_filter_dropdown
(
attribute
,
attr_text
,
on_text
,
off_text
)
filter
=
"
#{
attribute
}
_eq"
li_dropdown
do
concat
dropdown_toggle_link
(
attr_text
+
bool_toggler_text_end
(
filter
,
on_text
,
off_text
))
concat
dropdown_ul
(
tag
.
li
{
all_link_to
(
filter
)
})
{
concat
li_a_element
(
on_text
,
bool_toggle_url
(
filter
,
true
),
class:
list_filter_link_class
(
filter
,
'true'
))
concat
li_a_element
(
off_text
,
bool_toggle_url
(
filter
,
false
),
class:
list_filter_link_class
(
filter
,
'false'
))
}
end
filters
=
{
q:
"
#{
attribute
}
_eq"
}
true_active
=
filter_active?
(
filters
[
:q
],
'true'
)
false_active
=
true_active
?
false
:
filter_active?
(
filters
[
:q
],
'false'
)
render_filter_dropdown
(
all_url:
filters
[
:q
],
filters:
[
filters
.
merge
(
text:
on_text
,
url:
bool_toggle_url
(
filters
[
:q
],
true
),
link_class:
list_filter_link_class
(
true_active
)),
filters
.
merge
(
text:
off_text
,
url:
bool_toggle_url
(
filters
[
:q
],
false
),
link_class:
list_filter_link_class
(
false_active
))
],
top_text:
attr_text
+
bool_toggler_text_end
(
filters
[
:q
],
on_text
,
off_text
))
end
# Creates a dropdown with multiple fully customizable filters
# Params:
# name - the displayed filter group name
# filters - rest parameters of n hashes
# :q - symbol defining the Ransack filter (eg. attribute_eq)
# :value - string passed to the Ransack filter in this link (eg. true)
# :text - string for frontend display
def
custom_filter_dropdown
(
name
,
*
filters
)
filter_keys
=
filters
.
map
{
|
filter
|
filter
[
:q
]
}
filter_keys
+=
filters
.
map
{
|
filter
|
filter
[
:qs
]
}
li_dropdown
do
concat
dropdown_toggle_link
(
name
+
custom_text_end
(
filters
))
concat
dropdown_ul
(
tag
.
li
{
all_link_to
(
filter_keys
)
})
{
filters
.
map
do
|
filter
|
concat
li_a_element
(
filter
[
:text
],
custom_filter_url
(
filter
[
:q
],
filter
[
:qs
],
filter
[
:value
],
*
filter_keys
.
reject
{
|
key
|
key
==
filter
[
:q
]
}.
reject
{
|
key
|
filter
[
:qs
]
&
.
include?
key
}
),
class:
list_filter_link_class
(
filter
[
:q
],
filter
[
:value
]))
end
}
end
def
render_filter_dropdown
(
locals
)
render
template:
'application/filter_dropdown'
,
locals:
locals
.
merge
(
all_url:
all_url_for
(
locals
[
:all_url
]))
end
def
custom_text_end
(
filters
)
in_search
=
custom_text_filter_in_search
(
filters
)
in_search
=
filters
.
find_all
{
|
filter
|
search_parameters
.
key?
(
filter
[
:q
].
to_s
)
}
if
in_search
.
blank?
''
elsif
in_search
.
size
==
1
":
#{
in_search
.
first
[
:text
]
}
"
' '
else
"
:
#{
custom_text_filter_value_in_search
(
in_search
)
[
:text
]
}
"
'
:
%s'
%
[
in_search
.
find
{
|
h
|
h
[
:active
]
}
[
:text
]
]
end
end
def
custom_text_filter_in_search
(
filters
)
filter
s
.
find_all
do
|
filter
|
search_parameters
.
keys
.
include?
filter
[
:q
].
to_s
end
def
all_url_for
(
q_
filters
)
filter
=
search_parameters
.
except
(
*
q_
filter
s
)
filter
=
{
all:
true
}
if
filter
.
empty?
url_for
(
q:
filter
)
end
def
custom_text_filter_value_in_search
(
in_search
)
in_search
.
find
do
|
filter
|
filter
[
:value
].
to_s
==
search_parameters
[
filter
[
:q
]].
to_s
end
def
filter_dropdown_url
(
q_filter
,
filter_attribute
,
bool
=
false
)
q_params
=
if
filter_active?
(
q_filter
,
bool
||
filter_attribute
)
search_parameters
.
except
(
q_filter
)
else
search_parameters
.
merge
(
q_filter
=>
bool
||
filter_attribute
)
end
url_for
(
params_except
(
'page'
).
merge
(
q:
q_params
))
end
def
custom_filter_url
(
filter
,
multi_qs
,
value
,
*
excludes
)
q_values
=
search_parameters
.
except
(
*
excludes
).
merge
(
"
#{
filter
}
"
:
value
.
to_s
)
q_values
=
q_values
.
merge
(
multi_qs
.
map
{
|
q
|
[
q
,
value
.
to_s
]
}.
to_h
)
if
multi_qs
url_for
(
params_except
(
'page'
).
merge
(
q:
q_values
))
def
list_filter_link_class
(
active
,
value
=
nil
,
filter
=
nil
)
return
''
unless
active
if
[
:process_eq
,
:acceptance_eq
].
include?
filter
"bg-
#{
value
}
"
else
'bg-success'
end
end
def
bool_toggle_url
(
filter
,
toggle
=
false
)
url_for
(
params_except
(
'page'
).
merge
(
q:
search_parameters
.
merge
(
"
#{
filter
}
"
:
toggle
.
to_s
)))
end
def
toggler_text
(
attribute
,
q_filter
)
if
q_filter
.
size
>
1
||
search_parameters
[
q_filter
[
0
]].
nil?
t_attr
(
attribute
)
else
"
#{
t_attr
(
attribute
)
}
:
#{
translate_value
(
search_parameters
[
q_filter
[
0
]],
q_filter
)
}
"
end
end
def
bool_toggler_text_end
(
filter
,
on_text
,
off_text
)
case
search_parameters
[
filter
]
when
'true'
...
...
@@ -103,112 +134,24 @@ module FilterDropdownHelper
end
end
def
params_except
(
*
key
)
params
.
to_unsafe_hash
.
except
(
*
key
)
end
def
dropdown_list_filter
(
attribute
,
filter_links
,
*
q_filters
)
li_dropdown
do
concat
dropdown_toggle_link
(
toggler_text
(
attribute
,
q_filters
))
concat
dropdown_menu
(
filter_links
,
q_filters
)
end
end
def
li_dropdown
tag
.
li
class:
'dropdown'
do
yield
end
end
def
list_filter_link
(
q_filter
,
filter_attribute
,
bool_filter:
false
)
tag
.
li
do
link_to
(
filter_url
(
q_filter
,
bool_filter
,
filter_attribute
),
class:
list_filter_link_class
(
q_filter
,
bool_filter
||
filter_attribute
)
)
do
translate_value
(
filter_attribute
,
q_filter
)
end
end
end
def
list_filter_link_class
(
filter
,
value
)
if
!
filter_active?
(
filter
,
value
)
''
elsif
[
:process_eq
,
:acceptance_eq
].
include?
filter
"bg-
#{
value
}
"
else
'bg-success'
end
end
def
li_a_element
(
text
,
href
,
*
options
)
tag
.
li
do
link_to
(
text
,
href
,
*
options
)
end
end
def
filter_url
(
q_filter
,
bool_filter
,
filter_attribute
)
if
filter_active?
(
q_filter
,
bool_filter
||
filter_attribute
)
url_for
(
params_except
(
'page'
).
merge
(
q:
search_parameters
.
except
(
q_filter
)))
else
filter_parameter
=
{
q_filter
=>
bool_filter
||
filter_attribute
}
url_for
(
params_except
(
'page'
).
merge
(
q:
search_parameters
.
merge
(
filter_parameter
)))
end
end
def
filter_active?
(
filter
,
value
)
value
.
present?
&&
search_parameters
[
filter
].
to_s
==
value
.
to_s
end
def
dropdown_menu
(
filter_links
,
q_filters
)
dropdown_ul
(
content_tag
(
:li
,
all_link_to
(
q_filters
)))
do
filter_links
.
each
{
|
item
|
concat
item
}
end
end
def
clear_filter_button
filter
=
{
all:
true
,
s:
params
.
dig
(
:q
,
:s
)
}.
compact
button_link
t
(
'clear_filters'
),
url_for
(
q:
filter
),
dimension: :sm
end
def
all_link_to
(
q_filters
)
filter
=
search_parameters
.
except
(
*
q_filters
)
filter
=
{
all:
true
}
if
filter
.
empty?
link_to
t
(
'all'
),
url_for
(
q:
filter
)
end
def
dropdown_ul
(
all_list_link
)
tag
.
ul
class:
'dropdown-menu'
do
concat
all_list_link
concat
tag
.
li
class:
'divider'
,
role:
'separator'
yield
end
end
def
dropdown_toggle_link
(
title_text
)
tag
.
a
dropdown_toggler_options
do
concat
title_text
+
' '
concat
tag
.
span
class:
'caret'
end
end
def
toggler_text
(
attribute
,
q_filter
)
return
t_attr
(
attribute
)
if
q_filter
.
size
>
1
||
search_parameters
[
q_filter
[
0
]].
nil?
'%{att}: %{val}'
%
{
att:
t_attr
(
attribute
),
val:
translate_value
(
search_parameters
[
q_filter
[
0
]],
q_filter
)
}
def
params_except
(
*
key
)
params
.
to_unsafe_hash
.
except
(
*
key
)
end
def
dropdown_toggler_options
{
class:
'dropdown-toggle btn btn-default btn-sm'
,
role:
'button'
,
href:
'#'
,
data:
{
toggle:
'dropdown'
},
aria:
{
expanded:
'false'
,
haspopup:
'true'
}
}
def
filter_active?
(
filter
,
value
)
value
.
present?
&&
search_parameters
[
filter
].
to_s
==
value
.
to_s
end
def
translate_value
(
filter_attribute
,
q_filter
)
return
t
(
'all'
)
if
filter_attribute
.
blank?
if
[
Department
,
GroupOfferCategory
].
include?
(
filter_attribute
.
class
)
||
filter_attribute
.
to_s
.
to_i
!=
0
binding
.
pry
return
filter_attribute
.
to_s
end
q_filter
=
q_filter
.
is_a?
(
Symbol
)
?
q_filter
.
to_s
:
q_filter
.
first
.
to_s
...
...
app/views/application/filter_dropdown.html.slim
0 → 100644
View file @
96b0c7f2
li
.dropdown
a
*{
class:
'dropdown-toggle
btn
btn-default
btn-sm',
role:
'button',
href:
'#',
data
:
{
toggle:
'dropdown'
},
aria:
{
expanded:
'false',
haspopup:
'true'
}
}
=
>
top_text
span
.caret
ul
.dropdown-menu
li
=
link_to
t
(
'all'
),
all_url
li
.divider
[
role
=
"separator"
]
-
filters
.
each
do
|
filter
|
li
=
link_to
filter
[
:text
],
filter
[
:url
],
class:
filter
[
:link_class
]
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment