ASP checkbox 'checked' attribute always returning true - c#

I have several asp:checkboxes on my webform which are filled in on page load, then returned on button submit.
the buttons are always returning the same as the server boolean behind them, no matter whether changed on the client side before being returned. After checking the clientID of the variables, they are exactly the same so it is not down to any hidden IDs or anything like that.
ASPX
<script type="text/javascript">
function slideTable(link) {
$(link).parent().next().toggle()
$(link).find(".navPlus").toggleClass("rotate1");
$(link).find(".navPlus").toggleClass("rotate");
var txt = $(link).parent().next().is(':visible') ? 'Minimise' : 'View all';
$(link).find(".navPlus").text(txt);
};
function boxchange(box) {
//Change has already happened at this point
if ($(box).prop("checked")==true) {
$(box).attr("checked", "checked");
}
else {
$(box).removeAttr("checked");
}
var table = $(box).closest('table');
var allChecked = $('#subjectsTable :checkbox:checked').length == $('#subjectsTable :checkbox').length;
if (allChecked) {
$(table).prev().find(":input").prop("checked", true);
$(table).prev().find(":input").attr("checked", true);
}
else {
$(table).prev().find(":input").prop("checked", false);
$(table).prev().find(":input").attr("checked", false);
}
};
</script>
<div>
<span class="headerSpan" onclick="slideTable(this)" style="clear:both" >
<img class="logo-image" alt="HalsburyLogo" src="../images/siteStyle/logo.png"/>
<span class="navPlus rotate1">View all</span>
</span>
<input onclick="chkHeader_click(this)" style="float:none; display:inline" type="checkbox" id="chkSubjects"/>
</div>
<table id="subjectsTable" class="subscriptionTable">
<tr>
<td style="width: 300px">
<label>Art</label></td>
<td>
<asp:CheckBox onclick="boxchange(this)" ID="chkArt" CssClass="chkSubject" runat="server" /></td>
</tr>
</table>
When a submit button is clicked, the value of chkArt is always the same. - upon checking, the clientID of chkArt on the serverside is also chkArt
edit: in the page load event the following code is present:
chkArt.Checked = //a bool from the database

chkArt.Checked = //a bool from the database
This code is in Page_Load? Unless you're conditionally running this code (which you aren't in the question at least...) then this is being executed every time the page loads. Page_Load is invoked whenever a request is made to a page, postback or otherwise.
So essentially your page is receiving the changed values, but ignoring them and just resetting them to their previous state.
You can conditionally check for postbacks in Page_Load:
if (!IsPostBack)
chkArt.Checked = //a bool from the database
That way the initial state of the CheckBox is set only on the initial load of the page, and not re-set on every postback.

Related

AsyncFileUpload does not fire server side UploadComplete

I have an AsyncFileUpload control inside an update panel in a page that is using a master page.
When I select a file, the client side OnClientUploadComplete fires but not the server side. I searched the issue and tried different suggestions, including adding a hidden button outside update panel and "click" it on client script to force an async postback as well as modifying the "form" tag on master page to include encrypt type but nothing seems to be working.
In aspx file I have:
<script type="text/javascript">
function onClientUploadComplete(sender, e) {debugger
var ct = e.get_contentType();
var fn = e.get_fileName();
var l = e.get_length();
var p = e.get_path();
document.getElementById('uploadCompleteInfo').innerHTML = '';
__doPostBack('upnlNews', '');
}
function onClientUploadStart(sender, e) {
document.getElementById('uploadCompleteInfo').innerHTML = 'Please wait while uploading ' + e._fileName;
}
</script>
<asp:UpdatePanel runat="server" ID="upnlNews">
<ContentTemplate>
<ajaxToolkit:AsyncFileUpload runat="server" ID="fuAttchedDocs"
ThrobberID="myThrobber"
UploaderStyle="Traditional"
OnClientUploadComplete="onClientUploadComplete"
onuploadedcomplete="fuAttchedDocs_UploadedComplete"
onuploadedfileerror="fuAttchedDocs_UploadedFileError" />
<asp:Label runat="server" ID="myThrobber" Style="display: none;">
<img align="middle" alt="" src="../assets/images/6.gif" />
</asp:Label>
<div id="uploadCompleteInfo"></div><br />
</ContentTemplate>
</asp:UpdatePanel>
Additional Info
when I put a breakpoint in client side script and check the variables in Chrome Developer Tool, I see the following:
function onClientUploadComplete(sender, e) {debugger
var ct = e.get_contentType(); ==> ct = ""
var fn = e.get_fileName(); ==> fn = "spock.jpg"
var l = e.get_length(); ==> l = "NaN"
var p = e.get_path(); ==> p = "C:\fakepath\spock.jpg"
document.getElementById('uploadCompleteInfo').innerHTML = '';
__doPostBack('upnlNews', '');
}
The fact that file length shows as NaN is a bit fishy!
I found out that the UI designer had added a Search text box and button combo and had contained them in a <form>...</form> tag; so the page two <form> tags, one contained within the other (main page form tag and this one). This broke the code. I realized that when I found that even a regular button would not fire its OnClick event. After I changed the form tags to div everything worked fine.

