jqgrid_rails 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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