среда, 31 марта 2010 г.

1С + JavaScript

Интересная публикация появилась на InfoStart. Технология шифрования кода 1С (а это пока скорее только технология) Golden Key 8.1 Prototype.
Основной смысл заключается в том, что часть кода 1С преобразуется в html-код (а если быть точнее в JavaScript), который хранится в соответствующих контейнерах внутри конфигурации (обработки). А сам html-код "шифруется" известными преобразователями кода, которые делаю его не читаемым, но с сохранением функциональности.
Конечно, как сторонник OpenSource, я не поощряю такие методы, однако надо отметить, что вызов JavaScript, а главное работа с объектами метаданных 1С из JavaScript это сам по себе достаточно интересный ход.

воскресенье, 28 марта 2010 г.

Старый хлам в картонной коробке

Знаете, как обычно бывает, когда делаешь уборку и находишь коробку с разным старым хламом.
"Ну, вот я ее щас выкину, - думаешь. - Только погляжу что там лежит".
И вот тут уборка останавливается. Начинаешь доставать, разглядывать. А потом задвинешь ее обратно как есть, потому что жалко же выбрасывать, столько воспоминаний. Примерно тоже происходит и со старыми исходниками, разными файлами, старыми проектами. Набрел сегодня на такую свою "коробку" и кое-чем поделюсь с вами.

Lab_5_18
Когда-то я зарабатывал карманные деньги тем, что делал лабораторки для старшекурсников. Все это было, конечно, примитивно и скучно: работа с массивами, списками, основы языка... Но одна лабораторка мне нравится до сих пор. Каждый раз как запускаю умиляюсь, до чего хорошо получилось. Это парсер, который раскладывает арифметическое выражение в дерево:
Кстати, тут видно, что он не только строил дерево, но и немного сжимал его, избавляясь от сложения с нулем и подобных операций. Конечно, когда формула уже лежит в дереве, то работать с ней становится легко и приятно, можно применять разные шаблоны, тасовать узлы как угодно и получать просто восхитительные результаты. Например, формульный калькулятор в компилируемых языках. Думаю, что именно такой способ представления формул используется в каком-нибудь MathLab.

DemoAsm
Первая программа на ассемблере. Скомпилирована еще тогда, но до сих пор работает. Чего бы ей не работать. Собственно включает режим 0x13h и рисует желтую точку на экране. Управлять точкой можно с помощью клавиш q,a,o,p, выход - Esc. Скриншот, к сожалению, не делается. Кстати! Размер EXE-шника всего 956 байт.Т.е. меньше килобайта. Нет, все-таки в ассемблере что-то есть.

Fistpath
Патчер для какой-то из версий игры "Элита" (кажется First Encounters). Добавлял произвольное количество денег. Кажется, речь шла о "стартовых" деньгах.
Патчер примечателен тем, что в нем переопределялся знакогенератор для режима 0x03h и менялась палитра. За счет этого достигался эффект плавной бегущей строки (в текстовом режиме) и плавного появления/исчезновения звезд на фоне. Тут я тоже не осилил сделать скриншот, но вы можете посмотреть сами.

WinKley
Софтина задумывалась как "клей" для windows-программ. По-идее должна была "склеивать" два EXE-шника в один таким образом, чтобы сначала загружался один, а за ним другой. Сам клей реализован так и не был, но зато получился симпатичный интерфейс (нужно помнить, что речь идет о времени, когда WinXP с ее красивыми темами еще не вышла). Он весь подсвечивается и подзвучивается при наведениях и нажатиях. Кстати, что-то оно с EXE-шниками все же делает, во всяком случае мой антивирус ругается на Output file.

Kt
Электронный камертон. Ничего необычного, просто пищит через PC-спикер. Замечательно то, что тут используется библиотека sCrt. Это моя собственная библиотека (очень примитивная надо отметить, были намного профессиональнее) упрощающая построение интерфейса в стиле Norton. Тогда это, был самый популярный пользовательский интерфейс для DOS-приложений. Кажется это было одно из последних приложений под DOS. Все-таки 2001-год, я уже писал под Windows.

