Ayman Ayman - 3 months ago 45
ASP.NET (C#) Question

Issue with passing hiddenfield value

I am trying to pass HiddenField value to WebMethod

GetAutoCompleteData
to enable auto complete in text box based on selected search field.

I have tried pass HiddenField values using code-behind, but it didn't work.

There is no issues with javascript codes.

Note: I have tried to use HiddenField value in another method, and it worked, so I am sure that HiddenField is taking values using JavaScript code.

Code-behind:

public static string hdnvalue { get; set; }
protected void Page_Load(object sender, EventArgs e)
{
hdnvalue = hdnSearchParam.Value;
}

[WebMethod]
public static List<string> GetAutoCompleteData(string value)
{
string hiddenfiedlvalue = hdnvalue;
List<string> result = new List<string>();

string strConnString = ConfigurationManager.ConnectionStrings["ConnString"].ConnectionString;
using (SqlConnection con = new SqlConnection(strConnString))
{
using (SqlCommand cmd = new SqlCommand("select @hiddenfiedlvalue from Users where @hiddenfiedlvalue LIKE '%'+@SearchText+'%'", con))
{
con.Open();
cmd.Parameters.AddWithValue("@SearchText", value);
cmd.Parameters.AddWithValue("@hiddenfiedlvalue", hiddenfiedlvalue);

SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
result.Add(string.Format("{0}", hiddenfiedlvalue));
}
return result;
}
}
}


Code used to pass selected values from drop-down menu to HiddenField:

<script type="text/javascript">
$(document).ready(function (e) {
$('.search-panel .dropdown-menu').find('a').click(function (e) {
e.preventDefault();
var param = $(this).attr("href").replace("#", "");
var concept = $(this).text();
$('.search-panel span#search_concept').text(concept);
$('[id$=hdnSearchParam]').val(param);

});
});
</script>


Auto complete code:

<script type="text/javascript">
$(function () {
SearchText();
});
function SearchText() {
$(".autosuggest").autocomplete({
source: function (request, response) {
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "Default.aspx/GetAutoCompleteData",
data: "{'value':'" + $('#txtSearch').val() + "'}",
dataType: "json",
success: function (data) {
if (data.d.length > 0) {
response($.map(data.d, function (item) {
return {
label: item.split('/')[0],
val: item.split('/')[1]
}
}));
}
else {
response([{ label: 'No Records Found', val: -1 }]);
}
},
error: function (result) {
alert("Error");
}
});
},
});
}
</script>


ASPX:

<asp:HiddenField ID="hdnSearchParam" runat="server" />
<div class="col-xs-8">
<div class="input-group">
<div class="input-group-btn search-panel">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
<span id="search_concept">Filter by</span> <span class="caret"></span>
</button>

<ul class="dropdown-menu" role="menu">
<li><a href="#UserID">User ID</a></li>
<li><a href="#TypeName">User Type</a></li>
<li><a href="#UserName">User Name</a></li>
<li><a href="#FirstName">First Name</a></li>
<li><a href="#LastName">Last Name</a></li>
<li><a href="#Email">Email</a></li>
</ul>


</div>
<input type="hidden" name="search_param" value="all" id="search_param">
<asp:TextBox ID="txtSearch" CssClass="autosuggest form-control" runat="server"></asp:TextBox>

<span class="input-group-btn"></span>
</div>
</div>

Answer

Your page has several issues.

First, why are you using a hidden field for this? Why don't you just pass the dropdown value as a second parameter in the Ajax request?

Second, in your code behind you are reading the hidden value only on page load, and that value is never updated with each Ajax request (Page_Load is not executed again). You made that static trick with hdnvalue just to make it compile, but it won't work. Also, making it static makes it be shared among all web clients using that page!

Third, why are you storing the dropdown value in its href as well? You could use a span or even simple text instead.

Fourth, you are using the server controls markup ID instead of the ClientID, which may be different depending on the .NET framework you are using. Better play safe and use ClientID always.

Fifth, if with jQuery you select by ID, just use the ID, there's no need to use any other class selectors. Of course, you should never have repeated IDs!

Sixth, you can't use parameterized variables as column names. You must use a dynamic query. More info about that here. Also the reader wasn't working properly (only adding the hidden field) and it's better to enclose the ExecuteReader in a using block.

Summarizing, use this:

protected void Page_Load(object sender, EventArgs e)
{
}

[WebMethod]
public static List<string> GetAutoCompleteData(string value, string filterBy)
{
    string strConnString = ConfigurationManager.ConnectionStrings["ConnString"].ConnectionString;
    using (SqlConnection con = new SqlConnection(strConnString))
    {
        con.Open();
        string command = string.Format("select {0} from Users where {0} LIKE '%'+@SearchText+'%'", filterBy);
        using (SqlCommand cmd = new SqlCommand(command, con))
        {
            cmd.Parameters.AddWithValue("@SearchText", value);

            using (SqlDataReader dr = cmd.ExecuteReader())
            {
                List<string> result = new List<string>();
                while (dr.Read())
                {
                    result.Add(dr.GetString(0));
                }
                return result;
            }
        }
    }
}


<script type="text/javascript">
    $(document).ready(function (e) {
        $('.search-panel .dropdown-menu').find('a').click(function (e) {
            e.preventDefault();
            var concept = $(this).text();
            $('#search_concept').text(concept);
        });
    });
</script>

Important: if you are afraid of SQL Injection, you may want to do some validation with filterBy first.

In your Javascript, fix this line only:

 data: "{'value':'" + $('#<%= txtSearch.ClientID %>').val() + "','filterBy':'" + $('#search_concept').text() + "'}",

Finally, just get rid of both hidden fields (user control and html control).