ezframe 0.0.4 → 0.4.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.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -0
  3. data/README.md +1 -1
  4. data/asset/css/materialize.min.css +13 -0
  5. data/asset/css/style.css +3 -0
  6. data/asset/html/index.html +1 -0
  7. data/{app_template/asset/image/favicon.ico → asset/image/c_e.ico} +0 -0
  8. data/asset/js/ezframe.js +387 -0
  9. data/exe/check_column_yml +64 -0
  10. data/exe/console +2 -2
  11. data/exe/{create_table.rb → create_table} +7 -4
  12. data/exe/dbmigrate +174 -0
  13. data/exe/html2ruby +61 -0
  14. data/ezframe.gemspec +10 -8
  15. data/lib/ezframe.rb +9 -3
  16. data/lib/ezframe/auth.rb +50 -31
  17. data/lib/ezframe/column_set.rb +314 -103
  18. data/lib/ezframe/column_type.rb +456 -99
  19. data/lib/ezframe/config.rb +27 -6
  20. data/lib/ezframe/controller.rb +41 -38
  21. data/lib/ezframe/database.rb +171 -52
  22. data/lib/ezframe/editor_common.rb +74 -0
  23. data/lib/ezframe/email.rb +34 -0
  24. data/lib/ezframe/ezlog.rb +40 -0
  25. data/lib/ezframe/ht.rb +42 -17
  26. data/lib/ezframe/html.rb +47 -31
  27. data/lib/ezframe/japanese_utils.rb +15 -0
  28. data/lib/ezframe/jquery-ui.rb +29 -0
  29. data/lib/ezframe/loader.rb +4 -4
  30. data/lib/ezframe/main_editor.rb +19 -0
  31. data/lib/ezframe/main_page_kit.rb +226 -0
  32. data/lib/ezframe/materialize.rb +10 -14
  33. data/lib/ezframe/message.rb +46 -0
  34. data/lib/ezframe/page_base.rb +59 -71
  35. data/lib/ezframe/route.rb +126 -0
  36. data/lib/ezframe/server.rb +16 -5
  37. data/lib/ezframe/single_page_editor.rb +22 -0
  38. data/lib/ezframe/single_page_kit.rb +199 -0
  39. data/lib/ezframe/sub_editor.rb +25 -0
  40. data/lib/ezframe/sub_page_kit.rb +213 -0
  41. data/lib/ezframe/template.rb +5 -4
  42. data/lib/ezframe/util.rb +45 -23
  43. data/lib/ezframe/version.rb +1 -1
  44. metadata +74 -34
  45. data/.rubocop.yml +0 -44
  46. data/app_template/asset/js/ezframe.js +0 -288
  47. data/app_template/config.ru +0 -10
  48. data/app_template/config/generic.yml +0 -3
  49. data/app_template/config/materialize.yml +0 -5
  50. data/app_template/pages/basic.rb +0 -5
  51. data/exe/setup.rb +0 -15
  52. data/lib/ezframe/editor.rb +0 -188
  53. data/lib/ezframe/model.rb +0 -52
  54. data/lib/ezframe/page_kit.rb +0 -63
@@ -0,0 +1,34 @@
1
+ require "mail"
2
+
3
+ module Ezframe
4
+ class Email
5
+ class << self
6
+ def receive
7
+
8
+ end
9
+
10
+ # options =
11
+ # :address => "smtp.server.host",
12
+ # :port => 1025,
13
+ # :user_name => login user,
14
+ # :password => login password,
15
+ # :authentication => 'plain',
16
+ # :ssl => true,
17
+ def setup_smtp(options)
18
+ Mail.defaults do
19
+ delivery_method :smtp, options
20
+ end
21
+ end
22
+
23
+ def send(data)
24
+ mail = Mail.new do
25
+ from data[:mail_from]
26
+ to data[:mail_to]
27
+ subject data[:subject]
28
+ body data[:body]
29
+ end
30
+ mail.deliver!
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,40 @@
1
+ module Ezframe
2
+ class EzLog
3
+ class << self
4
+ @instance = nil
5
+
6
+ def writer(level="", msg)
7
+ # unless @instance
8
+ # @instance = File.open("log/#{ENV['RACK_ENV']||'development'}.log", "a+")
9
+ # @instance.sync = true
10
+ # end
11
+ # @instance.puts "#{Time.now.to_s}:#{level.upcase}:#{msg}"
12
+ File.open("log/#{ENV['RACK_ENV']||'development'}.log", "a+") {|f| f.puts "#{Time.now.to_s}:#{level.upcase}:#{msg}"}
13
+ end
14
+
15
+ def level=(lv)
16
+ @level = lv
17
+ end
18
+
19
+ def info(msg)
20
+ writer("info", msg)
21
+ end
22
+
23
+ def debug(msg)
24
+ writer("debug", msg)
25
+ end
26
+
27
+ def warn(msg)
28
+ writer("warn", msg)
29
+ end
30
+
31
+ def error(msg)
32
+ writer("debug", msg)
33
+ end
34
+
35
+ def <<(msg)
36
+ writer("", msg)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -3,24 +3,33 @@ module Ezframe
3
3
  module Ht
