我们目前有一个具有标准多选功能的表单,“这里是可用选项,这里是选定的选项,这里是一些来回移动内容的按钮。”但是,客户现在不仅希望能够选择某些项目,还希望能够对它们进行分类。例如,给定一个书单,他们不仅要选择自己拥有的书,还要选择他们读过的书、想读的书和听说过的书。 (所有示例都是虚构的。)值得庆幸的是,所选项目一次只能属于一个类别。
我可以找到许多在列表框之间移动项目的示例,但找不到一个在多个列表框之间移动项目的示例。为了增加复杂性,表单需要有两组列表+类别,例如除了上述书籍之外,还需要分类的电影列表。
编辑:现在已经真正坐下来尝试编写非 javascripty 位的代码,我需要修改我的问题,因为我意识到多个选择列表不会真正从“我如何通知服务器所有这个可爱的新信息”的立场。所以html代码现在是一个伪列表框,即一个无序列表(<ul>
)显示在一个带有滚动条的框中,每个列表项(<li>
)有一组五个单选按钮(未选择/拥有/阅读/喜欢/听说过)。
我的任务仍然大致相同:如何使用这个列表并使项目易于分类,以便用户一眼就能看出什么是什么类别。 (伪列表框有一些与多选列表框相同的缺点,即如果列表足够长可以滚动,则很难判断选择了什么。)理想的解决方案是拖放式的东西,但是此时连按钮都可以。
另一个修改(一个很好的修改)是客户修改了列表,所以最长的现在“只有”62 个项目(而不是以前的数百个)。这些类别仍将主要包含零个、一个或两个选定的项目,如果用户过于热心,可能还会包含更多。
至于操作系统和其他东西,该站点是经典的 asp(别窃笑!),服务器端代码是 VBScript,到目前为止,我们通过几乎从不使用客户端的简单权宜之计避免了各种 Javascript 库端脚本。目前,针对这个客户的这种形式是一个很大的异常(exception)。给他们一英寸,他们想要一英里...
哦,我必须补充一点:我不擅长 Javascript,或者真的不擅长任何 C 语言后裔。花括号让我得了荨麻疹。我真的非常喜欢我可以复制并粘贴到我的页面中的东西,也许可以调整一些变量名称,然后再也不会看它了。一个女孩可以做梦,不是吗? :)
[现有代码已删除,因为它在很大程度上是不相关的。]
最佳答案
有趣的是,就在昨天,我还在谷歌上搜索“在多个列表框之间移动项目”,然后弹出了您的问题。
我没有阅读您的整篇文章,所以我不确定是否可以提供帮助。 但这解决了我的问题。 我下载了this解决方案。 然后做了如下改动...
- 在html中添加一个额外的hidenfield 每个(额外)列表框。
- 修改如下,即可 比较我所做的更改...
//...
公共(public)部分类 ErrorActions : System.Web.UI.Page { 私有(private) XmlDocument _xmlDocument = new XmlDocument(); 公共(public)列表框 FromListBox { 得到 { 返回 lstFrom; }
public ListBox AbortListBox
{
get
{
return lstToAbort;
}
}
public ListBox ClearingListBox
{
get
{
return lstToClearing;
}
}
protected void Page_Load(object sender, EventArgs e)
{
Page.ClientScript.RegisterClientScriptInclude("listboxjs", "/JavaScripts/listbox.js");
if (!IsPostBack)
{
string movejs = "move('{0}','{1}','{2}')";
string unselectjs = "unselect('{0}')";
lstFrom.Attributes["onclick"] = String.Format(unselectjs, lstToAbort.ClientID);
lstFrom.Attributes["onclick"] = String.Format(unselectjs, lstToClearing.ClientID);
lstToAbort.Attributes["onclick"] = String.Format(unselectjs, lstFrom.ClientID);
lstToAbort.Attributes["onclick"] = String.Format(unselectjs, lstToClearing.ClientID);
lstToClearing.Attributes["onclick"] = String.Format(unselectjs, lstFrom.ClientID);
lstToClearing.Attributes["onclick"] = String.Format(unselectjs, lstToAbort.ClientID);
btnToAbort.Attributes["onclick"] = String.Format(movejs, lstFrom.ClientID, lstToAbort.ClientID, hdnDropdownsAbort.ClientID);
btnFromAbort.Attributes["onclick"] = String.Format(movejs, lstToAbort.ClientID, lstFrom.ClientID, hdnDropdownsAbort.ClientID);
btnToClearing.Attributes["onclick"] = String.Format(movejs, lstFrom.ClientID, lstToClearing.ClientID, hdnDropdownsClearing.ClientID);
btnFromClearing.Attributes["onclick"] = String.Format(movejs, lstToClearing.ClientID, lstFrom.ClientID, hdnDropdownsClearing.ClientID);
}
else
{
//if (!(String.IsNullOrEmpty(hdnDropdowns.Value)))
//{
// PopulateListBoxes();
//}
if (!(String.IsNullOrEmpty(hdnDropdownsAbort.Value)))
{
PopulateAbortListBox();
}
if (!(String.IsNullOrEmpty(hdnDropdownsClearing.Value)))
{
PopulateClearingListBox();
}
}
}
private void PopulateListBox(ListBox listBox)
{
listBox.Items.Clear();
XmlNodeList nodes = _xmlDocument.SelectNodes("listboxes/" + listBox.ClientID + "/option");
foreach (XmlNode node in nodes)
{
listBox.Items.Add(new ListItem(node["key"].InnerText, node["value"].InnerText));
}
}
//private void PopulateListBoxes()
//{
// _xmlDocument.LoadXml(HttpUtility.UrlDecode(hdnDropdownsAbort.Value));
// //PopulateListBox(lstFrom);
// PopulateListBox(lstToAbort);
// PopulateListBox(lstToClearing);
//}
private void PopulateAbortListBox()
{
_xmlDocument.LoadXml(HttpUtility.UrlDecode(hdnDropdownsAbort.Value));
PopulateListBox(lstToAbort);
}
private void PopulateClearingListBox()
{
_xmlDocument.LoadXml(HttpUtility.UrlDecode(hdnDropdownsClearing.Value));
PopulateListBox(lstToClearing);
}
protected void btnDoIt_Click(object sender, EventArgs e)
{
MissionErrorCodeDB db = new MissionErrorCodeDB();
db.DeleteErrorCodeActions(ErrorAction.AbortMission);
db.DeleteErrorCodeActions(ErrorAction.GoToClearingStation);
foreach (ListItem item in lstToAbort.Items)
{
db.AddErrorCodeAction(Convert.ToInt32(item.Value), ErrorAction.AbortMission);
}
foreach (ListItem item in lstToClearing.Items)
{
db.AddErrorCodeAction(Convert.ToInt32(item.Value), ErrorAction.GoToClearingStation);
}
}
protected override void OnPreRender(EventArgs e)
{
MissionErrorCodeDB db = new MissionErrorCodeDB();
List<MissionErrorCode> aborts = db.GetAll(ErrorAction.AbortMission);
List<MissionErrorCode> clearing = db.GetAll(ErrorAction.GoToClearingStation);
List<MissionErrorCode> all = db.GetAll();
all.RemoveAll(delegate(MissionErrorCode mec)
{
foreach (MissionErrorCode item in aborts)
{
if( mec.ErrorCode == item.ErrorCode )
return true;
}
return false;
});
all.RemoveAll(delegate(MissionErrorCode mec)
{
foreach (MissionErrorCode item in clearing)
{
if (mec.ErrorCode == item.ErrorCode)
return true;
}
return false;
});
populateBoxFromDatabase(AbortListBox, aborts);
populateBoxFromDatabase(ClearingListBox, clearing);
populateBoxFromDatabase(FromListBox, all);
base.OnPreRender(e);
}
private void populateBoxFromDatabase(ListBox listBox, List<MissionErrorCode> errorCodes)
{
string text;
int textLength = 46;
listBox.Items.Clear();
foreach (MissionErrorCode item in errorCodes)
{
if (item.ErrorText.Length < textLength)
{
text = item.ErrorCode + " - " + item.ErrorText;
}
else
{
text = item.ErrorCode + " - " + item.ErrorText.Substring(0, textLength - 1) + "...";
}
listBox.Items.Add(new ListItem(text, item.ErrorCode.ToString()));
}
}
//...
关于javascript - 在多个列表之间移动选项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2504194/