css, html, php, javascript, jQuery, ajax … – решения, примеры, рецепты
27 Фев
Итак в предыдущей статье (jqGrid Часть I:Знакомство) мы с вами подготовили платформу для опытов и выполнили «пробный запуск» плагина, с самыми «базовейшими» параметрами. Согласно которым таблица запрашивает данные с сервера в XML разметке, при этом у нас есть возможность сортировать данные в столбцах.
В данной статье мы продолжим эксперименты и прощупаем еще ряд замечательных возможностей jqGrid, вот план действий:
I. Другие способы загрузки данных
1) Загрузка данных в виде JSON объекта
JSON – как и XML является текстовым форматом обмена данными, при этом намного моложе последнего. Является более прогрессивным методом, благодаря большей гибкости своей архитектуры по сравнению с XML. На тему сравнения XML и JSON есть очень хорошая статья (JSON и XML. Что лучше?). Но при генерировании ответа в JSON методами PHP, есть ряд особенностей при работе с кириллицей. Повествование о которых выходит за рамки данной статьи, поэтому я ограничиваюсь лишь упоминанием.
Итак на практике загрузка таких данных требует следующей конфигурации плагина:
$(function(){
$('#table').jqGrid({
url:'p2e1.php',
datatype: 'json',
mtype: 'GET',
colNames:['Код страны','Код региона', 'Город','Долгота','Широта','nbip'],
colModel :[
{name:'country_code', index:'country_code', width:80},
{name:'region_code', index:'region_code', width:80},
{name:'city', index:'city', width:90},
{name:'latitude', index:'latitude', width:60},
{name:'longitude', index:'longitude', width:60},
{name:'nbip', index:'nbip', width:30}],
pager: $('#tablePager'),
rowNum:10,
rowList:[10,20,30,100],
sortname: 'city',
sortorder: 'asc',
caption: 'Загрузка JSON данных',
rownumbers: true,
rownumWidth: 40
});
});
Все изменения я выделил отступами (строки 4, 19-21). Как вы можете видеть в листинге параметру datatype: присвоено значение ‘json’, что говорит плагину о том что от сервера ожидается ответ в виде JSON объекта. Далее я ввел в конфиг таблицы еще три свойства caption, rownumbers, rownumWidth. Что они определяют?
С данного момента, я ввожу еще одно правило в этот цикл статей. Все свойства-параметры инициализации jqGrid вы будете самостоятельно изучать на странице документации плагина в разделе Options и colModel Options. Но при этом я буду комментировать, то на что следует обратить внимание.
C параметрами клиентской части разобрались, теперь перейдем к серверной. Здесь я привожу листинг только последних строк кода, собственно это момент формирования и вывод ответа сервера.
Пример 1 – используя массив
...
// Начало формирование массива
// для последующего преобразоования
// в JSON объект
$data['page'] = $page;
$data['total'] = $total_pages;
$data['records'] = $count;
// Строки данных для таблицы
$i = 0;
while($row = mysql_fetch_assoc($result)) {
$data['rows'][$i]['id'] = $row['id'];
$data['rows'][$i]['cell'][] = $row['country_code'];
$data['rows'][$i]['cell'][] = $row['region_code'];
$data['rows'][$i]['cell'][] = $row['city'];
$data['rows'][$i]['cell'][] = $row['latitude'];
$data['rows'][$i]['cell'][] = $row['longitude'];
$data['rows'][$i]['cell'][] = $row['nbip'];
$i++;
}
// Перед выводом не забывайте выставить header
// с типом контента и кодировкой
header("Content-type: application/json;charset=utf-8");
echo json_encode($data);
Пример 2 – используя объект
...
// Начало формирование объекта
// для последующего преобразоования
// в JSON объект
$data->page = $page;
$data->total = $total_pages;
$data->records = $count;
// Строки данных для таблицы
$i = 0;
while($row = mysql_fetch_assoc($result)) {
$data->rows[$i]['id'] = $row[id];
$data->rows[$i]['cell'] = array($row[country_code],$row[region_code],$row[city],$row[latitude],$row[longitude],$row[nbip]);
$i++;
}
// Перед выводом не забывайте выставить header
// с типом контента и кодировкой
header("Content-type: text/script;charset=utf-8");
echo json_encode($data);
Оба подхода выполняют одни и те же действия, но при этом выбор подхода зависит от ваших предпочтений и уровня мастерства.
Вот ссылка на ДЕМО2.1 и ссылка на архив с примером.
Подытожив, скажу, что как видите в данном способе загрузки данных нет ничего сложного и принцип работы идентичен с загрузкой данных в виде XML, но при этом немного облегчается код серверного скрипта. Также повторюсь, что при кодировании данных в JSON методом PHP следует учитывать особенности работы с кириллицей!
2) Загрузка данных в виде массива
Теперь рассмотрим пример, как можно создать jqGrid используя в качестве источника данных массив. Как вы понимаете для данного примера не понадобится серверный скрипт, а клиентский скрипт будет выглядеть приблизительно так.
$(function(){
$('#table').jqGrid({
datatype: 'local',
colNames:['ID','Код страны','Код региона', 'Город','Долгота','Широта','nbip'],
colModel :[
{name:'id', index:'id', width:20},
{name:'country_code', index:'country_code', width:80},
{name:'region_code', index:'region_code', width:80},
{name:'city', index:'city', width:90},
{name:'latitude', index:'latitude', width:60},
{name:'longitude', index:'longitude', width:60},
{name:'nbip', index:'nbip', width:30}
],
caption: 'Загрузка массива данных'
});
var data = [
{id: '1', country_code:'AD', region_code:'02', city:'Canillo', latitude:'42.5667', longitude: '1.6', nbip:'0'},
{id: '2', country_code:'AD', region_code:'02', city:'El Tarter', latitude:'42.5833', longitude: '1.65', nbip:'0'},
{id: '3', country_code:'AD', region_code:'03', city:'Encamp', latitude:'42.5333', longitude: '1.5833', nbip:'0'},
{id: '4', country_code:'AD', region_code:'04', city:'Arinsal', latitude:'42.5667', longitude: '1.4833', nbip:'1'},
{id: '5', country_code:'AD', region_code:'04', city:'La Massana', latitude:'42.55', longitude: '1.5167', nbip:'0'},
{id: '6', country_code:'AD', region_code:'04', city:'Llorts', latitude:'42.6', longitude: '1.5333', nbip:'0'},
{id: '7', country_code:'AD', region_code:'05', city:'Ordino', latitude:'42.55', longitude: '1.5333', nbip:'2'},
{id: '8', country_code:'AD', region_code:'06', city:'Sant JuliГ De LГІria', latitude:'42.4667', longitude: '1.5', nbip:'0'},
{id: '9', country_code:'AD', region_code:'07', city:'Andorra La Vella', latitude:'42.5', longitude: '1.5167', nbip:'56'},
{id: '10', country_code:'AD', region_code:'08', city:'Engordany', latitude:'42.5167', longitude: '1.55', nbip:'1'},
{id: '11', country_code:'AD', region_code:'08', city:'Les Escaldes', latitude:'42.5', longitude: '1.5333', nbip:'0'},
{id: '12', country_code:'AE', region_code:'01', city:'Abu Dhabi', latitude:'24.4667', longitude: '54.3667', nbip:'824'},
{id: '13', country_code:'AE', region_code:'01', city:'Al Ain', latitude:'24.1917', longitude: '55.7606', nbip:'19'},
{id: '14', country_code:'AE', region_code:'03', city:'Deira', latitude:'25.2722', longitude: '55.3111', nbip:'0'},
{id: '15', country_code:'AE', region_code:'03', city:'Dubai', latitude:'25.2521', longitude: '55.28', nbip:'7082'},
{id: '16', country_code:'AE', region_code:'03', city:'Jumairah', latitude:'25.2097', longitude: '55.2478', nbip:'0'},
{id: '17', country_code:'AE', region_code:'04', city:'Fujairah', latitude:'25.1231', longitude: '56.3375', nbip:'1'},
{id: '18', country_code:'AE', region_code:'05', city:'Ras Al Khaima', latitude:'25.7911', longitude: '55.9428', nbip:'0'},
{id: '19', country_code:'AE', region_code:'05', city:'Ras Al Khaimah', latitude:'25.7911', longitude: '55.9428', nbip:'2'},
{id: '20', country_code:'AE', region_code:'06', city:'Dibba', latitude:'25.6167', longitude: '56.2667', nbip:'1'},
{id: '21', country_code:'AE', region_code:'06', city:'Sharjah', latitude:'25.3622', longitude: '55.3911', nbip:'297'},
{id: '22', country_code:'AF', region_code:'11', city:'Herat', latitude:'34.3469', longitude: '62.1983', nbip:'0'},
{id: '23', country_code:'AF', region_code:'13', city:'Kabul', latitude:'34.5167', longitude: '69.1833', nbip:'161'},
{id: '24', country_code:'AF', region_code:'23', city:'Iran', latitude:'31.8314', longitude: '65.0689', nbip:'0'},
{id: '25', country_code:'AF', region_code:'23', city:'Kandahar', latitude:'31.6125', longitude: '65.7094', nbip:'0'}
]
for(var i = 0;i <= data.length; i++){
$('#table').jqGrid('addRowData',i+1,data[i]);
}
});
Как видите и в этом примере нет ничего «военного», все предельно просто. В качестве datatype: указываем ‘local’. Далее каким-либо образом(в данном примере простым присвоением) создаем массив объектов (каждая строка данных является объектом) и производим добавление данных методом addRowData в цикле (for(var i = 0;i <= data.length; i++)).
На данном этапе мне следует дать небольшой комментарий. Почему я написал «… добавление данных методом …» а при этом вся конструкция выглядит как передача параметра. Т.е. фактически происходит передача названия метода addRowData методу jqGrid() в качестве параметра. Дело все в том, что с версии 3.6 разработчики реализовали новый API для работы с jqGrid, согласно которому запись вида $(‘#table’).jqGrid(‘addRowData’,i+1,data[i]); равноценна $(‘#table’).addRowData(i+1,data[i]); Но будьте внимательны, не все методы могут быть использованы в аннотации нового API, перед использованием методов обязательно ознакомьтесь с документацией по данному методу на странице Methods.
Также в свойствах инициализации jqGrid вы не найдете параметров панели-листалки, потому что данные уже загружены и нет необходимости запрашивать их порциями.
Если присмотреться, то можно заметить что данный способ загрузки данных напоминает работу с JSON, но только на стороне клиента. Такой способ может пригодиться если вы по каким-либо причинам не можете сформировать XML или JSON ответ с данными от сервера.
3) Конвертирование простой таблицы в jqGrid
Данный способ создания jqGrid будет полезен во время «страховки» на странице. Т.е. у нас есть страница, на которой есть таблица jqGrid в «нормальном браузере», но как же пользователи у которых браузер не поддерживает JavaScript (Простите но тут обязан быть смайл
)? Они не увидят таблицу? И вот тут то и пригодится данное свойство плагина.
План действий таков:
Вот и листинг
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>
<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<title>Осваиваем jqGrid с Linkexchanger</title></p>
<link rel='stylesheet' type='text/css' media='screen' href='css/flick/jquery-ui-1.7.2.custom.css' />
<link rel='stylesheet' type='text/css' media='screen' href='css/ui.jqgrid.css' />
<p><style>
html, body {
margin: 0;
padding: 0;
font-size: 80%;
}
</style>
<script type='text/javascript' src='js/jquery-1.4.min.js'></script>
<script src='js/i18n/grid.locale-ru.js' type='text/javascript'></script>
<script src='js/jquery.jqgrid.min.js' type='text/javascript'></script>
<script type='text/javascript'>
$(function(){
$('#table').click(function(){
tableToGrid('#table');
});
});
</script></head>
<body>
<?php
// Подключение и выбор БД
//$db = mysql_connect('database_host', 'database_user', 'database_password');
//mysql_select_db('database_name');
// Подключение и выбор БД
$db = mysql_connect('database_host', 'database_user', 'database_password');
mysql_select_db('database_name');</p>
// Запрос выборки данных
$query = 'SELECT id, country_code, region_code, city, latitude, longitude, nbip FROM cities LIMIT 30';
$result = mysql_query($query);
// Строим таблицу с данными
echo "<table id='table' border='1'>";
echo "<thead><tr><th>ID</th><th>Код страны</th><th>Код региона</th><th>Город</th><th>Долгота</th><th>Широта</th><th>nbip</th></tr></thead>";
while($row = mysql_fetch_assoc($result)) {
echo "<tbody><tr><td>'.$row['id'].'</td><td>'.$row['country_code'].'</td><td>'.$row['region_code'].'</td><td>'.$row['city'].'</td>td>'.$row['latitude'].'</td><td>'.$row['longitude'].'</td><td>'.$row['nbip'].'</td></tr></tbody>";
}
echo "</table>";
?>
</body>
</html>
И ссылка на ДЕМО2.2 (просто кликните на таблицу)
Как видите простейший код, при клике на объект #table собственно таблицу, выполняется функция tableToGrid() которой в качестве параметра передается селектор таблицы которую следует преобразовать в jqGrid.
Использование свойств при конвертировании таблицы в jqGrid
И раз уж мы начали разговор про этот метод инициализации jqGrid, то давайте рассмотрим на примере ДЕМО2.2_1 его работу. А следом и код
var options = {
caption: 'Конвертирование таблицы',
width: 800,
height: 600,
colModel :[
{name:'ID', width:20},
{name:'Код страны', width:80},
{name:'Страна', width:100, formatter:'select', editoptions:{value:"AD:Andorra; AE:United Arab Emirates; AF:Afghanistan; AG:Antigua and Barbuda; AI:Anguilla; AL:Albania; AM:Armenia; AN:Netherland Antilles; AO:Angola; AR:Argentina"}},
{name:'Код региона', width:80},
{name:'Город', width:90},
{name:'Долгота', width:60},
{name:'Широта', width:60},
{name:'nbip', index:'nbip', width:30}
]};
tableToGrid("#table",options);
Как видите при использовании этой функции, в качестве второго параметра можно передать объект с параметрами таблицы. Но при этом следует обратить внимание на то, что заголовки столбцов должны иметь такое же имя как и текст в заголовке конвертируемой таблицы. Я думаю вы обратили внимание на дополнительные параметры в строке 8, мы рассмотрим их далее в этой статье.
II. Форматирование данных
1) Форматирование ячеек
Википедия определяет Форматирование как «приведение чего-либо к какому-либо формату». Соответственно в нашем случае это будет преобразование полученных от сервера данных, к другому виду. jqGrid позволяет производить как простое так и сложное форматирование. «Простым форматированием» я условно назвал «Выравнивание» и «Изменением цвета» данных при этом мы «форматируем ячейку».
Давайте посмотрим как это делается на примере ДЕМО2.3
$(function(){
$('#table').jqGrid({
datatype: 'local',
colNames:['ID','Код страны','Код региона', 'Город','Долгота','Широта','nbip'],
colModel :[
{name:'id', index:'id', width:20, align: 'center'},
{name:'country_code', index:'country_code', width:80, align: 'right'},
{name:'region_code', index:'region_code', width:80, align: 'left'},
{name:'city', index:'city', width:90},
{name:'latitude', index:'latitude', width:60},
{name:'longitude', index:'longitude', width:60},
{name:'nbip', index:'nbip', width:30}
],
caption: 'Простое форматирование',
width: 600,
afterInsertRow: function(row_id, row_data){
if (row_data.country_code == 'AD') {
$('#table').jqGrid('setCell',row_id,'city','',{'color':'#FF00FF'});
}else if(row_data.country_code == 'AE'){
$('#table').jqGrid('setCell',row_id,'city','',{'color':'red'});
}else{
$('#table').jqGrid('setCell',row_id,'city','',{'background-color': '#999999'});
if(row_data.country_code == 'CZ'){
$('#table').jqGrid('setCell',row_id,'city','',{'color':'#FF00FF', 'font-weight':'bold'},{'title': 'Чехия Ура!'});
}
}
}
});
var data = [
{id: '1', country_code:'AD', region_code:'02', city:'Canillo', latitude:'42.5667', longitude: '1.6', nbip:'0'},
{id: '2', country_code:'AD', region_code:'02', city:'El Tarter', latitude:'42.5833', longitude: '1.65', nbip:'0'},
{id: '3', country_code:'AD', region_code:'03', city:'Encamp', latitude:'42.5333', longitude: '1.5833', nbip:'0'},
{id: '4', country_code:'AD', region_code:'04', city:'Arinsal', latitude:'42.5667', longitude: '1.4833', nbip:'1'},
{id: '5', country_code:'AD', region_code:'04', city:'La Massana', latitude:'42.55', longitude: '1.5167', nbip:'0'},
{id: '6', country_code:'AD', region_code:'04', city:'Llorts', latitude:'42.6', longitude: '1.5333', nbip:'0'},
{id: '7', country_code:'AD', region_code:'05', city:'Ordino', latitude:'42.55', longitude: '1.5333', nbip:'2'},
{id: '8', country_code:'AD', region_code:'06', city:'Sant JuliГ De LГІria', latitude:'42.4667', longitude: '1.5', nbip:'0'},
{id: '9', country_code:'AD', region_code:'07', city:'Andorra La Vella', latitude:'42.5', longitude: '1.5167', nbip:'56'},
{id: '10', country_code:'AD', region_code:'08', city:'Engordany', latitude:'42.5167', longitude: '1.55', nbip:'1'},
{id: '11', country_code:'AD', region_code:'08', city:'Les Escaldes', latitude:'42.5', longitude: '1.5333', nbip:'0'},
{id: '12', country_code:'AE', region_code:'01', city:'Abu Dhabi', latitude:'24.4667', longitude: '54.3667', nbip:'824'},
{id: '13', country_code:'AE', region_code:'01', city:'Al Ain', latitude:'24.1917', longitude: '55.7606', nbip:'19'},
{id: '14', country_code:'AE', region_code:'03', city:'Deira', latitude:'25.2722', longitude: '55.3111', nbip:'0'},
{id: '15', country_code:'AE', region_code:'03', city:'Dubai', latitude:'25.2521', longitude: '55.28', nbip:'7082'},
{id: '16', country_code:'AE', region_code:'03', city:'Jumairah', latitude:'25.2097', longitude: '55.2478', nbip:'0'},
{id: '17', country_code:'AE', region_code:'04', city:'Fujairah', latitude:'25.1231', longitude: '56.3375', nbip:'1'},
{id: '18', country_code:'AE', region_code:'05', city:'Ras Al Khaima', latitude:'25.7911', longitude: '55.9428', nbip:'0'},
{id: '19', country_code:'AE', region_code:'05', city:'Ras Al Khaimah', latitude:'25.7911', longitude: '55.9428', nbip:'2'},
{id: '20', country_code:'AE', region_code:'06', city:'Dibba', latitude:'25.6167', longitude: '56.2667', nbip:'1'},
{id: '21', country_code:'AE', region_code:'06', city:'Sharjah', latitude:'25.3622', longitude: '55.3911', nbip:'297'},
{id: '22', country_code:'AF', region_code:'11', city:'Herat', latitude:'34.3469', longitude: '62.1983', nbip:'0'},
{id: '23', country_code:'AF', region_code:'13', city:'Kabul', latitude:'34.5167', longitude: '69.1833', nbip:'161'},
{id: '24', country_code:'AF', region_code:'23', city:'Iran', latitude:'31.8314', longitude: '65.0689', nbip:'0'},
{id: '25', country_code:'AF', region_code:'23', city:'Kandahar', latitude:'31.6125', longitude: '65.7094', nbip:'0'},
{id: '26', country_code:'CZ', region_code:'23', city:'Stav', latitude:'50.4667', longitude: '15.4667', nbip:'0'}
]
for(var i = 0;i <= data.length; i++){
$('#table').jqGrid('addRowData',i+1,data[i]);
}
});
Для этого примера я взял код «Загрузки данных из массива». Давайте разберем, то что изменилось. Во-первых для удобства это таблица имеет ширину 600px (width: 600), во-вторых появился обработчик на событие afterInsertRow и в-третьих – в набор данных добавилась строка id 26.
Итак выравнивание текста в ячейке осуществляется простым определением свойства align в модели столбца (colModel).
А вот чтобы раскрасить, а также изменить другие стилевые свойства ячейки, нужно писать пользовательскую функцию, например как та что написал я. Давайте разберемся что же происходит.
Сразу после добавления строки в таблицу возникает событие afterInsertRow (все события вы можете изучить на странице Events), при котором выполняется функция. Функции принимает в качестве параметров (см. описание события) Id строки (row_id) и объект с данными (row_data) текущей строки, вставка которой вызвала событие. Далее смотрим чему равен country_code текущей строки.
Как вы понимаете благодаря такому подходу, можно раскрасить таблицу как угодно.
2) Изменение представления данных
Другим мощным инструментом форматирования данных в jqGrid является набор «предопределенных форматтеров» (Predefined Formatter). Это функции, которые выполняются над данными в столбце.
Существует 9 стандартных форматтеров
$(function(){
$('#table').jqGrid({
url:'p2e4.php',
datatype: 'json',
mtype: 'GET',
colNames:['id', 'integer', 'number', 'currency','date','email','link','showlink','checkbox','select','ip'],
colModel :[
{name:'id', index:'id', width:15},
{name:'integer', index:'integer', width:50},
{name:'number', index:'number', width:50},
{name:'currency', index:'currency', width:60},
{name:'date', index:'date', width:65},
{name:'email', index:'email', width:70},
{name:'link', index:'link', width:300},
{name:'showlink', index:'showlink', width:130},
{name:'checkbox', index:'checkbox', width:35},
{name:'select', index:'select', width:30},
{name:'ip', index:'ip', width:50}],
caption: 'Данные в чистом виде',
autowidth: true
});
$('#tableFormated').jqGrid({
url:'p2e4.php',
datatype: 'json',
mtype: 'GET',
colNames:['id', 'integer', 'number', 'currency','date','email','link','showlink','checkbox','select','ip'],
colModel :[
{name:'id', index:'id', width:15},
{name:'integer', index:'integer', width:50, formatter:'integer', formatoptions:{defaultValue: 'n.a.'}},
{name:'number', index:'number', width:50, formatter:'number',formatoptions:{decimalPlaces: 3}},
{name:'currency', index:'currency', width:60, formatter:'currency',formatoptions:{prefix: '$', suffix:'p.'}},
{name:'date', index:'date', width:65, formatter: 'date',formatoptions:{srcformat:'Y-m-d H:i:s',newformat:'F d'}},
{name:'email', index:'email', width:70, formatter: 'email'},
{name:'link', index:'link', width:300, formatter:'link',formatoptions:{target: '_blank'}},
{name:'title', index:'title', width:130, formatter:'showlink',formatoptions:{baseLinkUrl: 'http://www.linkexchanger.su/forum/',showAction: 'viewtopic.php', addParam: '&f=4', idName:'t',target: '_blank'}},
{name:'checkbox', index:'checkbox', width:35, formatter:'checkbox',formatoptions:{disabled: true}},
{name:'select', index:'select', width:30, formatter:'select', editoptions:{value:":Все; black:Черный; white:Белый; yellow:Желтый; red:Красный"}},
{name:'ip', index:'ip', width:50, formatter:long2ip}],
caption: 'Встроенное форматирование',
autowidth: true
});
function long2ip (proper_address) {
var output = false;
if ( !isNaN( proper_address ) && ( proper_address >= 0 || proper_address <= 4294967295 ) ) {
output = Math.floor(proper_address / Math.pow( 256, 3 ) ) + '.' +
Math.floor( ( proper_address % Math.pow( 256, 3 ) ) / Math.pow( 256, 2 ) ) + '.' +
Math.floor( ( ( proper_address % Math.pow( 256, 3 ) ) % Math.pow( 256, 2 ) ) / Math.pow( 256, 1 ) ) + '.' +
Math.floor( ( ( ( proper_address % Math.pow( 256, 3 ) ) % Math.pow( 256, 2 ) ) % Math.pow( 256, 1 ) ) / Math.pow( 256, 0 ) );
}
return output;
}
});
Работающий код данного примера можно увидеть на ДЕМО2.4. Или если вы хотите скачать его, то вот ссылка на архив, внутри клиентский и серверный скрипты, а также дамп БД.
Давайте разберемся как все это работает. Сам пример выглядит как две таблицы и как написано в заголовках, верхняя – отображает данные с сервера как они есть, а нижняя – применяет собственные методы форматирования. Как вы уже наверное догадались, в этом примере важен только клиентский код, поэтому серверный скрипт я упростил до минимума, поэтому таблица не сортирует данные в столбцах. Все столбцы кроме последнего названы в соответствии с используемым «форматтером». Все «форматтеры» используются одинаково, указывая имя и параметры в colModel таблицы, описания всех параметров доступны на странице Predefined Formatter документации плагина.
Теперь подробнее по применению в данном примере.
На этом Стандартные «форматтеры» закончились, а в последнем столбце используется пользовательский. Он представляет из себя функцию function long2ip (proper_address) полный аналог PHP’шной функции, но написанной на и для JS, которая переводит IP из unsignet int в «человеко-понятный» вид октетов с точками.
Если возникла необходимость создать сложный пользовательский «форматтер» со множеством параметров, то на странице Predefined Formatter можно посмотреть пример расширения jqGrid своим «форматтером».
III. Панели инструментов и дополнительные панели
1) Панель-листалка (Pager)
C этой панелью мы уже знакомы, именно ее мы инициализировали устанавливая свойства pager:, rowNum:, rowList: в предыдущих примерах. В принципе об этой панели рассказывать более нечего, я лишь приведу ссылку на прочие свойства панели Pager, которые возможно понадобятся вам для решения какой-то специфической задачи.
2) Панель инструментов (Navigator)
Данная панель совсем не является панелью это функция, которая позволяет добавлять элементы управления (кнопки) на панель-листалку. Т.е. если вы хотите использовать pager, то вы обязательно должны его объявить при инициализации jqGrid хотя бы со стандартными параметрами, без использования rowNum:, rowList:. После этого уже можно добавлять кнопки, давайте взглянем на ДЕМО2.5. Добавление кнопок стандартных функций.
$(function(){
var pager = $('#tablePager');
$('#table').jqGrid({
url:'p2e1.php',
datatype: 'json',
mtype: 'GET',
colNames:['Код страны','Код региона', 'Город','Долгота','Широта','nbip'],
colModel :[
{name:'country_code', index:'country_code', width:80},
{name:'region_code', index:'region_code', width:80},
{name:'city', index:'city', width:90},
{name:'latitude', index:'latitude', width:60},
{name:'longitude', index:'longitude', width:60},
{name:'nbip', index:'nbip', width:30}],
pager: pager,
sortname: 'city',
sortorder: 'asc',
caption: 'Pager в качестве панели инструментов',
autowidth: true
}).jqGrid('navGrid', pager);
});
Итак друзья мы с вами переступили порог начального уровня использования плагина, с этого момента я буду рассказывать о продвинутых функциях jqGrid.
Как вы уже заметили на листалке появились 6 кнопок, при этом 4 «практически не работают», 1 – «практически работает» и 1 работает, давайте разберемся. Листинг выглядит вполне «стандартно», разве что строка var pager = $(‘#tablePager’); может вызвать легкое недоумение у новичков, но это обычная практика программирования JS, а именно кэширование, об этом написан цикл хороших статей, возьмите эту методику на вооружение! Далее вы можете видеть что после инициализации jqGrid я инициализирую панель Navigator используя метод navGrid. Данному методу в качестве первого параметра передается селектор панели листалки, вторым параметром (не указан в листинге) – объект в котором указывается функции (редактировать, добавить и т.п.) которые необходимо задействовать на панели (например {view:true, del:false}), а далее идут объекты с параметрами по каждой из функций в определенном порядке. Давайте я приведу иллюстрацию в виде списка:
Я уверен, что теперь вам стало ясно почему не работают или не совсем работают задействованные функции, потому что они просто не настроены. Т.к. использование этих функций будет рассмотрена в последующих статьях, я не буду продолжать рассмотрение настроек, а перейду к следующему подпункту Добавление пользовательских кнопок.
jqGrid позволяет добавлять на панель pager пользовательские кнопки и назначать на них функции, ниже приведен листинг ДЕМО2.6
$(function(){
var pager = $('#tablePager');
$('#table').jqGrid({
url:'p2e1.php',
datatype: 'json',
mtype: 'GET',
colNames:['Код страны','Код региона', 'Город','Долгота','Широта','nbip'],
colModel :[
{name:'country_code', index:'country_code', width:80},
{name:'region_code', index:'region_code', width:80},
{name:'city', index:'city', width:90},
{name:'latitude', index:'latitude', width:60},
{name:'longitude', index:'longitude', width:60},
{name:'nbip', index:'nbip', width:30}],
pager: pager,
sortname: 'city',
sortorder: 'asc',
caption: 'Pager в качестве панели инструментов',
autowidth: true
}).jqGrid('navGrid', pager,{add: false, del: false, edit: false, search: false});
$('#table').jqGrid('navSeparatorAdd','#tablePager');
$('#table').jqGrid('navButtonAdd','#tablePager',{
caption: 'Закрутить ',
title: 'Ключ рожковый, обыкновенный',
buttonicon: 'ui-icon-wrench',
onClickButton: function(){
alert('Скрип, скрип, скрип!..');
},
position:'last'
}).jqGrid('navButtonAdd','#tablePager',{
caption: 'Замкнуть ',
title: 'Открытый замок',
buttonicon: 'ui-icon-unlocked',
onClickButton: lock,
position:'last'
});
function lock(){
alert('Взяли и замкнули что-то...');
}
});
В данном примере после стандартных кнопок, из которых я оставил только «Обновить», вставлен разделитель (separator) и две кнопки «Закрутить» и «Замкнуть», простите но оригинальнее я не смог ничего придумать. По нажанию на эту кнопку вызываются функции, которые показывают стандартный alert.
Разделитель добавляется методом navSeparatorAdd, первым параметром которого является строка-селектор панели-листалки (pager), а в качестве второго (не указан в листинге) объект с параметрами разделителя.
Вот тут следует немного отвлечся и обратить ваше внимание на небольшой ньюанс, возможно разработчики что-то не доделали или не захотели доделать, но при использовании методов navSeparatorAdd и navButtonAdd в качестве первого параметра должна быть передана именно строка-селектор, но никак не переменная содержащая последний.
Параметры разделителя по-умолчанию:
{sepclass: ‘ui-separator’, sepcontent: »}
Где
Кнопка вставляется с помощью метода navButtonAdd
{ caption:’NewButton’, buttonicon:’ui-icon-newwin’, onClickButton:null, position: ‘last’, title:’ ‘, cursor: ‘pointer’}
Где
Однако при всем своем удобстве, у данного подхода к созданию панели инструментов есть ряд недостатков, таких как то что панель находится в нижней части таблицы, мало места для каких-то дополнительных элементов, большого размера и т.п. Для этих целей разработчики добавили еще и возможность создания пользовательских панелей.
3) Пользовательские панели
Вот ДЕМО2.7 листинги которого приведены ниже.
Клиентская часть
$(function(){
$('#table').jqGrid({
sortable: true,
url:'p2e1.php?userdata=true',
datatype: 'json',
mtype: 'GET',
colNames:['Код страны','Код региона', 'Город','Долгота','Широта','nbip'],
colModel :[
{name:'country_code', index:'country_code', width:80},
{name:'region_code', index:'region_code', width:80},
{name:'city', index:'city', width:90},
{name:'latitude', index:'latitude', width:60},
{name:'longitude', index:'longitude', width:60, resizable: false},
{name:'nbip', index:'nbip', width:30}],
pager: $('#tablePager'),
toolbar: [true,'both'],
sortname: 'city',
sortorder: 'asc',
caption: 'Пользовательские панели инструментов',
autowidth: true,
loadComplete: function() {
var udata = $('#table').jqGrid('getUserData');
$('#tb_table').css('text-align','right').html(udata.msg+' '+udata.sum_regions_numbers+' '+udata.button);
}
});
$("#t_table").height(60); //Set height of toolbar
$("#t_table").append('<input id="say_hello" type="button" value="Привет" style="height:60px; width:80px">');
$("#say_hello").click(function(){
alert("Привет! Спасибо что читаете linkexchanger.su!");
});
$('#show_sum').live('click',function(){
var val = $(this).val();
alert('Обратите внимание, с сервера мы получили кнопку с сууммой '+val+', а обработчик назначили уже на странице');
});
});
И серверная, практически полностью повторяющая пример 2.1
// Начало формирование массива
// для последующего преобразоования
// в JSON объект
$data['page'] = $page;
$data['total'] = $total_pages;
$data['records'] = $count;
// Дополнительная информация с сервера
if($_GET['userdata']){
$data['userdata']['msg'] = '<span style="font-weight: normal; color: red;">Сумма всех чисел в столбце <em>"region_code"<em> равна</span> ';
$data['userdata']['sum_regions_numbers'] = '<em>'. $row['sum'].'<em>';
$data['userdata']['button'] = '<input id="show_sum" type="button" value="'.$row['sum'].'">';
}
// Строки данных для таблицы
$i = 0;
while($row = mysql_fetch_assoc($result)) {
$data['rows'][$i]['id'] = $row['id'];
$data['rows'][$i]['cell'][] = $row['country_code'];
$data['rows'][$i]['cell'][] = $row['region_code'];
$data['rows'][$i]['cell'][] = $row['city'];
$data['rows'][$i]['cell'][] = $row['latitude'];
$data['rows'][$i]['cell'][] = $row['longitude'];
$data['rows'][$i]['cell'][] = $row['nbip'];
$i++;
}
// Перед выводом не забывайте выставить header
// с типом контента и кодировкой
header("Content-type: text/script;charset=utf-8");
echo json_encode($data);
Ну а теперь по традиции давайте разберем пример подробнее
jqGrig позволяет создавать две независимые панели инструментов. Для этого стоит свойству toolbar: присвоить массив [true,'both'], элементы которго в данном случае означают, что нужно создать обе(верхнюю и нижнюю) панели инструментов. Вместо ‘both’ также можно указать ‘top’ или ‘bottom’ для верхней и нижней панелей соответственно.
Теперь давайте рассмотрим первый вариант манипуляции с элементами на панелях, начнем с верхней панели. При инициализации плагина с определенным свойством toolbar: jqGrid автоматически выставит атрибут id верхней панели как id=»t_»(«t_table» в нашем случае), а нижнюю id=»tb_» («tb_table» в нашем случае). С помощью этих идентификаторов можно отыскать «тулбары» в DOM и выполнить например такие манипуляции
$("#t_table").height(60);
$("#t_table").append('<input id="say_hello" type="button" value="Привет" style="height:60px; width:80px">');
...
$("#say_hello").click(function(){
alert("Привет! Спасибо что читаете linkexchanger.su!");
});
Первая строка сделает высоту верхней панели равной 60px, а вторая поместит на нее кнопку, код которой вы видите. После этого определяется функция-обработчик которая выполнится при щелчке по добавленной кнопке. Думаю такая методика использования не вызовет затруднений.
А вот второй, альтернативный вариант манипуляций с элементами на панелях, иллюстрируется на примере нижней панели. Это следующие строки кода
...
loadComplete: function() {
var udata = $('#table').jqGrid('getUserData');
$('#tb_table').css('text-align','right').html(udata.msg+' '+udata.sum_regions_numbers+' '+udata.button);
}
...
$('#show_sum').live('click',function(){
var val = $(this).val();
alert('Обратите внимание, с сервера мы получили кнопку с суммой '+val+', а обработчик назначили уже на странице');
});
...
Работает это следующим образом. После окончания загрузки данных возникает событие loadComplete: и вызывается функция. Эта функция (var udata = $(‘#table’).jqGrid(‘getUserData’); ) получает пользовательские данные из ответа сервера, об этом немного ниже, в виде JSON объекта в данном случае и выводит эти данные на нижнюю панель ($(‘#tb_table’)) в виде HTML выравнивая по правому краю (css(‘text-align’,'right’)). После чего выполняется объявление обработчика используя метод live.
Ну откуда же берутся эти пользовательские данные? С сервера как и все остальные! Вот например как сделал я
$userdata = $_GET['userdata'];
// Выполним запрос, который вернет суммарное кол-во записей в таблице
$result = mysql_query("SELECT COUNT(*)AS count, SUM(region_code) AS sum FROM cities");
if($userdata){
$data['userdata']['msg'] = '<span style="font-weight: normal; color: red;">Сумма всех чисел в столбце <em>"region_code"<em> равна</span> ';
$data['userdata']['sum_regions_numbers'] = '<em>'. $row['sum'].'<em>';
$data['userdata']['button'] = '<input id="show_sum" type="button" value="'.$row['sum'].'">';
}
// Строки данных для таблицы
$i = 0;
while($row = mysql_fetch_assoc($result)) {
$data['rows'][$i]['id'] = $row[id];
$data['rows'][$i]['cell'][] = $row[country_code];
}
echo json_encode($data);
Итак я запрашиваю серверный скрипт (url:’p2e1.php?userdata=true’), который выполняет запрос. После выполнения запроса, вместе с суммарным кол-вом записей получаем сумму всех значений полей region_code. Далее полученные данные помещаем в массив $data и кодируем в формат JSON.
IV. Управление столбцами данных
1) Изменение размера и положения столбцов
На самом деле никаких манипуляций для реализации этих возможностей таблицы делать не придется. Возможно вы заметили что в листинге предыдущего примера есть не рассмотренное свойство sortable: true и если схватить за заголовок любого из столбцов, то можно drag’n'drop’ом переместить его на место другого столбца. Определение этого свойства как true как раз и включает возможность перетаскивать столбцы. Но перед использованием этой опции плагина убедитесь:
При этом можно изменять ширину любых столбцов, в colModel-опциях которых не определено свойство resizable: false как столбец «Широта» в ДЕМО2.7, при условии что вы скачали jqGrid с опцией jQuiery UI addons.
2) Скрываем не нужные или отображаем нужные столбцы данных
Начнем обсуждение с ДЕМО2.8.
<link rel="stylesheet" type="text/css" media="screen" href="../../../_library/css/ui.multiselect.css" />
<script type="text/javascript" src="../../../_library/js/ui.multiselect.js"></script>
<script type="text/javascript">
$(function(){
var table = $('#table');
table.jqGrid({
url:'p2e1.php',
datatype: 'json',
mtype: 'GET',
colNames:['Код страны','Код региона', 'Город','Долгота','Широта','nbip'],
colModel :[
{name:'country_code', index:'country_code', width:80, hidden: true},
{name:'region_code', index:'region_code', width:80, hidden: true},
{name:'city', index:'city', width:90},
{name:'latitude', index:'latitude', width:60},
{name:'longitude', index:'longitude', width:60},
{name:'nbip', index:'nbip', width:30, hidden: true}],
pager: $('#tablePager'),
toolbar: [true,"top"],
sortname: 'city',
sortorder: 'asc',
caption: 'Управление видимостью столбцов',
width: 400
});
var tBar = $("#t_table");
tBar.append('<input id="c_chooser1" type="button" value="Базовый мастер">');
tBar.append('<input id="c_chooser2" type="button" value="Сторонний мастер">');
$("#c_chooser1").click(function(){
table.jqGrid('setColumns',{
colnameview:false,
updateAfterCheck: true
});
});
$("#c_chooser2").click(function(){
table.jqGrid('columnChooser');
});
});
</script>
Первое что бросается в глаза так это то, что не все столбцы показаны, хотя все объявлены. Эта опция будет полезна если у вас имеется очень много колонок, при этом обычно не все они нужны, но могут понадобится при более детальном рассмотрении каких-то строк. Сделать столбец не видимым при инициализации таблицы можно указав в colModel колонки свойство hidden: true. Но спрятанные колонки нужно как-то показывать при необходимости. Для таких целей можно воспользоваться 2 способами.
Послесловие
В данной статье мы рассмотрели очень много вспомогательных возможностей плагина-таблицы jqGrid, при этом мы пересекли черту «начального использования» таблицы, от всей души поздравляю! Мы хорошо потрудились и дальше нас ждет еще больше интересного, а именно:
Отзывов (11) на «jqGrid Часть II: Базовые возможности»
Отличная статья, большое спасибо
Спасибо, полезная статья, ждем продолжения
…
.jqGrid(‘navButtonAdd’,'#tablePager’,{
caption: ‘Замкнуть ‘,
title: ‘Открытый замок’,
buttonicon: ‘ui-icon-unlocked’,
onClickButton: lock,
position:’last’
});
Не работает ни один из подобных методов(
jqGrid подключил, в параметрах задал поле, по которому сортируются данные в таблице, «листалка» работает, даже количество всех записей в pager-е выводится, но никак не получется добавить на панель кнопки «Обновить данные» др.
Может, кто-нибудь подскажет, где может бытьпроблема?
пожалуйста сформулируйте свой вопрос на форуме
Дорогие читатели, в очередной раз умоляю вас:
Используйте комментарии только для предложений и пожеланий, а все вопросы – на форум в раздел Плагины jQuery c пометкой jqGrid. Вам обязательно помогут и подскажут.
Все вопросы в комментариях будут безжалостно удаляться!
Спасибо за понимание
Поправьте пожалуйста ссылки, ни одна ссылка не работает.
В ссылках все верно, это проблемы с моим провайдером. Сегодня-завтра обещают все наладить.
отлично )
Да я для себя новый мир открыл)))))
Только что заметил что практически все демо не работоспособны, точнее не подгружают данные. Прошу прощения за это неудобство постараюсь в ближайшее время все исправить
От я шляпа! Обновил сервер и забыл реконфигурировать пакеты) Прошу прощения если кому-то доставил неудобства
Оставьте отзыв