Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Сообщения за день
 

Вернуться   Форум Flasher.ru > Flash > ActionScript 3.0

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 18.03.2014, 00:39
SpetZ_Naz вне форума Посмотреть профиль Отправить личное сообщение для SpetZ_Naz Найти все сообщения от SpetZ_Naz
  № 1  
Ответить с цитированием
SpetZ_Naz

Регистрация: Aug 2012
Сообщений: 77
Question DataGrid - отслеживание изменений в ячейке, неужели нужно изобретать велосипед?

Здравствуйте, уважаемые форумчане!

Цель: отследить были ли произведены изменения в ячейке и если были, то перекрасить ее в другой цвет и показать кнопку Сохранить изменения, если изменения небыли произведены (или передумали вводить изменения), вернуть цвет обратно. Делается это с целью записи изменений в массив с указанием где именно внести изменения и внести их в xml из которого таблица и заполнялась.

Столкнулся с некоторыми проблемами, решить которые надеюсь в Вашей помощью.

Мои изыскания по достижению вышеописанной цели (за одно кому-то время сэкономлю с реализацией частичных решений):

Ниже привожу пример добывания вновь введенного текста, для меня это пока основная проблема (процесс сравнения и перекрашивания ячеек не обсуждаю и не описываю).

Начинаю с простого считывания текста по событию TextEvent.TEXT_INPUT и присвоение глобальной переменной _changedKey:
Код AS3:
 
private var _changedKey:String;
 
.......................................
 
dataGrid.addEventListener(TextEvent.TEXT_INPUT, onGridTextInputHandler);
 
protected function onGridTextInputHandler(event:TextEvent):void
		{
			_changedKey = event.target.text; 
		}
// ех, если бы оно сразу ловило свежевведенный  текст, но в _changedKey  не дописывается последний введенный символ
Как выясняется, с помощью события DataGrid --> TextEvent.TEXT_INPUT, не получится обновлять текст, так как данное событие выводит старый текст, т.е. на шаг опаздывает и не обновит переменную _changedKey 'свежим' текстом.

Самое простое решение присвоить последний вводимый символ запаздывающему тексту:

Код AS3:
private var _changedKey:String;
 
.......................................
 
dataGrid.addEventListener(TextEvent.TEXT_INPUT, onGridTextInputHandler);
 
protected function onGridTextInputHandler(event:TextEvent):void
		{
			_changedKey = event.target.text + event.text; //измененная строка 
		}
Недостаток: если мы поменяем позицию каретки и захотим продолжать вводит текст в середине слова, он всеравно продолжит присваиваться вконце слова.

Решение: Написать функцию, которая учитывает позицию каретки и присваивает новый символ в нужное место в слове.

Код AS3:
private var _changedKey:String;
private var _keyArrTemp: Array; //объявляем массив
private var _caret:uint; //объявляем переменную для каретки
 
 
.......................................
 
dataGrid.addEventListener(TextEvent.TEXT_INPUT, onGridTextInputHandler);
 
dataGrid.addEventListener(KeyboardEvent.KEY_DOWN, onGridKeyDownHandler); //вешаем новый слушатель
 
protected function onGridTextInputHandler(event:TextEvent):void
		{
			_changedKey = event.target.text + event.text; 
                                      convertSymbols(event.text, 'add'); // получаем введенный текст
		}
 
protected function onGridKeyDownHandler(keyevent:KeyboardEvent):void
		{
			_caret = keyevent.target.caretIndex; // считываем позицию каретки
                               }
 
protected function convertSymbols(text:String, backspace:String, ind:uint = 1):void 
		{
			switch (backspace)
			{
				case 'add':
				_keyArrTemp = _changedKey.split(''); // бью слово на буквы и записываем в массив
				_keyArrTemp.splice(_caret, 0, text); //записываю новую букву в позицию каретки
				break
			}
			_changedKey = _keyArrTemp.toString().split(',').join('');
		}
Работает. Но дальше вступает проблемка.. TextEvent.TEXT_INPUT - не умеет ловить клавиши Backspace и Del. поэтому нужно прослушивать нажатие клавиш клавиатуры. Программно ловим упомянутые клавиши:

Код AS3:
private var _changedKey:String;
private var _keyArrTemp: Array; //объявляем массив
private var _caret:uint;
 
.......................................
 
dataGrid.addEventListener(TextEvent.TEXT_INPUT, onGridTextInputHandler);
 
