在没有 InfoPath 的情况下向 SharePoint 表单添加重复控件的解决方法
Workaround to add repetitive controls to a SharePoint form without InfoPath
我正在尝试创建一个重复的 SharePoint 表单controls.I我是 SharePoint Online 用户 (Office 365)。
我正在寻找一种解决方法来执行此操作,而无需使用 InfoPath 或任何第三方软件(如 Nintex)。
JavaScript 解决方案是理想的。
非常感谢任何建议。
既然您知道如何将 JavaScript 插入表单,您就可以将重复数据存储在多行文本字段中。
在多行文本字段中以结构化格式存储数据,例如 JSON,然后使用 JavaScript 读取该字段的值并呈现适当的重复控件(标签、文本输入,下拉菜单)在屏幕上。
查看下面我丑陋但实用的示例(用您要在其中存储重复数据的多行文本字段的显示名称替换单词 "Multiline Text Column"):
(function(){
// define the data you want captured in the repeating field
var fields = [{type:"text",label:"Employee Name"},
{type:"text",label:"ID Number"},
{type:"choice",label:"Status",choices:["Full Time","Part Time","Intern","Consultant"]}
];
// find and hide the text area
var textarea = document.querySelector("[title=\"Multiline Text Column\"]");
// textarea.style.display = "none"; // uncomment this line to hide the text area
// create a new container for your repeating field
var repeatingData = [];
var container = document.createElement("div");
textarea.parentNode.appendChild(container);
// add a button for adding new rows
var addButton = document.createElement("input");
addButton.setAttribute("type","button");
addButton.value = "Add row";
addButton.addEventListener("click",function(){addRow();});
textarea.parentNode.appendChild(addButton);
// get the existing data, if any
var existing = JSON.parse(textarea.value);
for(var i = 0; i < existing.length; i++){
addRow(existing[i]);
}
function addRow(data){
if(typeof data === "undefined"){
data = {};
}
repeatingData.push(data);
var last = repeatingData.length-1;
var index = last;
if(last > 0){index = repeatingData[index-1]["data-id"] + 1;}
repeatingData[last]["data-id"] = index;
var row = document.createElement("div");
row.setAttribute("data-id",index);
row.style.border = "1px solid black";
row.style.margin = "2px"; row.style.padding = "2px";
for(var i = 0; i < fields.length; i++){
var field = fields[i];
var lbl = document.createElement("span");
lbl.insertAdjacentHTML("beforeend",field.label+": ");
row.appendChild(lbl);
switch(field.type){
case "text":
var txt = document.createElement("input");
txt.setAttribute("type","text");
if(data[field.label]){
txt.value = data[field.label];
}
(function(label){
txt.addEventListener("keyup",function(){
getRecord(index)[label]=this.value;
updateTextArea();});
})(field.label);
row.appendChild(txt);
break;
case "choice":
var sel = document.createElement("select");
var option = sel.appendChild(document.createElement("option"));
option.value = "";
option.innerHTML = "";
for(var j = 0; j < field.choices.length; j++){
option = document.createElement("option");
option.value = field.choices[j];
option.appendChild(document.createTextNode(field.choices[j]));
sel.appendChild(option);
}
if(data[field.label]){
sel.value = data[field.label];
}
(function(label){
sel.addEventListener("change",function(){
getRecord(index)[label]=this.value;
updateTextArea();});
})(field.label);
row.appendChild(sel);
break;
}
row.appendChild(document.createElement("br"));
}
var remove = document.createElement("a");
remove.href = "return false;";
row.appendChild(remove);
remove.innerHTML = "remove";
remove.addEventListener("click",function(event){
event.preventDefault();
repeatingData.splice(getRecordIndex(index),1);
container.removeChild(row);
updateTextArea();
return false;});
container.appendChild(row);
updateTextArea();
}
function getRecord(i){
return repeatingData[getRecordIndex(i)];
}
function getRecordIndex(i){
for(var j = 0; j < repeatingData.length; j++){
if(repeatingData[j]["data-id"] == i){
return j;
}
}
return -1;
}
function updateTextArea(){
textarea.value = JSON.stringify(repeatingData);
}
})();
.ms-formtable{
font-family:"Segoe UI","Segoe",Tahoma,Helvetica,Arial,sans-serif;
font-size:13px;
font-weight:400;
}
.ms-formlabel{
padding-right:5px;
}
.ms-long{ border:1px solid rgb(186,186,186); padding-left:5px; padding-right:5px; padding-bottom:2px; padding-top:2px;
<table class="ms-formtable">
<tr>
<td width="113" class="ms-formlabel" valign="top">
<span class="ms-h3 ms-standardheader"><nobr>Multiline Text Column</nobr></span>
</td>
<td width="350" class="ms-formbody" valign="top">
<span dir="none"><textarea class="ms-long" title="Multiline Text Column" cols="20">[{"Employee Name":"Joe Blow","ID Number":"123","Status":"Full Time"},{"Employee Name":"Jane Doe","ID Number":"321","Status":"Consultant"}]</textarea></span>
</td>
</tr>
</table>
请注意,只要行控件中的值发生变化,textarea 中的基础值就会发生变化。保存表单时,textarea 中的值将保存到 SharePoint。
请注意,您需要稍微不同(更简单)的代码才能使其适用于显示表单和编辑表单。
我正在尝试创建一个重复的 SharePoint 表单controls.I我是 SharePoint Online 用户 (Office 365)。
我正在寻找一种解决方法来执行此操作,而无需使用 InfoPath 或任何第三方软件(如 Nintex)。 JavaScript 解决方案是理想的。
非常感谢任何建议。
既然您知道如何将 JavaScript 插入表单,您就可以将重复数据存储在多行文本字段中。
在多行文本字段中以结构化格式存储数据,例如 JSON,然后使用 JavaScript 读取该字段的值并呈现适当的重复控件(标签、文本输入,下拉菜单)在屏幕上。
查看下面我丑陋但实用的示例(用您要在其中存储重复数据的多行文本字段的显示名称替换单词 "Multiline Text Column"):
(function(){
// define the data you want captured in the repeating field
var fields = [{type:"text",label:"Employee Name"},
{type:"text",label:"ID Number"},
{type:"choice",label:"Status",choices:["Full Time","Part Time","Intern","Consultant"]}
];
// find and hide the text area
var textarea = document.querySelector("[title=\"Multiline Text Column\"]");
// textarea.style.display = "none"; // uncomment this line to hide the text area
// create a new container for your repeating field
var repeatingData = [];
var container = document.createElement("div");
textarea.parentNode.appendChild(container);
// add a button for adding new rows
var addButton = document.createElement("input");
addButton.setAttribute("type","button");
addButton.value = "Add row";
addButton.addEventListener("click",function(){addRow();});
textarea.parentNode.appendChild(addButton);
// get the existing data, if any
var existing = JSON.parse(textarea.value);
for(var i = 0; i < existing.length; i++){
addRow(existing[i]);
}
function addRow(data){
if(typeof data === "undefined"){
data = {};
}
repeatingData.push(data);
var last = repeatingData.length-1;
var index = last;
if(last > 0){index = repeatingData[index-1]["data-id"] + 1;}
repeatingData[last]["data-id"] = index;
var row = document.createElement("div");
row.setAttribute("data-id",index);
row.style.border = "1px solid black";
row.style.margin = "2px"; row.style.padding = "2px";
for(var i = 0; i < fields.length; i++){
var field = fields[i];
var lbl = document.createElement("span");
lbl.insertAdjacentHTML("beforeend",field.label+": ");
row.appendChild(lbl);
switch(field.type){
case "text":
var txt = document.createElement("input");
txt.setAttribute("type","text");
if(data[field.label]){
txt.value = data[field.label];
}
(function(label){
txt.addEventListener("keyup",function(){
getRecord(index)[label]=this.value;
updateTextArea();});
})(field.label);
row.appendChild(txt);
break;
case "choice":
var sel = document.createElement("select");
var option = sel.appendChild(document.createElement("option"));
option.value = "";
option.innerHTML = "";
for(var j = 0; j < field.choices.length; j++){
option = document.createElement("option");
option.value = field.choices[j];
option.appendChild(document.createTextNode(field.choices[j]));
sel.appendChild(option);
}
if(data[field.label]){
sel.value = data[field.label];
}
(function(label){
sel.addEventListener("change",function(){
getRecord(index)[label]=this.value;
updateTextArea();});
})(field.label);
row.appendChild(sel);
break;
}
row.appendChild(document.createElement("br"));
}
var remove = document.createElement("a");
remove.href = "return false;";
row.appendChild(remove);
remove.innerHTML = "remove";
remove.addEventListener("click",function(event){
event.preventDefault();
repeatingData.splice(getRecordIndex(index),1);
container.removeChild(row);
updateTextArea();
return false;});
container.appendChild(row);
updateTextArea();
}
function getRecord(i){
return repeatingData[getRecordIndex(i)];
}
function getRecordIndex(i){
for(var j = 0; j < repeatingData.length; j++){
if(repeatingData[j]["data-id"] == i){
return j;
}
}
return -1;
}
function updateTextArea(){
textarea.value = JSON.stringify(repeatingData);
}
})();
.ms-formtable{
font-family:"Segoe UI","Segoe",Tahoma,Helvetica,Arial,sans-serif;
font-size:13px;
font-weight:400;
}
.ms-formlabel{
padding-right:5px;
}
.ms-long{ border:1px solid rgb(186,186,186); padding-left:5px; padding-right:5px; padding-bottom:2px; padding-top:2px;
<table class="ms-formtable">
<tr>
<td width="113" class="ms-formlabel" valign="top">
<span class="ms-h3 ms-standardheader"><nobr>Multiline Text Column</nobr></span>
</td>
<td width="350" class="ms-formbody" valign="top">
<span dir="none"><textarea class="ms-long" title="Multiline Text Column" cols="20">[{"Employee Name":"Joe Blow","ID Number":"123","Status":"Full Time"},{"Employee Name":"Jane Doe","ID Number":"321","Status":"Consultant"}]</textarea></span>
</td>
</tr>
</table>
请注意,只要行控件中的值发生变化,textarea 中的基础值就会发生变化。保存表单时,textarea 中的值将保存到 SharePoint。
请注意,您需要稍微不同(更简单)的代码才能使其适用于显示表单和编辑表单。