MaintainScrollPositionOnPostback is not working - how to debug? - asp.net

I inherited some web shop project (ASP.NET 3.5, Webforms, Visual Studio 2008 PRO).
On one page I have MaintainScrollPositionOnPostback set to true.
When shopping cart (user control loaded in master page) is empty, then asp.net is not generating Javascript code required for scroll position. When I add some items to the cart, then everything works fine.
Can you give me any advice how to find part of the code which is responsible for this issue?
I don't have an access to the 3rd party profilers.

Are you utilizing UpdatePanels in that specific page?
If Yes, following article may give you some direction:
http://basgun.wordpress.com/2008/06/09/maintain-scroll-position-updatepanel-postback/
If No, this one may assist:
Javascript: Maintaining Page Scroll Position
Here is the code from that article:
// function saves scroll position
function fScroll(val)
{
var hidScroll = document.getElementById('hidScroll');
hidScroll.value = val.scrollTop;
}
// function moves scroll position to saved value
function fScrollMove(what)
{
var hidScroll = document.getElementById('hidScroll');
document.getElementById(what).scrollTop = hidScroll.value;
}
</script>
</head>
<body onload="fScrollMove('div_scroll');" onunload="document.forms(0).submit()";>
<form>
<input type="text" id="hidScroll" name="a">< /br>
<div id="div_scroll" onscroll="fScroll(this);"
style="overflow:auto;height:100px;width:100px;">
.. VERY LONG TEXT GOES HERE
</div>
</form>
</body>
</html>
Hope one of these links help!

Related

AngularJS events with ASP.NET UpdatePanel

I'm trying to use AngularJS within an ASP UpdatePanel, very much like in this question: AngularJS with ASP.NET Updatepanel partial update
That solution also helped a lot, at least regarding the static parts, ie everything showed upon initialization.
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(function (sender, args) {
var elem = angular.element(document.getElementById("myDiv"));
var newElem = $compile(elem)($scope);
$scope.$apply();
elem.replaceWith(newElem.html());
});
Properties setup within add_endRequest() are shown properly. My problem is that all interaction is dead.
For example if I put
<div id="myDiv">
{{testtext}}
<div ng-init="testtext='hello world'"/>
</div>
it'll print out the string as expected. But when adding ie a click event nothing happens.
<div ng-click="testtext='hello world'">Click here</div>
Any ideas why? As I understand it the angular $compile and $scope.$apply() should apply to all angularjs functionality, but it seems not.
Figured it out with a little help from my friends. The problem was that only the element with my AngularJS list <div id="myDiv"> was recompiled in the add_endRequest() method. When changing this to the div holding the angularjs controller, surrounding the entire UpdatePanel section...
<div ng-controller="UpdatePanelController" id="UpdatePanelController">
<asp:UpdatePanel ID="UpdatePanel" UpdateMode="Conditional" runat="server">
...
</asp:UpdatePanel>
</div>
and then compiling its children...
OneViewApp.controller("UpdatePanelController", function ($scope, $compile) {
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(function () {
var elem = angular.element(document.getElementById("UpdatePanelController"));
$compile(elem.children())($scope);
$scope.$apply();
});
});
everything worked fine. Since UpdatePanel replaces the html, the entire controller needs to be recompiled in order for it to work properly.
This can of course also be achieved by (re)bootstraping the angular app for every step, as suggested in another answer, but the above solution is closer to the original code and thus simpler in this case.
I had the same issue.
I have an Angular page that have an iframe, that contains an old asp.net application (with user controls and an update panel).
I've tried to add an Angular directive to the .NET part, and had the same issue. The directive had an empty template (no HTML content under the directive's div).
And after applying the solution you've mentioned:
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(function (sender, args) {
var elem = angular.element(document.getElementById("myDiv"));
var newElem = $compile(elem)($scope);
$scope.$apply();
elem.replaceWith(newElem.html());
});
I saw the html content but without Angular bindings, like ng-repeat or ng-click.
The solution was found here:
http://blog.travisgosselin.com/integrating-angularjs-in-a-tight-spot/
You need to manually initialize your module in the add_endRequest event:
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(function (sender, args) {
angular.bootstrap($('#myDiv'), ['myNgApp']);
});
This solution was enough, and I removed the solution that you've mentioned with the $compile.
You can read about angular.bootstrap in the documentation:
https://docs.angularjs.org/guide/bootstrap