4
4
  class << self
5
5
  # メソッド名の名前のタグのhthashを生成
6
- def wrap_tag(opts = {})
7
- if opts.is_a?(String) || opts.is_a?(Array)
8
- h = { child: opts }
9
- elsif opts.is_a?(Hash)
10
- if opts[:tag] && !__callee__.to_s.index("wrap_tag")
11
- h = { child: opts }
6
+ def wrap_tag(ht_h = {})
7
+ return nil unless ht_h
8
+ if ht_h.is_a?(String) || ht_h.is_a?(Array)
9
+ h = { child: ht_h }
10
+ elsif ht_h.is_a?(Hash)
11
+ if ht_h[:tag] && !__callee__.to_s.index("wrap_tag")
12
+ h = { child: ht_h }
12
13
  else
13
- h = opts.dup
14
+ h = ht_h.dup
14
15
  end
15
16
  else
16
- mylog("wrap_tag: unknown type: #{opts.inspect}")
17
+ EzLog.info("[WARN] wrap_tag: unknown type: #{ht_h.inspect}")
17
18
  return nil
18
19
  end
19
20
  h[:tag] ||= __callee__.to_s
21
+ h[:wrap] = true
20
22
  raise "no tag" if h[:tag] == "wrap_tag"
21
23
  return h
22
24
  end
23
25
 
26
+ def single_tag(ht_h = {})
27
+ ht_h[:tag] ||= __callee__.to_s
28
+ raise "no tag" if ht_h[:tag] == "wrap_tag"
29
+ raise "has child: #{ht_h.inspect}" if ht_h[:child]
30
+ return ht_h
31
+ end
32
+
24
33
  alias_method :script, :wrap_tag
25
34
 
26
35
  alias_method :h1, :wrap_tag
@@ -30,8 +39,8 @@ module Ezframe
30
39
  alias_method :h5, :wrap_tag
31
40
  alias_method :h6, :wrap_tag
32
41
  alias_method :p, :wrap_tag
33
- alias_method :br, :wrap_tag
34
- alias_method :hr, :wrap_tag
42
+ alias_method :br, :single_tag
43
+ alias_method :hr, :single_tag
35
44
  alias_method :div, :wrap_tag
36
45
  alias_method :span, :wrap_tag
37
46
  alias_method :i, :wrap_tag
@@ -45,11 +54,12 @@ module Ezframe
45
54
  alias_method :tr, :wrap_tag
46
55
  alias_method :th, :wrap_tag
47
56
  alias_method :td, :wrap_tag
48
- alias_method :img, :wrap_tag
57
+ alias_method :img, :single_tag
49
58
  alias_method :a, :wrap_tag
50
59
  alias_method :form, :wrap_tag
51
- alias_method :input, :wrap_tag
60
+ alias_method :input, :single_tag
52
61
  alias_method :select, :wrap_tag
62
+ alias_method :option, :wrap_tag
53
63
  alias_method :textarea, :wrap_tag
54
64
  alias_method :label, :wrap_tag
55
65
  alias_method :fieldset, :wrap_tag
@@ -57,6 +67,8 @@ module Ezframe
57
67
  alias_method :footer, :wrap_tag
58
68
 
59
69
  alias_method :small, :wrap_tag
