/** * jQuery Yii ListView plugin file. * * @author Qiang Xue * @link http://www.yiiframework.com/ * @copyright 2008-2010 Yii Software LLC * @license http://www.yiiframework.com/license/ */ ;(function($) { var yiiXHR = {}; /** * yiiListView set function. * @param options map settings for the list view. Availablel options are as follows: * - ajaxUpdate: array, IDs of the containers whose content may be updated by ajax response * - ajaxVar: string, the name of the request variable indicating the ID of the element triggering the AJAX request * - ajaxType: string, the type (GET or POST) of the AJAX request * - pagerClass: string, the CSS class for the pager container * - sorterClass: string, the CSS class for the sorter container * - updateSelector: string, the selector for choosing which elements can trigger ajax requests * - beforeAjaxUpdate: function, the function to be called before ajax request is sent * - afterAjaxUpdate: function, the function to be called after ajax response is received */ $.fn.yiiListView = function(options) { return this.each(function(){ var settings = $.extend({}, $.fn.yiiListView.defaults, options || {}), $this = $(this), id = $this.attr('id'); if(settings.updateSelector == undefined) { settings.updateSelector = '#'+id+' .'+settings.pagerClass.replace(/\s+/g,'.')+' a, #'+id+' .'+settings.sorterClass.replace(/\s+/g,'.')+' a'; } $.fn.yiiListView.settings[id] = settings; if(settings.ajaxUpdate.length > 0) { $(document).on('click.yiiListView', settings.updateSelector,function(){ if(settings.enableHistory && window.History.enabled) { var url = $(this).attr('href').split('?'), params = $.deparam.querystring('?'+ (url[1] || '')); delete params[settings.ajaxVar]; window.History.pushState(null, document.title, decodeURIComponent($.param.querystring(url[0], params))); } else { $.fn.yiiListView.update(id, {url: $(this).attr('href')}); } return false; }); if(settings.enableHistory && window.History.enabled) { $(window).bind('statechange', function() { // Note: We are using statechange instead of popstate var State = window.History.getState(); // Note: We are using History.getState() instead of event.state $.fn.yiiListView.update(id, {url: State.url}); }); } } }); }; $.fn.yiiListView.defaults = { ajaxUpdate: [], ajaxVar: 'ajax', ajaxType: 'GET', pagerClass: 'pager', loadingClass: 'loading', sorterClass: 'sorter' // updateSelector: '#id .pager a, '#id .sort a', // beforeAjaxUpdate: function(id) {}, // afterAjaxUpdate: function(id, data) {}, // url: 'ajax request URL' }; $.fn.yiiListView.settings = {}; /** * Returns the key value for the specified row * @param id string the ID of the list view container * @param index integer the zero-based index of the data item * @return string the key value */ $.fn.yiiListView.getKey = function(id, index) { return $('#'+id+' > div.keys > span:eq('+index+')').text(); }; /** * Returns the URL that generates the list view content. * @param id string the ID of the list view container * @return string the URL that generates the list view content. */ $.fn.yiiListView.getUrl = function(id) { var settings = $.fn.yiiListView.settings[id]; return settings.url || $('#'+id+' > div.keys').attr('title'); }; /** * Performs an AJAX-based update of the list view contents. * @param id string the ID of the list view container * @param options map the AJAX request options (see jQuery.ajax API manual). By default, * the URL to be requested is the one that generates the current content of the list view. */ $.fn.yiiListView.update = function(id, options) { var customError, settings = $.fn.yiiListView.settings[id]; if (options && options.error !== undefined) { customError = options.error; delete options.error; } options = $.extend({ type: settings.ajaxType, url: $.fn.yiiListView.getUrl(id), success: function(data,status) { $.each(settings.ajaxUpdate, function(i,v) { var id='#'+v; $(id).replaceWith($(id,'
'+data+'
')); }); if(settings.afterAjaxUpdate != undefined) settings.afterAjaxUpdate(id, data); }, complete: function() { $('#'+id).removeClass(settings.loadingClass); yiiXHR[id] = null; }, error: function(XHR, textStatus, errorThrown) { var ret, err; if (XHR.readyState === 0 || XHR.status === 0) { return; } if (customError !== undefined) { ret = customError(XHR); if (ret !== undefined && !ret) { return; } } switch (textStatus) { case 'timeout': err = 'The request timed out!'; break; case 'parsererror': err = 'Parser error!'; break; case 'error': if (XHR.status && !/^\s*$/.test(XHR.status)) { err = 'Error ' + XHR.status; } else { err = 'Error'; } if (XHR.responseText && !/^\s*$/.test(XHR.responseText)) { err = err + ': ' + XHR.responseText; } break; } if (settings.ajaxUpdateError !== undefined) { settings.ajaxUpdateError(XHR, textStatus, errorThrown, err); } else if (err) { alert(err); } } }, options || {}); if(options.data!=undefined && options.type=='GET') { options.url = $.param.querystring(options.url, options.data); options.data = {}; } if(settings.ajaxVar) options.url = $.param.querystring(options.url, settings.ajaxVar+'='+id); if(yiiXHR[id] != null) { yiiXHR[id].abort(); } $('#'+id).addClass(settings.loadingClass); if(settings.beforeAjaxUpdate != undefined) settings.beforeAjaxUpdate(id); yiiXHR[id] = $.ajax(options); }; })(jQuery);