aurita-gui 0.1.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.
- data/History.txt +7 -0
- data/LICENSE +19 -0
- data/aurita-gui-0.1.0.gem +0 -0
- data/aurita-gui.gemspec +37 -0
- data/lib/aurita-gui.rb +6 -0
- data/lib/aurita-gui/button.rb +85 -0
- data/lib/aurita-gui/element.rb +161 -0
- data/lib/aurita-gui/form.rb +232 -0
- data/lib/aurita-gui/form/checkbox_field.rb +34 -0
- data/lib/aurita-gui/form/date_field.rb +94 -0
- data/lib/aurita-gui/form/datetime_field.rb +101 -0
- data/lib/aurita-gui/form/fieldset.rb +55 -0
- data/lib/aurita-gui/form/file_field.rb +30 -0
- data/lib/aurita-gui/form/form_error.rb +10 -0
- data/lib/aurita-gui/form/form_field.rb +93 -0
- data/lib/aurita-gui/form/hidden_field.rb +43 -0
- data/lib/aurita-gui/form/input_field.rb +29 -0
- data/lib/aurita-gui/form/options_field.rb +115 -0
- data/lib/aurita-gui/form/radio_field.rb +35 -0
- data/lib/aurita-gui/form/select_field.rb +34 -0
- data/lib/aurita-gui/form/textarea_field.rb +22 -0
- data/lib/aurita-gui/html.rb +119 -0
- data/lib/aurita-gui/table.rb +192 -0
- data/test/tc_form.rb +30 -0
- data/test/tc_table.rb +23 -0
- metadata +86 -0
@@ -0,0 +1,29 @@
|
|
1
|
+
|
2
|
+
require('aurita-gui/form/form_field')
|
3
|
+
|
4
|
+
module Aurita
|
5
|
+
module GUI
|
6
|
+
|
7
|
+
# Usage:
|
8
|
+
#
|
9
|
+
# i = Input_Field.new(:name => :description,
|
10
|
+
# :label => 'Description',
|
11
|
+
# :value => 'Lorem ipsum dolor')
|
12
|
+
#
|
13
|
+
class Input_Field < Form_Field
|
14
|
+
def initialize(params, &block)
|
15
|
+
params[:tag] = :input
|
16
|
+
params[:type] = :text unless params[:type]
|
17
|
+
if block_given? then
|
18
|
+
params[:value] = yield
|
19
|
+
end
|
20
|
+
super(params)
|
21
|
+
end
|
22
|
+
def element
|
23
|
+
HTML.input(@attrib)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
|
2
|
+
require('aurita-gui/form/form_field')
|
3
|
+
|
4
|
+
module Aurita
|
5
|
+
module GUI
|
6
|
+
|
7
|
+
# Abstract base class for all form elements containing
|
8
|
+
# options, like Select_Field, Radio_Field, Checkbox_Field
|
9
|
+
# or any custom implementation.
|
10
|
+
#
|
11
|
+
# Usage:
|
12
|
+
#
|
13
|
+
# r = Radio_Field.new(:options => { 1 => 'first',
|
14
|
+
# 2 => 'second',
|
15
|
+
# 3 => 'third' },
|
16
|
+
# :label => 'Which one?',
|
17
|
+
# :value => 1)
|
18
|
+
# Same as
|
19
|
+
#
|
20
|
+
# r = Radio_Field(:option_range => (1..3)
|
21
|
+
# :option_labels => ['First', 'Second', 'Third']
|
22
|
+
# :value => 1,
|
23
|
+
# :label => 'Which one?')
|
24
|
+
#
|
25
|
+
# Set a selected value using parameter :value
|
26
|
+
#
|
27
|
+
# r = Radio_Field.new(:value => 42, :name => :amount,
|
28
|
+
# :label => 'Select amount')
|
29
|
+
# r.value = 23
|
30
|
+
#
|
31
|
+
# If there may be more than one selected field, e.g. for Checkbox_Field,
|
32
|
+
# @value is an Array instance:
|
33
|
+
#
|
34
|
+
# c = Checkbox_Field.new(:value => [ 1, 3 ],
|
35
|
+
# :options => { 1 => 'first', 2 => 'second', 3 => 'third' },
|
36
|
+
# :label => 'Choose')
|
37
|
+
# c.value = [ 2, 3 ]
|
38
|
+
#
|
39
|
+
#
|
40
|
+
# There are many ways to define options:
|
41
|
+
#
|
42
|
+
# select = Select_Field.new(:name => :category, :label => 'Category')
|
43
|
+
# select.options = { 1 => 'first', 2 => 'second' }
|
44
|
+
# select.add_option(3 => 'third')
|
45
|
+
# select[3] = HTML.option(:value => 4) { 'fourth' }
|
46
|
+
# select[4] = { 5 => 'fifth' }
|
47
|
+
#
|
48
|
+
#
|
49
|
+
#
|
50
|
+
class Options_Field < Form_Field
|
51
|
+
|
52
|
+
attr_accessor :options, :options_range, :options_labels, :value
|
53
|
+
|
54
|
+
def initialize(params, &block)
|
55
|
+
@options = params[:options]
|
56
|
+
@options_range = params[:options_range]
|
57
|
+
@options_labels = params[:options_labels]
|
58
|
+
@options ||= {}
|
59
|
+
@options_range ||= []
|
60
|
+
@options_labels ||= []
|
61
|
+
@option_elements = []
|
62
|
+
@value = params[:value]
|
63
|
+
if block_given? then
|
64
|
+
yield.each { |option|
|
65
|
+
add_option(option)
|
66
|
+
}
|
67
|
+
elsif params[:options] then
|
68
|
+
add_option(params[:options])
|
69
|
+
end
|
70
|
+
params.delete(:options)
|
71
|
+
params.delete(:value) # Value is determined via selected value
|
72
|
+
params.delete(:options_range)
|
73
|
+
params.delete(:options_labels)
|
74
|
+
super(params)
|
75
|
+
end
|
76
|
+
|
77
|
+
def add_option(option={})
|
78
|
+
if option.kind_of? Array then
|
79
|
+
@option_elements += option
|
80
|
+
elsif option.kind_of? Hash then
|
81
|
+
@option_elements << options
|
82
|
+
elsif option.kind_of? Range then
|
83
|
+
@option_elements += option.to_a
|
84
|
+
end
|
85
|
+
# @option_elements << option
|
86
|
+
end
|
87
|
+
|
88
|
+
def options=(options)
|
89
|
+
if options.kind_of? Array then
|
90
|
+
@option_elements = options
|
91
|
+
elsif options.kind_of? Hash then
|
92
|
+
@option_elements = [ options ]
|
93
|
+
elsif options.kind_of? Range then
|
94
|
+
@option_elements = options.to_a
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def [](index)
|
99
|
+
@option_elements[index]
|
100
|
+
end
|
101
|
+
def []=(index, option_element)
|
102
|
+
@option_elements[index] = option_element
|
103
|
+
end
|
104
|
+
|
105
|
+
def element
|
106
|
+
raise Form_Error.new('Method #element from Abstract class Options_Field has not been overloaded.')
|
107
|
+
end
|
108
|
+
|
109
|
+
def content
|
110
|
+
option_elements()
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
|
2
|
+
require('aurita-gui/form/options_field')
|
3
|
+
|
4
|
+
module Aurita
|
5
|
+
module GUI
|
6
|
+
|
7
|
+
class Radio_Field < Options_Field
|
8
|
+
|
9
|
+
def option_elements
|
10
|
+
options = []
|
11
|
+
@option_elements.each { |option|
|
12
|
+
if option.kind_of? Hash then
|
13
|
+
option.each_pair { |k,v|
|
14
|
+
options << HTML.input(:type => :radio, :value => k, :name => @attrib[:name] ) { v }
|
15
|
+
}
|
16
|
+
elsif option.kind_of? Element then
|
17
|
+
option.name = @attrib[:name]
|
18
|
+
option.tag = :input
|
19
|
+
option.type = :radio
|
20
|
+
options << option
|
21
|
+
end
|
22
|
+
}
|
23
|
+
options
|
24
|
+
end
|
25
|
+
|
26
|
+
def element
|
27
|
+
HTML.ul(:class => :radio_options) {
|
28
|
+
option_elements().map { |o| HTML.li() { o } }
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
|
2
|
+
require('aurita-gui/form/options_field')
|
3
|
+
|
4
|
+
module Aurita
|
5
|
+
module GUI
|
6
|
+
|
7
|
+
class Select_Field < Options_Field
|
8
|
+
def option_elements
|
9
|
+
options = []
|
10
|
+
@option_elements.each { |option|
|
11
|
+
if option.kind_of? Hash then
|
12
|
+
option.each_pair { |k,v|
|
13
|
+
selected = (@value && k.to_s == @value.to_s)? true : nil
|
14
|
+
options << HTML.option(:value => k, :selected => selected) { v }
|
15
|
+
}
|
16
|
+
elsif option.kind_of? Element then
|
17
|
+
option.tag = :option
|
18
|
+
options << option
|
19
|
+
else
|
20
|
+
selected = (@value && option.to_s == @value.to_s)? true : nil
|
21
|
+
options << HTML.option(:value => option, :selected => selected) { option }
|
22
|
+
end
|
23
|
+
}
|
24
|
+
options
|
25
|
+
end
|
26
|
+
def element
|
27
|
+
HTML.select(@attrib) {
|
28
|
+
option_elements()
|
29
|
+
}
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
|
2
|
+
require('aurita-gui/form/form_field')
|
3
|
+
|
4
|
+
module Aurita
|
5
|
+
module GUI
|
6
|
+
|
7
|
+
class Textarea_Field < Form_Field
|
8
|
+
def initialize(params, &block)
|
9
|
+
params[:tag] = :textarea
|
10
|
+
# Move value parameter to @content:
|
11
|
+
@content = params[:value]
|
12
|
+
params.delete(:value)
|
13
|
+
super(params, &block)
|
14
|
+
@value = @content
|
15
|
+
end
|
16
|
+
def element
|
17
|
+
HTML.textarea(@attrib) { @value }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
|
2
|
+
require('aurita-gui/element')
|
3
|
+
|
4
|
+
module Aurita
|
5
|
+
module GUI
|
6
|
+
|
7
|
+
# Aurita::GUI::HTML is a convenient factory for
|
8
|
+
# Aurita::GUI::Element. Almost every class method
|
9
|
+
# is redirected to generate a correspoding
|
10
|
+
# Element instance.
|
11
|
+
#
|
12
|
+
# It implements an object-oriented, minimalistic
|
13
|
+
# generator for HTML code.
|
14
|
+
# For tags without enclosed content (i.e. without
|
15
|
+
# closing tag):
|
16
|
+
#
|
17
|
+
# HTML.br
|
18
|
+
# # --> '<br />'
|
19
|
+
#
|
20
|
+
# HTML.hr(:class => 'divide')
|
21
|
+
# # --> '<hr class="divide" />'
|
22
|
+
#
|
23
|
+
# This is effectively a wrapper for
|
24
|
+
#
|
25
|
+
# Element.new(:tag => :hr, :class => 'divide')
|
26
|
+
#
|
27
|
+
# Enclosed content is passed in a block:
|
28
|
+
#
|
29
|
+
# HTML.a(:href => 'http://domain.com') { 'click me' }
|
30
|
+
# # --> '<a href="http://domain.com">click me</a>'
|
31
|
+
#
|
32
|
+
class HTML
|
33
|
+
|
34
|
+
def self.br
|
35
|
+
'<br />'
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.render(meth_name, attrib_hash={}, &block)
|
39
|
+
raise ::Exception.new('Missing attributes for HTML.' << meth_name.inspect) unless attrib_hash
|
40
|
+
attrib_hash[:tag] = meth_name
|
41
|
+
label = yield if block_given?
|
42
|
+
label = label.to_s unless label.kind_of? String
|
43
|
+
attrib_hash[:content] = label
|
44
|
+
Element.new(attrib_hash)
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.a(attrib_hash={}, &block)
|
48
|
+
render(:a, attrib_hash, &block)
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.method_missing(meth_name, attrib_hash={}, &block)
|
52
|
+
render(meth_name, attrib_hash, &block)
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
# A minimalistic generator for javascript calls.
|
58
|
+
# Usage:
|
59
|
+
#
|
60
|
+
# my_element.onclick = Javascript.new("alert('an alert message');")
|
61
|
+
#
|
62
|
+
# or just:
|
63
|
+
#
|
64
|
+
# my_element.onclick = Javascript.my_function('foo', 2, 'bar')
|
65
|
+
# --> my_function('foo', 2, 'bar');
|
66
|
+
#
|
67
|
+
# For namespaces:
|
68
|
+
#
|
69
|
+
# my_element.onclick = Javascript[:Foo].my_function(1,2)
|
70
|
+
# --> Foo.my_function('foo', 2, 'bar');
|
71
|
+
#
|
72
|
+
# Method #string renders the code passed in constructir,
|
73
|
+
# enclosed in <script> tags:
|
74
|
+
#
|
75
|
+
# Javascript.new("alert('message');").string
|
76
|
+
# -->
|
77
|
+
# <script language="Javascript" type="text/javascript">
|
78
|
+
# alert('message');
|
79
|
+
# </script>
|
80
|
+
#
|
81
|
+
class Javascript
|
82
|
+
|
83
|
+
def initialize(script)
|
84
|
+
@script = script
|
85
|
+
end
|
86
|
+
|
87
|
+
# Renders script to a <script> block.
|
88
|
+
def code_block
|
89
|
+
'<script language="Javascript" type="text/javascript">' << "\n" <<
|
90
|
+
@script + "\n" <<
|
91
|
+
'</script>'
|
92
|
+
end
|
93
|
+
|
94
|
+
def string
|
95
|
+
@script
|
96
|
+
end
|
97
|
+
alias to_s string
|
98
|
+
|
99
|
+
def self.[](namespace)
|
100
|
+
return self.new(namespace.to_s + '.')
|
101
|
+
end
|
102
|
+
|
103
|
+
def self.method_missing(meth, *args)
|
104
|
+
args = args.collect { |arg|
|
105
|
+
if arg.instance_of? String then
|
106
|
+
'\'' << arg << '\''
|
107
|
+
else
|
108
|
+
arg
|
109
|
+
end
|
110
|
+
}
|
111
|
+
args_string = args.join(',')
|
112
|
+
meth.to_s << '(' << args_string + ');'
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
end # module
|
118
|
+
end # module
|
119
|
+
|
@@ -0,0 +1,192 @@
|
|
1
|
+
|
2
|
+
require('aurita-gui/html')
|
3
|
+
|
4
|
+
module Aurita
|
5
|
+
module GUI
|
6
|
+
|
7
|
+
|
8
|
+
# Usage:
|
9
|
+
#
|
10
|
+
# table = Table.new(:headers => [ 'user', 'phone', 'mobile', 'email' ])
|
11
|
+
# table.add_row('fuchsto', '+49 89 123456', '+49 89 987654', 'fuchst@wortundform.de')
|
12
|
+
#
|
13
|
+
# A row element may be of type Aurita::GUI::Element.
|
14
|
+
# In this case, method #string is invoked to render the cell.
|
15
|
+
#
|
16
|
+
# More examples:
|
17
|
+
#
|
18
|
+
# t = Table.new(:headers => ['user', 'phone', 'email'],
|
19
|
+
# :options => { :class => 'css_class', :id => 'test_table' })
|
20
|
+
# t.add_row([ 'a','b','c' ])
|
21
|
+
# t.add_row([ 'd','e','f' ])
|
22
|
+
|
23
|
+
# t[0][0].value = 'foo'
|
24
|
+
# t[0][0].value = 45
|
25
|
+
# t[1][0].onclick = 'test();'
|
26
|
+
# t[0][1] = HTML.a(:href => 'http://google.com') { 'google' }
|
27
|
+
|
28
|
+
# t[0][1].value.href = 'other'
|
29
|
+
# t[0][1].value.content = 'clickme'
|
30
|
+
|
31
|
+
# puts t[0][1].value.string
|
32
|
+
|
33
|
+
# t[0].class = 'highlighted'
|
34
|
+
#
|
35
|
+
class Table < Element
|
36
|
+
|
37
|
+
attr_accessor :columns, :headers, :rows, :template, :row_css_classes, :column_css_classes, :options
|
38
|
+
|
39
|
+
def initialize(params={}, &block)
|
40
|
+
@options = params[:options]
|
41
|
+
@options[:tag] = 'table'
|
42
|
+
@headers = params[:headers]
|
43
|
+
@num_columns = params[:num_columns]
|
44
|
+
@num_columns = @headers.length if (!@columns && @headers)
|
45
|
+
@columns = []
|
46
|
+
@rows = []
|
47
|
+
@row_css_classes = params[:row_css_classes]
|
48
|
+
@row_css_classes ||= []
|
49
|
+
@column_css_classes = params[:column_css_classes]
|
50
|
+
@column_css_classes ||= []
|
51
|
+
super(@options, &block)
|
52
|
+
end
|
53
|
+
|
54
|
+
def add_row(row_data)
|
55
|
+
row = Table_Row.new(row_data, :parent => self)
|
56
|
+
@rows << row
|
57
|
+
|
58
|
+
# Add row content to columns
|
59
|
+
row_index = 0
|
60
|
+
@columns.each { |c|
|
61
|
+
c.add[row[row_index]]
|
62
|
+
row_index += 1
|
63
|
+
}
|
64
|
+
end
|
65
|
+
|
66
|
+
def string
|
67
|
+
@content = "\n"
|
68
|
+
@content << HTML.tr { @headers.collect { |cell| HTML.th { cell } }.join }.string
|
69
|
+
@content << @rows.collect { |row| row.string }.join("\n")
|
70
|
+
super()
|
71
|
+
end
|
72
|
+
alias to_s string
|
73
|
+
|
74
|
+
def set_column_decorator(column_index, decorator)
|
75
|
+
end
|
76
|
+
|
77
|
+
def set_data(row_array)
|
78
|
+
row_array.each { |row|
|
79
|
+
@rows << Table_Row.new(row, :parent => self)
|
80
|
+
}
|
81
|
+
end
|
82
|
+
|
83
|
+
def cell(column, row)
|
84
|
+
@rows[row][column]
|
85
|
+
end
|
86
|
+
|
87
|
+
def [](row_index)
|
88
|
+
@rows[row_index]
|
89
|
+
end
|
90
|
+
def []=(row_index, row_data)
|
91
|
+
@rows[row_index] = row_data
|
92
|
+
end
|
93
|
+
|
94
|
+
def columns
|
95
|
+
Table_Column.new(@columns)
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
class Table_Row < Element
|
101
|
+
def initialize(cell_data, params={})
|
102
|
+
@cell_data = cell_data
|
103
|
+
@cells = []
|
104
|
+
@cell_data.each { |cell|
|
105
|
+
@cells << Table_Cell.new(cell, :parent => self)
|
106
|
+
}
|
107
|
+
params[:tag] = 'tr'
|
108
|
+
super(params)
|
109
|
+
end
|
110
|
+
|
111
|
+
def table
|
112
|
+
@params[:parent]
|
113
|
+
end
|
114
|
+
|
115
|
+
def [](column_index)
|
116
|
+
@cells[column_index]
|
117
|
+
end
|
118
|
+
def []=(column_index, cell_data)
|
119
|
+
@cells[column_index].value = cell_data
|
120
|
+
end
|
121
|
+
|
122
|
+
def string
|
123
|
+
@content = "\n" << @cells.collect { |c| c.string }.join()
|
124
|
+
super()
|
125
|
+
end
|
126
|
+
|
127
|
+
def inspect
|
128
|
+
'[' << @cells.collect { |c| c.value }.join(',') + ']'
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
# Virtual Element: There is no mapped HTML element
|
133
|
+
# for table columns.
|
134
|
+
class Table_Column
|
135
|
+
def initialize(cell_array)
|
136
|
+
@cells = cell_array
|
137
|
+
end
|
138
|
+
def [](row_index)
|
139
|
+
@cells[row_index]
|
140
|
+
end
|
141
|
+
def []=(row_index, cell_element)
|
142
|
+
@cells[row_index] = cell_element
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
# Accessor for a table cell.
|
147
|
+
# Usage:
|
148
|
+
#
|
149
|
+
# cell = my_table[row][column]
|
150
|
+
# cell.content = 'New cell content'
|
151
|
+
# cell.class = 'table_cell_css_class'
|
152
|
+
#
|
153
|
+
class Table_Cell < Element
|
154
|
+
|
155
|
+
attr_accessor :value, :presentation_class
|
156
|
+
|
157
|
+
def initialize(cell_element, params={})
|
158
|
+
params[:tag] = 'td'
|
159
|
+
@presentation_class = false
|
160
|
+
super(params)
|
161
|
+
@value = cell_element
|
162
|
+
@content = cell_element
|
163
|
+
end
|
164
|
+
|
165
|
+
def value=(val)
|
166
|
+
@value = val
|
167
|
+
@content = val.to_s
|
168
|
+
if @presentation_class then
|
169
|
+
@content = @presentation_class.new(@value).string
|
170
|
+
else
|
171
|
+
@content = @value.to_s
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def set_presentation(presentation_class)
|
176
|
+
@presentation_class = presentation_class
|
177
|
+
end
|
178
|
+
|
179
|
+
def string
|
180
|
+
if @presentation_class then
|
181
|
+
@content = @presentation_class.new(@value).string
|
182
|
+
else
|
183
|
+
@content = @value.to_s
|
184
|
+
end
|
185
|
+
super()
|
186
|
+
end
|
187
|
+
|
188
|
+
end
|
189
|
+
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|