Asp.Net MVC2 控件开发实例(2)

想开发一个控件,功能比较简单,实现这样一个多选功能:一个文本框,点击时弹出层,左侧展示绑定数据表的数据,右侧为选择后的结果,有左选和右选,取消、清除功能,如下图:

 

 以HtmlHelper的形式调用:

         <%=Html.MultiSelectFor(m => m.CodeMC, m => m.CodeDM, "dm_jwrylbb","dm<80",",",500,"标题"new { @style = "width:400px" })%>

选择后点击确定,选择项会用分隔符拼接存入文本框,关键信息(如显示项的ID)会存入隐藏域 

其中参数按顺序为:文本框ID,隐藏域ID,数据表名称,绑定的数据表过滤条件,分隔符,弹出层高度,标题,htmlAttributes。 

思路:在htmlhelper中构建文本框和隐藏域控件,文本框控件赋予onfocus事件,此事件post调用PartialViewResult:ShowView(...),此action绑定弹出层所需model,并返回控件view并填充到弹出层中。先来看helper:(篇幅关系不列出所有重载)

标准的htmlHelper:
 1 public static MvcHtmlString MultiSelectFor<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expressionMC, Expression<Func<TModel, TValue>> expressionDM,string tableName,string condition,string split,int height,string caption, object mcHtmlAttributes)
 2         {
 3             StringBuilder sb = new StringBuilder();
 4             string mcString = ExpressionHelper.GetExpressionText(expressionMC);
 5             string dmString = ExpressionHelper.GetExpressionText(expressionDM);
 6 
 7             TagBuilder tag = new TagBuilder("input");
 8             tag.Attributes.Add("type""text");
 9             tag.Attributes.Add("name", mcString);
10             tag.GenerateId(mcString);
11 
12             object mcValue = ModelMetadata.FromLambdaExpression(expressionMC, helper.ViewData).Model;
13             string mcValueParameter = Convert.ToString(mcValue, System.Globalization.CultureInfo.CurrentCulture);
14             tag.MergeAttribute("value", mcValueParameter);
15 
16             TagBuilder tagHidden = new TagBuilder("input");
17             tagHidden.Attributes.Add("type""hidden");
18             tagHidden.Attributes.Add("name", dmString);
19             tagHidden.GenerateId(dmString);
20 
21             object dmValue = ModelMetadata.FromLambdaExpression(expressionDM, helper.ViewData).Model;
22             string dmValueParameter = Convert.ToString(dmValue, System.Globalization.CultureInfo.CurrentCulture);
23             tagHidden.MergeAttribute("value", dmValueParameter);
24             RouteValueDictionary dictionary = new RouteValueDictionary();
25 
26             if (mcHtmlAttributes != null)
27                 tag.MergeAttributes(new RouteValueDictionary(mcHtmlAttributes));
28             if (!mcHtmlAttributes.ToString().Contains("readonly"))
29             {
30                 dictionary.Add("onfocus", GetClickEventString(mcString, dmString, tableName, condition, split, height, caption));
31             }
32             tag.MergeAttributes(dictionary);
33             sb.Append(tag.ToString(TagRenderMode.SelfClosing));
34             sb.Append(tagHidden.ToString(TagRenderMode.SelfClosing));
35             sb.Append(GetScript(mcString, dmString,height));
36             return MvcHtmlString.Create(sb.ToString());}
 

 

文本框点击事件:(这段折叠显示不出来)

private static string GetClickEventString(string mcName, string dmName, string tableName, string condition, string split,int height,string caption)
        {
            StringBuilder sbClick = new StringBuilder();
            //sbClick.Append("setMSFloat();");
            sbClick.Append("var selectorMC='#'+'" + mcName + "';if($(selectorMC).attr('readonly')==true){return;}");
            sbClick.Append("$.post('/FM/MultiSelect/ShowView',{");
            sbClick.Append("mc:\"" + mcName + "\",dm:\"" + dmName
                + "\",table:\"" + tableName + "\",condition:\"" + condition + "\",sign:\""
                + split + "\",height:\"" + height + "\",mcContent:$('#" + mcName + "').val(),dmContent:$('#" + dmName + "').val()");
            sbClick.Append("},function(data){");
            sbClick.Append("$('#divMS').html(data);}");
            sbClick.Append(");");
            sbClick.Append("$('#divMS').dialog('open');");
            sbClick.Append("$('#divMS').dialog({ title: '" + (string.IsNullOrEmpty(caption) ? "多选" : caption) + "' });");
            return sbClick.ToString();

        } 

 

 其他需要加载的脚本(主要为弹出层初始化代码,弹出层使用了jquery.ui.dialog,具体使用可查官方文档:http://docs.jquery.com/UI/Dialog)

View Code
private static string GetScript(string modelMCName, string modelDMName,int height)
        {
            StringBuilder script 
= new StringBuilder();
            script.Append(
"<script type='text/javascript'>");
            script.Append(
"$(function () {");

            
//script.Append("function setMSFloat(){");
            script.Append("$('<form id=formMS name=formMS><div id=divMS></div></form>').appendTo('body');");
            script.AppendFormat(
"initDialog('#formMS', '多选', '#divMS', {0}, 480);var s=document.getElementsByName('formMS')[1];$(s).remove();", height);
            
//script.Append("};");
            script.Append("});");

            script.Append(
"</script>");
            
return script.ToString();
        }

    } 

 之后是post调用的action:

