Reputation: 873
Goal: Have ASP Label text color change when an ASP Dropdown ListItem is chosen. If ListItem's value is false, then the Label's text should be red. Otherwise stay black.
Problem: It changes color only when the page is refreshed (or if the value is already false from the database upon original page load)
What I've tried:
Is this possible purely in C#/asp.net without a page refresh? If I need to do javascript, how can I do it from the Dropdownlist to the Label?
HTML:
<div>
<asp:ScriptManager runat="server"></asp:ScriptManager>
<asp:UpdatePanel runat="server">
<ContentTemplate>
<asp:Image ID="img1" runat="server" height="20" width="20" CssClass="providericon"/><sup><asp:Label ID="myLabel" runat="server" Font-Size="20px" CssClass="oval"/></sup>
<asp:Label ID="myLabelMid" runat="server" CssClass="professorname"/>
<asp:DropdownList runat="server" id="ddlAvailability1" AutoPostBack="true" OnSelectedIndexChanged="ddlAvailability_OnSelectedIndexChanged" CssClass="dropdowns">
<asp:ListItem ID="LT1"></asp:ListItem>
<asp:ListItem ID="RT1"></asp:ListItem>
</asp:DropdownList>
</ContentTemplate>
</asp:UpdatePanel>
</div>
<asp:Panel ID="row2" runat="server" Visible="false">
<%--<asp:ScriptManager runat="server"></asp:ScriptManager>--%>
<asp:UpdatePanel runat="server">
<ContentTemplate>
<asp:Image ID="img2" runat="server" CssClass="professoricon"/><sup><asp:Label ID="L2" runat="server" Font-Size="20px" CssClass="oval"/></sup> <asp:Label ID="M2" runat="server" CssClass="professorname"/>
<asp:DropdownList runat="server" id="ddlAvailability2" AutoPostBack="true" OnSelectedIndexChanged="ddlAvailability_OnSelectedIndexChanged" CssClass="dropdowns">
<asp:ListItem ID="LT2"></asp:ListItem>
<asp:ListItem ID="RT2"></asp:ListItem>
</asp:DropdownList>
</ContentTemplate>
</asp:UpdatePanel>
</asp:Panel>
CSS:
.professorname {
margin-left: 15px;
position: absolute;
left: 55px;
}
.redtext {
color: red;
margin-left: 15px;
position: absolute;
left: 55px;
}
C#:
Page_Load(){
myLabelMid.CssClass = (ddlAvailability1.SelectedValue == "False") ? "redtext" : "professorname";
M2.CssClass = (ddlAvailability2.SelectedValue == "False") ? "redtext" : "professorname";
M3.CssClass = (ddlAvailability3.SelectedValue == "False") ? "redtext" : "professorname";
}
protected void ddlAvailability_OnSelectedIndexChanged(object sender, EventArgs e)
{
DropDownList ddlSender = (DropDownList)sender;
int professorIndex = getProviderIndex(ddlSender.ClientID);
}
public int getProfessorIndex(string ddlSenderClientID)
{
int professorIndex = 0;
switch (ddlSenderClientID)
{
case "ddlAvailability1":
professorIndex = 0;
myLabelMid.CssClass = (ddlAvailability1.SelectedValue == "False") ? "redtext" : "professorname ";
break;
case "ddlAvailability2":
professorIndex = 1;
M2.CssClass = (ddlAvailability2.SelectedValue == "False") ? "redtext" : "professorname ";
break;
}
return professorIndex;
}
Upvotes: 0
Views: 820
Reputation: 19792
VDWWD's answer raised some important concerns with your code. You should also use the AssociatedControlId
attribute on your labels to correctly associate the label element with your dropdown. This will add the for
attribute to your labels. We can then leverage that in javascript.
Something like the following.
<!-- Note the added AssociatedControlId attribute and the
removal of OnSelectedIndexChange and AutoPostback -->
<div>
<asp:ScriptManager runat="server"></asp:ScriptManager>
<asp:UpdatePanel runat="server">
<ContentTemplate>
<asp:Image ID="img1" runat="server" height="20" width="20" CssClass="providericon"/><sup><asp:Label ID="myLabel" runat="server" Font-Size="20px" CssClass="oval" /></sup>
<asp:Label ID="myLabelMid" runat="server" CssClass="professorname" AssociatedControlId="ddlAvailability1" />
<asp:DropdownList runat="server" id="ddlAvailability1" CssClass="dropdowns">
<asp:ListItem value="true">Yes</asp:ListItem>
<asp:ListItem value="false">No</asp:ListItem>
</asp:DropdownList>
</ContentTemplate>
</asp:UpdatePanel>
</div>
<asp:Panel ID="row2" runat="server" Visible="false">
<%--<asp:ScriptManager runat="server"></asp:ScriptManager>--%>
<asp:UpdatePanel runat="server">
<ContentTemplate>
<asp:Image ID="img2" runat="server" CssClass="professoricon"/><sup><asp:Label ID="L2" runat="server" Font-Size="20px" CssClass="oval"/></sup> <asp:Label ID="M2" runat="server" CssClass="professorname" AssociatedControlId="ddlAvailability1"/>
<asp:DropdownList runat="server" id="ddlAvailability2" CssClass="dropdowns">
<asp:ListItem value="true">Yes</asp:ListItem>
<asp:ListItem value="false">No</asp:ListItem>
</asp:DropdownList>
</ContentTemplate>
</asp:UpdatePanel>
</asp:Panel>
Javascript
let dropdowns = document.querySelectorAll(".dropdowns");
//Add Event Listeners
for(var i = 0; i < dropdowns.length; i++) {
dropdowns[i].addEventListener("change", function() {
//Find labels associated with control
let labels = document.querySelectorAll("[for=" + this.id +"]");
//toggle the redtext class on labels based on the selected value
for(var j = 0; j < labels.length; j++) {
labels[0].classList.toggle("redtext", this.value === "true");
}
//NOTE: if you know each dropdown only has one label
// use document.querySelectorAll and skip the loop
// document.querySelector("[for=" + this.id +"]").classList.toggle("redtext", this.value === "false");
})
}
NOTE all code is untested and some debugging might be required but this should get you moving in the right direction. Also note jQuery is also an option here if you're already using it.
Upvotes: 0
Reputation: 35544
There are a few issues with your code.
If you use OnSelectedIndexChanged
the DDL will trigger a PostBack and all changes made to the DOM with jQuery will be lost. You seem to know this, but I mention it just to make sure. So if you use this, make sure you bind data inside an IsPostBack
check.
And there is no False
in your code snippet. A ListItem is selected or not, but you use the Value
, not the yes/no selected state.
A ListItem does not have an ID
property.
Take a look at the snippet below for a jQuery text color change demo. Use either one, not both at the same time.
<asp:DropDownList runat="server" ID="ddlAvailability1" CssClass="dropdowns">
<asp:ListItem Value="">Select a Professor</asp:ListItem>
<asp:ListItem Value="LT1">Professor LT1</asp:ListItem>
<asp:ListItem Value="LT2">Professor LT2</asp:ListItem>
<asp:ListItem Value="LT3">Professor LT4</asp:ListItem>
</asp:DropDownList>
<script>
//this changes the color to red as soon as something changes in the dll
$('.dropdowns').bind('change', function () {
$(this).addClass('redtext');
});
//this changes the color to red when anything other than the first item is selected,
//else it becomes black again
$('.dropdowns').bind('change', function () {
if ($(this).prop('selectedIndex') !== 0) {
$(this).addClass('redtext');
} else {
$(this).removeClass('redtext');
}
});
</script>
<style>
.dropdowns {
color: black;
}
.redtext {
color: red;
}
</style>
Upvotes: 1
Reputation: 1396
DropdownList is an ASP.NET control and it needs AutoPostback to fire the SelectedIndexChanged event, I just adapted your problem and the simplest solution is to use an update panel that covers the DropdownList and Label:
ASPX Code:
<asp:ScriptManager runat="server"></asp:ScriptManager>
<asp:UpdatePanel runat="server">
<ContentTemplate>
<asp:Label ID="myLabelMid" runat="server" CssClass="professorname" Text="test"/>
<asp:DropdownList runat="server" ID="ddlAvailability1" AutoPostBack="true" OnSelectedIndexChanged="ddlAvailability1_SelectedIndexChanged" CssClass="dropdowns">
<asp:ListItem ID="LT1" Text="yes"></asp:ListItem>
<asp:ListItem ID="RT1" Text="no"></asp:ListItem>
</asp:DropdownList>
</ContentTemplate>
</asp:UpdatePanel>
C# Code:
protected void ddlAvailability1_SelectedIndexChanged(object sender, EventArgs e)
{
if (ddlAvailability1.SelectedValue == "no") { myLabelMid.CssClass = "redtext"; }
else { myLabelMid.CssClass = "professorname";}
}
I think that reaching the same behavior through JavScript is possible but it is a more complicated solution with an ASP.NET control, because you will need to do the validation in your function once the PostBack finishes, this can be done using Sys.WebForms.PageRequestManager.getInstance()
.
Upvotes: 1