70
+ alias_method :pre, :wrap_tag
71
+ alias_method :iframe, :wrap_tag
60
72
 
61
73
  alias_method :checkbox, :wrap_tag
62
74
  alias_method :radio, :wrap_tag
@@ -69,7 +81,7 @@ module Ezframe
69
81
  h[:tag] = "icon"
70
82
  return wrap_tag(h)
71
83
  elsif arg.is_a?(String)
72
- return { tag: "icon", name: arg }
84
+ return { tag: "icon", wrap: true, name: arg }
73
85
  end
74
86
  end
75
87
 
@@ -88,6 +100,21 @@ module Ezframe
88
100
  end
89
101
  return child
90
102
  end
103
+
104
+ def search(ht_h, opts)
105
+ @found ||= []
106
+ if ht_h.is_a?(Hash)
107
+ if opts[:tag] && ht_h[:tag] && ht_h[:tag] == opts[:tag]
108
+ @found.push(ht_h)
109
+ end
110
+ if ht_h[:child]
111
+ search(ht_h[:child], opts)
112
+ end
113
+ elsif ht_h.is_a?(Array)
114
+ ht_h.map { |h| search(h, opts) }
115
+ end
116
+ return @found
117
+ end
91
118
  end
92
119
 
93
120
  # 配列を<UL><OL>要素に変換するためのクラス
@@ -95,10 +122,8 @@ module Ezframe
95
122
  attr_accessor :tag
96
123
  def to_h(opts = {})
97
124
  return nil if self.empty?
98
- child = self.map do |elem|
99
- { tag: "li", child: elem }
100
- end
101
- h = { tag: @tag, child: child }
125
+ child = self.map { |elem| Ht.li(elem) }
126
+ h = { tag: @tag, wrap: true, child: child }
102
127
  h.update(opts)
103
128
  return h
104
129
  end
@@ -4,6 +4,7 @@ module Ezframe
4
4
  class Html
5
5
  class << self
6
6
  def convert(ht_h = {})
7
+ ht_h = hook_for_convert(ht_h)
7
8
  return "" if ht_h.nil? || ht_h.to_s.empty?
8
9
  return ht_h.to_html if ht_h.respond_to?(:to_html)
9
10
  return ht_h.to_s if ht_h.is_a?(String) || ht_h.is_a?(Symbol) || ht_h.is_a?(Integer) || ht_h.is_a?(Time)
@@ -11,24 +12,38 @@ module Ezframe
11
12
 
12
13
  tag = ht_h[:tag]
13
14
  case tag
14
- when "input"
15
- input(ht_h)
15
+ when "textarea"
16
+ textarea(ht_h)
16
17
  when "select"
17
- return select(ht_h) if ht_h[:items]
18
+ return select(ht_h) if ht_h[:item]
18
19
  when "icon"
19
20
  tag = "i"
20
21
  end
21
- opt_s, child_s = join_attributes(ht_h)
22
- if child_s.length >= 0
23
- return "<#{ht_h[:tag]} #{opt_s}>\n#{child_s}\n</#{ht_h[:tag]}>\n"
22
+ tag = ht_h[:tag]
23
+ join_info = join_attribute(ht_h)
24
+ start_tag = [ht_h[:tag], join_info[:attr]].compact.join(" ").strip
25
+ if ht_h[:wrap] # !child_s.strip.empty? ||
26
+ return "#{join_info[:before]}<#{start_tag}>#{join_info[:child]}</#{ht_h[:tag]}>#{join_info[:after]}"
24
27
  end
25
- "<#{ht_h[:tag]} #{opt_s}/>"
28
+ # tag_content = [ ht_h[:tag], join_info[:attr] ].compact.join(" ")
29
+ return "#{join_info[:before]}<#{start_tag}/>#{join_info[:after]}"
26
30
  end
27
31
 
28
- def join_attributes(attrs)
32
+ # attributeの連結文字列化
33
+ def join_attribute(attrs)
29
34
  child_s = ""
35
+ before = ""
36
+ after = ""
30
37
  opt_a = attrs.map do |k, v|
31
38
  case k
