Nette, Dibi a našeptávání

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
knyttl
Člen | 196
+
0
-

Dobrý den,

potřebuji implementovat našeptávání pro přidávání tagů k článkům: Mám tabulky tags, articles a tags4articles, která tvoří vazby mezi nimi. Chci vytvořit input, který nebude součástí AppForm, ale bude sloužit pouze jako políčko pro našeptávání. Po zadání několika písmen a vybrání jednoho z navrhovaných tagů se ten vybraný přidá do AppForm jako hidden a našeptávací políčko se vyprázdní.

Samozřejmě se to dá natvrdo napsat přes jQuery, ale moc hezké to nebude – implementoval někdo něco podobného? Jak to udělat v Nette hezky?

Díky

wdolek
Člen | 331
+
0
-

neco podobneho jsem resil (tagum jsem ale rikal „keywords“), a jeste s tou funkci, ze kdyz tag neexistoval, tak se automaticky pridal.

prirazeni tagu pak spocitalo v tom, ze se tag pridal do multi-selectboxu, takze jsem pak jeste musel pridat udalost na odesilani formulare, aby se v selectu oznacilo vse (samozrejme sem to mohl cpat do nejakeho hidden inputu)…

data z naseptavace lezli pres ajax pres handler.

	/**
	 * @param string $kw
	 * @return void
	 */
	public function handleKeywordAutocomplete($kw) {
		$this->payload->kwAutoComplete = array();

		$kw = \Nette\String::trim($kw);
		if (!empty ($kw) && (strlen($kw) >= 3)) {
			$keywords = Keyword::find($kw);
			if (!empty ($keywords)) {
				foreach ($keywords as $keyword) {
					$this->payload->kwAutoComplete[$keyword->getId()] = $keyword->getWord();
				}
			}
		}
		$this->terminate();
	}
<script type="text/javascript">
	// <![CDATA[

	// form submit
	$('form').submit(function() {
		$(this).find('select[name^=keywords] option').each(function() {
			this.selected = true;
		});
		return true;
	});

	// keyword autocmoplete
	var cache = {};
	var matrix = [];

	$('form input#inKW').autocomplete({
		source: function(req, add) {
			if (cache.term == req.term && cache.content) {
				add(cache.content);
			}

			if (new RegExp(cache.term).test(req.term) && cache.content && cache.content.length < 13) {
				var matcher = new RegExp($.ui.autocomplete.escapeRegex(req.term), "i");
				add($.grep(cache.content, function(value) {
    				return matcher.test(value.value)
				}));
			}

			$.getJSON({link keywordAutocomplete!}, {'kw': req.term}, function(payload) {
				var suggestions = [];
				for (var i in payload.kwAutoComplete) {
					cache.term = req.term;
					cache.content = payload.kwAutoComplete[i];

					matrix[ payload.kwAutoComplete[i] ] = i;

					suggestions.push(payload.kwAutoComplete[i]);
				}
				add(suggestions);
			});
		},
		minLength: 3,
		delay: 0
	});

	// when <Enter> pressed on 'inKW' input, form wont be submitted
	$('form input#inKW').keydown(function(e) {
		var key = e.keyCode || e.which;
		if (key === 13) {
			e.preventDefault();
			$('form a#addKW').click();
		}
	});

	// add keyword button click event
	$('form a#addKW').click(function() {
		var newKW = $('form input#inKW').val();
		newKW = jQuery.trim(newKW);

		if (newKW.length == 0) {
			return;
		}

		// check if keyword is not already in list
		if ($('form select[name^=keywords] option').length) {
			var kwFound = false;
			$('form select[name^=keywords] option').each(function(i, el) {
				if (el.text == newKW) {
					kwFound = true;
					return;
				}
			});
			if (kwFound) {
				$('form input#inKW').val('');
				return;
			}
		}

		// create new option
		var $newOpt = $(document.createElement('option'));
		var kwID = ((matrix[newKW] == undefined) ? newKW : matrix[newKW]);

		$newOpt.attr('value', kwID);
		$newOpt.text(newKW);

		// append option to list
		$('form select[name^=keywords]').append($newOpt);

		// clear textfield
		$('form input#inKW').val('');
	});

	// remove keyword(s) button click event
	$('form a#rmKW').click(function() {
		var i = $('form select[name^=keywords] option:selected').remove();
	});

	// ]]>
</script>

a nemam pocit, ze by to bylo zas tak moc ohavne reseni :) … autocomplete prevzat z http://jqueryui.com/…utocomplete/#…