Звездный рейтинг

UPD Статья относится к старому движку, так что никакого рейтинга вы сейчас тут не найдете, может потом снова прикручу.

Для тех, кому леньки написать комментарий я решил установить плагин star rating. Сложностей с установкой в принципе не возникло, но было пару нюансов которые я хочу описать.

Не смотря на всю красоту примеров в плагине, он совсем не такой красивый с точки зрения кода. Я начну с простых недостатков и перейду к сложным. Так вот первое что бросается в глаза, открыв код, это что автор не знает что такое табуляция и логические переносы строк. Код читается тяжело как книга начала века, в которой еще есть твердые знаки, на концах существительных, и буква ять.

В общем после небольшой обработки кода становятся видны прочие недостатки.

Первая погрешность выяснилась еще на стадии чтения документации, оказывается автор перепутал и при флаге required:false кнопка отмены показывается а при required:true наоборот — исчезает. Но это не беда по сравнению с тем, что будет дальше, от этого хотя бы есть лечение.

В моей большой и светлой мечте предполагалось что есть набор из 5 звездочек, два пользователя нажали 3 и 4, общий бал получился 3,5 так вот я предполагал что можно будет показывать звездочку закрашенную на половину, а нажав на нее отправить результат соответствующий номеру звездочки, а что в результате?! Если показывать звездочку, поделенную пополам то и нажимать на нее можно как на две, на одну половину и на вторую. Отсюда вывод, что для корректного отображения и голосования требуется выводить плагин дважды, один раз задисейбленый для оповещения о текущем результате второй раз, активный, для самого голосования, ну прямо таки ВиО!

Но это пол беды, для отправки формы используется метод ajaxSubmit, который не описан в самом классе, значит нужно найти плагин который реализовывает этот функционал. Нашелся он у меня совершенно случайно, это был плагин form, который я использую для комментариев. В общем, все бы ничего, да только захотелось отключить посылку формы при повторном нажатии на звездочку, то есть задизейблить. Раз послали, больше послать не можем, а то начнут рейтинг накручивать, а точнее в какашки втаптывать. И тут я столкнулся с тем, что плагин не имеет такого функционала, то есть плагин с самого начала можно запустить, используя флаг readOnly, но в процессе привести его в неактивное состояние не представляется возможным.

Посмотрев документацию и код я нашел, что в плагине для перехвата доступно только три события fill, reset, click, причем по странному стечению обстоятельств все три получают одни и те же параметры (значение и ссылку), и происходят в области видимости текущего html элемента (li). Почему я об этом заговорил?! Да потому что при нажатии на звездочку нельзя получить доступа к объекту плагина, это не есть хорошо! Потому что если я захочу получить, например коллекцию звездочек, то я не смогу это сделать, надо будет смотреть сгенерированный код и искать звездочки, отталкиваясь от него. Ну, в общем-то, я этим и занялся я посмотрел какой код получается в результате и выковыряв из него элементы прошелся по ним функцией обратной их созданию, то есть сначала убрал классы css и заменил на те которые используются при дезейбле, а потом отбиндил приаттаченные события.

В результате имеем вот такой простой и незатейливый код. Кстати первых два параметра (метода), хоть и взяты из мануала, но мне очень не нравиться, как-то плохо они состыковываются с концепцией jQuery.


	$('#rating :radio').rating({
		focus: function(value, link){
			var tip = $('#star-tip');
			tip[0].data = tip[0].data || tip.html();
			tip.html(link.title || 'value: '+value);
		},
		blur: function(value, link){
			var tip = $('#star-tip');
			$('#star-tip').html(tip[0].data || '');
		},
		callback: function(value, link){
			var form = $(this.form)
			form.ajaxSubmit({
				success:function(data) {
					$("div",form)
		                        .removeClass("star_live")
		                        .addClass("star_readonly")
		                        .unbind("mouseover")
		                        .unbind("mouseout")
		                        .unbind("click");
					$('#rate-message').text("Твой голос учтен!");
				},
				error:function(data) {
					form.fadeOut("slow");
					$('#rate-message').text("Ошибка!");
				}
			});
		},
		required:true
	});

Хочу еще заметить, что пришлось вызывать три раза подряд функцию unbind, потому что нельзя анбиндить сразу несколько анонимных функций, можно только именованные, вот так.

2 Комментарии “Звездный рейтинг

  1. Меня убивают создатели сайтов, которые не размещают свои координаты для связи (хотя бы мыло). Поэтому приходится постить комментами. Обалдеть!..

    Вообщем строка:
    $('#<b style="background-color:#ff0">rating</b> :radio').<b style="background-color:#ff0">rating</b>({
    меня полностью убила. Чтоже это за элемент, у которого такой id? Или автор чего-то напутал?
    Если можно, то хотелось бы получить ответ на мыло.
    Спасибо.

  2. @San
    Собственно ответ на Ваш вопрост прост))) это значит что вы перещли на эту статью с гугла, и одним из слов в поиске было "rating", вот оно и подсветилось жолтым. На будущее учту что такой глюк имеет место быть и поправлю. копия коментария отправлена на мыло

Комментарии закрыты