postbacks from inside not firing

I have a bit of ASP code that I'm trying to show/hide via Magnific Popup, by passing it a div from the page as a source.
Insert New Record
<div id="import-popup" class="white-popup mfp-hide">
<span>Proposal to Import:</span>
<asp:TextBox ID="txtPropNum" runat="server" />
<asp:Button ID="btnImport" runat="server" Text="Import" OnClick="btnImport_Click" />
</div>
JS:
$(document).ready(function () {
$('.open-popup-link').magnificPopup({
type: 'inline',
midClick: true // Allow opening popup on middle mouse click. Always set it to true if you don't provide alternative source in href.
});
})
The div displays and hides perfectly fine. I can't seem to get the asp:Button id="btnImport" to actually fire it's function (which right now is a MsgBox to display the contents of the asp:TextBox) though. In fact, I don't even see a post/get request being logged in my web console.
The button however, works fine when not located inside that div, and the TextBox is even accessible from code behind as well, so I know my actual click function is working. Any ideas what might be going on? Is Magnific somehow preventing a postback?
If you are using the latest version of .magnificPopup then you can use the new prependTo method, and sent the .net form ID when setting it up.
$('.popup-with-form').magnificPopup({
type: 'inline',
preloader: false,
focus: '#name',
prependTo: $('#form1'),
The only solution I could find for this (as I didn't see any options in the API) was to modify the core code (yuck!).
I changed the line:
// add everything to DOM
mfp.bgOverlay.add(mfp.wrap).prependTo( document.body );
to:
// add everything to DOM
mfp.bgOverlay.add(mfp.wrap).prependTo( $('#form1') );
where form1 is the ID of my form element.
I wound up moving my popup's content to it's own page, then invoking magnific through the iframe type, as below:
JS:
$(document).ready(function () {
$('.open-popup-link').magnificPopup({
type: 'iframe',
iframe: {
markup: '<div class="mfp-iframe-scaler" style="width:100px; height:100px;">'+
'<div class="mfp-close"></div>' +
'<div class="custom-mfp-border">'+
'<iframe class="mfp-iframe" frameborder="0" allowfullscreen></iframe>' +
'</div>'+
'</div>'
},
midClick: true // Allow opening popup on middle mouse click. Always set it to true if you don't provide alternative source in href.
});
})
Parent Page:
Insert New Record
Then my child page is essentially just the <div> I posted in the question.
adding prependTo: $('#form1')
worked for me! using VS 2010

Refresh issue in ASP.Net MVC4 view

I have code like below in ASP.Net MVC4. and I am using Razor engine.
#{
string sDefaultEnvironId = string.Empty;
}
<script language="javascript" type="text/javascript" >
function changeHd() {
$("#hdSelEnvironmentId").val("1");
}
</script>
<input type="button" value="ChangeHD" onclick="changeHd();" />
#Html.Hidden("hdSelEnvironmentId", sDefaultEnvironId)
The value of hidden field hdSelEnvironmentId is empty when accessing this view at first time. then it was changed to 1 after I clicked button ChangeHD.
But after I pressed F5, the value of hidden field hdSelEnvironmentId is still 1, I expected it with initial empty value instead of 1. Can anyone help me to figure it out ?I just can not understand it. I am using Firefox and Firebug, thanks.
Edit As discovered by Andreas here, you can remove this behavior by adding an attribute autocomplete=off to your input:
#Html.Hidden("hdSelEnvironmentId", sDefaultEnvironId, new { autocomplete = "off" })
This effect is not due to the cache -- it's a feature (bug?) of Firefox, that when you refresh a page, the inputs of the page do not seem to get re-loaded from the server.
try the same thing in Chrome or IE, you'll see that the value resets to empty
clear the cache in Firefox, and you'll notice the value still does not get reset.
So, I'm not sure if there's a workaround, but this issue does seem to be restricted to Firefox.
instead of setting it in
#{
string sDefaultEnvironId = string.Empty;
}
just initialize it in JavaScript.
$(document).ready(function(){
$("#hdSelEnvironmentId").val() = "";
});
function changeHd() {
$("#hdSelEnvironmentId").val() = "";
$("#hdSelEnvironmentId").val("1");
}
i think this will help.. even on page refresh as document loads again the value will be set to empty and then to 1 on button click

Cross-browser client-side redirection in a new tab or window

we need a kind of client-side redirection and the only options we have are:
window.location
window.open
HTTP 301, 302, 303 responses
window.location doesn't support opening the target location in a new tab or window. (I think this is related to browsing context)
window.open doesn't work in Chrome and seems to be dependent upon some client-side configurations made to the browser, which makes it a less favorable option, since we don't have control on it.
HTTP redirect response doesn't open a new tab or window, just like window.location.
Any idea?
After playing around with this for hours last night, I had a flash of inspiration this morning, and I have just tested this solution in FF3, Chrome, IE7 and IE8 - it's a bit hacky but it works in all.
<html>
<head>
<title>Redirect in a new window</title>
<script type="text/javascript">
function doIt () {
var form = document.createElement('form');
form.action = 'http://www.google.com/';
form.target = '_blank';
document.getElementById('hidden_div').appendChild(form);
form.submit();
}
</script>
<style>
#hidden_div {
display: none;
}
</style>
</head>
<body>
<div>
This is my page content<br />
This is a link to Google...<br />
...and this button will open Google in a new tab or window: <input type="button" value="Click Me!" onclick="doIt();" />
</div>
<div id="hidden_div"></div>
</body>
</html>
How It Works
You need a hidden <div> on your page somewhere that you can get a reference to in JS (no big deal - just create one with display: none).
When you want to do the redirect, use document.createElement() to create a new <form> element, assign it's action attribute with the address of the page where you want to take the user, and give it a target attribute as appropriate (I have used _blank in my example above). Then simply append it to your hidden <div> and call it's submit() method.
Hey presto, your redirect opens in a new window/tab!
Unfortunately you are still at the mercy of how the user configures their browser to handle target="_blank" but it will be either a new window or a new tab, and it should work everywhere...