dataGrid.addEventListener(KeyboardEvent.KEY_DOWN, onGridKeyDownHandler); 
 
protected function onGridTextInputHandler(event:TextEvent):void
		{
			_changedKey = event.target.text + event.text; 
                                      convertSymbols(event.text, 'add'); 
		}
 
protected function onGridKeyDownHandler(keyevent:KeyboardEvent):void
		{
			_caret = keyevent.target.caretIndex; // считываем позицию каретки
 
                              if (_changedKey == '') _changedKey = keyevent.currentTarget.selectedItem[_colName];
 
 
		if (keyevent.keyCode == 8) convertSymbols(_changedKey, 'back'); // ловим клавишу backspace
		if (keyevent.keyCode == 127 || keyevent.keyCode == 46) // ловим клавишу del
                              convertSymbols(_changedKey, 'del');
                               }
 
protected function convertSymbols(text:String, backspace:String, ind:uint = 1):void 
		{
			switch (backspace)
			{
				case 'back':
				_keyArrTemp = text.split('');
				_keyArrTemp.splice(_caret-1, ind);
				break;
 
				case 'del':
				_keyArrTemp = text.split('');
				_keyArrTemp.splice(_caret, ind);
				break
 
				case 'add':
				_keyArrTemp = _changedKey.split('');
				_keyArrTemp.splice(_caret, 0, text);
				break
			}
			_changedKey = _keyArrTemp.toString().split(',').join('');
		}
Кто заметил неизвестную переменную _colName, она берется со слушателя DataGridEvent.ITEM_EDIT_BEGIN :

Код AS3:
 
dataGrid.addEventListener(DataGridEvent.ITEM_EDIT_BEGIN, onGridItemSelectedHandler);
 
protected function onGridItemSelectedHandler(eObj:Object):void 
		{
			_colName =  eObj.target.columns[eObj.columnIndex].dataField;
                               }

Ну так вот, дальше вступают следующие проблемы:

1. Как считывать редактирование текста, ели пользователю захотелось через зажатый Shift+стрелка влево (право) выделить текст и нажать Del (и еще хуже Backspace). Сработает алгоритм удаления Del или Back и удалится не то что нужно...

2. При выделении мышой нескольких букв и нажатии Ctrl-X нужно снова таки ловить эту комбинацию, высчитывать каретки, количесво выделенных букв... Короче гемор..


Пока в поисках простого решения данной задачи... Хоть бери каким-то образом отключай поддержку комбинаций клавиш, выделение Shift'ом и т.п. чтобы все работало, да и как отключить эти комбинации...

Вижу решение проблемы в том, чтобы каким-то образом искусственно генерировать событие TextEvent.TEXT_INPUT (та даже просто добавлять пробел вконце и сплитить его) дабы считывался вновь введенный текст... Но как это сделать.

Ну или может кто подскажет как он отслеживает изменения в ячейке DataGrid?


У кого какие идеи? Неужели и дальше придется велосипед изобретать?



.
__________________
Набирать программы могут многие, программировать - единицы

Старый 18.03.2014, 01:00
GBee вне форума Посмотреть профиль Отправить личное сообщение для GBee Найти все сообщения от GBee
  № 2  
Ответить с цитированием
GBee
 
Аватар для GBee

Регистрация: Jan 2009
Сообщений: 3,067
Записей в блоге: 3
Отправить сообщение для GBee с помощью Skype™
У вас какой грид то?
http://help.adobe.com/ru_RU/FlashPla...nt:itemEditEnd

Добавлено через 43 секунды
columnStretch
Отправляется, когда пользователь увеличивает ширину столбца. DataGrid

headerRelease
Отправляется, когда пользователь щелкает ячейку заголовка. DataGrid

itemEditBegin
Отправляется, когда установлено свойство editedItemPosition, и элемент доступен для редактирования. DataGrid

itemEditBeginning
Отправляется, когда пользователь подготавливает элемент к редактированию, например, отпустив над ним кнопку мыши. DataGrid

itemEditEnd
Передается, когда по какой-либо причине завершается сеанс редактирования элемента. DataGrid

itemFocusIn
Отправляется, когда элемент получает фокус. DataGrid

itemFocusOut
Отправляется, когда элемент теряет фокус.
__________________
Чтобы доказать, что вы не робот, причините вред другому человеку.

Старый 18.03.2014, 01:47
SpetZ_Naz вне форума Посмотреть профиль Отправить личное сообщение для SpetZ_Naz Найти все сообщения от SpetZ_Naz
  № 3  
