togo 0.4.1 → 0.6.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.
@@ -6,7 +6,7 @@ var app = (function() {
6
6
 
7
7
  var searchInputHandler = function(action) {
8
8
  return function(e) {
9
- console.log(e);
9
+ e = e || window.event;
10
10
  if (this.value == '') {
11
11
  this.value = searchInputDefaultValue;
12
12
  }
@@ -17,6 +17,7 @@ var app = (function() {
17
17
  };
18
18
 
19
19
  var handleMultiSelect = function(e) {
20
+ e = e || window.event;
20
21
  var id = e.target.getAttribute('id').split('_')[1];
21
22
  if (e.target.checked) {
22
23
  selectedItems.push(id);
@@ -42,7 +43,7 @@ var app = (function() {
42
43
  var c = el('list-table').getElementsByTagName('input');
43
44
  for (var i = 0; i < c.length; i++) {
44
45
  if (c[i].getAttribute('type') == 'checkbox') {
45
- c[i].addEventListener('click', handleMultiSelect, false);
46
+ listen('click', c[i], handleMultiSelect);
46
47
  }
47
48
  }
48
49
 
@@ -1,3 +1,22 @@
1
+ if (!Array.prototype.some)
2
+ {
3
+ Array.prototype.some = function(fun /*, thisp*/)
4
+ {
5
+ var len = this.length;
6
+ if (typeof fun != "function")
7
+ throw new TypeError();
8
+
9
+ var thisp = arguments[1];
10
+ for (var i = 0; i < len; i++)
11
+ {
12
+ if (i in this &&
13
+ fun.call(thisp, this[i], i, this))
14
+ return true;
15
+ }
16
+
17
+ return false;
18
+ };
19
+ }
1
20
  function el(node) {
2
21
  return document.getElementById(node);
3
22
  }
@@ -86,6 +105,20 @@ var ajax = function(opts) {
86
105
  req.send(null);
87
106
  };
88
107
 
108
+ var ensureEvent = function(func) {
109
+ return function() {
110
+ var e = window.event;
111
+ e.target = e.srcElement;
112
+ e.preventDefault = function() {
113
+ e.returnValue = false;
114
+ };
115
+ e.stopPropagation = function() {
116
+ e.cancelBubble = true;
117
+ };
118
+ func.call(e.srcElement,e);
119
+ };
120
+ };
121
+
89
122
  var listen = function(evnt, elem, func) {
90
123
  if (elem.addEventListener) {
91
124
  listen = function(evnt, elem, func) {
@@ -93,7 +126,7 @@ var listen = function(evnt, elem, func) {
93
126
  };
94
127
  } else if (elem.attachEvent) {
95
128
  listen = function(evnt, elem, func) {
96
- elem.attachEvent('on' + evnt, func);
129
+ elem.attachEvent('on' + evnt, ensureEvent(func));
97
130
  };
98
131
  }
99
132
  listen(evnt,elem,func);
@@ -106,7 +139,7 @@ var unlisten = function(evnt, elem, func) {
106
139
  };
107
140
  } else if (elem.attachEvent) {
108
141
  unlisten = function(evnt, elem, func) {
109
- elem.detachEvent('on' + evnt, func);
142
+ elem.detachEvent('on' + evnt, ensureEvent(func));
110
143
  };
111
144
  }
112
145
  unlisten(evnt,elem,func);
@@ -232,23 +265,24 @@ AssociationManager.prototype.addLinkToValue = function(id, value, linkIt) {
232
265
  return '<a href="/edit/' + this.model + '/' + id + '">' + value + '</a>';
233
266
  };
234
267
 
235
- AssociationManager.prototype.generateRow = function(data) {
236
- var out = '<tr><td class="checkbox active">' +
237
- '<input type="' + this.selectorType + '" value="' + data.id + '" id="selection_' + this.model + '_' + data.id + '"';
268
+ AssociationManager.prototype.appendRow = function(data) {
269
+ var tr = this.tbody.insertRow(-1);
270
+ var td = tr.insertCell(-1);
271
+ var cb = '<input type="' + this.selectorType + '" value="' + data.id + '" id="selection_' + this.model + '_' + data.id + '"';
238
272
  if (this.relatedIds[data.id]) {
239
- out += ' checked="checked"';
273
+ cb += ' checked="checked"';
240
274
  }
241
275
  if (this.selectorType == 'radio') {
242
- out += ' name=' + this.model + '_' + this.name + '_selection';
276
+ cb += ' name="' + this.model + '_' + this.name + '_selection"';
243
277
  }
244
- out += ' /></td>';
278
+ cb += ' />';
279
+ addClass(td, 'checkbox active');
280
+ td.innerHTML = cb;
245
281
  var linkIt = true;
246
282
  for (var i = 0, len = this.fields.length; i < len; i++) {
247
283
  if (i == 1) { linkIt = false; }
248
- out += '<td>' + this.addLinkToValue(data.id, (data[this.fields[i]] == null ? '-' : data[this.fields[i]]), linkIt) + '</td>';
284
+ tr.insertCell(-1).innerHTML = this.addLinkToValue(data.id, (data[this.fields[i]] == null ? '-' : data[this.fields[i]]), linkIt);
249
285
  }
250
- out += '</tr>';
251
- return out;
252
286
  };
253
287
 
254
288
  AssociationManager.prototype.clearTable = function() {
@@ -330,11 +364,9 @@ AssociationManager.prototype.searchResultsHandler = function(handler) {
330
364
  handler.pageCountField.innerHTML = handler.pageCount;
331
365
  handler.pageNumberField.innerHTML = handler.pageNumber;
332
366
  if (data.results.length > 0) {
333
- var out = [];
334
367
  for (var i = 0, len = data.results.length; i < len; i++) {
335
- out.push(handler.generateRow(data.results[i]));
368
+ handler.appendRow(data.results[i]);
336
369
  }
337
- handler.tbody.innerHTML = out.join('');
338
370
  } else {
339
371
  }
340
372
  handler.toggleCheckboxes();
@@ -0,0 +1,14 @@
1
+ <div id="paging" class="paging">
2
+ <%= @count %> result<%= @count != 1 ? 's' : '' %>
3
+ <% if @page_count > 1 %>
4
+ / Page <span class="page-number"><%= @p %></span> of <span class="page-count"><%= @page_count %></span> /
5
+ <% prev_link, next_link = paging_links(@p, @page_count, :q => params[:q], :o => params[:o]) %>
6
+ <%= prev_link %>
7
+ <%= next_link %>
8
+ <% end %>
9
+ <form method="get" id="search-form">
10
+ <fieldset>
11
+ <input type="text" name="q" value="<%= params[:q].blank? ? 'Search...' : params[:q] %>" size="40" />
12
+ </fieldset>
13
+ </form>
14
+ </div>
@@ -1,6 +1,9 @@
1
- <h1><a href="/<%= @model.name %>"><%= @model.display_name %></a> / Edit</h1>
2
1
  <form action="/update/<%= @model.name %>/<%= @content.id %>" method="post" id="edit-form">
3
- <div class="wrapper">
2
+ <input type="hidden" name="return_url" value="<%= request.referer || '/locations' %>" />
3
+ <div id="subhead">
4
+ <h1><a href="/<%= @model.name %>"><%= @model.display_name %></a> / Edit</h1>
5
+ </div>
6
+ <div id="main">
4
7
  <% if @errors %><div id="save_errors" class="errors"><%= @errors %></div><% end %>
5
8
  <% @model.get_form_properties.each do |p| %>
6
9
  <fieldset id="property-<%= p.name %>" class="<%= @model.field_class_for(p) %>">
@@ -9,13 +12,7 @@
9
12
  <% end %>
10
13
  </div>
11
14
  <div class="actions">
12
- <button type="submit" class="save">Save</button>
15
+ <button type="submit" class="save">Save <%= @model.display_name.singularize %></button>
13
16
  </div>
14
17
  </form>
15
- <div class="actions external">
16
- <form action="/delete/<%= @model.name %>" method="post" id="delete-form">
17
- <input type="hidden" id="delete-list" name="id" value="<%= @content.id %>" />
18
- <button type="submit" id="delete-button">Delete</button>
19
- </form>
20
- </div>
21
18
  <script type="text/javascript" src="/js/edit.js"></script>
@@ -1,53 +1,53 @@
1
- <h1><%= @model.display_name %></h1>
2
- <div id="paging">
3
- <%= @count %> item<%= @count != 1 ? 's' : '' %>
4
- <% if @page_count > 1 %>
5
- Page <span class="page-number"><%= @p %></span> of <span class="page-count"><%= @page_count %></span>
6
- <% prev_link, next_link = paging_links(@p, @page_count, :q => params[:q]) %>
7
- <%= prev_link %>
8
- <%= next_link %>
9
- <% end %>
10
- </div>
11
- <form method="get" id="search-form">
12
- <fieldset>
13
- <input type="text" name="q" value="<%= params[:q].blank? ? 'Search...' : params[:q] %>" size="40" />
14
- </fieldset>
15
- </form>
16
- <div class="wrapper">
17
- <table id="list-table">
18
- <thead>
19
- <tr>
20
- <% if not @content.empty? %>
21
- <th></th>
22
- <% end %>
23
- <% @model.get_list_properties.each do |p| %>
24
- <th><%= p.name.to_s.humanize.titleize %></th>
1
+ <div id="subhead">
2
+ <h1><%= @model.display_name %>
3
+ <div id="model-select">
4
+ <ul>
5
+ <% Togo.models.each do |m| %>
6
+ <% next if m == @model %>
7
+ <li><a href="/<%= m.name %>"><%= m.display_name %></a></li>
25
8
  <% end %>
26
- </tr>
27
- </thead>
28
- <tbody>
29
- <% if @content.empty? %>
30
- <tr>
31
- <td colspan="<%= @model.get_list_properties.size %>"><% if params[:q] %>No results for '<%= params[:q] %>'<% else %>No content has been created yet.<% end %></td>
32
- </tr>
33
- <% else %>
34
- <% @content.each do |c| %>
35
- <tr>
36
- <td class="checkbox"><input type="checkbox" name="selection[<%= c.id %>]" value="1" id="selection_<%= c.id %>" /></td>
37
- <% @model.get_list_properties.each_with_index do |p,i| %>
38
- <td><% if i == 0 %><a href="/edit/<%= @model.name %>/<%= c.id %>"><%= c.send(p.name.to_sym) || '-' %></a><% else %><%= c.send(p.name.to_sym) %><% end %></td>
39
- <% end %>
40
- </tr>
41
- <% end %>
42
- <% end %>
43
- </tbody>
44
- </table>
9
+ </ul>
10
+ </div>
11
+ </h1>
12
+ </div>
13
+ <div id="main">
14
+ <%= partial :_paging %>
15
+ <div class="list-table-wrapper">
16
+ <table cellspacing="0" id="list-table">
17
+ <thead>
18
+ <tr>
19
+ <% if not @content.empty? %>
20
+ <th>&nbsp;</th>
21
+ <% end %>
22
+ <% @model.get_list_properties.each do |p| %>
23
+ <th><%= column_head_link(p, @order, :q => params[:q], :p => params[:p]) %></th>
24
+ <% end %>
25
+ </tr>
26
+ </thead>
27
+ <tbody>
28
+ <% if @content.empty? %>
29
+ <tr>
30
+ <td colspan="<%= @model.get_list_properties.size %>"><% if params[:q] %>No results for '<%= params[:q] %>'<% else %>No content has been created yet.<% end %></td>
31
+ </tr>
32
+ <% else %>
33
+ <% @content.each do |c| %>
34
+ <tr>
35
+ <td class="checkbox"><input type="checkbox" name="selection[<%= c.id %>]" value="1" id="selection_<%= c.id %>" /></td>
36
+ <% @model.get_list_properties.each_with_index do |p,i| %>
37
+ <td><% if i == 0 %><a href="/edit/<%= @model.name %>/<%= c.id %>"><%= c.send(p.name.to_sym) || '-' %></a><% else %><%= c.send(p.name.to_sym) %><% end %></td>
38
+ <% end %>
39
+ </tr>
40
+ <% end %>
41
+ <% end %>
42
+ </tbody>
43
+ </table>
44
+ </div>
45
45
  </div>
46
46
  <div class="actions">
47
- <a href="/new/<%= @model.name %>" class="action new" id="new-button">New</a>
48
47
  <form action="/delete/<%= @model.name %>" method="post" id="delete-form">
49
48
  <input type="hidden" id="delete-list" name="id" value="" />
50
49
  <button type="submit" id="delete-button" disabled="disabled" onclick="return confirm('Are you sure you want to delete these items?');">Delete</button>
51
50
  </form>
51
+ <button onclick="window.location='/new/<%= @model.name %>'; return false;">New...</button>
52
52
  </div>
53
53
  <script type="text/javascript" src="/js/index.js"></script>
@@ -1,24 +1,22 @@
1
- <?xml version="1.0" encoding="iso-8859-1"?>
2
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
3
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
4
- <html xmlns="http://www.w3.org/1999/xhtml">
1
+ <!DOCTYPE html>
2
+ <html>
5
3
  <head>
6
4
  <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
7
5
  <title>Togo Admin</title>
8
- <link rel="stylesheet" href="/css/screen.css" />
6
+ <link rel="stylesheet" href="/css/screen.css" type="text/css" media="screen" />
9
7
  <script type="text/javascript" src="/js/togo.js"></script>
10
8
  </head>
11
- <body>
12
- <div id="header">Togo</div>
13
- <div id="nav">
14
- <ul>
15
- <% Togo.models.each do |m| %>
16
- <li><a href="/<%= m.name %>" class="<%= @model.name == m.name ? 'selected' : '' %>"><%= m.display_name %></a></li>
17
- <% end %>
18
- </ul>
19
- </div>
20
- <div id="main">
21
- <%= yield %>
9
+ <body id="<%= @body_id %>">
10
+ <div id="container">
11
+ <div id="header">
12
+ <h1>Togo Admin</h1>
13
+ <div id="system-menu">
14
+ <span>System Menu</span>
15
+ </div>
16
+ </div>
17
+ <div id="content">
18
+ <%= yield %>
19
+ </div>
22
20
  </div>
23
21
  </body>
24
22
  </html>
@@ -1,6 +1,9 @@
1
- <h1><a href="/<%= @model.name %>"><%= @model.display_name %></a> / New</h1>
2
1
  <form action="/create/<%= @model.name %>" method="post" id="edit-form">
3
- <div class="wrapper">
2
+ <input type="hidden" name="return_url" value="<%= request.referer || '/locations' %>" />
3
+ <div id="subhead">
4
+ <h1><a href="/<%= @model.name %>"><%= @model.display_name %></a> / New</h1>
5
+ </div>
6
+ <div id="main">
4
7
  <% if @errors %><div id="save_errors" class="errors"><%= @errors %></div><% end %>
5
8
  <% @model.get_form_properties.each do |p| %>
6
9
  <fieldset id="property-<%= p.name %>" class="<%= @model.field_class_for(p) %>">
@@ -1,4 +1,7 @@
1
1
  require 'erubis/tiny'
2
+ %w( relationship_manager many_to_one one_to_many ).each{|l|
3
+ require "togo/model/relationship_manager/#{l}"
4
+ }
2
5
 
3
6
  module Togo
4
7
  module DataMapper
@@ -13,6 +16,8 @@ module Togo
13
16
  base.send(:class_variable_set, :@@user_form_properties, [])
14
17
  base.send(:class_variable_set, :@@custom_form_templates, {})
15
18
  base.send(:class_variable_set, :@@property_options, {})
19
+ base.send(:class_variable_set, :@@inflector, (Extlib::Inflection rescue ActiveSupport::Inflector))
20
+
16
21
  if MODELS.include?(base) # support code reloading
17
22
  MODELS[MODELS.index(base)] = base # preserve order of which models were loaded
18
23
  else
@@ -44,11 +49,11 @@ module Togo
44
49
  end
45
50
 
46
51
  def update_content!(id,attrs)
47
- stage_content(get(id),attrs).save!
52
+ stage_content(get(id),attrs).save
48
53
  end
49
54
 
50
55
  def create_content!(attrs)
51
- stage_content(new,attrs).save!
56
+ stage_content(new,attrs).save
52
57
  end
53
58
 
54
59
  def stage_content(content,attrs)
@@ -56,7 +61,7 @@ module Togo
56
61
  relationships.each do |r|
57
62
  val = attrs["related_#{r[0]}".to_sym]
58
63
  next if not val or val == 'unset'
59
- content = RelationshipManager.new(content, r, :ids => val).relate
64
+ content = RelationshipManager.create(content, r, :ids => val).relate
60
65
  end
61
66
  content
62
67
  end
@@ -77,6 +82,7 @@ module Togo
77
82
  q = "%#{opts[:q].gsub(/\s+/,'%')}%"
78
83
  limit = opts[:limit]
79
84
  offset = opts[:offset]
85
+ order = opts[:order]
80
86
  conditions, values = [], []
81
87
  search_properties.each{|l|
82
88
  conditions << "#{l.name} like ?"
@@ -84,6 +90,7 @@ module Togo
84
90
  }
85
91
  params = {:conditions => [conditions.join(' OR ')] + values}
86
92
  params.merge!(:limit => limit.to_i, :offset => offset.to_i) if limit and offset
93
+ params.merge!(:order => order) if order
87
94
  all(params)
88
95
  end
89
96
 
@@ -107,19 +114,27 @@ module Togo
107
114
 
108
115
  def type_from_property(property)
109
116
  case property
110
- when ::DataMapper::Property
111
- Extlib::Inflection.demodulize(property.type || property.class).downcase # type seems to be deprecated in 1.0
117
+ when ::DataMapper::Property::Text
118
+ 'text'
119
+ when (defined?(::DataMapper::Property::Enum) and ::DataMapper::Property::Enum)
120
+ 'string'
112
121
  when ::DataMapper::Associations::ManyToMany::Relationship
113
122
  'many_to_many'
114
123
  when ::DataMapper::Associations::ManyToOne::Relationship
115
124
  'belongs_to'
116
125
  when ::DataMapper::Associations::OneToMany::Relationship
117
126
  'has_n'
127
+ when ::DataMapper::Property
128
+ class_variable_get(:@@inflector).demodulize(property.type || property.primitive || property.class).downcase # type seems to be deprecated in 1.0
118
129
  else
119
130
  'string'
120
131
  end
121
132
  end
122
133
 
134
+ def is_extended_type?(property)
135
+
136
+ end
137
+
123
138
  def pick_properties(selection, args)
124
139
  if class_variable_get(:"@@#{selection}_properties").empty?
125
140
  args = shown_properties.map{|p| p.name} if args.empty?
@@ -146,38 +161,5 @@ module Togo
146
161
  end
147
162
 
148
163
  end # Model
149
-
150
- class RelationshipManager
151
- def initialize(content, relationship, opts = {})
152
- @content = content
153
- @relationship = relationship[1]
154
- @relationship_name = relationship[0]
155
- @ids = (opts[:ids] || '').split(',').map(&:to_i)
156
- define_values
157
- end
158
-
159
- def relate
160
- @content.send("#{@relationship_name}=", find_for_assignment)
161
- @content
162
- end
163
-
164
- def define_values
165
- case @relationship
166
- when ::DataMapper::Associations::ManyToOne::Relationship
167
- @unset_value = nil
168
- @related_model = @relationship.parent_model
169
- @find_op = Proc.new{|p| p.get(@ids.first)}
170
- when ::DataMapper::Associations::OneToMany::Relationship
171
- @unset_value = []
172
- @related_model = @relationship.child_model
173
- @find_op = Proc.new{|p| p.all(:id => @ids)}
174
- end
175
- end
176
-
177
- def find_for_assignment
178
- return @unset_value if @ids.blank?
179
- @find_op.call(@related_model)
180
- end
181
- end # RelationshipManager
182
164
  end # DataMapper
183
165
  end # Togo
@@ -0,0 +1,19 @@
1
+ module Togo
2
+ module DataMapper
3
+
4
+ class ManyToOne < RelationshipManager
5
+ def unset_value
6
+ nil
7
+ end
8
+
9
+ def related_model
10
+ @relationship.parent_model
11
+ end
12
+
13
+ def find_for_assignment
14
+ related_model.get(@ids.first)
15
+ end
16
+ end
17
+
18
+ end # DataMapper
19
+ end # Model
@@ -0,0 +1,19 @@
1
+ module Togo
2
+ module DataMapper
3
+
4
+ class OneToMany < RelationshipManager
5
+ def unset_value
6
+ []
7
+ end
8
+
9
+ def related_model
10
+ @relationship.child_model
11
+ end
12
+
13
+ def find_for_assignment
14
+ related_model.all(:id => @ids)
15
+ end
16
+ end
17
+
18
+ end # DataMapper
19
+ end # Model
@@ -0,0 +1,40 @@
1
+ module Togo
2
+ module DataMapper
3
+ class RelationshipManager
4
+
5
+ def self.create(content, relationship, opts = {})
6
+ case relationship[1]
7
+ when ::DataMapper::Associations::ManyToOne::Relationship
8
+ ManyToOne.new(content, relationship, opts)
9
+ when ::DataMapper::Associations::OneToMany::Relationship
10
+ OneToMany.new(content, relationship, opts)
11
+ end
12
+ end
13
+
14
+ def initialize(content, relationship, opts = {})
15
+ @content = content
16
+ @relationship = relationship[1]
17
+ @relationship_name = relationship[0]
18
+ @ids = (opts[:ids] || '').split(',').map(&:to_i)
19
+ end
20
+
21
+ def relate
22
+ @content.send("#{@relationship_name}=", find_for_assignment)
23
+ @content
24
+ end
25
+
26
+ def unset_values
27
+ raise NotImplementedError
28
+ end
29
+
30
+ def related_model
31
+ raise NotImplementedError
32
+ end
33
+
34
+ def find_for_assignment
35
+ raise NotImplementedError
36
+ end
37
+
38
+ end
39
+ end # DataMapper
40
+ end # Togo
@@ -5,49 +5,51 @@
5
5
  <input type="hidden" name="related_<%= property.name %>" class="related_ids" value="unset" />
6
6
  <label for="<%= property.name %>"><%= related_model.display_name %></label>
7
7
  <div class="search" id="search-<%= related_model.name %>">
8
- <input type="text" name="search-<%= property.name %>" value="Search..." />
9
8
  <div class="paging">
10
- Page <span class="page-number">1</span> of <span class="page-count"><%= (content_count/10).ceil %></span>
11
- <a href="#" rel="prev">&laquo; Previous</a> <a href="#" rel="next">Next &raquo;</a>
9
+ <input type="text" name="search-<%= property.name %>" value="Search..." />
10
+ Page <span class="page-number">1</span> of <span class="page-count"><%= (content_count/10).ceil %></span> /
11
+ <a href="#" rel="prev">Previous</a> <a href="#" rel="next">Next</a>
12
12
  </div>
13
13
  </div>
14
- <table>
15
- <thead>
16
- <tr>
17
- <th class="checkbox"></th>
18
- <% related_model.get_list_properties.each do |p| %>
19
- <th><%= p.name.to_s.humanize.titleize %></th>
20
- <% end %>
21
- </tr>
22
- </thead>
23
- <tfoot>
24
- <tr>
25
- <td class="checkbox"></td>
26
- <td colspan="<%= related_model.get_form_properties.size-2 %>">
27
- <span class="associated-count-display" style="display: none;">
28
- ...and <span class="associated-count"><%= content_count-related_content.size %></span> more associated items
29
- </span>
30
- <button class="association-modify">Modify</button>
31
- </td>
32
- </tr>
33
- </tfoot>
34
- <tbody>
35
- <% if related_content.empty? %>
36
- <tr>
37
- <td colspan="<%= related_model.get_form_properties.size %>">No Content Associated.</td>
38
- </tr>
39
- <% else %>
40
- <% related_content.each do |c| %>
41
- <tr>
42
- <td class="checkbox"><input type="radio" name="selection[<%= c.id %>]" value="<%= c.id %>" id="selection_<%= related_model.name %>_<%= c.id %>" checked="checked" /></td>
43
- <% related_model.get_list_properties.each_with_index do |p,i| %>
44
- <td><% if i == 0 %><a href="/edit/<%= related_model.name %>/<%= c.id %>"><%= c.send(p.name.to_sym) || '-' %></a><% else %><%= c.send(p.name.to_sym) %><% end %></td>
45
- <% end %>
46
- </tr>
47
- <% end %>
48
- <% end %>
49
- </tbody>
50
- </table>
14
+ <div class="list-table-wrapper">
15
+ <table cellspacing="0">
16
+ <thead>
17
+ <tr>
18
+ <th class="checkbox">&nbsp;</th>
19
+ <% related_model.get_list_properties.each do |p| %>
20
+ <th><%= p.name.to_s.humanize.titleize %></th>
21
+ <% end %>
22
+ </tr>
23
+ </thead>
24
+ <tfoot>
25
+ <tr>
26
+ <td class="checkbox"></td>
27
+ <td colspan="<%= related_model.get_list_properties.size %>">
28
+ <span class="associated-count-display" style="display: none;">
29
+ ...and <span class="associated-count"><%= content_count-related_content.size %></span> more associated items
30
+ </span>
31
+ <button class="association-modify">Modify</button>
32
+ </td>
33
+ </tr>
34
+ </tfoot>
35
+ <tbody>
36
+ <% if related_content.empty? %>
37
+ <tr>
38
+ <td colspan="<%= related_model.get_list_properties.size %>">No Content Associated.</td>
39
+ </tr>
40
+ <% else %>
41
+ <% related_content.each do |c| %>
42
+ <tr>
43
+ <td class="checkbox"><input type="radio" name="selection[<%= c.id %>]" value="<%= c.id %>" id="selection_<%= related_model.name %>_<%= c.id %>" checked="checked" /></td>
44
+ <% related_model.get_list_properties.each_with_index do |p,i| %>
45
+ <td><% if i == 0 %><a href="/edit/<%= related_model.name %>/<%= c.id %>"><%= c.send(p.name.to_sym) || '-' %></a><% else %><%= c.send(p.name.to_sym) %><% end %></td>
46
+ <% end %>
47
+ </tr>
48
+ <% end %>
49
+ <% end %>
50
+ </tbody>
51
+ </table>
52
+ </div>
51
53
  <script type="text/javascript">
52
54
  new AssociationManager({
53
55
  relationship: 'belongs_to',