kiss 1.7.4 → 1.8
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/VERSION +1 -1
- data/bin/kiss +1 -1
- data/data/scaffold.tgz +0 -0
- data/lib/kiss/action.rb +1 -1
- data/lib/kiss/ext/core.rb +1 -1
- data/lib/kiss/form/field.rb +527 -110
- data/lib/kiss/form.rb +165 -88
- data/lib/kiss.rb +3 -3
- metadata +3 -5
- data/lib/kiss/form/field_types.rb +0 -239
data/lib/kiss/form.rb
CHANGED
@@ -36,29 +36,70 @@ end
|
|
36
36
|
|
37
37
|
class Kiss
|
38
38
|
class Form
|
39
|
+
class Column
|
40
|
+
_attr_accessor :form, :components
|
41
|
+
def initialize(form = nil)
|
42
|
+
@_form = form
|
43
|
+
@_components = []
|
44
|
+
end
|
45
|
+
|
46
|
+
# Renders HTML for form fields.
|
47
|
+
def components_html
|
48
|
+
@_components.map do |component|
|
49
|
+
form.component_html(component)
|
50
|
+
end.join
|
51
|
+
end
|
52
|
+
alias_method :fields_html, :components_html
|
53
|
+
|
54
|
+
# Renders open of form table.
|
55
|
+
def table_html_open
|
56
|
+
%Q(<table class="kiss_form_column" border=0 cellspacing=0><tbody>)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Renders close of form table.
|
60
|
+
def table_html_close
|
61
|
+
'</tbody></table>'
|
62
|
+
end
|
63
|
+
|
64
|
+
def html
|
65
|
+
[
|
66
|
+
'<td class="kiss_form_column">',
|
67
|
+
table_html_open,
|
68
|
+
components_html,
|
69
|
+
table_html_close,
|
70
|
+
'</td>'
|
71
|
+
].join
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
class Section
|
76
|
+
_attr_accessor :form, :columns, :current_columns
|
77
|
+
def initialize(form = nil)
|
78
|
+
@_form = form
|
79
|
+
@_columns = [Column.new(form)]
|
80
|
+
end
|
81
|
+
|
82
|
+
def html
|
83
|
+
[
|
84
|
+
'<tr><td>',
|
85
|
+
'<table class="kiss_form_section"><tbody><tr>',
|
86
|
+
columns.map {|column| column.html}.join,
|
87
|
+
'</tr></tbody></table>',
|
88
|
+
'</td></tr>',
|
89
|
+
].join
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
39
93
|
_attr_accessor :fields, :params, :submitted, :has_field_errors, :has_required_fields,
|
40
|
-
:delegate, :controller, :components, :form, :new_object_index
|
94
|
+
:delegate, :controller, :components, :form, :new_object_index, :sections,
|
95
|
+
:current_section, :current_columns
|
41
96
|
dsl_accessor :name, :url, :action, :method, :enctype, :errors, :cancel, :mark_required,
|
42
97
|
:id, :class, :style, :html, :error_class, :field_error_class, :objects_save_order,
|
43
98
|
:object, :prepend_html, :append_html, :year, :timezone
|
44
|
-
|
45
|
-
@@component_types = {
|
46
|
-
:text => TextField,
|
47
|
-
:hidden => HiddenField,
|
48
|
-
:textarea => TextAreaField,
|
49
|
-
:password => PasswordField,
|
50
|
-
:boolean => BooleanField,
|
51
|
-
:file => FileField,
|
52
|
-
:select => SelectField,
|
53
|
-
:radio => RadioField,
|
54
|
-
:checkbox => CheckboxField,
|
55
|
-
:multiselect => MultiSelectField,
|
56
|
-
:submit => SubmitField
|
57
|
-
}
|
58
99
|
|
59
100
|
# Create DSL methods for component types
|
60
101
|
self.class_eval(
|
61
|
-
|
102
|
+
COMPONENT_TYPES.keys.map do |type|
|
62
103
|
"def #{type}(*args, &block); add_component(:#{type}, *args, &block); end; "
|
63
104
|
end.join
|
64
105
|
)
|
@@ -94,6 +135,10 @@ class Kiss
|
|
94
135
|
|
95
136
|
@_method ||= 'post'
|
96
137
|
|
138
|
+
@_sections = [Section.new(self)]
|
139
|
+
@_current_section = @_sections.first
|
140
|
+
@_current_column = @_current_section.columns.first
|
141
|
+
|
97
142
|
@_components = []
|
98
143
|
@_fields = Hashay.new
|
99
144
|
@_object_fields = {}
|
@@ -136,6 +181,17 @@ class Kiss
|
|
136
181
|
end
|
137
182
|
end
|
138
183
|
|
184
|
+
def column_break
|
185
|
+
@_current_column = Column.new(self)
|
186
|
+
@_current_section.columns << @_current_column
|
187
|
+
end
|
188
|
+
|
189
|
+
def section_break
|
190
|
+
@_current_section = Section.new(self)
|
191
|
+
@_current_column = @_current_section.columns.first
|
192
|
+
@_sections << @_current_section
|
193
|
+
end
|
194
|
+
|
139
195
|
# Creates and adds a field to the form, according to specified attributes.
|
140
196
|
def add_field(attrs = {}, &block)
|
141
197
|
attrs = @_with.merge(attrs) if @_with
|
@@ -145,12 +201,11 @@ class Kiss
|
|
145
201
|
name = @_field_name_prefix + name unless @_field_name_prefix.empty?
|
146
202
|
|
147
203
|
type = attrs[:type] ? attrs[:type].to_sym : :text
|
148
|
-
raise "invalid field type '#{type}'" unless
|
204
|
+
raise "invalid field type '#{type}'" unless COMPONENT_TYPES.has_key?(type)
|
149
205
|
|
150
|
-
field =
|
206
|
+
field = COMPONENT_TYPES[type].new(self, attrs.merge(
|
151
207
|
:name => name,
|
152
|
-
:key => key
|
153
|
-
:type => type
|
208
|
+
:key => key
|
154
209
|
), &block)
|
155
210
|
|
156
211
|
field.object = @_object if @_object && !field.object
|
@@ -169,15 +224,9 @@ class Kiss
|
|
169
224
|
|
170
225
|
@_fields[name] = field
|
171
226
|
@_components << field
|
227
|
+
@_current_column.components << field
|
172
228
|
|
173
|
-
|
174
|
-
other_field = field.other_field
|
175
|
-
break unless other_field
|
176
|
-
other_field.form = self
|
177
|
-
@_other_field = @_form.create_field( { :name => @_name + '.other' }.merge(@_other) )
|
178
|
-
end
|
179
|
-
|
180
|
-
@_enctype = 'multipart/form-data' if field.type == :file
|
229
|
+
@_enctype = 'multipart/form-data' if field.is_a?(FileField)
|
181
230
|
|
182
231
|
field
|
183
232
|
end
|
@@ -197,7 +246,7 @@ class Kiss
|
|
197
246
|
attrs.merge!(args.pop) if args.last.is_a?(Hash)
|
198
247
|
attrs[:options] = args if args.size > 0
|
199
248
|
attrs = @_with.merge(attrs) if @_with
|
200
|
-
@_submit =
|
249
|
+
@_submit = COMPONENT_TYPES[:submit].new(self, attrs, &block)
|
201
250
|
else
|
202
251
|
@_submit
|
203
252
|
end
|
@@ -221,8 +270,8 @@ class Kiss
|
|
221
270
|
def values
|
222
271
|
@_values ||= begin
|
223
272
|
hash = {}
|
224
|
-
@_fields.each {|field|
|
225
|
-
hash['submit'] = @_submit.value = params[@_submit.name
|
273
|
+
@_fields.each {|field| field.set_value_to_hash(hash) }
|
274
|
+
hash['submit'] = @_submit.value = params[@_submit.name]
|
226
275
|
hash
|
227
276
|
end
|
228
277
|
end
|
@@ -320,22 +369,14 @@ class Kiss
|
|
320
369
|
|
321
370
|
def set_object_data(obj = @_object)
|
322
371
|
@_object_fields[obj.object_id].values.each do |field|
|
323
|
-
#
|
372
|
+
# skip fields whose name starts with underscore
|
324
373
|
next if field.name =~ /\A\_/
|
325
|
-
#
|
326
|
-
next
|
327
|
-
#
|
328
|
-
next if field.
|
374
|
+
# skip fields with save == false
|
375
|
+
next unless field.save
|
376
|
+
# skip file fields
|
377
|
+
next if field.is_a?(FileField)
|
329
378
|
|
330
|
-
|
331
|
-
value = (field.value != nil || obj.class.db_schema[key].allow_null) ?
|
332
|
-
field.value : (obj.class.db_schema[key][:default] ||= field.format.default)
|
333
|
-
|
334
|
-
if field.digest
|
335
|
-
value = Digest.const_get(field.digest.to_sym).hexdigest(value)
|
336
|
-
end
|
337
|
-
|
338
|
-
obj[key] = value if field.save
|
379
|
+
field.set_value_to_object(obj)
|
339
380
|
end
|
340
381
|
end
|
341
382
|
|
@@ -413,12 +454,18 @@ class Kiss
|
|
413
454
|
(@_errors.size > 0 || @_has_field_errors)
|
414
455
|
end
|
415
456
|
|
457
|
+
# Returns true if user submitted form in this request.
|
458
|
+
def submitted?
|
459
|
+
@_submitted
|
460
|
+
end
|
461
|
+
|
416
462
|
# Returns true if user submitted form with non-cancel submit button
|
417
463
|
# (non-nil submit param, not equal to cancel submit button value).
|
418
|
-
def accepted
|
464
|
+
def accepted?
|
419
465
|
raise 'form missing submit field' unless @_submit
|
420
466
|
return params[@_submit.name] != @_submit.cancel
|
421
467
|
end
|
468
|
+
alias_method :accepted, :accepted?
|
422
469
|
|
423
470
|
# Renders error HTML block for top of form, and returns as string.
|
424
471
|
def errors_html
|
@@ -435,7 +482,7 @@ class Kiss
|
|
435
482
|
@_errors.pop if @_has_field_errors
|
436
483
|
|
437
484
|
plural = @_errors.size > 1 || @_has_field_errors ? 's' : nil
|
438
|
-
%Q(<table class="
|
485
|
+
%Q(<table class="kiss_form_errors"><tr><td>#{content}</td></tr></table>)
|
439
486
|
end
|
440
487
|
|
441
488
|
# Renders current action using form's HTML as action render content.
|
@@ -468,93 +515,115 @@ class Kiss
|
|
468
515
|
styles = []
|
469
516
|
styles.push( <<-EOT
|
470
517
|
table.kiss_form {
|
518
|
+
border: 0;
|
519
|
+
border-collapse: collapse;
|
520
|
+
margin-right: -12px;
|
521
|
+
}
|
522
|
+
table.kiss_form > tbody > tr > td {
|
523
|
+
padding: 0;
|
524
|
+
}
|
525
|
+
|
526
|
+
table.kiss_form_section {
|
527
|
+
border: 0;
|
528
|
+
border-collapse: collapse;
|
529
|
+
}
|
530
|
+
table.kiss_form_section > tbody > tr > td {
|
531
|
+
padding: 0 12px 0 0;
|
532
|
+
}
|
533
|
+
|
534
|
+
td.kiss_form_column {
|
535
|
+
vertical-align: top;
|
536
|
+
}
|
537
|
+
table.kiss_form_column {
|
471
538
|
margin-bottom: 6px;
|
472
539
|
}
|
473
|
-
.
|
474
|
-
padding: 2px
|
540
|
+
table.kiss_form_column > tbody > tr > td {
|
541
|
+
padding: 2px 6px 2px 0;
|
475
542
|
vertical-align: middle;
|
476
543
|
}
|
477
|
-
.
|
544
|
+
.kiss_form_errors {
|
478
545
|
margin-bottom: 4px;
|
479
546
|
}
|
480
|
-
.
|
547
|
+
.kiss_form_errors td {
|
481
548
|
background-color: #ff8;
|
482
549
|
padding: 2px 4px;
|
483
550
|
line-height: 135%;
|
484
551
|
color: #900;
|
485
|
-
border: 1px solid #
|
552
|
+
border: 1px solid #db4;
|
486
553
|
}
|
487
|
-
.
|
554
|
+
.kiss_form_errors td ul {
|
488
555
|
padding-left: 16px;
|
489
556
|
margin: 0;
|
490
557
|
}
|
491
|
-
.kiss_form .
|
492
|
-
padding:
|
558
|
+
.kiss_form .kiss_form_help {
|
559
|
+
padding-bottom: 4px;
|
493
560
|
font-size: 90%;
|
494
561
|
color: #555;
|
495
562
|
}
|
496
|
-
.
|
563
|
+
.kiss_form_required {
|
497
564
|
color: #a21;
|
498
565
|
font-size: 150%;
|
499
566
|
line-height: 50%;
|
500
567
|
position: relative;
|
501
568
|
top: 4px;
|
502
569
|
}
|
503
|
-
.
|
570
|
+
.kiss_form_column td.kiss_form_label {
|
504
571
|
text-align: right;
|
505
572
|
white-space: nowrap;
|
506
573
|
}
|
507
|
-
.
|
574
|
+
.kiss_form_column td.kiss_form_label.error {
|
508
575
|
color: #b10;
|
509
576
|
}
|
510
|
-
.
|
577
|
+
.kiss_form_column tr.kiss_form_prompt td {
|
511
578
|
padding: 8px 3px 0px 4px;
|
512
579
|
}
|
513
|
-
.
|
514
|
-
|
515
|
-
|
516
|
-
.kiss_form input[type="text"],
|
517
|
-
.kiss_form input[type=password],
|
518
|
-
.kiss_form textarea {
|
580
|
+
.kiss_form_column input[type="text"],
|
581
|
+
.kiss_form_column input[type=password],
|
582
|
+
.kiss_form_column textarea {
|
519
583
|
width: 250px;
|
520
584
|
margin-left: 0;
|
521
585
|
margin-right: 0;
|
522
586
|
}
|
523
|
-
.
|
587
|
+
.kiss_form_column table.kiss_form_field_columns {
|
524
588
|
border-spacing: 0;
|
525
589
|
border-collapse: collapse;
|
526
590
|
width: 100%;
|
527
591
|
}
|
528
|
-
.
|
592
|
+
.kiss_form_column table.kiss_form_field_columns td {
|
529
593
|
padding: 0 16px 2px 0;
|
530
594
|
vertical-align: top;
|
531
595
|
}
|
532
|
-
.
|
596
|
+
.kiss_form_column .kiss_form_checkbox .kiss_form_label {
|
533
597
|
vertical-align: top;
|
534
598
|
padding-top: 3px;
|
535
599
|
}
|
536
|
-
.
|
600
|
+
.kiss_form_column .kiss_form_radio .kiss_form_label {
|
537
601
|
vertical-align: top;
|
538
602
|
padding-top: 4px;
|
539
603
|
}
|
540
|
-
.
|
604
|
+
.kiss_form_column .kiss_form_textarea .kiss_form_label {
|
541
605
|
vertical-align: top;
|
542
606
|
padding-top: 3px;
|
543
607
|
}
|
608
|
+
.kiss_form tr.kiss_form_submit td {
|
609
|
+
padding: 0 6px 0 0;
|
610
|
+
text-align: center;
|
611
|
+
}
|
544
612
|
EOT
|
545
613
|
)
|
546
|
-
|
614
|
+
|
615
|
+
if @_error_class == 'kiss_form_error_message'
|
616
|
+
styles.push( <<-EOT
|
547
617
|
.kiss_form_error_message {
|
548
618
|
padding: 1px 4px;
|
549
|
-
border: 1px solid #
|
550
|
-
border-top: 0;
|
551
|
-
border-bottom: 1px solid #db4;
|
619
|
+
border: 1px solid #db4;
|
552
620
|
background-color: #ff8;
|
553
621
|
color: #900;
|
554
622
|
font-size: 90%;
|
555
623
|
line-height: 135%;
|
556
624
|
display: block;
|
557
625
|
float: left;
|
626
|
+
width: 246px;
|
558
627
|
margin-bottom: 2px;
|
559
628
|
}
|
560
629
|
.kiss_form_error_message div {
|
@@ -574,7 +643,8 @@ tr.kiss_form_error_row .kiss_form_error_message {
|
|
574
643
|
margin-bottom: 0;
|
575
644
|
}
|
576
645
|
EOT
|
577
|
-
|
646
|
+
)
|
647
|
+
end
|
578
648
|
style_tag = styles.size == 0 ? '' : "<style>" + styles.join('') + "</style>"
|
579
649
|
|
580
650
|
# combine
|
@@ -586,7 +656,14 @@ EOT
|
|
586
656
|
"</div></form>#{@_append_html}"
|
587
657
|
end
|
588
658
|
|
589
|
-
# Renders form
|
659
|
+
# Renders HTML for form sections.
|
660
|
+
def sections_html
|
661
|
+
sections.map do |section|
|
662
|
+
section.html
|
663
|
+
end.join
|
664
|
+
end
|
665
|
+
|
666
|
+
# Renders HTML for form fields.
|
590
667
|
def components_html
|
591
668
|
@_components.map do |component|
|
592
669
|
component_html(component)
|
@@ -596,22 +673,22 @@ EOT
|
|
596
673
|
|
597
674
|
# Renders open of form table.
|
598
675
|
def table_html_open
|
599
|
-
%Q(<table class="kiss_form" border=0 cellspacing=0>)
|
676
|
+
%Q(<table class="kiss_form" border=0 cellspacing=0><tbody>)
|
600
677
|
end
|
601
678
|
|
602
679
|
def required_legend_html
|
603
680
|
(@_has_required_fields && @_mark_required) ?
|
604
|
-
%Q( <tr><td
|
681
|
+
%Q( <tr><td class="kiss_form_help">Required fields marked by <span class="kiss_form_required">*</span></td></tr> ) : ''
|
605
682
|
end
|
606
683
|
|
607
684
|
# Renders close of form table.
|
608
685
|
def table_html_close
|
609
|
-
'</table>'
|
686
|
+
'</tbody></table>'
|
610
687
|
end
|
611
688
|
|
612
689
|
# Renders form submit buttons.
|
613
690
|
def submit_html
|
614
|
-
@_submit ?
|
691
|
+
@_submit ? %Q(<tr class="kiss_form_submit"><td>#{@_submit.element_html}</td></tr>) : ''
|
615
692
|
end
|
616
693
|
|
617
694
|
# Renders complete form HTML.
|
@@ -620,7 +697,7 @@ EOT
|
|
620
697
|
html_open,
|
621
698
|
table_html_open,
|
622
699
|
required_legend_html,
|
623
|
-
|
700
|
+
sections_html,
|
624
701
|
submit_html,
|
625
702
|
table_html_close,
|
626
703
|
html_close
|
@@ -630,23 +707,23 @@ EOT
|
|
630
707
|
# Renders HTML for specified form field.
|
631
708
|
def component_html(field)
|
632
709
|
field = fields[field.to_s] if (field.is_a?(Symbol) || field.is_a?(String))
|
633
|
-
return field.element_html if field.
|
710
|
+
return field.element_html if field.is_a?(HiddenField)
|
634
711
|
|
635
|
-
type = field.type
|
712
|
+
type = field.class.type
|
636
713
|
prompt = field.prompt
|
637
714
|
label = field.label
|
638
715
|
errors = field.errors_html
|
639
|
-
required = field.required ? %Q(<span class="
|
716
|
+
required = field.required ? %Q(<span class="kiss_form_required">#{@_mark_required}</span> ) : ''
|
640
717
|
|
641
718
|
([
|
642
|
-
prompt ? %Q(<tr class="
|
719
|
+
prompt ? %Q(<tr class="kiss_form_prompt"><td class="kiss_form_label">#{required}</td><td>#{prompt.to_s}</td></tr>) : '',
|
643
720
|
|
644
|
-
%Q(<tr class="
|
721
|
+
%Q(<tr class="kiss_form_#{type}"><td class="kiss_form_label#{errors ? ' error' : ''}">),
|
645
722
|
!prompt ? (required + (label.blank? ? '' : label.to_s + ':' )) : '',
|
646
|
-
%Q(</td><td class="
|
723
|
+
%Q(</td><td class="kiss_form_#{type}">),
|
647
724
|
field.element_html, "</td></tr>"
|
648
725
|
] + (errors ? [
|
649
|
-
'<tr class="kiss_form_error_row"><td class="
|
726
|
+
'<tr class="kiss_form_error_row"><td class="kiss_form_required"></td><td>',
|
650
727
|
errors,
|
651
728
|
'</td></tr>'
|
652
729
|
] : [])).join
|
data/lib/kiss.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# Kiss - A web application framework for Ruby
|
2
|
-
# Copyright (C) 2005-
|
2
|
+
# Copyright (C) 2005-2012 AppJudo Inc.
|
3
3
|
# See LICENSE for details.
|
4
4
|
|
5
|
-
# Author:: Shawn Van Ittersum,
|
6
|
-
# Copyright:: Copyright (c) 2005-
|
5
|
+
# Author:: Shawn Van Ittersum, AppJudo Inc.
|
6
|
+
# Copyright:: Copyright (c) 2005-2012 AppJudo Inc.
|
7
7
|
# License:: MIT X11 License
|
8
8
|
|
9
9
|
require 'rubygems'
|
metadata
CHANGED
@@ -4,9 +4,8 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 1
|
7
|
-
-
|
8
|
-
|
9
|
-
version: 1.7.4
|
7
|
+
- 8
|
8
|
+
version: "1.8"
|
10
9
|
platform: ruby
|
11
10
|
authors:
|
12
11
|
- Shawn Van Ittersum
|
@@ -14,7 +13,7 @@ autorequire:
|
|
14
13
|
bindir: bin
|
15
14
|
cert_chain: []
|
16
15
|
|
17
|
-
date: 2012-02-
|
16
|
+
date: 2012-02-11 00:00:00 -08:00
|
18
17
|
default_executable:
|
19
18
|
dependencies:
|
20
19
|
- !ruby/object:Gem::Dependency
|
@@ -107,7 +106,6 @@ files:
|
|
107
106
|
- lib/kiss/ext/sequel_database.rb
|
108
107
|
- lib/kiss/ext/sequel_mysql_dataset.rb
|
109
108
|
- lib/kiss/form/field.rb
|
110
|
-
- lib/kiss/form/field_types.rb
|
111
109
|
- lib/kiss/form.rb
|
112
110
|
- lib/kiss/format.rb
|
113
111
|
- lib/kiss/html/exception_report.css
|