Обработка голосований
Набросал прототип кода для обработки голосований в движке. Это не законченный код, а некий его прототип, может кому пригодиться, пока не вышла новая версия. Этот код позволяет легко управлять голосованием и снизить объём HTML кода.
JS класс на Mootools:
Стили:
HTML голосования:
И не забываем подключить либы:
JS класс на Mootools:
<script>
var msgErrorBox=new Roar({
position: 'upperRight',
className: 'roar-error'
});
var msgNoticeBox=new Roar({
position: 'upperRight',
className: 'roar-notice'
});
var DIR_WEB_ROOT='http://livestreet';
var lsVote;
var lsVoteClass = new Class({
Implements: Options,
options: {
classes_action: {
voted: 'voted',
plus: 'plus',
minus: 'minus',
positive: 'positive',
negative: 'negative',
quest: 'quest'
},
classes_element: {
voting: 'voting',
count: 'count',
total: 'total',
plus: 'plus',
minus: 'minus'
}
},
typeVote: {
topic_comment: {
url: DIR_WEB_ROOT+'/include/ajax/voteComment.php'
}
},
initialize: function(options){
this.setOptions(options);
},
vote: function(idTarget,objVote,value,type) {
if (!this.typeVote[type]) {
return false;
}
this.idTarget=idTarget;
this.objVote=objVote;
this.value=value;
this.type=type;
thisObj=this;
JsHttpRequest.query(
this.typeVote[type].url,
{ idComment: idTarget, value: value },
function(result, errors) {
thisObj.onVote(result, errors, thisObj);
},
true
);
},
onVote: function(result, errors, thisObj) {
if (!result) {
msgErrorBox.alert('Error','Please try again later');
}
if (result.bStateError) {
msgErrorBox.alert(result.sMsgTitle,result.sMsg);
} else {
msgNoticeBox.alert(result.sMsgTitle,result.sMsg);
var divVoting=thisObj.objVote.getParent('div.'+thisObj.options.classes_element.voting);
divVoting.addClass(thisObj.options.classes_action.voted);
if (this.value>0) {
divVoting.addClass(thisObj.options.classes_action.plus);
}
if(this.value<0) {
divVoting.addClass(thisObj.options.classes_action.minus);
}
var divTotal=divVoting.getChildren('div.'+thisObj.options.classes_element.total);
result.iRating=parseInt(result.iRating);
if (result.iRating>0) {
divVoting.removeClass(thisObj.options.classes_action.negative);
divVoting.addClass(thisObj.options.classes_action.positive);
divTotal.set('text','+'+result.iRating);
}
if (result.iRating<0) {
divVoting.removeClass(thisObj.options.classes_action.positive);
divVoting.addClass(thisObj.options.classes_action.negative);
divTotal.set('text',result.iRating);
}
if (result.iRating==0) {
divTotal.set('text','0');
}
}
}
});
window.addEvent('domready', function() {
lsVote=new lsVoteClass();
});
</script>
Стили:
.voting a{
width:14px;
height:13px;
display:block;
}
.voting.voted .plus a, .voting.voted .minus a, .voting.quest .plus a, .voting.quest .minus a {
cursor:default;
}
.voting.plus .plus a {
background:transparent url(templates/skin/habra/img/vote_comment_up.gif) no-repeat;
}
.voting.plus .minus a {
background:transparent url(templates/skin/habra/img/vote_comment_down_gray.gif) no-repeat;
}
.voting.minus .plus a {
background:transparent url(templates/skin/habra/img/vote_comment_up_gray.gif) no-repeat;
}
.voting.minus .minus a {
background:transparent url(templates/skin/habra/img/vote_comment_down.gif) no-repeat;
}
.voting .minus a{
background:transparent url(templates/skin/habra/img/vote_comment_down.gif) no-repeat;
}
.voting .plus a{
background:transparent url(templates/skin/habra/img/vote_comment_up.gif) no-repeat;
}
.voting.quest .minus a {
background:transparent url(templates/skin/habra/img/vote_comment_down_gray.gif) no-repeat;
}
.voting.quest .plus a {
background:transparent url(templates/skin/habra/img/vote_comment_up_gray.gif) no-repeat;
}
.voting .total{
color: #c5c5c5;
}
.voting.negative .total{
color: #ff0000;
}
.voting.positive .total{
color: #339900;
}
HTML голосования:
<div class="voting">
<div class="count">12</div>
<div class="total">0</div>
<div class="plus"><a href="#" onclick="lsVote.vote(117,this,1,'topic_comment'); return false;"></a></div>
<div class="minus"><a href="#" onclick="lsVote.vote(117,this,-1,'topic_comment'); return false;"></a></div>
</div>
И не забываем подключить либы:
<script type="text/javascript" src="http://livestreet/classes/lib/external/MooTools_1.2/mootools-1.2-core-yc.js"></script>
<script type="text/javascript" src="http://livestreet/classes/lib/external/JsHttpRequest/JsHttpRequest.js"></script>
<script type="text/javascript" src="http://livestreet/classes/lib/external/MooTools_1.2/plugs/Roal/Roar.js"></script>
49 комментариев
Макс, обьясни, что это у тебя в HTML голосования:
<div class="voting">
<div class="count">12</div>
<div class="total">0</div>
<div class="plus"><a href="#" onclick="lsVote.vote(117,this,1,'topic_comment'); return false;"></a></div>
<div class="minus"><a href="#" onclick="lsVote.vote(117,this,-1,'topic_comment'); return false;"></a></div>
</div>
count — рейтинг комментария?
total — кол-во проголосовавших за комментарий?
117 — id комментрия?
total — рейтинг
117 — id коммента
там css не совсем правильный по-моему .voting.minus .minus ;)
DIR_WEB_ROOT по-моему определяется в header.tpl. Нужно только перенести его выше подключения этого скрипта.
насколько я понял сейчас реализованно только голосование за комментарии, правильно?typeVote: {
topic_comment: {
url: DIR_WEB_ROOT+'/include/ajax/voteComment.php'
}
},
но здесь нужно изменить обработчики аякса, т.к. сейчас они принимают на вход разные параметры(idComment, idTopic и т.п.), сделать их, например, idTarget
if (result.bStateError) {
msgErrorBox.alert(result.sMsgTitle,result.sMsgTitle.sMsg);
} else {
msgNoticeBox.alert(result.sMsgTitle,result.sMsgTitle.sMsg);
нужно исправить на
if (result.bStateError) {
msgErrorBox.alert(result.sMsgTitle,result.sMsg);
} else {
msgNoticeBox.alert(result.sMsgTitle,result.sMsg);
я переделал часть, касающуюся css
/* css voter */
.voting a.btn {
width:14px;
height:13px;
display:block;
background: transparent url(../img/btnVoteComment.png) no-repeat;
outline: 0;
}
/* can vote*/
.voting a.minus {
background-position: top right;
}
.voting a.plus {
background-position: top left;
}
.voting a.minus:hover {
background-position: -14px -13px;
}
.voting a.plus:hover {
background-position: 0-13px;
}
/* can vote*/
.voting.voted a.minus {
background-position: bottom right;
}
.voting.voted a.plus {
background-position: bottom left;
}
/* voted */
.voting.negative a.minus {
background-position: top right !important;
}
.voting.positive a.plus {
background-position: top left !important;
}
/**/
.voting .total{
color: #c5c5c5;
}
.voting.negative .total{
color: #ff0000;
}
.voting.positive .total{
color: #339900;
}
html
<!-- -->
<div class="voting">
<div class="count">0</div>
<div class="total">{$oComment->getRating()}</div>
<div><a class="btn plus" href="#" onclick="lsVote.vote({$oComment->getId()},this,1,'topic_comment'); return false;"></a></div>
<div><a class="btn minus" href="#" onclick="lsVote.vote({$oComment->getId()},this,-1,'topic_comment'); return false;"></a></div>
</div>
<!-- -->
картинка btnVoteComment.png
я в main.js подключил в конце… только в header.tpl вот эту конструкцию нужно выше подключения самого main.js перенести
<script type="text/javascript">
var DIR_WEB_ROOT='{$DIR_WEB_ROOT}';
var DIR_STATIC_SKIN='{$DIR_STATIC_SKIN}';
var BLOG_USE_TINYMCE='{$BLOG_USE_TINYMCE}';
</script>
ну и это убрать
<script>
var msgErrorBox=new Roar({
position: 'upperRight',
className: 'roar-error'
});
var msgNoticeBox=new Roar({
position: 'upperRight',
className: 'roar-notice'
});
var DIR_WEB_ROOT='http://livestreet';
к предыдущемы… замена в actions/actionBlog/comment.tpl
<!-- -->
{if !$oComment->getDelete()}
{if $oUserCurrent}
{if $oComment->getUserId()==$oUserCurrent->getId()}
<div class="voting voted">
{else}
{if $oComment->getUserIsVote()}
{if $oComment->getUserVoteDelta()>0}
<div class="voting positive">
{else}
<div class="voting voted negative">
{/if}
{else}
<div class="voting">
{/if}
{/if}
{else}
<div class="voting voted">
{/if}
<div class="count"></div>
<div class="total">{$oComment->getRating()}</div>
<div><a class="btn plus" href="#" onclick="lsVote.vote({$oComment->getId()},this,1,'topic_comment'); return false;"></a></div>
<div><a class="btn minus" href="#" onclick="lsVote.vote({$oComment->getId()},this,-1,'topic_comment'); return false;"></a></div>
</div>
{/if}
<!-- -->
и в мой css добавить вверх
.voting {
float:right;
height:13px;
}
.voting div {
float:left;
padding: 0002px;
}
у меня все работает ;) спасибо ort`у. Давно ждал…
.voting .total{
margin:-10px 000;
}
ну -10 многовато конечно, это так, для примера. В реальности хватит и -1
<div class="voting voted">
во втором вхождении лучше заменить на
<div class="voting quest">
юзер два проголосовал положительно — всё отлично зеленая кнопка активна, красная неактивна
юзер2 проголосовал отрицательно красная активна, зеленая не активна, по после рефреша активны обе
заходим юзером 1 на сайт и видим свои оценки напротив комментариев серым цветом как положительные так и отрицательные
а какой код в шаблоне /actions/actionBlog/comment.tpl? После рефреша ну никак не могут быть активны обе кнопки… потому как{if $oComment->getUserVoteDelta()>0}
<div class="voting positive">
{else}
<div class="voting voted negative">
{/if}т.е. либо то, либо другое.
Насчет серого цвета — пока не занимался
вот небольшая поправочка. цифорка меняет цвет (зеленая/красная) и при перезагрузке страницы нормально отображается результат голосования.<!-- -->
{if !$oComment->getDelete()}
{if $oUserCurrent}
{if $oComment->getUserId()==$oUserCurrent->getId()}
<div class="voting voted">
{else}
{if $oComment->getUserIsVote()}
{if $oComment->getUserVoteDelta()>0}
<div class="voting voted positive">
{else}
<div class="voting voted negative">
{/if}
{else}
{if $oComment->getRating()>=0}
<div class="voting positive">
{else}
<div class="voting negative">
{/if}
{/if}
{/if}
{else}
<div class="voting voted">
{/if}
<div class="count"></div>
<div class="total">{$oComment->getRating()}</div>
<div><a class="btn plus" href="#" onclick="lsVote.vote({$oComment->getId()},this,1,'topic_comment'); return false;"></a></div>
<div><a class="btn minus" href="#" onclick="lsVote.vote({$oComment->getId()},this,-1,'topic_comment'); return false;"></a></div>
</div>
{/if}
<!-- -->
после рефреша всё нормально -1
если зайти автором, которому ставили оценки все циферки серенькие
В js коде замени
divTotal.set('text','-'+result.iRating);
на
divTotal.set('text',result.iRating);
от двойного минуса это спасет точно
вот html
вот код comment.tpl
сейчас ниодна кнопка не нажимается