Кнопки: Библиотека ExtJS для новичков
Эта статья является продолжением учебника по библиотеке компонентов ExtJS, используемой для создания web-приложений с функциональным интерфейсом пользователя.
Один из самых простых компонентов библиотеки – кнопка (Button), создается тривиально:
button = new Ext.Button({
text: 'Кнопка',
renderTo: Ext.getBody()
})
Что обычно требуется от кнопки? Правильно: реагировать на нажатия. Давайте определим специальную функцию ShowMessage(), которая будет выдавать простое сообщение пользователю о нажатии на кнопку:
function ShowMessage() {
Ext.MessageBox.alert("На меня нажали!", "Сообщение");
}
Присвоим ранее созданной кнопке эту функцию-обработчик.
button.setHandler(ShowMessage)
Обратите внимание, что многие начинающие разработчики в этом месте создают ошибку: указывают имя функции со скобками ShowMessage() вместо ссылки на нее как на объект ShowMessage, что приводит к вызову функции, а потом передаче в качестве параметра возвращенного ей результата, что неверно.
Щелкаем по кнопке – получаем сообщение:
Функцию-обработчик можно задавать напрямую в конфигурации компонента как анонимную функцию:
button = new Ext.Button({
text: 'Кнопка',
renderTo: Ext.getBody(),
handler: function() { Ext.MessageBox.alert("На меня нажали!", "Сообщение"); }
})
Для удобства нескольким кнопкам можно присваивать один обработчик. Обратимся к новому примеру:
function ButtonClick() {
Ext.MessageBox.alert("На меня нажали!", "Сообщение");
}
for (i=1;i<=10;i++) {
new Ext.Button({
text: 'Кнопка номер '+i,
renderTo: Ext.getBody(),
handler: ButtonClick,
id: 'button_'+i
})
}
Теперь при нажатии на любую из созданных в цикле десяти кнопок будет запускаться одна и та же функция:
Обратите внимание, что на этот раз мы не сохраняем созданный в результате вызова конструктора кнопки объект, а задаем в его конфигурации параметр id вида button_N, где N – порядковый номер кнопки. В дальнейшем зная идентификатор компонента можно получить его объект конструкцией:
Ext.getCmp(‘button_N’)
Следующий цикл выполняет перебор ранее созданных кнопок и их переименование:
for (i=1;i<=10;i++) {
Ext.getCmp('button_'+i).setText('Кнопочка '+i)
}
Интересно, а можно с помощью всего лишь одной функции-обработчика сделать привязку к нажатой кнопке? Переопределим функцию-обработчик, добавив ей два параметра: button (объект кнопки, которая была нажата) и e (тип полученного обработчиком события):
function ButtonClick(button, e) {
Ext.MessageBox.prompt("Изменить?", "Введите новое название кнопки", function(btn, text) {
if (btn == 'ok') {
button.setText(text)
}
})
}
К сожалению, простого переопределения функции в Firebug с таким же именем для привязки к ранее созданным кнопкам недостаточно. Снова переберем существующие кнопки и присвоим новый обработчик:
for (i=1; i<=10; i++) {
Ext.getCmp('button_'+i).setHandler(ButtonClick)
}
Проверяем: кнопки переименовываются!
В обычном HTML кнопка задается подобными тегами:
<input type="submit" id="btnLaunch" value="Lancer" name="btnLaunch"/>
А что представляет из себя компонент-кнопка из библиотеки ExtJS в DOM-документе? Вы будете смеяться, но это таблица с декоративными элементами и тегом <button>:
<table cellspacing="0" cellpadding="0" border="0" class="x-btn-wrap x-btn x-btn-text-icon" id="ext-comp-1169" style="width: auto;"> <tbody><tr> <td class="x-btn-left"><i> </i></td> <td class="x-btn-center"><em unselectable="on"> <button type="button" class="x-btn-text" id="ext-gen138" style="background-image: url(/img/settings.gif);"> Profile</button></em></td><td class="x-btn-right"><i> </i> </td></tr> </tbody> </table>
Внутренняя структура одной из наших кнопок в Firebug:
Давайте посмотрим, как можно управлять положением кнопок с помощью изменения свойств их DOM-элементов.
function getBrowserHeight() {
return document.compatMode=='CSS1Compat' && !window.opera?
document.documentElement.clientHeight:document.body.clientHeight;
}
function getBrowserWidth() {
return document.compatMode=='CSS1Compat' && !window.opera?
document.documentElement.clientWidth:document.body.clientWidth;
}
for (i=1;i<=10;i++) {
dom = Ext.getCmp('button_'+i).el.dom;
dom.style.position="absolute";
dom.style.marginLeft=Math.round(Math.random()*(getBrowserWidth()-dom.clientWidth));
dom.style.marginTop=Math.round(Math.random()*(getBrowserHeight()-dom.clientHeight));
}
Выше мы определили две кроссбраузерные функции getBrowserHeight() и getBrowserWidth(), которые будут оценивать доступную область экрана (соответственно высоту и ширину) браузера в пикселах. Далее в процессе цикла перебираем все кнопки и присваиваем им абсолютные координаты, сгенерировав их из случайных значений. Обратите внимание, что мы подсчитываем метрику окна браузера, вычитаем из этого значения метрику кнопки (чтобы не появлялись полосы прокрутки) и на основании полученной величины присваиваем верхней или левой координате DOM-элемента кнопки случайное значение из этого диапазона:
Теперь немного позабавимся: сделаем так, что кнопки заживут своей жизнью. Давайте представим, что каждая кнопка будет двигаться в собственном направлении, которое определяется двумя переменными кнопки moveX и moveY, имеющими значения -1 (для сдвига против оси), 0 (без изменения по оси) и 1 (для сдвига по оси). Для удобства зададим функцию-генератор этих значений:
function getDirection() {
return Math.round(Math.random()*2)-1;
}
Задаем первоначальные направления движения кнопкам:
for (i=1;i<=10;i++) {
Ext.getCmp('button_'+i).moveX = getDirection();
Ext.getCmp('button_'+i).moveY = getDirection();
}
А теперь реализуем функцию crazy(), которая будет осуществлять движение:
function crazy() {
for (i=1;i<=10;i++) {
comp = Ext.getCmp('button_'+i)
X = parseInt(comp.el.dom.style.marginLeft);
X += comp.moveX;
if ((X == 0) || (X == (getBrowserWidth()-comp.el.dom.clientWidth))) {
comp.moveX = invertDirection(comp.moveX);
}
comp.el.dom.style.marginLeft = X;
Y = parseInt(comp.el.dom.style.marginTop);
Y += comp.moveY;
if ((Y == 0) || (Y == (getBrowserHeight()-comp.el.dom.clientHeight))) {
comp.moveY = invertDirection(comp.moveY);
}
comp.el.dom.style.marginTop = Y;
}
}
function invertDirection(dir) {
if (dir == -1) { return 1; }
if (dir == 1) { return -1; }
return 0;
}
Выше мы определили функцию crazy, которая высчитывает изменения координат кнопок, а при достижении границ экрана меняет направление движения на обратное с помощью вспомогательной функции invertDirection.
Запускаем в работу:
setInterval(«crazy()», 100)
Заметьте, что во время отображения всплывающего окна с сообщением при нажатии любой кнопки, их движение продолжается несмотря на то, что выводится модальный диалог.
Что еще можно делать с кнопками?
- С помощью метода focus() определенной кнопке можно передать фокус ввода.
- К кнопке можно привязать выпадающее меню (свойство menu конфигурации компонента и его методы showMenu и hideMenu)
- Кнопка может работать в режиме переключателя (свойства enableToggle, pressed, toggleHandler и toggleGroup в конфигурации и свойство объекта toggle)
- Кнопку можно заблокировать (свойство disabled в конфигурации)
- К кнопке можно добавить изображение-иконку (свойство icon в конфигурации и его метод setIconClass)
- К кнопке можно добавить всплывающую подсказку (свойства tooltip и tooltipType в конфигурации)
Перейти далее к разделу Расширенная работа с панелями…
Перейти к содержанию Учебника по ExtJS






| setInterval(«crazy()», 100)
crazy же в данном случае надо писать без скобок…
Абсолютно не понятно для чего нужен параметр «е» в функции
function ButtonClick(button, e) {
Ext.MessageBox.prompt(«Изменить?», «Введите новое название кнопки», function(btn, text) {
if (btn == ‘ok’) {
button.setText(text)
}
})
}
Так же не плохо было бы объяснить в тексте что в callback функцию автоматом передается код нажатой пользователем кнопки и введенный им текст.
Автор, вы мне так и не скажете для чего нужен параметр «e» в функции:
function ButtonClick(button, e) {
Ext.MessageBox.prompt(«Изменить?», «Введите новое название кнопки», function(btn, text) {
if (btn == ‘ok’) {
button.setText(text)
}
})
}
Код работает и без него.
Хорошие статьи, как раз для самых начинающих.
Пишите еще!
А примерчик доходчивый можно по кнопке toggle. Ато чото пишет enableToggle – не функция