How to get next month of selected month?

I have one drop down list of months like 'January' 'February'...'December' in asp.net c#
<asp:DropDownList ID="dlsalmonth" runat="server" class="form-control form-control-solid placeholder-no-fix">
<asp:ListItem>January</asp:ListItem>
<asp:ListItem>February</asp:ListItem>
<asp:ListItem>March</asp:ListItem>
<asp:ListItem>April</asp:ListItem>
<asp:ListItem>May</asp:ListItem>
<asp:ListItem>June</asp:ListItem>
<asp:ListItem>July</asp:ListItem>
<asp:ListItem>August</asp:ListItem>
<asp:ListItem>September</asp:ListItem>
<asp:ListItem>October</asp:ListItem>
<asp:ListItem>November</asp:ListItem>
<asp:ListItem>December</asp:ListItem>
</asp:DropDownList>
<div class="col-md-4" style="margin-top: 2%">
<asp:TextBox ID="txtnextmonth" runat="server" CssClass="form-control" placeholder="Next Month" ReadOnly="true"></asp:TextBox>
</div>
What I want is when I select a Month from this list I want exact next Month in my text box next to it. Let say if I select February from this drop down list then March should be displayed in my text box.
you can try something like this
protected void dlsalmonth_OnSelectedIndexChanged(object sender, EventArgs e)
{
txtnextmonth.Text = dlsalmonth.SelectedItem.Text == "December" ?
dlsalmonth.Items[0].Text :
dlsalmonth.Items[dlsalmonth.SelectedIndex + 1].Text;
}
and also dont forget to add AutoPostBack="True" or it will not go to dlsalmonth_OnSelectedIndexChanged event
You can use SelectedIndexChanged event and in that event use the selectedIndex property to find the next month. You will have to take care of December as the next item will be the first not at next index. You will need to set AutoPostBack property to true to postback on drop down selection change. You will also need to bind the SelectedIndexChanged event.
protected void dlsalmonth_SelectedIndexChanged(object sender, EventArgs e)
{
txtnextmonth.Text = dlsalmonth.Items[(dlsalmonth.SelectedIndex+1)%12].Text;
}
Its could be done on server side as show above but it is recommended to do it on client side to save postback. You can do this with javascript like this.
In HTML, bind the onchange javascript event and pass it dropdownlist object using this.
<asp:DropDownList ID="dlsalmonth" runat="server" onchange="dlsalmonthChange(this);" class="form-control form-control-solid placeholder-no-fix">
In Javascript, put the script tag just before the closing body tag. get the textbox object and assign next element of drop down taking care of December and January.
<script type="text/javascript" language="javascript">
function dlsalmonthChange(sel)
{
document.getElementById("<%= txtnextmonth.ClientID%>").value = sel.options[(sel.selectedIndex+1) % 12].text
}
dlsalmonthChange(document.getElementById("<%= dlsalmonth.ClientID%>")); // to set the textbox on form load
</script>
</body>
I explicitly called the dlsalmonthChange on page load to set the textbox for the first time when page loads.
You could use a client side solution. This will remove the need for an extra PostBack.
<script type="text/javascript">
$("#<%=dlsalmonth.ClientID %>").change(function () {
var index = $(this).prop('selectedIndex') + 1;
var nextValue = $("#<%=dlsalmonth.ClientID %> option").eq(index % 12).val();
$("#<%=txtnextmonth.ClientID %>").val(nextValue);
});
</script>

UpdatePanel triggers not firing

