widget_list 1.0.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.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +260 -0
- data/Rakefile +1 -0
- data/lib/widget_list.rb +2054 -0
- data/lib/widget_list/md5.rb +19 -0
- data/lib/widget_list/version.rb +3 -0
- data/widget_list.gemspec +20 -0
- metadata +70 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 TODO: Write your name
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,260 @@
|
|
1
|
+
widget_list
|
2
|
+
====================
|
3
|
+
# WidgetList
|
4
|
+
|
5
|
+
## Introduction
|
6
|
+
|
7
|
+
This is my first gem ever!
|
8
|
+
|
9
|
+
I feel like there are not very good lists in ruby/rails and/or dont care to find any because nothing will compare to widget_list's implementation.
|
10
|
+
|
11
|
+
In rails you have will_paginate and other ones like it using the ActiveRecord approach, but widget_list adds some awesome treats to standard boring pagers:
|
12
|
+
|
13
|
+
* A sleek ajaxified list
|
14
|
+
* Full sorting
|
15
|
+
* Search bar/Ajax searching
|
16
|
+
* Column mappings
|
17
|
+
* Buttons for each row and areas on the bottom of the grid where you can add "Action buttons" like Add R
|
18
|
+
|
19
|
+
|
20
|
+
## Installation
|
21
|
+
|
22
|
+
Add this line to your application's Gemfile:
|
23
|
+
|
24
|
+
gem 'widget_list'
|
25
|
+
|
26
|
+
And then execute:
|
27
|
+
|
28
|
+
$ bundle
|
29
|
+
|
30
|
+
Or install it yourself as:
|
31
|
+
|
32
|
+
$ gem install widget_list
|
33
|
+
|
34
|
+
## Usage
|
35
|
+
|
36
|
+
### #1 - Add widget_list CSS and JS to your application css and js
|
37
|
+
|
38
|
+
Change application.css to:
|
39
|
+
|
40
|
+
*= require widget_list
|
41
|
+
*= require widgets
|
42
|
+
|
43
|
+
Change application.js to:
|
44
|
+
|
45
|
+
//= require widget_list
|
46
|
+
|
47
|
+
### #2 - Run bundle exec rails s to have widget_list create config/widget-list.yml
|
48
|
+
|
49
|
+
Change application.css to:
|
50
|
+
|
51
|
+
*= require widget_list
|
52
|
+
*= require widgets
|
53
|
+
|
54
|
+
Change application.js to:
|
55
|
+
|
56
|
+
//= require widget_list
|
57
|
+
|
58
|
+
### Example Calling Page That Sets up Config and calls WidgetList.render
|
59
|
+
|
60
|
+
#
|
61
|
+
# Load Sample "items" Data. Comment out in your first time executing a widgetlist to create the items table
|
62
|
+
#
|
63
|
+
|
64
|
+
# no table - create it and load it with 5K records
|
65
|
+
WidgetList::List.get_database.create_table :items do
|
66
|
+
primary_key :id
|
67
|
+
String :name
|
68
|
+
Float :price
|
69
|
+
end
|
70
|
+
items = WidgetList::List.get_database[:items]
|
71
|
+
100.times {
|
72
|
+
items.insert(:name => 'abc', :price => rand * 100)
|
73
|
+
items.insert(:name => '123', :price => rand * 100)
|
74
|
+
items.insert(:name => 'asdf', :price => rand * 100)
|
75
|
+
items.insert(:name => 'qwerty', :price => rand * 100)
|
76
|
+
items.insert(:name => 'poop', :price => rand * 100)
|
77
|
+
}
|
78
|
+
|
79
|
+
|
80
|
+
#
|
81
|
+
# Setup your first widget_list
|
82
|
+
#
|
83
|
+
|
84
|
+
button_column_name = 'actions'
|
85
|
+
list_parms = {}
|
86
|
+
|
87
|
+
#
|
88
|
+
# action_buttons will add buttons to the bottom of the list.
|
89
|
+
#
|
90
|
+
|
91
|
+
action_buttons = WidgetList::Widgets::widget_button('Add New Item', {'page' => '/add/'} ) + WidgetList::Widgets::widget_button('Do something else', {'page' => '/else/'} )
|
92
|
+
|
93
|
+
#
|
94
|
+
# Give it a name, some SQL to feed widget_list and set a noDataMessage
|
95
|
+
#
|
96
|
+
list_parms['name'] = 'ruby_items_yum'
|
97
|
+
list_parms['view'] = '(SELECT \'\' as checkbox,a.* FROM items a ) a'
|
98
|
+
list_parms['noDataMessage'] = 'No Tables Found'
|
99
|
+
list_parms['title'] = 'Ruby Items!!!'
|
100
|
+
|
101
|
+
#
|
102
|
+
# Create small button array and pass to the buttons key
|
103
|
+
#
|
104
|
+
|
105
|
+
mini_buttons = {}
|
106
|
+
mini_buttons['button_edit'] = {'page' => '/edit',
|
107
|
+
'text' => 'Edit',
|
108
|
+
'function' => 'Redirect',
|
109
|
+
#pass tags to pull from each column when building the URL
|
110
|
+
'tags' => {'my_key_name' => 'name','value_from_database'=>'price'}}
|
111
|
+
|
112
|
+
mini_buttons['button_delete'] = {'page' => '/delete',
|
113
|
+
'text' => 'Delete',
|
114
|
+
'function' => 'alert',
|
115
|
+
'innerClass' => 'danger'}
|
116
|
+
list_parms['buttons'] = {button_column_name => mini_buttons}
|
117
|
+
list_parms['function'] = {button_column_name => "'' " + button_column_name }
|
118
|
+
list_parms['groupByItems']= ['All Records','Another Grouping Item']
|
119
|
+
|
120
|
+
#
|
121
|
+
# Generate a template for the DOWN ARROW for CUSTOM FILTER
|
122
|
+
#
|
123
|
+
|
124
|
+
template = {}
|
125
|
+
input = {}
|
126
|
+
|
127
|
+
input['id'] = 'comments'
|
128
|
+
input['name'] = 'comments'
|
129
|
+
input['width'] = '170'
|
130
|
+
input['max_length'] = '500'
|
131
|
+
input['input_class'] = 'info-input'
|
132
|
+
input['title'] = 'Optional CSV list'
|
133
|
+
|
134
|
+
button_search = {}
|
135
|
+
button_search['innerClass'] = "success btn-submit"
|
136
|
+
button_search['onclick'] = "alert('This would search, but is not coded. That is for you to do')"
|
137
|
+
|
138
|
+
list_parms['list_search_form'] = WidgetList::Utils::fill( {
|
139
|
+
'<!--COMMENTS-->' => WidgetList::Widgets::widget_input(input),
|
140
|
+
'<!--BUTTON_SEARCH-->' => WidgetList::Widgets::widget_button('Search', button_search),
|
141
|
+
'<!--BUTTON_CLOSE-->' => "HideAdvancedSearch(this)" } ,
|
142
|
+
'
|
143
|
+
<div id="advanced-search-container">
|
144
|
+
<div class="widget-search-drilldown-close" onclick="<!--BUTTON_CLOSE-->">X</div>
|
145
|
+
<ul class="advanced-search-container-inline" id="search_columns">
|
146
|
+
<li>
|
147
|
+
<div>Search Comments</div>
|
148
|
+
<!--COMMENTS-->
|
149
|
+
</li>
|
150
|
+
</ul>
|
151
|
+
<br/>
|
152
|
+
<div style="text-align:right;width:100%;height:30px;" class="advanced-search-container-buttons"><!--BUTTON_RESET--><!--BUTTON_SEARCH--></div>
|
153
|
+
</div>')
|
154
|
+
|
155
|
+
#
|
156
|
+
# Setup a custom field for checkboxes stored into the session and reloaded when refresh occurs
|
157
|
+
#
|
158
|
+
|
159
|
+
list_parms.deep_merge!({'fields' =>
|
160
|
+
{
|
161
|
+
'checkbox'=> 'checkbox_header',
|
162
|
+
'id'=> 'Item Id',
|
163
|
+
'name'=> 'Name',
|
164
|
+
'price'=> 'Price of Item',
|
165
|
+
button_column_name => button_column_name.capitalize,
|
166
|
+
}
|
167
|
+
})
|
168
|
+
|
169
|
+
list_parms.deep_merge!({'inputs' =>
|
170
|
+
{'checkbox'=>
|
171
|
+
{'type' => 'checkbox'
|
172
|
+
}
|
173
|
+
}
|
174
|
+
})
|
175
|
+
|
176
|
+
list_parms.deep_merge!({'inputs' =>
|
177
|
+
{'checkbox'=>
|
178
|
+
{'items' =>
|
179
|
+
{
|
180
|
+
'name' => 'visible_checks[]',
|
181
|
+
'value' => 'id', #the value should be a column name mapping
|
182
|
+
'class_handle' => 'info_tables',
|
183
|
+
}
|
184
|
+
}
|
185
|
+
}
|
186
|
+
})
|
187
|
+
|
188
|
+
list_parms.deep_merge!({'inputs' =>
|
189
|
+
{'checkbox_header'=>
|
190
|
+
{'type' => 'checkbox'
|
191
|
+
}
|
192
|
+
}
|
193
|
+
})
|
194
|
+
|
195
|
+
list_parms.deep_merge!({'inputs' =>
|
196
|
+
{'checkbox_header'=>
|
197
|
+
{'items' =>
|
198
|
+
{
|
199
|
+
'check_all' => true,
|
200
|
+
'id' => 'info_tables_check_all',
|
201
|
+
'class_handle' => 'info_tables',
|
202
|
+
}
|
203
|
+
}
|
204
|
+
}
|
205
|
+
})
|
206
|
+
|
207
|
+
list = WidgetList::List.new(list_parms)
|
208
|
+
|
209
|
+
#
|
210
|
+
# If AJAX, send back JSON
|
211
|
+
#
|
212
|
+
if $_REQUEST.key?('BUTTON_VALUE') && $_REQUEST['LIST_NAME'] == list_parms['name']
|
213
|
+
ret = {}
|
214
|
+
ret['list'] = WidgetList::Utils::fill({ '<!--CUSTOM_CONTENT-->' => action_buttons } , list.render() )
|
215
|
+
ret['list_id'] = list_parms['name']
|
216
|
+
ret['callback'] = 'ListSearchAheadResponse'
|
217
|
+
return render :inline => WidgetList::Utils::json_encode(ret)
|
218
|
+
else
|
219
|
+
#
|
220
|
+
# Else assign to variable for view
|
221
|
+
#
|
222
|
+
@output = WidgetList::Utils::fill({ '<!--CUSTOM_CONTENT-->' => action_buttons } , list.render() )
|
223
|
+
end
|
224
|
+
|
225
|
+
## Contributing
|
226
|
+
|
227
|
+
1. Fork it
|
228
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
229
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
230
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
231
|
+
5. Create new Pull Request
|
232
|
+
|
233
|
+
|
234
|
+
Meta
|
235
|
+
----
|
236
|
+
|
237
|
+
* Gems: <http://rubygems.org/gems/widget-list>
|
238
|
+
|
239
|
+
|
240
|
+
Authors
|
241
|
+
-------
|
242
|
+
|
243
|
+
David Renne :: david_renne @ ya hoo - .com :: @phpnerd
|
244
|
+
|
245
|
+
License
|
246
|
+
-------
|
247
|
+
|
248
|
+
Copyright 2012 David Renne
|
249
|
+
|
250
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
251
|
+
you may not use this file except in compliance with the License.
|
252
|
+
You may obtain a copy of the License at
|
253
|
+
|
254
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
255
|
+
|
256
|
+
Unless required by applicable law or agreed to in writing, software
|
257
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
258
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
259
|
+
See the License for the specific language governing permissions and
|
260
|
+
limitations under the License.
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/lib/widget_list.rb
ADDED
@@ -0,0 +1,2054 @@
|
|
1
|
+
require 'widget_list/sequel'
|
2
|
+
require 'widget_list/version'
|
3
|
+
require 'widget_list/hash'
|
4
|
+
require 'widget_list/string'
|
5
|
+
require 'widget_list/utils'
|
6
|
+
require 'widget_list/tpl'
|
7
|
+
require 'widget_list/widgets'
|
8
|
+
require 'widget_list/railtie'
|
9
|
+
require 'json'
|
10
|
+
require 'uri'
|
11
|
+
require 'extensions/action_controller_base'
|
12
|
+
require 'sequel'
|
13
|
+
|
14
|
+
|
15
|
+
module WidgetList
|
16
|
+
|
17
|
+
if defined?(Rails) && defined?(Rails::Engine)
|
18
|
+
class Engine < ::Rails::Engine
|
19
|
+
require 'widget_list/engine'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class List
|
24
|
+
|
25
|
+
@debug = true
|
26
|
+
|
27
|
+
include ActionView::Helpers::SanitizeHelper
|
28
|
+
|
29
|
+
def self.connect
|
30
|
+
|
31
|
+
if Rails.root.join("config", "widget-list.yml").file?
|
32
|
+
config = YAML.load(ERB.new(File.new(Rails.root.join("config", "widget-list.yml")).read).result)[Rails.env]
|
33
|
+
@primary_conn = config[:primary]
|
34
|
+
@secondary_conn = config[:secondary]
|
35
|
+
else
|
36
|
+
throw 'widget-list.yml not found'
|
37
|
+
end
|
38
|
+
|
39
|
+
$DATABASE = Sequel.connect(@primary_conn) if @primary_conn.class.name == 'String'
|
40
|
+
$DATABASE2 = Sequel.connect(@secondary_conn) if @secondary_conn.class.name == 'String'
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.get_database
|
45
|
+
case $current_db_selection
|
46
|
+
when 'primary'
|
47
|
+
$DATABASE
|
48
|
+
when 'secondary'
|
49
|
+
$DATABASE2
|
50
|
+
else
|
51
|
+
$DATABASE
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# @param [Hash] list
|
56
|
+
def initialize(list={})
|
57
|
+
|
58
|
+
@items = {
|
59
|
+
'name' => ([*('A'..'Z'),*('0'..'9')]-%w(0 1 I O)).sample(16).join,
|
60
|
+
'database' => 'primary',
|
61
|
+
'title' => '',# will add <h1> title and horizontal rule
|
62
|
+
'listDescription' => '',# will add grey header box
|
63
|
+
'pageId' => $_SERVER['PATH_INFO'],
|
64
|
+
'sql' => '',
|
65
|
+
'table' => '',
|
66
|
+
'view' => '',
|
67
|
+
'data' => {},
|
68
|
+
'mode' => 'passive',
|
69
|
+
'collClass' => '',
|
70
|
+
'collAlign' => '',
|
71
|
+
'fields' => {},
|
72
|
+
'columns' => {},
|
73
|
+
'bindVars' => [],
|
74
|
+
'bindVarsLegacy' => {},
|
75
|
+
'links' => {},
|
76
|
+
'results' => {},
|
77
|
+
'buttons' => {},
|
78
|
+
'inputs' => {},
|
79
|
+
'filter' => '',
|
80
|
+
'rowStart' => 0,
|
81
|
+
'rowLimit' => 10,
|
82
|
+
'orderBy' => '',
|
83
|
+
'allowHTML' => true,
|
84
|
+
'strlength' => 30,
|
85
|
+
'searchClear' => false, # build a custom conditional for each page to clear session
|
86
|
+
'searchClearAll' => false, # build a custom conditional for each page to clear session
|
87
|
+
'showPagination' => true,
|
88
|
+
'searchSession' => true, #on list render use last filter
|
89
|
+
|
90
|
+
#
|
91
|
+
# Custom count query
|
92
|
+
#
|
93
|
+
'force_count_sql' => '',
|
94
|
+
'force_query_sql' => '',
|
95
|
+
|
96
|
+
#
|
97
|
+
# Counts
|
98
|
+
#
|
99
|
+
'count_cache_time' => 180, #
|
100
|
+
'cachedCount' => -1, #pass the count
|
101
|
+
|
102
|
+
#
|
103
|
+
# Ajax
|
104
|
+
#
|
105
|
+
'ajax_action' => '',
|
106
|
+
'ajax_function' => 'ListJumpMin',
|
107
|
+
'ajax_search_function'=> 'ListJumpMin',
|
108
|
+
|
109
|
+
#
|
110
|
+
# Search
|
111
|
+
#
|
112
|
+
'showSearch' => true,
|
113
|
+
'searchOnkeyup' => '',
|
114
|
+
'searchOnclick' => '',
|
115
|
+
'searchIdCol' => 'id', #By default `id` column is here because typically if you call your PK's id and are auto-increment
|
116
|
+
'searchInputLegacyCSS'=> false,
|
117
|
+
'searchBtnName' => 'Search by Id or a list of Ids and more',
|
118
|
+
'searchTitle' => '',
|
119
|
+
'searchFieldsIn' => {}, #White list of fields to include in a alpha-numeric based search
|
120
|
+
'searchFieldsOut' => {'id'=>true}, #Black list of fields to include in a alpha-numeric based search (default `id` to NEVER search when alpha seach)
|
121
|
+
|
122
|
+
|
123
|
+
#
|
124
|
+
# Group By Box
|
125
|
+
#
|
126
|
+
'groupByItems' => [], #array of strings (each a new "select option")
|
127
|
+
'groupBySelected' => false, #initially selected grouping - defaults to first in list if not
|
128
|
+
'groupByLabel' => 'Group By',
|
129
|
+
|
130
|
+
|
131
|
+
#
|
132
|
+
# Advanced searching
|
133
|
+
#
|
134
|
+
'list_search_form' => '', #The HTML form used for the advanced search drop down
|
135
|
+
'list_search_attribs' => {}, #widgetinput "search_ahead" attributes
|
136
|
+
|
137
|
+
#
|
138
|
+
# Column Specific
|
139
|
+
#
|
140
|
+
'columnStyle' => {},
|
141
|
+
'columnClass' => {},
|
142
|
+
'columnPopupTitle' => {},
|
143
|
+
'columnSort' => {},
|
144
|
+
'columnWidth' => {},
|
145
|
+
'columnNoSort' => {},
|
146
|
+
'columnFilter' => {},
|
147
|
+
|
148
|
+
#
|
149
|
+
# Row specifics
|
150
|
+
#
|
151
|
+
'rowColor' => '#FFFFFF',
|
152
|
+
'rowClass' => '',
|
153
|
+
'rowColorByStatus' => {},
|
154
|
+
'rowStylesByStatus' => {},
|
155
|
+
'offsetRows' => true,
|
156
|
+
'rowOffsets' => ['FFFFFF','FFFFFF'],
|
157
|
+
|
158
|
+
'class' => 'listContainerPassive',
|
159
|
+
'tableclass' => '',
|
160
|
+
'noDataMessage' => 'Currently no data.',
|
161
|
+
'useSort' => true,
|
162
|
+
'headerClass' => {},
|
163
|
+
'groupBy' => '',
|
164
|
+
'function' => {},
|
165
|
+
'buttonVal' => 'templateListJump',
|
166
|
+
'linkFunction' => 'ButtonLinkPost',
|
167
|
+
'template' => '',
|
168
|
+
'templateFilter' => '',
|
169
|
+
'pagerFull' => true,
|
170
|
+
'LIST_COL_SORT_ORDER' => 'ASC',
|
171
|
+
'LIST_COL_SORT' => '',
|
172
|
+
'LIST_FILTER_ALL' => '',
|
173
|
+
'ROW_LIMIT' => '',
|
174
|
+
'LIST_SEQUENCE' => 1,
|
175
|
+
'NEW_SEARCH' => false,
|
176
|
+
|
177
|
+
#
|
178
|
+
# Checkbox
|
179
|
+
#
|
180
|
+
'checked_class' => 'widgetlist-checkbox',
|
181
|
+
'checked_flag' => {},
|
182
|
+
|
183
|
+
#
|
184
|
+
# Hooks
|
185
|
+
#
|
186
|
+
'column_hooks' => {},
|
187
|
+
'row_hooks' => {}
|
188
|
+
}
|
189
|
+
|
190
|
+
@totalRowCount= 0
|
191
|
+
@totalPages = 0
|
192
|
+
@fixHtmlLinksReplace = {}
|
193
|
+
|
194
|
+
@sequence = 1
|
195
|
+
@totalRows = 0
|
196
|
+
@totalPage = 0
|
197
|
+
@listSortNext = 'ASC'
|
198
|
+
@filter = ''
|
199
|
+
@listFilter = ''
|
200
|
+
@fieldList = []
|
201
|
+
@templateFill = {}
|
202
|
+
@results = {}
|
203
|
+
|
204
|
+
@items.deep_merge!({'template' =>
|
205
|
+
'
|
206
|
+
<!--HEADER-->
|
207
|
+
<div class="<!--CLASS-->" id="<!--NAME-->">
|
208
|
+
<table class="list <!--TABLE_CLASS-->" style="<!--INLINE_STYLE-->" border="0" width="100%" cellpadding="0" cellspacing="0">
|
209
|
+
<!--LIST_TITLE-->
|
210
|
+
<tr class="list_header"><!--HEADERS--></tr>
|
211
|
+
<!--DATA-->
|
212
|
+
<tr>
|
213
|
+
<td colspan="<!--COLSPAN_FULL-->" align="left" style="padding:0px;margin:0px;text-align:left">
|
214
|
+
<div style="background-color:#ECECEC;height:50px;"><div style="padding:10px"><!--CUSTOM_CONTENT--></div>
|
215
|
+
</td>
|
216
|
+
</tr>
|
217
|
+
</table>
|
218
|
+
<div class="pagination" style="float:left;text-align:left;width:100%;margin:0px;padding:0px;"><div style="margin:auto;float:left;margin:0px;padding:0px;"><!--PAGINATION_LIST--></div></div>
|
219
|
+
<!--FILTER-->
|
220
|
+
<input type="hidden" name="<!--JUMP_URL_NAME-->" id="<!--JUMP_URL_NAME-->" value="<!--JUMP_URL-->">
|
221
|
+
</div>
|
222
|
+
'
|
223
|
+
})
|
224
|
+
|
225
|
+
@items.deep_merge!({'row' =>
|
226
|
+
'
|
227
|
+
<tr style="background-color:<!--BGCOLOR-->;<!--ROWSTYLE-->" class="<!--ROWCLASS-->"><!--CONTENT--></tr>
|
228
|
+
'
|
229
|
+
})
|
230
|
+
|
231
|
+
@items.deep_merge!({'list_description' =>
|
232
|
+
'
|
233
|
+
<tr class="summary">
|
234
|
+
<td id="<!--LIST_NAME-->_list_description" class="header" style="text-align:left;padding-bottom:5px;padding-top:5px;" colspan="<!--COLSPAN-->"><!--LIST_DESCRIPTION--></td>
|
235
|
+
</tr>
|
236
|
+
'
|
237
|
+
})
|
238
|
+
|
239
|
+
@items.deep_merge!({'col' =>
|
240
|
+
'
|
241
|
+
<td class="<!--CLASS-->" align="<!--ALIGN-->" title="<!--TITLE-->" onclick="<!--ONCLICK-->" style="<!--STYLE-->"><!--CONTENT--></td>
|
242
|
+
'
|
243
|
+
})
|
244
|
+
|
245
|
+
@items.deep_merge!({'templateSequence' =>
|
246
|
+
'
|
247
|
+
<!--LIST_SEQUENCE--> of <!--TOTAL_PAGES-->
|
248
|
+
'
|
249
|
+
})
|
250
|
+
#Sorting
|
251
|
+
#
|
252
|
+
@items.deep_merge!({'templateSortColumn' =>
|
253
|
+
'
|
254
|
+
<td style="font-weight:bold;<!--INLINE_STYLE-->" id="<!--COL_HEADER_ID-->" class="<!--COL_HEADER_CLASS-->" valign="middle"><span onclick="<!--FUNCTION-->(\'<!--COLSORTURL-->\',\'<!--NAME-->\')" style="cursor:pointer;background:none;" title="<!--TITLE_POPUP-->"><!--TITLE--><!--COLSORTICON-></span></td>
|
255
|
+
'
|
256
|
+
})
|
257
|
+
|
258
|
+
@items.deep_merge!({'templateNoSortColumn' =>
|
259
|
+
'
|
260
|
+
<td style="font-weight:bold;<!--INLINE_STYLE-->" title="<!--TITLE_POPUP-->" id="<!--COL_HEADER_ID-->" class="<!--COL_HEADER_CLASS-->" valign="middle"><span style="background:none;"><!--TITLE--></span></td>
|
261
|
+
'
|
262
|
+
})
|
263
|
+
|
264
|
+
@items.deep_merge!({'statement' =>
|
265
|
+
{'select'=>
|
266
|
+
{'view' =>
|
267
|
+
'
|
268
|
+
SELECT <!--FIELDS--> FROM <!--SOURCE--> <!--WHERE--> <!--GROUPBY--> <!--ORDERBY--> <!--LIMIT-->
|
269
|
+
'
|
270
|
+
}
|
271
|
+
}
|
272
|
+
})
|
273
|
+
|
274
|
+
@items.deep_merge!({'statement' =>
|
275
|
+
{'select'=>
|
276
|
+
{'sql' =>
|
277
|
+
'
|
278
|
+
SELECT <!--FIELDS--> FROM (<!--SQL-->) a <!--WHERE--> <!--GROUPBY--> <!--ORDERBY--> <!--LIMIT-->
|
279
|
+
'
|
280
|
+
}
|
281
|
+
}
|
282
|
+
})
|
283
|
+
|
284
|
+
@items.deep_merge!({'statement' =>
|
285
|
+
{'count'=>
|
286
|
+
{'view' =>
|
287
|
+
'
|
288
|
+
SELECT count(1) total FROM <!--VIEW--> <!--WHERE-->
|
289
|
+
'
|
290
|
+
}
|
291
|
+
}
|
292
|
+
})
|
293
|
+
|
294
|
+
@items.deep_merge!({'statement' =>
|
295
|
+
{'count'=>
|
296
|
+
{'sql' =>
|
297
|
+
'
|
298
|
+
SELECT count(1) total FROM (<!--SQL-->) s <!--WHERE-->
|
299
|
+
'
|
300
|
+
}
|
301
|
+
}
|
302
|
+
})
|
303
|
+
|
304
|
+
@items.deep_merge!({'statement' =>
|
305
|
+
{'count'=>
|
306
|
+
{'table' =>
|
307
|
+
'
|
308
|
+
SELECT count(1) total FROM <!--TABLE--> <!--WHERE-->
|
309
|
+
'
|
310
|
+
}
|
311
|
+
}
|
312
|
+
})
|
313
|
+
|
314
|
+
#Pagintion
|
315
|
+
#
|
316
|
+
|
317
|
+
@items.deep_merge!({'template_pagination_wrapper' =>
|
318
|
+
'
|
319
|
+
<ul id="pagination" class="page_legacy">
|
320
|
+
Page <!--PREVIOUS_BUTTON-->
|
321
|
+
<input type="text" value="<!--SEQUENCE-->" size="1" style="width:15px;padding:0px;font-size:10px;">
|
322
|
+
<input type="hidden" id="<!--LIST_NAME-->_total_rows" value="<!--TOTAL_ROWS-->">
|
323
|
+
<!--NEXT_BUTTON--> of <!--TOTAL_PAGES--> pages <span style="margin-left:20px">Total <!--TOTAL_ROWS--> records found</span>
|
324
|
+
<span style="padding-left:20px;">Show <!--PAGE_SEQUENCE_JUMP_LIST--> per page</span>
|
325
|
+
</ul>
|
326
|
+
'
|
327
|
+
})
|
328
|
+
|
329
|
+
@items.deep_merge!({'template_pagination_next_active' =>
|
330
|
+
"
|
331
|
+
<li><span onclick=\"<!--FUNCTION-->('<!--NEXT_URL-->','<!--LIST_NAME-->')\" style=\"cursor:pointer;background: transparent url(<!--HTTP_SERVER-->images/page-next.gif) no-repeat\"> </span></li>
|
332
|
+
"
|
333
|
+
})
|
334
|
+
|
335
|
+
@items.deep_merge!({'template_pagination_next_disabled' =>
|
336
|
+
"
|
337
|
+
<li><span style=\"opacity:0.4;filter:alpha(opacity=40);background: transparent url(<!--HTTP_SERVER-->images/page-next.gif) no-repeat\"> </span></li>
|
338
|
+
"
|
339
|
+
})
|
340
|
+
|
341
|
+
@items.deep_merge!({'template_pagination_previous_active' =>
|
342
|
+
"
|
343
|
+
<li><span onclick=\"<!--FUNCTION-->('<!--PREVIOUS_URL-->','<!--LIST_NAME-->')\" style=\"cursor:pointer;background: transparent url(<!--HTTP_SERVER-->images/page-back.gif) no-repeat\"> </span></li>
|
344
|
+
"
|
345
|
+
})
|
346
|
+
|
347
|
+
@items.deep_merge!({'template_pagination_previous_disabled' =>
|
348
|
+
"
|
349
|
+
<li><span style=\"opacity:0.4;filter:alpha(opacity=40);background: transparent url(<!--HTTP_SERVER-->images/page-back.gif) no-repeat\"> </span></li>
|
350
|
+
"
|
351
|
+
})
|
352
|
+
|
353
|
+
@items.deep_merge!({'template_pagination_jump_active' =>
|
354
|
+
'
|
355
|
+
<li><div class="active"><!--SEQUENCE--></div></li>
|
356
|
+
'
|
357
|
+
})
|
358
|
+
|
359
|
+
@items.deep_merge!({'template_pagination_jump_unactive' =>
|
360
|
+
'
|
361
|
+
<li onclick="<!--FUNCTION-->(\'<!--JUMP_URL-->\',\'<!--LIST_NAME-->\')"><div><!--SEQUENCE--></div></li>
|
362
|
+
'
|
363
|
+
})
|
364
|
+
|
365
|
+
@items = WidgetList::Widgets::populate_items(list,@items)
|
366
|
+
|
367
|
+
|
368
|
+
begin
|
369
|
+
@isJumpingList = false
|
370
|
+
|
371
|
+
#Ajax ListJump
|
372
|
+
if ! $_REQUEST.empty?
|
373
|
+
if $_REQUEST.key?('LIST_FILTER_ALL')
|
374
|
+
@items['LIST_FILTER_ALL'] = $_REQUEST['LIST_FILTER_ALL']
|
375
|
+
@isJumpingList = true
|
376
|
+
end
|
377
|
+
|
378
|
+
if $_REQUEST.key?('LIST_COL_SORT')
|
379
|
+
@items['LIST_COL_SORT'] = $_REQUEST['LIST_COL_SORT']
|
380
|
+
@isJumpingList = true
|
381
|
+
end
|
382
|
+
|
383
|
+
if $_REQUEST.key?('LIST_COL_SORT_ORDER')
|
384
|
+
@items['LIST_COL_SORT_ORDER'] = $_REQUEST['LIST_COL_SORT_ORDER']
|
385
|
+
@isJumpingList = true
|
386
|
+
end
|
387
|
+
|
388
|
+
if $_REQUEST.key?('LIST_SEQUENCE')
|
389
|
+
@items['LIST_SEQUENCE'] = $_REQUEST['LIST_SEQUENCE'].to_i
|
390
|
+
@isJumpingList = true
|
391
|
+
end
|
392
|
+
|
393
|
+
if $_REQUEST.key?('ROW_LIMIT')
|
394
|
+
@items['ROW_LIMIT'] = $_REQUEST['ROW_LIMIT']
|
395
|
+
@isJumpingList = true
|
396
|
+
|
397
|
+
if @items['showPagination']
|
398
|
+
$_SESSION['pageDisplayLimit'] = $_REQUEST['ROW_LIMIT']
|
399
|
+
$_SESSION.deep_merge!({'ROW_LIMIT' => { @items['name'] => $_REQUEST['ROW_LIMIT']} })
|
400
|
+
end
|
401
|
+
|
402
|
+
end
|
403
|
+
|
404
|
+
clear_sort_get_vars()
|
405
|
+
|
406
|
+
if $_REQUEST.key?('list_action') && $_REQUEST['list_action'] == 'ajax_widgetlist_checks'
|
407
|
+
ajax_maintain_checks()
|
408
|
+
end
|
409
|
+
|
410
|
+
end
|
411
|
+
|
412
|
+
# current_db is a flag of the last known primary or secondary YML used or defaulted when running a list
|
413
|
+
$current_db_selection = @items['database']
|
414
|
+
|
415
|
+
@items['groupByClick'] = "ListChangeGrouping('" + @items['name'] + "')"
|
416
|
+
|
417
|
+
=begin
|
418
|
+
#todo
|
419
|
+
@items['fieldNames'] = {};
|
420
|
+
if (empty(@items['fields']) && empty(@items['data']))
|
421
|
+
{
|
422
|
+
#Lazy mode where new columns added to view show up in list (unless you name the column "HIDE_xxxxx")
|
423
|
+
#
|
424
|
+
if (@items['sql'])
|
425
|
+
{
|
426
|
+
preg_match("/\s+from\s+`?([a-z\d_]+)`?/i", @items['sql'], $match);
|
427
|
+
$viewName = $match[1];
|
428
|
+
}
|
429
|
+
elseif (@items['view'])
|
430
|
+
{
|
431
|
+
$viewName = @items['view'];
|
432
|
+
}
|
433
|
+
|
434
|
+
if ($this->DATABASE->Select("SHOW FULL COLUMNS IN ".$viewName))
|
435
|
+
{
|
436
|
+
foreach($this->DATABASE->results['FIELD'] as $col)
|
437
|
+
{
|
438
|
+
@items['fieldNames'][] = $col;
|
439
|
+
$columnUpper = strtoupper($col);
|
440
|
+
$columnLower = strtolower($col);
|
441
|
+
if (substr($columnUpper,0,5) != 'HIDE_')
|
442
|
+
{
|
443
|
+
#any columns named HIDE_ will not show
|
444
|
+
#
|
445
|
+
@items['fields'][$columnLower] = $this->autoColumnName($columnUpper);
|
446
|
+
if ($columnLower != 'features')
|
447
|
+
{
|
448
|
+
@items['columnSort'][$columnLower] = $columnLower;
|
449
|
+
}
|
450
|
+
}
|
451
|
+
}
|
452
|
+
}
|
453
|
+
}
|
454
|
+
=end
|
455
|
+
|
456
|
+
if $_REQUEST.key?('searchClear')
|
457
|
+
clear_search_session()
|
458
|
+
end
|
459
|
+
|
460
|
+
if @items['searchClear'] || @items['searchClearAll']
|
461
|
+
clear_search_session(@items.key?('searchClearAll'))
|
462
|
+
end
|
463
|
+
|
464
|
+
matchesCurrentList = $_REQUEST.key?('BUTTON_VALUE') && $_REQUEST['BUTTON_VALUE'] == @items['buttonVal']
|
465
|
+
isSearchRequest = $_REQUEST.key?('search_filter')
|
466
|
+
templateCustomSearch = !@items['templateFilter'].empty? # if you define templateFilter WidgetList will not attempt to build a where clause with search
|
467
|
+
|
468
|
+
#
|
469
|
+
# Search restore
|
470
|
+
#
|
471
|
+
if !isSearchRequest && $_SESSION.key?('SEARCH_FILTER') && $_SESSION['SEARCH_FILTER'].key?(@items['name']) && @items['searchSession']
|
472
|
+
isSearchRestore = true
|
473
|
+
end
|
474
|
+
|
475
|
+
if (isSearchRequest && matchesCurrentList && !templateCustomSearch && @items['showSearch']) || isSearchRestore
|
476
|
+
if !isSearchRestore
|
477
|
+
$_SESSION.deep_merge!({'SEARCH_FILTER' => { @items['name'] => $_REQUEST['search_filter']} })
|
478
|
+
searchFilter = $_REQUEST['search_filter'].strip_or_self()
|
479
|
+
else
|
480
|
+
searchFilter = $_SESSION['SEARCH_FILTER'][@items['name']]
|
481
|
+
end
|
482
|
+
|
483
|
+
if ! searchFilter.empty?
|
484
|
+
if ! @items['filter'].empty? && @items['filter'].class.name != 'Array'
|
485
|
+
# convert string to array filter
|
486
|
+
filterString = @items['filter']
|
487
|
+
@items['filter'] = []
|
488
|
+
@items['filter'] << filterString
|
489
|
+
end
|
490
|
+
|
491
|
+
fieldsToSearch = @items['fields']
|
492
|
+
|
493
|
+
@items['columns'].each { |columnPivot|
|
494
|
+
fieldsToSearch[columnPivot] = columnPivot
|
495
|
+
}
|
496
|
+
|
497
|
+
searchCriteria = searchFilter.strip_or_self()
|
498
|
+
searchSQL = []
|
499
|
+
numericSearch = false
|
500
|
+
|
501
|
+
#
|
502
|
+
# Comma delimited search
|
503
|
+
#
|
504
|
+
if searchFilter.include?(',')
|
505
|
+
#It is either a CSV or a comma inside the search string
|
506
|
+
#
|
507
|
+
criteriaTmp = searchFilter.split_it(',')
|
508
|
+
|
509
|
+
#Assumed a CSV of numeric ids
|
510
|
+
#
|
511
|
+
isNumeric = true
|
512
|
+
criteriaTmp.each_with_index { |value, key|
|
513
|
+
if !value.empty?
|
514
|
+
criteriaTmp[key] = value.strip_or_self()
|
515
|
+
|
516
|
+
if !criteriaTmp[key].nil? && ! criteriaTmp[key].empty?
|
517
|
+
if ! WidgetList::Utils::numeric?(criteriaTmp[key])
|
518
|
+
isNumeric = false
|
519
|
+
end
|
520
|
+
else
|
521
|
+
criteriaTmp.delete(key)
|
522
|
+
end
|
523
|
+
end
|
524
|
+
}
|
525
|
+
|
526
|
+
if isNumeric
|
527
|
+
if @items['searchIdCol'].class.name == 'Array'
|
528
|
+
@items['searchIdCol'].each { |searchIdCol|
|
529
|
+
if(fieldsToSearch.key?(searchIdCol))
|
530
|
+
searchSQL << "`" + searchIdCol + "` IN(" + searchFilter + ")"
|
531
|
+
end
|
532
|
+
}
|
533
|
+
|
534
|
+
if !searchSQL.empty?
|
535
|
+
#
|
536
|
+
# Assemble Numeric Filter
|
537
|
+
#
|
538
|
+
@items['filter'] << "(" + searchSQL.join(' OR ') + ")"
|
539
|
+
end
|
540
|
+
elsif @items['fields'].key?(@items['searchIdCol'])
|
541
|
+
numericSearch = true
|
542
|
+
@items['filter'] << "`#{@items['searchIdCol']}` IN(" + criteriaTmp.join(',') + ")"
|
543
|
+
end
|
544
|
+
end
|
545
|
+
elsif @items['searchIdCol'].class.name == 'Array'
|
546
|
+
if WidgetList::Utils::numeric?(searchFilter) && ! searchFilter.include?('.')
|
547
|
+
@items['searchIdCol'].each { |searchIdCol|
|
548
|
+
if fieldsToSearch.key?(searchIdCol)
|
549
|
+
searchSQL << "`#{searchIdCol}` IN(#{searchFilter})"
|
550
|
+
end
|
551
|
+
}
|
552
|
+
|
553
|
+
if !searchSQL.empty?
|
554
|
+
#
|
555
|
+
# Assemble Numeric Filter
|
556
|
+
#
|
557
|
+
@items['filter'] << "(" + searchSQL.join(' OR ') + ")"
|
558
|
+
end
|
559
|
+
end
|
560
|
+
#elsif WidgetList::Utils::numeric?(searchFilter) && ! searchFilter.include?('.') && @items['fields'].key?(@items['searchIdCol'])
|
561
|
+
# #19.95 is numeric, but people might be searching for dollar amounts which should be string based search
|
562
|
+
# numericSearch = true
|
563
|
+
#
|
564
|
+
# @items['filter'] << "`#{@items['searchIdCol']}` IN(" + searchFilter + ")"
|
565
|
+
end
|
566
|
+
|
567
|
+
# If it is not an id or a list of ids then it is assumed a string search
|
568
|
+
if !numericSearch
|
569
|
+
ii = 0
|
570
|
+
fieldsToSearch.each { |fieldName,fieldTitle|
|
571
|
+
|
572
|
+
# new lodgette. if function exists, find all matches and skip them
|
573
|
+
skip = false
|
574
|
+
(@items['function']||{}).each { |k,v|
|
575
|
+
if fieldName == k
|
576
|
+
skip = true
|
577
|
+
end
|
578
|
+
}
|
579
|
+
|
580
|
+
#buttons must ALWAYS BE ON THE RIGHT SIDE IN ORDER FOR THIS NOT TO SEARCH A NON-EXISTENT COLUMN (used to be hard coded to 'features' as a column to remove)
|
581
|
+
if (!@items['buttons'].empty? && ii == (fieldsToSearch.length - 1)) || skip
|
582
|
+
next
|
583
|
+
end
|
584
|
+
|
585
|
+
#Search only specified fields. This can involve a dynamic field list from an advanced search form
|
586
|
+
#
|
587
|
+
if ! @items['searchFieldsIn'].empty?
|
588
|
+
#
|
589
|
+
# If it exists in either key or value
|
590
|
+
#
|
591
|
+
if ! @items['searchFieldsIn'].key?(fieldName) && ! @items['searchFieldsIn'].include?(fieldName)
|
592
|
+
next
|
593
|
+
end
|
594
|
+
elsif ! @items['searchFieldsOut'].empty?
|
595
|
+
if @items['searchFieldsOut'].key?(fieldName) || @items['searchFieldsOut'].include?(fieldName)
|
596
|
+
next
|
597
|
+
end
|
598
|
+
end
|
599
|
+
|
600
|
+
#todo - escape bind variables using Sequel
|
601
|
+
searchSQL << "`#{fieldName}` LIKE '%" + searchCriteria + "%'"
|
602
|
+
ii = ii + 1
|
603
|
+
}
|
604
|
+
|
605
|
+
#
|
606
|
+
# Assemble String Filter
|
607
|
+
#
|
608
|
+
if(! searchSQL.empty?)
|
609
|
+
@items['filter'] << "(" + searchSQL.join(' OR ') + ")"
|
610
|
+
end
|
611
|
+
end
|
612
|
+
end
|
613
|
+
end
|
614
|
+
|
615
|
+
if !$_REQUEST.key?('BUTTON_VALUE')
|
616
|
+
|
617
|
+
#Initialize page load/Session stuff whe list first loads
|
618
|
+
#
|
619
|
+
clear_check_box_session(@items['name'])
|
620
|
+
end
|
621
|
+
|
622
|
+
|
623
|
+
if ! @items.key?('templateHeader')
|
624
|
+
@items['templateHeader'] = ''
|
625
|
+
end
|
626
|
+
|
627
|
+
#Set a list title if it exists
|
628
|
+
#
|
629
|
+
|
630
|
+
if ! $_REQUEST.key?('BUTTON_VALUE') && !@items['title'].empty?
|
631
|
+
@items['templateHeader'] = '
|
632
|
+
<h1><!--TITLE--></h1><div class="horizontal_rule"></div>
|
633
|
+
<!--FILTER_HEADER-->
|
634
|
+
'
|
635
|
+
else
|
636
|
+
if !$_REQUEST.key?('BUTTON_VALUE')
|
637
|
+
# Only if not in ajax would we want to output the filter header
|
638
|
+
#
|
639
|
+
@items['templateHeader'] = '
|
640
|
+
<!--FILTER_HEADER-->
|
641
|
+
'
|
642
|
+
end
|
643
|
+
end
|
644
|
+
|
645
|
+
# Build the filter (If any)
|
646
|
+
#
|
647
|
+
# todo - unit test filter
|
648
|
+
if !@items['filter'].empty? && @items['filter'].class.name == 'Array'
|
649
|
+
@filter = @items['filter'].join(' AND ')
|
650
|
+
elsif !@items['filter'].empty? && @items['filter'].class.name == 'String'
|
651
|
+
@filter = @items['filter']
|
652
|
+
end
|
653
|
+
|
654
|
+
#Sorting
|
655
|
+
#
|
656
|
+
|
657
|
+
if !@items['LIST_COL_SORT'].empty?
|
658
|
+
@items['LIST_SEQUENCE'] = 1
|
659
|
+
end
|
660
|
+
|
661
|
+
if @items['LIST_SEQUENCE'].class.name == 'Fixnum' && @items['LIST_SEQUENCE'] > 0
|
662
|
+
@sequence = @items['LIST_SEQUENCE'].to_i
|
663
|
+
end
|
664
|
+
|
665
|
+
if ! @items['ROW_LIMIT'].empty?
|
666
|
+
@items['rowLimit'] = @items['ROW_LIMIT'].to_i
|
667
|
+
end
|
668
|
+
|
669
|
+
if $_SESSION.key?('ROW_LIMIT') && $_SESSION['ROW_LIMIT'].key?(@items['name']) && !$_SESSION['ROW_LIMIT'][@items['name']].empty?
|
670
|
+
@items['rowLimit'] = $_SESSION['ROW_LIMIT'][@items['name']].to_i
|
671
|
+
end
|
672
|
+
|
673
|
+
if ! @items['LIST_COL_SORT'].empty?
|
674
|
+
case @items['LIST_COL_SORT_ORDER']
|
675
|
+
when 'ASC'
|
676
|
+
@listSortNext = 'DESC'
|
677
|
+
else
|
678
|
+
@listSortNext = 'ASC'
|
679
|
+
end
|
680
|
+
end
|
681
|
+
|
682
|
+
generate_limits()
|
683
|
+
rescue Exception => e
|
684
|
+
@templateFill['<!--DATA-->'] = '<tr><td colspan="50"><div id="noListResults">' + generate_error_output(e) + @items['noDataMessage'] + '</div></td></tr>'
|
685
|
+
end
|
686
|
+
end
|
687
|
+
|
688
|
+
def ajax_maintain_checks()
|
689
|
+
|
690
|
+
#
|
691
|
+
# A list must be provided
|
692
|
+
#
|
693
|
+
if $_REQUEST.key?('LIST_NAME')
|
694
|
+
listName = $_REQUEST['LIST_NAME']
|
695
|
+
sqlHash = $_REQUEST['SQL_HASH']
|
696
|
+
|
697
|
+
#
|
698
|
+
# The placeholder is created when the list initially forms. This validates it and makes it so
|
699
|
+
# not just anything can be injected into the session via this method.
|
700
|
+
#
|
701
|
+
|
702
|
+
#
|
703
|
+
# For each posted check box
|
704
|
+
#
|
705
|
+
|
706
|
+
$_REQUEST.each { |value, checked|
|
707
|
+
if checked.to_s == '1'
|
708
|
+
#
|
709
|
+
# Set it as checked
|
710
|
+
#
|
711
|
+
$_SESSION.deep_merge!({'list_checks' => { listName + sqlHash + value => true } })
|
712
|
+
else
|
713
|
+
#
|
714
|
+
# Unset if it exists and is unchecked
|
715
|
+
#
|
716
|
+
if $_SESSION['list_checks'].key?(listName + sqlHash + value)
|
717
|
+
$_SESSION['list_checks'].delete(listName + sqlHash + value)
|
718
|
+
end
|
719
|
+
end
|
720
|
+
}
|
721
|
+
|
722
|
+
#
|
723
|
+
# Check All
|
724
|
+
#
|
725
|
+
if $_REQUEST.key?('checked_all')
|
726
|
+
if $_SESSION.key?('list_checks')
|
727
|
+
|
728
|
+
if $_SESSION['list_checks'].key?('check_all_' + sqlHash + $_REQUEST['LIST_NAME'] + $_REQUEST['LIST_SEQUENCE'])
|
729
|
+
if $_REQUEST['checked_all'].empty?
|
730
|
+
$_SESSION['list_checks'].delete('check_all_' + sqlHash + $_REQUEST['LIST_NAME'] + $_REQUEST['LIST_SEQUENCE'])
|
731
|
+
else
|
732
|
+
$_SESSION.deep_merge!({'list_checks' => { 'check_all_' + sqlHash + $_REQUEST['LIST_NAME'] + $_REQUEST['LIST_SEQUENCE'] => true } })
|
733
|
+
end
|
734
|
+
else
|
735
|
+
if ! $_REQUEST['checked_all'].empty?
|
736
|
+
$_SESSION.deep_merge!({'list_checks' => { 'check_all_' + sqlHash + $_REQUEST['LIST_NAME'] + $_REQUEST['LIST_SEQUENCE'] => true } })
|
737
|
+
end
|
738
|
+
end
|
739
|
+
end
|
740
|
+
end
|
741
|
+
end
|
742
|
+
end
|
743
|
+
|
744
|
+
def clear_check_box_session(name='')
|
745
|
+
|
746
|
+
if $_SESSION.key?('DRILL_DOWN_FILTERS')
|
747
|
+
$_SESSION.delete('DRILL_DOWN_FILTERS')
|
748
|
+
end
|
749
|
+
|
750
|
+
if $_SESSION.key?('DRILL_DOWNS')
|
751
|
+
$_SESSION.delete('DRILL_DOWNS')
|
752
|
+
end
|
753
|
+
|
754
|
+
end
|
755
|
+
|
756
|
+
def clear_search_session(all=false)
|
757
|
+
|
758
|
+
if $_SESSION.key?('SEARCH_FILTER') && $_SESSION['SEARCH_FILTER'].key?(@items['name'])
|
759
|
+
$_SESSION['SEARCH_FILTER'].delete(@items['name'])
|
760
|
+
end
|
761
|
+
|
762
|
+
if $_SESSION.key?('ROW_LIMIT') && $_SESSION['ROW_LIMIT'].key?(@items['name'])
|
763
|
+
$_SESSION['ROW_LIMIT'].delete(@items['name'])
|
764
|
+
end
|
765
|
+
|
766
|
+
if all && $_SESSION.key?('SEARCH_FILTER')
|
767
|
+
$_SESSION.delete('SEARCH_FILTER')
|
768
|
+
end
|
769
|
+
|
770
|
+
if all && $_SESSION.key?('ROW_LIMIT')
|
771
|
+
$_SESSION.delete('ROW_LIMIT')
|
772
|
+
end
|
773
|
+
|
774
|
+
end
|
775
|
+
|
776
|
+
def clear_sql_session(all=false)
|
777
|
+
|
778
|
+
if $_SESSION.key?('LIST_SEQUENCE') && $_SESSION['LIST_SEQUENCE'].key?(@sqlHash)
|
779
|
+
$_SESSION['LIST_SEQUENCE'].delete(@sqlHash)
|
780
|
+
end
|
781
|
+
|
782
|
+
if $_SESSION.key?('LIST_COL_SORT') && $_SESSION['LIST_COL_SORT'].key?(@sqlHash)
|
783
|
+
$_SESSION['LIST_COL_SORT'].delete(@sqlHash)
|
784
|
+
end
|
785
|
+
|
786
|
+
if all && $_SESSION.key?('LIST_COL_SORT')
|
787
|
+
$_SESSION.delete('LIST_COL_SORT')
|
788
|
+
end
|
789
|
+
|
790
|
+
if all && $_SESSION.key?('LIST_SEQUENCE')
|
791
|
+
$_SESSION.delete('LIST_SEQUENCE')
|
792
|
+
end
|
793
|
+
|
794
|
+
end
|
795
|
+
|
796
|
+
def clear_sort_get_vars()
|
797
|
+
$_REQUEST.delete('LIST_FILTER_ALL')
|
798
|
+
$_REQUEST.delete('ROW_LIMIT')
|
799
|
+
$_REQUEST.delete('LIST_SEQUENCE')
|
800
|
+
$_REQUEST.delete('LIST_COL_SORT_ORDER')
|
801
|
+
$_REQUEST.delete('LIST_COL_SORT')
|
802
|
+
$_REQUEST.delete('LIST_FILTER_ALL')
|
803
|
+
end
|
804
|
+
|
805
|
+
def generate_limits()
|
806
|
+
#Pagination
|
807
|
+
#
|
808
|
+
@items['bindVarsLegacy']['LOW'] = @items['rowStart']
|
809
|
+
@items['bindVarsLegacy']['HIGH'] = @items['rowLimit']
|
810
|
+
|
811
|
+
if @sequence.to_i > 1 && ! @items['NEW_SEARCH']
|
812
|
+
@items['bindVarsLegacy']['LOW'] = (((@sequence * @items['rowLimit']) - @items['rowLimit']))
|
813
|
+
end
|
814
|
+
end
|
815
|
+
|
816
|
+
# @param [Hash] results
|
817
|
+
# pass results of $DATABASE.final_results after running a _select query
|
818
|
+
def render(results={})
|
819
|
+
|
820
|
+
begin
|
821
|
+
if !results.empty?
|
822
|
+
@items['data'] = results
|
823
|
+
end
|
824
|
+
|
825
|
+
#Get total records for statement validation and pagination
|
826
|
+
#
|
827
|
+
@items['data'].keys.each { |column|
|
828
|
+
@items['fields'][column.downcase] = auto_column_name(column)
|
829
|
+
} if !@items['data'].empty? && @items['fields'].empty?
|
830
|
+
|
831
|
+
if @items['data'].empty?
|
832
|
+
# Generate count() from database
|
833
|
+
#
|
834
|
+
@totalResultCount = get_total_records()
|
835
|
+
else
|
836
|
+
# Count the items in the passed data
|
837
|
+
#
|
838
|
+
@items['data'].keys.each { |column|
|
839
|
+
@totalResultCount = @items['data'][column].count
|
840
|
+
@totalRowCount = @totalResultCount
|
841
|
+
@totalRows = @totalResultCount
|
842
|
+
break
|
843
|
+
}
|
844
|
+
end
|
845
|
+
|
846
|
+
build_rows()
|
847
|
+
|
848
|
+
build_headers()
|
849
|
+
|
850
|
+
listJumpUrl = {}
|
851
|
+
listJumpUrl['PAGE_ID'] = @items['pageId']
|
852
|
+
listJumpUrl['ACTION'] = 'AJAX'
|
853
|
+
listJumpUrl['BUTTON_VALUE'] = @items['buttonVal']
|
854
|
+
listJumpUrl['LIST_COL_SORT'] = @items['LIST_COL_SORT']
|
855
|
+
listJumpUrl['LIST_COL_SORT_ORDER'] = @items['LIST_COL_SORT_ORDER']
|
856
|
+
listJumpUrl['LIST_FILTER_ALL'] = @items['LIST_FILTER_ALL']
|
857
|
+
listJumpUrl['ROW_LIMIT'] = @items['ROW_LIMIT']
|
858
|
+
listJumpUrl['LIST_SEQUENCE'] = @sequence
|
859
|
+
listJumpUrl['LIST_NAME'] = @items['name']
|
860
|
+
listJumpUrl['SQL_HASH'] = @sqlHash
|
861
|
+
|
862
|
+
if @items.key?('ajax_action')
|
863
|
+
listJumpUrl['list_action'] = @items['ajax_action']
|
864
|
+
end
|
865
|
+
|
866
|
+
@templateFill['<!--HEADER-->'] = @items['templateHeader']
|
867
|
+
@templateFill['<!--TITLE-->'] = @items['title']
|
868
|
+
@templateFill['<!--NAME-->'] = @items['name']
|
869
|
+
@templateFill['<!--JUMP_URL-->'] = WidgetList::Utils::build_url(@items['pageId'],listJumpUrl,(!$_REQUEST.key?('BUTTON_VALUE')))
|
870
|
+
@templateFill['<!--JUMP_URL_NAME-->'] = @items['name'] + '_jump_url'
|
871
|
+
@templateFill['<!--CLASS-->'] = @items['class']
|
872
|
+
|
873
|
+
if @totalRowCount > 0
|
874
|
+
@templateFill['<!--INLINE_STYLE-->'] = ''
|
875
|
+
@templateFill['<!--TABLE_CLASS-->'] = @items['tableclass']
|
876
|
+
else
|
877
|
+
@templateFill['<!--INLINE_STYLE-->'] = 'table-layout:auto;'
|
878
|
+
end
|
879
|
+
#Filter form
|
880
|
+
#
|
881
|
+
if @items['showSearch'] === true
|
882
|
+
if ! @items['templateFilter'].empty?
|
883
|
+
@templateFill['<!--FILTER_HEADER-->'] = @items['templateFilter']
|
884
|
+
else
|
885
|
+
if !$_REQUEST.key?('search_filter') && !@isJumpingList
|
886
|
+
|
887
|
+
#Search page url
|
888
|
+
#
|
889
|
+
searchUrl = ''
|
890
|
+
searchVal = ''
|
891
|
+
|
892
|
+
if ! @items['buttonVal'].empty?
|
893
|
+
searchVal = @items['buttonVal']
|
894
|
+
else
|
895
|
+
searchVal = @items['name']
|
896
|
+
end
|
897
|
+
|
898
|
+
filterParameters = {}
|
899
|
+
filterParameters['BUTTON_VALUE'] = searchVal
|
900
|
+
filterParameters['PAGE_ID'] = @items['pageId']
|
901
|
+
filterParameters['LIST_NAME'] = @items['name']
|
902
|
+
filterParameters['SQL_HASH'] = @sqlHash
|
903
|
+
if @items.key?('ajax_action') && ! @items['ajax_action'].empty?
|
904
|
+
filterParameters['list_action'] = @items['ajax_action']
|
905
|
+
end
|
906
|
+
|
907
|
+
searchUrl = WidgetList::Utils::build_url(@items['pageId'], filterParameters, (!$_REQUEST.key?('BUTTON_VALUE')))
|
908
|
+
|
909
|
+
list_search = {}
|
910
|
+
#
|
911
|
+
# Search value
|
912
|
+
#
|
913
|
+
list_search['value'] = ''
|
914
|
+
|
915
|
+
if @items['searchSession']
|
916
|
+
if $_SESSION.key?('SEARCH_FILTER') && $_SESSION['SEARCH_FILTER'].key?(@items['name'])
|
917
|
+
list_search['value'] = $_SESSION['SEARCH_FILTER'][@items['name']]
|
918
|
+
end
|
919
|
+
end
|
920
|
+
|
921
|
+
#
|
922
|
+
# Search Input Field
|
923
|
+
#
|
924
|
+
list_search['list-search'] = true
|
925
|
+
list_search['width'] = '500'
|
926
|
+
list_search['input_class'] = 'info-input'
|
927
|
+
list_search['title'] = (@items['searchTitle'].empty?) ? @items['searchBtnName'] :@items['searchTitle']
|
928
|
+
list_search['id'] = 'list_search_id_' + @items['name']
|
929
|
+
list_search['name'] = 'list_search_name_' + @items['name']
|
930
|
+
list_search['class'] = 'inputOuter widget-search-outer ' + @items['name'].downcase + '-search'
|
931
|
+
list_search['search_ahead'] = {
|
932
|
+
'url' => searchUrl,
|
933
|
+
'skip_queue' => false,
|
934
|
+
'target' => @items['name'],
|
935
|
+
'search_form' => @items['list_search_form'],
|
936
|
+
'onclick' => (! @items['searchOnclick'].empty? && ! @items['list_search_form'].empty?) ? @items['searchOnclick'] : '',
|
937
|
+
'onkeyup' => (! @items['searchOnkeyup'].empty?) ? @items['searchOnkeyup'] : ''
|
938
|
+
}
|
939
|
+
|
940
|
+
@templateFill['<!--FILTER_HEADER-->'] = WidgetList::Widgets::widget_input(list_search)
|
941
|
+
|
942
|
+
end
|
943
|
+
|
944
|
+
#
|
945
|
+
# Grouping box
|
946
|
+
#
|
947
|
+
if ! @items['groupByItems'].empty?
|
948
|
+
list_group = {}
|
949
|
+
list_group['arrow_action'] = 'var stub;'
|
950
|
+
list_group['readonly'] = true
|
951
|
+
if @items['groupBySelected']
|
952
|
+
list_group['value'] = @items['groupBySelected']
|
953
|
+
else
|
954
|
+
list_group['value'] = @items['groupByItems'][0]
|
955
|
+
end
|
956
|
+
|
957
|
+
list_group['style'] = 'cursor:pointer;margin-left:5px;'
|
958
|
+
list_group['input_style'] = 'cursor:pointer;'
|
959
|
+
list_group['outer_onclick'] = 'ToggleAdvancedSearch(this);SelectBoxResetSelectedRow(\'' + @items['name'] + '\');'
|
960
|
+
list_group['list-search'] = false
|
961
|
+
list_group['width'] = '200' #hard code for now. needs to be dynamic based on max str length if this caller is made into a "WidgetFakeSelect"
|
962
|
+
list_group['id'] = 'list_group_id_' + @items['name']
|
963
|
+
list_group['name'] = 'list_group_name_' + @items['name']
|
964
|
+
list_group['class'] = 'inputOuter widget-search-outer ' + @items['name'].downcase + '-group'
|
965
|
+
|
966
|
+
className = ''
|
967
|
+
groupRows = []
|
968
|
+
if !@items['groupBySelected']
|
969
|
+
className = 'widget-search-results-row-selected'
|
970
|
+
end
|
971
|
+
|
972
|
+
@items['groupByItems'].each { |grouping|
|
973
|
+
if @items['groupBySelected'] && @items['groupBySelected'] === grouping
|
974
|
+
className = 'widget-search-results-row-selected'
|
975
|
+
end
|
976
|
+
groupRows << '<div class="widget-search-results-row ' + className + '" title="' + grouping + '" onmouseover="jQuery(\'.widget-search-results-row\').removeClass(\'widget-search-results-row-selected\')" onclick="SelectBoxSetValue(\'' + grouping + '\',\'' + @items['name'] + '\');' + @items['groupByClick'] + '">' + grouping + '</div>'
|
977
|
+
className = ''
|
978
|
+
}
|
979
|
+
|
980
|
+
list_group['search_ahead'] = {
|
981
|
+
'skip_queue' => false,
|
982
|
+
'search_form'=> '
|
983
|
+
<div id="advanced-search-container" style="height:100% !important;">
|
984
|
+
' + groupRows.join("\n") + '
|
985
|
+
</div>',
|
986
|
+
'onclick' => @items['searchOnclick']
|
987
|
+
}
|
988
|
+
if !@templateFill.key?('<!--FILTER_HEADER-->')
|
989
|
+
@templateFill['<!--FILTER_HEADER-->'] = ''
|
990
|
+
end
|
991
|
+
@templateFill['<!--FILTER_HEADER-->'] += '<div class="fake-select"><div class="label">' + @items['groupByLabel'] + ':</div> ' + WidgetList::Widgets::widget_input(list_group) + '</div>'
|
992
|
+
end
|
993
|
+
end
|
994
|
+
end
|
995
|
+
rescue Exception => e
|
996
|
+
out = '<tr><td colspan="50"><div id="noListResults">' + generate_error_output(e) + @items['noDataMessage'] + '</div></td></tr>'
|
997
|
+
if !@templateFill.key?('<!--DATA-->')
|
998
|
+
@templateFill['<!--DATA-->'] = out
|
999
|
+
else
|
1000
|
+
@templateFill['<!--DATA-->'] += out
|
1001
|
+
end
|
1002
|
+
end
|
1003
|
+
|
1004
|
+
return WidgetList::Utils::fill(@templateFill, @items['template'])
|
1005
|
+
|
1006
|
+
end
|
1007
|
+
|
1008
|
+
def build_pagination()
|
1009
|
+
pageRange = 3
|
1010
|
+
pageNext = 1
|
1011
|
+
pagePrev = 1
|
1012
|
+
showPrev = false
|
1013
|
+
showNext = true
|
1014
|
+
prevUrl = ''
|
1015
|
+
nextUrl = ''
|
1016
|
+
tags = ''
|
1017
|
+
urlTags = {}
|
1018
|
+
templates = {}
|
1019
|
+
|
1020
|
+
urlTags['SQL_HASH'] = @sqlHash
|
1021
|
+
urlTags['PAGE_ID'] = @items['pageId']
|
1022
|
+
urlTags['LIST_NAME'] = @items['name']
|
1023
|
+
urlTags['BUTTON_VALUE'] = @items['buttonVal']
|
1024
|
+
urlTags['LIST_FILTER_ALL'] = @items['LIST_FILTER_ALL']
|
1025
|
+
|
1026
|
+
templates['btn_previous'] = @items['template_pagination_previous_disabled']
|
1027
|
+
templates['btn_next'] = @items['template_pagination_next_active']
|
1028
|
+
|
1029
|
+
if $_REQUEST.key?('search_filter') && ! $_REQUEST['search_filter'].empty?
|
1030
|
+
urlTags['search_filter'] = $_REQUEST['search_filter']
|
1031
|
+
end
|
1032
|
+
|
1033
|
+
if @items['LIST_COL_SORT'].empty?
|
1034
|
+
urlTags['LIST_COL_SORT'] = @items['LIST_COL_SORT']
|
1035
|
+
urlTags['LIST_COL_SORT_ORDER'] = @items['LIST_COL_SORT_ORDER']
|
1036
|
+
urlTags['ROW_LIMIT'] = @items['ROW_LIMIT']
|
1037
|
+
end
|
1038
|
+
|
1039
|
+
if @items['links'].key?('paginate') && @items['links']['paginate'].class.name == 'Hash'
|
1040
|
+
@items['links']['paginate'].each { |tagName, tag|
|
1041
|
+
urlTags[tagName] = tag
|
1042
|
+
}
|
1043
|
+
end
|
1044
|
+
|
1045
|
+
if @items.key?('ajax_action') && ! @items['ajax_action'].empty?
|
1046
|
+
urlTags['list_action'] = @items['ajax_action']
|
1047
|
+
end
|
1048
|
+
|
1049
|
+
if (@sequence == @totalPages || ! (@totalPages > 0))
|
1050
|
+
showNext = false
|
1051
|
+
else
|
1052
|
+
urlTags['LIST_SEQUENCE'] = @sequence + 1
|
1053
|
+
nextUrl = WidgetList::Utils::build_url(@items['pageId'],urlTags,(!$_REQUEST.key?('BUTTON_VALUE')))
|
1054
|
+
end
|
1055
|
+
|
1056
|
+
if @sequence > 1
|
1057
|
+
pagePrev = @sequence - 1
|
1058
|
+
urlTags['LIST_SEQUENCE'] = pagePrev
|
1059
|
+
prevUrl = WidgetList::Utils::build_url(@items['pageId'],urlTags,(!$_REQUEST.key?('BUTTON_VALUE')))
|
1060
|
+
showPrev = true
|
1061
|
+
end
|
1062
|
+
|
1063
|
+
if !showNext
|
1064
|
+
templates['btn_next'] = @items['template_pagination_next_disabled']
|
1065
|
+
end
|
1066
|
+
|
1067
|
+
if showPrev
|
1068
|
+
templates['btn_previous'] = @items['template_pagination_previous_active']
|
1069
|
+
end
|
1070
|
+
|
1071
|
+
#Assemble navigation buttons
|
1072
|
+
#
|
1073
|
+
pieces = {
|
1074
|
+
'<!--NEXT_URL-->' => nextUrl,
|
1075
|
+
'<!--LIST_NAME-->' => @items['name'],
|
1076
|
+
'<!--HTTP_SERVER-->' => $_SERVER['rack.url_scheme'] + '://' + $_SERVER['HTTP_HOST'] + '/assets/',
|
1077
|
+
'<!--PREVIOUS_URL-->' => prevUrl,
|
1078
|
+
'<!--FUNCTION-->' => @items['ajax_function']
|
1079
|
+
}
|
1080
|
+
|
1081
|
+
templates['btn_next'] = WidgetList::Utils::fill(pieces,templates['btn_next'])
|
1082
|
+
templates['btn_previous'] = WidgetList::Utils::fill(pieces,templates['btn_previous'])
|
1083
|
+
|
1084
|
+
#
|
1085
|
+
# Sequence Range Drop Down
|
1086
|
+
#
|
1087
|
+
# Show x per page
|
1088
|
+
#
|
1089
|
+
urlTags['LIST_SEQUENCE'] = @sequence
|
1090
|
+
urlTags['ROW_LIMIT'] = 10
|
1091
|
+
|
1092
|
+
# Automate select box and rules
|
1093
|
+
#
|
1094
|
+
rowLimitSelect = [10,20,50,100,500,1000]
|
1095
|
+
rowLimitSelectData = {}
|
1096
|
+
rowLimitSelectConfigs = {}
|
1097
|
+
|
1098
|
+
#Set a default of 10
|
1099
|
+
#
|
1100
|
+
urlTags['ROW_LIMIT'] = 10
|
1101
|
+
options = ''
|
1102
|
+
rowLimitSelect.each_with_index { |jumpCount, key|
|
1103
|
+
if (@totalRows >= jumpCount || @totalRows > rowLimitSelect[key-1])
|
1104
|
+
urlTags['ROW_LIMIT'] = jumpCount
|
1105
|
+
|
1106
|
+
rowLimitUrl = WidgetList::Utils::build_url(@items['pageId'],urlTags,(!$_REQUEST.key?('BUTTON_VALUE')))
|
1107
|
+
selected = ''
|
1108
|
+
if (@items['rowLimit'] == jumpCount)
|
1109
|
+
selected = 'selected'
|
1110
|
+
end
|
1111
|
+
options += "<option value='#{rowLimitUrl}' #{selected}>#{jumpCount}</option> "
|
1112
|
+
end
|
1113
|
+
}
|
1114
|
+
|
1115
|
+
# WidgetSelect( todo)
|
1116
|
+
pageSelect = <<-EOD
|
1117
|
+
<select onchange="#{@items['ajax_function']}(this.value,'#{@items['name']}')" style="width:58px">
|
1118
|
+
#{options}
|
1119
|
+
</select>
|
1120
|
+
EOD
|
1121
|
+
|
1122
|
+
#Ensure the range does not exceed the actual number of pages
|
1123
|
+
#
|
1124
|
+
if @totalPages < pageRange
|
1125
|
+
pageRange = @totalPages
|
1126
|
+
end
|
1127
|
+
|
1128
|
+
###
|
1129
|
+
# Create a range of x or less numbers.
|
1130
|
+
#
|
1131
|
+
# Take 2 off and add 2 or as much as possible either way
|
1132
|
+
###
|
1133
|
+
startingPoint = @sequence
|
1134
|
+
vkill = pageRange
|
1135
|
+
|
1136
|
+
while vkill > 0 do
|
1137
|
+
vkill = vkill - 1
|
1138
|
+
if startingPoint <= 1
|
1139
|
+
break
|
1140
|
+
else
|
1141
|
+
startingPoint = startingPoint-1
|
1142
|
+
end
|
1143
|
+
end
|
1144
|
+
|
1145
|
+
endPoint = @sequence
|
1146
|
+
vkill = pageRange
|
1147
|
+
|
1148
|
+
while vkill > 0 do
|
1149
|
+
vkill = vkill - 1
|
1150
|
+
if endPoint <= 1
|
1151
|
+
endPoint = endPoint+1
|
1152
|
+
else
|
1153
|
+
break
|
1154
|
+
end
|
1155
|
+
end
|
1156
|
+
|
1157
|
+
jumpSection = []
|
1158
|
+
|
1159
|
+
#Builds jump section previous 4 5 6 7 next
|
1160
|
+
#
|
1161
|
+
for page in startingPoint..endPoint
|
1162
|
+
urlTags['LIST_SEQUENCE'] = page
|
1163
|
+
urlTags['SQL_HASH'] = @sqlHash
|
1164
|
+
jumpTemplate = ''
|
1165
|
+
jumpUrl = ''
|
1166
|
+
jumpUrl = WidgetList::Utils::build_url(@items['pageId'], urlTags, (!$_REQUEST.key?('BUTTON_VALUE')))
|
1167
|
+
|
1168
|
+
if page == @sequence
|
1169
|
+
jumpTemplate = @items['template_pagination_jump_active']
|
1170
|
+
else
|
1171
|
+
jumpTemplate = @items['template_pagination_jump_unactive']
|
1172
|
+
end
|
1173
|
+
|
1174
|
+
jumpSection << WidgetList::Utils::fill({'<!--SEQUENCE-->'=>page,'<!--JUMP_URL-->'=>jumpUrl,'<!--LIST_NAME-->'=>@items['name'],'<!--FUNCTION-->'=>@items['ajax_function']}, jumpTemplate)
|
1175
|
+
end
|
1176
|
+
|
1177
|
+
pieces = {
|
1178
|
+
'<!--PREVIOUS_BUTTON-->' => templates['btn_previous'],
|
1179
|
+
'<!--SEQUENCE-->' => @sequence,
|
1180
|
+
'<!--NEXT_BUTTON-->' => templates['btn_next'],
|
1181
|
+
'<!--TOTAL_PAGES-->' => @totalPages,
|
1182
|
+
'<!--TOTAL_ROWS-->' => @totalRows,
|
1183
|
+
'<!--PAGE_SEQUENCE_JUMP_LIST-->' => pageSelect,
|
1184
|
+
'<!--JUMP-->' => jumpSection.join(''),
|
1185
|
+
'<!--LIST_NAME-->' => @items['name'],
|
1186
|
+
}
|
1187
|
+
|
1188
|
+
paginationOutput = WidgetList::Utils::fill(pieces,@items['template_pagination_wrapper'])
|
1189
|
+
|
1190
|
+
if (@items['showPagination'])
|
1191
|
+
return paginationOutput
|
1192
|
+
else
|
1193
|
+
return ''
|
1194
|
+
end
|
1195
|
+
|
1196
|
+
end
|
1197
|
+
|
1198
|
+
def build_headers()
|
1199
|
+
headers = []
|
1200
|
+
@items['fields'].each { |field, fieldTitle|
|
1201
|
+
colWidthStyle = '';
|
1202
|
+
colClass = '';
|
1203
|
+
popupTitle = '';
|
1204
|
+
templateIdx = 'templateNoSortColumn'
|
1205
|
+
|
1206
|
+
#Column class
|
1207
|
+
#
|
1208
|
+
if ! @items['headerClass'].empty?
|
1209
|
+
if @items['headerClass'].key?(field.downcase)
|
1210
|
+
colClass = @items['headerClass'][field.downcase]
|
1211
|
+
end
|
1212
|
+
end
|
1213
|
+
|
1214
|
+
#Column width
|
1215
|
+
#
|
1216
|
+
if ! @items['columnWidth'].empty?
|
1217
|
+
if @items['columnWidth'].key?(field.downcase)
|
1218
|
+
colWidthStyle = "width:" + @items['columnWidth'][field.downcase] + ";"
|
1219
|
+
end
|
1220
|
+
end
|
1221
|
+
|
1222
|
+
$_SESSION.deep_merge!({'LIST_SEQUENCE' => { @sqlHash => @sequence} })
|
1223
|
+
|
1224
|
+
#Hover Title
|
1225
|
+
#
|
1226
|
+
if @items['columnPopupTitle'].key?(field.downcase)
|
1227
|
+
popupTitle = @items['columnPopupTitle'][field.downcase]
|
1228
|
+
end
|
1229
|
+
|
1230
|
+
|
1231
|
+
#
|
1232
|
+
# Column is an input
|
1233
|
+
#
|
1234
|
+
if @items['inputs'].key?(fieldTitle) && @items['inputs'][fieldTitle].class.name == 'Hash'
|
1235
|
+
#
|
1236
|
+
# Default checkbox hover to "Select All"
|
1237
|
+
#
|
1238
|
+
# Do specific input type functions
|
1239
|
+
#
|
1240
|
+
case @items['inputs'][fieldTitle]['type']
|
1241
|
+
when 'checkbox'
|
1242
|
+
|
1243
|
+
if popupTitle.empty? && @items['inputs'][fieldTitle]['items']['check_all']
|
1244
|
+
popupTitle = 'Select All'
|
1245
|
+
end
|
1246
|
+
|
1247
|
+
#
|
1248
|
+
# No sort on this column
|
1249
|
+
#
|
1250
|
+
if ! @items['columnNoSort'].key?(fieldTitle)
|
1251
|
+
@items['columnNoSort'][field] = field
|
1252
|
+
end
|
1253
|
+
|
1254
|
+
if colClass.empty?
|
1255
|
+
@items['headerClass'] = { fieldTitle => 'widgetlist-checkbox-header'}
|
1256
|
+
colClass = @items['headerClass'][fieldTitle]
|
1257
|
+
end
|
1258
|
+
end
|
1259
|
+
|
1260
|
+
#
|
1261
|
+
# Build the input
|
1262
|
+
#
|
1263
|
+
fieldTitle = build_column_input(fieldTitle)
|
1264
|
+
|
1265
|
+
end
|
1266
|
+
|
1267
|
+
if (@items['useSort'] && (@items['columnSort'].include?(field) || (@items['columnSort'].key?(field)) && !@items['columnNoSort'].include?(field)) || (@items['columnSort'].empty? && !@items['columnNoSort'].include?(field)))
|
1268
|
+
|
1269
|
+
templateIdx = 'templateSortColumn'
|
1270
|
+
colSort = {}
|
1271
|
+
|
1272
|
+
#Assign the column to be sorted
|
1273
|
+
#
|
1274
|
+
if !@items['columnSort'].empty? && @items['columnSort'].key?(field)
|
1275
|
+
colSort['LIST_COL_SORT'] = @items['columnSort'][field]
|
1276
|
+
elsif (!@items['columnSort'].empty? && @items['columnSort'].include?(field)) || @items['columnSort'].empty?
|
1277
|
+
colSort['LIST_COL_SORT'] = field
|
1278
|
+
end
|
1279
|
+
|
1280
|
+
colSort['PAGE_ID'] = @items['pageId']
|
1281
|
+
colSort['LIST_NAME'] = @items['name']
|
1282
|
+
colSort['BUTTON_VALUE'] = @items['buttonVal']
|
1283
|
+
colSort['LIST_COL_SORT_ORDER'] = @listSortNext
|
1284
|
+
colSort['LIST_FILTER_ALL'] = @items['LIST_FILTER_ALL']
|
1285
|
+
colSort['ROW_LIMIT'] = @items['ROW_LIMIT']
|
1286
|
+
colSort['LIST_SEQUENCE'] = @sequence
|
1287
|
+
|
1288
|
+
icon = ""
|
1289
|
+
|
1290
|
+
if (
|
1291
|
+
( (@items.key?('LIST_COL_SORT') && !@items['LIST_COL_SORT'].empty?) && @items['LIST_COL_SORT'] == colSort['LIST_COL_SORT']) ||
|
1292
|
+
( $_SESSION.key?('LIST_COL_SORT') && $_SESSION['LIST_COL_SORT'].key?(@sqlHash) && $_SESSION['LIST_COL_SORT'][@sqlHash].key?(field))
|
1293
|
+
)
|
1294
|
+
changedSession = false
|
1295
|
+
if @items.key?('LIST_COL_SORT') && !@items['LIST_COL_SORT'].empty?
|
1296
|
+
changedSession = ( $_SESSION.key?('LIST_COL_SORT') && $_SESSION['LIST_COL_SORT'].key?(@sqlHash) && ! $_SESSION['LIST_COL_SORT'][@sqlHash].key?(@items['LIST_COL_SORT']) )
|
1297
|
+
if $_SESSION.key?('LIST_COL_SORT') && $_SESSION['LIST_COL_SORT'].key?(@sqlHash)
|
1298
|
+
$_SESSION['LIST_COL_SORT'].delete(@sqlHash)
|
1299
|
+
end
|
1300
|
+
$_SESSION.deep_merge!({'LIST_COL_SORT' => { @sqlHash => {@items['LIST_COL_SORT']=> @items['LIST_COL_SORT_ORDER'] } } })
|
1301
|
+
end
|
1302
|
+
|
1303
|
+
if !changedSession && @items.key?('LIST_COL_SORT') && ! @items['LIST_COL_SORT'].empty?
|
1304
|
+
if @items['LIST_COL_SORT_ORDER'] == 'DESC'
|
1305
|
+
icon = "↑"
|
1306
|
+
else
|
1307
|
+
icon = "↓"
|
1308
|
+
end
|
1309
|
+
elsif !changedSession && $_SESSION['LIST_COL_SORT'].class.name == 'Hash' && $_SESSION['LIST_COL_SORT'].key?(@sqlHash)
|
1310
|
+
#load sort from session
|
1311
|
+
$_SESSION['LIST_COL_SORT'][@sqlHash].each_with_index { |order,void|
|
1312
|
+
if order[1] == 'DESC'
|
1313
|
+
colSort['LIST_COL_SORT_ORDER'] = "ASC"
|
1314
|
+
icon = "↑"
|
1315
|
+
else
|
1316
|
+
colSort['LIST_COL_SORT_ORDER'] = "DESC"
|
1317
|
+
icon = "↓"
|
1318
|
+
end
|
1319
|
+
}
|
1320
|
+
end
|
1321
|
+
end
|
1322
|
+
|
1323
|
+
#Carry over any search criteria on a sort to SORT URL
|
1324
|
+
#
|
1325
|
+
if $_REQUEST.key?('search_filter') && ! $_REQUEST['search_filter'].empty?
|
1326
|
+
if $_REQUEST['search_filter'].empty?
|
1327
|
+
colSort['search_filter'] = $_REQUEST['search_filter']
|
1328
|
+
end
|
1329
|
+
end
|
1330
|
+
|
1331
|
+
if @items.key?('ajax_action') && ! @items['ajax_action'].empty?
|
1332
|
+
colSort['list_action'] = @items['ajax_action']
|
1333
|
+
end
|
1334
|
+
colSort['SQL_HASH'] = @sqlHash
|
1335
|
+
|
1336
|
+
pieces = { '<!--COLSORTURL-->' => WidgetList::Utils::build_url(@items['pageId'],colSort,(!$_REQUEST.key?('BUTTON_VALUE'))),
|
1337
|
+
'<!--NAME-->' => @items['name'],
|
1338
|
+
'<!--COLSORTICON->' => icon,
|
1339
|
+
'<!--COL_HEADER_ID-->' => strip_tags(field).gsub(/\s/,'_'),
|
1340
|
+
'<!--INLINE_STYLE-->' => colWidthStyle,
|
1341
|
+
'<!--TITLE_POPUP-->' => popupTitle,
|
1342
|
+
'<!--COL_HEADER_CLASS-->' => colClass,
|
1343
|
+
'<!--TITLE-->' => fieldTitle,
|
1344
|
+
'<!--FUNCTION-->' => @items['ajax_function']
|
1345
|
+
}
|
1346
|
+
headers << WidgetList::Utils::fill(pieces, @items[templateIdx])
|
1347
|
+
else
|
1348
|
+
pieces = { '<!--TITLE-->' => fieldTitle,
|
1349
|
+
'<!--INLINE_STYLE-->' => colWidthStyle,
|
1350
|
+
'<!--TITLE_POPUP-->' => popupTitle,
|
1351
|
+
'<!--COL_HEADER_CLASS-->' => colClass,
|
1352
|
+
'<!--COL_HEADER_ID-->' => strip_tags(field).gsub(/\s/,'_')
|
1353
|
+
}
|
1354
|
+
|
1355
|
+
headers << WidgetList::Utils::fill(pieces, @items[templateIdx])
|
1356
|
+
end
|
1357
|
+
}
|
1358
|
+
|
1359
|
+
@templateFill['<!--COLSPAN_FULL-->'] = headers.count()
|
1360
|
+
|
1361
|
+
if @items['mode'] != 'passive'
|
1362
|
+
pieces = {'<!--LIST_SEQUENCE-->' => @sequence,
|
1363
|
+
'<!--TOTAL_PAGES-->' => @totalPages}
|
1364
|
+
|
1365
|
+
@templateFill['<!--PAGE_SEQUENCE_DISPLAY-->'] = WidgetList::Utils::fill(pieces, @items['templateSequence'])
|
1366
|
+
end
|
1367
|
+
|
1368
|
+
@templateFill['<!--PAGINATION_LIST-->'] = build_pagination()
|
1369
|
+
@templateFill['<!--HEADERS-->'] = headers.join('')
|
1370
|
+
|
1371
|
+
if ! @items['listDescription'].empty?
|
1372
|
+
fillDesc = {}
|
1373
|
+
fillDesc['<!--COLSPAN-->'] = headers.count()
|
1374
|
+
fillDesc['<!--LIST_DESCRIPTION-->'] = @items['listDescription']
|
1375
|
+
fillDesc['<!--LIST_NAME-->'] = @items['name']
|
1376
|
+
@templateFill['<!--LIST_TITLE-->'] = WidgetList::Utils::fill(fillDesc,@items['list_description'])
|
1377
|
+
else
|
1378
|
+
@templateFill['<!--LIST_TITLE-->'] = ''
|
1379
|
+
end
|
1380
|
+
|
1381
|
+
end
|
1382
|
+
|
1383
|
+
# @param [String] column (the name)
|
1384
|
+
# @param [Fixnum] row (the id or pointer in the loop to fetch the data)
|
1385
|
+
def build_column_input(column, row='')
|
1386
|
+
content = ''
|
1387
|
+
|
1388
|
+
inputManager = @items['inputs'][column]
|
1389
|
+
case inputManager['type']
|
1390
|
+
when "checkbox"
|
1391
|
+
|
1392
|
+
|
1393
|
+
input = {}
|
1394
|
+
input['name'] = 'widget_check_name'
|
1395
|
+
input['id'] = 'widget_check_id'
|
1396
|
+
input['check_all'] = false
|
1397
|
+
input['value'] = ''
|
1398
|
+
input['checked'] = ''
|
1399
|
+
input['onclick'] = ''
|
1400
|
+
input['input_class'] = 'widgetlist-checkbox-input'
|
1401
|
+
|
1402
|
+
input['class_handle'] = ''
|
1403
|
+
|
1404
|
+
input = WidgetList::Widgets::populate_items(inputManager['items'],input)
|
1405
|
+
|
1406
|
+
onClick = []
|
1407
|
+
checkAllId = ''
|
1408
|
+
|
1409
|
+
#
|
1410
|
+
# Get a value. Assumes it is a column initially.
|
1411
|
+
#
|
1412
|
+
# @note headers are ignored and would fail as row would be null
|
1413
|
+
#
|
1414
|
+
if @results.key?(input['value'].upcase) && !@results[input['value'].upcase][row].to_s.empty?
|
1415
|
+
input['value'] = @results[ input['value'].upcase ][row]
|
1416
|
+
end
|
1417
|
+
|
1418
|
+
#
|
1419
|
+
# Append class handle
|
1420
|
+
#
|
1421
|
+
input['input_class'] = "#{input['input_class']} #{input['class_handle']}"
|
1422
|
+
|
1423
|
+
if input['check_all']
|
1424
|
+
checkAllId = input['id']
|
1425
|
+
if $_SESSION.key?('list_checks') && $_SESSION['list_checks'].key?('check_all_' + @sqlHash.to_s + @items['name'].to_s + @sequence.to_s)
|
1426
|
+
input['checked'] = true
|
1427
|
+
end
|
1428
|
+
|
1429
|
+
#
|
1430
|
+
# Set header class
|
1431
|
+
#
|
1432
|
+
if @items['headerClass'].class.name == 'Array' && @items['headerClass'].key?('checkbox')
|
1433
|
+
if $_SESSION['list_checks'].key?('check_all_' + @sqlHash.to_s + @items['name'].to_s + @sequence.to_s)
|
1434
|
+
input['checked'] = true
|
1435
|
+
end
|
1436
|
+
end
|
1437
|
+
else
|
1438
|
+
input['input_class'] = "#{input['input_class']} #{input['class_handle']} #{input['class_handle']}_list"
|
1439
|
+
end
|
1440
|
+
|
1441
|
+
#
|
1442
|
+
# Setup onclick action
|
1443
|
+
#
|
1444
|
+
if input['onclick'].empty?
|
1445
|
+
listJumpUrl = {}
|
1446
|
+
listJumpUrl['BUTTON_VALUE'] = @items['buttonVal']
|
1447
|
+
listJumpUrl['LIST_COL_SORT'] = @items['LIST_COL_SORT']
|
1448
|
+
listJumpUrl['LIST_COL_SORT_ORDER'] = @items['LIST_COL_SORT_ORDER']
|
1449
|
+
listJumpUrl['LIST_FILTER_ALL'] = @items['LIST_FILTER_ALL']
|
1450
|
+
listJumpUrl['ROW_LIMIT'] = @items['ROW_LIMIT']
|
1451
|
+
listJumpUrl['LIST_SEQUENCE'] = @sequence
|
1452
|
+
listJumpUrl['LIST_NAME'] = @items['name']
|
1453
|
+
listJumpUrl['SQL_HASH'] = @sqlHash
|
1454
|
+
listJumpUrl['list_action'] = 'ajax_widgetlist_checks'
|
1455
|
+
|
1456
|
+
onClick << "AjaxMaintainChecks(this, '#{input['class_handle']}', '#{@items['name']}', '" + WidgetList::Utils::build_url(@items['pageId'],listJumpUrl,(!$_REQUEST.key?('BUTTON_VALUE'))) + "', '#{checkAllId}');"
|
1457
|
+
end
|
1458
|
+
|
1459
|
+
input['onclick'] = onClick.join(' ')
|
1460
|
+
|
1461
|
+
#
|
1462
|
+
# Checkbox is checked or not per query value
|
1463
|
+
#
|
1464
|
+
if ! @items['checked_flag'].empty?
|
1465
|
+
if @items['checked_flag'].key?(column)
|
1466
|
+
input['checked'] = !!@results[ @items['checked_flag'][column].upcase ][row]
|
1467
|
+
end
|
1468
|
+
end
|
1469
|
+
|
1470
|
+
#
|
1471
|
+
# Checkbox is checked or not per session (overwrites query)
|
1472
|
+
#
|
1473
|
+
if $_SESSION.key?('list_checks') && $_SESSION['list_checks'].key?(@items['name'] + @sqlHash + input['value'].to_s)
|
1474
|
+
input['checked'] = true
|
1475
|
+
end
|
1476
|
+
|
1477
|
+
content = WidgetList::Widgets::widget_check(input)
|
1478
|
+
|
1479
|
+
#todo never implemented
|
1480
|
+
|
1481
|
+
when "text"
|
1482
|
+
a=1
|
1483
|
+
#content = WidgetInput()
|
1484
|
+
|
1485
|
+
when "select"
|
1486
|
+
a=1
|
1487
|
+
#content = WidgetSelect()
|
1488
|
+
|
1489
|
+
end
|
1490
|
+
|
1491
|
+
return content
|
1492
|
+
end
|
1493
|
+
|
1494
|
+
def build_column_button(column,j)
|
1495
|
+
buttons = @items['buttons'][column]
|
1496
|
+
columnValue = @results[column.upcase][j]
|
1497
|
+
btnOut = []
|
1498
|
+
strCnt = 0
|
1499
|
+
nameId = ''
|
1500
|
+
|
1501
|
+
buttons.each { |buttonId,buttonAttribs|
|
1502
|
+
#url = array('PAGE_ID')
|
1503
|
+
function = @items['linkFunction']
|
1504
|
+
parameters = ''
|
1505
|
+
renderButton = true
|
1506
|
+
|
1507
|
+
if buttonAttribs.key?('tags')
|
1508
|
+
buttonAttribs['tags'].each { | tagName , tag |
|
1509
|
+
#only uppercase will be replaced
|
1510
|
+
#
|
1511
|
+
|
1512
|
+
if @results.key?(tag.upcase) && @results[tag.upcase][j]
|
1513
|
+
|
1514
|
+
buttonAttribs.deep_merge!({'args' =>
|
1515
|
+
{
|
1516
|
+
tagName => @results[tag.upcase][j]
|
1517
|
+
}
|
1518
|
+
})
|
1519
|
+
else
|
1520
|
+
buttonAttribs.deep_merge!({'args' =>
|
1521
|
+
{
|
1522
|
+
tagName => tag
|
1523
|
+
}
|
1524
|
+
})
|
1525
|
+
end
|
1526
|
+
}
|
1527
|
+
end
|
1528
|
+
nameId = buttonId.to_s + '_' + j.to_s
|
1529
|
+
|
1530
|
+
buttonAttribs['name'] = nameId
|
1531
|
+
buttonAttribs['id'] = nameId
|
1532
|
+
|
1533
|
+
#if buttonAttribs.key?('condition')
|
1534
|
+
#never show button if you pass a condition unless explicitly matching the value of the features
|
1535
|
+
#
|
1536
|
+
#renderButton = false
|
1537
|
+
#allConditions = columnValue.split(':')
|
1538
|
+
#if (in_array(ltrim($buttonAttribs['condition'], ':'), $allConditions))
|
1539
|
+
# renderButton = true
|
1540
|
+
#end
|
1541
|
+
#end
|
1542
|
+
|
1543
|
+
if (renderButton)
|
1544
|
+
strCnt += (buttonAttribs['text'].length * 15)
|
1545
|
+
btnOut << WidgetList::Widgets::widget_button(buttonAttribs['text'], buttonAttribs, true)
|
1546
|
+
end
|
1547
|
+
}
|
1548
|
+
|
1549
|
+
#BS width algorithm. HACK/TWEAK/OMG Get it working.
|
1550
|
+
#
|
1551
|
+
colWidth = ((strCnt + (btnOut.count * 35)) / 2) + 10
|
1552
|
+
|
1553
|
+
return '<div style="border:0px solid black;text-align:center;white-space:nowrap;margin:auto;width:' + colWidth.to_s + 'px"><div style="margin:auto;display:inline-block">' + btnOut.join('') + '</div></div>'
|
1554
|
+
end
|
1555
|
+
|
1556
|
+
# @param [String] column
|
1557
|
+
def build_column_link(column,j)
|
1558
|
+
|
1559
|
+
links = @items['links'][column]
|
1560
|
+
url = {'PAGE_ID' => @items['pageId']}
|
1561
|
+
function = @items['linkFunction']
|
1562
|
+
parameters = ''
|
1563
|
+
|
1564
|
+
if links.key?('PAGE_ID') && ! links['PAGE_ID'].empty?
|
1565
|
+
url['PAGE_ID'] = links['PAGE_ID']
|
1566
|
+
end
|
1567
|
+
|
1568
|
+
if links.key?('ACTION') && ! links['ACTION'].empty?
|
1569
|
+
url['list_action'] = links['ACTION']
|
1570
|
+
end
|
1571
|
+
|
1572
|
+
if links.key?('BUTTON_VALUE') && ! links['BUTTON_VALUE'].empty?
|
1573
|
+
url['BUTTON_VALUE'] = links['BUTTON_VALUE']
|
1574
|
+
end
|
1575
|
+
|
1576
|
+
#todo unit test this and all of column links
|
1577
|
+
if links.key?('tags')
|
1578
|
+
links['tags'].each { | tagName, tag |
|
1579
|
+
if @results[tag][j]
|
1580
|
+
url[tagName] = @results[tag][j]
|
1581
|
+
else
|
1582
|
+
url[tagName] = tag
|
1583
|
+
end
|
1584
|
+
}
|
1585
|
+
end
|
1586
|
+
|
1587
|
+
if links.key?('onclick') && links['onclick'].class.name == 'Hash'
|
1588
|
+
if links['onclick'].key?('function') && !links['onclick']['function'].empty?
|
1589
|
+
function = links['onclick']['function']
|
1590
|
+
end
|
1591
|
+
|
1592
|
+
if links['onclick'].key?('tags') && !links['onclick']['tags'].empty?
|
1593
|
+
links['onclick']['tags'].each { | tagName , tag|
|
1594
|
+
if @results.key?(tag.upcase)
|
1595
|
+
parameters = ", '" + @results[tag.upcase][j] + "'"
|
1596
|
+
end
|
1597
|
+
}
|
1598
|
+
end
|
1599
|
+
end
|
1600
|
+
|
1601
|
+
if @items.key?('ajax_action') && !@items['ajax_action'].empty?
|
1602
|
+
url['list_action'] = @items['ajax_action']
|
1603
|
+
end
|
1604
|
+
|
1605
|
+
url['SQL_HASH'] = @sqlHash
|
1606
|
+
linkUrl = WidgetList::Utils::build_url(@items['pageId'],(!$_REQUEST.key?('BUTTON_VALUE')))
|
1607
|
+
|
1608
|
+
"#{function}('#{linkUrl}'#{parameters})"
|
1609
|
+
end
|
1610
|
+
|
1611
|
+
def build_rows()
|
1612
|
+
sql = build_statement()
|
1613
|
+
if @totalResultCount > 0
|
1614
|
+
if @items['data'].empty?
|
1615
|
+
#Run the actual statement
|
1616
|
+
#
|
1617
|
+
@totalRowCount = WidgetList::List.get_database._select(sql, @items['bindVars'], @items['bindVarsLegacy'])
|
1618
|
+
end
|
1619
|
+
|
1620
|
+
if @totalRowCount > 0
|
1621
|
+
if @items['data'].empty?
|
1622
|
+
@results = WidgetList::List.get_database.final_results
|
1623
|
+
else
|
1624
|
+
@results = @items['data']
|
1625
|
+
end
|
1626
|
+
|
1627
|
+
#Build each row
|
1628
|
+
#
|
1629
|
+
max = @totalRowCount-1
|
1630
|
+
rows = []
|
1631
|
+
j = 0
|
1632
|
+
for j in j..max
|
1633
|
+
columns = []
|
1634
|
+
customRowColor = ''
|
1635
|
+
customRowStyle = ''
|
1636
|
+
|
1637
|
+
#
|
1638
|
+
# For each column (field) in this row
|
1639
|
+
#
|
1640
|
+
|
1641
|
+
@items['fields'].each { |column , fieldTitle|
|
1642
|
+
colPieces = {}
|
1643
|
+
colClasses = []
|
1644
|
+
theStyle = ''
|
1645
|
+
colData = ''
|
1646
|
+
colClass = ''
|
1647
|
+
onClick = ''
|
1648
|
+
colWidthStyle = ''
|
1649
|
+
content = ''
|
1650
|
+
contentTitle = ''
|
1651
|
+
|
1652
|
+
|
1653
|
+
|
1654
|
+
#todo unit test build_column_link
|
1655
|
+
|
1656
|
+
#
|
1657
|
+
# Column is a Link
|
1658
|
+
#
|
1659
|
+
if @items['links'].key?(column) && @items['links'][column].class.name == 'Hash'
|
1660
|
+
onClick = build_column_link(column,j)
|
1661
|
+
|
1662
|
+
#
|
1663
|
+
# Column is a Button
|
1664
|
+
#
|
1665
|
+
elsif @items['buttons'].key?(column) && @items['buttons'][column].class.name == 'Hash'
|
1666
|
+
content = build_column_button(column, j)
|
1667
|
+
|
1668
|
+
|
1669
|
+
#
|
1670
|
+
# Column is an input
|
1671
|
+
#
|
1672
|
+
elsif @items['inputs'].key?(column) && @items['inputs'][column].class.name == 'Hash'
|
1673
|
+
colClasses << @items['checked_class']
|
1674
|
+
content = build_column_input(column, j)
|
1675
|
+
|
1676
|
+
|
1677
|
+
#
|
1678
|
+
# Column is text
|
1679
|
+
#
|
1680
|
+
else
|
1681
|
+
cleanData = strip_tags(@results[column.upcase][j].to_s)
|
1682
|
+
|
1683
|
+
if cleanData.length > @items['strlength']
|
1684
|
+
=begin
|
1685
|
+
$contentTitle = $cleanData;
|
1686
|
+
|
1687
|
+
$possibleMatches = array("/(.*)(\(<a.*?>.*?<\/a>\)\s)(.*)/i" => array(3), #<a>(id)</a> Text
|
1688
|
+
"/(.*)(<a.*?>)(.*)(<\/a>)(.*)/i" => array(3) #<a>Text</a> other text
|
1689
|
+
);
|
1690
|
+
|
1691
|
+
foreach($possibleMatches as $regex => $toFix)
|
1692
|
+
{
|
1693
|
+
$matched = preg_match_all($regex, @results[strtoupper($column)][$j], $matches, PREG_PATTERN_ORDER);
|
1694
|
+
|
1695
|
+
if(! empty($matched))
|
1696
|
+
{
|
1697
|
+
$pieces = {};
|
1698
|
+
|
1699
|
+
unset($matches[0]);
|
1700
|
+
|
1701
|
+
foreach($matches as $key => $theText)
|
1702
|
+
{
|
1703
|
+
$fixedText = '';
|
1704
|
+
|
1705
|
+
if(in_array($key, $toFix))
|
1706
|
+
{
|
1707
|
+
$fixedText = substr($theText[0], 0, @items['strlength']) . '...';
|
1708
|
+
}
|
1709
|
+
else
|
1710
|
+
{
|
1711
|
+
$fixedText = $theText[0];
|
1712
|
+
}
|
1713
|
+
|
1714
|
+
$pieces[] = $fixedText;
|
1715
|
+
}
|
1716
|
+
|
1717
|
+
$content = implode('', $pieces);
|
1718
|
+
|
1719
|
+
break;
|
1720
|
+
}
|
1721
|
+
}
|
1722
|
+
|
1723
|
+
if(empty($matched))
|
1724
|
+
{
|
1725
|
+
if ((strpos(@results[strtoupper($column)][$j],'&#') !== false && strpos(@results[strtoupper($column)][$j],';') !== false))
|
1726
|
+
{
|
1727
|
+
$content = @results[strtoupper($column)][$j];
|
1728
|
+
}
|
1729
|
+
else
|
1730
|
+
{
|
1731
|
+
$content = substr(@results[strtoupper($column)][$j], 0, @items['strlength']) . '...';
|
1732
|
+
}
|
1733
|
+
}
|
1734
|
+
=end
|
1735
|
+
content = @results[column.upcase][j].to_s[ 0, @items['strlength'] ] + '...'
|
1736
|
+
|
1737
|
+
else
|
1738
|
+
content = @results[column.upcase][j].to_s
|
1739
|
+
end
|
1740
|
+
|
1741
|
+
#Strip HTML
|
1742
|
+
#
|
1743
|
+
if !@items['allowHTML']
|
1744
|
+
content = strip_tags(content)
|
1745
|
+
end
|
1746
|
+
content = WidgetList::List.get_database._bind(content, @items['bindVarsLegacy'])
|
1747
|
+
|
1748
|
+
# Column color
|
1749
|
+
#
|
1750
|
+
if ! @items['columnStyle'].empty?
|
1751
|
+
if @items['columnStyle'].key?(column.downcase)
|
1752
|
+
colHeader = @items['columnStyle'][column.downcase]
|
1753
|
+
|
1754
|
+
if @results.key?(colHeader.upcase)
|
1755
|
+
theStyle = @results[colHeader.upcase][j]
|
1756
|
+
else
|
1757
|
+
theStyle = colHeader
|
1758
|
+
end
|
1759
|
+
|
1760
|
+
end
|
1761
|
+
end
|
1762
|
+
|
1763
|
+
# Column width
|
1764
|
+
#
|
1765
|
+
if ! @items['columnWidth'].empty?
|
1766
|
+
if @items['columnWidth'].key?(column.downcase)
|
1767
|
+
colWidthStyle = "width:" + @items['columnWidth'][column.downcase] + ";"
|
1768
|
+
end
|
1769
|
+
end
|
1770
|
+
|
1771
|
+
# Column Class
|
1772
|
+
#
|
1773
|
+
if !@items['columnClass'].empty?
|
1774
|
+
if @items['columnClass'].key?(column.downcase)
|
1775
|
+
colClasses << @items['columnClass'][column.downcase]
|
1776
|
+
end
|
1777
|
+
end
|
1778
|
+
|
1779
|
+
end
|
1780
|
+
|
1781
|
+
|
1782
|
+
#
|
1783
|
+
# Setup any column classes
|
1784
|
+
#
|
1785
|
+
colClasses << @items['collClass']
|
1786
|
+
colClass = colClasses.join(' ')
|
1787
|
+
|
1788
|
+
#
|
1789
|
+
# Row Color
|
1790
|
+
#
|
1791
|
+
if !@items['rowColorByStatus'].empty? && @items['rowColorByStatus'].key?(column) && !@items['rowColorByStatus'][column].empty?
|
1792
|
+
@items['rowColorByStatus'][column].each { |status,color|
|
1793
|
+
if status === content
|
1794
|
+
customRowColor = color
|
1795
|
+
end
|
1796
|
+
}
|
1797
|
+
end
|
1798
|
+
|
1799
|
+
#
|
1800
|
+
# Row Style
|
1801
|
+
#
|
1802
|
+
if !@items['rowStylesByStatus'].empty? && @items['rowStylesByStatus'].key?(column) && !@items['rowStylesByStatus'][column].empty?
|
1803
|
+
@items['rowStylesByStatus'][column].each { |status,inlineStyle|
|
1804
|
+
if status === content
|
1805
|
+
customRowStyle = color
|
1806
|
+
end
|
1807
|
+
}
|
1808
|
+
end
|
1809
|
+
|
1810
|
+
#
|
1811
|
+
# Set up Column Pieces
|
1812
|
+
#
|
1813
|
+
colPieces['<!--CLASS-->'] = colClass
|
1814
|
+
colPieces['<!--ALIGN-->'] = @items['collAlign']
|
1815
|
+
colPieces['<!--STYLE-->'] = theStyle + colWidthStyle
|
1816
|
+
colPieces['<!--ONCLICK-->'] = onClick
|
1817
|
+
colPieces['<!--TITLE-->'] = contentTitle #todo htmlentities needed ?
|
1818
|
+
colPieces['<!--CONTENT-->'] = content
|
1819
|
+
#
|
1820
|
+
# Assemble the Column
|
1821
|
+
#
|
1822
|
+
columns << WidgetList::Utils::fill(colPieces, @items['col'])
|
1823
|
+
|
1824
|
+
}
|
1825
|
+
|
1826
|
+
#Draw the row
|
1827
|
+
#
|
1828
|
+
|
1829
|
+
pieces = {'<!--CONTENT-->' => columns.join('') }
|
1830
|
+
if @items['rowColorByStatus'].empty? && @items['rowStylesByStatus'].empty?
|
1831
|
+
#Set the row color
|
1832
|
+
#
|
1833
|
+
rowColor = @items['rowColor']
|
1834
|
+
|
1835
|
+
if @items['offsetRows']
|
1836
|
+
if( j % 2 ==0)
|
1837
|
+
rowColor = @items['rowOffsets'][1]
|
1838
|
+
else
|
1839
|
+
rowColor = @items['rowOffsets'][0]
|
1840
|
+
end
|
1841
|
+
end
|
1842
|
+
|
1843
|
+
#Draw default color
|
1844
|
+
#
|
1845
|
+
pieces['<!--BGCOLOR-->'] = rowColor
|
1846
|
+
pieces['<!--ROWSTYLE-->'] = ''
|
1847
|
+
pieces['<!--ROWCLASS-->'] = @items['rowClass']
|
1848
|
+
else
|
1849
|
+
pieces['<!--BGCOLOR-->'] = !customRowColor.empty? ? customRowColor : @items['rowColor']
|
1850
|
+
pieces['<!--ROWSTYLE-->'] = customRowStyle.empty? ? customRowStyle : ''
|
1851
|
+
pieces['<!--ROWCLASS-->'] = @items['rowClass']
|
1852
|
+
end
|
1853
|
+
rows << WidgetList::Utils::fill(pieces, @items['row'])
|
1854
|
+
|
1855
|
+
end
|
1856
|
+
|
1857
|
+
@templateFill['<!--DATA-->'] = rows.join('')
|
1858
|
+
|
1859
|
+
else
|
1860
|
+
@templateFill['<!--DATA-->'] = '<tr><td colspan="50"><div id="noListResults">' + generate_error_output() + @items['noDataMessage'] + '</div></td></tr>'
|
1861
|
+
end
|
1862
|
+
|
1863
|
+
else
|
1864
|
+
@templateFill['<!--DATA-->'] = '<tr><td colspan="50"><div id="noListResults">' + generate_error_output() + @items['noDataMessage'] + '</div></td></tr>'
|
1865
|
+
end
|
1866
|
+
|
1867
|
+
end
|
1868
|
+
|
1869
|
+
def generate_error_output(ex='')
|
1870
|
+
sqlDebug = ""
|
1871
|
+
if Rails.env == 'development'
|
1872
|
+
sqlDebug += "<br/><br/><textarea style='width:100%;height:400px;'>" + WidgetList::List.get_database.last_sql.to_s + "</textarea>"
|
1873
|
+
end
|
1874
|
+
|
1875
|
+
if Rails.env == 'development' && WidgetList::List.get_database.errors
|
1876
|
+
sqlDebug += "<br/><br/><strong style='color:red'>(" + WidgetList::List.get_database.last_error.to_s + ")</strong>"
|
1877
|
+
end
|
1878
|
+
|
1879
|
+
if Rails.env == 'development' && ex != ''
|
1880
|
+
sqlDebug += "<br/><br/><strong style='color:red'>(" + ex.to_s + ") <pre>" + $!.backtrace.join("\n\n") + "</pre></strong>"
|
1881
|
+
end
|
1882
|
+
|
1883
|
+
sqlDebug
|
1884
|
+
end
|
1885
|
+
|
1886
|
+
def build_statement()
|
1887
|
+
statement = ''
|
1888
|
+
pieces = { '<!--FIELDS-->' => '',
|
1889
|
+
'<!--SOURCE-->' => '',
|
1890
|
+
'<!--WHERE-->' => '',
|
1891
|
+
'<!--GROUPBY-->' => '',
|
1892
|
+
'<!--ORDERBY-->' => '',
|
1893
|
+
'<!--LIMIT-->' => ''}
|
1894
|
+
|
1895
|
+
if !@items['sql'].empty? || !@items['force_query_sql'].empty?
|
1896
|
+
if !@items['fieldNames'].empty?
|
1897
|
+
@items['fieldNames'].each { |column|
|
1898
|
+
tick = '`'
|
1899
|
+
if(isset(@items['function'][column]))
|
1900
|
+
tick = ''
|
1901
|
+
column = @items['function'][column]
|
1902
|
+
end
|
1903
|
+
@fieldList << "#{tick}#{column}#{tick}"
|
1904
|
+
}
|
1905
|
+
fields = @fieldList.join(',')
|
1906
|
+
|
1907
|
+
|
1908
|
+
else
|
1909
|
+
fields = "*";
|
1910
|
+
end
|
1911
|
+
|
1912
|
+
|
1913
|
+
sqlPieces = {};
|
1914
|
+
sqlPieces['<!--FIELDS-->'] = fields;
|
1915
|
+
sqlPieces['<!--SQL-->'] = @items['sql'];
|
1916
|
+
|
1917
|
+
if !@items['force_query_sql'].empty?
|
1918
|
+
statement = @items['force_query_sql']
|
1919
|
+
else
|
1920
|
+
statement = @items['statement']['select']['sql']
|
1921
|
+
end
|
1922
|
+
|
1923
|
+
statement = WidgetList::Utils::fill(sqlPieces, @items['statement']['count']['table'])
|
1924
|
+
|
1925
|
+
elsif !@items['view'].empty?
|
1926
|
+
#Build out a list of columns to select from
|
1927
|
+
#
|
1928
|
+
@items['fields'].each { |column, fieldTitle|
|
1929
|
+
if @items['function'].key?(column) && !@items['function'][column].empty?
|
1930
|
+
column = @items['function'][column]
|
1931
|
+
end
|
1932
|
+
|
1933
|
+
@fieldList << column
|
1934
|
+
}
|
1935
|
+
|
1936
|
+
#Add any columns without corresponding header titles
|
1937
|
+
#
|
1938
|
+
@items['columns'].each { |column|
|
1939
|
+
@fieldList << column
|
1940
|
+
}
|
1941
|
+
|
1942
|
+
viewPieces = {}
|
1943
|
+
viewPieces['<!--FIELDS-->'] = @fieldList.join(',')
|
1944
|
+
viewPieces['<!--SOURCE-->'] = @items['view']
|
1945
|
+
|
1946
|
+
statement = WidgetList::Utils::fill(viewPieces, @items['statement']['select']['view'])
|
1947
|
+
end
|
1948
|
+
|
1949
|
+
@sqlHash = Digest::SHA2.hexdigest( WidgetList::Utils::fill(pieces, statement) )
|
1950
|
+
|
1951
|
+
if @items['searchClear'] || @items['searchClearAll']
|
1952
|
+
clear_sql_session(@items.key?('searchClearAll'))
|
1953
|
+
end
|
1954
|
+
|
1955
|
+
if !$_REQUEST.key?('BUTTON_VALUE') && $_SESSION.key?('LIST_SEQUENCE') && $_SESSION['LIST_SEQUENCE'].key?(@sqlHash) && $_SESSION['LIST_SEQUENCE'][@sqlHash] > 0
|
1956
|
+
@sequence = $_SESSION['LIST_SEQUENCE'][@sqlHash]
|
1957
|
+
generate_limits
|
1958
|
+
end
|
1959
|
+
|
1960
|
+
if !@filter.empty?
|
1961
|
+
where = ' WHERE '
|
1962
|
+
pieces['<!--WHERE-->'] = where + @filter
|
1963
|
+
end
|
1964
|
+
|
1965
|
+
if !@items['groupBy'].empty?
|
1966
|
+
pieces['<!--GROUPBY-->'] += ' GROUP BY ' + @items['groupBy']
|
1967
|
+
end
|
1968
|
+
|
1969
|
+
if !@items['LIST_COL_SORT'].empty? || $_SESSION.key?('LIST_COL_SORT') && $_SESSION['LIST_COL_SORT'].class.name == 'Hash' && $_SESSION['LIST_COL_SORT'].key?(@sqlHash)
|
1970
|
+
if ! @items['LIST_COL_SORT'].empty?
|
1971
|
+
pieces['<!--ORDERBY-->'] += ' ORDER BY `' + @items['LIST_COL_SORT'] + "` " + @items['LIST_COL_SORT_ORDER']
|
1972
|
+
else
|
1973
|
+
$_SESSION['LIST_COL_SORT'][@sqlHash].each_with_index { |order,void|
|
1974
|
+
pieces['<!--ORDERBY-->'] += ' ORDER BY `' + order[0] + "` " + order[1]
|
1975
|
+
} if $_SESSION.key?('LIST_COL_SORT') && $_SESSION['LIST_COL_SORT'].class.name == 'Hash' && $_SESSION['LIST_COL_SORT'].key?(@sqlHash)
|
1976
|
+
end
|
1977
|
+
|
1978
|
+
# Add base order by
|
1979
|
+
if ! @items['orderBy'].empty?
|
1980
|
+
pieces['<!--ORDERBY-->'] += ',' + @items['orderBy']
|
1981
|
+
end
|
1982
|
+
|
1983
|
+
elsif !@items['orderBy'].empty?
|
1984
|
+
pieces['<!--ORDERBY-->'] += ' ORDER BY ' + @items['orderBy']
|
1985
|
+
end
|
1986
|
+
|
1987
|
+
pieces['<!--LIMIT-->'] = ' LIMIT :LOW, :HIGH'
|
1988
|
+
|
1989
|
+
statement = WidgetList::Utils::fill(pieces, statement)
|
1990
|
+
|
1991
|
+
if @items['rowLimit'] >= @totalRows
|
1992
|
+
@items['bindVarsLegacy']['LOW'] = 0
|
1993
|
+
@sequence = 1
|
1994
|
+
end
|
1995
|
+
|
1996
|
+
statement
|
1997
|
+
end
|
1998
|
+
|
1999
|
+
def auto_column_name(name='')
|
2000
|
+
name.gsub(/\_/,' ').gsub(/\-/,' ').capitalize
|
2001
|
+
end
|
2002
|
+
|
2003
|
+
def get_total_records()
|
2004
|
+
|
2005
|
+
filter = ''
|
2006
|
+
fields = {}
|
2007
|
+
sql = ''
|
2008
|
+
hashed = false
|
2009
|
+
|
2010
|
+
if !@items['force_count_sql'].empty?
|
2011
|
+
sql = @items['force_count_sql']
|
2012
|
+
elsif !@items['table'].empty?
|
2013
|
+
sql = WidgetList::Utils::fill({'<!--TABLE-->' => @items['table']}, @items['statement']['count']['table'])
|
2014
|
+
elsif !@items['sql'].empty?
|
2015
|
+
sql = WidgetList::Utils::fill({'<!--SQL-->' => @items['sql']}, @items['statement']['count']['sql'])
|
2016
|
+
elsif !@items['view'].empty?
|
2017
|
+
sql = WidgetList::Utils::fill({'<!--VIEW-->' => @items['view']}, @items['statement']['count']['view'])
|
2018
|
+
end
|
2019
|
+
|
2020
|
+
if ! @filter.empty?
|
2021
|
+
filter = ' WHERE ' + @filter
|
2022
|
+
end
|
2023
|
+
|
2024
|
+
sql = WidgetList::Utils::fill({'<!--WHERE-->' => filter}, sql)
|
2025
|
+
|
2026
|
+
if ! sql.empty?
|
2027
|
+
if @items['showPagination']
|
2028
|
+
if WidgetList::List.get_database._select(sql, [], @items['bindVarsLegacy']) > 0
|
2029
|
+
rows = WidgetList::List.get_database.final_results['TOTAL'][0]
|
2030
|
+
else
|
2031
|
+
rows = 0
|
2032
|
+
end
|
2033
|
+
if rows > 0
|
2034
|
+
@totalRows = rows
|
2035
|
+
end
|
2036
|
+
else
|
2037
|
+
rows = 1
|
2038
|
+
end
|
2039
|
+
else
|
2040
|
+
rows = 0
|
2041
|
+
end
|
2042
|
+
|
2043
|
+
if @totalRows > 0
|
2044
|
+
@totalPages = (@totalRows.to_f / @items['rowLimit'].to_f).ceil()
|
2045
|
+
end
|
2046
|
+
|
2047
|
+
rows
|
2048
|
+
end
|
2049
|
+
|
2050
|
+
end
|
2051
|
+
|
2052
|
+
end
|
2053
|
+
|
2054
|
+
|