Skip to content

Commit 4847036

Browse files
author
Nils Henning
committed
[FEATURE] refactor select component
1 parent 9624264 commit 4847036

File tree

11 files changed

+100
-122
lines changed

11 files changed

+100
-122
lines changed

app/concepts/matestack/ui/core/form/checkbox/checkbox.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ def response
1515
if checkbox_options
1616
checkbox_options.to_a.each do |item|
1717
input html_attributes.merge(
18-
attributes: vue_attributes.merge(ref: "select.multiple.#{attr_key}"),
18+
attributes: vue_attributes,
1919
type: :checkbox,
2020
id: "#{id_for_item(item_value(item))}",
2121
name: item_name(item),
@@ -35,7 +35,7 @@ def response
3535
def vue_attributes
3636
(options[:attributes] || {}).merge({
3737
"@change": change_event,
38-
ref: "input.#{attr_key}",
38+
ref: "select.multiple.#{attr_key}",
3939
'init-value': init_value,
4040
'v-bind:class': "{ '#{input_error_class}': #{error_key} }",
4141
'value-type': value_type,

app/concepts/matestack/ui/core/form/input/input.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ def custom_options_validation
4343
raise "included form config is missing, please add ':include' to parent form component" if @included_config.nil?
4444
end
4545

46+
def attr_key
47+
super + "#{'[]' if multiple && type == :file}"
48+
end
49+
4650
private
4751

4852
def parse_value(value)

app/concepts/matestack/ui/core/form/radio/radio.rb

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ class Radio < Matestack::Ui::Core::Component::Static
88
include Matestack::Ui::Core::Form::HasErrors
99

1010
requires :key
11-
optional :value, :false_value, :multiple, :init, for: { as: :input_for }, label: { as: :input_label }, options: { as: :radio_options }
11+
optional :multiple, :init, for: { as: :input_for }, label: { as: :input_label }, options: { as: :radio_options }
1212

1313
def response
1414
radio_options.to_a.each do |item|
1515
input html_attributes.merge(
16-
attributes: vue_attributes.merge(ref: "select.#{attr_key}"),
16+
attributes: vue_attributes,
1717
type: :radio,
1818
id: "#{id_for_item(item_value(item))}",
1919
name: item_name(item),
@@ -51,10 +51,6 @@ def item_label(item)
5151
item.is_a?(Array) ? item.first : item
5252
end
5353

54-
def checked_value
55-
value || 1
56-
end
57-
5854
def v_model_type
5955
if radio_options && item_value(radio_options.first).is_a?(Integer)
6056
'v-model.number'
@@ -68,7 +64,7 @@ def change_event
6864
end
6965

7066
def id_for_item(value)
71-
"#{html_attributes[:id]}_#{value}"
67+
"#{html_attributes[:id] || attr_key}_#{value}"
7268
end
7369

7470
end
Lines changed: 9 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,9 @@
1-
- if options[:label]
2-
3-
%label=options[:label]
4-
5-
- if options[:type] == :dropdown
6-
7-
%select{@tag_attributes,
8-
"#{model_binding}" => input_key,
9-
ref: "select.#{attr_key}",
10-
"@change": "inputChanged(\"#{attr_key}\")",
11-
"init-value": init_value,
12-
"value-type": options_type}
13-
%option{disabled: true}= options[:placeholder]
14-
- if options[:options].is_a?(Hash)
15-
- options[:options].each do |key, value|
16-
%option{value: key}=value
17-
- if options[:options].is_a?(Array)
18-
- options[:options].each do |option|
19-
%option{value: option}=option
20-
= render_errors
21-
22-
- if options[:type] == :radio
23-
24-
%div{id: component_id, ref: "select.#{attr_key}", "init-value": init_value}
25-
- if options[:options].is_a?(Hash)
26-
- options[:options].each do |key, value|
27-
%input{@tag_attributes.except(:id),
28-
type: :radio,
29-
id: id_for_option(value),
30-
"#{model_binding}": input_key,
31-
"@change": "inputChanged(\"#{attr_key}\")",
32-
"value-type": options_type,
33-
name: "#{attr_key}_#{key}",
34-
value: key}/
35-
%label{for: id_for_option(value)}=value
36-
- if options[:options].is_a?(Array)
37-
- options[:options].each do |value|
38-
%input{@tag_attributes.except(:id),
39-
type: :radio,
40-
id: id_for_option(value),
41-
"#{model_binding}": input_key,
42-
"@change": "inputChanged(\"#{attr_key}\")",
43-
"value-type": options_type,
44-
name: "#{attr_key}_#{value}",
45-
value: value}/
46-
%label{for: id_for_option(value)}=value
47-
= render_errors
1+
- if input_label
2+
%label= input_label
3+
4+
%select{html_attributes.merge(vue_attributes)}
5+
- if placeholder
6+
%option{value: 'null', disabled: true, selected: init_value.nil?}= placeholder
7+
- select_options.to_a.each do |item|
8+
%option{value: item_value(item), disabled: item_disabled(item)}= item_label(item)
9+
= render_errors

app/concepts/matestack/ui/core/form/select/select.rb

Lines changed: 59 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -5,74 +5,83 @@ class Select < Matestack::Ui::Core::Component::Static
55
include Matestack::Ui::Core::Form::Utils
66
include Matestack::Ui::Core::Form::HasErrors
77

8+
html_attributes :autofocus, :disabled, :form, :multiple, :name, :required, :size
9+
810
requires :key
9-
requires options: { as: :select_options }
11+
optional :multiple, :init, :placeholder, :disabled_values,
12+
for: { as: :input_for },
13+
label: { as: :input_label },
14+
options: { as: :select_options }
1015

11-
def setup
12-
if @tag_attributes[:id].nil?
13-
@tag_attributes[:id] = attr_key
14-
end
16+
# def response
17+
# radio_options.to_a.each do |item|
18+
# input html_attributes.merge(
19+
# attributes: vue_attributes.merge(ref: "select.#{attr_key}"),
20+
# type: :radio,
21+
# id: "#{id_for_item(item_value(item))}",
22+
# name: item_name(item),
23+
# value: item_value(item),
24+
# )
25+
# label text: item_label(item), for: id_for_item(item_value(item))
26+
# end
27+
# render_errors
28+
# end
29+
30+
# def html_options
31+
# html_attributes.merge(
32+
# attributes: vue_attributes,
33+
# )
34+
# end
35+
36+
def vue_attributes
37+
(options[:attributes] || {}).merge({
38+
"@change": change_event,
39+
ref: vue_ref,
40+
'init-value': init_value || [],
41+
'v-bind:class': "{ '#{input_error_class}': #{error_key} }",
42+
'value-type': value_type,
43+
"#{v_model_type}": input_key,
44+
})
1545
end
1646

17-
def attr_key
18-
key.to_s
47+
def vue_ref
48+
"select#{'.multiple' if multiple}.#{attr_key}"
1949
end
2050

21-
def option_values
22-
values = select_options if select_options.is_a?(Array)
23-
values = select_options.keys if select_options.is_a?(Hash)
24-
return values
51+
def value_type
52+
item_value(select_options.first).is_a?(Integer) ? Integer : nil
2553
end
2654

27-
def options_type
28-
return Integer if option_values.first.is_a?(Integer)
29-
return String if option_values.first.is_a?(String)
55+
def item_value(item)
56+
item.is_a?(Array) ? item.last : item
3057
end
3158

32-
def model_binding
59+
def item_name(item)
60+
"#{attr_key}_#{item.is_a?(Array) ? item.first : item}"
61+
end
3362

34-
if option_values.first.is_a?(Integer)
35-
return "v-model.number"
36-
else
37-
return "v-model"
38-
end
63+
def item_disabled(item)
64+
disabled_values.present? && disabled_values.include?(item_value(item))
3965
end
4066

41-
def init_value
42-
unless options[:init].nil?
43-
return options[:init]
44-
end
67+
def item_label(item)
68+
item.is_a?(Array) ? item.first : item
69+
end
4570

46-
unless options[:for].nil?
47-
value = options[:for].send(key)
48-
if [true, false].include? value
49-
value ? 1 : 0
50-
else
51-
return value
52-
end
71+
def v_model_type
72+
if select_options && item_value(select_options.first).is_a?(Integer) && !multiple
73+
'v-model.number'
5374
else
54-
unless @included_config.nil? && @included_config[:for].nil?
55-
if @included_config[:for].respond_to?(key)
56-
value = @included_config[:for].send(key)
57-
if [true, false].include? value
58-
value ? 1 : 0
59-
else
60-
return value
61-
end
62-
else
63-
if @included_config[:for].is_a?(Symbol) || @included_config[:for].is_a?(String)
64-
return nil
65-
end
66-
if @included_config[:for].is_a?(Hash)
67-
return @included_config[:for][key]
68-
end
69-
end
70-
end
75+
'v-model'
7176
end
7277
end
7378

74-
def id_for_option value
75-
return "#{@tag_attributes[:id]}_#{value}"
79+
def change_event
80+
"inputChanged('#{attr_key}')"
81+
end
82+
83+
def id_for_item(value)
84+
"#{html_attributes[:id]}_#{value}"
7685
end
7786

7887
end

app/concepts/matestack/ui/core/form/utils.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
module Matestack::Ui::Core::Form::Utils
22

33
def input_key
4-
"data['#{key.to_s}']"
4+
"data['#{attr_key.to_s}']"
55
end
66

77
def input_wrapper
@@ -18,9 +18,9 @@ def input_wrapper
1818

1919
def attr_key
2020
if input_wrapper.nil?
21-
return "#{key.to_s}#{'[]' if multiple}"
21+
return "#{key.to_s}"
2222
else
23-
return "#{input_wrapper}.#{key.to_s}#{'[]' if multiple}"
23+
return "#{input_wrapper}.#{key.to_s}"
2424
end
2525
end
2626

app/concepts/matestack/ui/core/view/view.rb

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,6 @@ class View < Matestack::Ui::Core::Component::Static
99
optional view: { as: :view_path } # Specify a view path to render
1010
optional partial: { as: :partial_path } # Specifiy a partial to render
1111

12-
def vue_js_component_name
13-
'matestack-ui-core-rails-view'
14-
end
15-
1612
def include_partial
1713
controller = @view_context.present? ? @view_context.controller : options[:matestack_context][:controller]
1814
if view_path
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
Matestack::Ui::DynamicComponent = Matestack::Ui::Core::Component::Dynamic
2+
Matestack::Ui::VueJsComponent = Matestack::Ui::Core::Component::Static
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
Matestack::Ui::StaticComponent = Matestack::Ui::Core::Component::Static
2+
Matestack::Ui::Component = Matestack::Ui::Core::Component::Static

spec/0.8/components/dynamic/form/form_spec.rb

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ class ExamplePage < Matestack::Ui::Page
243243
def response
244244
form form_config, :include do
245245
form_select id: "my-array-test-dropdown", key: :array_input, type: :dropdown, options: ["Array Option 1","Array Option 2"]
246-
form_select id: "my-hash-test-dropdown", key: :hash_input, type: :dropdown, options: { "1": "Hash Option 1", "2": "Hash Option 2" }
246+
form_select id: "my-hash-test-dropdown", key: :hash_input, type: :dropdown, options: { "Hash Option 1": 1, "Hash Option 2": 2 }
247247
form_submit do
248248
button text: "Submit me!"
249249
end
@@ -267,7 +267,7 @@ def form_config
267267
select "Array Option 2", from: "my-array-test-dropdown"
268268
select "Hash Option 2", from: "my-hash-test-dropdown"
269269
expect_any_instance_of(FormTestController).to receive(:expect_params)
270-
.with(hash_including(my_object: { array_input: "Array Option 2", hash_input: "2" }))
270+
.with(hash_including(my_object: { array_input: "Array Option 2", hash_input: 2 }))
271271
click_button "Submit me!"
272272
end
273273

@@ -276,7 +276,7 @@ class ExamplePage < Matestack::Ui::Page
276276
def response
277277
form form_config, :include do
278278
form_select id: "my-array-test-dropdown", key: :array_input, type: :dropdown, options: ["Array Option 1","Array Option 2"], init: "Array Option 1"
279-
form_select id: "my-hash-test-dropdown", key: :hash_input, type: :dropdown, options: { "1": "Hash Option 1", "2": "Hash Option 2" }, init: "1"
279+
form_select id: "my-hash-test-dropdown", key: :hash_input, type: :dropdown, options: { "Hash Option 1": 1, "Hash Option 2": 2 }, init: 1
280280
form_submit do
281281
button text: "Submit me!"
282282
end
@@ -297,11 +297,11 @@ def form_config
297297

298298
visit "/example"
299299
expect(page).to have_field("my-array-test-dropdown", with: "Array Option 1")
300-
expect(page).to have_field("my-hash-test-dropdown", with: "1")
300+
expect(page).to have_field("my-hash-test-dropdown", with: 1)
301301
select "Array Option 2", from: "my-array-test-dropdown"
302302
select "Hash Option 2", from: "my-hash-test-dropdown"
303303
expect_any_instance_of(FormTestController).to receive(:expect_params)
304-
.with(hash_including(my_object: { array_input: "Array Option 2", hash_input: "2" }))
304+
.with(hash_including(my_object: { array_input: "Array Option 2", hash_input: 2 }))
305305
click_button "Submit me!"
306306
end
307307

@@ -322,7 +322,7 @@ def response
322322
form form_config, :include do
323323
form_input id: "description", key: :description, type: :text
324324
# TODO: Provide better Enum Options API
325-
form_select id: "status", key: :status, type: :dropdown, options: TestModel.statuses.invert, init: TestModel.statuses[@test_model.status]
325+
form_select id: "status", key: :status, type: :dropdown, options: TestModel.statuses, init: TestModel.statuses[@test_model.status]
326326
form_submit do
327327
button text: "Submit me!"
328328
end
@@ -368,7 +368,7 @@ def response
368368
form form_config, :include do
369369
form_input id: "description", key: :description, type: :text
370370
# TODO: Provide better Enum Options API
371-
form_select id: "status", key: :status, type: :dropdown, options: TestModel.statuses.invert, init: TestModel.statuses[@test_model.status]
371+
form_select id: "status", key: :status, type: :dropdown, options: TestModel.statuses, init: TestModel.statuses[@test_model.status]
372372
form_submit do
373373
button text: "Submit me!"
374374
end
@@ -413,7 +413,7 @@ def prepare
413413
def response
414414
form form_config, :include do
415415
# TODO: Provide better Enum Options API
416-
form_select id: "status", key: :status, type: :dropdown, options: TestModel.statuses.invert, init: TestModel.statuses[@test_model.status]
416+
form_select id: "status", key: :status, type: :dropdown, options: TestModel.statuses, init: TestModel.statuses[@test_model.status]
417417
form_submit do
418418
button text: "Submit me!"
419419
end
@@ -445,7 +445,7 @@ class ExamplePage < Matestack::Ui::Page
445445
def response
446446
form form_config, :include do
447447
form_select id: "my-array-test-dropdown", key: :array_input, type: :dropdown, options: ["Array Option 1","Array Option 2"], class: "form-control"
448-
form_select id: "my-hash-test-dropdown", key: :hash_input, type: :dropdown, options: { "1": "Hash Option 1", "2": "Hash Option 2" }, class: "form-control"
448+
form_select id: "my-hash-test-dropdown", key: :hash_input, type: :dropdown, options: { "Hash Option 1": 1, "Hash Option 2": 2 }, class: "form-control"
449449
form_submit do
450450
button text: "Submit me!"
451451
end

0 commit comments

Comments
 (0)