<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>johna's blog</title>
<link>https://johna.compoutpost.com/</link>
<description>...mostly about web development and programming, with a little bit of anything else related to the Internet, computers and technology.</description>
<item>
<title>ASP.NET bug with RadioButton GroupName in Repeater</title>
<link>https://johna.compoutpost.com/blog/1074/asp-net-bug-with-radiobutton-groupname-in-repeater/</link>
<description>I was recently working on an ASP.NET Web Forms project where I needed to create a group of RadioButtons with a Repeater.&lt;br&gt;&lt;br&gt;I rediscovered a bug in ASP.NET that results in each RadioButton having a unique GroupName which means they all operate independently.&lt;br&gt;&lt;br&gt;Of course I attempted to take the easy route of Google-ing the problem and I found many discussions and posts about this issue. I looked at and tried some of the suggested workarounds but didn't like some and others didn't work.&lt;br&gt;&lt;br&gt;Inspired by some JavaScript solutions that simply deselect all other RadioButtons in the same group, I put together the following simple jQuery script to do the same.&lt;br&gt;&lt;br&gt;&lt;pre&gt;$(function(){&lt;br&gt;    $('[name$=&quot;$RadioButton1&quot;]').click(function(){&lt;br&gt;        var clientId=$(this).attr('id');&lt;br&gt;        $('[name$=&quot;$RadioButton1&quot;]').each(function(){&lt;br&gt;            if($(this).attr('id') != clientId){&lt;br&gt;                $(this).prop('checked',false);&lt;br&gt;            }&lt;br&gt;        });&lt;br&gt;    });&lt;br&gt;});&lt;/pre&gt;&lt;br&gt;You need to replace &quot;RadioButton1&quot; with the ID of your RadioButton control in the two places in the script.&lt;br&gt;&lt;br&gt;I added this script in the code-behind file in the Page_PreRender event when it was needed, like this:&lt;br&gt;&lt;br&gt;&lt;pre&gt;Page.ClientScript.RegisterStartupScript(this.GetType(), &quot;RadioButton1&quot;, &quot;$(function(){$('[name$=&quot;$RadioButton1&quot;]').click(function(){var clientId=$(this).attr('id');$('[name$=&quot;$RadioButton1&quot;]').each(function(){if($(this).attr('id')!=clientId){$(this).prop('checked',false);}});});});&quot;, true);&lt;/pre&gt;&lt;br&gt;I know this script could be improved a lot, but as is often the case, as soon as my prototype worked as required I left it as is and moved on to other priorities. No time for optimisation.&lt;br&gt;&lt;br&gt;&lt;img alt=&quot;asp-net-radiobutton-in-repeater-issue.jpg&quot; src=&quot;/blog/uploads/img1074_asp-net-radiobutton-in-repeater-issue.jpg&quot; class=&quot;img-fluid&quot; /&gt;&lt;br&gt;&lt;br&gt;&lt;em&gt;[A Google search shows many people have faced this problem... Wonder why it hasn't been fixed?]&lt;/em&gt;</description>
<comments>https://johna.compoutpost.com/blog/1074/asp-net-bug-with-radiobutton-groupname-in-repeater/#comments</comments>
<pubDate>2019-09-01T12:00:00+10:00</pubDate>
<category>ASP.NET Web Forms</category>
<image>https://johna.compoutpost.com/blog/uploads/img1074_asp-net-radiobutton-in-repeater-issue.jpg</image>
<guid>https://johna.compoutpost.com/blog/1074</guid>
</item>
<item>
<title>More on Bootstrap 4 modals in ASP.NET Web Forms applications using UpdatePanels</title>
<link>https://johna.compoutpost.com/blog/1007/more-on-bootstrap-4-modals-in-asp-net-web-forms-applications-using-updatepanels/</link>
<description>&lt;a href=&quot;/blog/uploads/img1007_asp-net-bootstrap-4-modal.jpg&quot;&gt;&lt;img alt=&quot;ASP.NET Bootstrap 4 Modal&quot; src=&quot;/blog/uploads/img1007_asp-net-bootstrap-4-modal.jpg&quot; class=&quot;img-fluid&quot; /&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;I've now written a couple of posts on the topic of using Bootstrap modals in ASP.NET Web Forms projects, &lt;a href=/blog/778/bootstrap-modals-inside-updatepanels-in-asp-net-web-forms/&gt;one&lt;/a&gt; on using native Bootstrap modal methods with ClientScript and &lt;a href=/blog/832/asp-net-web-forms-and-bootstrap-3-modals/&gt;another&lt;/a&gt; attempting to control them with server-side code only. Both methods had some issues.&lt;br&gt;&lt;br&gt;In this, my third post, I go over the methods I am using now and the problems I have encountered and overcome.&lt;br&gt;&lt;br&gt;The previous server-side method was ideal, but I couldn't get around some issues, so I now believe the best method is to use the native JavaScript methods to hide and show the modals.&lt;br&gt;&lt;br&gt;Here's some sample code for how I do this now:&lt;br&gt;&lt;br&gt;&lt;pre&gt;&amp;lt;asp:UpdatePanel ID=&quot;UpdatePanel1&quot; runat=&quot;server&quot; UpdateMode=&quot;Conditional&quot;&amp;gt;&lt;br&gt;	&amp;lt;ContentTemplate&amp;gt;&lt;br&gt;		&amp;lt;asp:Button ID=&quot;Button1&quot; runat=&quot;server&quot; CssClass=&quot;btn btn-primary&quot; OnClick=&quot;Button1_Click&quot; Text=&quot;Show Modal&quot; /&amp;gt;&lt;br&gt;	&amp;lt;/ContentTemplate&amp;gt;&lt;br&gt;&amp;lt;/asp:UpdatePanel&amp;gt;&lt;br&gt;&lt;br&gt;&amp;lt;asp:Panel ID=&quot;Modal1&quot; runat=&quot;server&quot; CssClass=&quot;modal&quot; data-backdrop=&quot;static&quot; tabindex=&quot;-1&quot; role=&quot;dialog&quot;&amp;gt;&lt;br&gt;	&amp;lt;div class=&quot;modal-dialog&quot; role=&quot;document&quot;&amp;gt;&lt;br&gt;		&amp;lt;div class=&quot;modal-content&quot;&amp;gt;&lt;br&gt;			&amp;lt;div class=&quot;modal-header&quot;&amp;gt;&lt;br&gt;				&amp;lt;h5 class=&quot;modal-title&quot;&amp;gt;Sample Modal&amp;lt;/h5&amp;gt;&lt;br&gt;			&amp;lt;/div&amp;gt;&lt;br&gt;			&amp;lt;div class=&quot;modal-body&quot;&amp;gt;&lt;br&gt;				Sample modal content.&lt;br&gt;			&amp;lt;/div&amp;gt;&lt;br&gt;			&amp;lt;div class=&quot;modal-footer&quot;&amp;gt;&lt;br&gt;				&amp;lt;asp:UpdatePanel ID=&quot;UpdatePanel2&quot; runat=&quot;server&quot; UpdateMode=&quot;Conditional&quot;&amp;gt;&lt;br&gt;					&amp;lt;ContentTemplate&amp;gt;&lt;br&gt;						&amp;lt;asp:Button ID=&quot;Button2&quot; runat=&quot;server&quot; CssClass=&quot;btn btn-primary&quot; OnClick=&quot;Button2_Click&quot; Text=&quot;Continue&quot; /&amp;gt;&lt;br&gt;					&amp;lt;/ContentTemplate&amp;gt;&lt;br&gt;				&amp;lt;/asp:UpdatePanel&amp;gt;&lt;br&gt;			&amp;lt;/div&amp;gt;&lt;br&gt;		&amp;lt;/div&amp;gt;&lt;br&gt;	&amp;lt;/div&amp;gt;&lt;br&gt;&amp;lt;/asp:Panel&amp;gt;&lt;/pre&gt;&lt;br&gt;&lt;br&gt;&lt;pre&gt;protected void Button1_Click(object sender, EventArgs e)&lt;br&gt;{&lt;br&gt;	ScriptManager.RegisterStartupScript(UpdatePanel1, UpdatePanel1.GetType(), &quot;Modal1_show&quot;, &quot;$(function(){$('#&quot; + Modal1.ClientID + &quot;').modal('show');});&quot;, true);&lt;br&gt;}&lt;br&gt;&lt;br&gt;protected void Button2_Click(object sender, EventArgs e)&lt;br&gt;{&lt;br&gt;	ScriptManager.RegisterStartupScript(UpdatePanel2, UpdatePanel2.GetType(), &quot;Modal1_hide&quot;, &quot;$(function(){$('#&quot; + Modal1.ClientID + &quot;').modal('hide');});&quot;, true);&lt;br&gt;}&lt;/pre&gt;&lt;br&gt;&lt;br&gt;It is important that any controls inside the modal that cause a postback are contained in an UpdatePanel &lt;b&gt;inside&lt;/b&gt; the modal. Remember that UpdatePanel contents are recreated on partial postback, and if this happens the modal gets destroyed and can no longer be controlled so you must not update the UpdatePanel that wraps the modal itself. This will leave the page with no modal but still with the grey backdrop making the page unusable.&lt;br&gt;&lt;br&gt;In my example, I have an UpdatePanel wrapped around Button2 which is used to close the modal.&lt;br&gt;&lt;br&gt;What if you want some other part of the page to update based on an action inside the modal or when the modal is closed? You need to have an UpdatePanel wrapping the other content you want to update and in your server-side code you must manually force an update to both (or more) UpdatePanels.&lt;br&gt;&lt;br&gt;Let's change the above code so that when the modal is clicked it updates a Label control in another UpdatePanel:&lt;br&gt;&lt;br&gt;&lt;pre&gt;&amp;lt;asp:UpdatePanel ID=&quot;UpdatePanel3&quot; runat=&quot;server&quot; UpdateMode=&quot;Conditional&quot;&amp;gt;&lt;br&gt;	&amp;lt;ContentTemplate&amp;gt;&lt;br&gt;		&amp;lt;div&amp;gt;&lt;br&gt;			&amp;lt;asp:Label ID=&quot;Label1&quot; runat=&quot;server&quot; Text=&quot;&quot;&amp;gt;&amp;lt;/asp:Label&amp;gt;&lt;br&gt;		&amp;lt;div&amp;gt;&lt;br&gt;	&amp;lt;/ContentTemplate&amp;gt;&lt;br&gt;&amp;lt;/asp:UpdatePanel&amp;gt;&lt;/pre&gt;&lt;br&gt;&lt;br&gt;&lt;pre&gt;protected void Button2_Click(object sender, EventArgs e)&lt;br&gt;{&lt;br&gt;	Label1.Text += &quot;Modal closed. &quot;;&lt;br&gt;&lt;br&gt;	ScriptManager.RegisterStartupScript(UpdatePanel2, UpdatePanel2.GetType(), &quot;Modal1_hide&quot;, &quot;$(function(){$('#&quot; + Modal1.ClientID + &quot;').modal('hide');});&quot;, true);&lt;br&gt;&lt;br&gt;	UpdatePanel2.Update();&lt;br&gt;	UpdatePanel3.Update();&lt;br&gt;}&lt;/pre&gt;&lt;br&gt;&lt;br&gt;Note that this applies to both Bootstrap v3.x and v4.x.</description>
<comments>https://johna.compoutpost.com/blog/1007/more-on-bootstrap-4-modals-in-asp-net-web-forms-applications-using-updatepanels/#comments</comments>
<pubDate>2019-04-09T12:00:00+10:00</pubDate>
<category>ASP.NET Web Forms</category>
<category>Bootstrap</category>
<image>https://johna.compoutpost.com/blog/uploads/img1007_asp-net-bootstrap-4-modal.jpg</image>
<guid>https://johna.compoutpost.com/blog/1007</guid>
</item>
<item>
<title>Custom error pages for ASP.NET Web Forms and Classic ASP in IIS 7 and 8.5</title>
<link>https://johna.compoutpost.com/blog/1003/custom-error-pages-for-asp-net-web-forms-and-classic-asp-in-iis-7-and-8-5/</link>
<description>I was recently doing some work on a website which has a mixture of older Classic ASP pages and ASP.NET Web Forms pages. The website is running on IIS 8.5 and .NET framework 4.x.&lt;br&gt;&lt;br&gt;The website has some code that sent email notifications of any Classic ASP server errors, but nothing for .NET errors. It also has custom 404 and 500 error pages for Classic ASP but nothing for ASP.NET.&lt;br&gt;&lt;br&gt;I attempted to create some custom error pages and email notification for .NET but ran into some troubles along the way.&lt;br&gt;&lt;br&gt;Here's what you need to do and some of the things that can go wrong.&lt;br&gt;&lt;br&gt;&lt;b&gt;httpErrors element&lt;/b&gt;&lt;br&gt;&lt;br&gt;This is under system.webServer in the web.config file and is used for non-aspx pages.&lt;br&gt;&lt;br&gt;Here you can set your custom 404 page not found errors for Classic ASP and other non-aspx pages, like images or folders.&lt;br&gt;&lt;br&gt;You can also set your custom error pages for 500 internal server errors.&lt;br&gt;&lt;br&gt;My Classic ASP error email notification code is in the custom 500 error page (coded in Classic ASP of course). One problem I came across here was that Server.GetLastError was not reporting any error. I found that you must specify the 100 subStatusCode of the 500 error here to get the details of the error with Server.GetLastError.&lt;br&gt;&lt;br&gt;Here's a sample of this section from my working web.config:&lt;br&gt;&lt;br&gt;&lt;pre&gt;&amp;lt;system.webServer&amp;gt;&lt;br&gt;	&amp;lt;httpErrors errorMode=&quot;Custom&quot;&amp;gt;&lt;br&gt;		&amp;lt;remove statusCode=&quot;404&quot; subStatusCode=&quot;-1&quot; /&amp;gt;&lt;br&gt;		&amp;lt;error statusCode=&quot;404&quot; prefixLanguageFilePath=&quot;&quot; path=&quot;/_Error404.aspx&quot; responseMode=&quot;ExecuteURL&quot; /&amp;gt;&lt;br&gt;		&amp;lt;remove statusCode=&quot;500&quot; subStatusCode=&quot;100&quot; /&amp;gt;&lt;br&gt;		&amp;lt;error statusCode=&quot;500&quot; subStatusCode=&quot;100&quot; prefixLanguageFilePath=&quot;&quot; path=&quot;/_Error500.asp&quot; responseMode=&quot;ExecuteURL&quot; /&amp;gt;&lt;br&gt;	&amp;lt;/httpErrors&amp;gt;&lt;br&gt;&amp;lt;/system.webServer&amp;gt;&lt;/pre&gt;&lt;br&gt;&lt;br&gt;Note that I use an aspx page for my custom 404 error page so I only need one for all 404 errors, but I have a asp page for my custom 500 error page so I can send email notifications.&lt;br&gt;&lt;br&gt;&lt;b&gt;customErrors element&lt;/b&gt;&lt;br&gt;&lt;br&gt;This is under system.web in the web.config and is used for aspx pages.&lt;br&gt;&lt;br&gt;Here's a sample from my working web.config:&lt;br&gt;&lt;br&gt;&lt;pre&gt;&amp;lt;system.web&amp;gt;&lt;br&gt;	&amp;lt;customErrors mode=&quot;On&quot; redirectMode=&quot;ResponseRewrite&quot;&amp;gt;&lt;br&gt;		&amp;lt;error statusCode=&quot;404&quot; redirect=&quot;/_Error404.aspx&quot; /&amp;gt;&lt;br&gt;	&amp;lt;/customErrors&amp;gt;&lt;br&gt;&amp;lt;/system.web&amp;gt;&lt;/pre&gt;&lt;br&gt;&lt;br&gt;Note that I only trap for 404 errors for aspx page requests here.&lt;br&gt;&lt;br&gt;Setting the redirectMode to ResponseRewrite means that the user does not get redirected to the custom error pages. However, one problem that I ran into with this setting is that my aspx custom 404 error page didn't show, I just saw an application error. The problem is that Session is not available if you use ResponseRewrite so you must not attempt to access the Session object in your custom error page.&lt;br&gt;&lt;br&gt;&lt;b&gt;Trapping 500 internal server errors for aspx pages&lt;/b&gt;&lt;br&gt;&lt;br&gt;You could trap these errors also in the customErrors element but I chose to do this instead in the global.asax page.&lt;br&gt;&lt;br&gt;I send my email error notification then use Server.Transfer to show the custom 500 error page, like this:&lt;br&gt;&lt;br&gt;&lt;pre&gt;void Application_Error(object sender, EventArgs e)&lt;br&gt;{&lt;br&gt;	//error notification code here&lt;br&gt;&lt;br&gt;	Server.Transfer(&quot;/_Error500.aspx&quot;);&lt;br&gt;}&lt;/pre&gt;&lt;br&gt;&lt;br&gt;&lt;b&gt;Notes about custom 500 error pages&lt;/b&gt;&lt;br&gt;&lt;br&gt;It should be obvious but your custom 500 error pages should not include any code that might cause an error itself, or at least it should be handled properly.&lt;br&gt;&lt;br&gt;For this reason I generally use a very simple custom 500 error page with no database calls. I don't use my website's MasterPage as that usually has code for things like logged-in user, or shopping cart lookups that might result in errors.&lt;br&gt;&lt;br&gt;If you're sending email notifications it's also a good idea to handle mail sending errors in case your mail server is down. That way the user still sees your friendly error message.&lt;br&gt;&lt;br&gt;Custom 404 errors don't have this problem (except for the abovementioned Session object issue) so can be rich in content and have full functionality. In fact it's good practice to make your custom 404 error pages as helpful as possible: attempt to offer an alternate page that you think matches the user's original request; briefly explain what your website is all about; and, offer a next relevant step for the user so that hopefully they don't leave your site.</description>
<comments>https://johna.compoutpost.com/blog/1003/custom-error-pages-for-asp-net-web-forms-and-classic-asp-in-iis-7-and-8-5/#comments</comments>
<pubDate>2019-02-20T12:00:00+10:00</pubDate>
<category>ASP.NET Web Forms</category>
<category>Classic ASP</category>
<guid>https://johna.compoutpost.com/blog/1003</guid>
</item>
<item>
<title>Nicer localised UpdateProgress&#8217; for your ASP.NET pages with multiple UpdatePanels</title>
<link>https://johna.compoutpost.com/blog/914/nicer-localised-updateprogress-for-your-asp-net-pages-with-multiple-updatepanels/</link>
<description>&lt;img alt=&quot;Nicer localised UpdateProgress&#226;&#8364;&#8482; for your ASP.NET p&quot; src=&quot;/blog/uploads/img914_asp-net-update-progress.jpg&quot; class=&quot;img-fluid&quot; /&gt;&lt;br&gt;&lt;br&gt;On an ASP.NET Web Forms page with multiple UpdatePanels it&#8217;s nice to give the user some feedback when one of the panels is being updated, so they know to wait and can also not change any form values in that panel during the update.&lt;br&gt;&lt;br&gt;In my example screen capture on this page, you can see that the delivery address is being updated and it is greyed out, yet other parts of the page are unaffected.&lt;br&gt;&lt;br&gt;This is easy to accomplish using an UpdateProgress for each UpdatePanel and some CSS.&lt;br&gt;&lt;br&gt;&lt;h2&gt;Mark up&lt;/h2&gt;Inside each UpdatePanel we need to add an outer DIV (required so that inner elements can be positioned relatively), and then an UpdateProgress with a DIV that is used to block input and create the effect of the area being greyed out.&lt;br&gt;&lt;br&gt;Optionally we can add an AJAX loader animated GIF to show the user something is going on. This requires a second DIV inside the UpdateProgress.&lt;br&gt;&lt;br&gt;&lt;pre&gt;&amp;lt;asp:UpdatePanel ID=&quot;UpdatePanel1&quot; runat=&quot;server&quot; UpdateMode=&quot;Conditional&quot;&amp;gt;&lt;br&gt;	&amp;lt;ContentTemplate&amp;gt;&lt;br&gt;		&amp;lt;div class=&quot;update-panel&quot;&amp;gt;&lt;br&gt;			&amp;lt;asp:UpdateProgress ID=&quot;UpdateProgress1&quot; runat=&quot;server&quot; AssociatedUpdatePanelID=&quot;UpdatePanel1&quot; DisplayAfter=&quot;0&quot;&amp;gt;&lt;br&gt;				&amp;lt;ProgressTemplate&amp;gt;&lt;br&gt;					&amp;lt;div class=&quot;update-progress-gif&quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br&gt;					&amp;lt;div class=&quot;update-progress&quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br&gt;				&amp;lt;/ProgressTemplate&amp;gt;&lt;br&gt;			&amp;lt;/asp:UpdateProgress&amp;gt;&lt;br&gt;&lt;br&gt;			&amp;lt;!--- your content here ---&amp;gt;&lt;br&gt;&lt;br&gt;		&amp;lt;/div&amp;gt;&lt;br&gt;	&amp;lt;/ContentTemplate&amp;gt;&lt;br&gt;&amp;lt;/asp:UpdatePanel&amp;gt;&lt;/pre&gt;&lt;br&gt;&lt;br&gt;&lt;h2&gt;CSS&lt;/h2&gt;The CSS for &#8220;update-progress-gif&#8221; is only required if adding a AJAX loader image, and the URL would need to be adjusted based on the image file name and location.&lt;br&gt;&lt;br&gt;I like the free AJAX loader images at &lt;a href=&quot;http://www.ajaxload.info/&quot; target=&#8221;_blank&#8221;&gt;www.ajaxload.info&lt;/a&gt;.&lt;br&gt;&lt;br&gt;&lt;pre&gt;.update-panel {&lt;br&gt;	position: relative;&lt;br&gt;}&lt;br&gt;&lt;br&gt;.update-progress {&lt;br&gt;	background: #fff;&lt;br&gt;	height: 100%;&lt;br&gt;	left: 0;&lt;br&gt;	position: absolute;&lt;br&gt;	top: 0;&lt;br&gt;	width: 100%;&lt;br&gt;	opacity: .8;&lt;br&gt;	filter: alpha(opacity=80);&lt;br&gt;	zoom:1;&lt;br&gt;	z-index:9998;&lt;br&gt;}&lt;br&gt;&lt;br&gt;.update-progress-gif {&lt;br&gt;	background: url(/images/ajax-loader.gif) top left no-repeat;&lt;br&gt;	position: absolute;&lt;br&gt;	top: 50%;&lt;br&gt;	width: 50%;&lt;br&gt;	left: 50%;&lt;br&gt;	height: 50%;&lt;br&gt;	z-index:9999;&lt;br&gt;}&lt;/pre&gt;&lt;br&gt;&lt;br&gt;Note that if you have nested UpdatePanels then you should include the UpdateProgress only on the outer UpdatePanel otherwise you will get multiple UpdateProgress controls appearing simultaneously.</description>
<comments>https://johna.compoutpost.com/blog/914/nicer-localised-updateprogress-for-your-asp-net-pages-with-multiple-updatepanels/#comments</comments>
<pubDate>2018-02-09T12:00:00+10:00</pubDate>
<category>ASP.NET Web Forms</category>
<image>https://johna.compoutpost.com/blog/uploads/img914_asp-net-update-progress.jpg</image>
<guid>https://johna.compoutpost.com/blog/914</guid>
</item>
<item>
<title>ASP.NET Web Forms and Bootstrap 3 and 4 Modals</title>
<link>https://johna.compoutpost.com/blog/832/asp-net-web-forms-and-bootstrap-3-modals/</link>
<description>&lt;img alt=&quot;ASP.NET and Bootstrap 4 Modals&quot; src=&quot;/blog/uploads/img832_asp-net-bootstrap-4-modal.jpg&quot; class=&quot;img-fluid&quot; /&gt;&lt;br&gt;&lt;br&gt;&lt;strong&gt;Update: this technique including CSS works without any changes for Bootstrap 4.0 too!&lt;/strong&gt;&lt;br&gt;&lt;br&gt;There are a few methods for hiding and showing Bootstrap 3.x modals in an ASP.NET Web Forms application, including a client script method I mentioned in a &lt;a href=&quot;/blog/778/bootstrap-modals-inside-updatepanels-in-asp-net-web-forms/&quot;&gt;previous post&lt;/a&gt;.&lt;br&gt;&lt;br&gt;This technique is pure ASP.NET (requires no client script) and allows you to show and hide modals by changing the Visible property of a containing PlaceHolder or Panel.&lt;br&gt;&lt;br&gt;The advantage over this method over using client script and the native Bootstrap methods is that the modal will not be affected by full or partial postbacks and will be fully controlled by server-side ASP.NET.&lt;br&gt;&lt;br&gt;A few new CSS classes are needed for this method:&lt;br&gt;&lt;br&gt;&lt;pre&gt;.modal-static-backdrop {&lt;br&gt;	-ms-filter:&quot;progid:DXImageTransform.Microsoft.Alpha(Opacity=50)&quot;;&lt;br&gt;	filter: alpha(opacity=50);&lt;br&gt;	-moz-opacity:0.5;&lt;br&gt;	-khtml-opacity: 0.5;&lt;br&gt;	opacity: 0.5;&lt;br&gt;	background:#000;&lt;br&gt;	height:100%;&lt;br&gt;	left:0;&lt;br&gt;	position:fixed;&lt;br&gt;	top:0;&lt;br&gt;	width:100%;&lt;br&gt;	z-index:2000;&lt;br&gt;}&lt;br&gt;&lt;br&gt;.modal-static {&lt;br&gt;	bottom: auto;&lt;br&gt;	display:block !important;&lt;br&gt;	position:absolute;&lt;br&gt;	z-index:2001;&lt;br&gt;}&lt;/pre&gt;&lt;br&gt;The Bootstrap modal itself needs a few tweaks:&lt;br&gt;&lt;br&gt;&lt;pre&gt;&amp;lt;asp:PlaceHolder ID=&quot;ModalPlaceHolder&quot; runat=&quot;server&quot; Visible=&quot;false&quot;&amp;gt;&lt;br&gt;	&amp;lt;div class=&quot;modal-static-backdrop&quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br&gt;	&amp;lt;div class=&quot;modal modal-static&quot;&amp;gt;&lt;br&gt;		&amp;lt;div class=&quot;modal-dialog&quot;&amp;gt;&lt;br&gt;			&amp;lt;div class=&quot;modal-content&quot;&amp;gt;&lt;br&gt;				&amp;lt;div class=&quot;modal-header&quot;&amp;gt;&lt;br&gt;					&amp;lt;asp:LinkButton ID=&quot;btnModalCloseHeader&quot; runat=&quot;server&quot; CssClass=&quot;close&quot; OnClick=&quot;btnModalClose_Click&quot;&amp;gt;&amp;lt;span aria-hidden=&quot;true&quot;&amp;gt;&amp;times;&amp;lt;/span&amp;gt;&amp;lt;/asp:LinkButton&amp;gt;&lt;br&gt;					&amp;lt;h4 class=&quot;modal-title&quot;&amp;gt;Sample Modal&amp;lt;/h4&amp;gt;&lt;br&gt;				&amp;lt;/div&amp;gt;&lt;br&gt;				&amp;lt;div class=&quot;modal-body&quot;&amp;gt;&lt;br&gt;					&amp;lt;p&amp;gt;My modal content&amp;lt;/p&amp;gt;&lt;br&gt;				&amp;lt;/div&amp;gt;&lt;br&gt;				&amp;lt;div class=&quot;modal-footer&quot;&amp;gt;&lt;br&gt;					&amp;lt;asp:LinkButton ID=&quot;btnModalCloseFooter&quot; runat=&quot;server&quot; CssClass=&quot;btn btn-primary&quot; OnClick=&quot;btnModalClose_Click&quot; Text=&quot;Close&quot;&amp;gt;&amp;lt;/asp:LinkButton&amp;gt;&lt;br&gt;				&amp;lt;/div&amp;gt;&lt;br&gt;			&amp;lt;/div&amp;gt;&lt;br&gt;		&amp;lt;/div&amp;gt;&lt;br&gt;	&amp;lt;/div&amp;gt;&lt;br&gt;&amp;lt;/asp:PlaceHolder&amp;gt;&lt;/pre&gt;&lt;br&gt;Then to control showing and hiding of the modal you can just set the Visible property of the placeholder, eg:&lt;br&gt;&lt;br&gt;&lt;pre&gt;ModalPlaceHolder.Visible = true; //or false to hide it&lt;/pre&gt;&lt;br&gt;In my example above, the modal is closed using either of the buttons in the header and footer which reference a btnModalClose_Click event which simply sets the PlaceHolder's Visible property to false.&lt;br&gt;&lt;br&gt;Note that you should not use any of Bootstrap's own decoration of elements, eg. data-dismiss=&quot;modal&quot; otherwise you could lose server-side control of the modal.&lt;br&gt;&lt;br&gt;Also note that the modal should be positioned outside of any element that has a CSS 'position' set, otherwise the modal will appear relative to that element. It is best to move your modals out to just within the BODY CSS element.&lt;br&gt;&lt;br&gt;Put the PlaceHolder (or whatever containing control you use) inside an UpdatePanel and the modal will show and hide without a full postback.&lt;br&gt;&lt;br&gt;&lt;b&gt;Update:&lt;/b&gt; Be aware that the modal will always display at the top of the page, but the user may be scrolled further down the page. You should take steps to scroll to the top of the page when showing a modal.&lt;br&gt;&lt;br&gt;If the modal is inside an UpdatePanel then you can use something like the following code when showing your modal.&lt;br&gt;&lt;br&gt;&lt;pre&gt;ScriptManager.RegisterStartupScript(UpdatePanel1, UpdatePanel1.GetType(), &quot;UpdatePanel1StartupScript&quot;, &quot;setTimeout('window.scrollTo(0,0)', 0);&quot;, true);&lt;/pre&gt;</description>
<comments>https://johna.compoutpost.com/blog/832/asp-net-web-forms-and-bootstrap-3-modals/#comments</comments>
<pubDate>2017-07-06T12:00:00+10:00</pubDate>
<category>Bootstrap</category>
<category>ASP.NET Web Forms</category>
<image>https://johna.compoutpost.com/blog/uploads/img832_asp-net-bootstrap-4-modal.jpg</image>
<guid>https://johna.compoutpost.com/blog/832</guid>
</item>
<item>
<title>Disable common UpdateProgress controls for an UpdatePanel with an associated UpdateProgress</title>
<link>https://johna.compoutpost.com/blog/827/disable-common-updateprogress-controls-for-an-updatepanel-with-an-associated-updateprogress/</link>
<description>If you have an ASP.NET Web Forms page with multiple UpdatePanels and multiple UpdateProgress controls, sometimes you may want one or more UpdateProgress controls associated with a specific UpdatePanel, and one or more UpdateProgress controls that have no association with an UpdatePanel so are shown when any UpdatePanel is updated.&lt;br&gt;&lt;br&gt;However, to me it makes sense that if an UpdatePanel has an associated UpdateProgress control, then any other UpdateProgress controls should not be displayed.&lt;br&gt;&lt;br&gt;Unfortunately this is not how it works in ASP.NET. All unassociated UpdateProgress controls will be displayed, even if there is an associated UpdateProgress.&lt;br&gt;&lt;br&gt;If you want to override how it works by default, and instead not display UpdateProgress controls if an UpdateProgress control exists that is associated with the UpdatePanel that triggered the update, then the following client-side script can be used.&lt;br&gt;&lt;br&gt;The script should be placed or included after the ASP.NET ScriptResource.axd files are included. It's safe to place or include this script after the closing ASP.NET &lt;/form&gt; tag.&lt;br&gt;&lt;br&gt;Note that this script will not function if a partial post back is triggered by a control outside of any UpdatePanel. You could modify the script to accommodate this if needed.&lt;br&gt;&lt;br&gt;&lt;pre&gt; &amp;lt;script type=&quot;text/javascript&quot;&amp;gt;&lt;br&gt;&lt;br&gt;	//array of original values&lt;br&gt;	var updateProgressDefaults = [];&lt;br&gt;&lt;br&gt;	Sys.Application.add_init(appl_init);&lt;br&gt;&lt;br&gt;	function appl_init() {&lt;br&gt;&lt;br&gt;	 	var c = Sys.Application.getComponents();&lt;br&gt;	 	for (var i = 0; i &lt; c.length; i++) {&lt;br&gt;	 		if (Object.getType(c[i]).getName() == &quot;Sys.UI._UpdateProgress&quot; &amp;&amp; !c[i]._associatedUpdatePanelId) {&lt;br&gt;	 			updateProgressDefaults[c[i].get_id()] = c[i]._associatedUpdatePanelId;&lt;br&gt;	 		};&lt;br&gt;	 	}&lt;br&gt;&lt;br&gt;	 	var pgRegMgr = Sys.WebForms.PageRequestManager.getInstance();&lt;br&gt;	 	pgRegMgr.add_initializeRequest(BeginHandler);&lt;br&gt;	 	pgRegMgr.add_endRequest(EndHandler);&lt;br&gt;	}&lt;br&gt;&lt;br&gt;	function BeginHandler(sender, args) {&lt;br&gt;		//There is no _updatePanelsToUpdate if a trigger is outside of an UpdatePanel&lt;br&gt;		if (!args._updatePanelsToUpdate) return;&lt;br&gt;&lt;br&gt;		//Check if the affected UpdatePanel has an associated UpdateProgress control&lt;br&gt;		var hasUpdateProgress = false;&lt;br&gt;&lt;br&gt;	 	var c = Sys.Application.getComponents();&lt;br&gt;	 	for (var i = 0; i &lt; args._updatePanelsToUpdate.length; i++) {&lt;br&gt;	 		for (var j = 0; j &lt; c.length; j++) {&lt;br&gt;	 			if (Object.getType(c[j]).getName() == &quot;Sys.UI._UpdateProgress&quot; &amp;&amp; args._updatePanelsToUpdate[i].replace(/$/g, &quot;_&quot;) == c[j]._associatedUpdatePanelId) {&lt;br&gt;	 				hasUpdateProgress = true;&lt;br&gt;	 				break;&lt;br&gt;	 			}&lt;br&gt;	 		}&lt;br&gt;&lt;br&gt;	 		if (hasUpdateProgress) break;&lt;br&gt;	 	}&lt;br&gt;&lt;br&gt;		//If the UpdatePanel has an associated UpdateProgress control then set all the UpdateProgress controls without associated UpdatePanels to a non-existant UpdatePanel&lt;br&gt;	 	if (hasUpdateProgress) {&lt;br&gt;	 		for (var i = 0; i &lt; c.length; i++) {&lt;br&gt;	 			var id = c[i].get_id();&lt;br&gt;	 			var type = Object.getType(c[i]).getName();&lt;br&gt;	 			if (type == &quot;Sys.UI._UpdateProgress&quot; &amp;&amp; !c[i]._associatedUpdatePanelId) {&lt;br&gt;	 				c[i]._associatedUpdatePanelId = &quot;NullUpdateProgress&quot;;&lt;br&gt;	 			};&lt;br&gt;&lt;br&gt;	 		}&lt;br&gt;	 	}&lt;br&gt;	}&lt;br&gt;&lt;br&gt;	//Restores AssociatedUpdatePanelId for all UpdateProgress controls&lt;br&gt;	function EndHandler() {&lt;br&gt;	 	for (var key in updateProgressDefaults) {&lt;br&gt;	 		$get(key).control._associatedUpdatePanelId = updateProgressDefaults[key];&lt;br&gt;	 	}&lt;br&gt;	}&lt;br&gt;&amp;lt;/script&amp;gt;&lt;/pre&gt;&lt;br&gt;</description>
<comments>https://johna.compoutpost.com/blog/827/disable-common-updateprogress-controls-for-an-updatepanel-with-an-associated-updateprogress/#comments</comments>
<pubDate>2017-04-12T12:00:00+10:00</pubDate>
<category>ASP.NET Web Forms</category>
<guid>https://johna.compoutpost.com/blog/827</guid>
</item>
<item>
<title>Bootstrap checkbox-inline and radio-inline with ASP.NET CheckBoxList and RadioButtonList controls</title>
<link>https://johna.compoutpost.com/blog/809/bootstrap-checkbox-inline-and-radio-inline-with-asp-net-checkboxlist-and-radiobuttonlist-controls/</link>
<description>&lt;b&gt;Update: This applies to Bootstrap 3. See update at end for Bootstrap 4.&lt;/b&gt;&lt;br&gt;&lt;br&gt;Although you can easily create inline checkboxes and radio buttons using ASP.NET CheckBoxes and RadioButtons using Bootstrap's checkbox-inline and radio-inline classes, it's not so easy with ASP.NET CheckBoxList and RadioButtonList controls.&lt;br&gt;&lt;br&gt;There's probably several ways of emulating the Bootstrap inline styling using these ASP.NET controls, this is how I have been doing it.&lt;br&gt;&lt;br&gt;Additional CSS classes:&lt;br&gt;&lt;br&gt;&lt;pre&gt;.checkboxlist-inline li, .radiobuttonlist-inline li&lt;br&gt;{&lt;br&gt;	display:inline-block;&lt;br&gt;}&lt;br&gt;&lt;br&gt;.checkboxlist-inline, .radiobuttonlist-inline&lt;br&gt;{&lt;br&gt;	margin-left: 20px;&lt;br&gt;}&lt;br&gt;&lt;br&gt;.checkboxlist-inline label, .radiobuttonlist-inline label&lt;br&gt;{&lt;br&gt;	padding-left:0;&lt;br&gt;	padding-right:30px;&lt;br&gt;}&lt;/pre&gt;&lt;br&gt;&lt;br&gt;Then your ASP.NET controls will need some CSS classes applied, and some special attributes:&lt;br&gt;&lt;br&gt;&lt;pre&gt;&amp;lt;asp:CheckBoxList ID=&quot;CheckBoxList1&quot; runat=&quot;server&quot; CssClass=&quot;list-unstyled checkbox checkboxlist-inline&quot; RepeatDirection=&quot;Vertical&quot; RepeatLayout=&quot;UnorderedList&quot;&amp;gt;&amp;lt;/asp:CheckBoxList&amp;gt;&lt;br&gt;&lt;br&gt;&amp;lt;asp:RadioButtonList ID=&quot;RadioButtonList1&quot; runat=&quot;server&quot; CssClass=&quot;list-unstyled radio radiobuttonlist-inline&quot; RepeatDirection=&quot;Vertical&quot; RepeatLayout=&quot;UnorderedList&quot;&amp;gt;&amp;lt;/asp:RadioButtonList&amp;gt;&lt;/pre&gt;&lt;br&gt;&lt;br&gt;As you can see, I use the UnorderdedList layout and then change the styling of the LI elements to inline-blocks. By using the Bootstrap checkbox/radio classes combined with the list-unstyled we get a result very similar to the native Bootstrap styling.&lt;br&gt;&lt;br&gt;&lt;b&gt;Update for Bootstrap 4:&lt;/b&gt;&lt;br&gt;&lt;br&gt;Here are the CSS changes for Bootstrap 4.x.&lt;br&gt;&lt;br&gt;&lt;pre&gt;.checkboxlist-inline li, .radiobuttonlist-inline li&lt;br&gt;{&lt;br&gt;	display: inline-flex;&lt;br&gt;			&lt;br&gt;	align-items: center;&lt;br&gt;	padding-left: 0;&lt;br&gt;	margin-right: .75rem;&lt;br&gt;&lt;br&gt;	position: relative;&lt;br&gt;}&lt;br&gt;&lt;br&gt;.checkboxlist-inline li input, .radiobuttonlist-inline li input&lt;br&gt;{&lt;br&gt;	position: static;&lt;br&gt;	margin-top: 0;&lt;br&gt;	margin-right: .3125rem;&lt;br&gt;	margin-left: 0;&lt;br&gt;}&lt;br&gt;&lt;br&gt;.checkboxlist-inline li label, .radiobuttonlist-inline li label {&lt;br&gt;	margin-bottom: 0;&lt;br&gt;}&lt;/pre&gt;&lt;br&gt;&lt;br&gt;And here is how your RadioButtonList should be marked up:&lt;br&gt;&lt;br&gt;&lt;pre&gt;&amp;lt;asp:RadioButtonList ID=&quot;RadioButtonList1&quot; runat=&quot;server&quot; CssClass=&quot;list-unstyled radiobuttonlist-inline&quot; RepeatLayout=&quot;UnorderedList&quot;&amp;gt;&amp;lt;/asp:RadioButtonList&amp;gt;&lt;/pre&gt;</description>
<comments>https://johna.compoutpost.com/blog/809/bootstrap-checkbox-inline-and-radio-inline-with-asp-net-checkboxlist-and-radiobuttonlist-controls/#comments</comments>
<pubDate>2016-06-20T12:00:00+10:00</pubDate>
<category>Bootstrap</category>
<category>ASP.NET Web Forms</category>
<guid>https://johna.compoutpost.com/blog/809</guid>
</item>
<item>
<title>Page.Title is blank in MasterPage after setting in ASPX page</title>
<link>https://johna.compoutpost.com/blog/805/page-title-is-blank-in-masterpage-after-setting-in-aspx-page/</link>
<description>I came across an issue where I was setting Page.Title in my ASPX page's Page_Load event, but it was appearing blank when I was attempting to retrieve the value in the MasterPage's Page_PreRender event.&lt;br&gt;&lt;br&gt;Thanks to a comment on &lt;a href=&quot;http://www.cosnetics.co.uk/articles/asp.net-page-titles-are-blank/&quot; target=&quot;_blank&quot;&gt;this blog post&lt;/a&gt;, I found the solution.&lt;br&gt;&lt;br&gt;Here's what the anonymous comment said:&lt;br&gt;&lt;br&gt;&lt;blockquote&gt;I ran into this problem as well. Looked in Reflector and figured out why. Seems like this is a bug to me. On the setter, if the page has a Header control, then setting the Title property actually changes Header.Title, but if the _titleToBeSet property already has a value (mine does because I'm using localized resources) then it doesn't clear out the old value and the getter still returns _titleToBeSet instead of Header.Title.&lt;br&gt;&lt;br&gt;So I just changed my code to return this:&lt;br&gt;return (Page.Header != null ? Page.Header.Title : null) ?? Page.Title;&lt;/blockquote&gt;&lt;br&gt;So the solution is to use the following instead of Page.Title:&lt;br&gt;&lt;br&gt;&lt;pre&gt;(Page.Header != null ? Page.Header.Title : null) ?? Page.Title;&lt;/pre&gt;&lt;br&gt;</description>
<comments>https://johna.compoutpost.com/blog/805/page-title-is-blank-in-masterpage-after-setting-in-aspx-page/#comments</comments>
<pubDate>2016-06-08T12:00:00+10:00</pubDate>
<category>ASP.NET Web Forms</category>
<guid>https://johna.compoutpost.com/blog/805</guid>
</item>
<item>
<title>Bootstrap Modals inside UpdatePanels in ASP.NET Web Forms</title>
<link>https://johna.compoutpost.com/blog/778/bootstrap-modals-inside-updatepanels-in-asp-net-web-forms/</link>
<description>&lt;div class=&quot;well&quot;&gt;&lt;strong&gt;Update:&lt;/strong&gt; I'm now using a purely server-side technique to control Bootstrap 3.x modals. See my &lt;a href=&quot;/blog/832/asp-net-web-forms-and-bootstrap-3-modals/&quot;&gt;new post&lt;/a&gt;.&lt;/div&gt;&lt;br&gt;I have been working on an ASP.NET Web Forms project that is being converted to Bootstrap 3 and have run into a few issues with Modals.&lt;br&gt;&lt;br&gt;From this experience, here's how you can structure your markup for when you need to use Bootstrap Modals inside ASP.NET UpdatePanels.&lt;br&gt;&lt;br&gt;The most important part of this is that you don't place Modals inside UpdatePanels.&lt;br&gt;&lt;br&gt;Okay, so that contradicts a bit with what I said above, but I'm not suggesting you don't use UpdatePanels, just that you place them appropriately.&lt;br&gt;&lt;br&gt;Bootstrap Modals don't work when the relevant parts of the DOM are altered after the page is initially rendered. This makes them a bit more difficult to implement in an ASP.NET Web Forms environment.&lt;br&gt;&lt;br&gt;Let's look at an example where we have a list of records generated by a Repeater, each having an edit button which opens a Modal where the record can be edited.&lt;br&gt;&lt;br&gt;I would wrap an UpdatePanel around the table, have the Modal outside of this UpdatePanel, but have a second UpdatePanel inside the Modal.&lt;br&gt;&lt;br&gt;&lt;pre&gt;&amp;lt;asp:UpdatePanel ID=&quot;UpdatePanel1&quot; runat=&quot;server&quot; UpdateMode=&quot;Conditional&quot;&amp;gt;&lt;br&gt;	&amp;lt;ContentTemplate&amp;gt;&lt;br&gt;		&amp;lt;ul&amp;gt;&lt;br&gt;			&amp;lt;asp:Repeater ID=&quot;Repeater1&quot; runat=&quot;server&quot; OnItemCommand=&quot;Repeater1_ItemCommand&quot;&amp;gt;&lt;br&gt;				&amp;lt;ItemTemplate&amp;gt;&lt;br&gt;					&amp;lt;li&amp;gt;&amp;lt;asp:LinkButton ID=&quot;Button1&quot; runat=&quot;server&quot; CommandArgument='&amp;lt;%# Eval(&quot;ID&quot;) %&amp;gt;' Text='&amp;lt;%# Eval(&quot;Title&quot;) %&amp;gt;'&amp;gt;&amp;lt;/asp:LinkButton&amp;gt;&amp;lt;/li&amp;gt;&lt;br&gt;				&amp;lt;/ItemTemplate&amp;gt;&lt;br&gt;			&amp;lt;/asp:Repeater&amp;gt;&lt;br&gt;		&amp;lt;/ul&amp;gt;&lt;br&gt;	&amp;lt;/ContentTemplate&amp;gt;&lt;br&gt;&amp;lt;/asp:UpdatePanel&amp;gt;&lt;br&gt;&lt;br&gt;&amp;lt;asp:Panel ID=&quot;Panel1&quot; runat=&quot;server&quot; CssClass=&quot;modal&quot; DefaultButton=&quot;btnContactInsertSubmit&quot; tabindex=&quot;-1&quot; role=&quot;dialog&quot; aria-labelledby=&quot;myLabel&quot;&amp;gt;&lt;br&gt;	&amp;lt;div class=&quot;modal-dialog&quot; role=&quot;document&quot;&amp;gt;&lt;br&gt;		&amp;lt;div class=&quot;modal-content&quot;&amp;gt;&lt;br&gt;			&amp;lt;asp:UpdatePanel ID=&quot;UpdatePanel2&quot; runat=&quot;server&quot; UpdateMode=&quot;Conditional&quot;&amp;gt;&lt;br&gt;				&amp;lt;ContentTemplate&amp;gt;&lt;br&gt;					&amp;lt;div class=&quot;modal-header&quot;&amp;gt;&lt;br&gt;						&amp;lt;h4 class=&quot;modal-title&quot; id=&quot; myLabel &quot;&amp;gt;Edit&amp;lt;/h4&amp;gt;&lt;br&gt;					&amp;lt;/div&amp;gt;&lt;br&gt;					&amp;lt;div class=&quot;modal-body&quot;&amp;gt;&lt;br&gt;						...&lt;br&gt;					&amp;lt;/div&amp;gt;&lt;br&gt;					&amp;lt;div class=&quot;modal-footer&quot;&amp;gt;&lt;br&gt;						&amp;lt;asp:Button ID=&quot;Button2&quot; runat=&quot;server&quot; CssClass=&quot;btn btn-primary&quot; OnClick=&quot;Button2_Click&quot; Text=&quot;Submit&quot; /&amp;gt;&lt;br&gt;						&amp;lt;asp:LinkButton ID=&quot;Button3&quot; runat=&quot;server&quot; CssClass=&quot;btn btn-link&quot; OnClick=&quot;Button3_Click&quot; Text=&quot;Cancel&quot;&amp;gt;&amp;lt;/asp:LinkButton&amp;gt;&lt;br&gt;					&amp;lt;/div&amp;gt;&lt;br&gt;				&amp;lt;/ContentTemplate&amp;gt;&lt;br&gt;			&amp;lt;/asp:UpdatePanel&amp;gt;&lt;br&gt;		&amp;lt;/div&amp;gt;&lt;br&gt;	&amp;lt;/div&amp;gt;&lt;br&gt;&amp;lt;/asp:Panel&amp;gt;&lt;/pre&gt;&lt;br&gt;In the code behind we can handle the showing and hiding of the Modal by injecting some JavaScript on asynchronous PostBack, and selectively updating only the appropriate UpdatePanel.&lt;br&gt;&lt;br&gt;&lt;pre&gt;protected void repContact_ItemCommand(object sender, RepeaterCommandEventArgs e)&lt;br&gt;{&lt;br&gt;	int id = Utilities.IntParse(e.CommandArgument.ToString());&lt;br&gt;//Populate your form inside the Modal here&lt;br&gt;ScriptManager.RegisterStartupScript(UpdatePanel2, UpdatePanel2.GetType(), &quot;show&quot;, &quot;$(function () { $('#&quot; + Panel1.ClientID + &quot;').modal('show'); });&quot;, true);&lt;br&gt;UpdatePanel2.Update();&lt;br&gt;}&lt;br&gt;&lt;br&gt;protected void Button3_Click(object sender, EventArgs e)&lt;br&gt;{&lt;br&gt;	ScriptManager.RegisterStartupScript(UpdatePanel1, UpdatePanel1.GetType(), &quot;hide&quot;, &quot;$(function () { $('#&quot; + Panel1.ClientID + &quot;').modal('hide'); });&quot;, true);&lt;br&gt;	UpdatePanel1.Update();&lt;br&gt;}&lt;br&gt;&lt;br&gt;protected void Button2_Click(object sender, EventArgs e)&lt;br&gt;{&lt;br&gt;	//Save your record here&lt;br&gt;	ScriptManager.RegisterStartupScript(UpdatePanel1, UpdatePanel1.GetType(), &quot;hide&quot;, &quot;$(function () { $('#&quot; + Panel1.ClientID + &quot;').modal('hide'); });&quot;, true);&lt;br&gt;	UpdatePanel1.Update();&lt;br&gt;}&lt;/pre&gt;&lt;br&gt;This solution has worked perfectly for me even in complex Web Forms scenarios.&lt;br&gt;&lt;br&gt;&lt;div class=&quot;well&quot;&gt;&lt;strong&gt;Update:&lt;/strong&gt; I'm now using a purely server-side technique to control Bootstrap 3.x modals. See my &lt;a href=&quot;/blog/832/asp-net-web-forms-and-bootstrap-3-modals/&quot;&gt;new post&lt;/a&gt;.&lt;/div&gt;</description>
<comments>https://johna.compoutpost.com/blog/778/bootstrap-modals-inside-updatepanels-in-asp-net-web-forms/#comments</comments>
<pubDate>2015-07-14T12:00:00+10:00</pubDate>
<category>Bootstrap</category>
<category>ASP.NET Web Forms</category>
<guid>https://johna.compoutpost.com/blog/778</guid>
</item>
<item>
<title>Bootstrap styling for ASP.NET RadioButtonList and CheckBoxList in Horizontal Forms</title>
<link>https://johna.compoutpost.com/blog/777/bootstrap-styling-for-asp-net-radiobuttonlist-and-checkboxlist-in-horizontal-forms/</link>
<description>Following on from my last post about improving Bootstrap styling and accessibility for ASP.NET RadioButtonLists and CheckBoxLists, &lt;a href=&quot;/blog/776/better-styling-and-accessibility-for-asp-net-controls-using-bootstrap-3/&quot;&gt;Better styling and accessibility for ASP.NET controls using Bootstrap 3&lt;/a&gt;, in this post I offer a solution for styling these controls within Bootstrap horizontal forms.&lt;br&gt;&lt;br&gt;This example below uses the same CSS changes as my last post, but with a revised HTML structure to suit Bootstrap's &lt;em&gt;form-horizontal&lt;/em&gt; classes.&lt;br&gt;&lt;br&gt;&lt;pre&gt;&amp;lt;div class=&quot;form-horizontal&quot;&amp;gt;&lt;br&gt;	&amp;lt;fieldset class=&quot;form-group&quot;&amp;gt;&lt;br&gt;		&amp;lt;legend class=&quot;col-sm-3 control-label&quot;&amp;gt;Label for CheckBoxList1&amp;lt;/legend&amp;gt;&lt;br&gt;		&amp;lt;div class=&quot;checkbox checkboxlist col-sm-9&quot;&amp;gt;&lt;br&gt;			&amp;lt;asp:CheckBoxList ID=&quot;CheckBoxList1&quot; runat=&quot;server&quot; RepeatDirection=&quot;Vertical&quot; RepeatLayout=&quot;Flow&quot;&amp;gt;&lt;br&gt;				&amp;lt;asp:ListItem Text=&quot;Option one&quot;&amp;gt;&amp;lt;/asp:ListItem&amp;gt;&lt;br&gt;				&amp;lt;asp:ListItem Text=&quot;Option two&quot;&amp;gt;&amp;lt;/asp:ListItem&amp;gt;&lt;br&gt;				&amp;lt;asp:ListItem Text=&quot;Option three&quot;&amp;gt;&amp;lt;/asp:ListItem&amp;gt;&lt;br&gt;			&amp;lt;/asp:CheckBoxList&amp;gt;&lt;br&gt;		&amp;lt;/div&amp;gt;&lt;br&gt;	&amp;lt;/fieldset&amp;gt;&lt;br&gt;	&amp;lt;fieldset class=&quot;form-group&quot;&amp;gt;&lt;br&gt;		&amp;lt;legend class=&quot;col-sm-3 control-label&quot;&amp;gt;Label for RadioButtonList1&amp;lt;/legend&amp;gt;&lt;br&gt;		&amp;lt;div class=&quot;radio radiobuttonlist col-sm-9&quot;&amp;gt;&lt;br&gt;			&amp;lt;asp:RadioButtonList ID=&quot;RadioButtonList1&quot; runat=&quot;server&quot; RepeatDirection=&quot;Vertical&quot; RepeatLayout=&quot;Flow&quot;&amp;gt;&lt;br&gt;				&amp;lt;asp:ListItem Text=&quot;Option one&quot;&amp;gt;&amp;lt;/asp:ListItem&amp;gt;&lt;br&gt;				&amp;lt;asp:ListItem Text=&quot;Option two&quot;&amp;gt;&amp;lt;/asp:ListItem&amp;gt;&lt;br&gt;				&amp;lt;asp:ListItem Text=&quot;Option three&quot;&amp;gt;&amp;lt;/asp:ListItem&amp;gt;&lt;br&gt;			&amp;lt;/asp:RadioButtonList&amp;gt;&lt;br&gt;		&amp;lt;/div&amp;gt;&lt;br&gt;	&amp;lt;/fieldset&amp;gt;&lt;br&gt;&amp;lt;/div&amp;gt;&lt;/pre&gt;&lt;br&gt;&lt;br&gt;And here's what this looks like:&lt;br&gt;&lt;br&gt;&lt;img alt=&quot;After CSS changes&quot; src=&quot;/blog/uploads/img777_after.JPG&quot;&gt;</description>
<comments>https://johna.compoutpost.com/blog/777/bootstrap-styling-for-asp-net-radiobuttonlist-and-checkboxlist-in-horizontal-forms/#comments</comments>
<pubDate>2015-07-13T12:00:00+10:00</pubDate>
<category>Bootstrap</category>
<category>ASP.NET Web Forms</category>
<guid>https://johna.compoutpost.com/blog/777</guid>
</item>
<item>
<title>Better styling and accessibility for ASP.NET controls using Bootstrap</title>
<link>https://johna.compoutpost.com/blog/776/better-styling-and-accessibility-for-asp-net-controls-using-bootstrap-3/</link>
<description>&lt;b&gt;Update:&lt;/b&gt; This applies to Bootstrap 3.x. See the update at the end of the article for Bootstrap 4.&lt;br&gt;&lt;br&gt;Using some ASP.NET Web Forms controls with Bootstrap raises a few issues due to the markup that ASP.NET produces. There is also some accessibility issues with Bootstrap.&lt;br&gt;&lt;br&gt;&lt;b&gt;Styling&lt;/b&gt;&lt;br&gt;&lt;br&gt;If you have used a RadioButtonList or CheckBoxList with Bootstrap you would have seen that these do not get styled correctly.&lt;br&gt;&lt;br&gt;&lt;b&gt;Accessibility&lt;/b&gt;&lt;br&gt;&lt;br&gt;From my research, if you need to add a label to a RadioButtonList, CheckBoxList, or group of RadioButtons or CheckBoxes then you should use a fieldset with a legend.&lt;br&gt;&lt;br&gt;&lt;b&gt;Sample&lt;/b&gt;&lt;br&gt;&lt;br&gt;The following sample ASP.NET markup illustrates the styling issues when the correct structure is used.&lt;br&gt;&lt;br&gt;&lt;pre&gt;&amp;lt;div class=&quot;form-group&quot;&amp;gt;&lt;br&gt;	&amp;lt;asp:Label runat=&quot;server&quot; AssociatedControlID=&quot;TextBox1&quot; Text=&quot;Label for TextBox&quot;&amp;gt;&amp;lt;/asp:Label&amp;gt;&lt;br&gt;	&amp;lt;asp:TextBox ID=&quot;TextBox1&quot; runat=&quot;server&quot; CssClass=&quot;form-control&quot;&amp;gt;&amp;lt;/asp:TextBox&amp;gt;&lt;br&gt;&amp;lt;/div&amp;gt;&lt;br&gt;&lt;br&gt;&amp;lt;div class=&quot;form-group&quot;&amp;gt;&lt;br&gt;	&amp;lt;asp:Label runat=&quot;server&quot; AssociatedControlID=&quot;DropDownList1&quot; Text=&quot;Label for DropDownList&quot;&amp;gt;&amp;lt;/asp:Label&amp;gt;&lt;br&gt;	&amp;lt;asp:DropDownList ID=&quot;DropDownList1&quot; runat=&quot;server&quot; CssClass=&quot;form-control&quot;&amp;gt;&lt;br&gt;		&amp;lt;asp:ListItem Text=&quot;Option one&quot;&amp;gt;&amp;lt;/asp:ListItem&amp;gt;&lt;br&gt;		&amp;lt;asp:ListItem Text=&quot;Option two&quot;&amp;gt;&amp;lt;/asp:ListItem&amp;gt;&lt;br&gt;		&amp;lt;asp:ListItem Text=&quot;Option three&quot;&amp;gt;&amp;lt;/asp:ListItem&amp;gt;&lt;br&gt;	&amp;lt;/asp:DropDownList&amp;gt;&lt;br&gt;&amp;lt;/div&amp;gt;&lt;br&gt;&lt;br&gt;&amp;lt;fieldset&amp;gt;&lt;br&gt;	&amp;lt;legend&amp;gt;Label for CheckBox&amp;lt;/legend&amp;gt;&lt;br&gt;	&amp;lt;div class=&quot;checkbox&quot;&amp;gt;&lt;br&gt;		&amp;lt;label&amp;gt;&lt;br&gt;			&amp;lt;asp:CheckBox ID=&quot;CheckBox1&quot; runat=&quot;server&quot; /&amp;gt;&lt;br&gt;			Option one&lt;br&gt;		&amp;lt;/label&amp;gt;&lt;br&gt;	&amp;lt;/div&amp;gt;&lt;br&gt;	&amp;lt;div class=&quot;checkbox&quot;&amp;gt;&lt;br&gt;		&amp;lt;label&amp;gt;&lt;br&gt;			&amp;lt;asp:CheckBox ID=&quot;CheckBox2&quot; runat=&quot;server&quot; /&amp;gt;&lt;br&gt;			Option two&lt;br&gt;		&amp;lt;/label&amp;gt;&lt;br&gt;	&amp;lt;/div&amp;gt;&lt;br&gt;	&amp;lt;div class=&quot;checkbox&quot;&amp;gt;&lt;br&gt;		&amp;lt;label&amp;gt;&lt;br&gt;			&amp;lt;asp:CheckBox ID=&quot;CheckBox3&quot; runat=&quot;server&quot; /&amp;gt;&lt;br&gt;			Option three&lt;br&gt;		&amp;lt;/label&amp;gt;&lt;br&gt;	&amp;lt;/div&amp;gt;&lt;br&gt;&amp;lt;/fieldset&amp;gt;&lt;br&gt;&lt;br&gt;&amp;lt;fieldset&amp;gt;&lt;br&gt;	&amp;lt;legend&amp;gt;Label for CheckBoxList&amp;lt;/legend&amp;gt;&lt;br&gt;	&amp;lt;div class=&quot;checkbox checkboxlist&quot;&amp;gt;&lt;br&gt;		&amp;lt;asp:CheckBoxList ID=&quot;CheckBoxList1&quot; runat=&quot;server&quot; RepeatDirection=&quot;Vertical&quot; RepeatLayout=&quot;Flow&quot;&amp;gt;&lt;br&gt;			&amp;lt;asp:ListItem Text=&quot;Option one&quot;&amp;gt;&amp;lt;/asp:ListItem&amp;gt;&lt;br&gt;			&amp;lt;asp:ListItem Text=&quot;Option two&quot;&amp;gt;&amp;lt;/asp:ListItem&amp;gt;&lt;br&gt;			&amp;lt;asp:ListItem Text=&quot;Option three&quot;&amp;gt;&amp;lt;/asp:ListItem&amp;gt;&lt;br&gt;		&amp;lt;/asp:CheckBoxList&amp;gt;&lt;br&gt;	&amp;lt;/div&amp;gt;&lt;br&gt;&amp;lt;/fieldset&amp;gt;&lt;br&gt;&lt;br&gt;&amp;lt;fieldset&amp;gt;&lt;br&gt;	&amp;lt;legend&amp;gt;Label for RadioButton&amp;lt;/legend&amp;gt;&lt;br&gt;	&amp;lt;div class=&quot;radio&quot;&amp;gt;&lt;br&gt;		&amp;lt;label&amp;gt;&lt;br&gt;			&amp;lt;asp:RadioButton ID=&quot;RadioButton1&quot; runat=&quot;server&quot; GroupName=&quot;GroupName1&quot; /&amp;gt;&lt;br&gt;			Option one&lt;br&gt;		&amp;lt;/label&amp;gt;&lt;br&gt;	&amp;lt;/div&amp;gt;&lt;br&gt;	&amp;lt;div class=&quot;radio&quot;&amp;gt;&lt;br&gt;		&amp;lt;label&amp;gt;&lt;br&gt;			&amp;lt;asp:RadioButton ID=&quot;RadioButton2&quot; runat=&quot;server&quot; GroupName=&quot;GroupName1&quot; /&amp;gt;&lt;br&gt;			Option two&lt;br&gt;		&amp;lt;/label&amp;gt;&lt;br&gt;	&amp;lt;/div&amp;gt;&lt;br&gt;	&amp;lt;div class=&quot;radio&quot;&amp;gt;&lt;br&gt;		&amp;lt;label&amp;gt;&lt;br&gt;			&amp;lt;asp:RadioButton ID=&quot;RadioButton3&quot; runat=&quot;server&quot; GroupName=&quot;GroupName1&quot; /&amp;gt;&lt;br&gt;			Option three&lt;br&gt;		&amp;lt;/label&amp;gt;&lt;br&gt;	&amp;lt;/div&amp;gt;&lt;br&gt;&amp;lt;/fieldset&amp;gt;&lt;br&gt;&lt;br&gt;&amp;lt;fieldset&amp;gt;&lt;br&gt;	&amp;lt;legend&amp;gt;Label for RadioButtonList&amp;lt;/legend&amp;gt;&lt;br&gt;	&amp;lt;div class=&quot;radio radiobuttonlist&quot;&amp;gt;&lt;br&gt;		&amp;lt;asp:RadioButtonList ID=&quot;RadioButtonList1&quot; runat=&quot;server&quot; RepeatDirection=&quot;Vertical&quot; RepeatLayout=&quot;Flow&quot;&amp;gt;&lt;br&gt;			&amp;lt;asp:ListItem Text=&quot;Option one&quot;&amp;gt;&amp;lt;/asp:ListItem&amp;gt;&lt;br&gt;			&amp;lt;asp:ListItem Text=&quot;Option two&quot;&amp;gt;&amp;lt;/asp:ListItem&amp;gt;&lt;br&gt;			&amp;lt;asp:ListItem Text=&quot;Option three&quot;&amp;gt;&amp;lt;/asp:ListItem&amp;gt;&lt;br&gt;		&amp;lt;/asp:RadioButtonList&amp;gt;&lt;br&gt;	&amp;lt;/div&amp;gt;&lt;br&gt;&amp;lt;/fieldset&amp;gt;&lt;/pre&gt;&lt;br&gt;And here's what that looks like:&lt;br&gt;&lt;br&gt;&lt;img alt=&quot;The before picture&quot; src=&quot;/blog/uploads/img776_before.JPG&quot;&gt;&lt;br&gt;&lt;br&gt;&lt;b&gt;CSS changes to correct this&lt;/b&gt;&lt;br&gt;&lt;br&gt;Note in my markup above I already added classes &lt;em&gt;checkboxlist&lt;/em&gt; and &lt;em&gt;radiobuttonlist&lt;/em&gt; that will be used to apply styling to these controls.&lt;br&gt;&lt;br&gt;Here's my CSS additions that override Bootstrap's defaults.&lt;br&gt;&lt;br&gt;&lt;pre&gt;.radio.radiobuttonlist input[type=&quot;radio&quot;],&lt;br&gt;.checkbox.checkboxlist input[type=&quot;checkbox&quot;]&lt;br&gt;{&lt;br&gt;	margin-left: 0;&lt;br&gt;}&lt;br&gt;&lt;br&gt;.radio.radiobuttonlist label,&lt;br&gt;.checkbox.checkboxlist label&lt;br&gt;{&lt;br&gt;	margin-bottom: 4px;&lt;br&gt;	margin-left: 0;&lt;br&gt;}&lt;br&gt;&lt;br&gt;fieldset legend&lt;br&gt;{&lt;br&gt;	border: 0;&lt;br&gt;	font-size: inherit;&lt;br&gt;	font-weight: 700;&lt;br&gt;	margin-bottom: 0;&lt;br&gt;}&lt;br&gt;&lt;br&gt;fieldset .radio,&lt;br&gt;fieldset .checkbox&lt;br&gt;{&lt;br&gt;	margin-top: 4px;&lt;br&gt;}&lt;/pre&gt;&lt;br&gt;And here's what my sample markup looks like now:&lt;br&gt;&lt;br&gt;&lt;img alt=&quot;After CSS changes&quot; src=&quot;/blog/uploads/img776_after.JPG&quot;&gt;&lt;br&gt;&lt;br&gt;For Bootstrap Horizontal Forms, see my other post, &lt;a href=&quot;/blog/777/bootstrap-styling-for-asp-net-radiobuttonlist-and-checkboxlist-in-horizontal-forms/&quot;&gt;Bootstrap styling for ASP.NET RadioButtonList and CheckBoxList in Horizontal Forms&lt;/a&gt;.&lt;br&gt;&lt;br&gt;&lt;b&gt;Update:&lt;/b&gt; For Bootstrap 4.x, you can use the following CSS.&lt;br&gt;&lt;br&gt;&lt;pre&gt;.radio.radiobuttonlist input[type=&quot;radio&quot;],&lt;br&gt;.checkbox.checkboxlist input[type=&quot;checkbox&quot;]&lt;br&gt;{&lt;br&gt;	position: absolute;&lt;br&gt;	margin-top: 0.3rem;&lt;br&gt;	margin-left: -1.25rem;&lt;br&gt;}&lt;br&gt;&lt;br&gt;.radio.radiobuttonlist label,&lt;br&gt;.checkbox.checkboxlist label&lt;br&gt;{&lt;br&gt;	margin-bottom: 0;&lt;br&gt;	display: inline-block;&lt;br&gt;}&lt;br&gt;&lt;br&gt;fieldset legend&lt;br&gt;{&lt;br&gt;	font-size: inherit;&lt;br&gt;}&lt;br&gt;&lt;br&gt;fieldset .radio,&lt;br&gt;fieldset .checkbox&lt;br&gt;{&lt;br&gt;	position: relative;&lt;br&gt;	display: block;&lt;br&gt;	padding-left: 1.25rem;&lt;br&gt;}&lt;/pre&gt;</description>
<comments>https://johna.compoutpost.com/blog/776/better-styling-and-accessibility-for-asp-net-controls-using-bootstrap-3/#comments</comments>
<pubDate>2015-07-10T12:00:00+10:00</pubDate>
<category>Bootstrap</category>
<category>ASP.NET Web Forms</category>
<image>https://johna.compoutpost.com/blog/uploads/img776_before.JPG</image>
<guid>https://johna.compoutpost.com/blog/776</guid>
</item>
<item>
<title>Navigate away protection for ASP.NET Web Forms</title>
<link>https://johna.compoutpost.com/blog/768/navigate-away-protection-for-asp-net-web-forms/</link>
<description>I have wanted to add protection from vavigating away from some of my web forms but most of the solutions I have seen do not work well with ASP.NET with it's many possible ways of posting back and AJAX using Update Panels.&lt;br&gt;&lt;br&gt;For my situation I wanted to protect against the user navigating away using the website's main navigation, closing the browser, clicking back or forward or even going to a favourite website. I did not want to protect against the user clicking any Button, Link Button or any control with AutoPostBack enabled within my form.&lt;br&gt;&lt;br&gt;After a Stack Overflow question and investigation of many possible solutions I have created the following JavaScript/jQuery code that does this better than anything I found.&lt;br&gt;&lt;br&gt;Please note that this code does not check whether any changes were made to the values in the form, although this functionality could be added easily. In my situation I wanted to protect against navigating away because my system had a form of record locking in place that required the user to exit correctly (or wait for lock to timeout).&lt;br&gt;&lt;br&gt;&lt;pre&gt;var navigateAway = function (e) {&lt;br&gt;	e = e || window.event;&lt;br&gt;&lt;br&gt;	//This is the message that is shown when navigating away improperly&lt;br&gt;	var message = &quot;Exiting the form this way will result in this record being locked to you. Use cancel changes instead to exit correctly&quot;;&lt;br&gt;&lt;br&gt;	if (e) {&lt;br&gt;		e.returnValue = message;&lt;br&gt;	}&lt;br&gt;&lt;br&gt;	return message;&lt;br&gt;}&lt;br&gt;&lt;br&gt;function EnableUnloadEvent() {&lt;br&gt;	window.onbeforeunload = navigateAway;&lt;br&gt;}&lt;br&gt;&lt;br&gt;$(function () {&lt;br&gt;	$(&quot;#myform select&quot;).change(function () {&lt;br&gt;		window.onbeforeunload = null;&lt;br&gt;		window.setTimeout(&quot;EnableUnloadEvent()&quot;, 100);&lt;br&gt;	});&lt;br&gt;&lt;br&gt;	$(&quot;#myform&quot;).click(function (e) {&lt;br&gt;		window.onbeforeunload = null;&lt;br&gt;		window.setTimeout(&quot;EnableUnloadEvent()&quot;, 100);&lt;br&gt;	});&lt;br&gt;&lt;br&gt;	EnableUnloadEvent();&lt;br&gt;});&lt;/pre&gt;&lt;br&gt;&lt;br&gt;&lt;em&gt;#myform&lt;/em&gt; refers to the ID of the container (eg. DIV) that contains all of your form elements that can be clicked or changed without triggering the unload message. Anything outside of this container will trigger the message.&lt;br&gt;&lt;br&gt;Should you want to only show the message if one or more of the form elements anywhere on the page have been changed, you could add functionality to store the initial values, then compare these in the unload event (some code sourced from &lt;a href=&quot;http://www.codeproject.com/Articles/132445/Work-smarter-not-harder-Navigate-Away-feature-for&quot; target=&quot;_blank&quot;&gt;Code Project&lt;/a&gt;). Note that if you have anything on your page that causes a full PostBack (rather than a partial PostBack) it will set and compare the initial values from the most recent PostBack, so won't be accurate.&lt;br&gt;&lt;br&gt;&lt;pre&gt;var initialValue = &quot;&quot;;&lt;br&gt;&lt;br&gt;var navigateAway = function (e) {&lt;br&gt;&lt;br&gt;	if (initialValue != GetFormValues()) {&lt;br&gt;&lt;br&gt;		e = e || window.event;&lt;br&gt;&lt;br&gt;		var message = &quot;Exiting the form this way will result in this record being locked to you. Use cancel changes instead to exit correctly&quot;;&lt;br&gt;&lt;br&gt;		if (e) {&lt;br&gt;			e.returnValue = message;&lt;br&gt;		}&lt;br&gt;&lt;br&gt;		return message;&lt;br&gt;	}&lt;br&gt;}&lt;br&gt;&lt;br&gt;function EnableUnloadEvent() {&lt;br&gt;	window.onbeforeunload = navigateAway;&lt;br&gt;}&lt;br&gt;&lt;br&gt;function GetFormValues() {&lt;br&gt;	var formValues = &quot;&quot;;&lt;br&gt;	$.each($(&quot;form&quot;).serializeArray(), function (i, field) {&lt;br&gt;		if (field.name != &quot;__EVENTVALIDATION&quot;&lt;br&gt;		&amp;&amp; field.name != &quot;__EVENTTARGET&quot;&lt;br&gt;		&amp;&amp; field.name != &quot;__EVENTARGUMENT&quot;&lt;br&gt;		&amp;&amp; field.name != &quot;__VIEWSTATE&quot;&lt;br&gt;		&amp;&amp; field.name != &quot;__VIEWSTATEENCRYPTED&quot;) {&lt;br&gt;&lt;br&gt;			var inputField = $(&quot;[name=&quot; + field.name + &quot;]&quot;);&lt;br&gt;			var displayProperty = $(inputField).css(&quot;display&quot;);&lt;br&gt;&lt;br&gt;			if (displayProperty != &quot;none&quot;) {&lt;br&gt;				formValues = formValues + &quot;-&quot; + field.name + &quot;:&quot; + field.value;&lt;br&gt;			}&lt;br&gt;		}&lt;br&gt;	});&lt;br&gt;&lt;br&gt;	$(&quot;:checkbox&quot;).each(function () {&lt;br&gt;		formValues = formValues + &quot;-&quot; + $(this).attr(&quot;checked&quot;);&lt;br&gt;	});&lt;br&gt;&lt;br&gt;	$(&quot;:radio&quot;).each(function () {&lt;br&gt;		formValues = formValues + &quot;-&quot; + $(this).attr(&quot;checked&quot;);&lt;br&gt;	});&lt;br&gt;&lt;br&gt;	$(&quot;:file&quot;).each(function () {&lt;br&gt;		formValues = formValues + &quot;-&quot; + $(this).val();&lt;br&gt;	});&lt;br&gt;	return formValues;&lt;br&gt;}&lt;br&gt;&lt;br&gt;$(function () {&lt;br&gt;&lt;br&gt;	initialValue = GetFormValues();&lt;br&gt;&lt;br&gt;	$(&quot;#form select&quot;).change(function () {&lt;br&gt;		window.onbeforeunload = null;&lt;br&gt;		window.setTimeout(&quot;EnableUnloadEvent()&quot;, 100);&lt;br&gt;	});&lt;br&gt;&lt;br&gt;	$(&quot;#form&quot;).click(function (e) {&lt;br&gt;		window.onbeforeunload = null;&lt;br&gt;		window.setTimeout(&quot;EnableUnloadEvent()&quot;, 100);&lt;br&gt;	});&lt;br&gt;&lt;br&gt;	EnableUnloadEvent();&lt;br&gt;});&lt;/pre&gt;</description>
<comments>https://johna.compoutpost.com/blog/768/navigate-away-protection-for-asp-net-web-forms/#comments</comments>
<pubDate>2015-05-20T12:00:00+10:00</pubDate>
<category>ASP.NET Web Forms</category>
<category>Jquery/Javascript</category>
<guid>https://johna.compoutpost.com/blog/768</guid>
</item>
<item>
<title>My latest project: Ghost Tour Bookings</title>
<link>https://johna.compoutpost.com/blog/766/my-latest-project-ghost-tour-bookings/</link>
<description>My latest web project is &lt;a href=&quot;http://www.ghosttourbookings.com/&quot; target=&quot;_blank&quot;&gt;Ghost Tour Bookings&lt;/a&gt;, a website where ghost tours are advertised and people can make enquiries or book the tour.&lt;br&gt;&lt;br&gt;The website is hosted by &lt;a href=&quot;http://www.smarterasp.net/&quot; target=&quot;_blank&quot;&gt;Smarter ASP&lt;/a&gt; and is developed using ASP.NET Web Forms.&lt;br&gt;&lt;br&gt;For speed of development, and to keep costs low, the website uses Bootstrap 3 for basic design and responsive capabilities. The logo and some images used on the website were created by freelancers on &lt;a href=&quot;http://freelancer.com/&quot; target=&quot;_blank&quot;&gt;freelancer.com&lt;/a&gt; and were of very good quality yet very inexpensive.&lt;br&gt;&lt;br&gt;Although the website is presently only listing ghost tours within Australian it is designed to be an international website and supports multiple domains where available, or a simple URL structure for countries where no country-specific domain is used.&lt;br&gt;&lt;br&gt;As all countries will be hosted on the one hosting plan with a single IP address. Subsequently, where SSL is required, the website only has one SSL certificate so reverts to the primary (.com) domain with country code as part of the URL structure for all SSL requests.&lt;br&gt;&lt;br&gt;ASP.NET routing is used for URL rewriting with most pages being routed to a main page where the URL is analysed and the requested page created by dynamically adding the appropriate user control for the page.&lt;br&gt;&lt;br&gt;The website uses an ASP.NET master page but to enhance performance and minimise data traffic an ASP.NET form tag is only added when necessary.&lt;br&gt;&lt;br&gt;ASP.NET Update Panels are used for AJAX on ASP.NET forms, otherwise jQuery is used for other AJAX functionality.&lt;br&gt;&lt;br&gt;The website uses all of the principles from my user account security post, &lt;a href=&quot;/blog/748/best-practices-for-membership-systems-login-pages-and-password-resets/&quot;&gt;Best practices for membership systems, login pages and password resets&lt;/a&gt;.&lt;br&gt;&lt;br&gt;&lt;img alt=&quot;Ghost Tour Bookings website&quot; src=&quot;/blog/uploads/img766_ghost-tour-bookings.jpg&quot; class=&quot;img-responsive&quot; /&gt;</description>
<comments>https://johna.compoutpost.com/blog/766/my-latest-project-ghost-tour-bookings/#comments</comments>
<pubDate>2015-04-04T12:00:00+10:00</pubDate>
<category>ASP.NET Web Forms</category>
<image>https://johna.compoutpost.com/blog/uploads/img766_ghost-tour-bookings.jpg</image>
<guid>https://johna.compoutpost.com/blog/766</guid>
</item>
<item>
<title>Can't change the Visible property of a control in ASP.NET Web Forms?</title>
<link>https://johna.compoutpost.com/blog/765/can-t-change-the-visible-property-of-a-control-in-asp-net-web-forms/</link>
<description>If you come across a problem where you set the Visible property of an ASP.NET control to true in a code behind file, but even when you debug it still shows the value as being false then the problem is most likely to be that the control is inside another control such as a Panel or PlaceHolder that has its Visible property set to false.&lt;br&gt;&lt;br&gt;It appears that the Visible property can be a little confusing. It has certainly tripped me up more than once.&lt;br&gt;&lt;br&gt;When a value is set for this property it will be remembered. So if you set Visible to true or false for a control that is within another control that is set to not be visible, if you later set that container control to be visible the control within it will then be visible or not visible depending on what value you set.&lt;br&gt;&lt;br&gt;However, when you get the value for the Visible property, you are actually getting the current visibility of the control, and if a container control is not visible then of course the control within will also not be visible, no matter whether you have set it to visible or not.&lt;br&gt;&lt;br&gt;To avoid problems it is best not to use the Visible property for certain conditional logic. Please see the example below for what not to do and how to do it correctly.&lt;br&gt;&lt;br&gt;Incorrect:&lt;br&gt;&lt;br&gt;&lt;pre&gt;btnSubmit.Visible = someValue == 1;&lt;br&gt;If (btnSubmit.Visible)&lt;br&gt;{&lt;br&gt;    //some code here&lt;br&gt;}&lt;/pre&gt;&lt;br&gt;Correct:&lt;br&gt;&lt;br&gt;&lt;pre&gt;btnSubmit.Visible = someValue == 1;&lt;br&gt;If (someValue == 1)&lt;br&gt;{&lt;br&gt;    //some code here&lt;br&gt;}&lt;/pre&gt;</description>
<comments>https://johna.compoutpost.com/blog/765/can-t-change-the-visible-property-of-a-control-in-asp-net-web-forms/#comments</comments>
<pubDate>2015-03-23T12:00:00+10:00</pubDate>
<category>ASP.NET Web Forms</category>
<guid>https://johna.compoutpost.com/blog/765</guid>
</item>
<item>
<title>UpdatePanel in incomplete state after using browser's back button</title>
<link>https://johna.compoutpost.com/blog/760/updatepanel-in-incomplete-state-after-using-browsers-back-button/</link>
<description>I recently experienced an issue with an ASP.NET Web Forms page with various UpdatePanels. The page has two DropDownLists, the selection of one results in populating of possible values in the other, and the selection of the other results in enabling of a Button. Then if the Button is clicked the user is redirected to another website, based on their selection.&lt;br&gt;&lt;br&gt;The problem is after the redirect to the other website, if the user then goes back to the original page, the first DropDownList is in its last state, but the second DropDownList is empty and to continue they must either select away from their last choice in the first DropDownList or refresh the page.&lt;br&gt;&lt;br&gt;Ideally I would like to return the page and all controls to their last state, or make the page reset to as if it was accessed for the first time.&lt;br&gt;&lt;br&gt;The &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/cc488548(v=vs.110).aspx&quot; target=&quot;_blank&quot;&gt;ScriptManager history functionality&lt;/a&gt; could probably be used for this purpose, but a simple solution that worked for me was to disable all caching of the page, which results in the page being reset.&lt;br&gt;&lt;br&gt;The following code might be a bit of overkill but does the job:&lt;pre&gt;Response.Expires = 0;&lt;br&gt;Response.ExpiresAbsolute = DateTime.Now.AddYears(-2);&lt;br&gt;Response.AddHeader(&quot;pragma&quot;, &quot;no-cache&quot;);&lt;br&gt;Response.AddHeader(&quot;cache-control&quot;, &quot;private&quot;);&lt;br&gt;Response.CacheControl = &quot;no-cache&quot;;&lt;br&gt;Response.Cache.SetExpires(DateTime.UtcNow.AddMinutes(-1));&lt;br&gt;Response.Cache.SetCacheability(HttpCacheability.NoCache);&lt;br&gt;Response.Cache.SetNoStore();&lt;/pre&gt;The answer came from &lt;a href=&quot;http://forums.asp.net/post/4129398.aspx&quot; target=&quot;_blank&quot;&gt;this answer on ASP.NET forums&lt;/a&gt;.</description>
<comments>https://johna.compoutpost.com/blog/760/updatepanel-in-incomplete-state-after-using-browsers-back-button/#comments</comments>
<pubDate>2015-01-27T12:00:00+10:00</pubDate>
<category>ASP.NET Web Forms</category>
<guid>https://johna.compoutpost.com/blog/760</guid>
</item>
</channel>
</rss>
