Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting hidden input value in Javascript, then accessing it in codebehind

I have been trying to set the value of a hidden input by using Javascript and then access the value from within my C# codebehind. When I run the code that is copied below, the value that is assigned to assignedIDs is "", which I assume is the default value for a hidden input. If I manually set the value in the html tag, then assignedIDs is set to that value.

This behavior suggests to me that the value of the input is being reset (re-rendered?) between the onClientClick and onClick events firing.

I would appreciate any help with the matter. I have spent hours trying to solve what seems like a very simple problem.

html/javascript:

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Admin Page - Manage Tasks</title>
    <script language="javascript" type="text/javascript">
        function PopulateAssignedIDHiddenInput() {
            var source = document.getElementById('assignedLinguistListBox');
            var s = "";
            var count = source.length;
            for (var i = count - 1; i >= 0; i--) {
                var item = source.options[i];
                if (s == "") { s = source.options[i].value; }
                else { s = s.concat(",",source.options[i].value); }
            }
            document.getElementById('assignedIDHiddenInput').Value = s;
            // I have confirmed that, at this point, the value of
            // the hidden input is set properly
        }
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Panel id="EditMode" runat="server">
            <table style="border: none;">
                <tr>
                    <td>
                        <asp:Label ID="availableLinguistLabel" runat="server" Text="Available"></asp:Label><br />
                        <asp:ListBox ID="availableLinguistListBox" runat="server" Rows="10" SelectionMode="Multiple"></asp:ListBox>
                    </td>
                    <td>
                        <input type="button" name="right" value="&gt;&gt;"
                            onclick="Javascript:MoveItem('availableLinguistListBox', 'assignedLinguistListBox');" /><br /><br />
                        <input type="button" name="left" value="&lt;&lt;"
                            onclick="Javascript:MoveItem('assignedLinguistListBox', 'availableLinguistListBox');" />
                    </td>
                    <td>
                        <asp:Label ID="assignedLinguistLabel" runat="server" Text="Assigned To"></asp:Label><br />
                        <asp:ListBox ID="assignedLinguistListBox" runat="server" Rows="10" SelectionMode="Multiple"></asp:ListBox>
                    </td>
                </tr>
            </table>
            //-snip-
            <asp:Button ID="save_task_changes_button" runat="server" ToolTip="Click to save changes to task"
                Text="Save Changes" OnClick="save_task_changes_button_click" OnClientClick="Javascript:PopulateAssignedIDHiddenInput()" />
        </asp:Panel>

        <!-- Hidden Inputs -->
        <!-- Note that I have also tried setting runat="server" with no change -->
        <input id="assignedIDHiddenInput" name="assignedIDHiddenInput" type="hidden" />
    </div>
    </form>
</body>

c#

protected void save_task_changes_button_click(object sender, EventArgs e)
{
    string assignedIDs = Request.Form["assignedIDHiddenInput"];
    // Here, assignedIDs == ""; also, Request.Params["assignedIDHiddenInput"] == ""
    // -snip-
}
like image 872
Siegesmith Avatar asked Apr 21 '10 22:04

Siegesmith


2 Answers

In javascript you need the value property to be lowercase, like this:

document.getElementById('assignedIDHiddenInput').value = s;

Then it will be set properly :) You can see an example in action here

Though if you alert the .Value it will show your value, you've actually added a new .Value property, but you haven't set the input's .value property which is what gets posted to the server. The example link above illustrates this both ways.

Also you can make it a bit faster especially if you have lots of options by using an array instead of string concatenation, like this:

var source = document.getElementById('assignedLinguistListBox');
var opts = [];
for (var i = 0; i < source.options.length; i++) {
    opts.push(source.options[i].value);
}
var s = opts.join(',');

Edit: The above code is updated, CMS is right that the previous method was browser dependent, the above should now behave consistently. Also, if jQuery is an option, there are shorter ways of getting this info still, like this:

var s = $('#assignedLinguistListBox option').map(function() { 
          return this.value; 
        }).get().join(',');
$('#assignedIDHiddenInput').val(s);

You can see a working example of this here

like image 132
Nick Craver Avatar answered Sep 18 '22 01:09

Nick Craver


I'm assuming ASP.NET here.

If so, your problem is the id of the control in the HTML generated by ASP.NET is not going to be "assignedIDHiddenInput" that you reference in the script. ASP.NET changes those before rendering the HTML from what you specify in the HTML page declaratively. Do a view source on the page and you will see what I mean.

Here is a way around that:

document.getElementById('<%=assignedIDHiddenInput.ClientID %>').value = s;

Update: As noted in the comments, this is only relevant if the control is set to RunAt=Server.

like image 21
JohnFx Avatar answered Sep 18 '22 01:09

JohnFx