seamless 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/seamless +36 -0
- data/lib/seamless.rb +70 -0
- data/lib/seamless/active_record_extension.rb +11 -0
- data/lib/seamless/dispatcher.rb +45 -0
- data/lib/seamless/message_broker.rb +12 -0
- data/lib/seamless/message_broker_controller.rb +11 -0
- data/lib/seamless/messagebroker/inmemory_message_broker.rb +45 -0
- data/lib/seamless/migration.rb +8 -0
- data/lib/seamless/model.rb +94 -0
- data/lib/seamless/service.rb +186 -0
- data/seamless/seamless_generator.rb +181 -0
- data/seamless/templates/README +24 -0
- data/seamless/templates/admin.html +166 -0
- data/seamless/templates/application.rb +7 -0
- data/seamless/templates/css/global.css +333 -0
- data/seamless/templates/css/seamless-admin.css +281 -0
- data/seamless/templates/css/seamless.css +632 -0
- data/seamless/templates/environment.rb +65 -0
- data/seamless/templates/generate +25 -0
- data/seamless/templates/images/arch.png +0 -0
- data/seamless/templates/images/arrow_undo.png +0 -0
- data/seamless/templates/images/cell_phone.png +0 -0
- data/seamless/templates/images/confirm.png +0 -0
- data/seamless/templates/images/deny.png +0 -0
- data/seamless/templates/images/dialog_close.gif +0 -0
- data/seamless/templates/images/dialog_close_hover.gif +0 -0
- data/seamless/templates/images/email.png +0 -0
- data/seamless/templates/images/exclamation.png +0 -0
- data/seamless/templates/images/indicator.gif +0 -0
- data/seamless/templates/images/indicator2.gif +0 -0
- data/seamless/templates/images/seamless.gif +0 -0
- data/seamless/templates/images/shadow.gif +0 -0
- data/seamless/templates/images/shadowAlpha.png +0 -0
- data/seamless/templates/images/small_star.png +0 -0
- data/seamless/templates/images/table_add.png +0 -0
- data/seamless/templates/images/table_delete.png +0 -0
- data/seamless/templates/images/table_edit.png +0 -0
- data/seamless/templates/images/table_go.png +0 -0
- data/seamless/templates/images/table_refresh.png +0 -0
- data/seamless/templates/images/tag.png +0 -0
- data/seamless/templates/images/warning.png +0 -0
- data/seamless/templates/images/wizard.gif +0 -0
- data/seamless/templates/images/work_phone.png +0 -0
- data/seamless/templates/index.html +171 -0
- data/seamless/templates/js/seamless-admin.js +255 -0
- data/seamless/templates/js/seamless.js +2755 -0
- data/seamless/templates/message_broker.rb +6 -0
- data/seamless/templates/message_broker_helper.rb +2 -0
- data/seamless/templates/robots.txt +2 -0
- data/seamless/templates/routes.rb +18 -0
- data/seamless/templates/seamless.xml +5 -0
- data/seamless/templates/server +4 -0
- data/seamless/templates/test_service.rb +13 -0
- data/service/USAGE +21 -0
- data/service/service_generator.rb +59 -0
- data/service/templates/service.rb +14 -0
- metadata +122 -0
@@ -0,0 +1,65 @@
|
|
1
|
+
# Be sure to restart your web server when you modify this file.
|
2
|
+
|
3
|
+
# Uncomment below to force Rails into production mode when
|
4
|
+
# you don't control web/app server and can't set it the proper way
|
5
|
+
# ENV['RAILS_ENV'] ||= 'production'
|
6
|
+
|
7
|
+
# Specifies gem version of Rails to use when vendor/rails is not present
|
8
|
+
<%= '# ' if freeze %>RAILS_GEM_VERSION = '<%= Rails::VERSION::STRING %>' unless defined? RAILS_GEM_VERSION
|
9
|
+
|
10
|
+
# Bootstrap the Rails environment, frameworks, and default configuration
|
11
|
+
require File.join(File.dirname(__FILE__), 'boot')
|
12
|
+
|
13
|
+
Rails::Initializer.run do |config|
|
14
|
+
# Settings in config/environments/* take precedence over those specified here
|
15
|
+
|
16
|
+
# Skip frameworks you're not going to use (only works if using vendor/rails)
|
17
|
+
# config.frameworks -= [ :action_web_service, :action_mailer ]
|
18
|
+
|
19
|
+
# Only load the plugins named here, by default all plugins in vendor/plugins are loaded
|
20
|
+
# config.plugins = %W( exception_notification ssl_requirement )
|
21
|
+
|
22
|
+
# NOTE: this is required to load seam(less) services so make sure
|
23
|
+
# you don't remove services dir
|
24
|
+
#
|
25
|
+
# Add additional load paths for your own custom dirs
|
26
|
+
config.load_paths += %W( #{RAILS_ROOT}/app/services )
|
27
|
+
|
28
|
+
# Force all environments to use the same logger level
|
29
|
+
# (by default production uses :info, the others :debug)
|
30
|
+
# config.log_level = :debug
|
31
|
+
|
32
|
+
# Use the database for sessions instead of the file system
|
33
|
+
# (create the session table with 'rake db:sessions:create')
|
34
|
+
# config.action_controller.session_store = :active_record_store
|
35
|
+
|
36
|
+
# Use SQL instead of Active Record's schema dumper when creating the test database.
|
37
|
+
# This is necessary if your schema can't be completely dumped by the schema dumper,
|
38
|
+
# like if you have constraints or database-specific column types
|
39
|
+
# config.active_record.schema_format = :sql
|
40
|
+
|
41
|
+
# Activate observers that should always be running
|
42
|
+
# config.active_record.observers = :cacher, :garbage_collector
|
43
|
+
|
44
|
+
# Make Active Record use UTC-base instead of local time
|
45
|
+
# config.active_record.default_timezone = :utc
|
46
|
+
|
47
|
+
# See Rails::Configuration for more options
|
48
|
+
end
|
49
|
+
|
50
|
+
# Add new inflection rules using the following format
|
51
|
+
# (all these examples are active by default):
|
52
|
+
# Inflector.inflections do |inflect|
|
53
|
+
# inflect.plural /^(ox)$/i, '\1en'
|
54
|
+
# inflect.singular /^(ox)en/i, '\1'
|
55
|
+
# inflect.irregular 'person', 'people'
|
56
|
+
# inflect.uncountable %w( fish sheep )
|
57
|
+
# end
|
58
|
+
|
59
|
+
# Add new mime types for use in respond_to blocks:
|
60
|
+
# Mime::Type.register "text/richtext", :rtf
|
61
|
+
# Mime::Type.register "application/x-mobile", :mobile
|
62
|
+
|
63
|
+
require 'seamless'
|
64
|
+
|
65
|
+
# Include your application configuration below
|
@@ -0,0 +1,25 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require File.dirname(__FILE__) + '/../config/boot'
|
3
|
+
|
4
|
+
if ARGV[0] =~ /((svc)|Service)/i
|
5
|
+
require 'rubygems'
|
6
|
+
gem 'rails'
|
7
|
+
|
8
|
+
# find the path to RAILS
|
9
|
+
rails_gem = Gem.cache.search('rails').last
|
10
|
+
RAILS = rails_gem.full_gem_path
|
11
|
+
|
12
|
+
# find the path to SEAMLESS
|
13
|
+
seamless_gem = Gem.cache.search('seamless').last
|
14
|
+
SEAMLESS = seamless_gem.full_gem_path
|
15
|
+
|
16
|
+
require RAILS + '/lib/rails_generator'
|
17
|
+
require 'rails_generator/scripts/generate'
|
18
|
+
|
19
|
+
path = SEAMLESS
|
20
|
+
Rails::Generator::Base.sources << Rails::Generator::PathSource.new('', path)
|
21
|
+
|
22
|
+
Rails::Generator::Scripts::Generate.new.run(ARGV, {:generator => 'service', :source_root => path, :source => path})
|
23
|
+
else
|
24
|
+
require 'commands/generate'
|
25
|
+
end
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,171 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
2
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:seamless="http://www.hakano.org/seamless">
|
3
|
+
<head>
|
4
|
+
<title>MySeam(less) Starter Application</title>
|
5
|
+
<meta http-equiv="Content-Type" content="UTF-8" />
|
6
|
+
|
7
|
+
<link rel="stylesheet" href="css/global.css" type="text/css" media="all" />
|
8
|
+
<link rel="stylesheet" href="css/seamless.css" type="text/css" media="all" />
|
9
|
+
|
10
|
+
<script src="js/seamless.js" type="text/javascript" />
|
11
|
+
|
12
|
+
<style>
|
13
|
+
body
|
14
|
+
{
|
15
|
+
color:#444;
|
16
|
+
}
|
17
|
+
#logo
|
18
|
+
{
|
19
|
+
float:right;
|
20
|
+
margin-left:10px;
|
21
|
+
margin-right:10px;
|
22
|
+
}
|
23
|
+
#form
|
24
|
+
{
|
25
|
+
margin:30px;
|
26
|
+
}
|
27
|
+
h2
|
28
|
+
{
|
29
|
+
font-weight:bold;
|
30
|
+
font-size:32px;
|
31
|
+
margin-bottom:15px;
|
32
|
+
}
|
33
|
+
textarea
|
34
|
+
{
|
35
|
+
width:100%;
|
36
|
+
height:100px;
|
37
|
+
margin-top:10px;
|
38
|
+
margin-bottom:10px;
|
39
|
+
border:1px solid #aaa;
|
40
|
+
font-size: 18px;
|
41
|
+
padding:3px;
|
42
|
+
}
|
43
|
+
textarea:focus
|
44
|
+
{
|
45
|
+
background-color:#ffffcc;
|
46
|
+
}
|
47
|
+
input#messagetype
|
48
|
+
{
|
49
|
+
margin-left:6px;
|
50
|
+
width:698px;
|
51
|
+
border:1px solid #aaa;
|
52
|
+
font-size: 18px;
|
53
|
+
padding:3px;
|
54
|
+
}
|
55
|
+
input#messagetype:focus
|
56
|
+
{
|
57
|
+
background-color:#ffffcc;
|
58
|
+
}
|
59
|
+
#messagebox
|
60
|
+
{
|
61
|
+
position:absolute;
|
62
|
+
top:380px;
|
63
|
+
left:350px;
|
64
|
+
width:350px;
|
65
|
+
padding:10px;
|
66
|
+
color:#3c78b5;
|
67
|
+
font-weight:bold;
|
68
|
+
}
|
69
|
+
form
|
70
|
+
{
|
71
|
+
margin-bottom:50px;
|
72
|
+
}
|
73
|
+
#trace
|
74
|
+
{
|
75
|
+
margin-top:5px;
|
76
|
+
width:100%;
|
77
|
+
font-family: courier;
|
78
|
+
font-size: 14px;
|
79
|
+
}
|
80
|
+
#banner
|
81
|
+
{
|
82
|
+
background-color:#850001;
|
83
|
+
border-bottom:1px solid #000;
|
84
|
+
height:60px;
|
85
|
+
}
|
86
|
+
#header
|
87
|
+
{
|
88
|
+
background-color:#444;
|
89
|
+
height:10px;
|
90
|
+
}
|
91
|
+
#intro
|
92
|
+
{
|
93
|
+
margin-top:20px;
|
94
|
+
margin-bottom:20px;
|
95
|
+
font-family: Georgia, sans-serif;
|
96
|
+
font-size: 18px;
|
97
|
+
}
|
98
|
+
#footer
|
99
|
+
{
|
100
|
+
margin-top:50px;
|
101
|
+
font-family: Georgia, sans-serif;
|
102
|
+
font-size: 15px;
|
103
|
+
}
|
104
|
+
</style>
|
105
|
+
|
106
|
+
<body>
|
107
|
+
<div id="header"></div>
|
108
|
+
|
109
|
+
<div id="banner">
|
110
|
+
<img id="logo" src="images/seamless.gif" alt="seamless"/>
|
111
|
+
</div>
|
112
|
+
|
113
|
+
<div id="form">
|
114
|
+
<h2 class="primary_light_color">Welcome to the Seam(less) Application Starter Project</h2>
|
115
|
+
|
116
|
+
<div id="intro">
|
117
|
+
This is a simple "starter" project called <strong>myseamless</strong>. The goal of this project is to
|
118
|
+
give you a simple application structure to start your Seam(less) application development. It contains
|
119
|
+
everything you need to make your application - <span class="highlight">seamless</span>.
|
120
|
+
</div>
|
121
|
+
|
122
|
+
<form>
|
123
|
+
<div>Type in a message to test server messaging connectivity: <input id="messagetype" fieldset="myform" type="text" validator="required" value="remote:seamless.test.message.request"/></div>
|
124
|
+
<div><textarea name="message" id="messageargs"></textarea></div>
|
125
|
+
<div>
|
126
|
+
<input type="button" fieldset="myform" onClickMessage="local:send.test.message" activators="messagetype" value="Send Message"/>
|
127
|
+
</div>
|
128
|
+
</form>
|
129
|
+
|
130
|
+
<div style="display:none;" class="infoBox" id="messagebox" onBindMessageEffect="remote:seamless.test.message" onBindMessageEffectType="Appear"
|
131
|
+
onBindMessageEffect1="remote:seamless.test.message" onBindMessageEffect1Type="Fade" onBindMessageEffect1Delay="3000">
|
132
|
+
<img src="images/confirm.png" alt="*"/><span> </span><span onBindMessage="remote:seamless.test.message" onBindMessageProperty="message"></span>
|
133
|
+
</div>
|
134
|
+
|
135
|
+
<div>
|
136
|
+
<strong>Message Trace Log</strong>
|
137
|
+
<textarea id="trace" readonly="true" onBindMessage="~.*" onBindMessageAppend="true" onBindMessageExpr="return '[' + hakano.util.DateTime.get12HourTime() + '] ' + this.direction+':' + this.type + ' => ' + this.data.toJSONString()+'\n'"></textarea>
|
138
|
+
</div>
|
139
|
+
|
140
|
+
<div id="footer">
|
141
|
+
For more information, documentation and demos, please visit <a href="http://www.hakano.org">http://www.hakano.org</a>. <br/>
|
142
|
+
To discuss Seam(less), please <a href="http://groups.google.com/group/seamless-web?hl=en">visit our discussion group</a> or email <a href="mailto:seamless@hakano.org">seamless@hakano.org</a>.<br/>
|
143
|
+
Seam(less) is a product of <a href="http://www.hakano.com">Hakano</a> and Copyright © 2006-2007 by Hakano, Inc. All Rights Reserved.
|
144
|
+
</div>
|
145
|
+
|
146
|
+
<seamless:script onBindMessage="local:send.test.message">
|
147
|
+
try
|
148
|
+
{
|
149
|
+
var type = $("messagetype").value;
|
150
|
+
var args = $('messageargs');
|
151
|
+
var value = args.value;
|
152
|
+
var message = {};
|
153
|
+
if (value.charAt(0)=='{')
|
154
|
+
{
|
155
|
+
message = eval('('+value+')');
|
156
|
+
}
|
157
|
+
else
|
158
|
+
{
|
159
|
+
message = {message:value};
|
160
|
+
}
|
161
|
+
hakano.util.MessageBroker.queue({type: type, data: message});
|
162
|
+
}
|
163
|
+
catch (e)
|
164
|
+
{
|
165
|
+
alert (e.stack);
|
166
|
+
}
|
167
|
+
</seamless:script>
|
168
|
+
|
169
|
+
</div>
|
170
|
+
</body>
|
171
|
+
</html>
|
@@ -0,0 +1,255 @@
|
|
1
|
+
var selectedRow = null;
|
2
|
+
var columns = null;
|
3
|
+
var primaryKeyColumn = 'id';
|
4
|
+
var rowData = null;
|
5
|
+
|
6
|
+
function deleteRow(data)
|
7
|
+
{
|
8
|
+
var table = $('table');
|
9
|
+
var tableName = table[table.selectedIndex].value;
|
10
|
+
hakano.util.MessageBroker.queue({type:'remote:seamless.'+tableName+'.delete.request',data:{id:getPrimaryKey(data)}});
|
11
|
+
selectedRow = null;
|
12
|
+
hakano.util.MessageBroker.queue({type:'local:search.table.nonselected',data:{}});
|
13
|
+
}
|
14
|
+
|
15
|
+
function updateFromDelete(data)
|
16
|
+
{
|
17
|
+
var id = data['id'];
|
18
|
+
$$('#search_results_table td.primarykey').each(function(td)
|
19
|
+
{
|
20
|
+
var value = td.innerHTML;
|
21
|
+
if (value == id)
|
22
|
+
{
|
23
|
+
var parent = td.parentNode;
|
24
|
+
Effect.Fade(parent,
|
25
|
+
{
|
26
|
+
afterFinish: function()
|
27
|
+
{
|
28
|
+
var p = parent.parentNode;
|
29
|
+
p.removeChild(parent);
|
30
|
+
$('search_count').innerHTML = parseInt($('search_count').innerHTML) - 1;
|
31
|
+
$('search_total').innerHTML = parseInt($('search_total').innerHTML) - 1;
|
32
|
+
}
|
33
|
+
});
|
34
|
+
throw $break;
|
35
|
+
}
|
36
|
+
});
|
37
|
+
}
|
38
|
+
|
39
|
+
function getPrimaryKey()
|
40
|
+
{
|
41
|
+
var idx = selectedRow.getAttribute('idx');
|
42
|
+
var datarow = rowData[parseInt(idx)];
|
43
|
+
return datarow[primaryKeyColumn||'id'] || '';
|
44
|
+
}
|
45
|
+
|
46
|
+
function loadModels (data)
|
47
|
+
{
|
48
|
+
var models = data['models'];
|
49
|
+
if (models.length > 0)
|
50
|
+
{
|
51
|
+
$('table_name').innerHTML = models[0].name;
|
52
|
+
loadTableAssembly(models[0].model);
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
function loadTableAssembly (tableName)
|
57
|
+
{
|
58
|
+
var request = 'remote:seamless.'+tableName+'.assembly.request';
|
59
|
+
hakano.util.MessageBroker.queue({type:request,data:{}});
|
60
|
+
}
|
61
|
+
|
62
|
+
function loadColumns (data)
|
63
|
+
{
|
64
|
+
columns = data['columns'];
|
65
|
+
refreshData();
|
66
|
+
}
|
67
|
+
|
68
|
+
function refreshData()
|
69
|
+
{
|
70
|
+
var table = $('table');
|
71
|
+
var tableName = table[table.selectedIndex].value;
|
72
|
+
hakano.util.MessageBroker.queue({type:'remote:seamless.'+tableName+'.list.request',data:{limit:10}});
|
73
|
+
}
|
74
|
+
|
75
|
+
function displayRecord(edit)
|
76
|
+
{
|
77
|
+
var html = '';
|
78
|
+
var table = $('table');
|
79
|
+
var tableName = table[table.selectedIndex].value;
|
80
|
+
|
81
|
+
if (edit)
|
82
|
+
{
|
83
|
+
var req = 'remote:seamless.' + tableName + '.update.request';
|
84
|
+
var resp = 'remote:seamless.' + tableName + '.update.response';
|
85
|
+
html+='<form onBindMessageDisable="'+req+'" onBindMessageEnable="'+resp+'">';
|
86
|
+
html+='<div style="display:none" class="editSuccess" onBindMessageEffect="'+resp+'" onBindMessageEffectCond="this.data.success" onBindMessageEffectType="Fade" onBindMessageEffectDelay="5000" onBindMessageShow="'+resp+'" onBindMessageShowCond="this.data.success"><img src="images/confirm.png"/> Record saved</div>';
|
87
|
+
html+='<div style="display:none" class="editFailed" onBindMessageHide="'+req+'" onBindMessageShow="'+resp+'" onBindMessageShowCond="!this.data.success"><img src="images/deny.png"/> <span onBindMessage="'+resp+'" onBindMessageCond="!this.data.success" onBindMessageProperty="message"/> </div>';
|
88
|
+
}
|
89
|
+
|
90
|
+
html += "<table class='record'>";
|
91
|
+
var idx = selectedRow.getAttribute('idx');
|
92
|
+
var datarow = rowData[parseInt(idx)];
|
93
|
+
|
94
|
+
var activators = (edit ? [] : null);
|
95
|
+
|
96
|
+
for (var c=0,len=columns.length;c<len;c++)
|
97
|
+
{
|
98
|
+
var name = columns[c].name;
|
99
|
+
if (edit)
|
100
|
+
{
|
101
|
+
switch (name)
|
102
|
+
{
|
103
|
+
case 'created_at':
|
104
|
+
case 'updated_at':
|
105
|
+
continue;
|
106
|
+
}
|
107
|
+
}
|
108
|
+
html+='<tr>';
|
109
|
+
if (!columns[c].primary)
|
110
|
+
{
|
111
|
+
html+='<td class="label '+(edit?'edit':'display')+'">'+name+'</td>';
|
112
|
+
}
|
113
|
+
else
|
114
|
+
{
|
115
|
+
html+='<td colspan="2"><input type="hidden" name="' + name + '" value="'+datarow[name]+'" fieldset="edit"/></td>';
|
116
|
+
continue;
|
117
|
+
}
|
118
|
+
|
119
|
+
var value = datarow[name];
|
120
|
+
if (!value || value == 'null') value = '';
|
121
|
+
|
122
|
+
if (edit)
|
123
|
+
{
|
124
|
+
html+='<td class="value edit">';
|
125
|
+
|
126
|
+
var type = 'text';
|
127
|
+
if (columns[c].type == 'boolean')
|
128
|
+
{
|
129
|
+
type = 'checkbox';
|
130
|
+
}
|
131
|
+
|
132
|
+
html+='<input fieldset="edit" type="' + type + '" name="' + name + '" id="' + name + '" value="'+value+'" ';
|
133
|
+
if (type=='checkbox' && (value=='true' || value==true))
|
134
|
+
{
|
135
|
+
html+='checked="true" ';
|
136
|
+
}
|
137
|
+
if (!columns[c].nullable)
|
138
|
+
{
|
139
|
+
activators.push(name);
|
140
|
+
|
141
|
+
html+="validator='";
|
142
|
+
html+=(name == 'password') ? "password" : "required";
|
143
|
+
html+="' decorator='";
|
144
|
+
html+=(name == 'password') ? "password" : "required";
|
145
|
+
html+="' ";
|
146
|
+
}
|
147
|
+
if (columns[c].limit)
|
148
|
+
{
|
149
|
+
html+="limit='" + (columns[c].limit || 100) + "' ";
|
150
|
+
}
|
151
|
+
html+=' /></td>';
|
152
|
+
}
|
153
|
+
else
|
154
|
+
{
|
155
|
+
html+='<td class="value display">'+value+'</td>';
|
156
|
+
}
|
157
|
+
html+='</tr>\n';
|
158
|
+
}
|
159
|
+
html+='</table>';
|
160
|
+
|
161
|
+
if (edit)
|
162
|
+
{
|
163
|
+
html+="<div id='save_button'><input fieldset='edit' type='button' value='Save' ";
|
164
|
+
if (activators.length > 0)
|
165
|
+
{
|
166
|
+
html+="activators='" + activators.join(',') + "' ";
|
167
|
+
}
|
168
|
+
html+=' onClickMessage="remote:seamless.' + tableName+'.update.request" ';
|
169
|
+
html+="/></div>";
|
170
|
+
|
171
|
+
html+="</form>";
|
172
|
+
}
|
173
|
+
|
174
|
+
$('search_results_table_container').innerHTML = html;
|
175
|
+
Seamless.wire($('search_results_table_container'),window,false,true);
|
176
|
+
}
|
177
|
+
|
178
|
+
function restoreTable ()
|
179
|
+
{
|
180
|
+
if (rowData)
|
181
|
+
{
|
182
|
+
loadTable({rows:rowData});
|
183
|
+
}
|
184
|
+
}
|
185
|
+
function loadTable (data)
|
186
|
+
{
|
187
|
+
try
|
188
|
+
{
|
189
|
+
var rows = data['rows'];
|
190
|
+
if (!rows) return;
|
191
|
+
var html = "<table id='search_results_table'>";
|
192
|
+
rowData = rows;
|
193
|
+
html+='<thead><tr>';
|
194
|
+
for (var c=0,len=columns.length;c<len;c++)
|
195
|
+
{
|
196
|
+
if (c < 6)
|
197
|
+
{
|
198
|
+
html+='<th>' + columns[c].name+ '</th>';
|
199
|
+
}
|
200
|
+
else
|
201
|
+
{
|
202
|
+
break;
|
203
|
+
}
|
204
|
+
}
|
205
|
+
html+='</tr></thead><tbody>';
|
206
|
+
for (var c=0,len=rows.length;c<len;c++)
|
207
|
+
{
|
208
|
+
html+='<tr idx="'+c+'">';
|
209
|
+
columns.each(function(col,idx)
|
210
|
+
{
|
211
|
+
var className = columns[idx].primary ? 'primarykey' : '';
|
212
|
+
html+='<td class="' + className + ' ' + ((c%2==0) ? 'even':'odd') + '">' + ( rows[c][col.name] || '') + '</td>';
|
213
|
+
if (idx >= 5) throw $break;
|
214
|
+
});
|
215
|
+
html+='</tr>';
|
216
|
+
}
|
217
|
+
html+='</tbody></table>';
|
218
|
+
$('search_results_table_container').innerHTML = html;
|
219
|
+
|
220
|
+
selectedRow = null;
|
221
|
+
|
222
|
+
$$('#search_results_table tr').each(function(cell)
|
223
|
+
{
|
224
|
+
cell.onclick = function(e)
|
225
|
+
{
|
226
|
+
var idx = cell.getAttribute('idx');
|
227
|
+
var datarow = rows[parseInt(idx)];
|
228
|
+
if (selectedRow)
|
229
|
+
{
|
230
|
+
$A(selectedRow.childNodes).each(function(n)
|
231
|
+
{
|
232
|
+
Element.removeClassName(n,'selected');
|
233
|
+
});
|
234
|
+
hakano.util.MessageBroker.queue({type:'local:search.table.unselected',data:{datarow:datarow}});
|
235
|
+
}
|
236
|
+
if (selectedRow == cell)
|
237
|
+
{
|
238
|
+
hakano.util.MessageBroker.queue({type:'local:search.table.nonselected',data:{}});
|
239
|
+
selectedRow = null;
|
240
|
+
return;
|
241
|
+
}
|
242
|
+
selectedRow = cell;
|
243
|
+
$A(selectedRow.childNodes).each(function(n)
|
244
|
+
{
|
245
|
+
Element.addClassName(n,'selected');
|
246
|
+
});
|
247
|
+
hakano.util.MessageBroker.queue({type:'local:search.table.selected',data:{datarow:datarow}});
|
248
|
+
};
|
249
|
+
});
|
250
|
+
}
|
251
|
+
catch(e)
|
252
|
+
{
|
253
|
+
alert(e);
|
254
|
+
}
|
255
|
+
}
|