您的位置:首页 > 其它

SharePoint里如何解决超长LookUp字段需要双击的问题

2011-06-12 16:36 369 查看
摘要:

如果LookUp字段里引用的列表数据超过20条的时候,Lookup字段将不通过Select标记进行输出,而是通过Textbox进行输出,微软希望提供的Textbox可以为用户提供输入过滤的功能,但是相应带来的问题却是用户需要通过双击而不是单击来选择Lookup下拉列表的内容,用户体验上并不友好。本文将通过Javascript的方式提供用户单击选择超长列表的方案。还有两种思路,一种是写一个自己的Lookup字段,注意Lookup字段不能被继承;另一种思路是通过控件的Adapter来改变输出时的行为。

问题介绍:

如下图所示,我们可以看到第一个Test1字段引用的列表只有19条数据,但是Test2引用的列表却又近百条数据,显而易见的是两个下拉列表的样式并不一样,而且选择Test2下拉列表内容的时候我们会发现需要点击两次相应两目才能选中。





解决思路:

我们查看HTML代码回发现针对Test1字段输出内容如下,采用的是HTML Select元素:





但针对Test2字段输出内容如下,采用的是类型为Text的Input元素:





进一步的我们查看Test2字段的HTML代码,我们会发现有几点内容值得关注:

optHid属性:此属性指定了存储选中项目ID的隐藏控件;

choices属性:此属性包含了需要显示的文本以及背后ID的所有信息;

match属性:此属性包含被选中的内容的信息;

当点击下拉列表的小箭头时实际调用了一个叫做showdropdown的方法,此方法来源于core.js文件,进一步的查看showdropdown方法的代码我们会发现这个方法调用EnsureSelectElement来在当前文本框后面添加一个Select元素来实现的,紧接着通过FilterChoice方法来为Select元素添加选项值,最后Select内容选择好以后调用SetCtrlFromOpt方法将文本内容设置到Text元素的Match属性,此外在FilterChoice还会将文本内容对应的Value值设置到Text元素的OptHid属性指定的隐藏控件里。最后再在Js中将值设置到Text元素文本框中。

因而我们的思路是在画面加载结束后通过Javascript脚本生成一个Select元素,并通过choices里的内容将其初始化,然后设置其onchange事件,确保新的内容被选择后相应的值会设置到原始的文本框里,这样保存的时候就能够存到SharePoint里去,最后我们通过属性设置隐藏掉原始的文本框。

解决步骤:

第一步,引入JQuery库(可至Jquey.com网站下载),通过SharePoint Designer上传到相关列表的文件夹内,再通过SharePoint Designer打开newform.aspx页面,在PlaceHolderMain里面加入对该库的引用,例如:

<script type="text/javascript" src="jquery-1.6.1.min.js" > </script>

第二步,添加代码如下:

<script type="text/javascript">
$(document).ready(function() {
var ctrl1 = $("input[title='Test2']")
var ctrl = document.getElementById(ctrl1.attr('id'));
ctrl.style.display="none";
var select=document.createElement("SELECT");
ctrl.parentNode.appendChild(select);
select.outerHTML="<select id='“+ ctrl.opt + “' ctrl='"+ctrl.id+"' class='ms-lookuptypeindropdown' name='” + ctrl.opt + “'></select>";
var opt = document.getElementById(ctrl.opt);
FillChoice(opt, ctrl, "");
});


首先我们通过JQuery的选择器获得了对原始的Test2字段的引用,紧接着我们通过此ID获得了对文本框控件本身的引用(有兴趣的朋友可以直修改剩余的代码完全通过Jquery来操作,本人为了图省事,大多数代码沿用SharePoint core.js里的内容),然后隐藏了该文本框控件,接着创建了一个Select元素,然后调用自定义的FillChoice方法对Select元素进行了初始化,该方法的算法借鉴了core.js的ilterChoice方法。

function FillChoice(opt, ctrl, strVal)
{
var i;    var strName=opt.name;
var strHtml="";
var strId=opt.id;
var strOpts=ctrl.choices;
var rgopt=strOpts.split("|");
var x=AbsLeft(ctrl);
var y=AbsTop(ctrl)+ctrl.offsetHeight;
var iMac=rgopt.length - 1;
for (i=0; i < rgopt.length; i=i+2)
{
var strOpt=rgopt[i];
while (i < iMac - 1 && rgopt[i+1].length==0)
{
strOpt=strOpt+"|";
i++;
if (i < iMac - 1)
{
strOpt=strOpt+rgopt[i+1];
}
i++;
}
var strValue=rgopt[i+1];
var strLowerOpt=strOpt.toLocaleLowerCase();
var strLowerVal=strVal.toLocaleLowerCase();
if (strLowerOpt.indexOf(strLowerVal)==0)
{
strHtml+="<option value=\""+strValue+"\">"+STSHtmlEncode(strOpt)+"</option>";        }
}
var strHandler=" onchange=HandleClick()";
var strOptHtml="";
strOptHtml="<select tabIndex='-1' ctrl='"+ctrl.id+"' name='"+strName+"' id='"+strId+"'"+strHandler;
strOptHtml+=" style='position:absolute;z-index:2;left:"+x+"px;top:"+y+"px'>"+strHtml+"</select>";

opt.outerHTML=strOptHtml;
}

function HandleClick()
{
var opt = event.srcElement;
var ctrl = document.getElementById(opt.ctrl);
SetCtrlFromOpt(ctrl, opt);
}


FillChoice方法通过提取原始文本框控件的choices属性值初始化了自定义的Select列表选项,注意onchange事件指定为HandleClick处理器。HandleClick事件调用core.js的SetCtrlFromOpt方法进行值得设置。

效果查看:

保存后我们可以发现第二个字段的样式已经与正常小于20条时的样式一致且可以正常保存列表。





说明:

该解决方案没有针对Firefox进行测试。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