jqgrid_rails 1.2.0

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