jqgrid_rails 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +5 -0
- data/LICENSE.rdoc +19 -0
- data/README.rdoc +62 -0
- data/examples/quick_ref.rdoc +83 -0
- data/examples/usage.rdoc +121 -0
- data/files/javascripts/jqgrid/README.md +1 -0
- data/files/javascripts/jqgrid/grid.locale-en.js +128 -0
- data/files/javascripts/jqgrid/jquery.jqGrid.min.js +510 -0
- data/files/stylesheets/jqgrid/ellipsis-xbl.xml +13 -0
- data/files/stylesheets/jqgrid/ui.jqgrid.css +136 -0
- data/init.rb +1 -0
- data/jqgrid_rails.gemspec +17 -0
- data/lib/jqgrid_rails.rb +20 -0
- data/lib/jqgrid_rails/escape_mappings.rb +23 -0
- data/lib/jqgrid_rails/jqgrid.rb +331 -0
- data/lib/jqgrid_rails/jqgrid_rails_controller.rb +286 -0
- data/lib/jqgrid_rails/jqgrid_rails_generators.rb +23 -0
- data/lib/jqgrid_rails/jqgrid_rails_helper.rb +12 -0
- data/lib/jqgrid_rails/jqgrid_rails_helpers.rb +250 -0
- data/lib/jqgrid_rails/jqgrid_rails_view.rb +71 -0
- data/lib/jqgrid_rails/jqgrid_rails_writeexcel.rb +45 -0
- data/lib/jqgrid_rails/jqgrid_url_generator.rb +9 -0
- data/lib/jqgrid_rails/railtie.rb +29 -0
- data/lib/jqgrid_rails/tasks.rb +21 -0
- data/lib/jqgrid_rails/version.rb +17 -0
- data/rails/init.rb +1 -0
- metadata +123 -0
@@ -0,0 +1,13 @@
|
|
1
|
+
<?xml version="1.0"?>
|
2
|
+
<bindings
|
3
|
+
xmlns="http://www.mozilla.org/xbl"
|
4
|
+
xmlns:xbl="http://www.mozilla.org/xbl"
|
5
|
+
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
6
|
+
<binding id="ellipsis">
|
7
|
+
<content>
|
8
|
+
<xul:window><!-- xul:window tag required for FF2 -->
|
9
|
+
<xul:description crop="end" xbl:inherits="value=xbl:text"><children/></xul:description>
|
10
|
+
</xul:window>
|
11
|
+
</content>
|
12
|
+
</binding>
|
13
|
+
</bindings>
|
@@ -0,0 +1,136 @@
|
|
1
|
+
/*Grid*/
|
2
|
+
.ui-jqgrid {position: relative; font-size:11px;}
|
3
|
+
.ui-jqgrid .ui-jqgrid-view {position: relative;left:0px; top: 0px; padding: .0em;}
|
4
|
+
/* caption*/
|
5
|
+
.ui-jqgrid .ui-jqgrid-titlebar {padding: .3em .2em .2em .3em; position: relative; border-left: 0px none;border-right: 0px none; border-top: 0px none;}
|
6
|
+
.ui-jqgrid .ui-jqgrid-title { float: left; margin: .1em 0 .2em; }
|
7
|
+
.ui-jqgrid .ui-jqgrid-titlebar-close { position: absolute;top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height:18px;}.ui-jqgrid .ui-jqgrid-titlebar-close span { display: block; margin: 1px; }
|
8
|
+
.ui-jqgrid .ui-jqgrid-titlebar-close:hover { padding: 0; }
|
9
|
+
/* header*/
|
10
|
+
.ui-jqgrid .ui-jqgrid-hdiv {position: relative; margin: 0em;padding: 0em; overflow-x: hidden; border-left: 0px none !important; border-top : 0px none !important; border-right : 0px none !important;}
|
11
|
+
.ui-jqgrid .ui-jqgrid-hbox {float: left; padding-right: 20px;}
|
12
|
+
.ui-jqgrid .ui-jqgrid-htable {table-layout:fixed;margin:0em;}
|
13
|
+
.ui-jqgrid .ui-jqgrid-htable th {height:22px;padding: 0 2px 0 2px;}
|
14
|
+
.ui-jqgrid .ui-jqgrid-htable th div {overflow: hidden; position:relative; height:17px;}
|
15
|
+
.ui-th-column, .ui-jqgrid .ui-jqgrid-htable th.ui-th-column {overflow: hidden;white-space: nowrap;text-align:center;border-top : 0px none;border-bottom : 0px none;}
|
16
|
+
.ui-th-ltr, .ui-jqgrid .ui-jqgrid-htable th.ui-th-ltr {border-left : 0px none;}
|
17
|
+
.ui-th-rtl, .ui-jqgrid .ui-jqgrid-htable th.ui-th-rtl {border-right : 0px none;}
|
18
|
+
.ui-first-th-ltr {border-right: 1px solid; }
|
19
|
+
.ui-first-th-rtl {border-left: 1px solid; }
|
20
|
+
.ui-jqgrid .ui-th-div-ie {white-space: nowrap; zoom :1; height:17px;}
|
21
|
+
.ui-jqgrid .ui-jqgrid-resize {height:20px !important;position: relative; cursor :e-resize;display: inline;overflow: hidden;}
|
22
|
+
.ui-jqgrid .ui-grid-ico-sort {overflow:hidden;position:absolute;display:inline; cursor: pointer !important;}
|
23
|
+
.ui-jqgrid .ui-icon-asc {margin-top:-3px; height:12px;}
|
24
|
+
.ui-jqgrid .ui-icon-desc {margin-top:3px;height:12px;}
|
25
|
+
.ui-jqgrid .ui-i-asc {margin-top:0px;height:16px;}
|
26
|
+
.ui-jqgrid .ui-i-desc {margin-top:0px;margin-left:13px;height:16px;}
|
27
|
+
.ui-jqgrid .ui-jqgrid-sortable {cursor:pointer;}
|
28
|
+
.ui-jqgrid tr.ui-search-toolbar th { border-top-width: 1px !important; border-top-color: inherit !important; border-top-style: ridge !important }
|
29
|
+
tr.ui-search-toolbar input {margin: 1px 0px 0px 0px}
|
30
|
+
tr.ui-search-toolbar select {margin: 1px 0px 0px 0px}
|
31
|
+
/* body */
|
32
|
+
.ui-jqgrid .ui-jqgrid-bdiv {position: relative; margin: 0em; padding:0; overflow: auto; text-align:left;}
|
33
|
+
.ui-jqgrid .ui-jqgrid-btable {table-layout:fixed; margin:0em; outline-style: none; }
|
34
|
+
.ui-jqgrid tr.jqgrow { outline-style: none; }
|
35
|
+
.ui-jqgrid tr.jqgroup { outline-style: none; }
|
36
|
+
.ui-jqgrid tr.jqgrow td {font-weight: normal; overflow: hidden; white-space: pre; height: 22px;padding: 0 2px 0 2px;border-bottom-width: 1px; border-bottom-color: inherit; border-bottom-style: solid;}
|
37
|
+
.ui-jqgrid tr.jqgfirstrow td {padding: 0 2px 0 2px;border-right-width: 1px; border-right-style: solid;}
|
38
|
+
.ui-jqgrid tr.jqgroup td {font-weight: normal; overflow: hidden; white-space: pre; height: 22px;padding: 0 2px 0 2px;border-bottom-width: 1px; border-bottom-color: inherit; border-bottom-style: solid;}
|
39
|
+
.ui-jqgrid tr.jqfoot td {font-weight: bold; overflow: hidden; white-space: pre; height: 22px;padding: 0 2px 0 2px;border-bottom-width: 1px; border-bottom-color: inherit; border-bottom-style: solid;}
|
40
|
+
.ui-jqgrid tr.ui-row-ltr td {text-align:left;border-right-width: 1px; border-right-color: inherit; border-right-style: solid;}
|
41
|
+
.ui-jqgrid tr.ui-row-rtl td {text-align:right;border-left-width: 1px; border-left-color: inherit; border-left-style: solid;}
|
42
|
+
.ui-jqgrid td.jqgrid-rownum { padding: 0 2px 0 2px; margin: 0px; border: 0px none;}
|
43
|
+
.ui-jqgrid .ui-jqgrid-resize-mark { width:2px; left:0; background-color:#777; cursor: e-resize; cursor: col-resize; position:absolute; top:0; height:100px; overflow:hidden; display:none; border:0 none;}
|
44
|
+
/* footer */
|
45
|
+
.ui-jqgrid .ui-jqgrid-sdiv {position: relative; margin: 0em;padding: 0em; overflow: hidden; border-left: 0px none !important; border-top : 0px none !important; border-right : 0px none !important;}
|
46
|
+
.ui-jqgrid .ui-jqgrid-ftable {table-layout:fixed; margin-bottom:0em;}
|
47
|
+
.ui-jqgrid tr.footrow td {font-weight: bold; overflow: hidden; white-space:nowrap; height: 21px;padding: 0 2px 0 2px;border-top-width: 1px; border-top-color: inherit; border-top-style: solid;}
|
48
|
+
.ui-jqgrid tr.footrow-ltr td {text-align:left;border-right-width: 1px; border-right-color: inherit; border-right-style: solid;}
|
49
|
+
.ui-jqgrid tr.footrow-rtl td {text-align:right;border-left-width: 1px; border-left-color: inherit; border-left-style: solid;}
|
50
|
+
/* Pager*/
|
51
|
+
.ui-jqgrid .ui-jqgrid-pager { border-left: 0px none !important;border-right: 0px none !important; border-bottom: 0px none !important; margin: 0px !important; padding: 0px !important; position: relative; height: 25px;white-space: nowrap;overflow: hidden;}
|
52
|
+
.ui-jqgrid .ui-pager-control {position: relative;}
|
53
|
+
.ui-jqgrid .ui-pg-table {position: relative; padding-bottom:2px; width:auto; margin: 0em;}
|
54
|
+
.ui-jqgrid .ui-pg-table td {font-weight:normal; vertical-align:middle; padding:1px;}
|
55
|
+
.ui-jqgrid .ui-pg-button { height:19px !important;}
|
56
|
+
.ui-jqgrid .ui-pg-button span { display: block; margin: 1px; float:left;}
|
57
|
+
.ui-jqgrid .ui-pg-button:hover { padding: 0px; }
|
58
|
+
.ui-jqgrid .ui-state-disabled:hover {padding:1px;}
|
59
|
+
.ui-jqgrid .ui-pg-input { height:13px;font-size:.8em; margin: 0em;}
|
60
|
+
.ui-jqgrid .ui-pg-selbox {font-size:.8em; line-height:18px; display:block; height:18px; margin: 0em;}
|
61
|
+
.ui-jqgrid .ui-separator {height: 18px; border-left: 1px solid #ccc ; border-right: 1px solid #ccc ; margin: 1px; float: right;}
|
62
|
+
.ui-jqgrid .ui-paging-info {font-weight: normal;height:19px; margin-top:3px;margin-right:4px;}
|
63
|
+
.ui-jqgrid .ui-jqgrid-pager .ui-pg-div {padding:1px 0;float:left;list-style-image:none;list-style-position:outside;list-style-type:none;position:relative;}
|
64
|
+
.ui-jqgrid .ui-jqgrid-pager .ui-pg-button { cursor:pointer; }
|
65
|
+
.ui-jqgrid .ui-jqgrid-pager .ui-pg-div span.ui-icon {float:left;margin:0 2px;}
|
66
|
+
.ui-jqgrid td input, .ui-jqgrid td select .ui-jqgrid td textarea { margin: 0em;}
|
67
|
+
.ui-jqgrid td textarea {width:auto;height:auto;}
|
68
|
+
.ui-jqgrid .ui-jqgrid-toppager {border-left: 0px none !important;border-right: 0px none !important; border-top: 0px none !important; margin: 0px !important; padding: 0px !important; position: relative; height: 25px !important;white-space: nowrap;overflow: hidden;}
|
69
|
+
/*subgrid*/
|
70
|
+
.ui-jqgrid .ui-jqgrid-btable .ui-sgcollapsed span {display: block;}
|
71
|
+
.ui-jqgrid .ui-subgrid {margin:0em;padding:0em; width:100%;}
|
72
|
+
.ui-jqgrid .ui-subgrid table {table-layout: fixed;}
|
73
|
+
.ui-jqgrid .ui-subgrid tr.ui-subtblcell td {height:18px;border-right-width: 1px; border-right-color: inherit; border-right-style: solid;border-bottom-width: 1px; border-bottom-color: inherit; border-bottom-style: solid;}
|
74
|
+
.ui-jqgrid .ui-subgrid td.subgrid-data {border-top: 0px none !important;}
|
75
|
+
.ui-jqgrid .ui-subgrid td.subgrid-cell {border-width: 0px 0px 1px 0px;}
|
76
|
+
.ui-jqgrid .ui-th-subgrid {height:20px;}
|
77
|
+
/* loading */
|
78
|
+
.ui-jqgrid .loading {position: absolute; top: 45%;left: 45%;width: auto;z-index:101;padding: 6px; margin: 5px;text-align: center;font-weight: bold;display: none;border-width: 2px !important;}
|
79
|
+
.ui-jqgrid .jqgrid-overlay {display:none;z-index:100;}
|
80
|
+
* html .jqgrid-overlay {width: expression(this.parentNode.offsetWidth+'px');height: expression(this.parentNode.offsetHeight+'px');}
|
81
|
+
* .jqgrid-overlay iframe {position:absolute;top:0;left:0;z-index:-1;width: expression(this.parentNode.offsetWidth+'px');height: expression(this.parentNode.offsetHeight+'px');}
|
82
|
+
/* end loading div */
|
83
|
+
/* toolbar */
|
84
|
+
.ui-jqgrid .ui-userdata {border-left: 0px none; border-right: 0px none; height : 21px;overflow: hidden; }
|
85
|
+
/*Modal Window */
|
86
|
+
.ui-jqdialog { display: none; width: 300px; position: absolute; padding: .2em; font-size:11px; overflow:visible;}
|
87
|
+
.ui-jqdialog .ui-jqdialog-titlebar { padding: .3em .2em; position: relative; }
|
88
|
+
.ui-jqdialog .ui-jqdialog-title { margin: .1em 0 .2em; }
|
89
|
+
.ui-jqdialog .ui-jqdialog-titlebar-close { position: absolute; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
|
90
|
+
|
91
|
+
.ui-jqdialog .ui-jqdialog-titlebar-close span { display: block; margin: 1px; }
|
92
|
+
.ui-jqdialog .ui-jqdialog-titlebar-close:hover, .ui-jqdialog .ui-jqdialog-titlebar-close:focus { padding: 0; }
|
93
|
+
.ui-jqdialog-content, .ui-jqdialog .ui-jqdialog-content { border: 0; padding: .3em .2em; background: none; height:auto;}
|
94
|
+
.ui-jqdialog .ui-jqconfirm {padding: .4em 1em; border-width:3px;position:absolute;bottom:10px;right:10px;overflow:visible;display:none;height:80px;width:220px;text-align:center;}
|
95
|
+
/* end Modal window*/
|
96
|
+
/* Form edit */
|
97
|
+
.ui-jqdialog-content .FormGrid {margin: 0px;}
|
98
|
+
.ui-jqdialog-content .EditTable { width: 100%; margin-bottom:0em;}
|
99
|
+
.ui-jqdialog-content .DelTable { width: 100%; margin-bottom:0em;}
|
100
|
+
.EditTable td input, .EditTable td select, .EditTable td textarea {margin: 0em;}
|
101
|
+
.EditTable td textarea { width:auto; height:auto;}
|
102
|
+
.ui-jqdialog-content td.EditButton {text-align: right;border-top: 0px none;border-left: 0px none;border-right: 0px none; padding-bottom:5px; padding-top:5px;}
|
103
|
+
.ui-jqdialog-content td.navButton {text-align: center; border-left: 0px none;border-top: 0px none;border-right: 0px none; padding-bottom:5px; padding-top:5px;}
|
104
|
+
.ui-jqdialog-content input.FormElement {padding:.3em}
|
105
|
+
.ui-jqdialog-content .data-line {padding-top:.1em;border: 0px none;}
|
106
|
+
|
107
|
+
.ui-jqdialog-content .CaptionTD {text-align: left; vertical-align: middle;border: 0px none; padding: 2px;white-space: nowrap;}
|
108
|
+
.ui-jqdialog-content .DataTD {padding: 2px; border: 0px none; vertical-align: top;}
|
109
|
+
.ui-jqdialog-content .form-view-data {white-space:pre}
|
110
|
+
.fm-button { display: inline-block; margin:0 4px 0 0; padding: .4em .5em; text-decoration:none !important; cursor:pointer; position: relative; text-align: center; zoom: 1; }
|
111
|
+
.fm-button-icon-left { padding-left: 1.9em; }
|
112
|
+
.fm-button-icon-right { padding-right: 1.9em; }
|
113
|
+
.fm-button-icon-left .ui-icon { right: auto; left: .2em; margin-left: 0; position: absolute; top: 50%; margin-top: -8px; }
|
114
|
+
.fm-button-icon-right .ui-icon { left: auto; right: .2em; margin-left: 0; position: absolute; top: 50%; margin-top: -8px;}
|
115
|
+
#nData, #pData { float: left; margin:3px;padding: 0; width: 15px; }
|
116
|
+
/* End Eorm edit */
|
117
|
+
/*.ui-jqgrid .edit-cell {}*/
|
118
|
+
.ui-jqgrid .selected-row, div.ui-jqgrid .selected-row td {font-style : normal;border-left: 0px none;}
|
119
|
+
/* Tree Grid */
|
120
|
+
.ui-jqgrid .tree-wrap {float: left; position: relative;height: 18px;white-space: nowrap;overflow: hidden;}
|
121
|
+
.ui-jqgrid .tree-minus {position: absolute; height: 18px; width: 18px; overflow: hidden;}
|
122
|
+
.ui-jqgrid .tree-plus {position: absolute; height: 18px; width: 18px; overflow: hidden;}
|
123
|
+
.ui-jqgrid .tree-leaf {position: absolute; height: 18px; width: 18px;overflow: hidden;}
|
124
|
+
.ui-jqgrid .treeclick {cursor: pointer;}
|
125
|
+
/* moda dialog */
|
126
|
+
* iframe.jqm {position:absolute;top:0;left:0;z-index:-1;width: expression(this.parentNode.offsetWidth+'px');height: expression(this.parentNode.offsetHeight+'px');}
|
127
|
+
.ui-jqgrid-dnd tr td {border-right-width: 1px; border-right-color: inherit; border-right-style: solid; height:20px}
|
128
|
+
/* RTL Support */
|
129
|
+
.ui-jqgrid .ui-jqgrid-title-rtl {float:right;margin: .1em 0 .2em; }
|
130
|
+
.ui-jqgrid .ui-jqgrid-hbox-rtl {float: right; padding-left: 20px;}
|
131
|
+
.ui-jqgrid .ui-jqgrid-resize-ltr {float: right;margin: -2px -2px -2px 0px;}
|
132
|
+
.ui-jqgrid .ui-jqgrid-resize-rtl {float: left;margin: -2px 0px -1px -3px;}
|
133
|
+
.ui-jqgrid .ui-sort-rtl {left:0px;}
|
134
|
+
.ui-jqgrid .tree-wrap-ltr {float: left;}
|
135
|
+
.ui-jqgrid .tree-wrap-rtl {float: right;}
|
136
|
+
.ui-jqgrid .ui-ellipsis {text-overflow:ellipsis; -moz-binding:url('ellipsis-xbl.xml#ellipsis');}
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'jqgrid_rails'
|
@@ -0,0 +1,17 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__)) + '/lib/'
|
2
|
+
require 'jqgrid_rails/version'
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = 'jqgrid_rails'
|
5
|
+
s.version = JqGridRails::VERSION
|
6
|
+
s.summary = 'jqGrid for Rails'
|
7
|
+
s.author = 'Chris Roberts'
|
8
|
+
s.email = 'chrisroberts.code@gmail.com'
|
9
|
+
s.homepage = 'http://github.com/chrisroberts/jqgrid_rails'
|
10
|
+
s.description = 'jqGrid for Rails'
|
11
|
+
s.require_path = 'lib'
|
12
|
+
s.has_rdoc = true
|
13
|
+
s.extra_rdoc_files = ['README.rdoc', 'LICENSE.rdoc', 'CHANGELOG.rdoc']
|
14
|
+
s.add_dependency 'rails_javascript_helpers', '~> 1.4'
|
15
|
+
s.add_dependency 'rails', '>= 2.3'
|
16
|
+
s.files = Dir.glob("**/*")
|
17
|
+
end
|
data/lib/jqgrid_rails.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'jqgrid_rails/version'
|
2
|
+
require 'jqgrid_rails/escape_mappings'
|
3
|
+
|
4
|
+
if(defined?(Rails))
|
5
|
+
if(defined?(Rails::Railtie))
|
6
|
+
require 'jqgrid_rails/railtie'
|
7
|
+
else
|
8
|
+
ActionView::Helpers::AssetTagHelper.register_javascript_expansion(
|
9
|
+
:jqgrid_rails => %w(/jqgrid_rails/javascripts/jqgrid/grid.locale-en.js /jqgrid_rails/javascripts/jqgrid/jquery.jqGrid.min.js)
|
10
|
+
)
|
11
|
+
ActionView::Helpers::AssetTagHelper.register_stylesheet_expansion(
|
12
|
+
:jqgrid_rails => %w(/jqgrid_rails/stylesheets/jqgrid/ui.jqgrid.css)
|
13
|
+
)
|
14
|
+
Dir.glob(File.join(File.dirname(__FILE__), 'jqgrid_rails', '*.rb')).each do |file|
|
15
|
+
unless(%w(railtie.rb tasks.rb version.rb).find{|skip| file.ends_with?(skip)})
|
16
|
+
require file
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module JqGridRails
|
2
|
+
ESCAPES = {
|
3
|
+
'.' => '___'
|
4
|
+
}
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def escape(string)
|
8
|
+
string = string.to_s.dup
|
9
|
+
ESCAPES.each_pair do |orig,mapping|
|
10
|
+
string.gsub!(orig,mapping)
|
11
|
+
end
|
12
|
+
string
|
13
|
+
end
|
14
|
+
|
15
|
+
def unescape(string)
|
16
|
+
string = string.to_s.dup
|
17
|
+
ESCAPES.each_pair do |orig,mapping|
|
18
|
+
string.gsub!(mapping,orig)
|
19
|
+
end
|
20
|
+
string
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,331 @@
|
|
1
|
+
require 'jqgrid_rails/jqgrid_url_generator'
|
2
|
+
require 'jqgrid_rails/jqgrid_rails_helpers'
|
3
|
+
module JqGridRails
|
4
|
+
class JqGrid
|
5
|
+
|
6
|
+
include ActionView::Helpers::UrlHelper
|
7
|
+
include ActionView::Helpers::JavaScriptHelper
|
8
|
+
include ActionView::Helpers::UrlHelper
|
9
|
+
include JqGridRails::Helpers
|
10
|
+
|
11
|
+
# Options used to build tables
|
12
|
+
attr_accessor :options
|
13
|
+
# Array of local data rows
|
14
|
+
attr_accessor :local
|
15
|
+
# table DOM ID
|
16
|
+
attr_accessor :table_id
|
17
|
+
# Options used for links toolbar
|
18
|
+
attr_reader :link_toolbar_options
|
19
|
+
|
20
|
+
|
21
|
+
# table_id:: DOM ID of table for grid to use
|
22
|
+
# args:: Hash of {jqGrid options}[http://www.trirand.com/jqgridwiki/doku.php?id=wiki:options]
|
23
|
+
def initialize(table_id, args={})
|
24
|
+
defaults = {
|
25
|
+
:datatype => :json,
|
26
|
+
:col_names => [],
|
27
|
+
:col_model => [],
|
28
|
+
:viewrecords => true,
|
29
|
+
:json_reader => {
|
30
|
+
:root => 'rows',
|
31
|
+
:page => 'page',
|
32
|
+
:total => 'total',
|
33
|
+
:records => 'records',
|
34
|
+
:id => args.delete(:row_id) || 0,
|
35
|
+
:repeatitems => false,
|
36
|
+
}
|
37
|
+
}
|
38
|
+
if(args[:url].blank? && args[:datatype].to_s != 'local')
|
39
|
+
raise ArgumentError.new 'URL is required unless :datatype is set to local'
|
40
|
+
end
|
41
|
+
@table_id = table_id.is_a?(String) ? table_id.gsub('#', '') : table_id
|
42
|
+
@options = defaults.merge(args)
|
43
|
+
@pager_options = {:edit => false, :add => false, :del => false}
|
44
|
+
if(t_args = @options.delete(:filter_toolbar))
|
45
|
+
enable_filter_toolbar(t_args.is_a?(Hash) ? t_args : nil)
|
46
|
+
end
|
47
|
+
if(t_args = options.delete(:link_toolbar))
|
48
|
+
enable_link_toolbar(t_args.is_a?(Hash) ? t_args : nil)
|
49
|
+
end
|
50
|
+
@local = []
|
51
|
+
@output = ''
|
52
|
+
end
|
53
|
+
|
54
|
+
# name:: Name of column (Invoice)
|
55
|
+
# attr:: Attribute of model (invoice_num)
|
56
|
+
# args:: Hash of {colModel options}[http://www.trirand.com/jqgridwiki/doku.php?id=wiki:colmodel_options]
|
57
|
+
def add_column(name, attr, args={})
|
58
|
+
col = {:name => attr, :index => attr}.merge(args)
|
59
|
+
map = col.delete(:map_values)
|
60
|
+
col[:index] = JqGridRails.escape(col[:index]) unless @options[:no_index_escaping]
|
61
|
+
col[:formatter] = add_value_mapper(map) if map
|
62
|
+
@options[:col_names].push name
|
63
|
+
@options[:col_model].push col
|
64
|
+
self
|
65
|
+
end
|
66
|
+
|
67
|
+
# ary:: Array of Hashes (rows in table)
|
68
|
+
# Sets data to be loaded into table
|
69
|
+
def set_local_data(ary)
|
70
|
+
if(ary.is_a?(Array))
|
71
|
+
@local = ary
|
72
|
+
else
|
73
|
+
raise TypeError.new "Expecting Array value. Received: #{ary.class}"
|
74
|
+
end
|
75
|
+
self
|
76
|
+
end
|
77
|
+
|
78
|
+
# hsh:: Hash of row data for loading into table
|
79
|
+
# Adds new row of data to be loaded into table
|
80
|
+
def add_local_data(hsh)
|
81
|
+
if(hsh.is_a?(Hash))
|
82
|
+
@local.push hsh
|
83
|
+
else
|
84
|
+
raise TypeError.new "Expecting Hash value. Received: #{ary.class}"
|
85
|
+
end
|
86
|
+
self
|
87
|
+
end
|
88
|
+
|
89
|
+
# options:: Options hash for the filter toolbar
|
90
|
+
# Enables the filter toolbar for the grid
|
91
|
+
def enable_filter_toolbar(options={})
|
92
|
+
options = {} unless options.is_a?(Hash)
|
93
|
+
@filter_toolbar_options = {
|
94
|
+
:string_result => true,
|
95
|
+
:search_on_enter => true
|
96
|
+
}.merge(options)
|
97
|
+
self
|
98
|
+
end
|
99
|
+
|
100
|
+
# options:: Options for toolbar
|
101
|
+
# Enables the link toolbar for the grid
|
102
|
+
def enable_link_toolbar(options={})
|
103
|
+
options = {} unless options.is_a?(Hash)
|
104
|
+
@link_toolbar_options = {
|
105
|
+
:top => true,
|
106
|
+
:bottom => false,
|
107
|
+
:links => []
|
108
|
+
}.merge(options)
|
109
|
+
@options[:toolbar] = [true, 'top']
|
110
|
+
self
|
111
|
+
end
|
112
|
+
|
113
|
+
def disable_filter_toolbar
|
114
|
+
@filter_toolbar_options = nil
|
115
|
+
self
|
116
|
+
end
|
117
|
+
|
118
|
+
def disable_link_toolbar
|
119
|
+
@link_toolbar_options = nil
|
120
|
+
self
|
121
|
+
end
|
122
|
+
|
123
|
+
# link:: url hash: :name, :url, :class
|
124
|
+
# Enables link on link toolbar
|
125
|
+
def link_toolbar_add(link)
|
126
|
+
enable_link_toolbar unless has_link_toolbar?
|
127
|
+
@link_toolbar_options[:links].push(link)
|
128
|
+
self
|
129
|
+
end
|
130
|
+
alias_method :add_toolbar_link, :link_toolbar_add
|
131
|
+
|
132
|
+
# name:: text for button
|
133
|
+
# Exports current grid into excel document
|
134
|
+
# TODO: Add options to turn off paging and the like
|
135
|
+
def add_excel_export_button(name='Export to XLS')
|
136
|
+
name = 'Export to XLS' unless name.is_a?(String)
|
137
|
+
link_toolbar_add(
|
138
|
+
:name => name,
|
139
|
+
:empty_selection => true,
|
140
|
+
:method => :post,
|
141
|
+
:url => RawJS.new("' + jQuery(#{convert_dom_id(@table_id)}).jqGrid('getGridParam', 'url') + '"),
|
142
|
+
:ajax_args => {
|
143
|
+
:data => RawJS.new("(function(){
|
144
|
+
vals = jQuery(#{convert_dom_id(@table_id)}).jqGrid('getGridParam', 'postData');
|
145
|
+
res = {};
|
146
|
+
Object.keys(vals).each(function(key){
|
147
|
+
res[key] = vals[key];
|
148
|
+
});
|
149
|
+
res['rows'] = 10000000;
|
150
|
+
res['page'] = 1;
|
151
|
+
res['format'] = 'xls';
|
152
|
+
return res;
|
153
|
+
})()")
|
154
|
+
}
|
155
|
+
)
|
156
|
+
self
|
157
|
+
end
|
158
|
+
|
159
|
+
# Resizes grid after loading has completed to prevent blowing out container
|
160
|
+
def fix_grid_width
|
161
|
+
js = "jQuery(#{convert_dom_id(@table_id)}).jqGrid('setGridWidth', jQuery(#{convert_dom_id(@table_id)} + '_holder').innerWidth(), true);"
|
162
|
+
if(@options[:load_complete])
|
163
|
+
@options[:load_complete] = RawJS.new(@options[:load_complete].to_s.sub(/^(\s*function.*?\{)/, "\\1#{js}"))
|
164
|
+
else
|
165
|
+
@options[:load_complete] = RawJS.new("function(){ #{js} return true; }")
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
# Builds out the jqGrid javascript and returns the string
|
170
|
+
def build
|
171
|
+
output = ''
|
172
|
+
fix_grid_width
|
173
|
+
@options[:datatype] = 'local' unless @local.blank?
|
174
|
+
resizable = @options.delete(:resizable_grid)
|
175
|
+
#############################################################
|
176
|
+
load_multi_select_fix unless @options[:no_multi_select_fix] # TODO: Remove this when fixed in jqGrid
|
177
|
+
#############################################################
|
178
|
+
map_double_click
|
179
|
+
map_single_click
|
180
|
+
set_search_options
|
181
|
+
@options = scrub_options_hash(@options)
|
182
|
+
sortable_rows = @options.delete(:sortable_rows)
|
183
|
+
has_pager? # convert if required
|
184
|
+
if(@options[:excel_exportable])
|
185
|
+
add_excel_export_button(@options.delete(:excel_exportable))
|
186
|
+
end
|
187
|
+
output << "jQuery(#{convert_dom_id(@table_id)}).jqGrid(#{format_type_to_js(@options)});\n"
|
188
|
+
unless(@local.blank?)
|
189
|
+
output << "if(typeof(jqgrid_local_data) == 'undefined'){ var jqgrid_local_data = new Hash(); }\n"
|
190
|
+
output << "jqgrid_local_data.set(#{convert_dom_id(@table_id)}, #{format_type_to_js(@local)});\n"
|
191
|
+
output << "for(var i = 0; i < jqgrid_local_data.get(#{convert_dom_id(@table_id)}).length; i++){ jQuery(#{convert_dom_id(@table_id)}).jqGrid('addRowData', i+1, jqgrid_local_data.get(#{convert_dom_id(@table_id)})[i]); }\n"
|
192
|
+
end
|
193
|
+
if(has_pager?)
|
194
|
+
output << "jQuery(#{convert_dom_id(@table_id)}).jqGrid('navGrid', #{format_type_to_js(@options[:pager])}, #{format_type_to_js(@pager_options)});"
|
195
|
+
end
|
196
|
+
if(has_filter_toolbar?)
|
197
|
+
output << "jQuery(#{convert_dom_id(@table_id)}).jqGrid('filterToolbar', #{format_type_to_js(@filter_toolbar_options)});\n"
|
198
|
+
end
|
199
|
+
if(has_link_toolbar?)
|
200
|
+
@link_toolbar_options[:links].each do |url_hash|
|
201
|
+
output << create_toolbar_button(url_hash)
|
202
|
+
end
|
203
|
+
output << "jQuery(#{convert_dom_id(@table_id)}).jqGrid('navGrid', #{convert_dom_id(@table_id)} + '_linkbar', {edit:false,add:false,del:false});\n"
|
204
|
+
end
|
205
|
+
if(sortable_rows)
|
206
|
+
output << enable_sortable_rows(scrub_options_hash(sortable_rows))
|
207
|
+
end
|
208
|
+
unless(resizable == false)
|
209
|
+
if(resizable.respond_to?(:[]))
|
210
|
+
output << resizable_grid(resizable)
|
211
|
+
else
|
212
|
+
output << resizable_grid
|
213
|
+
end
|
214
|
+
end
|
215
|
+
"#{@output}\n#{output}"
|
216
|
+
end
|
217
|
+
alias_method :to_s, :build
|
218
|
+
|
219
|
+
# Returns if the grid has a filter toolbar enabled
|
220
|
+
def has_filter_toolbar?
|
221
|
+
!@filter_toolbar_options.blank?
|
222
|
+
end
|
223
|
+
|
224
|
+
# Returns if the grid has a pager enabled
|
225
|
+
def has_pager?
|
226
|
+
@options[:pager] = RawJS.new("#{convert_dom_id(@table_id)} + '_pager'") if @options[:pager] == true
|
227
|
+
@options.has_key?(:pager)
|
228
|
+
end
|
229
|
+
|
230
|
+
# Returns if the grid has a link toolbar enabled
|
231
|
+
def has_link_toolbar?
|
232
|
+
!@link_toolbar_options.blank? && !@link_toolbar_options[:links].empty?
|
233
|
+
end
|
234
|
+
|
235
|
+
# map:: Hash of key value mapping
|
236
|
+
# Creates a client side value mapper using a randomized function name
|
237
|
+
def add_value_mapper(map)
|
238
|
+
function_name = "map_#{Digest::SHA1.hexdigest(Time.now.to_f.to_s)}"
|
239
|
+
@output << "jQuery.extend(jQuery.fn.fmatter, {
|
240
|
+
#{function_name} : function(cellvalue, options, rowdata){
|
241
|
+
keys = #{format_type_to_js(map.keys)}
|
242
|
+
values = #{format_type_to_js(map.values)}
|
243
|
+
return values[jQuery.inArray(cellvalue, keys)];
|
244
|
+
}
|
245
|
+
});"
|
246
|
+
function_name
|
247
|
+
end
|
248
|
+
|
249
|
+
# Creates function callback for row double clicks
|
250
|
+
def map_double_click
|
251
|
+
map_click(:ondbl_click_row, options) if options[:ondbl_click_row]
|
252
|
+
end
|
253
|
+
|
254
|
+
# Creates function callback from row single clicks
|
255
|
+
def map_single_click
|
256
|
+
map_click(:on_cell_select, options) if options[:on_cell_select]
|
257
|
+
map_click(:on_select_row, options) if options[:on_select_row]
|
258
|
+
end
|
259
|
+
|
260
|
+
# Syncs up filter toolbar values with advanced search values if the
|
261
|
+
# advanced search values have not already been provided
|
262
|
+
def set_search_options
|
263
|
+
if(@options[:col_model])
|
264
|
+
@options[:col_model].each do |column|
|
265
|
+
if(column[:editoptions] && column[:editoptions][:value])
|
266
|
+
column[:searchoptions] ||= {}
|
267
|
+
unless(column[:searchoptions].has_key?(:value))
|
268
|
+
column[:searchoptions][:value] = column[:editoptions][:value]
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
# url_hash:: Hash of url options. Use :method to specify request method other than 'get'
|
276
|
+
# Creates a toolbar button on the grid
|
277
|
+
def create_toolbar_button(url_hash)
|
278
|
+
build_toolbar_button(url_hash)
|
279
|
+
end
|
280
|
+
|
281
|
+
# sortable_rows:: options hash
|
282
|
+
# Enables row sorting on grid
|
283
|
+
# TODO: Add helpers to build remote callbacks in the
|
284
|
+
# same format as the click events and toolbar links
|
285
|
+
def enable_sortable_rows(sortable_rows)
|
286
|
+
sortable_rows = {} unless sortable_rows.is_a?(Hash)
|
287
|
+
"jQuery(#{convert_dom_id(@table_id)}).sortableRows(#{format_type_to_js(sortable_rows)});\n"
|
288
|
+
end
|
289
|
+
|
290
|
+
# This is a fix for the multi select within jqGrid. Rouge values will
|
291
|
+
# appear in the selection listing so this cleans things up properly
|
292
|
+
def load_multi_select_fix
|
293
|
+
@options[:on_select_all] = "function(row_ids, status){
|
294
|
+
var grid = jQuery(this);
|
295
|
+
grid.jqGrid('resetSelection');
|
296
|
+
if(status){
|
297
|
+
jQuery.each(grid.jqGrid('getRowData'), function(){
|
298
|
+
grid.jqGrid(
|
299
|
+
'setSelection',
|
300
|
+
this['id']
|
301
|
+
);
|
302
|
+
});
|
303
|
+
}
|
304
|
+
jQuery('#cb_' + #{convert_dom_id(@table_id)}.replace(/^#/, '')).attr('checked', status);
|
305
|
+
}"
|
306
|
+
end
|
307
|
+
|
308
|
+
# pad:: Padding after resize
|
309
|
+
# Binds to resizestop event on available parent that has been marked resizable
|
310
|
+
# via jqquery-ui. Resizes grid after container is resized
|
311
|
+
def resizable_grid(opts = {})
|
312
|
+
"var _resizable_parent = jQuery(#{convert_dom_id(@table_id)}).parents('.ui-resizable');
|
313
|
+
_resizable_parent.bind('resizestop', function(){
|
314
|
+
var width = _resizable_parent.attr('clientWidth');
|
315
|
+
if(width == null || width < 1){
|
316
|
+
width = _resizable_parent.attr('offsetWidth');
|
317
|
+
}
|
318
|
+
if(width > 0 && ((Math.abs(width) - jQuery(#{convert_dom_id(@table_id)}).width() > 5) || (Math.abs(width) - jQuery(#{convert_dom_id(@table_id)}).width() < -5))){
|
319
|
+
jQuery(#{convert_dom_id(@table_id)}).setGridWidth(width - #{(opts[:width_pad] || 40).to_i});
|
320
|
+
}
|
321
|
+
var height = _resizable_parent.attr('clientHeight');
|
322
|
+
if(height == null || height < 1){
|
323
|
+
height = _resizable_parent.attr('offsetHeight');
|
324
|
+
}
|
325
|
+
if(height > 0 && ((Math.abs(height) - jQuery(#{convert_dom_id(@table_id)}).height() > 5) || (Math.abs(height) - jQuery(#{convert_dom_id(@table_id)}).height() < -5))){
|
326
|
+
jQuery(#{convert_dom_id(@table_id)}).setGridHeight(height - #{(opts[:height_pad] || 40).to_i});
|
327
|
+
}
|
328
|
+
}).trigger('resize');"
|
329
|
+
end
|
330
|
+
end
|
331
|
+
end
|