继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

SharePoint 中时间轴 Timeline的实现

关注TA
已关注
手记
粉丝
获赞

阅读目录

  • 成果演示

  • 实现原理

  • 总结

客户需要在OA中实现每日动态功能,能够记录每一位员工的每天的工作动态,我很快想到了时间轴,因为时间轴能很直观的现实员工每一刻的动态。就像Facebook的Timeline效果(点击查看)。

尝试着搜索这个效果,园友的这篇博文正好给我启发,接下来就去实现吧。

回到顶部

成果演示

最终的效果如下所示:

点击每个员工的姓名,即可进入他当天的工作动态(只能看),若点击自己的名字(既能看又能发送/编辑/删除动态),如下所示:

动态的详细页,如下所示:

点击时间轴,即可新增动态,如下所示:

编辑效果,鼠标移至内容区域,现实黄色提醒,如下所示:

单击即可显示编辑界面,如下所示:

移开鼠标,即可自动保存。

当然如果想把一条当太删掉,点击右上角X即可。

 

回到顶部

实现原理

关于效果的实现原理可以参考这篇文章。

了解了上面提到的这篇文章之后(Masonry.js),接下来就是Sharepoint 客户端对象模型的实现了,比如Ecmascript。 

  • 根据登陆的用户点击的员工名字获取当天的动态,这儿需要利用CAML拼接出查询条件

复制代码