Poin1
После запуска на экран будет выведено несколько точек, а после нажатия клавиши точки будут обведены в многоугольник, причем так, что крайние точки станут его вершинами, а все остальные окажутся внутри. Т.е. многоугольник как бы "обтянет" эти точки. Такой же эффект, как если бы вы бегали с ниткой вокруг группы деревьев, некоторые оказались бы внутри ниточного ограждения, а на некоторые (самые внешние) оказались бы в вершинах ниточного многоугольника.
Вообще-то Poin1 это часть общей задачи которая изначально решалась в 3D для точек и многогранника. Это же ее разновидность для плоскости.

Matrix
Не думаю, что нужно объяснять что именно делает эта программа. Совершенно ничего особенного. Обычный Screen saver. Таких были сотни разновидностей. Вот еще один для DOS-а. Да, я немного подправил его сегодня, поставлял задержек, чтобы на современной машине можно было хоть что-то разглядеть.

Вот, собственно, и все что нашлось из интересного. А еще больше было потеряно, стерто и отформатировано. Мои эксперименты с 3D, куча разных мелких утилит под Windows и еще много чего.

Естественно, выкладываю все файлы (с исходниками) в архиве: old_prog.zip

суббота, 27 марта 2010 г.

rlinkf v1.0

Ура! Ура! Я закончил первую версию моего скрипта-редиректора и теперь я смогу быстро и просто делать всякие короткие ссылки вроде http://zfilin.org.ua/link/how-to-read (оригинальная ссылка: дли-и-и-и-и-и-инная ссылка)
Если вы хотите себе такое-же, то скрипт можно скачать по адресу http://zfilin.org.ua/link/rlinkf в разделе Downloads

четверг, 25 марта 2010 г.

среда, 24 марта 2010 г.

RetraTech

Недавно прошел тесты по PHP4 и CSS. Результаты так-себе, но проходной бал набрал.

Agile такой agile!

Все-таки методики гибкой разработки это очень интересно. Надеюсь, что узнаю много нового на Agile Base Camp 2.
Ну, кто со мной?

понедельник, 22 марта 2010 г.

О сложности C/C++

Когда-то я совсем-совсем не умел программировать и только играл в компьютерные игры. Но я знал, что игры на чем-то написаны, что существуют языки программирования. Я спрашивал: "На чем написана эта игра?" А мне отвечали: "На си!"
Какой же сложный этот C, раз на нем можно написать такую игру! - думал я.

Позже я стал писать программы на бейсике, паскале, немного познакомился с ассемблером для Z80 и освоил ворох разных технологий вроде программирования COM-порта или OpenGL, прочел книжку Питера Нортона о жестких дисках и получил первые деньги за программу. Примерно тогда же нам читали курс лекций по C и я думал:
"Все-таки C это очень сложно. Пожалуй, сложнее всего, что я знаю".

Шло время я, наконец, понял что такое "указатель", успел пожалеть о том, что почти не осталось конспектов с того курса лекций. Я стал 1С-программистом, перестал писать на других языках, снова начал писать на других языках, увлекся PHP и веб-разработкой, начал читать Дональда Кнута, освоил еще ворох новых технологий, поучаствовал и успешно угробил несколько стартапов, сменил несколько фирм, захватил власть в Изумрудном городе с помощью племени Марранов (извините, это не оттуда) наконец перестал воспринимать менеджера проекта как личного врага, а тестера как недочеловека, купил красный галстук и черный костюм... И установил Visual C++ Express Edition 2008 взамен привычной, но неизбежно устаревающей Delphi7. Я открыл редактор в который автоматически был загружен "Hello world" и, знаете что я подумал?
Какой же этот С все-таки сложный!

P.S.: Надеюсь это не последняя моя мысль о СИ и наша любовь еще впереди.

пятница, 19 марта 2010 г.

Gource

Очень красивые визуализации активности работы с вашими хранилищами исходников может делать утилита Gource.
В честь юбилейного, 512-го комита моего основного рабочего проекта я визуализировал его активность:


