【问题标题】:Tips on generating dynamic form fields from a string of data?从一串数据生成动态表单字段的技巧?
【发布时间】:2013-05-15 16:15:24
【问题描述】:

这就是我想要做的。我想获取一个短语列表,并在短语的某些部分表明需要用户输入..无论是下拉列表、文本框、日期字段等。在某种程度上有点像 Madlibs.. 但是具有从列表中选择事物的选项。

例如:

我拥有一个?list_of_cars?,我在?date? 上购买了它。它有?freetext? 英里数。

这个字符串被分解成文本和 HTML 表单域/ASP.net 控件的混合体。

?list_of_cars? 变成一个下拉列表,有几个选项可供选择。

?date? 变成日期字段(我创建的自定义用户控件)

?freetext? 只是一个用户可以输入信息的文本框。

我需要使用大约 50 个这样的短语。最终结果是,在用户填写所需的输入后,它们最终将成为文本框中的纯文本。

没有列表需要大量选项。汽车就是一个不好的例子。一个列表最多可能包含 5 个选项。

此时,我开始将带有多个分隔符和占位符的整个字符串存储到数据库表中。

例如,一行如下所示:

我拥有一个{list^Nissan,Ford,Chevy},我在{date} 上购买了它。上面有{text} 英里。

然后我将其分解并用表单字段替换占位符..然后将它们全部重新组合成纯文本。我觉得可能有更聪明/更好的方法来做到这一点。我不反对备份和更改初始短语的存储方式。

只是好奇是否有人可能有任何提示/建议?

【问题讨论】:

  • 我会先考虑如何分割零件。字段名称、某种类型以及一些格式信息怎么样。 {Car Make|list:carmake|n/a} 可能是提示 Car Make 的字段,如果 NULL 输出“n/a”,则选择来自表中的下拉列表。包含所有列表选项的表可以包含列表选择器(“carmake”)、选项等级(1、2、3、...)和选项(“Saab”、“Unimog”、“Volvo”...)。在许多形式中,您需要允许多次出现一个类型,例如计费 ZIP 和运输 ZIP。也考虑处理复数:{Dogs|int:dog:dogs|lonely}.

标签: c# asp.net sql-server vb.net sql-server-2005


【解决方案1】:

我会采用与您类似的方法,但您创建的控件可以读取编辑器的类型以及可用值。

而且我也会使用 String.Format 将它们分开存储,这样你就可以重复使用

所以我会有一个有两个属性的类

class RequiredInput
{
    public property string Phrase { get; set;}
    public property Field[] Fields { get; set;}
}

class Field
{
    public Type Type { get; set;}
    public object Default { get; set;}
    public object[] options { get; set;}
}

然后我会写下这样的解析器:

var sentence = new RequiredInput();
sentence.Phrase = "I own a {0}, I purchased it on {1}. It has {2} miles on it.";
sentece.options = new Field[] { 
    new field(typeof(ComboBox), new string[] { "Car1", "Car2", "Car3"}),
    new field(typeof(DateEdit), DateTime.Now),
    new field(typeof(TextEdit), String.Empty) }
}

我不知道,只是想......

【讨论】:

    【解决方案2】:

    以下是您必须考虑的不同方面的一些细节

    存储列表

    我建议你创建两个表 List (ListID, ListName) 和 ListItem (ListID, ItemName) 并将这些数据保存在数据库中以便于维护。如果您有多个相同的汽车列表,您需要稍后更新,这将使您的事情变得容易。另一方面,更新多个字符串并不像这样容易。

    标签

    需要使它们易于解析。我会避免使用复杂的名称,例如“{list^Nissan,Ford,Chevy}”,并将其定义为 ?list_ID?。所有标签都需要易于识别。也许?tag_name?这不是一个好主意,因为您会有问号,这可能会使解析更加困难。最好使用 #!tag_name!# 之类的东西

    ASP.NET

    所有控件都需要添加到 OnInit 方法中,而不是稍后在 Page_Load 中。

    解析

    这里有一些东西可以帮助您入门,但需要更多工作。

    private const string OPEN_TAG = "!#";
    private const string CLOSE_TAG = "#!";
    
    private void Parse(string s)
    {        
        int tagOpenIndex = 0;
        int tagCloseIndex = 0;
    
        tagOpenIndex = s.IndexOf(OPEN_TAG);
    
        string tag = string.Empty;
    
        while (tagOpenIndex >= 0)
        { 
            //Write everything before current tag opening 
            Response.Write(s.Substring(tagCloseIndex, tagOpenIndex));
    
            //Find where current tag is closing 
            tagCloseIndex = s.IndexOf(CLOSE_TAG, tagOpenIndex);
    
            //Get tag name
            tag = s.Substring(tagOpenIndex, tagCloseIndex - tagOpenIndex + 1);
    
            //Parse tag and create asp.net controls. Let's say this is a text box
            //You'll need to figure out where to put this and such
            //And also how to keep track of different control IDs so you can use these later.
            TextBox t = new TextBox();
            t.ID = "Generate some ID";
            Form.Controls.Add(t);
    
            //Get the index of next open tag
            tagOpenIndex = s.IndexOf(OPEN_TAG, tagCloseIndex);
        }
    }
    

    【讨论】:

    • 我喜欢这个答案,因为您扫描短语字符串的方法,谢谢。我最初使用的是Regex.Split,但我更喜欢你的方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-25
    • 2019-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多