Ответить с цитированием
SpetZ_Naz

Регистрация: Aug 2012
Сообщений: 77
Цитата:
Сообщение от GBee Посмотреть сообщение
У вас какой грид то?
Да простейший dataGrid. Во FlashBuilder 4.6 создал проект ActionScript. Во Flash CS 5.5 создал нужную мне форму, втащил туда местный компонент DataGrid дал ему имя 'dataGrid' и обращаюсь к нему из проекта. Я его точно так же мог создать программным кодом.

Хорошо, я вас понял. Вы предлагаете на itemEditBegin считывать исходное значение ячейки, а на itemEditEnd считывать измененное значение ячейки:

Код AS3:
_colName - объявлена в глобальной области
 
dataGridBase.addEventListener(DataGridEvent.ITEM_EDIT_BEGIN, onGridBeginEditHandler);
 
dataGridBase.addEventListener(DataGridEvent.ITEM_EDIT_END, onEditEndHandler);
 
protected function onGridBeginEditHandler(eObj:Object):void
		{
			_colName =  eObj.target.columns[eObj.columnIndex].dataField;
			_changedItem = eObj.target.selectedItem[_colName]; //Сюда должно записываться  значение ячейки до редактирования 
		}
 
protected function onEditEndHandler(eObj:Object):void
		{
			_colName =  eObj.target.columns[eObj.columnIndex].dataField;
			_changedItem = eObj.target.selectedItem[_colName]; //Сюда должно записываться значение после редактирования
		}
Нет, не считывает. В слушатель события ITEM_EDIT_END приходят одинаковые данные, без изменений. Может я не правильно делаю? Вы не могли бы конструктивней отвечать, с примерами?
__________________
Набирать программы могут многие, программировать - единицы

Старый 18.03.2014, 12:53
GBee вне форума Посмотреть профиль Отправить личное сообщение для GBee Найти все сообщения от GBee
  № 4  
Ответить с цитированием
GBee
 
Аватар для GBee

Регистрация: Jan 2009
Сообщений: 3,067
Записей в блоге: 3
Отправить сообщение для GBee с помощью Skype™
я так понял надо ловить itemEditBeginning и в событии уже приходит dataField и rowIndex, c помощью которых вы извлекаете значение из вашего датапровайдера. Типа

Код AS3:
_colName - объявлена в глобальной области
 
 
dataGrid.addEventListener(DataGridEvent.ITEM_EDIT_BEGINING, onGridBeginingEditHandler);
dataGrid.addEventListener(DataGridEvent.ITEM_EDIT_END, onEditEndHandler);
 
 
protected function onGridBeginingEditHandler(eObj:Object):void
{
	_colName =  eObj.dataField;
	_changedItem =  eObj.currentTarget.getItemAt(eObj.rowIndex)[eObj.dataField]; //Сюда должно записываться  значение ячейки до редактирования 
}
 
protected function onEditEndHandler(eObj:Object):void
{
	_colName =  eObj.dataField;
	_changedItem =  eObj.currentTarget.getItemAt(eObj.rowIndex)[eObj.dataField];//Сюда должно записываться значение после редактирования
}
__________________
Чтобы доказать, что вы не робот, причините вред другому человеку.

Старый 18.03.2014, 23:36
SpetZ_Naz вне форума Посмотреть профиль Отправить личное сообщение для SpetZ_Naz Найти все сообщения от SpetZ_Naz
  № 5  
Ответить с цитированием
SpetZ_Naz

Регистрация: Aug 2012
Сообщений: 77
Цитата:
Сообщение от GBee Посмотреть сообщение
я так понял надо ловить itemEditBeginning и в событии уже приходит dataField и rowIndex, c помощью которых вы извлекаете значение из вашего датапровайдера.
Нет, не ловит оно обновленную ячейку.. При переходе на следующую ячейку в слушатель события ITEM_EDIT_END приходит старое значение ячейки. Какой-то заколдованный круг.

Как же всетаки словить обновленное значение при окончании редактирования...?

Добавлено через 2 часа 44 минуты
В общем разобрался.

Решил через номера ячеек выкрутиться. Вот код:

Код AS3:
private var _tempArrChanges:Array = new Array();  // объявляем в глобальной области временный массив в 
                                                 //котором будем хранить значения покинутой ячейки
 
..............................................
dataGridBase.addEventListener(DataGridEvent.ITEM_EDIT_BEGINNING, onGridBeginEditHandler); // вешаем
                                       //слушателя на событие подготовки начала редактирования DataGrid'а
 
