I'm looking for an alternative to window.stop() for IE. I have tried document.execCommand('Stop'), but it doesn't seem to work. I'm trying to cancel a XMLHttpRequest which is called from within a ASP user control i'm using. I can't use jQuery's .abort() since i do not set the request my self.
I assume control on the page uses jQuery.ajax and you know when you need to abort the request, under your criteria.
How about something like this?
(function ($) {
var xhr = null,
originalAjax = $.ajax,
updatedAjax = function (url, options) {
xhr = originalAjax(url, options);
};
$.ajax = updatedAjax;
})(jQuery);
Now you have a variable called xhr which holds the underlying xmlhttp object. You can call abort() on the object when you need to.
The draw back is that variable will be populated for each ajax request done by jQuery, and I would only include this script on that particular page, maybe even reset the ajax when you are done.
I haven't tried this, just an idea, as I have been mocking ajax calls all the time. Some might think that this approach is a little bit drastic!
Hope you find it useful.
If you have access to the object you can do it with the object's abort() and onreadystatechange event handler. Here is a working example I tweaked from w3schools
<html>
<head>
<script type="text/javascript">
function loadXMLDoc()
{
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==2){ xmlhttp.abort();}
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","xmlhttp_info.txt",true);
xmlhttp.send();
}
</script>
</head>
<body>
<h2>Using the XMLHttpRequest object</h2>
<div id="myDiv"></div>
<button type="button" onclick="loadXMLDoc()">Change Content</button>
</body>
</html>
As you can see, the request text is not loaded because it gets aborted.
I understand you don't set the request yourself, but do you have any kind of access to it, so that you can use the onreadystatechanged-event in javascript? If so, you can then determine whether or not you have to cancel the event.
Related
I have this code in some of my ASCX files:
<%=Html.ActionLink(Resources.Localize.Routes_WidgetsEdit, "Edit", "Widget",
new { contentType = Model.ContentType, widgetSlug = Model.Slug, modal=true},
new
{
rel = "shadowbox;height=600;width=700",
title = Resources.Localize.Routes_WidgetsEdit,
#class = "editWidget"
})%>
Take note of that rel="shadowbox..." there. This is to wire up ShadowBox Lightbox clone for this ActionLink.
This works fine when user requests a page containing this User Control thru normal browser request. But I also render/build those View User controls trough AJAX requests. For instance, I would make request to /Widget/RenderToString/... using jQuery .ajax() method and it would return HTML code for that control. This works fine and it renders the code fine. I would then insert (append) the result to a DIV in a page from where the AJAX request was made. This also works fine and the returned HTML gets appended. The only problem is - ShadowBox is not wired up. Even though the code for it gets rendered.
It seems it requires page reload (F5) every time to wire ShadowBox up. Since I am doing AJAX GET and instant append to get rid of having to make a server roundtrip, I would also want ShadowBox to wire up without doing refresh.
Can someone help me with that? Thank you
UPDATE:
Yes, I have this in my Site.Master head:
<script src="<%=Url.Content("~/Scripts/shadowbox-build-3.0rc1/shadowbox.js") %>" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
// insert functions calls here that provide some default behaviour
externalLinks();
});
Shadowbox.init({
language: "en",
players: ["img", "html", "iframe"],
onClose: function() { location.reload(true) }
});
</script>
How do I init the Shadowbox again after AJAX call?
There are many shadowbox plugins... which one are you using? (I can't give you exact code without it.) In any case I imagine you have something in your $(document).ready(function () { ... }); that tells shadowbox plungin to bind itself. You need to call that again after the AJAX call.
Just found the solution here
// call this after adding the new HTML to the page
// set up all anchor elements with a "editWidget" class to work with Shadowbox
Shadowbox.setup("a.editWidget", {});
Suppose we have the following HTML file:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Test iframe download</title>
<script type="text/javascript">
var init = 0;
function download() {
document.getElementById("dload_frame").src = "http://example.com/dload.py";
}
function alert() {
if (init == 0) {
init = 1;
}
else {
document.getElementById("alert_span").innerHTML = "Got it!";
}
}
</script>
</head>
<body>
<span id="alert_span">Main content.</span><br/>
<input type="button" value="Download" id="btn" onclick="download()" />
<iframe id="dload_frame" src="http://404.com/404" onload="alert()"> </iframe>
</body>
</html>
Now, if the URL to which iframe's src is being rewritten to (in this case - "http://example.com/dload.py") returns HTML, no problem: the onload event fires, the span's contents are replaced, everybody's happy.
However, if the content type of the file returned by the URL is set to something that forces the browser to open the save file dialog, the iframe's onload event never fires.
Is there any workaround? Using iframes isn't necessary, the desired behavior is to launch a callback after the browser begins downloading the supplied file.
I have encountered the same problem as this:
Here is my work-around, please see if it works for you:
<script>
function download(){
var url = 'http://example.com/dload.py';
var htm = '<iframe src="' + url +'" onload="downloadComplete()"></iframe>';
document.getElementById('frameDiv').innerHTML = htm;
}
</script>
<div style="display:none" id="frameDiv">
</div>
<button onclick="download()">download file</button>
As far as I can remembered iframe's onload event fires only once.
Setting another value for src attribute will not cause the onload event to fire again.
I have the same problem, onLoad handler is only fire when the content change. If you download a file. If you delete HTTP header to print file content on iframe, the onload is correctly fire.
My solution after many different approaches to get this working across ff ie safari and chrome was not have a 2 step download.
the original JS request to create an iframe loads a src that would normally have loaded the pdf
However, the src now loads a page with yet another iframe inside of it, which now contains the url of the pdf.
in the html response I trigger the onload and also a catchall setTimeout funciton which calls my response on window.parent.window.handlerfunction which my onload on the top iframe would have been. The result is a PDF download and a trigger on the top level parent of the handler function that works across the browsers since it no longer relies on detecting an actual iframe load but rather relies on supported parent/child window relationships.
hope this helps someone who was also stuck
You can check iframe readyState property repeatedly after short time intervals until it gets completed.
function iframe_onload(iframe_id, js) {
var iframe = document.getElementById(iframe_id);
var iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
if (iframeDoc.readyState == 'complete') {
eval(js)
return;
}
window.setTimeout('iframe_onload("' + iframe_id + '",`' + js + '`);', 100);
}
You might need help of jquery for this, for instance you can do this:
$.get('http://example.com/dload.py',{},function(result){
$('alert_span').html(result);//or some content
});
I have an ASP.NET page with a number of ASP:Button instances on it. For some, I need to show a confirmation prompt and, should the user choose yes, the original postback method is called. Otherwise, the overall process is cancelled.
I've got an example running but I get inconsistent results, mainly in FF3 where I get an exception thrown:
[Exception... "Illegal operation on WrappedNative prototype object" nsresult: "0x8057000c (NS_ERROR_XPC_BAD_OP_ON_WN_PROTO)" location: "JS frame ::
I've looked this error up but I'm drawing a loss as to where I'm going wrong. Here's my example case. Note, for now I'm just using the css class as a lookup. Longer term I can embed the clientID of the control into my JS if it proves necessary :).
Html fragment:
<asp:Button ID="StartButton" runat="server" CssClass="startbutton" Text="Start" OnClick="OnStartClicked" />
Javascript:
$(".startbutton").each(function(){
$(document).data("startclick", $(this).get()[0].click);
$(this).unbind("click");
}).click(function(){
var oldclick = $(document).data("startclick");
alert("hello");
try
{
oldclick();
}
catch(err)
{
alert(err);
alert(err.description);
}
return false;
});
My code behind is relatively simple, the OnStart method simply executes a Response.Write
I've only just started looking into bind, unbind and trigger so my usage here is pretty much 'first time'.
Thanks for any help or advice.
S
EDIT:
This describes what I'm trying to do and also gives a run down of the kind of pitfalls:
http://www.nabble.com/onClick-prepend-td15194791s27240.html
How about this?
$(document).ready( function() {
$('.startbutton').click(function() {
return confirm('Are you sure?');
})
});
I've solved my problem for IE7 and FF3.
The trick is to make the postback work as an 'onclick' via an ASP.NET attribute on the button (see below). In Javascript this gets pulled out as a function reference when you read the click in JQuery.
To make it work, you then clear the onclick attribute (after saving it) and call it later on.
My code below shows it in action. This code isn't complete as I'm part way through making this into a generic prompt for my application. Its also a bit badly laid out! But at least it shows the principle.
ASP.NET button
<asp:Button ID="StartButton" runat="server" CssClass="startbutton" Text="Start" OnClick="OnStart" UseSubmitBehavior="false" />
Javascript:
$(".startbutton").each(function(){
$(document).data("startclick", $(this).attr("onclick"));
$(this).removeAttr("onclick");
}).click(function(){
$.blockUI({ message: $('#confirm'), css: { width: '383', cursor: 'auto' } });
$("#yes").click(function(){
$.unblockUI();
var oldclick = $(document).data("startclick");
try
{
oldclick();
}
catch(err)
{
alert(err);
alert(err.description);
}
});
$("#no").click(function(){
$.unblockUI();
});
return false;
});
Your problem comes from here :
$(document).data("startclick", $(this).get()[0].click);
...
var oldclick = $(document).data("startclick");
...
oldclick();
Here, you try to intercept a native event listener but there are two errors :
Using unbind will not remove the native event listener, just the ones added with jQuery
click is, AFAIK, a IE only method used to simulate a click, it not the event handler itself
You'll have to use onclick instead set its value to null instead of using unbind. Finally, don't store it in $(document).data(...), you'll have some problems when you add other buttons. Here is a sample code you can use :
$("selector").each(function()
{
var oldclick = this.onclick;
this.onclick = null;
$(this).click(function()
{
if (confirm("yes or no ?")) oldclick();
});
});
for mi works:
this.OnClientClick = "$.blockUI({ message: $('#ConfirmacionBOX'), css: { width: '275px' } });return false;";
This is a button (is a button class)
Is there a way to execute script when an UpdatePanel process is finished.
I have a page that allows "inserting", "copying", and "editing" of a record.
This is all done on an UpdatePanel to prevent a page navigation.
Somewhere else on the page I would like to print a "flash" message - like "You have successfully entered a record." It is not near the UpdatePanel and I'd like to use a jQuery effect on the message so it fades out after 4 seconds. How can I send script back with the UpdatePanel or have it execute after a UpdatePanel refresh? Should I write script to an asp:literal? thoughts?
Yes:
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(endRequestHandler);
And then:
function endRequestHandler(sender, args)
{
// Do stuff
}
Documentation here and here. Keep in mind that this will fire for every AJAX request on the page.
This should do the trick:
<script type="text/javascript">
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_beginRequest(BeginRequestHandler);
prm.add_endRequest(EndRequestHandler);
function BeginRequestHandler(sender, args)
{
//Jquery Call
}
function EndRequestHandler(sender, args)
{
//Jquery Call
}
</script>
Here is an article for how to do it using ScriptManager's static method RegisterClientScriptBlock. Tried it and works like a charm.
http://csharperimage.jeremylikness.com/2009/06/inject-dynamic-javascript-into-aspnet.html
var requestManager = Sys.WebForms.PageRequestManager.getInstance();
requestManager.add_beginRequest(function () { alert('here1') });
requestManager.add_endRequest(function () { alert(here2') });
Source: http://www.howtositecore.com/?p=36
The Sys.WebForms.PageRequestManager.getInstance() method works great for me as well.
I work with a lot of pages that contain multiple Updatepanels and I've learned that this will automatically fire even if the Updatepanel you don't want it for refreshes. So inside the function that fires on the event make sure you have something like:
function BeginRequestHandler(sender, args) {
if (args.get_postBackElement().id == "ID of the Updatepanel") {
// do stuff here
Bruno,
First, to answer your direct question. In your callback that is being called by the update panel, you should be able to use a RegisterStartupScript call to invoke a JS method . Then in your JS method, you would show the message and then you can use do a:
setTimeout('$('#myMessage').fadeOut("slow")', 4000);
to have it fade away after 4 seconds.
To go one step further, since you're already implementing JavaScript, I would invite you to check out this article about UpdatePanels. If possible, I would try to send Ajax calls to do your inserting, copying, and editing and this would further simplify your user feedback and would prevent excess info across the wire.
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!