评价系统其实是个input单选框,换成了星星样式而已,基本上是个纯前端的效果,使用现成的jquery基础上的plugin就可以了,实测可用的项目地址如下
https://github.com/wbotelhos/raty/
其中有用的只有
https://github.com/wbotelhos/raty/blob/master/lib/jquery.raty.js
https://github.com/wbotelhos/raty/blob/master/lib/jquery.raty.css
这两个文件,把这两个文件分别放在项目的
app/assets/javascripts
app/assets/stylesheets
下面
然后需要设置一下页面的预备载入,初始化时候加入该文件位置
config/initializers/assets.rb
Rails.application.config.assets.precompile += %w( jquery.raty.css )
Rails.application.config.assets.precompile += %w( jquery.raty.js )
但是这里面还是有个问题需要解决,就是需要设置评分的星星样式
比如我设置了两个图片分别是
star-off.png
start-on.png
图片下载地址如下
https://ooo.0o0.ooo/2016/11/21/5832a40577f56.png
https://ooo.0o0.ooo/2016/11/21/5832a40578015.png
直接放在了 public/ 下面,这样我就能通过/star-off.png和/star-on.png来直接调用
都设置完成后,我终于可以再项目中使用了
首先我需要做个带id的div
<div id="rating-for-message-1" class="text-center"></div>
在我需要给该rating嵌入一个script
$("#rating-for-message-1").raty({
path:"/",
starOff: 'star-off.png',
starOn: 'star-on.png',
size: 32
});
这就行了,跑起来后浏览器会把它渲染成为一个input,到时候里面填好值,直接放到表单里submit提交就行了
Ajax提交rating
如果是简单的表单提交评价,以上即可,如果是ajax提交要求页面不刷新,需要继续往下看
ajax提交首先后台需要有个接收提交的controller的action,比如这个接收三个参数conversation_id,message_id,rating
# 评价系统
def rating
# 获取message的参数
conversation_id = params[:conversation_id]
message_id = params[:message_id]
score = params[:rating]
# 找到指定的message
conversation = Conversation.find(conversation_id.to_i)
message = conversation.messages.find(message_id.to_i)
# 为message评级
message.rating = score
message.save
return 'success'
end
然后路由需要把它放出来
# 评价系统
collection do
post :rating
end
然后js部分比较繁琐
$(function() {
// 初始化rating选框
function initRating(obj) {
obj.raty({
path:"/",
starOff: 'star-off.png',
starOn: 'star-on.png',
size: 32,
click: function(score, evt) {
// ajax提交
ajaxRating(score);
// 锁定rating
lockRating(obj,score)
}
});
};
// ajax提交评级
function ajaxRating(score) {
$.ajax({
url: '<%= rating_account_questions_path %>',
type: 'POST',
dataType: 'json',
data: {
'conversation_id' : <%= @conversation.id %>,
'message_id' : <%= m.id %>,
'rating': score
},
})
.done(function() {
console.log("raty success");
})
.fail(function() {
console.log("raty error");
})
.always(function() {
console.log("raty complete");
});
};
// 锁定星星不可重新提交
function lockRating(obj,score) {
// 锁定部分样式
obj.raty({
path:"/",
starOff: 'star-off.png',
starOn: 'star-on.png',
size: 32,
readOnly: true, score: score
});
};
// 允许评分的对象
var ratableObj = $('#rating-for-message-<%= m.id %>');
initRating(ratableObj);
// 已经评过分的对象
var unRatableObj = $('#raty-for-message-<%= m.id %>');
lockRating(unRatableObj,'<%= m.rating %>');
});
</script>
细节是:
首先需要有个初始页面自动加载的函数
$(function() {
// 需要运行的所有js
});
然后需要区分两种星星,一种评价前的一种评价后的,使用不同的js函数来处理
// 允许评分的对象
var ratableObj = $('#rating-for-message-<%= m.id %>');
initRating(ratableObj);
// 已经评过分的对象
var unRatableObj = $('#raty-for-message-<%= m.id %>');
lockRating(unRatableObj,'<%= m.rating %>');
分别写initRating()和lockRating()
initRating()
// 初始化rating选框
function initRating(obj) {
obj.raty({
path:"/",
starOff: 'star-off.png',
starOn: 'star-on.png',
size: 32,
click: function(score, evt) {
// ajax提交
// 锁定rating
}
});
};
lockRating()
// 锁定星星不可重新提交
function lockRating(obj,score) {
// 锁定部分样式
obj.raty({
path:"/",
starOff: 'star-off.png',
starOn: 'star-on.png',
size: 32,
readOnly: true, score: score
});
};
未评价的input点击后事件是
click: function(score, evt) {
// ajax提交
ajaxRating(score);
// 锁定rating
lockRating(obj,score)
}
由于『锁定rating』直接用lockRating()就可以了,而『ajax提交』需要另外写,用来提交这三个参数
ajaxRating()
// ajax提交评级
function ajaxRating(score) {
$.ajax({
url: '<%= rating_account_questions_path %>',
type: 'POST',
dataType: 'json',
data: {
'conversation_id' : <%= @conversation.id %>,
'message_id' : <%= m.id %>,
'rating': score
},
})
.done(function() {
console.log("raty success");
})
.fail(function() {
console.log("raty error");
})
.always(function() {
console.log("raty complete");
});
};