jquery.yiilistview.js 5.82 KB
Newer Older
JULIO JARAMILLO's avatar
subida  
JULIO JARAMILLO committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
/**
 * jQuery Yii ListView plugin file.
 *
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @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 href = $(this).attr('href');
						if(href){
							var url = href.split('?'),
								params = $.deparam.querystring('?'+ (url[1] || ''));

							delete params[settings.ajaxVar];

							var updateUrl = $.param.querystring(url[0], params);
							window.History.pushState({url: updateUrl}, document.title, updateUrl);
						}
					} 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
						if (State.data.url === undefined) {
							State.data.url = State.url;
						}
						$.fn.yiiListView.update(id, State.data);
					});
				}
			}
		});
	};

	$.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,'<div>'+data+'</div>'));
				});
				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, id);
				} 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, options);
		yiiXHR[id] = $.ajax(options);
	};

})(jQuery);