Hide or Remove duplicate options in dropdownlist - c#

I'm using WebForms. In my Form, I have a dropdownlist control. Sometimes the Select option gets added twice in my from. How can remove this duplicate option or hide it?
I've tried to count how many times Select option is added then hide it but wasn't successful.
The reason why it's adding it twice is because grdview_Color_DataBound gets called twice.
<select name="ctl00$MainContent$grdview_Color$ctl10$ddl_Grd_Color" id="MainContent_grd_ddl_grdview_Color" class="form-control dropdown">
<option value="0" selected="selected" disabled="disabled">Select</option>
<option value="0" disabled="disabled">Select</option>
<option value="Yellow">Yellow</option>
<option value="Red">Red</option>
<option value="Blue">Blue</option>
<option value="Green">Green</option>
</select>
protected void grdview_Color_DataBound(object sender, EventArgs e)
{
ListItem firstItem = new ListItem("Select", "0");
firstItem.Attributes.Add("disabled", "disabled");
ddl.DataSource = dataSource;
ddl.DataTextField = TextField;
ddl.DataValueField = ValueField;
ddl.DataBind();
ddl.Items.Insert(0, firstItem);
}

A naive way would be to store the items in the drop down list in some kind of container like a list. Clear the drop down items and then loop through your container, only adding unique items back to the drop down items list with something like:
// Save the items
savedItems = dropDownItems.Items;
// Clear The items
dropDownItems.Items.Clear();
// Go through the container adding unique items to the drop down list
foreach (string item in savedItems){
if (!dropDownItems.Items.Contains(item)) {
dropDownItems.Items.Add(item);
}
}
of course this way is not the best way, but it is a way if you are in a hurry.

You need to set the AppendDataBoundItems property to true to preserve the existing values in the DDL. You also need to ensure that you are not doing it on every postback - your code sample does not show if and how you are doing this in the Page_Load() method.

Related

Clearing a selected DropDown item without bind-Value

How can we clear/reset the selected item on a Radzen DropDown?
I did not use bind-Value to get the selected item.
Instead, I used Change() to get the selected object.
However, if I select one item on the DropDown and change the content of tempLocations, the selected item itself will not be cleared.
View:
<RadzenDropDown Name="Location" TValue="string" Data=#tempLocations Change=#(args => LocationChange(args))>
<Template Context = "location">
#($"{location.id}:{location.name}")
</Template>
</RadzenDropDown>
I guess there will be no solution expect using bind-Value.
Here is my updated coding:
<RadzenDropDown #bind-Value=#tempSelectedLocation Name="ALocation" Data=#tempLocations Change=#(args => LocationChange(args))>
<Template Context = "location">
#($"{location.pressure} {location.name}")
</Template>
</RadzenDropDown>
tempSelectedLocation is a class object.

C# Automation: To get drop down values and store disable values

I want a solution for writing a script for C# Automation using selenium web driver library in TFS, I have to store all disabled values and then click on them. Actually, the validation is like that I should not be able to click on disabled values in a drop-down list. So I need help here in 2 things:
I want to store disabled values first and then
I want to iterate through them
To write a boolean/any function for validation that I am unable to click that values
Here is the code:
<select name="ctl00" onchange="javascript:setTimeout('__doPostBack(\'ctl00$ctl00$\',\'\')', 0)" id="ctl00_ctl00_" style="width:200px;">
<option value="1" disabled="disabled">A</option>
<option selected="selected" value="2" enabled="enabled">B</option>
<option value="3" disabled="disabled">C</option>
<option value="4" disabled="disabled">D</option>
</select>
So, A, C, and D are the options for which I want validation.
Need a helping hand :)
Thanks in Advance
I use something like this to search my pages for 'is-loading' classes to check for loading elements. I've reflavored to check for 'disabled' classes, pass them into an array, and then click on the. Not tested but hopefully gets you pointed in the right direction.
new WebDriverWait(driver, MyDefaultTimeout)
.Until(e => ((IJavaScriptExecutor)e)
.ExecuteScript(""+
"do {"+
// Find loading element(s)
"var element = document.getElementsByClassName('disabled');"+
// Create array of elements
"var elementList = Array.prototype.slice.call(element);"+
"if(!elementList === undefined && !elementList == 0) {"+
// Map Id and Attribute
"var array = elementList.map(function(v){ return {'ID': v.id} });"+ //"'Attr': v.getAttribute('data-custAtt')"+
// Output array of disabled objects
"console.log(array);"+
// Check to see if array is empty
"if (!array === undefined && !array.length == 0) {"+
// Click disabled element
"var i;"+
"for (i=0;i<array.length;i++){"+
"var disabledElement = array[i];"+
"disabledElement.click();}";"+
"}"+
"else"+ // Array is empty, exit the loop
"{"+
"done = true;"+
"}"+
"}"+
"else"+
"{"+
// We may not have an array of elements
// So if we only have 1
"if(!element === undefined) {"+
// Click disabled element
"element.click();"+
"}"+
"else"+
"{"+
"done = true;"+
"}"+
"}"+
"}"+
"while(done = 'false');")
.Equals("complete"));