Кстати, Стас Фомин сделал хорошую обертку для gource и codeswarm и использует как хороший рабочий инструмент. Знакомьтесь - ShowTeamWork.
На AgileDays'09 есть его доклад "Увидеть лес за деревьями" (особенно доставляет надпись, которую видно на скриншоте: "Стас потерял впустую месяц на архитектурные бантики", обязательно надо посмотреть все видео).

среда, 17 марта 2010 г.

Хроники пикирующего вебинара

В настоящий момент идет вебинар с темой "Как сделать так, чтобы управление рисками работало". Вебинар проводит компания Luxoft, докладчик Антон Грачев. Вебинар идет ТАМ, а я пишу ЗДЕСЬ. Потому что нет никакой возможности слушать как из тебя заживо тянут жилы и что-то рассказывают монотонным голосом. Возможно я переоценил свой интерес к управлению рисками, но скорее всего из происходящего следует извлечь печальный опыт.
Во-первых только самые профессиональные докладчики могут проводить чистые вебинары без живых слушателей. Ведущие на радио, MC и тому подобное. Не все "п-р-о-д-ж-е-к-т-м-е-н-е-д-ж-е-р-ы" обладают талантами ведущих. Во-всяком случае, если бы передо мной поставили микрофон и сказали: "Вещай!", я бы оказался в затруднительном положении. Нужно уметь общаться со стенкой при этом представляя перед собой большой концертный зал. Аудитория, которую ты видишь, подсказывает тебе как вести себя, о чем говорить. Думаю, что через пять минут скучающие физиономии в зале натолкнули бы докладчика на мысль о том, что надо добавить больше жизни в монотонное бубнение и вздохи. Затравить байку, рассказать анекдот и тому подобная классика выступлений. Стенка не сможет ничего подсказать, живой слушатель вносит живое общение, добавляет "экшена" и стесняется уйти посреди доклада. Кстати, мне интересно что будет когда счетчик слушателей вебинара у них упадет до нуля в середине доклада. Он продолжит рассказывать пустоте? =)
Вторым пунктом идет ряд чисто технических замечаний. Совершенно невыносимо читать (и слушать) громоздкие конструкции типа "как сделать так, чтобы". Обратите внимание, что в названии половина строки (чисто визуально, по длине) это вот это самое "как сделать так, чтобы". И это только название.
Нужно запомнить для себя раз и навсегда, что читать цифры со слайда это то, за что нужно вырезать язык. Особенно четырех-, пятизначные.
И, наконец, я считал, что повторяться это хорошо. До сегодняшнего дня. Нет, нужно все таки выделять главную мысль и проговаривать ее несколько раз по возможности слегка меняя "декорации". Но слушать несколько раз о том, о чем мы сегодня будем говорить, то есть несколько раз слушать содержание презентации, ну то есть несколько раз слушать о том, какие слайды мы посмотрим, и как я уже говорил, по-пунктам слушать о том, о чем будет сегодня рассказано... Ну, вы поняли. =)

Как бы мне хотелось самому не наступить на такие же грабли. Мне точно нужен опыт выступлений и вебинаров. Но где?..

четверг, 11 марта 2010 г.

Как сбросить HTTP-авторизацию (пример на PHP)

Иногда бывает необходимо защитить паролем одну страницу на сайте. Не всегда хочется использовать для этого сессии и прочие php заморочки. Для таких случаев удобно использовать HTTP-авторизацию.
Однако у нее есть один недостаток: нет нормального способа отлогиниться от страницы. Т.е. не закрывая браузер вы никак не сможете выйти из защищенной области так, чтобы при повторном входе страница снова потребовала бы у вас пароль.
На эту тему есть интересный трикс. Нужно снова зайти на страницу с заведомо не правильным логином и паролем. Сделать это можно, послав пользователя по ссылке вида:

http://user:pass@you-domain.com/you-page

Таким образом вы можете осуществить сброс HTTP авторизации. Конечно user и pass не должны быть зарегистрированы в системе.

