ezframe 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +2 -0
- data/exe/check_column_yml +1 -1
- data/exe/dbmigrate +112 -90
- data/lib/ezframe.rb +6 -1
- data/lib/ezframe/auth.rb +31 -22
- data/lib/ezframe/column_set.rb +63 -37
- data/lib/ezframe/column_type.rb +85 -49
- data/lib/ezframe/config.rb +4 -4
- data/lib/ezframe/controller.rb +6 -6
- data/lib/ezframe/database.rb +20 -13
- data/lib/ezframe/editor.rb +5 -5
- data/lib/ezframe/editor_common.rb +56 -0
- data/lib/ezframe/{logger.rb → ezlog.rb} +7 -6
- data/lib/ezframe/ht.rb +1 -1
- data/lib/ezframe/html.rb +2 -2
- data/lib/ezframe/main_editor.rb +238 -0
- data/lib/ezframe/materialize.rb +4 -4
- data/lib/ezframe/message.rb +3 -3
- data/lib/ezframe/page_base.rb +9 -9
- data/lib/ezframe/route.rb +12 -9
- data/lib/ezframe/server.rb +10 -3
- data/lib/ezframe/single_page_editor.rb +205 -0
- data/lib/ezframe/sub_editor.rb +222 -0
- data/lib/ezframe/template.rb +1 -1
- data/lib/ezframe/util.rb +9 -5
- data/lib/ezframe/version.rb +1 -1
- metadata +8 -3
data/lib/ezframe/route.rb
CHANGED
@@ -4,6 +4,9 @@ module Ezframe
|
|
4
4
|
def choose(request, route_h = nil)
|
5
5
|
path_parts = request.path_info.split("/").drop(1)
|
6
6
|
route_h ||= Config[:route].deep_dup
|
7
|
+
unless route_h
|
8
|
+
raise "Config[:route] is not defined. It should be defined in config/route.yml"
|
9
|
+
end
|
7
10
|
# puts "config=#{Config[:route]}, route_h=#{route_h}"
|
8
11
|
args = {}
|
9
12
|
opts = {}
|
@@ -22,13 +25,13 @@ module Ezframe
|
|
22
25
|
while path_parts.length > 0
|
23
26
|
part = path_parts.shift
|
24
27
|
# break if part.empty?
|
25
|
-
#
|
28
|
+
# EzLog.info "part=#{part}, route_h=#{route_h.inspect}"
|
26
29
|
if route_h.has_key?(part.to_sym)
|
27
|
-
#
|
30
|
+
# EzLog.info "has_route: #{part}"
|
28
31
|
class_a.push(part)
|
29
32
|
if path_parts[0].to_i > 0
|
30
33
|
args[part.to_sym] = val = path_parts.shift
|
31
|
-
#
|
34
|
+
# EzLog.info "value: part=#{part}, val=#{val}"
|
32
35
|
end
|
33
36
|
route_h = route_h[part.to_sym]
|
34
37
|
break if route_h.nil?
|
@@ -41,7 +44,7 @@ module Ezframe
|
|
41
44
|
end
|
42
45
|
else
|
43
46
|
# routeに無ければ、メソッドを探す
|
44
|
-
#
|
47
|
+
# EzLog.info "no_route: #{part}"
|
45
48
|
klass = get_class(class_a[-1])
|
46
49
|
return [ 404 ] unless klass
|
47
50
|
instance = klass.new
|
@@ -49,7 +52,7 @@ module Ezframe
|
|
49
52
|
if instance.respond_to?(method_name)
|
50
53
|
return [instance, method_name, args, opts]
|
51
54
|
else
|
52
|
-
|
55
|
+
EzLog.info "undefined method: #{klass}.#{method_name}: full path=#{request.path_info}"
|
53
56
|
end
|
54
57
|
end
|
55
58
|
end
|
@@ -63,7 +66,7 @@ module Ezframe
|
|
63
66
|
part = "default"
|
64
67
|
end
|
65
68
|
method_name = make_method_name(part, request.request_method)
|
66
|
-
#
|
69
|
+
#EzLog.info "method_name=#{method_name}"
|
67
70
|
instance = klass.new
|
68
71
|
if instance.respond_to?(method_name)
|
69
72
|
return [instance, method_name, args, opts]
|
@@ -74,7 +77,7 @@ module Ezframe
|
|
74
77
|
# ページクラスの階層を辿る
|
75
78
|
def get_path(class_snake, route_h = nil)
|
76
79
|
route_h = Config[:route] unless route_h
|
77
|
-
#
|
80
|
+
# EzLog.info "get_path: route_h=#{route_h}"
|
78
81
|
@get_path_found_it = nil
|
79
82
|
route =_scan_route(class_snake, route_h.deep_dup)
|
80
83
|
return route.reverse if route
|
@@ -106,11 +109,11 @@ module Ezframe
|
|
106
109
|
end
|
107
110
|
|
108
111
|
def get_class(keys)
|
109
|
-
#
|
112
|
+
# EzLog.info "get_class: #{keys.inspect}"
|
110
113
|
return nil unless keys
|
111
114
|
keys = [ keys ] if keys.is_a?(String)
|
112
115
|
klass = (%w[Ezframe] + keys.map { |k| k.to_s.to_camel }).join("::")
|
113
|
-
#
|
116
|
+
# EzLog.info "get_class: #{klass}"
|
114
117
|
if Object.const_defined?(klass)
|
115
118
|
return Object.const_get(klass)
|
116
119
|
else
|
data/lib/ezframe/server.rb
CHANGED
@@ -9,10 +9,17 @@ module Ezframe
|
|
9
9
|
def call(env)
|
10
10
|
req = Rack::Request.new(env)
|
11
11
|
res = Rack::Response.new
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
begin
|
13
|
+
Controller.exec(req, res)
|
14
|
+
rescue => e
|
15
|
+
EzLog.error("Controller.exec: exception: #{e.message}:\n#{e.backtrace}")
|
16
|
+
res.status = 500
|
17
|
+
res.headers["Content-Type"] = "text/plain"
|
18
|
+
res.body = [ "Internal server error" ]
|
15
19
|
end
|
20
|
+
# if res.body.empty?
|
21
|
+
# raise "no body in response"
|
22
|
+
# end
|
16
23
|
return res.finish
|
17
24
|
end
|
18
25
|
end
|
@@ -0,0 +1,205 @@
|
|
1
|
+
require_relative "editor_common"
|
2
|
+
|
3
|
+
module Ezframe
|
4
|
+
# ページ遷移無しでデータを編集する仕組み
|
5
|
+
class SinglePageEditor < PageBase
|
6
|
+
include EditorCommon
|
7
|
+
|
8
|
+
def init_vars
|
9
|
+
super
|
10
|
+
@sort_key = :id
|
11
|
+
@event = @parsed_body[:event] if @parsed_body
|
12
|
+
@dom_id = { create: "create-area", edit: "edit-area", index: "index-area", detail: "detail-area"}
|
13
|
+
# @show_delete_button = nil
|
14
|
+
end
|
15
|
+
|
16
|
+
def public_default_get
|
17
|
+
@id = get_id
|
18
|
+
# if @id
|
19
|
+
# return public_detail_post
|
20
|
+
# else
|
21
|
+
div = [ Ht.div(id: @dom_id[:create], child: make_index_top), Ht.div(id: @dom_id[:index], child: make_index_table) ]
|
22
|
+
layout = index_layout(center: Ht.form(child: div))
|
23
|
+
return show_base_template(title: Message[:index_page_title], body: Html.convert(layout))
|
24
|
+
# end
|
25
|
+
end
|
26
|
+
|
27
|
+
def make_index_top
|
28
|
+
make_create_button("on=click:url=#{make_base_url}/create")
|
29
|
+
end
|
30
|
+
|
31
|
+
def public_default_post
|
32
|
+
return { inject: "##{@dom_id[:index]}", body: Html.convert(make_index_table) }
|
33
|
+
end
|
34
|
+
|
35
|
+
# 新規データ登録
|
36
|
+
def public_create_post
|
37
|
+
@form = @event[:form]
|
38
|
+
EzLog.debug("public_create_post: event=#{@event}")
|
39
|
+
if @event[:cancel]
|
40
|
+
return { inject: "##{@dom_id[:create]}", body: Html.convert(make_index_top) }
|
41
|
+
elsif !@form
|
42
|
+
return { inject: "##{@dom_id[:create]}", body: Html.convert(make_edit_form(:create)) }
|
43
|
+
else
|
44
|
+
# 値の保存
|
45
|
+
@column_set.clear
|
46
|
+
form_values = @form
|
47
|
+
form_values.update(@env["url_params"])
|
48
|
+
# @column_set.values = form_values
|
49
|
+
@column_set[:id].value = @id = @column_set.create(form_values)
|
50
|
+
return { redirect: make_base_url(@id) }
|
51
|
+
# return public_default_post
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# データ編集受信
|
56
|
+
def public_edit_post
|
57
|
+
@id = get_id
|
58
|
+
unless @event[:form]
|
59
|
+
data = @column_set.set_from_db(@id)
|
60
|
+
return show_message_page("no data", "data is not defined: #{@id}") unless data
|
61
|
+
# フォームの表示
|
62
|
+
form = make_edit_form
|
63
|
+
found_a = Ht.search(form, tag: "input")
|
64
|
+
found_a.each { |h| h.add_class("#{@class_snake}-edit-box") if h[:size] }
|
65
|
+
return { inject: "##{@dom_id[:detail]}", body: Html.convert(form) }
|
66
|
+
else
|
67
|
+
if @event[:cancel]
|
68
|
+
data = @column_set.set_from_db(@id)
|
69
|
+
return act_after_cancel
|
70
|
+
else
|
71
|
+
# 値を保存
|
72
|
+
@column_set.update(@id, @event[:form])
|
73
|
+
end
|
74
|
+
return act_after_edit
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# データ詳細表示
|
79
|
+
def public_detail_post
|
80
|
+
@id ||= get_id
|
81
|
+
data = @column_set.set_from_db(@id)
|
82
|
+
target_keys = @detail_keys || @column_set.keys.select { |key| !@column_set[key].attribute[:no_view] }
|
83
|
+
line_a = []
|
84
|
+
target_keys.each do |key|
|
85
|
+
column = @column_set[key]
|
86
|
+
v = make_detail_line(column)
|
87
|
+
line_a.push(v) if v
|
88
|
+
end
|
89
|
+
table = Ht.div(line_a)
|
90
|
+
collection = Materialize::Collection.new
|
91
|
+
# 詳細表示用のblockを追加
|
92
|
+
collection.push(Ht.div(id: @dom_id[:detail], child: [button_for_detail_box(data), table]))
|
93
|
+
return { inject: "##{@dom_id[:detail]}", body: Html.convert(collection.to_h) }
|
94
|
+
end
|
95
|
+
|
96
|
+
def public_delete_post
|
97
|
+
@id = get_id
|
98
|
+
dataset = DB.dataset(@column_set.name)
|
99
|
+
DB.delete(dataset, @id)
|
100
|
+
return public_default_post
|
101
|
+
end
|
102
|
+
|
103
|
+
# 詳細表示欄の一行を生成
|
104
|
+
def make_detail_line(column)
|
105
|
+
view = column.view
|
106
|
+
if view
|
107
|
+
view = Ht.pre(view) if view.strip.index("\n")
|
108
|
+
return Ht.p([Ht.small(column.label), view])
|
109
|
+
end
|
110
|
+
return nil
|
111
|
+
end
|
112
|
+
|
113
|
+
def act_after_edit
|
114
|
+
return [public_default_post, public_detail_post]
|
115
|
+
end
|
116
|
+
|
117
|
+
def act_after_cancel
|
118
|
+
return public_detail_post
|
119
|
+
end
|
120
|
+
|
121
|
+
# 一覧表の生成
|
122
|
+
def make_index_table
|
123
|
+
list = list_for_index
|
124
|
+
target_keys = @index_keys
|
125
|
+
unless target_keys
|
126
|
+
target_keys = @column_set.keys.select {|k| !@column_set[k].no_view?}
|
127
|
+
end
|
128
|
+
labels = @table_labels
|
129
|
+
unless labels
|
130
|
+
labels = target_keys.map {|k| @column_set[k].label(force: true) || " "}
|
131
|
+
end
|
132
|
+
# 項目名欄の生成
|
133
|
+
thead = Ht.thead(Ht.tr(labels.map {|label| Ht.th(label||" ")}))
|
134
|
+
|
135
|
+
tr_a = list.map do |data|
|
136
|
+
view_a = make_index_line(target_keys, data)
|
137
|
+
td_a = view_a.map {|view| Ht.td(view)}
|
138
|
+
Ht.tr(id: "tr-#{@class_snake}-#{data[:id]}", child: td_a, event: "on=click:url=#{make_base_url(data[:id])}/detail")
|
139
|
+
end
|
140
|
+
tbody = Ht.tbody(tr_a)
|
141
|
+
return [
|
142
|
+
Ht.table(id: "enable_datatable_#{@class_snake}", child: [thead, tbody], ezload: "command=enable_datatable:target=#enable_datatable_#{@class_snake}"),
|
143
|
+
Ht.div(id: @dom_id[:detail], child: ""),
|
144
|
+
]
|
145
|
+
end
|
146
|
+
|
147
|
+
# 一覧表示の1行を生成
|
148
|
+
def make_index_line(target_keys, data)
|
149
|
+
@column_set.clear
|
150
|
+
@column_set.values = data
|
151
|
+
return target_keys.map { |key| make_index_column(key) }
|
152
|
+
end
|
153
|
+
|
154
|
+
# 一覧表示の1カラムを生成
|
155
|
+
def make_index_column(key)
|
156
|
+
column = @column_set[key.to_sym]
|
157
|
+
# if @with_label
|
158
|
+
# child = [Ht.small(column.label), column.view(force: true)]
|
159
|
+
# return Ht.p(id: "edit-#{@class_snake}-#{@column_set[:id].value}-column-#{column.key}", child: child)
|
160
|
+
# else
|
161
|
+
return column.view(force: true)
|
162
|
+
# end
|
163
|
+
end
|
164
|
+
|
165
|
+
# 一覧ページ用のデータリスト生成
|
166
|
+
def list_for_index
|
167
|
+
return @column_set.dataset.where(deleted_at: nil).order(@sort_key).all
|
168
|
+
end
|
169
|
+
|
170
|
+
# 一覧ページ用ボタン
|
171
|
+
def button_for_index_line(data)
|
172
|
+
Ht.button(class: %w[btn right], event: "on=click:url=#{make_base_url(data[:id])}/edit", child: [Ht.icon("edit"), Message[:edit_button_label]])
|
173
|
+
end
|
174
|
+
|
175
|
+
# 詳細ページ用ボタン
|
176
|
+
def button_for_detail_box(data)
|
177
|
+
buttons = [Ht.button(class: %w[btn right], event: "on=click:url=#{make_base_url(data[:id])}/edit", child: [Ht.icon("edit"), Message[:edit_button_label]]) ]
|
178
|
+
if @show_delete_button
|
179
|
+
buttons.push(make_delete_button)
|
180
|
+
end
|
181
|
+
return Ht.div(class: %w[button-box], child: buttons)
|
182
|
+
end
|
183
|
+
|
184
|
+
# 編集フォームの生成
|
185
|
+
def make_edit_form(command = :edit)
|
186
|
+
@id ||= get_id
|
187
|
+
target_keys = @edit_keys || @column_set.keys
|
188
|
+
list = target_keys.map do |colkey|
|
189
|
+
column = @column_set[colkey.to_sym]
|
190
|
+
unless column
|
191
|
+
EzLog.error("undefined column entry: #{colkey}")
|
192
|
+
next
|
193
|
+
end
|
194
|
+
form = column.form
|
195
|
+
Ht.p(class: %w[form-line], child: [Ht.small(column.label), form]) if form
|
196
|
+
end
|
197
|
+
send_button = Ht.button(id: "#{@class_snake}-#{command}-finish-button", class: %w[btn], child: [Ht.icon("check"), Message[:edit_finish_button_label]], event: "on=click:url=#{make_base_url(@id)}/#{command}:with=form")
|
198
|
+
cancel_button = make_cancel_button("on=click:url=#{make_base_url(@id)}/#{command}:cancel=true:with=form")
|
199
|
+
list.push(Ht.p(class: %w[edit-finish-buttons], child: [send_button, cancel_button]))
|
200
|
+
return Ht.form(list)
|
201
|
+
end
|
202
|
+
|
203
|
+
|
204
|
+
end
|
205
|
+
end
|
@@ -0,0 +1,222 @@
|
|
1
|
+
module Ezframe
|
2
|
+
# 各顧客に関連づいた情報の編集を一般化したクラス
|
3
|
+
class SubEditor < PageBase
|
4
|
+
include EditorCommon
|
5
|
+
|
6
|
+
def init_vars
|
7
|
+
super
|
8
|
+
@sort_key = :id
|
9
|
+
# @parent_key = :customer
|
10
|
+
@event = @parsed_body[:event] if @parsed_body
|
11
|
+
# @use_detail_box = true
|
12
|
+
end
|
13
|
+
|
14
|
+
def get_parent_id
|
15
|
+
params = @request.env["url_params"]
|
16
|
+
unless params
|
17
|
+
EzLog.info "[WARN] no url_params"
|
18
|
+
return nil
|
19
|
+
end
|
20
|
+
return params[@parent_key.to_sym]
|
21
|
+
end
|
22
|
+
|
23
|
+
def public_default_post
|
24
|
+
return { inject: "##{@class_snake}_tab", body: Html.convert(make_index_page) }
|
25
|
+
end
|
26
|
+
|
27
|
+
# 新規データ登録
|
28
|
+
def public_create_post
|
29
|
+
@form = @event[:form]
|
30
|
+
# EzLog.debug("public_create_post: form=#{@form}")
|
31
|
+
unless @form
|
32
|
+
{ inject: "##{@class_snake}-create-area", body: Html.convert(make_edit_form(:create)) }
|
33
|
+
else
|
34
|
+
# 値の保存
|
35
|
+
@column_set.clear
|
36
|
+
form_values = @form
|
37
|
+
form_values.update(@env["url_params"])
|
38
|
+
# @column_set.values = form_values
|
39
|
+
@column_set[:id].value = @id = @column_set.create(form_values)
|
40
|
+
# return { redirect: "#{make_base_url}/#{@id}" }
|
41
|
+
return public_default_post
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# データ編集受信
|
46
|
+
def public_edit_post
|
47
|
+
@id ||= get_id
|
48
|
+
unless @event[:form]
|
49
|
+
data = @column_set.set_from_db(@id)
|
50
|
+
# データが空ならエラーページ
|
51
|
+
return { inject: "##{edit_inject_element}", body: "データがありません: #{@id}"} unless data
|
52
|
+
# フォームの表示
|
53
|
+
form = make_edit_form
|
54
|
+
found_a = Ht.search(form, tag: "input")
|
55
|
+
found_a.each { |h| h.add_class("#{@class_snake}-edit-box") if h[:size] }
|
56
|
+
return { inject: "##{edit_inject_element}", body: Html.convert(form) }
|
57
|
+
else
|
58
|
+
if @event[:cancel]
|
59
|
+
data = @column_set.set_from_db(@id)
|
60
|
+
return act_after_cancel
|
61
|
+
else
|
62
|
+
# 値を保存
|
63
|
+
@column_set.update(@id, @event[:form])
|
64
|
+
end
|
65
|
+
return act_after_edit
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# データ詳細表示
|
70
|
+
def public_detail_post
|
71
|
+
@id = get_id
|
72
|
+
data = @column_set.set_from_db(@id)
|
73
|
+
target_keys = @show_keys || @column_set.keys.select { |key| !@column_set[key].attribute[:no_view] }
|
74
|
+
line_a = []
|
75
|
+
target_keys.each do |key|
|
76
|
+
column = @column_set[key]
|
77
|
+
v = make_detail_line(column)
|
78
|
+
line_a.push(v) if v
|
79
|
+
end
|
80
|
+
table = Ht.div(line_a)
|
81
|
+
collection = Materialize::Collection.new
|
82
|
+
# 詳細表示用のblockを追加
|
83
|
+
collection.push(Ht.div(class: "detail-box", child: [button_for_detail_box(data), table]))
|
84
|
+
return { inject: "##{edit_inject_element}", body: Html.convert(collection.to_h) }
|
85
|
+
end
|
86
|
+
|
87
|
+
# 削除ボタン押下時の処理
|
88
|
+
def public_delete_post
|
89
|
+
@id = get_id
|
90
|
+
dataset = DB.dataset(@column_set.name)
|
91
|
+
DB.delete(dataset, @id)
|
92
|
+
return public_default_post
|
93
|
+
end
|
94
|
+
|
95
|
+
# 詳細表示欄の一行を生成
|
96
|
+
def make_detail_line(column)
|
97
|
+
view = column.view
|
98
|
+
if view
|
99
|
+
view = Ht.pre(view) if view.index("\n")
|
100
|
+
return Ht.p([Ht.small(column.label), view])
|
101
|
+
end
|
102
|
+
return nil
|
103
|
+
end
|
104
|
+
|
105
|
+
def edit_inject_element
|
106
|
+
return "#{@class_snake}_show"
|
107
|
+
end
|
108
|
+
|
109
|
+
def act_after_edit
|
110
|
+
return [public_default_post, public_detail_post]
|
111
|
+
# return { inject: edit_inject_element, body: Html.convert(make_index_line(@column_set.get_hash(:value))) }
|
112
|
+
end
|
113
|
+
|
114
|
+
def act_after_cancel
|
115
|
+
return public_detail_post
|
116
|
+
end
|
117
|
+
|
118
|
+
# 一覧表の生成
|
119
|
+
def make_index_page
|
120
|
+
list = list_for_index
|
121
|
+
target_keys = @index_keys
|
122
|
+
unless target_keys
|
123
|
+
target_keys = @column_set.keys.select {|k| !@column_set[k].no_view?}
|
124
|
+
end
|
125
|
+
# 項目名欄の生成
|
126
|
+
if @table_labels
|
127
|
+
thead = Ht.thead(Ht.tr(@table_labels.map {|label| Ht.th(label)}))
|
128
|
+
else
|
129
|
+
thead = Ht.thead(Ht.tr(target_keys.map {|key|
|
130
|
+
if @column_set[key].respond_to?(:label)
|
131
|
+
Ht.th(@column_set[key].label(force: true))
|
132
|
+
else
|
133
|
+
nil
|
134
|
+
end
|
135
|
+
})).compact
|
136
|
+
end
|
137
|
+
|
138
|
+
tr_a = list.map do |data|
|
139
|
+
view_a = make_index_line(target_keys, data)
|
140
|
+
td_a = view_a.map {|view| Ht.td(view)}
|
141
|
+
Ht.tr(id: "tr-#{@class_snake}-#{data[:id]}", child: td_a, event: "on=click:url=#{make_base_url(data[:id])}/detail")
|
142
|
+
end
|
143
|
+
tbody = Ht.tbody(tr_a)
|
144
|
+
return [
|
145
|
+
area_for_create,
|
146
|
+
Ht.table(id: "enable_datatable_#{@class_snake}", child: [thead, tbody], ezload: "command=enable_datatable:target=#enable_datatable_#{@class_snake}"),
|
147
|
+
Ht.div(id: edit_inject_element),
|
148
|
+
]
|
149
|
+
end
|
150
|
+
|
151
|
+
# 一覧表示の1行を生成
|
152
|
+
def make_index_line(target_keys, data)
|
153
|
+
@column_set.clear
|
154
|
+
@column_set.set_values(data, from_db: true)
|
155
|
+
return target_keys.map { |key| make_index_column(key) }
|
156
|
+
end
|
157
|
+
|
158
|
+
# 一覧表示の1カラムを生成
|
159
|
+
def make_index_column(key)
|
160
|
+
column = @column_set[key.to_sym]
|
161
|
+
return column.view(force: true)
|
162
|
+
end
|
163
|
+
|
164
|
+
# 一覧ページ用のデータリスト生成
|
165
|
+
def list_for_index
|
166
|
+
return @column_set.dataset.where(@parent_key.to_sym => get_parent_id, deleted_at: nil).order(@sort_key).all
|
167
|
+
end
|
168
|
+
|
169
|
+
# 一覧ページ用ボタン
|
170
|
+
def button_for_index_line(data)
|
171
|
+
Ht.button(class: %w[btn right], event: "on=click:url=#{make_base_url(data[:id])}/edit", child: [Ht.icon("edit"), Message[:edit_button_label]])
|
172
|
+
end
|
173
|
+
|
174
|
+
# 詳細ページ用ボタン
|
175
|
+
def button_for_detail_box(data)
|
176
|
+
buttons = [Ht.button(class: %w[btn right], event: "on=click:url=#{make_base_url(data[:id])}/edit", child: [Ht.icon("edit"), Message[:edit_button_label]]) ]
|
177
|
+
if @show_delete_button
|
178
|
+
buttons.push(make_delete_button)
|
179
|
+
end
|
180
|
+
return Ht.div(class: %w[button-box], child: buttons)
|
181
|
+
end
|
182
|
+
|
183
|
+
#--------------------------------------------------------------------------------------------------------
|
184
|
+
# 新規データ追加欄
|
185
|
+
def area_for_create(extra_buttons = nil)
|
186
|
+
create_button = make_create_button
|
187
|
+
create_button[:event] = "on=click:url=#{make_base_url}/create"
|
188
|
+
return Ht.div(id: "#{@class_snake}-create-area", child: [ create_button, extra_buttons ].compact)
|
189
|
+
end
|
190
|
+
|
191
|
+
# 編集フォームの生成
|
192
|
+
def make_edit_form(command = :edit)
|
193
|
+
# @id ||= get_id
|
194
|
+
if command == :edit && !@id
|
195
|
+
EzLog.error "make_edit_form: @id is not defined"
|
196
|
+
end
|
197
|
+
target_keys = @edit_keys || @column_set.keys
|
198
|
+
list = target_keys.map do |colkey|
|
199
|
+
column = @column_set[colkey.to_sym]
|
200
|
+
unless column
|
201
|
+
EzLog.error("undefined column entry: #{colkey}")
|
202
|
+
next
|
203
|
+
end
|
204
|
+
make_edit_line(column)
|
205
|
+
end.compact
|
206
|
+
event = "on=click:url=#{make_base_url(@id)}/#{command}:with=form"
|
207
|
+
send_button = Ht.button(id: "#{@class_snake}-#{command}-finish-button", class: %w[btn], child: [Ht.icon("check"), Message[:edit_finish_button_label]], event: event)
|
208
|
+
cancel_button = make_cancel_button("on=click:url=#{make_base_url(@id)}/#{command}:cancel=true:with=form")
|
209
|
+
list.push(Ht.p(class: %w[edit-finish-buttons], child: [send_button, cancel_button]))
|
210
|
+
return Ht.form(list)
|
211
|
+
end
|
212
|
+
|
213
|
+
def make_edit_line(column)
|
214
|
+
form = column.form
|
215
|
+
if form
|
216
|
+
return Ht.p(class: %w[form-line], child: [ Ht.small(column.label), form ])
|
217
|
+
else
|
218
|
+
return nil
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|