0

I have a dropdownlist inside an update panel as I need to drive other content on the page on changes to the selected index.

However I am trying to apply a mobile look and feel to it. I tried JQuery Mobile at first but due to the way we are handling session information I had to disable the page ajax which in turn caused the site to be extremely slow.

I’ve since tried to apply some javascript I’ve found, which turns the opacity of the dropdown to 0 and then places a span over the top of it with some text and a background image, the image looking like a custom look drop down. It grabs all the select tags on the page to do this and sets the text to the current selected option tag. This is because even though it’s a dropdownlist, to html it is just a select with some options.

My problem is that on the partial post back when the selected index changes, the javascript is dropped from the targeted drop down. I’m trying to find a method that will allow me to re aply the javascript upon partial post back.

I’m coding in asp.net with c# code behind. I’m not using jquery and preferably don’t want to, I’d rather just pure javascript.

When I tried jquery mobile I had the same problem and this in the page load of the code behind fixed it:

ScriptManager.RegisterStartupScript(Page, GetType(), "temp", "<script type='text/javascript'>$('select').trigger('create');</script>", false); 

I’ve since tried this in the same place:

ScriptManager.RegisterClientScriptInclude(this, GetType(), "specialCombo", ResolveUrl("~") + "Js/test.js"); 

And also this in the head of the master page:

<script type="text/javascript">
    //On Page Load
    window.onload = function () {
        require("~/Js/test.js");
    };

    //On UpdatePanel Refresh
    var prm = Sys.WebForms.PageRequestManager.getInstance();
    if (prm != null) {
        prm.add_endRequest(function (sender, e) {
            if (sender._postBackSettings.panelsToUpdate != null) {
                require("~/Js/test.js");
            }
        });
    };

    function require(url) {
        var head = document.getElementsByTagName('head')[0];
        var script = document.createElement('script');
        script.type = 'text/javascript';
        script.src = url;

        head.appendChild(script);
    }
</script>

Which also caused a Sys not defined error so I put it underneath my script manager which was in the booking.aspx code. Neither of these worked.

Below is my html snippet, the JS file I am using, and the css applied to the JS that’s injected.

Any help would be appreciated

HTML

This in the head

<script language="javascript" src="Js/test.js"></script>

Then this in the body

<asp:UpdatePanel ID="f_NightsUpdatePanel" runat="server" RenderMode="Inline" UpdateMode="Conditional">
         <ContentTemplate>
                  <asp:DropDownList ID="f_Nights" runat="server" CssClass="inputComboHomePage" AutoPostBack="True" OnSelectedIndexChanged="f_Nights_SelectedIndexChanged">
                          <asp:ListItem Text="1" Value="1" Selected="True"></asp:ListItem>
                          <asp:ListItem Text="2" Value="2"></asp:ListItem>
                          <asp:ListItem Text="3" Value="3"></asp:ListItem>
                          <asp:ListItem Text="4" Value="4"></asp:ListItem>
                          <asp:ListItem Text="5" Value="5"></asp:ListItem>
                 </asp:DropDownList>
         </ContentTemplate>
</asp:UpdatePanel>

JAVASCRIPT – JS/test.js

var selectWidth = "190";


document.write('<style type="text/css">select.inputComboHomePage { position: relative; width: ' + selectWidth + 'px; opacity: 0; filter: alpha(opacity=0); z-index: 5; } .disabled { opacity: 0.5; filter: alpha(opacity=50); }</style>');

var Custom = {
    init: function () {
        var inputs = document.getElementsByTagName("input"), span = Array(), textnode, option, active;
        inputs = document.getElementsByTagName("select");
        for (a = 0; a < inputs.length; a++) {
            if (inputs[a].className == "inputComboHomePage") {
                option = inputs[a].getElementsByTagName("option");
                active = option[0].childNodes[0].nodeValue;
                textnode = document.createTextNode(active);
                for (b = 0; b < option.length; b++) {
                    if (option[b].selected == true) {
                        textnode = document.createTextNode(option[b].childNodes[0].nodeValue);
                    }
                }
                span[a] = document.createElement("span");
                span[a].className = "inputComboHomePage2";
                if (inputs[a].name == "ctl00$Main$f_RoomGroup1" || inputs[a].name == "ctl00$Main$f_BoardType1") {
                    span[a].style.color = 'gray';
                }
                span[a].id = "inputComboHomePage2" + inputs[a].name;
                span[a].appendChild(textnode);
                inputs[a].parentNode.insertBefore(span[a], inputs[a]);
                if (!inputs[a].getAttribute("disabled")) {
                    inputs[a].onchange = Custom.choose;
                } else {
                    inputs[a].previousSibling.className = inputs[a].previousSibling.className += " disabled";
                }
            }
        }
        document.onmouseup = Custom.clear;
    },
    choose: function () {
        option = this.getElementsByTagName("option");
        for (d = 0; d < option.length; d++) {
            if (option[d].selected == true) {
                document.getElementById("inputComboHomePage2" + this.name).childNodes[0].nodeValue = option[d].childNodes[0].nodeValue;
            }
        }
        if (this.name == "ctl00$Main$f_Nights") {
        __doPostBack('__Page', 'MyCustomArgument');
        }
    }
}
window.onload = Custom.init;

there is a manual post back at the end to force the page to post back and fire the selectedindexchanged event on just the relevant control

CSS

.inputComboHomePage2
{
    position: absolute;
         width: 158px; /* With the padding included, the width is 190 pixels: the actual width of the image. */
         height: 21px;
         padding: 0 24px 0 8px;
         color: #fff;
         font: 12px/21px arial,sans-serif;
         background: url(Images/select.png) no-repeat;
         overflow: hidden;
}
4

1 回答 1

0

Found a pure CSS solution to my original problem which was styling the dropdownlist.

I wrapped my ddl in a label

<label class="dropDownArrow" style="width:100%;">
      <asp:DropDownList ID="f_Nights" runat="server" CssClass="inputComboHomePage" AutoPostBack="True" OnSelectedIndexChanged="f_Nights_SelectedIndexChanged">
            <asp:ListItem Text="Number of Nights" Value="1" Selected="True"></asp:ListItem>
            <asp:ListItem Text="2" Value="2"></asp:ListItem>
      </asp:DropDownList>
</label>

And then applied the following css

.dropDownArrow
{
    position: relative;
    display: inline-block;
}
/* Select arrow styling */
.dropDownArrow:after {
    content: '';
    width: 26px;
    height: 26px;
    position: absolute;
    display: inline-block;
    top: 0px;
    right: 0px;
    background: url("Images/combo.png") no-repeat 0 0;
    pointer-events: none;
    z-index:999;
}

this overlaps an image over the ddl's arrow. the pointer events none allows clicks to pass through the image to the arrow behind.

slight issue with ie in that pointer events isnt supported but theres probably a fix for that somewhere.

于 2013-07-04T09:04:21.737 回答