Jump to content
Дизайн и модификация Invision Power Board IPBSkinsBETA
Search In
  • More options...
Find results that contain...
Find results in...
Sign in to follow this  
TemKa_SD

Фильтр по играм

Recommended Posts

Вы же уже делали что-то подобное.

 

Или сейчас ajax/cookie не нужны?

Share this post


Link to post
Share on other sites

Нужны, просто я переделываю приложение с нуля и решил сделать более грамотно его. Сейчас дошел до фильтра и подумал, что у этих функций более правильное решение. AJAX планирую сделать через файл, который обновляет ЛС, на его основе точнее. Ну куки работают сейчас и тут, с этим всё норм.

 

На этом эта мне надо сделать, чтобы контент обновлялся при нажатии на фильтр, потом уже буду ковырять AJAX.

 

Сейчас файл такой:

 

Чуть позже уберу всё лишнее тут.

 

/**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
* ips.forum.flow.js - Flow filter controller
*
* Author: Matt Mecham, certainly not Rikki Tissier (yet)
*/
;( function($, _, undefined){
"use strict";

ips.controller.register('wc3.front.games.runningGamesFilter', {

	_ids: [],
	_button: null,

	initialize: function () {
		this.on( 'click', '[data-node-id]', this.toggleFilters );

		this.setup();
	},

	/**
	 * Um, set up...
	 */
	setup: function () {
		/* Populate forum IDs */
		var _ids = ips.utils.url.getParam( 'botId' );

		var self = this;

		if ( ! _.isUndefined( _ids ) ) {
			/* Check URL */
			this._ids = decodeURIComponent( _ids ).split(',');
		} else if( ! _.isUndefined( ips.utils.cookie.get('runningGames_botIds') ) ) {
			/* Check local storage */
			this._ids = ips.utils.cookie.get('runningGames_botIds').split(',');
		}

		if( _.isObject( this._ids ) && _.size( this._ids ) ){
			_.each( this._ids, function (val, key) {
				if ( val ) {
					self.childSelect( val, true );
				}
			});
		}

		this._button = $('body').find('[data-role="fluidForumMobileDesc"]');
		this._updateButtonText();
	},

	/**
	 * Event handler for toggling a filter
	 *
	 * @param 	{event} 	e 	Event object
	 * @returns {void}
	 */
	toggleFilters: function (e) {
		e.preventDefault();
		var link = $( e.currentTarget );
		var id = link.attr('data-node-id');
		var parentId = link.attr('data-parent-id');
		var hasChildren = link.attr('data-has-children');

		if ( _.indexOf( this._ids, id ) == -1 ) {
			/* Does not exist, so add it */
			this.childSelect( id, false );

		} else {
			/* Exists, so remove it */
			this.childUnselect( id );
		}

		this._updateButtonText();

		$( document ).trigger( 'updateTableURL', { botId: _.uniq( _.values( this._ids ) ).join(',') } );
	},

	/**
	 * Is item selected
	 *
	 */
	isSelected: function(id) {
		return this.scope.find('[data-node-id="' + id + '"]').hasClass('cForumMiniList_selected') ? true : false;
	},

	/**
	 * Select a child
	 *
	 */
	childSelect: function(id, skipChildren) {
		Debug.log("Select child: " + id );
		this._ids.push( id );
		var node = this.scope.find('[data-node-id="' + id + '"]');
		node.addClass('cForumMiniList_selected');
		var parentId = node.attr('data-parent-id');

		/* Mark any children, but we do not need to keep individual row markings */
		if ( skipChildren === false && ( node.attr('data-has-children') || id == parentId ) ) {
			var self = this;
			_.each( this.scope.find('[data-parent-id="' + id + '"]'), function( v, k ) {
				var _cId = $(v).attr('data-node-id');
				if ( _cId != id ) {
					self.childSelect( _cId, false );
				}
			} );
		}

		this.updateCookie();
	},

	/**
	 * Unselect a child
	 *
	 */
	childUnselect: function(id) {
		Debug.log("UNselect child: " + id );
		/* Remove marking */
		this.scope.find('[data-node-id="' + id + '"]').removeClass('cForumMiniList_selected');

		/* Remove from local storage and id stack */
		this._ids = _.without( this._ids, id );
		this.updateCookie();

		/* Check for children of this and unselect those too */
		var self = this;
		_.each( this.scope.find('[data-parent-id="' + id + '"]'), function( v, k ) {
			var _cId = $(v).attr('data-node-id');
			if ( _cId != id ) {
				self.childUnselect( _cId );
			}
		} );

		/* And we always need to unselect the category */
		this.parentUnselect( this.scope.find('[data-node-id="' + id + '"]').closest('[data-category]').find('[data-node-id]').first().attr('data-node-id') );
	},

	/**
	 * Select a parent
	 *
	 */
	parentSelect: function(parentId) {
		Debug.log("Select parent: " + parentId );
		/* Mark category and children as selected */
		this.scope.find('[data-node-id="' + parentId + '"]').addClass('cForumMiniList_selected');

		/* Remove children from the arrays as PHP handles this */
		var self = this;
		_.each( this.scope.find('[data-parent-id="' + parentId + '"]'), function( v, k ) {
			var _cId = $(v).attr('data-node-id');

			if ( _cId != parentId ) {
				self.childUnselect( _cId );
			}
		} );
	},

	/**
	 * Unselect a parent
	 *
	 */
	parentUnselect: function(parentId) {
		Debug.log("UNselect parent: " + parentId );
		/* Unselect parent as marked */
		var node = this.scope.find('[data-node-id="' + parentId + '"]');
		node.removeClass('cForumMiniList_selected');

		this._ids = _.without( this._ids, parentId );
		this.updateCookie();

		/* Off up the tree we go */
		Debug.log( "Looking for parent ID " + node.attr('data-parent-id') );
		var self = this;
		_.each( this.scope.find('[data-node-id="' + node.attr('data-parent-id') + '"]'), function( v, k ) {
			var _cId = $(v).attr('data-node-id');
			if ( _cId != parentId ) {
				Debug.log( "Found " + _cId );
				self.parentUnselect( _cId );
			}
		} );
	},

	/**
	 * Update the cookie
	 */
	updateCookie: function(id) {
		var cookie = _.uniq( _.values( this._ids ) ).join(',');
		Debug.log("Updating cookie: " + cookie );

		ips.utils.cookie.set('runningGames_botIds', cookie, true);
	},

	/**
	 * Updates the mobile button text based on selected forums
	 *
	 * @param		{event}		e			The submit event
	 * @param		{element} 	elem 		The element this widget is being created on
	 * @returns		{void}
	 */
	_updateButtonText: function () {
		var blobs = this.scope.find('.cForumMiniList_blob');
		var selectedBlobRows = blobs.filter( function () {
			if( $( this ).closest('.cForumMiniList_selected').length ){
				return true;
			}
			return false;
		});
		var text = '';

		// If the counts are the same, we know we've selected all of them
		if( blobs.length == selectedBlobRows.length || selectedBlobRows.length === 0 ){
			text = ips.getString('topicsFromAllForums');
		} else {
			text = ips.pluralize( ips.getString( 'topicsFromXForums' ), selectedBlobRows.length );
		}

		this._button.text( text );
	}
});
}(jQuery, _));