View Code
#region MultiSelectController
    
public class MultiSelectController : Controller
    {
        [HttpPost()]
        
public PartialViewResult ShowView(string mc, string dm, string table, string condition, string sign, int height, string mcContent,string dmContent)
        {
            
string sql = string.Format("select * from {0} where 0=0 {1}", table, string.IsNullOrEmpty(condition) ? string.Empty : "and " + condition);
            System.Data.DataTable dt 
= ForeignerManagement.Operation.Common.Operation_Common.FillDataTable(sql);

            List
<MSDisplay> msDisplay = new List<MSDisplay>();

            
string[] mcArr = mcContent.Split(sign.ToCharArray());
            
string[] dmArr = dmContent.Split(sign.ToCharArray());
            
if ((!string.IsNullOrEmpty(mcContent)) && (mcArr.Length == dmArr.Length))
            {
                
for (int i = 0; i < mcArr.Length; i++)
                {
                    msDisplay.Add(
new MSDisplay { MSMC = mcArr[i], MSDM = dmArr[i] });
                }
            }
          

            dynamic m 
= new System.Dynamic.ExpandoObject();
            m.CodeCollection 
= dt.Rows;
            m.MC 
= mc;
            m.DM 
= dm;
            m.Sign 
= sign;
            m.Height 
= height - 100;
            m.ImgHeight 
= height / 4;
            m.List 
= msDisplay;
            
            
return PartialView("~/Views/Shared/MultiSelect.ascx", m);
        }
    }

    #endregion 

 注:此处使用了动态类型dynamic m = new System.Dynamic.ExpandoObject();省得还得构建一个Model

 页面的html和css:

View Code
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<dynamic>" %>
<style type="text/css">
.selectDiv
{
    width
:200px; border:1px solid #000; height:<%= Model.Height %>px;overflow:auto;
}
.centerDiv
{
    height
:310px;width:40px;float:left;
}
.imgDiv
{
    margin-top
:<%= Model.ImgHeight %>px;
}
.imgDiv img
{
    vertical-align
:middle;cursor:pointer;
}
.leftUL li
{
    cursor
:pointer;
}
.rightUL li
{
    cursor
:pointer;
}

</style>
<div>
<div class="selectDiv" style="float:left; ">
    
<ul class="leftUL">
        
<% if (Model.CodeCollection != null)
           {
               
string hrefID = string.Empty;
               
string hrefIDSelector = string.Empty;               
               foreach (System.Data.DataRow dr in Model.CodeCollection 
as System.Data.DataRowCollection)
               {
                   hrefID 
= "l_" + dr["DM"].ToString();
                   hrefIDSelector 
= "#" + hrefID;
                   
%>
        
<li onclick="toggleColor('<%=hrefIDSelector%>');">
            
<id="<%=hrefID%>"  style="color:Black;"><%=dr["MC"].ToString()%></a>
            
<input type="hidden" value="<%=dr["DM"].ToString()%>" />
        
</li>
        
<% }
           } 
%>
    
</ul>
</div>
<div class="centerDiv">
    
<div class="imgDiv">
        
<img src="<%=Url.Content("~/Content/Images/rightS.png")%>" onclick="rSelect();" />
        
<br />
        
<img src="<%=Url.Content("~/Content/Images/leftS.png")%>" onclick="lSelect();" />
    
</div>
</div>
<div class="selectDiv" style="float:left;">
    
<ul class="rightUL">
    