I have problem with UpdatePanel (ASP.Net WebForms, .Net 4.0). Here is code:
<div class="container-fluid">
<form id="form1" runat="server">
<h2>Poruke</h2>
<div class="row">
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true" />
<asp:UpdatePanel ID="msgListUpdatePanel" runat="server" UpdateMode="Conditional" ChildrenAsTriggers="False">
<ContentTemplate>
<div class="col-md-4">
<asp:ListBox ID="msgList" runat="server" OnSelectedIndexChanged="msgList_SelectedIndexChanged" AutoPostBack="true" ClientIDMode="AutoID"></asp:ListBox>
</div>
<div class="col-md-8">
<asp:ListBox ID="conversationList" runat="server" ClientIDMode="AutoID"></asp:ListBox>
<br class="divider" />
<p>
Odgovor: <span>
<asp:TextBox ID="replyTxtbox" runat="server"></asp:TextBox></span>
</p>
<asp:Button ID="sendBtn" runat="server" Text="PoĊĦalji" OnClick="sendBtn_Click" EnableViewState="false" ClientIDMode="AutoID" />
</div>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="msgList" EventName="SelectedIndexChanged"/>
</Triggers>
</asp:UpdatePanel>
</div>
</form>
</div>
and this is codebehind...
int userIdCookie = 0;
message selected = new message();
protected void Page_Load(object sender, EventArgs e)
{
if (!this.Page.User.Identity.IsAuthenticated)
{
FormsAuthentication.RedirectToLoginPage();
}
if (!Page.IsPostBack)
{
if (Int32.TryParse(HttpContext.Current.User.Identity.Name, out userIdCookie))
{
message msg = new message();
var allMsg = msg.allMessagesFormatted().Distinct().ToList();
msgList.DataSource = allMsg;
msgList.DataBind();
}
}
else
{
// test only!
replyTxtbox.Text = msgList.SelectedIndex.ToString();
msgListUpdatePanel.Update();
}
}
protected void msgList_SelectedIndexChanged(object sender, EventArgs e)
{
message msg = new message();
var allMsg = msg.allMessagesFormatted().Distinct().ToList();
msgList.DataSource = allMsg;
IList<message> boundList = (IList<message>)msgList.DataSource;
selected = boundList[msgList.SelectedIndex];
var conversation = msg.allMessagesFormatted().FindAll(x => x.conversationGuid == selected.conversationGuid);
conversationList.DataSource = conversation;
conversationList.DataBind();
}
protected void sendBtn_Click(object sender, EventArgs e)
{
if(selected.recipientId != 0)
{
message newmsg = new message();
newmsg.senderId = userIdCookie;
newmsg.recipientId = selected.recipientId;
newmsg.subject = selected.subject;
newmsg.messageTxt = replyTxtbox.Text;
newmsg.conversationGuid = selected.conversationGuid;
newmsg.time = DateTime.Now;
newmsg.Add();
}
}
msgList gets populated fine but when i change selection, nothing happens - its SelectedIndex event never fires. If I set AutoPostBack="true" to this listbox, it reloads page (which is exactly what I am trying to avoid).
To sum up - when i click on item in ListBox inside UpdatePanel, nothing happens (event isn't fired). I want to avoid page reload when selected index changes. I've tried dozen of solutions (ClientID, AsyncPostBack, "regular" PostBack triggers and I guess i missed one simple detail and it's driving me mad.
Can anyone help?
edit - as #mason pointed out, problem was in overidden message.ToString() method that contained \r\n chars which caused problems in postback.
You will receive a JavaScript error in your browser's console.
Uncaught Sys.WebForms.PageRequestManagerServerErrorException:
Sys.WebForms.PageRequestManagerServerErrorException: Invalid postback
or callback argument. Event validation is enabled using in configuration or <%# Page
EnableEventValidation="true" %> in a page. For security purposes,
this feature verifies that arguments to postback or callback events
originate from the server control that originally rendered them. If
the data is valid and expected, use the
ClientScriptManager.RegisterForEventValidation method in order to
register the postback or callback data for validation.
MsAjaxJs?v=c42ygB2U07n37m_Sfa8ZbLGVu4Rr2gsBo7MvUEnJeZ81:1 Uncaught
Sys.WebForms.PageRequestManagerServerErrorException:
Sys.WebForms.PageRequestManagerServerErrorException: Invalid postback
or callback argument. Event validation is enabled using in configuration or <%# Page
EnableEventValidation="true" %> in a page. For security purposes,
this feature verifies that arguments to postback or callback events
originate from the server control that originally rendered them. If
the data is valid and expected, use the
ClientScriptManager.RegisterForEventValidation method in order to
register the postback or callback data for validation.
You can see a simpler version if you use:
msgList.DataSource = new List<string>(){"A\r\n","B\r\n","C\r\n"};
When you watch it in the browser tab, you'll see POST request sent to the server, but on the server side the Page_Load method won't get hit at all.
The fix is either to not use \r\n characters in the data being used for the ListBox or to follow the directions to register it at ClientScriptManager.RegisterForEventValidation on MSDN.

Storing the data of Html Table while button click event fired

I am stuck in a situation, web site is running in ASP.NET 1.1
I am loading a page with some data. In the page there is a Html Table.
In each row, I am loading status(active/inactive) in one and message in another .
There is a save button when clicked it should save the status and message to database.
Since the data is in Html Table I am loosing the data while button is clicked.
I tried one option of keeping the status and message at page load in a global Javascript variable. But I will loose that also when button is clicked.
JS Code to store the data :
// To store all active or inactive feature values.
var arrType = [];
var interiorValues = [arrType];
var exteriorValues = [];
var mechanicalValues = [];
var standardValues = [];
function StoreChromeVallue()
{
var $jDecode = jQuery.noConflict();
var table = document.getElementById('dlInterior');
for (var i = 1, row; row = table.rows[i]; i++)
{
for (var j = 0, col; col = row.cells[j]; j++)
{
var imagePath = $jDecode(row.cells[0]).find('img:first').attr('src');
if(imagePath == "../icon_active1.gif")
{
arrType.push("active");
}
else if(imagePath == "../icon_deleted1.gif")
{
arrType.push("deleted");
}
else
{
arrType.push("active");
}
var featureValue = $jDecode(row.cells[1]).text();
arrType.push(featureValue);
arrType.push("Interior");
interiorValues.push(arrType);
}
}
alert(interiorValues[5][0]);
}
HTML TABLE WHERE DATA IS STORE
<TABLE id="dlInteriors" Width="300" Runat="server" CellSpacing="0" CellPadding="0">
<TR>
<TD id="interiortd" vAlign="top" width="350" runat="server"></TD>
</TR>
</TABLE>
Rows are dynamically added on page load.
Please guide me how I should go ahead on this.
You cant easily get all the values/strings in your HTML page while postback. You could able to get the form fields like input, select, etc in post back using Request.params[""].
But you could try with hidden variable (here it is your alternative Viewstate for your HTML table string values)
When & What you store / how to store /how to access in post back.
You can try the below steps for above question.
Before submit a form, fire a javascript function 'saveTableValues()'
which loops your HTML table and creates the object (var) for each row.
Prepare a javascript object array (just pushing the item in for each loop)
Convert it into JSON string and assign the whole JSON string
into Hidden Field
Do post back // just return true in JS
In code behind try accessing using Request.Params[""] or
normal way like hdnField.Text if it is server side control
In Code behing use a JavaScript Serializer
or JSON.Net to convert the JSON string into some collection.
Recommending JSON.Net here
This may help you.!
Edit:
As your website is running in 1.1 not sure those serializer dll will help you. So you try in XML format instead of JSON. Not sure JSON serializer dll is exist for 1.1 framework
Create table to run at server like this
<table id="users" runat="server">
and you will be able to access it using HtmlTable class,If required create a DataTable dynamically from the table rows and save that in a session. Have a look at http://msdn.microsoft.com/en-us/li
Use Jquery to get the rows values. Then store the data into hiddenfields. This way:
<script type="text/javascript">
function getTableValues() {
var tds = $('#dlInteriors tr td')
jQuery.each(tds, function () {
var url = $(this).children('img:first').attr('src');
var text = $(this).text();
if (url)
$('#hidValuesStatus').val($('#hidValuesStatus').val() + ',' + url);
if (text)
$('#hidValuesMessages').val($('#hidValuesMessages').val() + ',' + text);
});
}
</script>
Call the javascript function on the event "OnClientClick" of your asp:button
<TABLE id="dlInteriors" Width="300" Runat="server" CellSpacing="0" CellPadding="0">
<TR>
<TD id="interiortd" vAlign="top" width="350" runat="server"><img src="icon_active1.gif" /></TD>
<TD id="TD2" vAlign="top" width="350" runat="server">message1</TD>
</TR>
<TR>
<TD id="TD1" vAlign="top" width="350" runat="server"><img src="icon_deleted1.gif" /></TD>
<TD id="TD3" vAlign="top" width="350" runat="server">message2</TD>
</TR>
</TABLE>
<asp:Button runat="server" ID="btnSubmit" OnClientClick="javascript:getTableValues()" Text="SUBMIT" />
<input type="hidden" id="hidValuesMessages" runat="server" />
<input type="hidden" id="hidValuesStatus" runat="server"/>
And in the code behind get the data from the hidden fields:
Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
If IsPostBack Then
If Not IsNothing(Request.Form("hidValuesMessages")) Then
Dim str As String = Request("hidValuesMessages")
End If
If Not IsNothing(Request.Form("hidValuesStatus")) Then
Dim str2 As String = Request("hidValuesStatus")
End If
End If
End Sub
Split the string and get the final values.
Hope this helps!
Regards.

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=">>"
onclick="Javascript:MoveItem('availableLinguistListBox', 'assignedLinguistListBox');" /><br /><br />
<input type="button" name="left" value="<<"
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-
}
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
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.
I think ASP.NET is calling the javascript to execute a postback on that control before your javascript function is called to populate that hidden value.
I think it's possible to disable the default postback and handle it yourself but I'm sure others can advise better.
Stick an alert() into your function there to see if it is really getting called before post-back is triggered.

Categories