function GetCurrentUser(){    //Get the current context    var context=new SP.ClientContext.get_current();    //Load the web object    var web=context.get_web();    //Get current user     this.currentUser=web.get_currentUser();    //load currentUser    context.load(currentUser);    //Make a query call to execute the above statements    context.executeQueryAsync(OnGetCurrentUserSuccess,OnGetCurrentUserFailed);}function OnGetCurrentUserSuccess(){    GetDailyWorks();}function OnGetCurrentUserFailed(sender,args){    console.log('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());}function GetDailyWorks(){    //Get the current context    var context=new SP.ClientContext.get_current();    //Load the web object    var web=context.get_web();    //Get the list    var list=web.get_lists().getByTitle(listNameForDailyWork);        //Get items by caml in the specific list    var camlQuery=new SP.CamlQuery();    var d=new Date();    //Get specific field name     this.userNameWhenClickView=$("#currentUserHidden").val();    camlQuery.set_viewXml('<View><Query>'+                                         '<Where>'+                                             '<And>'+                                               '<And>'+                                                 '<And>'+                                                         '<Eq>'+                                                                 '<FieldRef Name=\'Title\'/>'+                                                                 '<Value Type=\'Text\'>'+userNameWhenClickView+'</Value>'+                                                         '</Eq>'+                                                         '<Eq>'+                                                                 '<FieldRef Name=\'CurrentYear\'/>'+                                                                 '<Value Type=\'Text\'>'+d.getFullYear()+'</Value>'+                                                         '</Eq>'+                                                 '</And>'+                                                 '<Eq>'+                                                     '<FieldRef Name=\'CurrentMonth\'/>'+                                                     '<Value Type=\'Text\'>'+(d.getMonth()+1)+'</Value>'+                                                 '</Eq>'+                                               '</And>'+                                               '<Eq>'+                                                     '<FieldRef Name=\'CurrentDay\'/>'+                                                     '<Value Type=\'Text\'>'+d.getDate()+'</Value>'+                                               '</Eq>'+                                            '</And>'+                                         '</Where>'+                                         '<OrderBy>'+                                             '<FieldRef Name=\'Created\' Ascending=\'True\'/>'+                                         '</OrderBy></Query></View>');    dailyWorks=list.getItems(camlQuery);    //Load the web in the context and retrieve only selected columns to improve perfomance    context.load(dailyWorks,'Include(ID,Title,DailyContent,Created)');    //Make a query call to execute the above statements    context.executeQueryAsync(OnGetDailyWorksSuccess,OnGetDailyWorkFailed);            }function OnGetDailyWorksSuccess(){    //Get the collection    var dailyWorksCollection=dailyWorks.getEnumerator();    //Iterate through daily works    while(dailyWorksCollection.moveNext()){        //Load the current daily work item in iterate        var workItem=dailyWorksCollection.get_current();        //Add work item to container                addWorkToContainer(workItem.get_item('ID'),workItem.get_item('Title'),workItem.get_item('DailyContent'),workItem.get_item("Created"));    }    //Items has added in container and execute AutoMasonry method    AutoMasonry();    //Init in line edit if current user has permission to edit    if(userNameWhenClickView==currentUser.get_title()){        InitInlineEdit($('.editable, .editable-area'));    }    }//Error Handlerfunction OnGetDailyWorkFailed(sender,args){    console.log('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());}

复制代码

  • 当然Add一个Item也是比较方便的,当Add Item完毕后,很重要的一点是利用Masonry Reload一下所有的item

复制代码

function AddNewDailyWorkItem(content){    //get the current context    var context=new SP.ClientContext.get_current();    //Load the web object    var web=context.get_web();    //Get the list    var list =web.get_lists().getByTitle(listNameForDailyWork);    //create the ListItemInfomational object    var listItemInfo=new SP.ListItemCreationInformation();    //add the item to the list    this.listItem=list.addItem(listItemInfo);    //get current user display name    var userDisplayName=currentUser.get_title();    //Assign values for fields    listItem.set_item('Title',userDisplayName);    listItem.set_item('DailyContent',content);    //Get current year ,month,day and assign values for fields    var newObj=new Date();    listItem.set_item('CurrentYear',newObj.getFullYear());    listItem.set_item('CurrentMonth',newObj.getMonth()+1);    listItem.set_item('CurrentDay',newObj.getDate());    //Apply changes to item    listItem.update(listItem);    context.load(listItem);    //Make a query call to execute the above statements    context.executeQueryAsync(AddDailyWorkItemSuccess,AddDailyWorkItemFailed);    }function AddDailyWorkItemSuccess(sender,args){        var content = $("#update").val();            $('<div class="item"><a href="#" itemId="'+listItem.get_id()+'" class="deletebox">X</a>' + '<div class="inner"><p itemId="'+listItem.get_id()+'" class="editable-area">' + content + '</p></div><p class="sendStyle">发送于'+(new Date()).getHours()+':'+((new Date()).getMinutes()<10?"0"+(new Date()).getMinutes():(new Date()).getMinutes())+'</p></div>').insertBefore("div#popup");        //reload masnory        $("#container").masonry("reload");        //Hiding existing arrows        $(".rightCorner").hide();        $(".leftCorner").hide();        //injecting fresh arrows        Arrow_Points();        //clear popup text box value        $("#update").val("");        //popup hide        $("#popup").hide();        //Init in line edit        $('p[itemId='+listItem.get_id()+']');        InitInlineEdit($('p[itemId='+listItem.get_id()+']'));        }function AddDailyWorkItemFailed(sender,args){    console.log('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());}

复制代码

  • Update 和Add是相同的逻辑,记得最后Reload即可

复制代码

function UpdateDailyWorkItem(itemId,updateContent){    //If no title is setted then show alert and set focus    /*if(updateContent==''){        $()    }*/    //Get the current context    var context = new SP.ClientContext.get_current();    //Load the web object    var web=context.get_web();    //Get the list    var list=web.get_lists().getByTitle(listNameForDailyWork);    //Get item to update by Id from the specific list    this.listItem=list.getItemById(itemId);    //Set the new property value    listItem.set_item('DailyContent',updateContent);    //Call the update method to commit the change    listItem.update();        context.executeQueryAsync(updateWorkItemSuccess,updateWorkItemFailed);    }function updateWorkItemSuccess(){    $editable    .removeClass('active-inline')    .children()    .replaceWith(edited);    if ($editable.hasClass('editable-area')) {        rapture($editable);        }    //reload masnory    $("#container").masonry("reload");    //Hiding existing arrows    $(".rightCorner").hide();    $(".leftCorner").hide();    //injecting fresh arrows    Arrow_Points();}function updateWorkItemFailed(){}

复制代码

  • Delete Item,根据item id进行删除,同Add和Update逻辑,删除完毕后也是需要Reload

复制代码

//Delete daily work item by item idfunction deleteDailyWork(workElement){    //Get the daily work item id    var itemId=workElement.attr("itemId");    //Get the current context    var context=new SP.ClientContext.get_current();    //Load the web object    var web=context.get_web();    //Get the list    var list=web.get_lists().getByTitle(listNameForDailyWork);    //Get item to delete by if form the list    var itemToDelete=list.getItemById(itemId);    //Add Delete method to the query    itemToDelete.deleteObject();    //Execute the query to perform the deletion    context.executeQueryAsync(DeleteWorkItemSuccess,DeleteWorkItemFailed);            }function DeleteWorkItemSuccess(){     //Masonry Reload}function DeleteWorkItemFailed(sender,args){    console.log('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());}

复制代码回到顶部

总结

值得注意的是我将每日的动态存入List中,对于List,他能负担的item的个数和一次从数据库里获取的item都是有限制,对于数据量很大的情况下,是有风险的。

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP