1/** 2 * jQuery Yii GridView plugin file. 3 * 4 * @author Qiang Xue <[email protected]> 5 * @link http://www.yiiframework.com/ 6 * @copyright Copyright © 2008-2010 Yii Software LLC 7 * @license http://www.yiiframework.com/license/ 8 */ 9 10(function ($) { 11 var selectCheckedRows, methods, 12 gridSettings = []; 13 /** 14 * 1. Selects rows that have checkbox checked (only checkbox that is connected with selecting a row) 15 * 2. Check if "check all" need to be checked/unchecked 16 * @return object the jQuery object 17 */ 18 selectCheckedRows = function (gridId) { 19 var settings = gridSettings[gridId], 20 table = $('#' + gridId).children('.' + settings.tableClass); 21 22 table.children('tbody').find('input.select-on-check').filter(':checked').each(function () { 23 $(this).closest('tr').addClass('selected'); 24 }); 25 26 table.children('thead').find('th input').filter('[type="checkbox"]').each(function () { 27 var name = this.name.substring(0, this.name.length - 4) + '[]', //.. remove '_all' and add '[]'' 28 $checks = $("input[name='" + name + "']", table); 29 this.checked = $checks.length > 0 && $checks.length === $checks.filter(':checked').length; 30 }); 31 return this; 32 }; 33 34 methods = { 35 /** 36 * yiiGridView set function. 37 * @param options map settings for the grid view. Available options are as follows: 38 * - ajaxUpdate: array, IDs of the containers whose content may be updated by ajax response 39 * - ajaxVar: string, the name of the GET variable indicating the ID of the element triggering the AJAX request 40 * - pagerClass: string, the CSS class for the pager container 41 * - tableClass: string, the CSS class for the table 42 * - selectableRows: integer, the number of rows that can be selected 43 * - updateSelector: string, the selector for choosing which elements can trigger ajax requests 44 * - beforeAjaxUpdate: function, the function to be called before ajax request is sent 45 * - afterAjaxUpdate: function, the function to be called after ajax response is received 46 * - ajaxUpdateError: function, the function to be called if an ajax error occurs 47 * - selectionChanged: function, the function to be called after the row selection is changed 48 * @return object the jQuery object 49 */ 50 init: function (options) { 51 var settings = $.extend({ 52 ajaxUpdate: [], 53 ajaxVar: 'ajax', 54 pagerClass: 'pager', 55 loadingClass: 'loading', 56 filterClass: 'filters', 57 tableClass: 'items', 58 selectableRows: 1 59 // updateSelector: '#id .pager a, '#id .grid thead th a', 60 // beforeAjaxUpdate: function (id) {}, 61 // afterAjaxUpdate: function (id, data) {}, 62 // selectionChanged: function (id) {}, 63 // url: 'ajax request URL' 64 }, options || {}); 65 66 settings.tableClass = settings.tableClass.replace(/\s+/g, '.'); 67 68 return this.each(function () { 69 var eventType, 70 $grid = $(this), 71 id = $grid.attr('id'), 72 pagerSelector = '#' + id + ' .' + settings.pagerClass.replace(/\s+/g, '.') + ' a', 73 sortSelector = '#' + id + ' .' + settings.tableClass + ' thead th a.sort-link', 74 inputSelector = '#' + id + ' .' + settings.filterClass + ' input, ' + '#' + id + ' .' + settings.filterClass + ' select'; 75 76 settings.updateSelector = settings.updateSelector 77 .replace('{page}', pagerSelector) 78 .replace('{sort}', sortSelector); 79 settings.filterSelector = settings.filterSelector 80 .replace('{filter}', inputSelector); 81 82 gridSettings[id] = settings; 83 84 if (settings.ajaxUpdate.length > 0) { 85 $(document).on('click.yiiGridView', settings.updateSelector, function () { 86 // Check to see if History.js is enabled for our Browser 87 if (settings.enableHistory && window.History.enabled) { 88 // Ajaxify this link 89 var url = $(this).attr('href').split('?'), 90 params = $.deparam.querystring('?'+url[1]); 91 92 delete params[settings.ajaxVar]; 93 window.History.pushState(null, document.title, decodeURIComponent($.param.querystring(url[0], params))); 94 } else { 95 $('#' + id).yiiGridView('update', {url: $(this).attr('href')}); 96 } 97 return false; 98 }); 99 } 100
101 $(document).on('change.yiiGridView keydown.yiiGridView', settings.filterSelector, function (event) { 102 if (event.type === 'keydown') { 103 if( event.keyCode !== 13) { 104 return; // only react to enter key 105 } else { 106 eventType = 'keydown'; 107 } 108 } else { 109 // prevent processing for both keydown and change events 110 if (eventType === 'keydown') { 111 eventType = ''; 112 return; 113 } 114 } 115 var data = $(settings.filterSelector).serialize(); 116 if (settings.pageVar !== undefined) { 117 data += '&' + settings.pageVar + '=1'; 118 } 119 if (settings.enableHistory && settings.ajaxUpdate !== false && window.History.enabled) { 120 // Ajaxify this link 121 var url = $('#' + id).yiiGridView('getUrl'), 122 params = $.deparam.querystring($.param.querystring(url, data)); 123 124 delete params[settings.ajaxVar]; 125 window.History.pushState(null, document.title, decodeURIComponent($.param.querystring(url.substr(0, url.indexOf('?')), params))); 126 } else { 127 $('#' + id).yiiGridView('update', {data: data}); 128 } 129 }); 130 131 if (settings.enableHistory && settings.ajaxUpdate !== false && window.History.enabled) { 132 $(window).bind('statechange', function() { // Note: We are using statechange instead of popstate 133 var State = window.History.getState(); // Note: We are using History.getState() instead of event.state 134 $('#' + id).yiiGridView('update', {url: State.url}); 135 }); 136 } 137 138 if (settings.selectableRows > 0) { 139 selectCheckedRows(this.id); 140 $(document).on('click.yiiGridView', '#' + id + ' .' + settings.tableClass + ' > tbody > tr', function (e) { 141 var $currentGrid, $row, isRowSelected, $checks, 142 $target = $(e.target); 143 144 if ($target.closest('td').is('.empty,.button-column') || (e.target.type === 'checkbox' && !$target.hasClass('select-on-check'))) { 145 return; 146 } 147 148 $row = $(this); 149 $currentGrid = $('#' + id); 150 $checks = $('input.select-on-check', $currentGrid); 151 isRowSelected = $row.toggleClass('selected').hasClass('selected'); 152 153 if (settings.selectableRows === 1) { 154 $row.siblings().removeClass('selected'); 155 $checks.prop('checked', false); 156 } 157 $('input.select-on-check', $row).prop('checked', isRowSelected); 158 $("input.select-on-check-all", $currentGrid).prop('checked', $checks.length === $checks.filter(':checked').length); 159 160 if (settings.selectionChanged !== undefined) { 161 settings.selectionChanged(id); 162 } 163 }); 164 if (settings.selectableRows > 1) { 165 $(document).on('click.yiiGridView', '#' + id + ' .select-on-check-all', function () { 166 var $currentGrid = $('#' + id), 167 $checks = $('input.select-on-check', $currentGrid), 168 $checksAll = $('input.select-on-check-all', $currentGrid), 169 $rows = $currentGrid.children('.' + settings.tableClass).children('tbody').children(); 170 if (this.checked) { 171 $rows.addClass('selected'); 172 $checks.prop('checked', true); 173 $checksAll.prop('checked', true); 174 } else { 175 $rows.removeClass('selected'); 176 $checks.prop('checked', false); 177 $checksAll.prop('checked', false); 178 } 179 if (settings.selectionChanged !== undefined) { 180 settings.selectionChanged(id); 181 } 182 }); 183 } 184 } else { 185 $(document).on('click.yiiGridView', '#' + id + ' .select-on-check', false); 186 } 187 }); 188 }, 189 190 /** 191 * Returns the key value for the specified row 192 * @param row integer the row number (zero-based index) 193 * @return string the key value 194 */ 195 getKey: function (row) { 196 return this.children('.keys').children('span').eq(row).text(); 197 }, 198 199 /** 200 * Returns the URL that generates the grid view content. 201 * @return string the URL that generates the grid view content. 202 */ 203 getUrl: function () { 204 var sUrl = gridSettings[this.attr('id')].url; 205 return sUrl || this.children('.keys').attr('title'); 206 }, 207 208 /** 209 * Returns the jQuery collection of the cells in the specified row. 210 * @param row integer the row number (zero-based index) 211 * @return jQuery the jQuery collection of the cells in the specified row. 212 */ 213 getRow: function (row) { 214 var sClass = gridSettings[this.attr('id')].tableClass; 215 return this.children('.' + sClass).children('tbody').children('tr').eq(row).children(); 216 }, 217 218 /** 219 * Returns the jQuery collection of the cells in the specified column. 220 * @param column integer the column number (zero-based index) 221 * @return jQuery the jQuery collection of the cells in the specified column. 222 */ 223 getColumn: function (column) { 224 var sClass = gridSettings[this.attr('id')].tableClass; 225 return this.children('.' + sClass).children('tbody').children('tr').children('td:nth-child(' + (column + 1) + ')'); 226 }, 227 228 /** 229 * Performs an AJAX-based update of the grid view contents. 230 * @param options map the AJAX request options (see jQuery.ajax API manual). By default, 231 * the URL to be requested is the one that generates the current content of the grid view. 232 * @return object the jQuery object 233 */ 234 update: function (options) { 235 var customError; 236 if (options && options.error !== undefined) { 237 customError = options.error; 238 delete options.error; 239 } 240 241 return this.each(function () { 242 var $form, 243 $grid = $(this), 244 id = $grid.attr('id'), 245 settings = gridSettings[id]; 246 $grid.addClass(settings.loadingClass); 247 248 options = $.extend({ 249 type: 'GET', 250 url: $grid.yiiGridView('getUrl'), 251 success: function (data) { 252 var $data = $('<div>' + data + '</div>'); 253 $grid.removeClass(settings.loadingClass); 254 $.each(settings.ajaxUpdate, function (i, el) { 255 var updateId = '#' + el; 256 $(updateId).replaceWith($(updateId, $data)); 257 }); 258 if (settings.afterAjaxUpdate !== undefined) { 259 settings.afterAjaxUpdate(id, data); 260 } 261 if (settings.selectableRows > 0) { 262 selectCheckedRows(id); 263 } 264 }, 265 error: function (XHR, textStatus, errorThrown) { 266 var ret, err; 267 $grid.removeClass(settings.loadingClass); 268 if (XHR.readyState === 0 || XHR.status === 0) { 269 return; 270 } 271 if (customError !== undefined) { 272 ret = customError(XHR); 273 if (ret !== undefined && !ret) { 274 return; 275 } 276 } 277 switch (textStatus) { 278 case 'timeout': 279 err = 'The request timed out!'; 280 break; 281 case 'parsererror': 282 err = 'Parser error!'; 283 break; 284 case 'error': 285 if (XHR.status && !/^\s*$/.test(XHR.status)) { 286 err = 'Error ' + XHR.status; 287 } else { 288 err = 'Error'; 289 } 290 if (XHR.responseText && !/^\s*$/.test(XHR.responseText)) { 291 err = err + ': ' + XHR.responseText; 292 } 293 break; 294 } 295 296 if (settings.ajaxUpdateError !== undefined) { 297 settings.ajaxUpdateError(XHR, textStatus, errorThrown, err); 298 } else if (err) { 299 alert(err); 300 } 301 } 302 }, options || {}); 303 if (options.data !== undefined && options.type === 'GET') { 304 options.url = $.param.querystring(options.url, options.data); 305 options.data = {}; 306 } 307 308 if (settings.ajaxUpdate !== false) { 309 options.url = $.param.querystring(options.url, settings.ajaxVar + '=' + id); 310 if (settings.beforeAjaxUpdate !== undefined) { 311 settings.beforeAjaxUpdate(id, options); 312 } 313 $.ajax(options); 314 } else { // non-ajax mode 315 if (options.type === 'GET') { 316 window.location.href = options.url; 317 } else { // POST mode 318 $form = $('<form action="' + options.url + '" method="post"></form>').appendTo('body'); 319 if (options.data === undefined) { 320 options.data = {}; 321 } 322 323 if (options.data.returnUrl === undefined) { 324 options.data.returnUrl = window.location.href; 325 } 326 327 $.each(options.data, function (name, value) { 328 $form.append($('<input type="hidden" name="t" value="" />').attr('name', name).val(value)); 329 }); 330 $form.submit(); 331 } 332 } 333 }); 334 }, 335 336 /** 337 * Returns the key values of the currently selected rows. 338 * @return array the key values of the currently selected rows. 339 */ 340 getSelection: function () { 341 var settings = gridSettings[this.attr('id')], 342 keys = this.find('.keys span'), 343 selection = []; 344 this.find('.' + settings.tableClass).children('tbody').children().each(function (i) { 345 if ($(this).hasClass('selected')) { 346 selection.push(keys.eq(i).text()); 347 } 348 }); 349 return selection; 350 }, 351 352 /** 353 * Returns the key values of the currently checked rows. 354 * @param column_id string the ID of the column 355 * @return array the key values of the currently checked rows. 356 */ 357 getChecked: function (column_id) { 358 var settings = gridSettings[this.attr('id')], 359 keys = this.find('.keys span'), 360 checked = []; 361 if (column_id.substring(column_id.length - 2) !== '[]') { 362 column_id = column_id + '[]'; 363 } 364 this.find('.' + settings.tableClass).children('tbody').children('tr').children('td').children('input[name="' + column_id + '"]').each(function (i) { 365 if (this.checked) { 366 checked.push(keys.eq(i).text()); 367 } 368 }); 369 return checked; 370 } 371 372 }; 373 374 $.fn.yiiGridView = function (method) { 375 if (methods[method]) { 376 return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); 377 } else if (typeof method === 'object' || !method) { 378 return methods.init.apply(this, arguments); 379 } else { 380 $.error('Method ' + method + ' does not exist on jQuery.yiiGridView'); 381 return false;
382 } 383 }; 384 385/****************************************************************************** 386 *** DEPRECATED METHODS 387 *** used before Yii 1.1.9 388 ******************************************************************************/ 389 $.fn.yiiGridView.settings = gridSettings; 390 /** 391 * Returns the key value for the specified row 392 * @param id string the ID of the grid view container 393 * @param row integer the row number (zero-based index) 394 * @return string the key value 395 */ 396 $.fn.yiiGridView.getKey = function (id, row) { 397 return $('#' + id).yiiGridView('getKey', row); 398 }; 399 400 /** 401 * Returns the URL that generates the grid view content. 402 * @param id string the ID of the grid view container 403 * @return string the URL that generates the grid view content. 404 */ 405 $.fn.yiiGridView.getUrl = function (id) { 406 return $('#' + id).yiiGridView('getUrl'); 407 }; 408 409 /** 410 * Returns the jQuery collection of the cells in the specified row. 411 * @param id string the ID of the grid view container 412 * @param row integer the row number (zero-based index) 413 * @return jQuery the jQuery collection of the cells in the specified row. 414 */ 415 $.fn.yiiGridView.getRow = function (id, row) { 416 return $('#' + id).yiiGridView('getRow', row); 417 }; 418 419 /** 420 * Returns the jQuery collection of the cells in the specified column. 421 * @param id string the ID of the grid view container 422 * @param column integer the column number (zero-based index) 423 * @return jQuery the jQuery collection of the cells in the specified column. 424 */ 425 $.fn.yiiGridView.getColumn = function (id, column) { 426 return $('#' + id).yiiGridView('getColumn', column); 427 }; 428 429 /** 430 * Performs an AJAX-based update of the grid view contents. 431 * @param id string the ID of the grid view container 432 * @param options map the AJAX request options (see jQuery.ajax API manual). By default, 433 * the URL to be requested is the one that generates the current content of the grid view. 434 */ 435 $.fn.yiiGridView.update = function (id, options) { 436 $('#' + id).yiiGridView('update', options); 437 }; 438 439 /** 440 * Returns the key values of the currently selected rows. 441 * @param id string the ID of the grid view container 442 * @return array the key values of the currently selected rows. 443 */ 444 $.fn.yiiGridView.getSelection = function (id) { 445 return $('#' + id).yiiGridView('getSelection'); 446 }; 447 448 /** 449 * Returns the key values of the currently checked rows. 450 * @param id string the ID of the grid view container 451 * @param column_id string the ID of the column 452 * @return array the key values of the currently checked rows. 453 */ 454 $.fn.yiiGridView.getChecked = function (id, column_id) { 455 return $('#' + id).yiiGridView('getChecked', column_id); 456 }; 457})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.