WebBrowser control HTMLDocument automate selecting option drop-down

I'm trying to automate in a WinForm using a WebBrowser control to navigate and pull report info from a website. You can enter values in textboxes and invoke the click events for buttons and links, but I have not figured out how select a option drop-down .... in a automated way. Anybody recommend how to select a item from a drop-down, given this html example:
<SELECT id="term_id" size="1" name="p_term_in"><option value="">Select Another Term<option value="201050">Summer 2010<option value="201010">Spring 2010<option value="200980">Fall 2009</SELECT>
For others that can learn from entering values to textboxes and invoking click events here's how you do it:
webBrowser1.Document.GetElementById("<HTML ELEMENT NAME>").SetAttribute("value", "THE NAME");
Invoke button or hyperlink click:
webBrowser1.Document.GetElementById("<BUTTON>").InvokeMember("click");
So I've solved entering values and invoking click, but I have not solved selecting a drop-down value.
Assuming you have the following select in the HTML:
<select id="term_id" size="1" name="p_term_in">
<option value="">Select Another Term
<option value="201050">Summer 2010
<option value="201010">Spring 2010
<option value="200980">Fall 2009
</select>
This should allow you to preselect the third value:
webBrowser1.Document.GetElementById("term_id").SetAttribute("value", "201010");
var select = webBrowser.Document.GetElementById("ddlProyectos");
mshtml.HTMLSelectElement cbProyectos = select.DomElement as mshtml.HTMLSelectElement;
var total = cbProyectos.length;
for (var i= 0; i < total; i++)
{
cbProyectos.selectedIndex = i;
if (cbProyectos.value.Contains("13963"))
{
break;
}
}
//cbProyectos.selectedIndex = 4;
select.InvokeMember("onchange");
select.Children[4].SetAttribute("selected", "selected");
var theElementCollection = webBrowser.Document.GetElementsByTagName("select");
foreach (HtmlElement el in theElementCollection)
{
if (el.GetAttribute("value").Equals("13963"))
{
el.SetAttribute("selected", "selected");
//el.InvokeMember("click");
}
}
You will have to select the selected attribute on the option you want.
Given:
<select id="mySelect">
<option>1</option>
<option>2</option>
<option>3</option>
</select>
The following would selct the third option:
webBrowser1.Document
.GetElementById("")
.Children.GetElementsByName("option")[2]
.SetAttribute("selected", "selected");
try this:
add reference to microsoft.mshtml in project --> add reference...
Dim cboTemp As mshtml.HTMLSelectElement
cboTemp = WebBrowser1.Document.GetElementById("myselect").DomElement
cbotemp.selectedindex = 2
having the variable cbotemp set to a select element gives you greater access to the control :)
HtmlElement hField = webBrowser1.Document.GetElementById("ID");
hField.SetAttribute("selectedIndex", "2");
select by index (zero based) not the value....
I'm answering on this post after five years, for the people who are searching a solution of this problem.
If you just need to submit/post a value for the dropdown then this line is sufficient:
webBrowser1.Document.GetElementById("term_id").SetAttribute("value", "200980");
But if you really need to select an underlying OPTION, then:
HtmlElement selectDom = webBrowser1.Document.GetElementById("term_id");
foreach (HtmlElement option in selectDom.GetElementsByTagName("option"))
{
if (option.GetAttribute("value") == "200980")
{
var dom = option.DomElement as dynamic;
dom.selected = true;
// selectDom.InvokeMember("onChange"); // if you need this too
break;
}
}
You can use this:
webBrowser1.Document.GetElementById("term_id").SetAttribute("value",yourText);

Binding DropDownList to ListItemCollection and the Value not being added to the DDL

