kiss 1.7.4 → 1.8

Sign up to get free protection for your applications and to get access to all the features.
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
- @@component_types.keys.map do |type|
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 @@component_types.has_key?(type)
204
+ raise "invalid field type '#{type}'" unless COMPONENT_TYPES.has_key?(type)
149
205
 
150
- field = @@component_types[type].new(self, attrs.merge(
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
- while true
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 = @@component_types[:submit].new(self, attrs, &block)
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| hash[field.name] = field.value }
225
- hash['submit'] = @_submit.value = params[@_submit.name.to_s]
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
- # ignore fields whose name starts with underscore
372
+ # skip fields whose name starts with underscore
324
373
  next if field.name =~ /\A\_/
325
- # don't save 'ignore' fields to the database
326
- next if field.ignore || !field.save
327
- # ignore file fields
328
- next if field.type == :file
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
- key = field.key.to_sym
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="kiss_error"><tr><td>#{content}</td></tr></table>)
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
- .kiss_form td {
474
- padding: 2px 4px;
540
+ table.kiss_form_column > tbody > tr > td {
541
+ padding: 2px 6px 2px 0;
475
542
  vertical-align: middle;
476
543
  }
477
- .kiss_form .kiss_error {
544
+ .kiss_form_errors {
478
545
  margin-bottom: 4px;
479
546
  }
480
- .kiss_form .kiss_error td {
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 #ea4;
552
+ border: 1px solid #db4;
486
553
  }
487
- .kiss_form .kiss_error td ul {
554
+ .kiss_form_errors td ul {
488
555
  padding-left: 16px;
489
556
  margin: 0;
490
557
  }
491
- .kiss_form .kiss_help {
492
- padding: 0px 3px 0 6px;
558
+ .kiss_form .kiss_form_help {
559
+ padding-bottom: 4px;
493
560
  font-size: 90%;
494
561
  color: #555;
495
562
  }
496
- .kiss_required {
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
- .kiss_form td.kiss_label {
570
+ .kiss_form_column td.kiss_form_label {
504
571
  text-align: right;
505
572
  white-space: nowrap;
506
573
  }
507
- .kiss_form td.kiss_label.error {
574
+ .kiss_form_column td.kiss_form_label.error {
508
575
  color: #b10;
509
576
  }
510
- .kiss_form tr.kiss_prompt td {
577
+ .kiss_form_column tr.kiss_form_prompt td {
511
578
  padding: 8px 3px 0px 4px;
512
579
  }
513
- .kiss_form tr.kiss_submit td.kiss_submit {
514
- padding: 6px 3px;
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
- .kiss_form table.kiss_field_columns {
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
- .kiss_form table.kiss_field_columns td {
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
- .kiss_form .kiss_checkbox .kiss_label {
596
+ .kiss_form_column .kiss_form_checkbox .kiss_form_label {
533
597
  vertical-align: top;
534
598
  padding-top: 3px;
535
599
  }
536
- .kiss_form .kiss_radio .kiss_label {
600
+ .kiss_form_column .kiss_form_radio .kiss_form_label {
537
601
  vertical-align: top;
538
602
  padding-top: 4px;
539
603
  }
540
- .kiss_form .kiss_textarea .kiss_label {
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
- styles.push( <<-EOT
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 #edc;
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
- ) if @_error_class == 'kiss_form_error_message'
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 fields HTML.
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></td><td class="kiss_help">Required fields marked by <span class="kiss_required">*</span></td></tr> ) : ''
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 ? field_html(@_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
- components_html,
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.type == :hidden
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="kiss_required">#{@_mark_required}</span> ) : ''
716
+ required = field.required ? %Q(<span class="kiss_form_required">#{@_mark_required}</span> ) : ''
640
717
 
641
718
  ([
642
- prompt ? %Q(<tr class="kiss_prompt"><td class="kiss_label">#{required}</td><td>#{prompt.to_s}</td></tr>) : '',
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="kiss_#{type}"><td class="kiss_label#{errors ? ' error' : ''}">),
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="kiss_#{type}">),
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="kiss_required"></td><td>',
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-2010 MultiWidget LLC.
2
+ # Copyright (C) 2005-2012 AppJudo Inc.
3
3
  # See LICENSE for details.
4
4
 
5
- # Author:: Shawn Van Ittersum, MultiWidget LLC
6
- # Copyright:: Copyright (c) 2005-2010 MultiWidget LLC.
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
- - 7
8
- - 4
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-02 00:00:00 -08:00
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