togo 0.4.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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',