<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>CTAPbIu_MABP&#039;s BLOG &#187; autocomplete</title>
	<atom:link href="http://mabp.kiev.ua/tag/autocomplete/feed/" rel="self" type="application/rss+xml" />
	<link>http://mabp.kiev.ua</link>
	<description>энтузиазм = 1/опыт © Старый Мавр</description>
	<lastBuildDate>Sat, 12 May 2012 07:40:54 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2</generator>
		<item>
		<title>JComboBox Demo</title>
		<link>http://mabp.kiev.ua/2009/12/04/jcombobox-demo/</link>
		<comments>http://mabp.kiev.ua/2009/12/04/jcombobox-demo/#comments</comments>
		<pubDate>Fri, 04 Dec 2009 18:00:10 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[JAVA]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[autocomplete]]></category>
		<category><![CDATA[combobox]]></category>
		<category><![CDATA[swing]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=1142</guid>
		<description><![CDATA[Пока я сижу без реального проекта вдохновение брать неоткуда :( Поэтому постить тут буду что есть, а есть первый толковый вопрос по Java с форума Задание было дизейблить кнопку если в комбике ничего не введено Swing конечно не jQuery но на нем тоже можно делать UI package ua.kiev.mabp; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JFrame; import [...]]]></description>
			<content:encoded><![CDATA[<p>Пока я сижу без реального проекта вдохновение брать неоткуда :( Поэтому постить тут буду что есть, а есть первый толковый вопрос по <a href="http://mabp.kiev.ua/category/programming/java/">Java</a> с <a href="http://pyha.ru/forum/" rel="nofollow external">форума</a></p>
<p>Задание было дизейблить кнопку если в комбике ничего не введено Swing конечно не jQuery но на нем тоже можно делать UI</p>

<span id="more-1142"></span>
<pre><code class="java">
package ua.kiev.mabp;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Vector;

/**
 * Created by IntelliJ IDEA.
 * User: CTAPbIu_MABP
 * Date: 30.11.2009
 * Time: 18:48:00
 */

public class ComboBoxEventDemo extends JFrame {

    public ComboBoxEventDemo(String name) {
        super(name);
    }

    public void addComponentsToPane(final Container pane) {

        String comboPrefix = "ComboBox Item #";
        int numItems = 15;
        Vector&lt;String&gt; vector = new Vector&lt;String&gt;(numItems);
        for (int i = 0; i &lt; numItems; i++) {
            vector.addElement(comboPrefix + i);
        }

        final JComboBox searchCombo = new JComboBox(vector);
        searchCombo.setEditable(true);
        final JButton okButton = new JButton("OK");

        searchCombo.getEditor().getEditorComponent().addKeyListener(new KeyListener() {
            public void keyTyped(KeyEvent e) {
                System.out.print("keyTyped");
            }

            public void keyPressed(KeyEvent e) {
                System.out.print("keyPressed");
            }

            public void keyReleased(KeyEvent e) {
                System.out.print("keyReleased");
                try {
                    String s = (String) searchCombo.getSelectedItem();
                    okButton.setEnabled(s != null &#038;& !s.isEmpty());
                }
                catch (NullPointerException npe) {
                    okButton.setEnabled(false);
                }
            }
        });

        add(searchCombo);
        add(okButton);

        pane.setLayout(new GridBagLayout());
        setPreferredSize(new Dimension(450, 450));
    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                FocusEventDemo frame = new ComboBoxEventDemo("JComboBox Demo");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.addComponentsToPane(frame.getContentPane());
                frame.pack();
                frame.setVisible(true);
            }
        });
    }
}
</code></pre>

<p>Я прекрасно понимаю что это гавно никому не надо не мне ни вам, хотя кто знает может кому-то когда-то пригодится, а пишу я это для того чтоб вы не забывали что я еще есть и жив, зашли на мой сайт оставить камент типа "ну и дерьмо же ты постишь, чувак, совсем хуевый стал, отпишусь ка я от твоего RSS" и тем самым накрутили бы мне счетчик посещаймости :D</p>
<p>Ладно заспойлю вам кое-что, может не отпишитесь от моего RSS. В ближайшее время будет статья о векторной графике с красивым примером.</p>]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2009/12/04/jcombobox-demo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Обновил автокомплит</title>
		<link>http://mabp.kiev.ua/2009/09/01/autocomplete-update-3/</link>
		<comments>http://mabp.kiev.ua/2009/09/01/autocomplete-update-3/#comments</comments>
		<pubDate>Tue, 01 Sep 2009 18:32:02 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[autocomplete]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=1107</guid>
		<description><![CDATA[С помощью Andrea Riciputi добрался поправить пару минорных багов в автокомплите, заодно с его пинка, точнее на основе его патча дописал новый функционал который позволяет кастомизировать селект под автокоплит. В общем смотрите сами: Common Eider Corncrake Common Crane Common Ringed Plover Common Snipe Common Redshank Common Tern Common Kingfisher Crested Lark Common Raven Corn Bunting [...]]]></description>
			<content:encoded><![CDATA[<p>С помощью Andrea Riciputi добрался поправить пару минорных багов в <a href="http://mabp.kiev.ua/2008/04/08/autocomplete/">автокомплите</a>, заодно с его пинка, точнее на основе его патча дописал новый функционал который позволяет кастомизировать селект под автокоплит. В общем смотрите сами:</p>
<span id="more-1107"></span>

<link href="/content/source/autocomplete/autocomplete.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="/content/source/autocomplete/jquery.autocomplete.js"></script>

<select name="myselect" id="myselect">
<option value='Somateria mollissima'>Common Eider</option>
<option value='Crex crex'>Corncrake</option>
<option value='Grus grus'>Common Crane</option>
<option value='Charadrius hiaticula'>Common Ringed Plover</option>
<option value='Gallinago gallinago'>Common Snipe</option>
<option value='Tringa totanus'>Common Redshank</option>
<option value='Sterna hirundo'>Common Tern</option>
<option value='Alcedo atthis'>Common Kingfisher</option>
<option value='Galerida cristata'>Crested Lark</option>
<option value='Corvus corax'>Common Raven</option>
<option value='Emberiza calandra'>Corn Bunting</option>
<option value='Tadorna tadorna'>Common Shelduck</option>
<option value='Bucephala clangula'>Common Goldeneye</option>
<option value='Buteo buteo'>Common Buzzard</option>
<option value='Phoenicurus phoenicurus'>Common Redstart</option>
<option value='Apus apus'>Common Swift</option>
<option value='Sylvia communis'>Common Whitethroat</option>
<option value='Tringa nebularia'>Common Greenshank</option>
<option value='Columba palumbus'>Common Wood Pigeon</option>
<option value='Delichon urbicum'>Common House Martin</option>
<option value='Carduelis cannabina'>Common Linnet</option>
<option value='Cuculus canorus'>Common Cuckoo</option>
<option value='Lophophanes cristatus'>Crested Tit</option>
<option value='Turdus merula'>Common Blackbird</option>
<option value='Actitis hypoleucos'>Common Sandpiper</option>
<option value='Emberiza schoeniclus'>Common Reed Bunting</option>
<option value='Sturnus vulgaris'>Common Starling</option>
<option value='Aythya ferina'>Common Pochard</option>
<option value='Phylloscopus collybita'>Common Chiffchaff</option>
<option value='Falco tinnunculus'>Common Kestrel</option>
<option value='Fringilla coelebs'>Common Chaffinch</option>
<option value='Gallinula chloropus'>Common Moorhen</option>
<option value='Anas crecca'>Common Teal</option>
<option value='Corvus corone'>Carrion Crow</option>
<option value='Periparus ater'>Coal Tit</option>
<option value='Cettia cetti'>Cetti's Warbler</option>
<option value='Motacilla citreola'>Citrine Wagtail</option>
<option value='Calidris ferruginea'>Curlew Sandpiper</option>
<option value='Loxia curvirostra'>Common Crossbill</option>
<option value='Coturnix coturnix'>Common Quail</option>
<option value='Luscinia megarhynchos'>Common Nightingale</option>
<option value='Hydroprogne caspia'>Caspian Tern</option>
<option value='Carpodacus erythrinus'>Common Rosefinch</option>
<option value='Locustella naevia'>Common Grasshopper Warbler</option>
<option value='Melanitta nigra'>Common Scoter</option>
<option value='Bubulcus ibis'>Cattle Egret</option>
<option value='Aythya valisineria'>Canvasback</option>
<option value='Calonectris borealis'>Cory`s Shearwater</option>
<option value='Dromas ardeola'>Crab-Plover</option>
<option value='Cursorius cursor'>Cream-coloured Courser</option>
<option value='Glareola pratincola'>Collared Pratincole</option>
<option value='Charadrius asiaticus'>Caspian Plover</option>
<option value='Larus cachinnans'>Caspian Gull</option>
<option value='Aethia cristatella'>Crested Auklet</option>
<option value='Chaetura pelagica'>Chimney Swift</option>
<option value='Saxicola maura variegata'>Caspian Stonechat</option>
<option value='Acrocephalus fuscus'>Caspian Reed Warbler</option>
<option value='Emberiza cirlus'>Cirl Bunting</option>
<option value='Melanocorypha calandra'>Calandra Lark</option>
<option value='Ficedula albicollis'>Collared Flycatcher</option>
<option value='Emberiza caesia'>Cretzschmar`s Bunting</option>
<option value='Emberiza rutila'>Chestnut Bunting</option>
<option value='Pyrrhocorax pyrrhocorax'>Chough</option>
<option value='Alectoris chukar'>Chukar</option>
</select>

<script type="text/javascript">
jQuery().ready(function($){
    $("select#myselect").autocomplete();
});
</script>

<p>Вот такая прелесть получается из вот такой простой разметки и одной строчки кода</p>

<pre><code class="html">
&lt;select name="myselect" id="myselect"&gt;
&lt;option value='Somateria mollissima'&gt;Common Eider&lt;/option&gt;
&lt;option value='Crex crex'&gt;Corncrake&lt;/option&gt;
&lt;option value='Grus grus'&gt;Common Crane&lt;/option&gt;
&lt;option value='Charadrius hiaticula'&gt;Common Ringed Plover&lt;/option&gt;
&lt;option value='Gallinago gallinago'&gt;Common Snipe&lt;/option&gt;
&lt;option value='Tringa totanus'&gt;Common Redshank&lt;/option&gt;
&lt;option value='Sterna hirundo'&gt;Common Tern&lt;/option&gt;
&lt;option value='Alcedo atthis'&gt;Common Kingfisher&lt;/option&gt;
&lt;option value='Galerida cristata'&gt;Crested Lark&lt;/option&gt;
&lt;option value='Corvus corax'&gt;Common Raven&lt;/option&gt;
&lt;option value='Emberiza calandra'&gt;Corn Bunting&lt;/option&gt;
&lt;option value='Tadorna tadorna'&gt;Common Shelduck&lt;/option&gt;
&lt;option value='Bucephala clangula'&gt;Common Goldeneye&lt;/option&gt;
&lt;option value='Buteo buteo'&gt;Common Buzzard&lt;/option&gt;
&lt;option value='Phoenicurus phoenicurus'&gt;Common Redstart&lt;/option&gt;
&lt;option value='Apus apus'&gt;Common Swift&lt;/option&gt;
&lt;option value='Sylvia communis'&gt;Common Whitethroat&lt;/option&gt;
&lt;option value='Tringa nebularia'&gt;Common Greenshank&lt;/option&gt;
&lt;option value='Columba palumbus'&gt;Common Wood Pigeon&lt;/option&gt;
&lt;option value='Delichon urbicum'&gt;Common House Martin&lt;/option&gt;
&lt;option value='Carduelis cannabina'&gt;Common Linnet&lt;/option&gt;
&lt;option value='Cuculus canorus'&gt;Common Cuckoo&lt;/option&gt;
&lt;option value='Lophophanes cristatus'&gt;Crested Tit&lt;/option&gt;
&lt;option value='Turdus merula'&gt;Common Blackbird&lt;/option&gt;
&lt;option value='Actitis hypoleucos'&gt;Common Sandpiper&lt;/option&gt;
&lt;option value='Emberiza schoeniclus'&gt;Common Reed Bunting&lt;/option&gt;
&lt;option value='Sturnus vulgaris'&gt;Common Starling&lt;/option&gt;
&lt;option value='Aythya ferina'&gt;Common Pochard&lt;/option&gt;
&lt;option value='Phylloscopus collybita'&gt;Common Chiffchaff&lt;/option&gt;
&lt;option value='Falco tinnunculus'&gt;Common Kestrel&lt;/option&gt;
&lt;option value='Fringilla coelebs'&gt;Common Chaffinch&lt;/option&gt;
&lt;option value='Gallinula chloropus'&gt;Common Moorhen&lt;/option&gt;
&lt;option value='Anas crecca'&gt;Common Teal&lt;/option&gt;
&lt;option value='Corvus corone'&gt;Carrion Crow&lt;/option&gt;
&lt;option value='Periparus ater'&gt;Coal Tit&lt;/option&gt;
&lt;option value='Cettia cetti'&gt;Cetti's Warbler&lt;/option&gt;
&lt;option value='Motacilla citreola'&gt;Citrine Wagtail&lt;/option&gt;
&lt;option value='Calidris ferruginea'&gt;Curlew Sandpiper&lt;/option&gt;
&lt;option value='Loxia curvirostra'&gt;Common Crossbill&lt;/option&gt;
&lt;option value='Coturnix coturnix'&gt;Common Quail&lt;/option&gt;
&lt;option value='Luscinia megarhynchos'&gt;Common Nightingale&lt;/option&gt;
&lt;option value='Hydroprogne caspia'&gt;Caspian Tern&lt;/option&gt;
&lt;option value='Carpodacus erythrinus'&gt;Common Rosefinch&lt;/option&gt;
&lt;option value='Locustella naevia'&gt;Common Grasshopper Warbler&lt;/option&gt;
&lt;option value='Melanitta nigra'&gt;Common Scoter&lt;/option&gt;
&lt;option value='Bubulcus ibis'&gt;Cattle Egret&lt;/option&gt;
&lt;option value='Aythya valisineria'&gt;Canvasback&lt;/option&gt;
&lt;option value='Calonectris borealis'&gt;Cory`s Shearwater&lt;/option&gt;
&lt;option value='Dromas ardeola'&gt;Crab-Plover&lt;/option&gt;
&lt;option value='Cursorius cursor'&gt;Cream-coloured Courser&lt;/option&gt;
&lt;option value='Glareola pratincola'&gt;Collared Pratincole&lt;/option&gt;
&lt;option value='Charadrius asiaticus'&gt;Caspian Plover&lt;/option&gt;
&lt;option value='Larus cachinnans'&gt;Caspian Gull&lt;/option&gt;
&lt;option value='Aethia cristatella'&gt;Crested Auklet&lt;/option&gt;
&lt;option value='Chaetura pelagica'&gt;Chimney Swift&lt;/option&gt;
&lt;option value='Saxicola maura variegata'&gt;Caspian Stonechat&lt;/option&gt;
&lt;option value='Acrocephalus fuscus'&gt;Caspian Reed Warbler&lt;/option&gt;
&lt;option value='Emberiza cirlus'&gt;Cirl Bunting&lt;/option&gt;
&lt;option value='Melanocorypha calandra'&gt;Calandra Lark&lt;/option&gt;
&lt;option value='Ficedula albicollis'&gt;Collared Flycatcher&lt;/option&gt;
&lt;option value='Emberiza caesia'&gt;Cretzschmar`s Bunting&lt;/option&gt;
&lt;option value='Emberiza rutila'&gt;Chestnut Bunting&lt;/option&gt;
&lt;option value='Pyrrhocorax pyrrhocorax'&gt;Chough&lt;/option&gt;
&lt;option value='Alectoris chukar'&gt;Chukar&lt;/option&gt;
&lt;/select&gt;
</code></pre>

<pre><code class="javascript">
$("select#myselect").autocomplete();
</code></pre>

<p>По умолчанию используются вот такие опции:</p>

<pre><code class="javascript">
{
    source: this,
    values: true,
    fillin: true,
    writable : false,
    onSelect: function() {
        select.val(this.pairs[this.ac.val()]);
    }
}
</code></pre>]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2009/09/01/autocomplete-update-3/feed/</wfw:commentRss>
		<slash:comments>28</slash:comments>
		</item>
		<item>
		<title>Обновил автокомплит</title>
		<link>http://mabp.kiev.ua/2009/05/16/autocomplete-update-2/</link>
		<comments>http://mabp.kiev.ua/2009/05/16/autocomplete-update-2/#comments</comments>
		<pubDate>Sat, 16 May 2009 13:49:11 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[autocomplete]]></category>
		<category><![CDATA[combobox]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=1069</guid>
		<description><![CDATA[Решил поправить несколько надоедливых багов в автокомплите. Обновления прошли под принципом KISS, чем меньше кода добавлено для получения максимальной гибкости, тем лучше! Поправлена кнопка таб, теперь при ее нажатии происходит выбор текущего элемента и переход курсора в следующее поле ввода. Добавлена возможность использовать кастомный формат данных переданных с бэкенда. Например можно использовать вложенные массивы [{a:'a'},{b:'b'}]. [...]]]></description>
			<content:encoded><![CDATA[<p>Решил поправить несколько надоедливых багов в <a href="http://mabp.kiev.ua/2008/04/08/autocomplete/">автокомплите</a>. Обновления прошли под принципом KISS, чем меньше кода добавлено для получения максимальной гибкости, тем лучше!</p>
<span id="more-1069"></span>
<ul>
<li>Поправлена кнопка таб, теперь при ее нажатии происходит выбор текущего элемента и переход курсора в следующее поле ввода.</li>
<li>Добавлена возможность использовать кастомный формат данных переданных с бэкенда. Например можно использовать вложенные массивы [{a:'a'},{b:'b'}]. Для этого надо использовать параметр dataHandler передавая в него функцию для обработки данных, пример функции смотрите в <a href="http://mabp.kiev.ua/2008/04/08/autocomplete/">example 12</a></li>
<li>Добавлена поддержка каскадных списков, для этого в параметр url теперь можно передавать функцию, которая будет возвращать новую ссылку, следите за тем чтобы функция очищала кеш.</li>
<li>Для неполных списков, добавлен флаг partial который будет заставлять автокомплит делать запрос на сервер каждый раз как введена следующая буква слова.</li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2009/05/16/autocomplete-update-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Обновил автокомплит</title>
		<link>http://mabp.kiev.ua/2009/02/18/autocomplete-update/</link>
		<comments>http://mabp.kiev.ua/2009/02/18/autocomplete-update/#comments</comments>
		<pubDate>Wed, 18 Feb 2009 20:16:01 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[autocomplete]]></category>
		<category><![CDATA[perfomance]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=737</guid>
		<description><![CDATA[Вчера весь вечер сидел дописывал в autocomplete вещи которые больше нельзя было игнорировать. А сегодня вашему вниманию предлагается changelog: Полностью убрано определение браузеров, потому что оно не просто бесполезно а по большому счету мешает и сбивает с толку в случаи с Chrome которого jQuery определяет как Safari , а на самом деле он ведет себя [...]]]></description>
			<content:encoded><![CDATA[<p>Вчера весь вечер сидел дописывал в <a href="http://mabp.kiev.ua/2008/04/08/autocomplete/" title="autocomplete">autocomplete</a> вещи которые больше нельзя было игнорировать. А сегодня вашему вниманию предлагается changelog:</p>
<span id="more-737"></span>
<ul>
<li>Полностью убрано определение браузеров, потому что оно не просто бесполезно а по большому счету мешает и сбивает с толку в случаи с <a href="http://mabp.kiev.ua/tag/chrome/">Chrome</a> которого <a href="http://mabp.kiev.ua/tag/jquery/">jQuery</a> определяет как <a href="http://mabp.kiev.ua/tag/safari/">Safari</a> , а на самом деле он ведет себя как <a href="http://mabp.kiev.ua/tag/firefox/">FireFox</a> . Теперь все везде работает за счет хаков <a href="http://mabp.kiev.ua/category/programming/css/">CSS</a> и сглаживания <a href="http://mabp.kiev.ua/tag/jquery/">jQuery</a> .</li>
<li>Сделал давно прошеную фишку, чтобы можно было передавать не только видимое значение (text) но и реальное значение (value). Это работает не только с option, но также с объектами и массивами. Для объекта будет возвращаться ключ, а для массива будет возвращаться порядковый номер начиная с нуля.</li>
<li>Для того чтобы передача истинного значения выглядела аккуратно пришлось еще добавить режим select-only который не даст пользователю написать свой вариант в <a href="http://mabp.kiev.ua/2008/04/08/autocomplete/" title="autocomplete">autocomplete</a>, но как по мне это не правильно, потому что так все возвращается обратно к функциональности select-box'a.</li>
<li>По скольку до объекта <a href="http://mabp.kiev.ua/2008/04/08/autocomplete/" title="autocomplete">autocomplete</a> напрямую кроме как из событий добраться нельзя я сделал событие onSetup в котором можно произвести произвольные манипуляции с <a href="http://mabp.kiev.ua/2008/04/08/autocomplete/" title="autocomplete">autocomplete</a>  после того как он будет создан. Это позволит управлять элементами назначая им новые обработчики или стили.</li>
<li>Еще убран хак для <a href="http://mabp.kiev.ua/tag/safari/">Safari</a> так как у меня на винде в найтбилдах он больше не появляется, если он не исчез - пишите и я верну.</li>
</ul>

<p>В остальных местах еще немного порефакторил. Но это влияет только на производительность. Где-то в глубине рефакторинга решил использовать метод live для всех элементов выпадающего списка, но потом понял что для этого придется отказаться от поддержки <a href="http://mabp.kiev.ua/tag/jquery/">jQuery</a> версии 1.2.6, а мне этого не хотелось и подумав еще я сумел сделать код еще проще.</p>

]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2009/02/18/autocomplete-update/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Автокэш</title>
		<link>http://mabp.kiev.ua/2008/05/08/autocache/</link>
		<comments>http://mabp.kiev.ua/2008/05/08/autocache/#comments</comments>
		<pubDate>Thu, 08 May 2008 16:08:29 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[algorithms]]></category>
		<category><![CDATA[autocomplete]]></category>
		<category><![CDATA[perfomance]]></category>

		<guid isPermaLink="false">http://mabp.localhost/?p=209</guid>
		<description><![CDATA[Я тут недавно получил комментарий от человека со странным ником, он сказал мне, что мой autocomplete конечно всем хорош, но имеет один существенный недостаток. Получив данные от сервера через AJAX, при уточнении критерия поиска он снова обращается к серверу, вместо того чтобы фильтровать уже полученные данные. Приведу пример. Мы ищем города начинающиеся на 'К' и [...]]]></description>
			<content:encoded><![CDATA[<p>Я тут недавно получил комментарий от человека со странным ником, он сказал мне, что мой <a href="http://mabp.kiev.ua/2008/04/08/autocomplete/" title="autocomplete">autocomplete</a> конечно всем хорош, но имеет один существенный недостаток. Получив данные от сервера через AJAX, при уточнении критерия поиска он снова обращается к серверу, вместо того чтобы фильтровать уже полученные данные.</p>
<span id="more-209"></span>
<p>Приведу пример. Мы ищем города начинающиеся на 'К' и получаем от сервера ответ ['кардуба','кардижопа','казупий','кипир'] :) При вводе второй буквы мы уже не обращаемся к серверу, а фильтруем то, что получили прошлый раз, например вторая буква 'А' тогда 'КА' = ['кардуба','кардижопа','казупий']. При вводе третьей буквы все повторяется 'КАР' =  ['кардуба','кардижопа'].</p>
<p>Я вижу два выхода из этой ситуации. </p>
<p>Первый - это простой обход всего массива каждый раз при вводе новой буквы, недостаток этого метода в том что при 1000 городах это будет занимать уже ощутимое время.</p>
<p>Второй способ полон геморроя и собственно его я и буду дальше описывать. Для его реализации понадобиться намного больше память, но намного меньше времени, я не могу сказать, что лучше память или время, но могу сказать, что второй способ хотя бы напряг мои мозги. Так вод вам понадобиться: вазелин офисный, пол литра, руки прямые, две штуки  и терпение, много терпения, хотя нет, руки, пожалуй, должны сгибаться в локтях....</p>
<p>Итак что собственно делаем. Вводим первую букву 'К', получаем от сервера ответ и сохраняем в переменной cache в таком виде.</p>

<pre><code class="javascript">
cache =  {
	'К':['кардуба','кардижопа','казупий','кипир']
};
</code></pre>

<p>Вводим вторую букву 'А', теперь у нас строка 'КА', выбираем все ключи нашего кэша и начиная с самого длинного начинаем искать вхождение ключа в строку, если находим берем массив-значение и фильтруем а потом сохраняем результат с новым ключом, в результате. </p>

<pre><code class="javascript">
cache = {
	'К':['кардуба','кардижопа','казупий','кипир'],
	'КА':['кардуба','кардижопа','казупий']
};
</code></pre>

<p>Еще раз та же процедура вводим 'Р', строка 'КАР', берем ключи объекта, разворачиваем в обратном порядке (чтобы сначала шли самые длинные), и ищем их вхождение в строку, если нашлось то снова фильтруем и сохраняем.</p>

<pre><code class="javascript">
cache = {
	'К':['кардуба','кардижопа','казупий','кипир'], 
	'КА':['кардуба','кардижопа','казупий'], 
	'КАР':['кардуба','кардижопа']
};
</code></pre>

<p>Как видите одни и те же города находятся в массиве много раз, это есть не очень экономно с точки зрения памяти но зато к ним очень быстро можно получить доступ. Реализация этого метода тоже весьма муторная и я был бы не против сильно её заоптимайзить но вот что-то никак...</p>

<pre><code class="javascript">

var cache = {'':['кардуба','кардижопа','казупий','кипир','другой город','еще село']},
	mask = ['к','ка','кар'];
	
function check(mask){
	// пытаемся быстро выйти
	if (cache[mask])
		return cache[mask]; 
	
	// инициализируем переменные
	var map = [], array = [];
	
	// получаем массив ключей
	for(var item in cache)
		array.push(item);
	// разворачиваем самыми длинными вначало
	array = array.reverse();
	
	// ищем...
	for(var item in array)
		// если вхождение ключа в строку имеет нулевую позицию
		if(!mask.indexOf(array[item])){
			// фильтруем
			for(var word in cache[array[item]])
				// если вхождение строки в элемент иммеет нулевую позицию
				if (!cache[array[item]][word].indexOf(mask))
					// сохраняем
					map.push(cache[array[item]][word]);
			break;
		}
	alert(map);
	cache[mask] = map
}

for (m in mask)
	check(mask[m]);
	

</code></pre>

<p>Вот такой вот алгоритм получился... Но это все было бы очень хорошо если бы наш бэкэнд (я имею ввиду сайт Киевстара) не возвращал только первых 500 найденных записей на каждый запрос, то есть если всего найдено 700 записей, то будут показаны только 500, причем первых найденных базой а не первых в алфавитном порядке.</p>
<p>Такое кэширование я конечно включу в следующий релиз <a href="http://mabp.kiev.ua/2008/04/08/autocomplete/" title="autocomplete">autocomplete</a>, но применять его сам вряд ли буду.</p>
]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2008/05/08/autocache/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Autocomplete</title>
		<link>http://mabp.kiev.ua/2008/04/08/autocomplete/</link>
		<comments>http://mabp.kiev.ua/2008/04/08/autocomplete/#comments</comments>
		<pubDate>Tue, 08 Apr 2008 14:57:44 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[animation]]></category>
		<category><![CDATA[autocomplete]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[UI plugin]]></category>

		<guid isPermaLink="false">http://mabp.localhost/?p=64</guid>
		<description><![CDATA[Prehistory First of all, I want to say, that this plugin was developed for KyivStar, therefore all fine details were studied and stipulated very carefully. For example, what should occur, when the user would reach last element of the list: whether it should rest against the end or begin a cycle all over again. Or [...]]]></description>
			<content:encoded><![CDATA[<h2 class="title">Prehistory</h2>
<br />
<p>First of all, I want to say, that this plugin was developed for <a href="http://www.kyivstar.ua/" rel="nofollow external">KyivStar</a>, therefore all fine details were studied and stipulated very carefully. For example, what should occur, when the user would reach last element of the list: whether it should rest against the end or begin a cycle all over again. Or whether the list should disappear when the cursor is out of it. All this passed through business analysts’ and designer and only then came to me. </p>

<span id="more-64"></span>

<link href="/content/source/autocomplete/autocomplete.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="/content/source/autocomplete/jquery.autocomplete.js"></script>
<script type="text/javascript" src="/content/source/jquery.bgiframe.js"></script>
<script type="text/javascript" src="/content/js/autocomplete.js"></script>

<p>On the other hand I tried to make autocomplete multifunctional (multipurpose) and as simple as possible for any person to use it on ones site. Remarkable is that even with switched off javascript the site would not lose functionality, and visitor can enter data anyway. Autocomplete was not made as a filtrator of data entered by the user but the tool which helps the user to fill the form more quickly. </p>
<p>Well-known plugin jquery.suggest was taken as an example. Pieces of which can be identified in some methods. In spite of the fact that I took mechanism, I have added some new functions and have removed some errors. So in last version jquery.suggest the code became more readable thanks to the removal of one check.  But at the end of the list the cursor (illumination) disappears for one position and then again appears at the first element of the list. It happens because jquery (in traversing) always return itself to the object and doesn’t give value to quantity chosen nodes. Another authors fault that he persistently tries to apply $.fn.bgiframe to the list &lt;ul/&gt;, This invention is certainly noble, but I couldn’t deal with this on practice. </p>
<p>Functions that were added: generation of the list from select-box, the limited visible part of the list with scrolling and prefilling of the list for it to look like a select-box. One more events handling onKeyPress. Well-known algorithm of caching MRU was deleted and replaced with my cache algorithm, this takes a lot of memory but it very fast!</p>

<br />
<br />
<h2 class="title">Downloads</h2>
<br />
<p>Last update 14.09.2009!</p>
<br />
<a href="http://mabp.kiev.ua/content/source/autocomplete/autocomplete.html">HTML file with examples (autocomplete.html)</a><br />
<a href="http://mabp.kiev.ua/content/source/autocomplete/jquery.autocomplete.js">Plugin itself (jquery.autocomplete.js)</a><br />
<a href="http://mabp.kiev.ua/content/source/autocomplete/autocomplete.css">Styles (autocomplete.css)</a><br />
<a href="http://mabp.kiev.ua/content/source/autocomplete/select.gif">Little blue arrow (select.gif)</a><br />
<a href="http://mabp.kiev.ua/content/source/autocomplete/progress.gif">Progress bar backgraund image (progress.gif)</a><br />
<a href="http://mabp.kiev.ua/content/source/autocomplete/search.phps">Php backend (search.phps)</a><br />
<p>Copy all this files to your own local web-server in root directory, rename search.phps to search.php and run http://path.to.your.server/autocomplete.html.</p>
<br />
<br />
<h2 class="title">Examples</h2>
<br />
<h4>Example 1: Minimal requirements</h4>
<p>To launch plugin you just need to put in one parameter, the url of php script which generats a list of words. Format of the list can be either xml or json.</p>
<input id="autocomplete1"/>
<pre><code class="javascript">
$("#autocomplete1").autocomplete({
	url:'search.php'
});
</code></pre>

<br />
<h4>Example 2: onSelect event</h4>
<p>Plugin has four public events. First of them is onSelect, it fires where you pick element from the list. You can activate it by left clicking or pressing 'enter' button on the selected item. In this example I use one second delay before searching, and string must be at least 2 characters. The ansver from server will be in xml format so you can omit <b>type</b> property.</p>
<input id="autocomplete2"/>
<pre><code class="javascript">
$("#autocomplete2").autocomplete({
	url:'search.php?type=xml',
	minchar:2,
	delay:1000, // in milliseconds
	onSelect:function(){
		alert(this.ac.val())
	},
	type:'xml'
});
</code></pre>

<br />
<h4>Example 3: onKeyPress</h4>
<p>onKeyPress event fires when you are typing. It can be used to filtrate user input. In this example you can use only alphabetical characters and white space, all other characters will be deleted. The <b>fillin</b> flag will fill in list before user start typing, because of input string is empty the request to the server will also contains empty mask value (i.e. search.php?type=json&#038;mask=). In this case you will see list of one item with text "The list is empty!". The ansver from server will be in json format and you must set <b>type</b> property to 'json'.</p>
<input id="autocomplete3"/>
<pre><code class="javascript">
$("#autocomplete3").autocomplete({
	url:'search.php?type=json',
	onKeyPress:function(){
		var o=this;
		setTimeout(function(){
			o.ac.val(o.ac.val().replace(/[^a-z ]+/g,""))
		},50)
	},
	fillin:true,
	type:'json'
});
</code></pre>

<br />
<h4>Example 4: onError event</h4>
<p>onError and onSuccess is the last two events, onError fires when AJAX has a problems otherwise onSuccess fires when you get answer from server. For example onError fires where you request for non-existing page. Also its an example of how to disable autocomplete. onSuccess get the same parametrs and scope.</p>
<input id="autocomplete4"/>
<pre><code class="javascript">
$("#autocomplete4").autocomplete({
	url:'non_exist.php',
	onError:function(XMLHttpRequest, textStatus, errorThrown){
		this.ac.val(textStatus);
		this.ac.attr({disabled:"disabled"}).css({'background-color':'#d0d0d0'});
		this.ul.hide();
		this.img.unbind("click");
	}
});
</code></pre>

<br />
<h4>Example 5: generation list from &lt;select&gt;</h4>
<p>All previous examples generats autocomplete from AJAX but you also can do this from html code of current page. You can replace existing select-boxes with autocomplete by using <b>source</b> instead of <b>url</b>. You can pass in plugin either string with selectors like '#select.class' or jQuery object $('#select.class'). Pre-filling and digit-only filtrating is enable.</p>
<input id="autocomplete5"/>
<select id="select">
<option>100</option><option>101</option><option>102</option><option>103</option><option>104</option><option>105</option><option>106</option><option>107</option><option>108</option><option>109</option>
<option>110</option><option>111</option><option>112</option><option>113</option><option>114</option><option>115</option><option>116</option><option>117</option><option>118</option><option>119</option>
<option>120</option><option>121</option><option>122</option><option>123</option><option>124</option><option>125</option><option>126</option><option>127</option><option>128</option><option>129</option>
<option>130</option><option>131</option><option>132</option><option>133</option><option>134</option><option>135</option><option>136</option><option>137</option><option>138</option><option>139</option>
<option>140</option><option>141</option><option>142</option><option>143</option><option>144</option><option>145</option><option>146</option><option>147</option><option>148</option><option>149</option>
<option>150</option><option>151</option><option>152</option><option>153</option><option>154</option><option>155</option><option>156</option><option>157</option><option>158</option><option>159</option>
<option>160</option><option>161</option><option>162</option><option>163</option><option>164</option><option>165</option><option>166</option><option>167</option><option>168</option><option>169</option>
<option>170</option><option>171</option><option>172</option><option>173</option><option>174</option><option>175</option><option>176</option><option>177</option><option>178</option><option>179</option>
<option>180</option><option>181</option><option>182</option><option>183</option><option>184</option><option>185</option><option>186</option><option>187</option><option>188</option><option>189</option>
<option>190</option><option>191</option><option>192</option><option>193</option><option>194</option><option>195</option><option>196</option><option>197</option><option>198</option><option>199</option>
</select>

<pre><code class="javascript">
$("#autocomplete5").autocomplete({
	source:"#select",
		onKeyPress:function(){
		var o=this;
		setTimeout(function(){
			o.ac.val(o.ac.val().replace(/[^0-9]+/g,""))
		},50)
	},
	fillin:true
});
</code></pre>

<br />
<h4>Example 6: generation list from array</h4>
<p>If you have no need to use AJAX or have no select-box on your page, you can generate autocomplete from array. Sorry but nested arrays are not supported so you can not use [{a:'a'},{b:'b'}]</p>
<input id="autocomplete6"/>
<pre><code class="javascript">
$("#autocomplete6").autocomplete({
	source:['a','b','c','d','e'],
	fillin:true
});
</code></pre>

<br />
<h4>Example 7: generation list from object</h4>
<p>The same as above. Sorry but nested objects are not supported so you can not use [{a:'a'},{b:'b'}] or {a:{b:c}}</p>
<input id="autocomplete7"/>
<pre><code class="javascript">
$("#autocomplete7").autocomplete({
	source:{a:'a',b:'b',c:'c',d:'d',e:'e'},
	fillin:true
});
</code></pre>

<br />
<h4>Example 8: list position</h4>
<p>Example of list position at the top of input box</p>
<input id="autocomplete8"/>
<pre><code class="javascript">
$("#autocomplete8").autocomplete({
	url:'search.php',
	top:true
});
</code></pre>

<br />
<h4>Example 9: real values</h4>
<p>Example of real values in non writeable fields</p>
<input id="autocomplete9"/>
<pre><code class="javascript">
$("#autocomplete9").autocomplete({
	url:'search.php',
	values : true,
	writable : false,
	onSelect:function(){
		alert(this.pairs[this.ac.val()]);
	}
});
</code></pre>

<br />
<h4>Example 10: alternative setup</h4>
<p>By onSetup event you can change all properties exept 'width' or change behaviour of elements after autocomplete created. This example demonstrate smooth animation to options list.</p>
<input id="autocomplete10"/>
<pre><code class="javascript">
$("#autocomplete10").autocomplete({
	onSetup:function(){
		var self = this;
		self.url = 'search.php';
		self.img.unbind("click")
			.bind("click", function() {
				clearTimeout(self.close);
				self.scroll();
				self.ul.slideToggle("slow")
				self.ac.focus();
			});
	}
});
</code></pre>

<br />
<h4>Example 11: progress animation</h4>
<p>Example of real usage with event hndling and animation</p>
<input id="autocomplete11"/>
<pre><code class="javascript">
$("#autocomplete11").autocomplete({
	url:'/content/polygon/search.php?type=json',
	onSuggest:function(){
		this.ac.css({'background-image': 'url("/content/source/autocomplete/progress.gif")'});
	},
	onError:function(XMLHttpRequest, textStatus, errorThrown){
		this.ac.val(textStatus);
		this.ac.attr({disabled:"disabled"}).css({'background-color':'#d0d0d0','background-image':'none'});
		this.ul.hide();
		this.img.unbind("click");
	},
	onDisplay:function(list){
		this.ac.css({'background-image':'none'});
		if (!list)
		this.ul.append("&lt;div style='line-height:100px;text-decoration:underline;text-align:center;'&gt;[Empty list...]&lt;/div&gt;");
	},
	minchar:2,
	type:'json'
});
</code></pre>
<br />
<h4>Example 12: custom data format</h4>
<p>Example of how to use custom data format</p>
<input id="autocomplete12"/>
<pre><code class="javascript">
$("#autocomplete12").autocomplete({
    source : [{a:'a'},{b:'b'},{c:'c'},{d:'d'},{e:'e'}],
    fillin : true,
    dataHandler : function(mask){
        var self = this;
        return function(i, n) {
        for (var key in n){
            self.cache[mask].push(n[key]);
        }
        self.store[mask] += self.mark(n[key],mask);
        if(self.values &#038;& !self.pairs[n[key]])
            self.pairs[n[key]] = key;
        };
    }
});
</code></pre>

<br />
<h4>Example 13: cascading selectbox</h4>
<p>Example of how create selectbox wich depends on another input field</p>
<input id="autocomplete13"/><input type="checkbox" id="c13"/>
<pre><code class="javascript">
$("#autocomplete13").autocomplete({
    url:function(self){
        var state = $("#c13").attr("checked");
        if (self.ac.data("c13") != state){
            self.ac.data("c13", state);
            self.cache = {};
            self.store = {};
            self.pairs = {};
        }
        return 'search.php?c13='+state;
    }
});
</code></pre>

<br />
<h4>Example 14: autocomplete form selectbox</h4>
<p>Example of how to customize selectbox with plug-in</p>
<select name="myselect" id="autocomplete14">
<option value='Somateria mollissima'>Common Eider</option>
<option value='Crex crex'>Corncrake</option>
<option value='Grus grus'>Common Crane</option>
<option value='Charadrius hiaticula'>Common Ringed Plover</option>
<option value='Gallinago gallinago'>Common Snipe</option>
<option value='Tringa totanus'>Common Redshank</option>
<option value='Sterna hirundo'>Common Tern</option>
<option value='Alcedo atthis'>Common Kingfisher</option>
<option value='Galerida cristata'>Crested Lark</option>
<option value='Corvus corax'>Common Raven</option>
<option value='Emberiza calandra'>Corn Bunting</option>
<option value='Tadorna tadorna'>Common Shelduck</option>
<option value='Bucephala clangula'>Common Goldeneye</option>
<option value='Buteo buteo'>Common Buzzard</option>
<option value='Phoenicurus phoenicurus'>Common Redstart</option>
<option value='Apus apus'>Common Swift</option>
<option value='Sylvia communis'>Common Whitethroat</option>
<option value='Tringa nebularia'>Common Greenshank</option>
<option value='Columba palumbus'>Common Wood Pigeon</option>
<option value='Delichon urbicum'>Common House Martin</option>
<option value='Carduelis cannabina'>Common Linnet</option>
<option value='Cuculus canorus'>Common Cuckoo</option>
<option value='Lophophanes cristatus'>Crested Tit</option>
<option value='Turdus merula'>Common Blackbird</option>
<option value='Actitis hypoleucos'>Common Sandpiper</option>
<option value='Emberiza schoeniclus'>Common Reed Bunting</option>
<option value='Sturnus vulgaris'>Common Starling</option>
<option value='Aythya ferina'>Common Pochard</option>
<option value='Phylloscopus collybita'>Common Chiffchaff</option>
<option value='Falco tinnunculus'>Common Kestrel</option>
<option value='Fringilla coelebs'>Common Chaffinch</option>
<option value='Gallinula chloropus'>Common Moorhen</option>
<option value='Anas crecca'>Common Teal</option>
<option value='Corvus corone'>Carrion Crow</option>
<option value='Periparus ater'>Coal Tit</option>
<option value='Cettia cetti'>Cetti's Warbler</option>
<option value='Motacilla citreola'>Citrine Wagtail</option>
<option value='Calidris ferruginea'>Curlew Sandpiper</option>
<option value='Loxia curvirostra'>Common Crossbill</option>
<option value='Coturnix coturnix'>Common Quail</option>
<option value='Luscinia megarhynchos'>Common Nightingale</option>
<option value='Hydroprogne caspia'>Caspian Tern</option>
<option value='Carpodacus erythrinus'>Common Rosefinch</option>
<option value='Locustella naevia'>Common Grasshopper Warbler</option>
<option value='Melanitta nigra'>Common Scoter</option>
<option value='Bubulcus ibis'>Cattle Egret</option>
<option value='Aythya valisineria'>Canvasback</option>
<option value='Calonectris borealis'>Cory`s Shearwater</option>
<option value='Dromas ardeola'>Crab-Plover</option>
<option value='Cursorius cursor'>Cream-coloured Courser</option>
<option value='Glareola pratincola'>Collared Pratincole</option>
<option value='Charadrius asiaticus'>Caspian Plover</option>
<option value='Larus cachinnans'>Caspian Gull</option>
<option value='Aethia cristatella'>Crested Auklet</option>
<option value='Chaetura pelagica'>Chimney Swift</option>
<option value='Saxicola maura variegata'>Caspian Stonechat</option>
<option value='Acrocephalus fuscus'>Caspian Reed Warbler</option>
<option value='Emberiza cirlus'>Cirl Bunting</option>
<option value='Melanocorypha calandra'>Calandra Lark</option>
<option value='Ficedula albicollis'>Collared Flycatcher</option>
<option value='Emberiza caesia'>Cretzschmar`s Bunting</option>
<option value='Emberiza rutila'>Chestnut Bunting</option>
<option value='Pyrrhocorax pyrrhocorax'>Chough</option>
<option value='Alectoris chukar'>Chukar</option>
</select>
<pre><code class="javascript">
$("select#autocomplete14").autocomplete();
</code></pre>

<br />
<h2 class="title">Notice</h2>
<p>There is no simple way to re-render autocomplete created from select-box or array (object). You just need to re-create it.</p>

<br />
<h2 class="title">Donation</h2>
<p>If you like this plugin please vote for it on <a href="http://plugins.jquery.com/project/jautocomplete" rel="nofollow">jquery site</a></p>

<br />
<h2 class="title">Thanks to</h2>
<ul>
<li>Damir</li>
<li>Connected</li>
<li>Joey</li>
<li>Pasha</li>
<li>Morleydots</li>
<li>Gianfrasoft</li>
<li>Andrea</li>
<li>Ztalker </li>
<li>WooYek</li>
<li>Naden</li>
<li>Andrea Riciputi</li>
</ul>

<br />
<br />
<h2 class="title">Advanced options</h2>
<h4>Properties</h4>
<ul>
<li><b>url</b> - [String|Function] ajax url </li>
<li><b>source</b> - [String|jQuery|Array|Object] css selector or raw html, jQuery object, array [], object {}</li>
<li><b>minchar</b> - [Integer] The minimum number of characters a user has to type before the autocompleter activates (default <b>1</b>)</li>
<li><b>delay</b> - [Integer] The delay in milliseconds the autocompleter waits after a keystroke to activate itself (default <b>50</b> miliseconds)</li>
<li><b>fillin</b> - [Boolean] Pre-fill in (default <b>false</b>)</li>
<li><b>width</b> - [Integer] width of autocomplete (default <b>200</b>)</li>
<li><b>type</b> - [String] type of server responce xml or json (default <b>xml</b>)</li>
<li><b>top</b> - [Boolean] position of the list (default <b>false</b> to the bottom)</li>
<li><b>writable</b> - [Boolean] allows to user write his own option (default <b>true</b>)</li>
<li><b>values</b> - [Boolean] keep values for options (default <b>false</b>)</li>
<li><b>partial</b> - [Boolean] makes request to server after each new letter (default <b>false</b>)</li>

</ul>
<h4>Events</h4>
<ul>
<li><b>onKeyPress</b> - fires when user press a button</li>
<li><b>onSetup</b> - fires once when autocomplit created</li>
<li><b>onSuggest</b> - fires after onKeyPress but before ajax request send</li>
<li><b>onSuccess</b> - fires when AJAX retuns result</li>
<li><b>onError</b> - fires when AJAX retuns error</li>
<li><b>onDisplay</b> - fires before list of items shows</li>
<li><b>onSelect</b> - fires when user picks up from list</li>
</ul>

<h4>Dependences</h4>
<ul>
<li><b>jQuery</b> - requires jQuery 1.2.6 or higher</li>
<li><b>bgiframe</b> - use bgiframe if installed</li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2008/04/08/autocomplete/feed/</wfw:commentRss>
		<slash:comments>100</slash:comments>
		</item>
		<item>
		<title>YUI: autocomplete</title>
		<link>http://mabp.kiev.ua/2006/11/28/yui-autocomplete/</link>
		<comments>http://mabp.kiev.ua/2006/11/28/yui-autocomplete/#comments</comments>
		<pubDate>Tue, 28 Nov 2006 14:25:06 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[autocomplete]]></category>
		<category><![CDATA[combobox]]></category>
		<category><![CDATA[YUI]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=1203</guid>
		<description><![CDATA[Что такое AJAX, наверное, уже знают все. (кто не знает, идет гуглить), А что такое YUI я рассказывал в прошлой статье Итак, автокомплит это технология, по которой данные взятые, например из аджакса (это совершенно не обязательно) предлагаются пользователю для быстрого заполнения полей формы. Например, пользователь пишет в поле "город" несколько букв - "Сан" ему будут [...]]]></description>
			<content:encoded><![CDATA[<p>Что такое AJAX, наверное, уже знают все. (кто не знает, идет гуглить), А что такое YUI я рассказывал в <a href="http://mabp.kiev.ua/2006/11/27/yui-calendar/">прошлой статье</a></p>

<p>Итак, автокомплит это технология, по которой данные взятые, например из аджакса (это совершенно не обязательно) предлагаются пользователю для быстрого заполнения полей формы. Например, пользователь пишет в поле "город" несколько букв - "Сан" ему будут предложены варианты "Санкт-Петербург", "Сан-Франциско" и "Сан Ремо" и пользователь быстро может выбрать мышкой или с клавиатуры то что ему нравится.</p>
<span id="more-1203"></span>
<p>Проблема один - AJAX. Надо писать frontend (javascript) приложение, для клиента основанное на классе JsHttpRequest и backend (например, на php) приложение с запросом к БД</p>

<p>Проблема два нарисовать красивый выпадающий список с навигацией с клавиатуры. Проблема собственно у ослика (как обычно) потому что он не обрабатывает нажатие стрелочек в отличие от всех других браузеров.</p>

<p>Кстати, как и в прошлой статье, я отнюдь не говорю что это либа это панацея всех проблем! например, она очень тяжелая. Но раз я уже начал писать, а вы читать... продолжим</p>

<p>подключаем либу</p>

<pre><code class="html">
&lt;script type="text/javascript" src="lib/yahoo/yahoo/yahoo.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript" src="lib/yahoo/dom/dom.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript" src="lib/yahoo/event/event.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript" src="lib/yahoo/connection/connection.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript" src="lib/yahoo/animation/animation.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript" src="lib/yahoo/autocomplete/autocomplete.js"&gt;&lt;/script&gt;
</code></pre>

<p>и css</p>

<pre><code class="css">
#ysearchmod {position:relative;padding:1em;}
#firstname_root {z-index:3000;} /* for IE z-index of absolute divs inside relative divs issue */
#secondname_root {z-index:2000;} /* for IE z-index of absolute divs inside relative divs issue */
#lastname_root {z-index:1000;} /* for IE z-index of absolute divs inside relative divs issue */
.yui-ac-content {position:absolute;width:100%;border:1px solid #404040;background:#fff;overflow:hidden;z-index:9050;}
.ysearchquery {position:absolute;right:10px;color:#808080;z-index:10;}
.yui-ac-shadow {position:absolute;margin:.3em;width:100%;background:#a0a0a0;z-index:9049;}
ul {padding:5px 0;width:100%;}
li {padding:0 5px;cursor:default;white-space:nowrap;}
li.yui-ac-highlight {background:#a0a0a0;}
li.yui-ac-prehighlight {background:pink;}
</code></pre>

<p>Для тех кто заметил что этот css сильно отличается от предлагаемого YAHOO объясняю - так как они описывают каждый элемент уже при трех полях на ajaxe css станет пухлым и дохлым поэтому я вынес его в JavaScript</p>

<p>И еще на заметку я буду предлагать заполнять ФИО</p>

<p>Последний штрих рисуем HTML</p>

<pre><code class="html">
&lt;div id="firstname_root"&gt;&lt;input type="text" name="firstname" id="firstname" value=""&gt;&lt;div id="firstname_conteiner"&gt;&lt;/div&gt;&lt;div&gt;
&lt;div id="secondname_root"&gt;&lt;input type="text" name="secondname" id="secondname" value=""&gt;&lt;div id="secondname_conteiner"&gt;&lt;div id="firstname_conteiner"&gt;&lt;/div&gt;&lt;div&gt;
&lt;div id="lastname_root"&gt;&lt;input type="text" name="lastname" id="lastname" value=""&gt;&lt;div id="firstname_conteiner"&gt;&lt;div id="lastname_conteiner"&gt;&lt;/div&gt;&lt;div&gt;
</code></pre>

<p>А теперь в тегах &lt;_script&gt;...&lt;_/script&gt; описываем загрузчик, он же frontend приложение</p>

<pre><code class="javascript">
// определяем именное пространство
YAHOO.namespace("AutoComplete");
/*
Грубо говоря если вы определите YAHOO.namespace("XXX");
то следующая строчка будет выглядеть так
YAHOO.XXX = function(input){
*/

// конструктор
YAHOO.AutoComplete = function(input){
var oACDS;
var oAutoComp;
var oDiv = null;

	// CSS, вот сюда то я и вынес все излишнее свойства
	if (oDiv=document.getElementById(input))
	{
		var rDiv = document.getElementById(input+'_root');
		var cDiv = document.getElementById(input+'_conteiner');
		oDiv.style.position = "absolute";
		oDiv.style.width = "100%";
		rDiv.style.height = "2em";
		rDiv.style.position = "relative";
		rDiv.style.margin_bottom = "1.5em";
		rDiv.style.width = "100%";
		cDiv.style.position = "absolute";
		cDiv.style.top = "1.7em";
		cDiv.style.width = "100%";
	}


    // заполняем первый объект oACDS, он у нас отвечает за AJAX
    // адресс backend'a с параметрами
    oACDS = new YAHOO.widget.DS_XHR("/backend.php", ["n", "t"]);
    // вид ответа - простой текст - по одному варианту на строку
    oACDS.responseType = YAHOO.widget.DS_XHR.TYPE_FLAT;
    // кеширование
   oACDS.queryMatchSubset = true;
    // время кеширования 60 сек
    oACDS.maxCacheEntries = 60;

    // этот параметр отвечает за дополнительные параметры в url, который запрашивается
    //тоесть вместо /backend.php данные будут посланы на /backend.php?active=имя_поля
    oACDS.scriptQueryAppend = '&#038;active=' + input;

    //заполняем второй объект отвечающий за autocomplete, ему по большому счету нужно только имя поля в
    //котором должен работать скрипт
    oAutoComp = new YAHOO.widget.AutoComplete(input,input+'_conteiner', oACDS);
    // разделитель (по умолчанию дописывает в конце выбранного варианта ';')
    oAutoComp.delimChar = "";
    // задержка в секундах до отправки запроса
    oAutoComp.queryDelay = 0;
    // минимальная длина строки перед поиском
    oAutoComp.minQueryLength=1;
    // имя класса для выделенного варианта ответа
    oAutoComp.prehighlightClassName = "yui-ac-prehighlight";
    // отключает автокомплит в браузере чтоб он не мешал
    oAutoComp.allowBrowserAutocomplete = false;
    // можно еще поизвращаться с анимацией, но это вы сделаете сами

};
//ну и собственно стартуем скрипт по разу на каждое поле
YAHOO.AutoComplete('firstname')
</code></pre>

Теперь backend надо написать, да?!

<pre><code class="php">
// я полностью писать не буду, просто объясню. Данные из аджакса приходят в кодировке UCS-2BE поэтому 
// ее надо перекодировать в win-1251

// таблица символов
$unicode_to_cp1251_tbl = array(
	0x0402 =&gt; "x80",	0x0403 =&gt; "x81",	0x201A =&gt; "x82",	0x0453 =&gt; "x83",
	0x201E =&gt; "x84",	0x2026 =&gt; "x85",	0x2020 =&gt; "x86",	0x2021 =&gt; "x87",
	0x20AC =&gt; "x88",	0x2030 =&gt; "x89",	0x0409 =&gt; "x8A",	0x2039 =&gt; "x8B",
	0x040A =&gt; "x8C",	0x040C =&gt; "x8D",	0x040B =&gt; "x8E",	0x040F =&gt; "x8F",
	0x0452 =&gt; "x90",	0x2018 =&gt; "x91",	0x2019 =&gt; "x92",	0x201C =&gt; "x93",
	0x201D =&gt; "x94",	0x2022 =&gt; "x95",	0x2013 =&gt; "x96",	0x2014 =&gt; "x97",
	0x2122 =&gt; "x99",	0x0459 =&gt; "x9A",	0x203A =&gt; "x9B",	0x045A =&gt; "x9C",
	0x045C =&gt; "x9D",	0x045B =&gt; "x9E",	0x045F =&gt; "x9F",	0x00A0 =&gt; "xA0",
	0x040E =&gt; "xA1",	0x045E =&gt; "xA2",	0x0408 =&gt; "xA3",	0x00A4 =&gt; "xA4",
	0x0490 =&gt; "xA5",	0x00A6 =&gt; "xA6",	0x00A7 =&gt; "xA7",	0x0401 =&gt; "xA8",
	0x00A9 =&gt; "xA9",	0x0404 =&gt; "xAA",	0x00AB =&gt; "xAB",	0x00AC =&gt; "xAC",
	0x00AD =&gt; "xAD",	0x00AE =&gt; "xAE",	0x0407 =&gt; "xAF",	0x00B0 =&gt; "xB0",
	0x00B1 =&gt; "xB1",	0x0406 =&gt; "xB2",	0x0456 =&gt; "xB3",	0x0491 =&gt; "xB4",
	0x00B5 =&gt; "xB5",	0x00B6 =&gt; "xB6",	0x00B7 =&gt; "xB7",	0x0451 =&gt; "xB8",
	0x2116 =&gt; "xB9",	0x0454 =&gt; "xBA",	0x00BB =&gt; "xBB",	0x0458 =&gt; "xBC",
	0x0405 =&gt; "xBD",	0x0455 =&gt; "xBE",	0x0457 =&gt; "xBF",	0x0410 =&gt; "xC0",
	0x0411 =&gt; "xC1",	0x0412 =&gt; "xC2",	0x0413 =&gt; "xC3",	0x0414 =&gt; "xC4",
	0x0415 =&gt; "xC5",	0x0416 =&gt; "xC6",	0x0417 =&gt; "xC7",	0x0418 =&gt; "xC8",
	0x0419 =&gt; "xC9",	0x041A =&gt; "xCA",	0x041B =&gt; "xCB",	0x041C =&gt; "xCC",
	0x041D =&gt; "xCD",	0x041E =&gt; "xCE",	0x041F =&gt; "xCF",	0x0420 =&gt; "xD0",
	0x0421 =&gt; "xD1",	0x0422 =&gt; "xD2",	0x0423 =&gt; "xD3",	0x0424 =&gt; "xD4",
	0x0425 =&gt; "xD5",	0x0426 =&gt; "xD6",	0x0427 =&gt; "xD7",	0x0428 =&gt; "xD8",
	0x0429 =&gt; "xD9",	0x042A =&gt; "xDA",	0x042B =&gt; "xDB",	0x042C =&gt; "xDC",
	0x042D =&gt; "xDD",	0x042E =&gt; "xDE",	0x042F =&gt; "xDF",	0x0430 =&gt; "xE0",
	0x0431 =&gt; "xE1",	0x0432 =&gt; "xE2",	0x0433 =&gt; "xE3",	0x0434 =&gt; "xE4",
	0x0435 =&gt; "xE5",	0x0436 =&gt; "xE6",	0x0437 =&gt; "xE7",	0x0438 =&gt; "xE8",
	0x0439 =&gt; "xE9",	0x043A =&gt; "xEA",	0x043B =&gt; "xEB",	0x043C =&gt; "xEC",
	0x043D =&gt; "xED",	0x043E =&gt; "xEE",	0x043F =&gt; "xEF",	0x0440 =&gt; "xF0",
	0x0441 =&gt; "xF1",	0x0442 =&gt; "xF2",	0x0443 =&gt; "xF3",	0x0444 =&gt; "xF4",
	0x0445 =&gt; "xF5",	0x0446 =&gt; "xF6",	0x0447 =&gt; "xF7",	0x0448 =&gt; "xF8",
	0x0449 =&gt; "xF9",	0x044A =&gt; "xFA",	0x044B =&gt; "xFB",	0x044C =&gt; "xFC",
	0x044D =&gt; "xFD",	0x044E =&gt; "xFE",	0x044F =&gt; "xFF",
);

// функция поиска по таблице
function utf8_to_cp1251($s) {
	$tbl = $GLOBALS['unicode_to_cp1251_tbl'];
	$uc = 0;
	$bits = 0;
	$r = "";
	for($i = 0, $l = strlen($s); $i &lt; $l; $i++)
	{
		$c = $s{$i};
		$b = ord($c);
		if($b &#038; 0x80) 
		{
			if($b &#038; 0x40)
			{
				if($b &#038; 0x20) 
				{
					$uc = ($b &#038; 0x0F) &lt;&lt; 12;
					$bits = 12;
				} else {
					$uc = ($b &#038; 0x1F) &lt;&lt; 6;
					$bits = 6;
				}
			} else {
				$bits -= 6;
				if($bits)
				{
					$uc |= ($b &#038; 0x3F) &lt;&lt; $bits;
				} else {
					$uc |= $b &#038; 0x3F;
					if($cc = @$tbl[$uc]) 
					{
						$r .= $cc;
					} else {
						$r .= '?';
					}
				}
			}
		} else {
			$r .= $c;
		}
	}
	return $r;
}

// применяем функцию ко всем входящим данным
foreach ($_REQUEST as $key =&gt; $value){
    $_REQUEST[$key] = utf8_to_cp1251($value);
}

// из всех данный нужно только 2
$like = $_REQUEST['query'];
$field = $_REQUEST['active'];

// соединяемся с БД
mysql_connect('localhost','user','pass');
mysql_select_db('namedatabase');

//Ну и собственно спрашиваем есть ли похожие имена
$sql = mysql_query("SELECT ".$field." AS suggestion FROM table_name WHERE ".$field." LIKE '$like%' ORDER BY ".$field."LIMIT 50");

// выводим списком ответ
while($result = mysql_fetch_assoc($sql)){
    echo $result['suggestion']."n";
}
</code></pre>

<p>Вот, пожалуй, и все. Кстати очень тяжелая (много килобайт весит) либа. Subsys от Котерова намного легче и практичнее, но не имеет автокомплита. Попытки втиснуть его туда насильно увенчались успехом только для FF1.5 и Opera8.0 , IE ругался</p>]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2006/11/28/yui-autocomplete/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