protected function onGridBeginEditHandler(eObj:Object):void 
		{			
			if (_tempArrChanges.length != 0)
			{
				var tempStr:String = '';  // строчка сравнения
				tempStr =  eObj.currentTarget.getItemAt(_tempArrChanges[0][0])[_tempArrChanges[0][1]];
 
				if (tempStr != _changedItem)  // сравниваем значения
				{
					Label.text = 'Были произведены изменения!!!';
				} else 
				{
					Label.text = 'Без изменений';
				}
			}
			_changedItem =  eObj.currentTarget.getItemAt(eObj.rowIndex)[eObj.dataField]; // записываем значение на которой клацнул пользователь
 
			if (_tempArrChanges.length != 0) _tempArrChanges.splice(0,1); // удалим 
                                                                   //ненужную больше запись
 
			_tempArrChanges.push([eObj.rowIndex, eObj.dataField]); // запомним номер строки 
                                                     //и имя столбика на котором клацнули
		}
GBee, спасибо. Ваши комментарии не пропали в пустую.


.
__________________
Набирать программы могут многие, программировать - единицы

Старый 19.03.2014, 20:34
djyamato вне форума Посмотреть профиль Отправить личное сообщение для djyamato Посетить домашнюю страницу djyamato Найти все сообщения от djyamato
  № 6  
Ответить с цитированием
djyamato
 
Аватар для djyamato

Регистрация: Feb 2006
Сообщений: 884
Записей в блоге: 2
Отправить сообщение для djyamato с помощью ICQ Отправить сообщение для djyamato с помощью Skype™
http://divisionby0.org/?p=77 возможно это вам поможет

Старый 19.03.2014, 23:51
SpetZ_Naz вне форума Посмотреть профиль Отправить личное сообщение для SpetZ_Naz Найти все сообщения от SpetZ_Naz
  № 7  
Ответить с цитированием
SpetZ_Naz

Регистрация: Aug 2012
Сообщений: 77
Цитата:
Сообщение от djyamato Посмотреть сообщение
http://divisionby0.org/?p=77 возможно это вам поможет
Да, тоже выход, идея хорошая, спасибо. Остановлюсь все же на своем способе.

Адобовцы могли более грамотней организовать слежение за изменениями в DataGrid'е... Ну, надеюсь приведенные способы кому-нибудь сэкономят день-два поисков.



.
__________________
Набирать программы могут многие, программировать - единицы

Старый 08.07.2014, 00:52
SpetZ_Naz вне форума Посмотреть профиль Отправить личное сообщение для SpetZ_Naz Найти все сообщения от SpetZ_Naz
  № 8  
Ответить с цитированием
SpetZ_Naz

Регистрация: Aug 2012
Сообщений: 77
Всетаки мой способ, так скажем, запаздывает на один шаг - пока не нажмешь на другой ячейке, редактирование не будет зафиксировано, что не совсем удобно..

Ссылка выше не работает уже..

Может кто подскажет ссылочку на более адекватные реализации отслеживания изменений в ячейке DataGrid (Флеш) ?
__________________
Набирать программы могут многие, программировать - единицы

Старый 21.09.2014, 20:17
SpetZ_Naz вне форума Посмотреть профиль Отправить личное сообщение для SpetZ_Naz Найти все сообщения от SpetZ_Naz
  № 9  
Ответить с цитированием
SpetZ_Naz

Регистрация: Aug 2012
Сообщений: 77
Кто сталкивался с проблемой моментального отслеживания изменений в ячейках DataGrid (Flash)(при наборе текста например), прошу поделиться решением... Максимум на что вышел - это отследить изменения при смене фокуса с ячейки.. моментально не получается.
__________________
Набирать программы могут многие, программировать - единицы

Старый 21.09.2014, 20:47
Gerbert вне форума Посмотреть профиль Найти все сообщения от Gerbert
  № 10  
Ответить с цитированием
Gerbert
Banned
[+1 06.12.14]
[+1 18.12.14]
[+1 30.12.14]

Регистрация: Aug 2014
Сообщений: 461
Это Вы полгода все ещё с сеткой какой-то разбираетесь?))))

Создать новую тему Ответ Часовой пояс GMT +4, время: 09:57.
Быстрый переход
  « Предыдущая тема | Следующая тема »  

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


Часовой пояс GMT +4, время: 09:57.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.