Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 27.11.2015, 16:49
Аватар для Infarch
Профессор
Отправить личное сообщение для Infarch Посмотреть профиль Найти все сообщения от Infarch
 
Регистрация: 06.06.2014
Сообщений: 292

Дополнительная проверка дропзоны
Здравствуйте.

В одном из гридов у меня есть сортировка через drag'n'drop. Но хитрость там в том, что некоторые позиции для дропа запрещены. Я могу это проверить через beforedrop, выдать сообщение и все такое... Но Было бы более красиво сразу запретить дроп в запрещенную зону, при движении через нее показать красный индикатор с соответствующим текстом. Я стал копаться в исходниках и не нашел ничего полезного, кроме как переписать кое-что в Ext.view.DropZone:
Ext.define('SafetyRound.patch.view.DropZone', {
  override: 'Ext.view.DropZone',
  
  isPositionValid: function(overRecord, draggingRecords, pos){
		var 
			me = this,
			valid = !Ext.Array.contains(draggingRecords, overRecord) &&
  			( pos === 'before' && !me.containsRecordAtOffset(draggingRecords, overRecord, -1) ||
					pos === 'after' && !me.containsRecordAtOffset(draggingRecords, overRecord, 1)
				);
		// <-------- some additional validation here
		return valid;
  },
  
	positionIndicator: function(node, data, e) {
		var
			me = this,
			view = me.view,
			pos = me.getPosition(e, node),
			overRecord = view.getRecord(node),
			draggingRecords = data.records,
			indicatorY;
		
		if (me.isPositionValid(overRecord, draggingRecords, pos)) {
			me.valid = true;
			if (me.overRecord !== overRecord || me.currentPosition !== pos) {
				indicatorY = Ext.fly(node).getY() - view.el.getY() - 1;
				if (pos === 'after') {
					indicatorY += Ext.fly(node).getHeight();
				}
				// If view is scrolled using CSS translate, account for then when positioning the indicator
				if (view.touchScroll === 2) {
					indicatorY += view.getScrollY();
				}
				me.getIndicator().setWidth(Ext.fly(view.el).getWidth()).showAt(0, indicatorY);
				// Cache the overRecord and the 'before' or 'after' indicator.
				me.overRecord = overRecord;
				me.currentPosition = pos;
			}
		} else {
			me.invalidateDrop();
		}
	}
  
});

Однако сей вариант очень костыльный. Если вдруг у меня будет более одного места с драгодропом, придется постоянно лепить всякие костыли и проверки.

Есть ли более человеческий способ?
Ответить с цитированием
  #2 (permalink)  
Старый 27.11.2015, 18:05
Аватар для Infarch
Профессор
Отправить личное сообщение для Infarch Посмотреть профиль Найти все сообщения от Infarch
 
Регистрация: 06.06.2014
Сообщений: 292

Немного улучшил ситуацию. В базовой дропзоне использовал функцию - заглушку:
isPositionValid: function(overRecord, draggingRecords, pos){
		var 
			me = this,
			valid = !Ext.Array.contains(draggingRecords, overRecord) &&
  			( pos === 'before' && !me.containsRecordAtOffset(draggingRecords, overRecord, -1) ||
					pos === 'after' && !me.containsRecordAtOffset(draggingRecords, overRecord, 1)
				);
		// some additional validation here
		return valid && me.validateExtended(overRecord, draggingRecords, pos);
  },
  
  // must be re-defined in shildren
  validateExtended: function(overRecord, draggingRecords, pos){
  	return true;
  },

При подключении плагина заглушку переписываю:
plugins: {
	ptype: 'gridviewdragdrop',
	dragText: '## Drag and drop to reorganize',
	dropZone: {
		validateExtended: function(overRecord, draggingRecords, pos){
			// disable draggind to other parent grous
	  	return overRecord.get('SafetyRoundMeasurePoint_ID') == draggingRecords[0].get('SafetyRoundMeasurePoint_ID');
	  }
	}
},

Так все выглядит лучше, но некоторая засада имеет место по прежнему. Если вдруг обновится фреймворк, и метод positionIndicator будет переписан, то может выйти бяка. Кроме того, остался открытым вопрос о драг тексте: как можно его менять динамически?
Ответить с цитированием
  #3 (permalink)  
Старый 30.11.2015, 17:00
Профессор
Отправить личное сообщение для siber-biber Посмотреть профиль Найти все сообщения от siber-biber
 
Регистрация: 07.08.2013
Сообщений: 214

Почему не сделать оверрайд вот этого метода: http://docs.sencha.com/extjs/6.0/6.0...hod-onNodeOver ?
Благо он template то есть просто предназначен для этого.

вот форк от вашего фидла: https://fiddle.sencha.com/#fiddle/11qe
Ответить с цитированием
  #4 (permalink)  
Старый 01.12.2015, 16:15
Аватар для Infarch
Профессор
Отправить личное сообщение для Infarch Посмотреть профиль Найти все сообщения от Infarch
 
Регистрация: 06.06.2014
Сообщений: 292

Дело в том что я на 5м эксте, а там судя по всему такого метода нет. Кстати, не могли бы вы рассказать, что это за темплейт методы? Или ссылку дайте где можно почитать.
Ответить с цитированием
  #5 (permalink)  