Вот вам пример защищенной страницы на PHP:
<?php
 $admin_user='admin';
 $admin_password='12345';

 $request_path=parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);

 if(isset($_GET['logout'])) {
  header("Location: http://x:x@".$_SERVER['SERVER_NAME'].$request_path);
 } elseif(@$_SERVER['PHP_AUTH_USER']!=$admin_user || @$_SERVER['PHP_AUTH_PW']!=$admin_password) {
  header('WWW-Authenticate: Basic realm="Please login"');
  header('HTTP/1.0 401 Unauthorized');
  die("Access forbidden");
 }

 echo '<h1>This page protected by http authorization.</h1>';

 echo '<a href="'.$request_path.'?logout">logout</a>';
?>

Кстати, трикс придумал не я, а подсмотрел его у Jacob Wright.

среда, 10 марта 2010 г.

Как я делал динамический список на jQuery #2

Продолжение поста "Как я делал динамический список на jQuery #1".

Итак, я немного окультурил динамический список теперь их может быть несколько на странице, за счет того, что обращение идет не через селектор id, а через селектор class. Впрочем, id тоже остался, но теперь это в прямом смысле id списка, который передается php-скрипту. А тот в свою очередь теперь умеет обрабатывать два списка.
Кроме того html-код, которым оперирует скрипт, теперь вынесен в переменные-шаблоны в начале скрипта и редактировать его будет удобнее. Главное помнить, что на место подстановочной последовательности %%index%% будет подставлен id элемента, а на место %%data%% его содержимое (подстановочные символы заменяются функцией .replace).
Блок добавления нового элемента внесен в список, в связи с чем появилась функция .before
Все остальное, за исключением некоторых изменений в селекторах, осталось неизменным.

В php-скрипте добавлена поддержка нескольких списков. Кроме того, в начале скрипта добавлена строка:
if($_SERVER['HTTP_X_REQUESTED_WITH']!='XMLHttpRequest') exit();

