Reputation: 33
I'm using Select2 on a DropDownList and when I select a value that make a full page refresh.
That's not happening selecting directly without Select2, making a partial postback.
The DropDownList have AutoPostback=true and is in an UpdatePanel.
Upvotes: 0
Views: 163
Reputation: 49039
Actually, I suspect that you don't have this working without an update panel anyway (that's why you should post a working example).
The next issue, is when using the jQuery select() library, I never been able to get the multiple selected items to work (multiple items can be selected, but only the first item shows selected = true).
As a result, then I suggest using a "select" tag, with a runat="server". As such, this results in about 99% of the same functionally as a dropdown list, but without the autopost-back feature.
To solve the missing autopostback feature, we simply place a hidden button on the form, and use jQuery to click that button for us, and then use the client side onchange() event of the select dropdown.
Next issue:
When the page loads, and the jQuery selector runs, it runs a boatloads of setup code to modify the select/dropdown list. And if you post back, or have a partial page post back (an update panel), then that jQuery select2() initialize drop down system has to run each time after a postback.
Keep in mind that an update panel does not prevent a page post back, but is what we call a partial page postback. That means the page load event runs, and that update panel goes though a full standard page post-back.
And that means that the markup in that panel is re-loaded with fresh markup from the server, and thus the jQuery select2() needs to run again on that drop down list.
So, to solve the issue of retrieving the selected = true, we have to dump use of the DropDown list.
This results in no autopost-back = true feature, and thus we will create our own auto post back.
We also have to add client-side code that runs after the update panel has finished its round trip, and specific, this means the select2() initialiser code has to run after the update panel is done.
So, here is a proof of concept based on above:
Markup:
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<div style="float: left">
<h4>Select Multiple Cites</h4>
<select id="DropDownList1" runat="server" clientidmode="static"
datatextfield="City"
multiple="true"
style="width:500px"
onchange="mychange()"
>
</select>
<script>
function mychange() {
$('#Button1').click()
}
</script>
</div>
<div style="float:left;margin-left:35px;margin-top:40px">
<asp:Button ID="Button1" runat="server" Text="Show Hotels"
ClientIDMode="Static"
CssClass="btn"
OnClick="Button1_Click" />
</div>
<div style="clear:both;height:20px"></div>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ID" CssClass="table" Width="40%">
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="LastName" />
<asp:BoundField DataField="HotelName" HeaderText="HotelName" />
<asp:BoundField DataField="City" HeaderText="City" />
<asp:BoundField DataField="Description" HeaderText="Description" />
</Columns>
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
<script>
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(runafterup);
function runafterup() {
// the select2 code needs to run AFTER the UP round trip
// and content comes back - no document ready will run/fire
console.log("on UP load select setup")
$('#DropDownList1').select2()
}
$(document).ready(function () {
console.log("on page load select setup")
$('#DropDownList1').select2()
});
</script>
In above, we have a Select in place of the DropDownList.
And upon selecting a value, we use that to filter the GridView to display a list of hotels based on the drop-down cities selected.
Note close that we have the jQuery select2 placed 2 times in the markup. One for the main page load, and then again for the Update Panel load. As noted, the jQuery or even JavaScript page load (on ready) does not trigger when using an update panel, hence the above has additional client code to ensure the jQuery select2() code runs again.
Out code behind is thus this:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
LoadData()
End If
End Sub
Sub LoadData()
Dim rstHotels As DataTable
rstHotels = MyRst("SELECT City FROM tblHotels
WHERE City is not null
GROUP BY City")
DropDownList1.DataSource = rstHotels
DropDownList1.DataBind()
End Sub
Protected Sub Button1_Click(sender As Object, e As EventArgs)
LoadGrid()
End Sub
Sub LoadGrid()
Dim strSQL As String =
"SELECT * FROM tblHotelsA"
Dim strWhere As String = ""
Dim cmdSQL As New SqlCommand()
Dim ParamCount As Integer = 0
Dim sP As String = ""
For Each MyPick As ListItem In DropDownList1.Items
Debug.Print($"Item = {MyPick.Text} selected = {MyPick.Selected}")
If MyPick.Selected Then
If strWhere <> "" Then strWhere &= ","
ParamCount += 1
sP = $"@P{ParamCount}"
strWhere &= sP
cmdSQL.Parameters.Add($"@P{ParamCount}", SqlDbType.NVarChar).Value = MyPick.Text
End If
Next
If strWhere <> "" Then
strSQL &= $" WHERE City IN ({strWhere}) "
End If
strSQL &= " ORDER BY HotelName"
cmdSQL.CommandText = strSQL
Dim dt As DataTable = MyRstP(cmdSQL)
GridView1.DataSource = dt
GridView1.DataBind()
End Sub
In above, while I could use a simple string concatenation for the SQL where clause, it would not be parameter safe. Hence for each selected item, we create a SQL injection safe parameter for each selected item.
The end result is thus this:
Upvotes: 0