Share this post


Link to post
Share on other sites

Еще хочу спросить, модуль который сейчас делаю, активные игры можно передавать с помощью вебсокета, я мало про него знаю, знаю что он с JS работает ну и у меня есть готовый код в принципе. В чем разница между вебсокетом и обычными данными ?

Share this post


Link to post
Share on other sites

Правильно вывел кол-во игр?

Мне кажется тут еще можно использовать группировку сразу в запросе по botid. За одно и приплюсовать там totalplayers и получить готовый результат.

 

->select( 'botid, gamename, SUM(totalplayers) as players, COUNT(*) as games', 'stats_gamelist', NULL, 'botid ASC', NULL, 'botid' )

  • Upvote 1

Share this post


Link to post
Share on other sites

@siv1987 Спасибо, позже рассмотрю эту инфу, башка не варит уже )))

 

@newbie Я разобрался, правда пол движка пришлось перекопать, ну ладно...

 

Этим параметром обновляются результаты, у меня не получилось только за счет HTML структуры превратить это в рабочий вариант, нужна всё равно форма от Table.

$( document ).trigger( 'updateTableURL', { botId: _.uniq( _.values( this._ids ) ).join(',') } );

 

Нужно реализовать что-то вроде:

 

$( document ).trigger( 'contentChange', [ this.scope ] );

 