Она прерывает выполнение скрипта, если скрипт вызван не AJAX-запросом. Что логично, так как наш скрипт других запросов не обрабатывает (подробнее тут: http://www.rsdn.ru/article/inet/jQuery.xml).

Ну, и код на JavaScript теперь лежит в отдельном файле. Если это еще не framework работы с динамическими списками, то уже очень на него похож.

P.S.: Несмотря на то, что php-скрипт теперь защищен от обычных (не AJAX) запросов это не значит что скрипт стал безопасным. В нем по прежнему множество уязвимостей и использовать его для ваших целей в таком виде не рекомендуется.

Естественно, выкладываю все файлы в архиве.

вторник, 9 марта 2010 г.

Софтверные патенты

Очень интересное эссе о софтверных  патентах на сайте Иван Сагалаева:
...
В общем и целом известно, что если вы пишете программу сложнее "Hello World!", вы можете быть совершенно уверены, что вы нарушаете чей нибудь патент. Или пачку. Поэтому вы вряд ли сможете получить патент на своё изобретение: скорее всего, оно уже запатентовано кем-то с формулировкой типа "штука, которая делает всё хорошо".
...
Полностью его можно почитать на сайте автора.

пятница, 5 марта 2010 г.

Как я делал динамический список на jQuery #1

Все началось с того, что мне нужно было сделать динамический список, то есть такой список элементы которого я бы мог редактировать и удалять, а так же добавлять новые.
- Черт возьми! - думал я. - Как я устал от того, что любое нажатие, даже вход в режим редактирования элемента списка, вызывает перезагрузку страницы! С этим определенно нужно что-то делать.
Я знал, что существует такая библиотека, как jQuery, но это все что я про нее знал. К тому же я совсем не владею JavaScript.
- Ладно, наверняка Google нам поможет. - подумал я и открыл Яндекс.
(Я тут не буду дословно приводить как именно я искал, в наше время "жужлить" должны уметь все. Так же, как правило, я открывал первые результаты в поиске, так что приводимые ссылки никак нельзя назвать "лучшее по теме", это просто первое, что нашлось.)
Первая серия ссылок очень помогла получить общее представление о jQuery:
(в действительности мне понадобились только первая и третья части)
И тут уже можно было с чего-то начинать. Во-первых я скачал библиотеку jQuery (официальный сайт).

Во-вторых сделал файл index.html:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>jQuery list demo</title>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<script type="text/javascript" src="jquery-1.3.2.js"></script>

</head>
<body>

<h1>List</h1>
<hr />

<ul id="dynamic_list_1">
<li id="0">First item</li>
<li id="1">Second item</li>
<li id="2">Third item</li>
</ul>

</body>
</html>

1. Все-таки динамический список
Это был совсем не динамический список. Я решил для начала сделать так, чтобы элементы списка подгружались динамически, для этого в заголовок страницы я добавил такой скрипт:
<script type="text/javascript">
$(document).ready(function(){ 
 $.getJSON('db.php', {act: "getall"}, function(json){

  $('#dynamic_list_1').html('');

  $.each(json,function(index,data){
   $('#dynamic_list_1').append(
    '<li id="' + index + '">' +
    '<div class="item_content">' + data + '</div>' +
    '<div class="controls"><a href="#" id="edit">edit</a> <a href="#" id="delete">delete</a></div>' +
    '</li>\n'
   );
  });
 }); 
});
</script>

И тут я хотел бы сказать кое-что о синтаксисе. Наверняка это хорошо известно тем, кто программирует на JavaScript, но меня тут ожидало большое открытие. Это передача функции и ее кода как параметра другой функции.
Смотрите, вот с самого начала мы вызываем функцию ready для документа, которая будет вызвана браузером сразу же, но какие параметры мы ей передаем? Мы ей передаем функцию, которая должна быть вызвана как только DOM документа будет полностью загружен. Если убрать все несущественное, то останется только:
jQuery(document).ready( function(){ /*...*/ } );
Вот эта function(){ /*...*/ } и есть тот параметр, который мы передали в функцию ready и она теперь "знает" какой код нужно выполнять когда DOM будет загружен.
Если вы никогда не использовали такие штуки, то вам может показаться, что это все очень не удобно, но стоит привыкнуть и вы поймете, что на самом деле это очень изящная парадигма передачи функций как параметров. К тому же весь jQurey построен на этом принципе.
Еще один пример встречается чуть ниже: итератор each.
jQurey.each(json,function(index,data){ /*...*/ });
Тут вызывается функция each, которой передается переменная-коллекция json и функция, которая будет вызвана на каждой итерации, в которую, в свою очередь, будет передан индекс (index) элемента коллекции и сам элемент коллекции в переменную data.
Кстати, про each я жужлил отдельно и нашел информацию на api.jquery.com. Запомните этот адрес там мно-о-о-ого полезного.

Вернемся к коду. Основная функция тут getJSON. Она делает вызов db.php и при помощи метода GET, передает в скрипт параметр с именем act и значением "getall". Так же функции getJSON передается функция, которая будет вызвана в случае успешной передачи данных в которую, в свою очередь, будет передана информация, которую вернул скрипт.

Строки $('#dynamic_list_1').html(''); и $('#dynamic_list_1').append('...'); подробно разбирать не будем. Первая очищает все внутри нашего списка, вторая добавляет в него элементы, полученные от скрипта db.php

Кстати, скрипт db.php по смыслу будет "серверной стороной" нашего списка и будет обслуживать запросы от index.html: изменять БД с нашим списком. Для примера, пусть список хранится в простом текстовом файле items.txt:
First item
Second item
Third item

А вот сам db.php
<?php
 $act=$_GET['act'];
   
 file_put_contents('debug.txt',var_export($_GET,true));
 
 if($act=='getall') {
  $items=file('items.txt');
  $items = array_map("rtrim", $items);
  echo json_encode($items);
 } 
?>

Запись в файл debug.txt (строка 4) тут нужна исключительно для отладки, чтобы отслеживать запросы ajax.
Функция json_encode сворачивает данные php в формат JSON (о формате JSON вы можете почитать в той серии ссылок, что я приводил выше, а о json_encode на оф.сайте php.net) А данные, в свою очередь, будет получены и переданы в итератор each, как я уже писал выше.

Итак, в двух словах: мы сделали код, который после загрузки страницы index.html обратится к скрипту db.php, получит у него список и выведет его.

2. Удалить элемент
Вы наверняка заметили, что в каждый элемент я добавил две ссылки: edit и delete. По нажатию на эти ссылки элемент должен редактироваться и удаляться, соответственно. Начнем с удаления, потому что это проще.

Реализовать удаление я предполагал следующим образом: послать запрос на удаление в php скрипт с индексом удаляемого элемента и если запрос успешно отработан удалить элемент со страницы. Для этого в index.html я добавил такой код:

$("div.controls #delete").live("click", function(){

  var item=$(this).parents("li");
  var item_id = item.attr('id'); 
  
  $.get('db.php', {act: 'del', id: item_id}, function(){
   item.animate({ opacity: 'hide' }, "fast");
   item.remove();
  });
    
 });

Давайте разберемся. Во-первых несмотря на то, что для отлавливания клика в "jQuery для начинающих. Часть 1." используется метод .click я использовал метод .live. Его я нашел на сайте перевода официальной документации. Разница в том, что .click работает только для статических элементов страницы, а .live так же и для тех, что были созданы самим скриптом.
В третьей строке мы получаем тэг-родитель li, собственно весь элемент списка, а в четвертой его id. (Как получить свойства тэга я нашел тут).
А дальше следует метод вызов метода .get (описание тут). Я решил не использовать .getJSON, поскольку мне не нужно принимать сложную структуру данных, а только убедиться в том, что вызов прошел успешно. В качестве параметров скрипту передается act="del" и id с номером элемента списка.
После, если вызов прошел успешно, со страницы удаляется элемент списка. Метод .animate я взял из "jQuery для начинающих", а .remove с форума JavaScript.ru.

db.php так же придется доработать. Я дополнил условие следующим кодом:
} elseif ($act=='del') {
  $items=file('items.txt');
  
  unset($items[$_GET['id']]);
  
  $items = array_map("rtrim", $items);
  $str = implode("\n", $items);
  file_put_contents ("items.txt", $str);
 }