39
+ when :before
40
+ before = convert(v)
41
+ next
42
+ when :after
43
+ after = convert(v)
44
+ next
45
+ when :wrap
46
+ nil
32
47
  when :child
33
48
  child_s = convert(v)
34
49
  next
@@ -47,62 +62,63 @@ module Ezframe
47
62
  end
48
63
  end
49
64
  end
50
- [opt_a.compact.join(" "), child_s]
65
+ { attr: opt_a.compact.join(" "), before: before, after: after, child: child_s }
51
66
  end
52
67
 
53
- def input(ht_h)
54
- size = ht_h[:size]
55
- # puts "input: size=#{size.inspect}"
56
- if size && (size.index("x") || size.index("*"))
57
- if /(\d+)\s*[x\*]\s*(\d+)/ =~ size
58
- ht_h[:cols], ht_h[:rows] = $1, $2
59
- end
60
- ht_h[:tag] = "textarea"
61
- ht_h[:child] = ht_h[:value]
68
+ def textarea(ht_h)
69
+ value = ht_h[:value]
70
+ if value
71
+ ht_h[:child] = value
62
72
  ht_h.delete(:value)
63
- p ht_h
64
73
  end
65
74
  end
66
75
 
67
76
  def select(ht_h = {})
68
77
  attr = ht_h.clone
69
- items = attr[:items]
70
- # puts "Html.select: #{items}"
71
- if items.is_a?(Hash)
72
- option_a = ht_h[:items].map do |k, v|
73
- h = { tag: "option", value: k }
78
+ item = attr[:item]
79
+ # puts "Html.select: #{item}"
80
+ if item.is_a?(Hash)
81
+ option_a = ht_h[:item].map do |k, v|
82
+ h = Ht.option(value: k)
74
83
  if v.is_a?(Array)
75
84
  v, selected = v
76
85
  h[:selected] = "selected" if selected
77
86
  end
78
87
  h[:child] = v
79
- if ht_h[:default] && ht_h[:default] == v
88
+ # EzLog.info "select: hash: k=#{k}, v=#{v}, value=#{ht_h[:value]}"
89
+ if ht_h[:value] && ht_h[:value].to_s == k.to_s
80
90
  h[:selected] = "selected"
81
91
  end
82
92
  h
83
93
  end
84
- elsif items.is_a?(Array)
85
- option_a = items.map do |v|
86
- h = { tag: "option", value: v[0], child: v[1] }
94
+ elsif item.is_a?(Array)
95
+ option_a = item.map do |v|
96
+ h = Ht.option(value: v[0], child: v[1])
87
97
  if %w[selected default].include?(v[2])
88
98
  h[:selected] = "selected"
89
99
  end
90
- if ht_h[:default] && ht_h[:default] == v
100
+ # EzLog.info "select: array: v=#{v}, value=#{ht_h[:value]}"
101
+ if ht_h[:value] && ht_h[:value].to_s == v[0].to_s
91
102
  h[:selected] = "selected"
92
103
  end
93
104
  # puts h.inspect
94
105
  h
95
106
  end
96
107
  else
97
- warn "unknown items: #{ht_h.inspect}"
108
+ warn "unknown item: #{ht_h.inspect}"
98
109
  end
99
110
  attr[:tag] = "select"
100
111
  attr[:child] = option_a
101
112
  attr[:name] ||= attr[:key]
102
113
  attr[:final] = true
103
- attr.delete(:items)
114
+ attr[:wrap] = true
115
+ attr.delete(:item)
104
116
  Html.convert(attr)
105
117
  end
118
+
119
+ def hook_for_convert(ht_h)
120
+ return ht_h
121
+ end
106
122
  end
107
123
  end
108
124
  end
@@ -36,5 +36,20 @@ class Japanese
36
36
  return nil if !str
37
37
  return str.tr("ぁ-ん\-ー―−", "ァ-ン\-ー―−")
38
38
  end
39
+
40
+ def to_wday(wday)
41
+ return nil unless wday
42
+ return %w(日 月 火 水 木 金 土)[wday]
43
+ end
44
+
45
+ def to_datetime_str(tm)
46
+ return nil unless tm
47
+ return "%d年%2d月%2d日 %2d:%02d:%02d" %[ tm.year, tm.mon, tm.mday, tm.hour, tm.min, tm.sec ]
48
+ end
49
+
50
+ def to_date_str(tm)
51
+ return nil unless tm
52
+ return "%d年%2d月%2d日" %[ tm.year, tm.mon, tm.mday]
53
+ end
39
54
  end