где this.scope - функция html обновления, помогите плиз.

Share this post


Link to post
Share on other sites

Спасибо, позже рассмотрю эту инфу, башка не варит уже )))

		foreach( \IPS\Db::i('wc3')->select( 'botid, gamename, SUM(totalplayers) as players, COUNT(*) as games', 'stats_gamelist', NULL, 'botid ASC', NULL, 'botid' ) as $bot )
		{
			$bot['gamename'] = trim( current( explode('#', $bot['gamename']) ) );
			static::$cachedBotlist[ $bot['botid'] ] = $bot;
		}

Share this post


Link to post
Share on other sites

Ура, у меня получилось обновить страничку при нажатии, осталось сделать обновление только таблицы ))))

 

 

		var rows = this.scope.find('[data-role="tableRows"]');

		if( !rows.length ){
			window.location = this._baseURL;
			return;
		}


		$( document ).trigger( 'contentChange', [ this.scope ] );

Share this post


Link to post
Share on other sites

window.location/reload это вообще топор. А почему не использовать ajax запрос? В ипс есть удобный апи для работы с ним если муторно разбиратся с таблицами форума.

Share this post


Link to post
Share on other sites

            foreach( \IPS\Db::i('wc3')->select( 'botid, gamename, SUM(totalplayers) as players, COUNT(*) as games', 'stats_gamelist', NULL, 'botid ASC', NULL, 'botid' ) as $bot )
            {
                $bot['gamename'] = trim( current( explode('#', $bot['gamename']) ) );
                static::$cachedBotlist[ $bot['botid'] ] = $bot;
            }

Забыл предложить вариант с GROUP BY

Предложенный код может не работать из-за ONLY_FULL_GROUP_BY (в mysql 5.7 включен по умолчанию)

Можно сделать так