Тут все очевидно, поэтому останавливаться не будем.

Теперь вы можете удалять элементы из списка.

3. Добавить элемент
К этому моменту у меня уже было достаточно практики и вычитанных манов, чтобы с добавлением никаких сложностей не возникло.

Общая схема добавления такая: читаем из полей специальной формы данные для элемента списка, добавляем его в базу и в случае успеха добавляем на страницу новый элемент списка.

Дополним index.html формой для ввода данных нового элемента. Для этого после нашего списка вставим такой код:
<div class="add_item">
 <input class="item_content" type="text" value="">
 <div class="controls"><a href="#" id="add">add</a></div>
</div>

А в скрипт вставим обработку:
$("div.add_item div.controls #add").click(function(){

  $("#dynamic_list_1 li.editing").remove();
  $("#dynamic_list_1 li").show();
  
  var context=$("div.add_item .item_content");
  
  $.get('db.php', {act: 'add', cont: context.attr('value')}, function(index){
   $('#dynamic_list_1').append(
          '<li id="' + index + '">' +
       '<div class="item_content">' + context.attr('value') + '</div>' +
       '<div class="controls"><a href="#" id="edit">edit</a> <a href="#" id="delete">delete</a></div>' +
       '</li>\n'
      );
   context.attr('value','');
  });

 });

Тут все достаточно очевидно, кроме 3-й и 4-й строки, которые мы рассмотрим, когда будем добавлять редактирование элементов.
В переменную context мы сразу запоминаем элемент страницы input в котором хранятся данные для нового элемента списка, потом делаем запрос к скрипту db.php, который возвращает номер добавленного элемента. И добавляем новый элемент на страницу. В самом конце поле input очищается (установка аттрибутов).

В db.php тоже добавим обработку вызова:
} elseif ($act=='add') {
  $items=file('items.txt');

  $items[]=$_GET['cont'];
  echo count($items)-1;
  
  $items = array_map("rtrim", $items);
  $str = implode("\n", $items);
  file_put_contents ("items.txt", $str);
 }

4. И, наконец, редактировать элемент
С редактированием элемента будет лишь немного сложнее, чем со всем остальным. Редактирование мы разделим на два этапа:
  1. Вход в режим редактирования
  2. Сохранение результатов, выход из режима редактирования

Вход в режим редактирования это чисто интерфейсная процедура. Смысл в том, что мы должны скрыть редактируемый элемент списка, а вместо него добавить поле для редактирования.