40
55
  end
@@ -0,0 +1,29 @@
1
+ module Ezframe
2
+ class Jquery
3
+ class << self
4
+ def into_html_header
5
+ css_a = Config[:extra_css_list].map {|file| "<link href=\"#{file}\" rel=\"stylesheet\">\n" }
6
+ js_a = Config[:extra_js_list].map {|file| "<script src=\"#{file}\"></script>\n" }
7
+
8
+ css_files = Dir["./asset/css/*.css"]||[]
9
+ css_a += css_files.map do |file|
10
+ file.gsub!("./asset", "")
11
+ "<link href=\"#{file}\" rel=\"stylesheet\">\n"
12
+ end
13
+ js_files = Dir["./asset/js/*.js"]||[]
14
+ js_a += js_files.map do |file|
15
+ file.gsub!("./asset", "")
16
+ "<script src=\"#{file}\"></script>\n"
17
+ end
18
+ (css_a+js_a).join
19
+ end
20
+
21
+ def into_bottom_of_body
22
+ ""
23
+ end
24
+
25
+ def convert(ht_h)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- if File.exist?("pages/common.rb")
4
- require "#{Dir.pwd}/pages/common.rb"
3
+ if File.exist?("page/common.rb")
4
+ require "#{Dir.pwd}/page/common.rb"
5
5
  end
6
- Dir["models/*.rb"].each do |file|
6
+ Dir["model/*.rb"].sort.each do |file|
7
7
  require "#{Dir.pwd}/#{file}"
8
8
  end
9
- Dir["pages/*.rb"].each do |file|
9
+ Dir["page/*.rb"].sort.each do |file|
10
10
  require "#{Dir.pwd}/#{file}"
11
11
  end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+ require_relative "main_page_kit"