->select( 'botid, MIN(gamename) as gamename, SUM(totalplayers) as players, COUNT(*) as games'

Share this post


Link to post
Share on other sites

Зачем Вам такая js-портянка нужна.

Если у Вас не таблица, то смысл переделывать под таблицу только из-за того, что есть какой-то js-код

 

Повторюсь. У Вас же был js-код для подобного. Возьмите и перепишите его.

Share this post


Link to post
Share on other sites

У меня не было обновления при клике. Сейчас мне нужно только это сделать, под таблицы не обязательно, просто нужно вот эту функцию правильно изменить: http://ipbskins.ru/forum/topic15808.html/page__view__findpost__p__105904 код небольшой и простой, там ничего лишнего сейчас нет, просто он более правильный и другой.

 

Т.е тут выбор чекбоксов, обновление их из куков и URL, запись в куки, немного для мобилок, с этим всё норм. Мне нудно вот по ссылке выше в коде сделать обновление моей таблице ПО НАЖАТИЮ на фильтр.

 

/**
*
* ips.games.runningGamesFilter.js - Bot filter controller
*
*/
;( function($, _, undefined){
"use strict";

ips.controller.register('wc3.front.games.runningGamesFilter', {

	_ids: [],
	_button: null,

	initialize: function () {
		this.on( 'click', '[data-bot-id]', this.toggleFilters );
		this.setup();
	},

	/**
	 * Um, set up...
	 */
	setup: function () {
		/* Populate forum IDs */
		var _ids = ips.utils.url.getParam( 'botId' );

		var self = this;

		/* BotId */
		if ( ! _.isUndefined( _ids ) ) {
			/* Проверка айди в строке URL */
			this._ids = decodeURIComponent( _ids ).split(',');
		} else if( ! _.isUndefined( ips.utils.cookie.get('runningGames_botIds') ) ) {
			/* Проверка айди в куках */
			this._ids = ips.utils.cookie.get('runningGames_botIds').split(',');
		}

		if( _.isObject( this._ids ) && _.size( this._ids ) ){
			_.each( this._ids, function (val, key) {
				if ( val ) {
					self.botSelect( val, true );
				}
			});
		}

		this._button = $('body').find('[data-role="fluidForumMobileDesc"]');
		this._updateButtonText();
	},

	/**
	 * Event handler for toggling a filter
	 *
	 * @param 	{event} 	e 	Event object
	 * @returns {void}
	 */
	toggleFilters: function (e) {
		e.preventDefault();
		var link = $( e.currentTarget );
		var id = link.attr('data-bot-id');

		if ( _.indexOf( this._ids, id ) == -1 ) {
			/* Does not exist, so add it */
			this.botSelect( id, false );

		} else {
			/* Exists, so remove it */
			this.botUnselect( id );
		}

		this._updateButtonText();

		$( document ).trigger( 'updateTableURL', { botId: _.uniq( _.values( this._ids ) ).join(',') } );
	},

	/**
	 * Is item selected
	 *
	 */
	isSelected: function(id) {
		return this.scope.find('[data-bot-id="' + id + '"]').hasClass('cForumMiniList_selected') ? true : false;
	},

	/**
	 * Select a child
	 *
	 */
	botSelect: function(id) {
		Debug.log("Выбран бот: " + id );
		this._ids.push( id );
		var node = this.scope.find('[data-bot-id="' + id + '"]');
		node.addClass('cForumMiniList_selected');

		this.updateCookie();
	},

	/**
	 * Unselect a child
	 *
	 */
	botUnselect: function(id) {
		Debug.log("Удален бот: " + id );
		/* Remove marking */
		this.scope.find('[data-bot-id="' + id + '"]').removeClass('cForumMiniList_selected');

		/* Remove from local storage and id stack */
		this._ids = _.without( this._ids, id );
		this.updateCookie();
	},

	/**
	 * Обновление куков
	 */
	updateCookie: function(id) {
		var cookie = _.uniq( _.values( this._ids ) ).join(',');
		Debug.log("Обновление куков: " + cookie );

		ips.utils.cookie.set('runningGames_botIds', cookie, true);
	},

	/**
	 * Updates the mobile button text based on selected forums
	 *
	 * @param		{event}		e			The submit event
	 * @param		{element} 	elem 		The element this widget is being created on
	 * @returns		{void}
	 */
	_updateButtonText: function () {
		var blobs = this.scope.find('.cForumMiniList_blob');
		var selectedBlobRows = blobs.filter( function () {
			if( $( this ).closest('.cForumMiniList_selected').length ){
				return true;
			}
			return false;
		});
		var text = '';

		// If the counts are the same, we know we've selected all of them
		if( blobs.length == selectedBlobRows.length || selectedBlobRows.length === 0 ){
			text = ips.getString('topicsFromAllForums');
		} else {
			text = ips.pluralize( ips.getString( 'topicsFromXForums' ), selectedBlobRows.length );
		}

		this._button.text( text );
	}

});
}(jQuery, _));

Share this post


Link to post
Share on other sites

Мне нудно вот по ссылке выше в коде сделать обновление моей таблице ПО НАЖАТИЮ на фильтр.

Делайте ajax-запрос и обновляйте html

Share this post


Link to post
Share on other sites

Так, помогите заменить содержимое при автоматическом обновлении, что-то не получается. http://prntscr.com/lly1r4

 

	/**
	 * Processes an ajax response
	 *
	 * @param	{object} 	response 	 	Server response
	 * @returns {void} 
	 */
	_handleResponse: function (response) {
		try {
			// If auto-polling is now disabled, stop everything
			if( response.error && response.error == 'auto_polling_disabled' ){
				this._stopPolling( true );
				return;
			}






			$('#gamelistTable').find('ol').html( response['html'] );








		} catch (err) {
			this._stopPolling( true );
			return;
		}
	},

Share this post


Link to post
Share on other sites

И где тут ajax-запрос? Тут уже какой-то ответ разбирается.

Share this post


Link to post
Share on other sites

response выводит шаблон который нужно из модуля > ajax, с этим всё в порядке, шаблон в логах выводится, но не заменяется в таблице.

 

	/**
	 * The main method to check notification status
	 * Checks in localstorage to see if the last poll was < 20s ago
	 *
	 * @returns {void}
	 */
	_checkNotifications: function () {

		// If our window is inactive, increase the count
		if( document[ ips.utils.events.getVisibilityProp() ] ){
			if( this._windowInactivePoll >= 3 && this._pollMultiplier === 1 ){ // 0-3 minutes @ 60s poll
				if( this._debugPolling ){
					Debug.log( "runningGames: Polled over 3 minutes, increasing multiplier to 2");
				}
				this._pollMultiplier = 2;
				this._setInterval( this._pollTimeout * this._pollMultiplier );
			} else if( this._windowInactivePoll >= 7 && this._pollMultiplier === 2 ) { // 4-11 minutes @ 120s poll
				if( this._debugPolling ){
					Debug.log( "runningGames: Polled over 10 minutes, increasing multiplier to 3");
				}
				this._pollMultiplier = 3;
				this._setInterval( this._pollTimeout * this._pollMultiplier );
			} else if( this._windowInactivePoll >= 25 && this._pollMultiplier === 3 ) { // > 60 mins stop
				if( this._debugPolling ){
					Debug.log( "runningGames: Polled over 60 mins, stopping polling");
				}
				this._stopPolling();
				return;
			}

			this._windowInactivePoll++;
		}

		// We send our currently-displayed bubble count to the backend
		// to find out if there's any change in number
		var dataToSend = { dataToSend };

		this._doAjaxRequest( dataToSend );

	},

	/**
	 * Calls the backend to get new notification data
	 *
	 * @param	{object} 	dataToSend 	 	Object containing current message and notification counts
	 * @returns {void} 
	 */
	_doAjaxRequest: function (dataToSend) {
		var self = this;
		var url = ips.getSetting( 'baseURL' ) + '?app=wc3&module=games&controller=runningGames&do=ajax';

		if( this._debugPolling ){
			Debug.log("runningGames: sending ajax request");
		}

		// We'll update the timestamp before polling so that other windows
		// don't start polling before this one is finished
		//this._updateTimestamp();

		// We do need to poll, it's been more than 20s
		this._ajaxObj = ips.getAjax()( url, {
			data: dataToSend
		})
			.done( _.bind( this._handleResponse, this ) )
			.fail( function () {
				self._stopPolling(true);
				Debug.error("Problem polling for new notifications; stopping.");
			});
	},


	/**
	 * Processes an ajax response
	 *
	 * @param	{object} 	response 	 	Server response
	 * @returns {void} 
	 */
	_handleResponse: function (response) {
		try {
			// If auto-polling is now disabled, stop everything
			if( response.error && response.error == 'auto_polling_disabled' ){
				this._stopPolling( true );
				return;
			}
			var html = '';
			var table = $('#gamelistTable');
			var tableBody = table.find('ol');

			if( this._debugPolling ){
				tableBody.replaceWith(response);
				Debug.log("Update");
			}

		} catch (err) {
			this._stopPolling( true );
			return;
		}
	},

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...