Старый 01.12.2015, 18:52
Профессор
Отправить личное сообщение для siber-biber Посмотреть профиль Найти все сообщения от siber-biber
 
Регистрация: 07.08.2013
Сообщений: 214

есть и в пятой версии: http://docs.sencha.com/extjs/5.1/5.1...hod-onNodeOver

template методы это хуки для вставки своей функциональности при расширении класса. Вот тут описано: https://docs.sencha.com/extjs/5.0/co...mplate_Methods
Поскольку по своей природе они являются публичными (или как минимум protected) использовать их безопаснее чем приватные вещи ..меньше вероятность что что-то сломается при апгрейде экста.
Ответить с цитированием
  #6 (permalink)  
Старый 02.12.2015, 11:29
Аватар для Infarch
Профессор
Отправить личное сообщение для Infarch Посмотреть профиль Найти все сообщения от Infarch
 
Регистрация: 06.06.2014
Сообщений: 292

Насчет темплейтов - спасибо! Почитаю про них. А вот насчет всего остального я несколько сомневаюсь. Нашел я таки этот класс: http://docs.sencha.com/extjs/5.1/5.1...hod-onNodeOver . Только вот он приватный. А мне как-то стремно с приватными вещами баловаться. Сама же Сенча и предупреждает: This is a private utility class for internal use by the framework. Don't rely on its existence. Так что этот метод не сильно лучше моего выглядит.

Последний раз редактировалось Infarch, 02.12.2015 в 11:36.
Ответить с цитированием
  #7 (permalink)  
Старый 02.12.2015, 17:38
Профессор
Отправить личное сообщение для novikov Посмотреть профиль Найти все сообщения от novikov
 
Регистрация: 19.11.2012
Сообщений: 178

Ext.tree.ViewDropZone приватный, однако его предок Ext.dd.DropZone вполне себе публичный. В нём присутствует ваш шаблонный метод onNodeOver
Ответить с цитированием
  #8 (permalink)  
Старый 02.12.2015, 17:57
Профессор
Отправить личное сообщение для novikov Посмотреть профиль Найти все сообщения от novikov
 
Регистрация: 19.11.2012
Сообщений: 178

{
    viewConfig: {
		plugins: {
			ptype: 'gridviewdragdrop',
			dragText: 'Drag and drop to reorganize',
            dropZone : {
                onNodeOver : function (node, dd) {
                    var result = this.callParent(arguments);
                    
                    // we allow to drop to nodes having ID > 3
                    var record = dd.view.getRecord(node);
                    var isValid = record && record.getId() > 3;
                    
                    if (!isValid) {
                        return this.dropNotAllowed;
                    }

                    return result;
                }
            }
		}
	},
}


fiddle
Ответить с цитированием
  #9 (permalink)  
Старый 02.12.2015, 21:08
Профессор
Отправить личное сообщение для siber-biber Посмотреть профиль Найти все сообщения от siber-biber
 
Регистрация: 07.08.2013
Сообщений: 214

Сообщение от novikov Посмотреть сообщение
{
    viewConfig: {
		plugins: {
			ptype: 'gridviewdragdrop',
			dragText: 'Drag and drop to reorganize',
            dropZone : {
                onNodeOver : function (node, dd) {
                    var result = this.callParent(arguments);
                    
                    // we allow to drop to nodes having ID > 3
                    var record = dd.view.getRecord(node);
                    var isValid = record && record.getId() > 3;
                    
                    if (!isValid) {
                        return this.dropNotAllowed;
                    }

                    return result;
                }
            }
		}
	},
}


fiddle
Это выглядит работающим ..но вопрос тут в следующем: что в данном случае вызывает callParent() ?

Ведь вы переопределили метод прямо на инстансе дроп зоны.
И если воткнуть debugger и зайти в недра callParent вы увидите что вызывается метод класса "Ext.dd.DropTarget", что не есть искомый результат.
Ответить с цитированием
  #10 (permalink)  
Старый 03.12.2015, 09:59
Профессор
Отправить личное сообщение для novikov Посмотреть профиль Найти все сообщения от novikov
 
Регистрация: 19.11.2012
Сообщений: 178

Да, копипаст - это зло. Вот этот вариант должен удовлетворять требованиям задачи:

viewConfig: {
		plugins: [{
			ptype: 'gridviewdragdrop',
			dragText: 'Drag and drop to reorganize',
            dropZone : {
                onNodeOver : function (node, dd) {
                    // we allow to drop to nodes having ID > 3
                    var record = dd.view.getRecord(node);
                    var isValid = record && record.getId() > 3;

                    return isValid ? this.dropAllowed : this.dropNotAllowed;
                }
            }
		}]
	},


Возвращается имя ЦСС-класса.

фиддл

Последний раз редактировалось novikov, 03.12.2015 в 10:08.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Проверка 'авторизации' DJ_CD Элементы интерфейса 4 18.12.2014 15:19
Проверка встроенной поддержки типа с помощью библиотеки Modernizr viy.li Общие вопросы Javascript 1 16.08.2013 12:02
проверка формы не работает в ie begelme Javascript под браузер 6 13.08.2013 01:00
Проверка встроенной поддержки типа с помощью библиотеки Modernizr viy.li Библиотеки/Тулкиты/Фреймворки 3 15.06.2013 15:48
Проверка сайта AndreyS AJAX и COMET 5 28.07.2011 20:45