<% if (Model.List.Count > 0)
       {
           
string hID = string.Empty;
           
string hSelector = string.Empty;  
           foreach (MSDisplay item in Model.List 
as List<MSDisplay>)
           {
               hID 
= "r_" + item.MSDM;
               hSelector 
= "#" + hID;
               
%>
        
<li onclick="toggleColor('<%=hSelector%>');">
            
<id="<%=hID%>" style="color:Black"><%=item.MSMC%></a>
            
<input type="hidden" value="<%=item.MSDM%>" />
        
</li>
        
<% }
       }
         
%>
    
</ul>
</div>
</div>

<div class="btnDiv" style="text-align:center; clear:both">
    
<input id="btnMSConfirm" type='button' value='确定' class="btnS" onclick="msConfirm();"  />
    
<input id="btnMSCancel" type='button' value='取消' class="btnS" onclick="msCancel();" />
    
<input id="btnMSClear" type='button' value='清除' class="btnS" onclick="msClear();" />
</div>
<%=Html.Hidden("hidMC",Model.MC as string%>
<%=Html.Hidden("hidDM",Model.DM as string%>  

<%=Html.Hidden("sign", Model.Sign as string)%>

至此页面已经可以出来了,下面是控件里面的功能事件脚本:

View Code
<script type="text/javascript">
    
//右选
    function rSelect() {
        
var a = '';
        
var b = '';
        
var selector = '';
        
var newA;
        
var newI;
        $(
'.leftUL li').each(function (i, n) {
            
if ($(this).children().first().css('color'== 'orange' || $(this).children().first().css('color'== 'rgb(255, 165, 0)') {
                
var arrV = new Array(1);
                arrV[
0= "0";
                $.each($(
'.rightUL input'), function (i, n) {
                    arrV.push($(
this).val());
                }
                );

                
if ($.inArray($(this).children().last().val(), arrV) == -1) {
                    selector 
= '#r_' + $(this).children().last().val();
                    newA 
= "<a id='r_" + $(this).children().last().val() + "' style='color:Black'>"
                    
+ $(this).children().first().html() + "</a>";
                    newI 
= "<input type='hidden' value='" + $(this).children().last().val() + "' />";
                    $(
'.rightUL').append("<li onclick=toggleColor('" + selector + "')>" + newA + newI + "</li>");
                }
            }
        }
        )
        $(
'.rightUL a').css('color''black');
    }

    
//左选
    function lSelect() {
        $(
'.rightUL li').each(function (i, n) {
            
if ($(this).children().first().css('color'== 'orange' || $(this).children().first().css('color'== 'rgb(255, 165, 0)') {
                $(
this).remove();
            }
        }
        )
    }

    
//点击颜色切换
    function toggleColor(e) {
        
if ($(e).css('color'== 'black' || $(e).css('color'== 'rgb(0, 0, 0)') {
            $(e).css(
'color''orange');
        }
        
else {
            $(e).css(
'color''black');
        }
    }

    
//确定
    function msConfirm() {
        $(
'#divMS').dialog('close');
        setValToMS();
        $(
'#divMS').empty();
    }

    
//赋值
    function setValToMS() {
        
var sign = $('#sign').val();
        
var mcSelector = '#' + $('#hidMC').val();
        
var dmSelector = '#' + $('#hidDM').val();
        
var mcVal = '';
        
var dmVal = '';

        $(
'.rightUL a').each(
        
function (i, n) {
            mcVal 
+= $(this).html();
            
if (i < $('.rightUL a').length - 1) {
                mcVal 
+= sign;
            }
        });
        $(
'.rightUL input[type=hidden]').each(
        
function (i, n) {
            dmVal 
+= $(this).val();
            
if (i < $('.rightUL input[type=hidden]').length - 1) {
                dmVal 
+= sign;
            }
        });
        $(mcSelector).val(mcVal);
        $(dmSelector).val(dmVal);

    }

    
//取消
    function msCancel() {
        $(
'#divMS').dialog('close');
        $('#divHid').empty();
    }

    
//清除
    function msClear() {
        $(
'.rightUL').empty();
    }

</script> 

 这里要注意下颜色切换这个方法,功能是鼠标点击一下会变成橘黄色,再点变回黑色

function toggleColor(e) {

        if ($(e).css('color'== 'black' || $(e).css('color'== 'rgb(0, 0, 0)') {
            $(e).css(
'color''orange');
        }
        
else {
            $(e).css(
'color''black');
        }
    }

在IE下 $(e).css('color')=='black'为true,而在chrome下为false,因为chrome下输出结果为

$(e).css('color'= 'rgb(0, 0, 0)' 

 

posted @ 2011-05-06 16:22  喵了个汪的2371  阅读(2113)  评论(6编辑  收藏  举报