雪山之巅的阳光

冰雪天地的清冷,超凡脱俗的时空,一缕色彩,点缀在清蓝的背景中....那就是——雪山之巅的阳光

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
题记:
    做BS架构的应用系统,最让人不满的操作方便性上始终无法和CS的应用媲美。希望不断的改进BS系统的易用性是大家共同的心愿。
    在BS系统上,业务数据的编辑方式,最常见的是逐条用表单编辑提交。用户常常说,为啥不象Excel一样可以批量操作?于是在DataGrid/GridView控件中使用模板列,每个格子里放一个文本框。让用户直接录入,批量提交。
    用户又说了,有些信息我几乎所有的人都差不多,一个个的填麻烦啊,能不能改进下?
我说:能!于是有了这篇博文,呵呵,供大家参考。

思路:
大家还记得IE浏览器中如何设置代理服务器的吧?呵呵。见下图


看,如果填写的内容差不多,可以只录入一次的,呵呵。因此我就设想了如下的使用场景:


大家,看——如果标题行的复选框没选中,那么,整列的内容都随着第一行的内容变化!不选中的列,则不受影响
除此之外,我还实现了以下功能:
特点:第一行的内容变化,其他行虽然变化,但用户依然可以对个别数据进行调整,可以大同小异,差异化操作。呵呵
特点:标题行的复选框选中后,然后如果再取消选择,其他文本框的内容可以复原。也就是记住开始的数值,撤消一致。
特点:可以不局限于文本框,各种控件都可以。自定义和用户控件可能要相应修改少量脚本。这里的示例使用了日期控件。
特点:IE6、IE7、Firefox下测试都通过。


我下面给出示例性代码,供大家参考。难度很小,大家一看就懂。大家照着思路和提示,相信很快可以完成自己批量操作功能。呵呵
javascript:脚本是关键啊
    <script type="text/javascript" language="javascript">
    TS_Util
=new Object();
    TS_Util.Arrs 
= new Array;
    TS_Util.AllSameCheck
=function(obj,no)
    
{
        
var theTable  = obj.parentNode.parentNode.parentNode; 
        
var j = obj.parentNode.cellIndex; 
        
        TS_Util.ArrayManage(no,theTable.rows.length);
        
        
for(var i=0;i<theTable.rows.length;i++
        
{
            
var objTextBox;
            
if (navigator.userAgent.indexOf('MSIE'> -1)
            
{
                objTextBox 
= theTable.rows[i].cells[j].childNodes[0];
                
if(i > 1 && no == 2)
                
{
                    theTable.rows[i].cells[j].childNodes[
2].disabled = obj.checked; 
                }

            }

            
else
            
{
                objTextBox 
= theTable.rows[i].cells[j].childNodes[1]; 
            }

            
if(obj.checked)   
            TS_Util.Arrs[no 
* theTable.rows.length + i] = objTextBox.value;
            
if(i > 1)
            
{
            
//    objTextBox.disabled = obj.checked; 
                if(obj.checked)
                    objTextBox.value 
= TS_Util.Arrs[no * theTable.rows.length + 1];
                
else
                    objTextBox.value 
= TS_Util.Arrs[no * theTable.rows.length + i];
            }

        }
 
    }

    TS_Util.ArrayManage
=function(no, MaxLength)
    
{
        
if(TS_Util.Arrs.length <= no * MaxLength)
        
{
            
var startpos = TS_Util.Arrs.length;
            
for(var i=startpos;i<(no+1* MaxLength;i++)
                TS_Util.Arrs.push(
'');
        }

    }

    TS_Util.AllSameValue
=function(obj)
    
{
        
var theTable  = obj.parentNode.parentNode.parentNode; 
        
var j = obj.parentNode.cellIndex; 
        
var objCheckBox = theTable.rows[0].cells[j].childNodes[1];
        
for(var i=2;i<theTable.rows.length;i++
        
{
            
var objTextBox;
            
if (navigator.userAgent.indexOf('MSIE'> -1)
                objTextBox 
= theTable.rows[i].cells[j].childNodes[0]; 
            
else
                objTextBox 
= theTable.rows[i].cells[j].childNodes[1]; 

            
if(objCheckBox.checked)
                objTextBox.value 
= obj.value;
        }
 
    }

    
</script> 

aspx页面的片段,datagrid中的一个模板列
                <asp:TemplateColumn HeaderText="DIC_NAME" SortExpression="DIC_NAME">
                    
<HeaderTemplate>
                        字典项(
<asp:CheckBox ID="CheckBox1" runat="server" Text="所有行相同"/>)
                    
</HeaderTemplate>
                    
<ItemTemplate>
                        
<asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("DIC_NAME") %>'></asp:TextBox>
                    
</ItemTemplate>
                
</asp:TemplateColumn>

注意 表头的控件:CheckBox1  编辑的文本框:TextBox1
C#代码把脚本和html上的服务器控件关联起来:
    protected void GridView1_RowDataBound(object sender, DataGridItemEventArgs e)
    
{
        
if (e.Item.ItemType == ListItemType.Header)
        
{
            CheckBox CheckBox1 
= (CheckBox)e.Item.FindControl("CheckBox1");
            CheckBox1.Attributes.Add(
"OnClick""TS_Util.AllSameCheck(this,0);");
        }

        
else if (e.Item.ItemType == ListItemType.Item && e.Item.ItemIndex == 0)
        
{
            TextBox TextBox1 
= (TextBox)e.Item.FindControl("TextBox1");
            TextBox1.Attributes.Add(
"onkeyup""TS_Util.AllSameValue(this);");
        }

    }

注意:CheckBox1.Attributes.Add("OnClick""TS_Util.AllSameCheck(this,0);");
如果想象前面的截图那样有多个列需要类似的功能,则为TS_Util.AllSameCheck(this,1);") 这个数字是从0开始,递增的,不能跳数。

其它值得注意的地方,如果您使用的不是文本框,比如象我一样使用一个日期控件,您可能不能使用Onkeyup事件。必须额外在对第一行数据中相应的控件中使用
TextBox3.Attributes.Add("onpropertychange", "TS_Util.AllSameValue(this);");
对,就是要 onpropertychange 这个事件,呵呵

还有前面给出的脚本代码中注意这句
if(i > 1 && no == 2)
{
    theTable.rows[i].cells[j].childNodes[2].disabled = obj.checked;
}

这个也是为了日期控件特意加的代码。因为就算你把日期的文本框设置成不能用的,但右边的图片还是可以点,可以弹出日期选择的。因此加了一句。不过大家每个公司使用的日期控件是五花八门的,或许有些人的控件就不需要这样处理。大家自己微调吧。

http://piedpiper.cnblogs.com
本文是偶原创,想转贴的朋友劳驾写明转贴二字。呵呵。如果大家使用中有什么疑问,欢迎一起交流。偶对javascript脚本没什么研究,估计写的比较烂,也请大家一起改进。改进后,请到这里教教偶,偶这算是抛砖引玉啦。
posted on 2007-12-31 14:43  雪山之巅  阅读(1765)  评论(7编辑  收藏  举报