今天实现文档或文章的标签的时候,发现没有想象的那么简单,记录一下。
这里为了简单起见,设计的标签都是使用英文的逗号分隔
服务端:
这里涉及两方面的问题:
1、新标签的批量添加、更新
2、原来标签的删除
用new_tag_array表示新的标签数组
用old_tag_array表示原来数据库中存储的标签数组
这里的思路:
使用array_diff(old_tag_array, new_tag_array)得到的差集,从数据库中批量删除
然后再批量添加new_tag_array到数据库
代码如下:
$param = $this->request->param();
$project_id = $param['project_id'];
//新的标签数组
$array = explode(',', $param['tags'] );
if(!empty($array)) {
//数据库中已经存在的标签
$old_tag_array = Db::name('book_tags')->where('book_id', $project_id)->column('tag_name','id');
if(empty($old_tag_array)) {
$new_tag_array = [];
foreach($array as $key=>$value){
$new_tag_array[$key]['book_id'] = $project_id;
$new_tag_array[$key]['tag_name'] = $value;
$new_tag_array[$key]['createtime'] = time();
}
Db::name('book_tags')->insertAll($new_tag_array);
} else {
$new_tags = [];
//需要删除的标签数组 带id
$delete = array_diff($old_tag_array, $array);
$old_tag_array_key = array_keys($old_tag_array);
Db::name('book_tags')->delete($old_tag_array_key);
//需要新增的标签数组
$add = array_diff($array, $old_tag_array);
foreach($add as $key=>$value){
$new_tags[$key]['book_id'] = $project_id;
$new_tags[$key]['tag_name'] = $value;
$new_tags[$key]['createtime'] = time();
}
Db::name('book_tags')->insertAll($new_tags);
}
}
—————————————————————————————————-
前端代码
这里实现的效果如下:
使用Backspace键可使标签为红色的选中状态,再次按Backspace键可实现删除标签
当鼠标悬浮某一标签的时候,出现”x”,点击可以实现删除标签
相关代码如下:
<script type="text/javascript">
$(function(){
var backSpace = 0;
var close = '<a class="close"></a>';
var PreTags = $('.tagarea').val().trim().split(",");
$('.tagarea').after('<ul class="tag-box"></ul>');
for (i=0 ; i < PreTags.length; i++ ){
$('.tag-box').append('<li class="tags">'+PreTags[i]+close+'</li>');
}
$('.tag-box').append('<li class="new-tag"><input class="input-tag" type="text" style="padding-left:1px;border:0px;"></li>');
$('.input-tag').bind("keydown", function (kp) {
var PreTagsString = $('.tagarea').val().trim();
var tag = $('.input-tag').val().trim();
var tags_array = $('.tagarea').val().trim().split(",");
$(".tags").removeClass("danger");
if(tag.length > 0){
backSpace = 0;
if(kp.keyCode == 13){
if(tags_array.indexOf(tag) > -1){
$('.input-tag').val("").focus();
return false;
}
$(".new-tag").before('<li class="tags">'+tag+close+'</li>');
$(this).val('');
if(PreTagsString == "") {
$('.tagarea').val(PreTagsString + tag);
} else {
$('.tagarea').val(PreTagsString+ ',' +tag);
}
return false;
}
} else {
if(kp.keyCode == 8 ){
$(".new-tag").prev().addClass("danger");
backSpace++;
if(backSpace == 2){
tags_array.pop();
var tags_string = tags_array.join(',');
$('.tagarea').val(tags_string);
$(".new-tag").prev().remove();
backSpace = 0;
}
}
}
});
$(".tag-box").on("click", ".close", function() {
$(this).parent().remove();
var tags_array = $('.tagarea').val().trim().split(",");
var delete_element = $(this).parent().text();
tags_array.splice(tags_array.indexOf(delete_element), 1);
var tags_string = tags_array.join(',');
$('.tagarea').val(tags_string);
});
$(".tag-box").click(function(){
$('.input-tag').focus();
});
})
</script>
Comments