3
+
4
+ module Ezframe
5
+ class MainEditor < PageBase
6
+ include EditorCommon
7
+ include MainPageKit::Default
8
+ include MainPageKit::Index
9
+ include MainPageKit::Edit
10
+ include MainPageKit::Detail
11
+
12
+ def init_vars
13
+ super
14
+ @sort_key = :id
15
+ @event = @parsed_body[:ezevent] if @parsed_body
16
+ @dom_id = { create: "create-area", edit: "edit-area", index: "index-area", detail: "detail-area"}
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,226 @@
1
+ module Ezframe
2
+ module MainPageKit
3
+ module Default
4
+ def public_default_get
5
+ @id = get_id
6
+ div = [Ht.div(id: @dom_id[:create], child: make_index_top), Ht.div(id: @dom_id[:index], child: "", ezload: "url=#{make_base_url}")]
7
+ layout = index_layout(center: make_form(make_base_url, div))
8
+ return show_base_template(title: Message[:index_page_title], body: Html.convert(layout))
9
+ end
10
+ end
11
+
12
+ # 一覧テーブルの生成
13
+ module Index
14
+ def public_default_post
15
+ return { inject: "#main-box", body: [ Ht.div(make_index_top), Ht.div(make_index_table)], set_url: make_base_url }
16
+ end
17
+
18
+ def make_index_table
19
+ data_a = list_for_index
20
+ EzLog.debug("make_index_table: #{data_a.length}")
21
+ target_keys = @index_keys
22
+ unless target_keys
23
+ target_keys = @column_set.keys.select { |k| !@column_set[k].no_view? }
24
+ end
25
+ tr_a = data_a.map do |data|
26
+ @column_set.clear
27
+ @column_set.set_values(data, from_db: true)
28
+ line = target_keys.map do |key|
29
+ view = @column_set[key].view
30
+ Ht.td(Ht.a(href: "#{make_base_url(data[:id])}", child: view))
31
+ end
32
+ Ht.tr(line)
33
+ end
34
+ th_a = target_keys.map { |key| Ht.th(@column_set[key.to_sym].label) }
35
+ thead = Ht.thead(Ht.tr(th_a))
36
+ tbody = Ht.tbody(tr_a)
37
+ table_id = "enable_datatable_#{@class_snake}"
38
+ return Ht.table(id: table_id, class: %w[enable_datatable], child: [thead, tbody], ezload: "command=enable_datatable:target=##{table_id}:size=10")
39
+ end
40
+
41
+ # 一覧ページの上部に表示するボタン等の生成
42
+ def make_index_top
43
+ make_create_button
44
+ end
45
+ end
46
+
47
+ module Edit
48
+ # 新規登録フォーム表示
49
+ def public_create_get
50
+ @column_set.clear
51
+ table = make_edit_form(:create)
52
+ layout = main_layout(center: make_form("#{make_base_url}/create", table), type: 2)
53
+ show_base_template(title: Message[:parent_create_page_title], body: Html.convert(layout))
54
+ end
55
+
56
+ # 新規登録受信
57
+ def public_create_post
58
+ validation = @column_set.validate(@form)
59
+ EzLog.debug("public_create_post: event=#{@event}, form=#{@form}")
60
+ if @event[:branch] == "single_validate"
61
+ EzLog.debug("public_create_post: single validate")
62
+ return single_validation(validation, @event[:target_key] || @form.keys[0])
63
+ end
64
+ unless @form
65
+ url = "#{make_base_url}/create"
66
+ return { inject: "#center-panel", body: Html.convert(make_form(url, make_edit_form(:create))), set_url: url }
67
+ else
68
+ if count_errors(validation) > 0
69
+ cmd_a = full_validation(validation)
70
+ EzLog.debug("public_create_post: cmd_a=#{cmd_a}")
71
+ return cmd_a if cmd_a.length > 0
72
+ end
73
+ # 値の保存
74
+ id = create_data(@form)
75
+ return { redirect: make_base_url(id) }
76
+ end
77
+ end
78
+
79
+ # データ編集受信
80
+ def public_edit_post
81
+ EzLog.debug("public_edit_post: #{@form}")
82
+ @id = get_id
83
+ validation = @column_set.validate(@form)
84
+ if @event[:branch] == "single_validate"
85
+ EzLog.debug("public_edit_post: single validate:event=#{@event}, form=#{@form}")
86
+ return single_validation(validation, @event[:target_key])
87
+ end
88
+ unless @form
89
+ data = @column_set.set_from_db(@id)
90
+ return show_message_page("no data", "data is not defined: #{@id}") unless data
91
+ return { inject: "#center-panel", body: Html.convert(make_form("#{make_base_url}/edit", make_edit_form)) }
92
+ else
93
+ if count_errors(validation) > 0
94
+ cmd_a = full_validation(validation)
95
+ return cmd_a
96
+ end
97
+ # 値を保存
98
+ update_data(@id, @form)
99
+ return { redirect: make_base_url(@id) }
100
+ end
101
+ end
102
+
103
+ # 自動入力を行う
104
+ def exec_completion
105
+ return nil
106
+ end
107
+
108
+ # 編集フォームの生成
109
+ def make_edit_form(command = :edit)
110
+ table = []
111
+ matrix = @column_set.map do |column|
112
+ next if column.no_edit?
113
+ form = column.form
114
+ table.push Ht.p([Ht.small(column.label), form]) if form
115
+ end
116
+ send_button = Ht.button(id: "edit-finish-button", child: Message[:edit_finish_button_label], class: %w[btn], ezevent: "on=click:url=#{make_base_url}/#{command}:with=form")
117
+ cancel_button = edit_cancel_button
118
+ cancel_button[:event] = "on=click:command=redirect:url=#{make_base_url}"
119
+ table.push(Ht.p([send_button, cancel_button]))
120
+ return table
121
+ end
122
+
123
+ # 1カラムに対してだけバリデーションを行う。
124
+ def single_validation(validate_h, target_key)
125
+ EzLog.debug("single_validation: validate_h=#{validate_h}, target_key=#{target_key}")
126
+ unless target_key
127
+ raise "target_key is empty: #{validate_h}"
128
+ return []
129
+ end
130
+ cmd_a = []
131
+ if validate_h[target_key.to_sym]
132
+ cmd_a = show_validate_result(validate_h)
133
+ end
134
+ if count_errors(validate_h) == 0
135
+ cmd_a.unshift({ reset_error: "#error-box-#{target_key}" })
136
+ end
137
+ comp_a = exec_completion(@form)
138
+ cmd_a += comp_a if comp_a
139
+ EzLog.debug("reset_error: #error-box-#{target_key}")
140
+ EzLog.debug("single_validation: target_key=#{target_key}, validate_h=#{validate_h}, count=#{count_errors(validate_h)}, cmd_a=#{cmd_a}")
141
+ return cmd_a
142
+ end
143
+
144
+ # 全てのカラムに対してバリデーションを行う
145
+ def full_validation(validate_h)
146
+ cmd_a = show_validate_result(validate_h)
147
+ cmd_a.unshift({ reset_error: ".error-box" })
148
+ EzLog.debug("full_validation: full, cmd_a=#{cmd_a}")
149
+ return cmd_a
150
+ end
151
+
152
+ # フォームの値の有効性チェックし、ajax用返信ハッシュを生成
153
+ def show_validate_result(validate_result)
154
+ cmd_a = []
155
+ validate_result.each do |key, status|
156
+ norm, err = status
157
+ EzLog.debug("norm=#{norm}, err=#{err}")
158
+ if norm
159
+ cmd_a.push({ set_value: "input[name=#{key}]", value: norm })
160
+ end
161
+ if err
162
+ msg = Message[err.to_sym] || err
163
+ cmd_a.push({ set_error: "#error-box-#{key}", value: msg })
164
+ end
165
+ end
166
+ return cmd_a
167
+ end
168
+
169
+ # validate_resultの中のエラーの数を数える
170
+ def count_errors(validate_result)
171
+ return validate_result.count { |k, a| a[1] }
172
+ end
173
+
174
+ def edit_cancel_button
175
+ Ht.span(class: %w[btn red small waves-effect waves-light switch-button], child: Ht.icon("clear"))
176
+ end
177
+
178
+ def make_create_button(event = nil)
179
+ event ||= "on=click:command=redirect:url=#{make_base_url}/create"
180
+ return Ht.button(class: %w[btn], child: [Ht.icon("add"), Message[:create_button_label]], ezevent: event)
181
+ end
182
+ end
183
+
184
+ # 詳細表示
185
+ module Detail
186
+ def make_detail_page
187
+ # EzLog.info "make_detail_page: #{@request.params.inspect}"
188
+ id = get_id(@class_snake)
189
+ unless @column_set.set_from_db(id)
190
+ return show_message_page("no data", "data is not defined: #{id}")
191
+ end
192
+ right = nil
193
+ right = right_tabs if @with_right_tabs
194
+ layout = main_layout(center: make_detail_table, right: right)
195
+ return show_base_template(title: Message[:customer_detail], body: Html.convert(layout))
196
+ end
197
+
198
+ # 詳細ページの表の生成
199
+ def make_detail_table
200
+ table = []
201
+ array = @column_set.map do |column|
202
+ next if column.no_view?
203
+ edit_btn = nil
204
+ if column.type.to_s == "textarea"
205
+ view = Ht.pre(id: "#{@class_snake}-#{column.key}-view", child: column.view)
206
+ else
207
+ view = Ht.span(id: "#{@class_snake}-#{column.key}-view", child: column.view)
208
+ end
209
+ table.push Ht.p(class: %w[hover-button-box], child: [Ht.small(column.label), view, edit_btn].compact)
210
+ end
211
+ edit_btn = Ht.button(id: "#{@class_snake}-detail-edit-button", class: %w[btn], child: [Ht.icon("edit"), Message[:edit_button_label]], ezevent: "on=click:url=#{make_base_url}/edit")
212
+ table.push edit_btn
213
+ return table
214
+ end
215
+
216
+ # 一覧ページ用のデータリスト生成
217
+ def list_for_index(where: nil)
218
+ where ||= {}
219
+ where[:deleted_at] = nil
220
+ sql = @column_set.dataset.where(where).order(@sort_key).sql
221
+ EzLog.debug("list_for_index: #{sql}")
222
+ return @column_set.dataset.where(where).order(@sort_key).all
223
+ end
224
+ end
225
+ end
226
+ end