在页面加载时,我尝试使用下面的JavaScript函数查看SharePoint列表,看看当前用户是否有任何请求,如果是,请允许他们批准或拒绝这些要求。
//Logic to approve events if the current user is a manager.
function promptToApproveEvents(){
var hostUrl = decodeURIComponent(getQueryStringParameter("SPHostUrl"));
var hostContext = new SP.AppContextSite(currentContext, hostUrl);
var hostweb = hostContext.get_web();
var list = hostweb.get_lists().getByTitle(paidTimeOffListName);
//A caml query to get records where manager is equal to current user.
var queryXml = "<View><Query><Where><Eq><FieldRef Name='Manager' /><Value Type='Integer'><UserID /></Value></Eq></Where></Query></View>"
var query = new SP.CamlQuery();
query.set_viewXml(queryXml);
var items = list.getItems(query);
currentContext.load(items);
currentContext.executeQueryAsync(
function() //on success.
{
for(var i = 0;i < items.get_count();i++) {
var item = items.getItemAtIndex(i);
//Is the item we're looking at in need of approval?
if (item.get_item("Approved") === false)
{
//Yes, prompt for approval.
//$('#approvalModal').modal('show'); //modals don't seem to work in loops.
confirm("here's something in need of approval.");
}
else
{
//No, do nothing.
alert("skip it, it doesn't need approved.");
}
}
},
function(sender,args){
alert("Failed to get manager's name. Make sure your Organization Contacts list is filled out! Error: " + args.get_message()); //On fail
});
}
我的问题是,我认为我能够使用引导模式提示用户输入每个未批准的请求。例如,向他们提供有关请求的一些信息,然后他们可以决定单击接受或拒绝按钮以使用类似下面的模型的提示传递判断。一旦他们做出了关于此请求的决定,我将运行一些代码来记录他们对此请求的决定,然后他们应该被提示有关下一个请求,直到for循环退出。
_________________________________________________________
| Hey boss. What to you think of this request? |
| Name: xx |
| Reason: xx |
| Other info: xx |
| |
| [ACCEPT] [REJECT] |
|_______________________________________________________|
不幸的是,只有一个引导模式弹出,并且在for循环结束后显示 - 它不适合所找到的每个匹配项目的提示的所需行为。
我基本上不确定实现这一目标的最佳方法是什么。这似乎是警报和确认框&#34;暂停&#34;像我想要的那样执行,并按照需要行事。 (例如,如果我有2个未经批准的请求和1个已批准,则上面的代码弹出两个&#34;确认&#34;框和#34;警告,&#34;正如预期的那样。)但他们的造型赢了&#39完全适合我的应用程序的其余部分,他们也有一个&#34; X&#34;我不希望在我的提示中出现的按钮(他们应该被迫明确点击接受或拒绝。)
关于我应该采取什么方法的任何建议?
答案 0 :(得分:1)
由于对引导程序的模态调用是异步的,因此您需要对异步调用的流程进行一些控制。这可以通过手动完成,但通常是一个巨大的麻烦(至少对我而言)。
有一些库(如q,异步等)。但我建议https://github.com/caolan/async,因为它是比较容易理解和开始使用的人之一。
对于您的情况,您可能会使用https://github.com/caolan/async#eachseriesarr-iterator-callback
取代for循环,请使用以下代码段:
async.eachSeries(items, function( item, callback) {
//Is the item we're looking at in need of approval?
if (item.get_item("Approved") === false)
{
//Yes, prompt for approval.
//$('#approvalModal').modal('show'); //modals don't seem to work in loops.
confirm("here's something in need of approval.", callback);
}
else
{
//No, do nothing.
alert("skip it, it doesn't need approved.");
}
});
此外,您需要让confirm
函数在模式关闭后调用callback
函数,因此async
将为您打开下一个模式(&#39} ;为什么我将回调添加到confirm
来电。)
答案 1 :(得分:0)
我最终使用递归函数而不是for循环。
重要的是,当从模态接收到回复时(在此实例中为Bootbox对话框),运行回调函数,再次调用递归函数,索引由一。通过这种方式,递归函数继续运行,直到它遍历列表中的所有项,每次都等待响应,并且表现得像异步for循环。
这是它的样子,以防它有类似问题的人。这里有一些额外的东西供我提示,但我决定将所有内容留给上下文。
//Recursive function that behaves like a for loop, stepping through all items and finding ones needing approval.
function recursiveCheckRequests(i) {
var item = items.getItemAtIndex(i);
//Is the item we're looking at in need of approval?
if (item.get_item("_ModerationStatus") === 2) {
//Yes, prompt for approval. (code for prompt goes here.)
//Fetch info about the request to be displayed in the dialog box.
var title = item.get_item('Title');
var location = item.get_item('Location');
var description = item.get_item('Description');
var requester = item.get_item('Requester').get_lookupValue();
var start = item.get_item('EventDate').toString("h:mm tt, dddd, MMMM d, yyyy"); //formatting the datetime
var end = item.get_item('EndDate').toString("h:mm tt, dddd, MMMM d, yyyy"); //formatting the datetime
//Generate a nicely formatted message using this crazy-looking string of HTML
var html="<p>We've found a pending request from a person you manage.</p>"
html +="<p>Would you like to approve this request? </p>"
html +="<br/>"
html +="<div class=\"form-horizontal\"><!-- Start of form !-->"
html +=" <div class=\"form-group\">"
html +=" <label class=\"col-sm-4 control-label\">Requester</label>"
html +=" <div class=\"col-sm-7\">"
html +=" <p style=\"text-align:left\" class=\"form-control-static\">" + requester + "</p>"
html +=" </div>"
html +=" </div>"
html +=" <div class=\"form-group\">"
html +=" <label class=\"col-sm-4 control-label\">Title</label>"
html +=" <div class=\"col-sm-7\">"
html +=" <p type=\"text-align:left\" class=\"form-control-static\">" + title + "</p>"
html +=" </div>"
html +=" </div>"
html +=" <div class=\"form-group\">"
html +=" <label class=\"col-sm-4 control-label\">Location</label>"
html +=" <div class=\"col-sm-7\">"
html +=" <p type=\"text-align:left\" class=\"form-control-static\">" + location + "</p>"
html +=" </div>"
html +=" </div>"
html +=" <div class=\"form-group\">"
html +=" <label class=\"col-sm-4 control-label\">Start</label>"
html +=" <div class=\"col-sm-7\">"
html +=" <p type=\"text-align:left\" class=\"form-control-static\">" + start + "</p>"
html +=" </div>"
html +=" </div>"
html +=" <div class=\"form-group\">"
html +=" <label class=\"col-sm-4 control-label\">End</label>"
html +=" <div class=\"col-sm-7\">"
html +=" <p type=\"text-align:left\" class=\"form-control-static\">" + end + "</p>"
html +=" </div>"
html +=" </div>"
html +=" <div class=\"form-group\">"
html +=" <label class=\"col-sm-4 control-label\">Description</label>"
html +=" <div class=\"col-sm-7\">"
html +=" <p type=\"text-align:left\" class=\"form-control-static\">" + description + "</p>"
html +=" </div>"
html +=" </div>"
html +="</div> <!-- End of Form !-->"
bootbox.dialog({
message: html,
title: "A pending request needs your verdict!",
buttons: {
approve: {
label: "Approve",
className: "btn-success",
callback: function() {
//Set it to approved.
item.set_item("_ModerationStatus", 0);
item.update();
currentContext.load(item);
currentContext.executeQueryAsync(
function(){
bootbox.dialog({
title: "Request Approved.",
message: "This request has been approved.",
buttons: {
sucess:{
label: "Ok",
callback: callback
}
}
});
},
function(sender, args){
bootbox.dialog({
title: "Something went wrong!",
message: "We failed to approve the request! Here's what we know about the problem: " + args.get_message() + '\n' + args.get_stackTrace(),
buttons: {
sucess:{
label: "Ok",
callback: callback
}
}
});
});
function callback(){
//Go on to next in list when we've received a reponse.
if (i + 1 < items.get_count()) {
recursiveCheckRequests(i + 1);
}
}
}
},
reject: {
label: "Reject",
className: "btn-danger",
callback: function() {
//Set it to rejected.
item.set_item("_ModerationStatus", 1);
item.update();
currentContext.load(item);
currentContext.executeQueryAsync(
function(){
bootbox.dialog({
title: "Request Rejected.",
message: "This request has been rejected.",
buttons: {
sucess:{
label: "Ok",
callback: callback
}
}
});
},
function(sender, args){
bootbox.dialog({
title: "Something went wrong!",
message: "We failed to reject the request! Here's what we know about the problem: " + args.get_message() + '\n' + args.get_stackTrace(),
buttons: {
sucess:{
label: "Ok",
callback: callback
}
}
});
});
function callback(){
//Go on to next in list when we've received a reponse.
if (i + 1 < items.get_count()) {
recursiveCheckRequests(i + 1);
}
}
}
},
Main: {
label: "Skip",
className: "btn-default",
callback: function() {
//Leave it as pending, which is equivalent to the line below
//item.set_item("_ModerationStatus", 2);
//Go on to next in list since we don't require a reponse.
if (i + 1 < items.get_count()) {
recursiveCheckRequests(i + 1);
}
}
}
}
});
}
else
{
//bootbox.alert("This request isn't pending.");
//Go on to next in list since this one doesn't need a response.
if (i + 1 < items.get_count()) {
recursiveCheckRequests(i + 1);
}
}
}
//Start the recursive function seen above.
recursiveCheckRequests(0);