kvasilov48
4/8/2015 - 7:26 AM

AjaxItems

AjaxItems

function AjaxItems($container, config) {
	var defaultOpts = {
		textNoItems: "Не знайдено",
		removalActionClass: "actionRemove",
		removalDialog: function(el) { return confirm('Видалити?') },
		showNoItems: function($container, message) {
			$container.empty().append( $div().text(message)	)
		},
		// If you want item removal to be handled, add an element with class .actionRemove (or another specified in removalActionClass option)
		itemDom: function(el) {
			return $div().text(el.toString())
		},
		// Should return {status: OK} if submission was successful, otherwise {status: "error message"}
		remove: function(el, done) {
			alert('"remove" option of AjaxItems was not configured!')
			done( { status: "OK" } )
		},
		showRemovalError: function(message) { alert(message) },
		confirmRemoval: function(el) { return confirm('Видалити?') }
	}
	var opts = $.extend({}, defaultOpts, config)
	var me = this,
		itemsCount = 0

	/**
	 * Show no items with some text. If message is not specified, default one will be used.
	 * @param message
	 */
	this.showNoItems = function(message) {
		var msg =  (message === undefined)? opts.textNoItems : message
		$container.empty()
		opts.showNoItems($container, msg)
		itemsCount = 0
	}

	function createItemDom(el) {
		var $x = opts.itemDom(el)
		$x.find('.'+opts.removalActionClass).data('_AjaxItems_itemElement', el).data('_AjaxItems_itemContainer', $x)
		return $x
	}

	/**
	 * Display items. If there are no items, textNoItems (if specified) or default configuration will be used.
	 * @param items
	 * @param textNoItems
	 */
	this.show = function(items, textNoItems) {
		if (items.length == 0) {
			var msg = (textNoItems === undefined)? opts.textNoItems : textNoItems
			this.showNoItems(msg)
		}
		else
		{
			$container.empty()
			for (var i = 0; i < items.length; i++)
				$container.append(createItemDom(items[i]))
			itemsCount = items.length
		}
	}

	this.add = function(item) {
		if (!itemsCount)
			$container.empty()
		createItemDom(item).prependTo($container)
		itemsCount++
	}

	this.itemDom = function(item) { return createItemDom(item) }
	this.container = function() { return $container }

	// When removal controls clicked
	$container.on('click', '.'+opts.removalActionClass, function(e){
		var el = $(this).data('_AjaxItems_itemElement')
		if (!el) {
			opts.showRemovalError('Cannot load _AjaxItems_itemElement data from clicked element')
			return
		}
		var elContainer = $(this).data('_AjaxItems_itemContainer')
		if (!elContainer) {
			opts.showRemovalError('Cannot load _AjaxItems_itemContainer data from clicked element')
			return
		}

		if (!opts.confirmRemoval(el))
			return

		opts.remove(el, function(res){
			if (typeof res != "object" || !res.status)
				opts.showRemovalError('Wrong removal result format')
			else if (res.status != "OK")
				opts.showRemovalError(res.status)
			else {
				elContainer.remove()
				itemsCount--
				if (!itemsCount)
					me.showNoItems()
			}
		})
	})
}

// Standard function that can be called in function of "remove" configuration of AjaxItems
standardAjaxItemsRemovalFunc = function(fDone, ajaxUrl, ajaxData) {
	$.ajax(ajaxUrl, {
		type: "POST",
		data: ajaxData
	}).done(function(data, textStatus, jqXHR){
			ajaxDone(data, textStatus, jqXHR, function(d){
				fDone({status: "OK"})
			})
		})
}