I have this code in a business class.
internal ListItemCollection GetAllAgents()
{
DataTable table = dao.GetAllAgents();
ListItemCollection list = new ListItemCollection();
foreach (DataRow row in table.Rows)
{
list.Add(new ListItem(row["agent_name"].ToString(), row["id"].ToString()));
}
return list;
}
I get the table back from the dao without issue. I watch the text and values properties populate properly(+1 for some awesome illiteration?) and returned to the presentation and I bind like this
Helper helper = new Helper();
ListItemCollection agentList = helper.GetAllAgents();
agentList.Insert(0,"");
this.ddlAgent.DataSource = agentList;
this.ddlAgent.DataBind();
when I make get the selected value
this.ddlAgent.SelectedValue
I would expect to see the agent id, but what I get is the text (agent name), so I tried this
this.ddlAgent.SelectedItem.Value
but I got the same results. I then took a look at the html source being generated and it looks like this
<select name="ctl00$ContentPlaceHolder1$ddlAgent" onchange="javascript:setTimeout('__doPostBack(\'ctl00$ContentPlaceHolder1$ddlAgent\',\'\')', 0)" id="ctl00_ContentPlaceHolder1_ddlAgent">
<option selected="selected" value=""></option>
<option value="agent1_name">agent1_name</option>
<option value="agent2_name">agent2_name</option>
this pattern continues for all the agents. I'm hoping I'm just doing something bone headed and you can all snicker as you solve my problem :)
Thanks guys.
EDIT: if I do it like this
ListItemCollection agentList = helper.GetAllAgents();
agentList.Insert(0,"");
foreach (ListItem agent in agentList)
{
this.ddlAgent.Items.Add(agent);
}
it works fine.
Try doing:
this.ddlAgent.DataTextField = "Text";
this.ddlAgent.DataValueField = "Value";
this.ddlAgent.DataSource = agentList;
this.ddlAgent.DataBind();
Should also work, and it's probably better than looping through the list for no reason.
Update Found another (shorter) way of doing this:
this.ddlAgent.Items.AddRange(agentList.ToArray());
this.ddlAgent.DataBind();
By using Items.AddRange() instead of setting the source with DataSource, ASP is able to figure out that it should use the Text and Value properties.
If agentList is a ListItemCollection the following code works for me, without calling this.ddlAgent.DataBind();
this.ddlAgent.Items.AddRange( agentList.Cast<ListItem>().ToArray() ) ;

How to dynamically Order a listbox with a dropdown?

I have a listbox with 20 colors. It looks something like this:
1:Red
2:Green
3:Blue
4:Orange
5:Red
6:Yellow
7:Orange
8:Red
9:Green
....
It gets the data from an ObjectDataSource which in turn gets it's data from a method which returns a datatable. I want a dropdown which basically has 2 items, Order By # and Order By Color. If the user chooses Order By #, it will Order the ListBox in ascending or descending order. If the user chooses Order By Color, it will Order By Color. How do I go about doing this?
Can I sort this using a DataView?
Thanks,
XaiSoft
You can add the sort expression to your ObjectDataSource as a Select parameter, you can define it like so:
<asp:ObjectDataSource
ID="ObjectDataSource1"
runat="server"
SelectMethod="SelectMethod"
TypeName="MyDataObject">
<asp:Parameter Direction="input" Type="string" Name="sortExpression">
</asp:Parameter>
</asp:ObjectDataSource>
Then in the "SelectMethod" method where the data is retrieved add a parameter of that name and return a DataView:
public DataView SelectMethod(string sortExpression)
{
DataTable table = GetData();
DataView dv = new DataView(table);
dv.Sort = sortExpression;
return dv;
}
Then in the wizard for the ObjectDataSource you can bind that Parameter to the dropdown SelectedValue. Make the value of each of the DropDown items the same as your column names.
(I'm assuming you've already figured out how to bind the ListBox in the first place.)
Set the property AutoPostback="true" on your DropdownList. This will cause the SelectedIndexChanged event to fire when the user picks a different value.
In there you can rebind your listbox.
Edit: deleted my misunderstanding around the ObjectDataSource - joshperry's answer covers that much better!
Just wonder... You already have the data in the ListBox, why not sorting it using javascript? To avoid go back to the server and ask for the same thing.
just get the correct list box id and you're done!
<script language="JavaScript" type="text/javascript">
function sortlist() {
var lb = document.getElementById('mylist'); // <-- Use $get(<%# myList.ClientID %>); if you want
arrTexts = new Array();
for(i=0; i<lb.length; i++) {
arrTexts[i] = lb.options[i].text;
}
arrTexts.sort();
// arrTexts.reverse() // <-- uncomment if you want descending
for(i=0; i<lb.length; i++) {
lb.options[i].text = arrTexts[i];
lb.options[i].value = arrTexts[i];
}
}
</script>
<select name="mylist" id="mylist" size="5">
<option value="Anton">Anton</option>
<option value="Mike">Mike</option>
<option value="Peter">Peter</option>
<option value="Bill">Bill</option>
<option value="Carl">Carl</option>
</select>
<br />
sort

Categories

Resources