Call onresize from ASP.NET content page

I have a JavaScript method that I need to run on one of my pages, in particular, the onresize event.
However, I don't see how I can set that event from my content page. I wish I could just put it on my master page, but I don't have the need for the method to be called on all pages that use that master page.
Any help would be appreciated.
Place the following in your content page:
<script type="text/javascript">
// here is a cross-browser compatible way of connecting
// handlers to events, in case you don't have one
function attachEventHandler(element, eventToHandle, eventHandler) {
if(element.attachEvent) {
element.attachEvent(eventToHandle, eventHandler);
} else if(element.addEventListener) {
element.addEventListener(eventToHandle.replace("on", ""), eventHandler, false);
} else {
element[eventToHandle] = eventHandler;
}
}
attachEventHandler(window, "onresize", function() {
// the code you want to run when the browser is resized
});
</script>
That code should give you the basic idea of what you need to do. Hopefully you are using a library that already has code to help you write up event handlers and such.
I had the same problem and have come across this post :
IE Resize Bug Revisited
The above code works but IE has a problem where the onresize is triggered when the body tag changes shape. This blog gives an alternate method which works well
How about use code like the following in your Content Page (C#)?
Page.ClientScript.RegisterStartupScript(this.GetType(), "resizeMyPage", "window.onresize=function(){ resizeMyPage();}", true);
Thus, you could have a resizeMyPage function defined somewhere in the Javascript and it would be run whenever the browser is resized!

Resources