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/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