Для этого в index.html добавим такой скрипт:

$("div.controls #edit").live("click", function(){

  $("#dynamic_list_1 li.editing").remove();
  $("#dynamic_list_1 li").show();
  
  var item=$(this).parents("li");
  var item_id = item.attr('id');
  var context=item.children('div.item_content'); 
  
  item.after(
   '<li class="editing" id="' + item_id + '">' +
   '<input class="item_content" type="text" value="' + context.html() + '">' +
   '<div class="controls"><a href="#" id="ok">ok</a> <a href="#" id="cancel">cancel</a></div>' +
   '</li>\n'
  );
  item.hide();
      
 });


По щелчку на ссылке edit скрипт добавляет код с полем ввода после элемента в котором кликнули edit (метод .after), а потом скрывает сам элемент методом .hide.

Третья и четвертые строки тут нужны вот для чего: если какой-то элемент уже был в режиме редактирования, то третья строка удаляет поле ввода редактирования, а четвертая показывает элемент, который был скрыт так как редактировался. Таким образом предыдущее редактирование отменяется и только после этого в режим редактирования "входит" новый элемент.
Аналогичные есть строки есть в блоке добавления элемента (см выше). Это нужно для сброса режима редактирования при добавлении новых элементов списка. В принципе это не обязательно, но интерфейсно понятнее для пользователя.

Добавим обработку ссылки cancel для режима редактирования:

$("li.editing div.controls #cancel").live("click", function(){
  $("#dynamic_list_1 li.editing").remove();
  $("#dynamic_list_1 li").show();
 });

И, наконец, отправка информации, которую мы отредактировали:

$("li.editing div.controls #ok").live("click", function(){

  var item=$(this).parents("li"); 
  var item_id = item.attr('id'); 
  var context=item.children("input.item_content");
  
  $.get('db.php', {act: 'edit', id:item_id, cont: context.attr('value')}, function(){
   item.after(
    '<li id="' + item_id + '">' +
    '<div class="item_content">' + context.attr('value') + '</div>' +
    '<div class="controls"><a href="#" id="edit">edit</a> <a href="#" id="delete">delete</a></div>' +
    '</li>\n'
   );
   item.remove();
   $("#dynamic_list_1 li:hidden").remove();
   
  });

 });

Общая логика такова: мы отправляем скрипту db.php информацию о редактировании с id редактируемого элемента и содержимым поля input. В случае успешного завершения вызова добавляем новый отредактированный элемент в список, а старый элемент и поле ввода режима редактирования удаляем.

Соответственно нужно добавить код и в db.php:
} elseif ($act=='edit') {
  $items=file('items.txt');
  
  $items[$_GET['id']]=$_GET['cont'];
  
  $items = array_map("rtrim", $items);
  $str = implode("\n", $items);
  file_put_contents ("items.txt", $str);
 }

Вот, собственно и все. Теперь у нас есть страница со списком, который мы можем редактировать не перегружая самой страницы.

Те, кто не захотел разбираться могут скачать все файлы в архиве и посмотреть как оно все работает уже готовое.

Конечно, приведенный код далеко не оптимальный, возможно имеет баги и проблемы безопасности, поэтому его нельзя использовать в ваших проектах. К тому же для работы со списками (и даже таблицами) есть специализированные framework-и созданные профессионалами. А этот пример нужен только для того, чтобы продемонстрировать основные принципы работы с jQuery и динамическими списками. А так же продемонстрировать то, что весь мир находится на грани катастрофы, потому что если кто-то захочет поработить человечество ему достаточно будет только пожужлить.

Итак, согласно принципам agile мы максимально быстро наупырили какое-то количество корявого кода. На следующем шаге я приведу его в порядок и обязательно поделюсь с вами.

Всем спасибо.

UPD.: Как я делал динамический список на jQuery #2

четверг, 4 марта 2010 г.

LinuxFoundation вебинары

SecurityLab сообщает, что вскоре начнется новая серия вебинаров от LinuxFoundation. Я уже совсем было собрался посмотреть, но оказалось, что наиболее интересный для меня Developing with GIT платный. Жаль.

вторник, 2 марта 2010 г.