Page out of frame load event runs several times - c#

I have an iframe on my first page and am redirecting the frame to second page on my second page I am using javascript to jump out of iframe as follow :
<script language="JavaScript" type="text/javascript">
<!--
function breakout_of_frame() {
if (top.location != location) {
top.location.href = document.location.href;
}
}
-->
</script>
My problem is that this will make the page run several times and my code in load event will execute (say if i am sending email on load will send three times).
Now I have tried using boolean values to see when email is sent set it to true and dont send if false...but it still will not work. any suggestions to prevent this from happening?

A simple, rough and ready solution:
On your following request, append something to the query string of your request to identify the difference between the two pages.
When you read document.location.href, parse it for the differing element and react accordingly.
for example:
your-domain/your-path/your-file?donealready=yes
alert(document.location.href) //will have the parameter at the end
//parse this to determine how to react

Related

Setting Content in RadEditor

I have visited the Telerik's website and viewed their demos etc...
But I am having problems trying to load content (html) in the RadEditor.
I have a Button_Click event where I get my html string and then set it to the RadEditor. The RadEditor is inside a RadWindow and only becomes visible when the button is clicked.
protected void btnSubmitHtml_Click(object sender, EventArgs e)
{
RadEditor1.Content = "<p>hello there</p>";
RadWindow1.Visible = true;
}
This doesn't show the html inside the RadEditor for some odd reason. I suspect it is the page life cycle that is involved with this problem.
Are there any suggestions to solve this?
I have encountered this problem multiple times and never found a "Proper" resolution.
However, a great work around is to simply set the content from the clientside via injected script. The end result is the same, and if you can tolerate the 10 millisecond delay, worthy of consideration.
EDIT after comment requested reference
Basically all you need to get an instance of the editor using ASP.NET WebForms $find function. That takes the html ID of the root of the rendered object and returns the client side viewModel if one exists.
The $(setEditorInitialContent) call at the end assumes that jQuery is present and delays the execution of the function till page load.
<telerik:radeditor runat="server" ID="RadEditor1">
<Content>
Here is sample content!
</Content>
</telerik:radeditor>
<script type="text/javascript">
function setEditorInitialContent() {
var editor = $find("<%=RadEditor1.ClientID%>"); //get a reference to RadEditor client object
editor.set_html("HEY THIS IS SOME CONTENT INTO YOUR EDITOR!!!!");
}
$(setEditorInitialContent);
</script>
Take a look here to see how to get a RadEditor to work in a RadWindow: http://www.telerik.com/help/aspnet-ajax/window-troubleshooting-radeditor-in-radwindow.html.
Said shortly, here is what you need to have in the OnClientShow event of the RadWindow:
function OnClientShow()
{
$find("<%=RadEditor1.ClientID %>").onParentNodeChanged();
}
To edit Html code only you can add -
EnableTextareaMode="true"
Add this property to the RadEditor.
I suspect that the way the control tries to interpret the html might be one of the problems. The other thing that may be causing this problem is the page life cycle.

How do I fire a aspx script when a dynamically added button is clicked?

Here is the context:
I am building a .aspx page that allows the user to administrate some xml documents we have on our server. The page content is loaded using AJAX, so buttons and forms are dynamically added to the document.
If I had static buttons that I was creating within the .aspx page before it loads on the client's machine, I could attach an event to it very easily. However, I'm dynamically adding and removing buttons and forms on the fly, using jQuery.
Here is a simplified example:
In the following jsFiddle, I'm pretending that the html document contains the following script:
<script language="C#" type="text/C#" runat="server">
void SaveAllChanges(Object sender, EventArgs e)
{
Button clickedButton = (Button)sender;
clickedButton.Text = "foobar";
}
</script>
And that I have a javascript file that contains the following:
$('button.buttonGenerator').click(function() {
$('.buttonContainer').append(
'<button onclick="SaveAllChanges">' +
'Save All Changes!' +
'</button>'
);
});
Obviously the buttons I am creating can not run the function SaveAllChanges with the way it is now. I added the onclick attribute to show what I needed to happen, in a pseudo-code kind of style.
How can I make it so that dynamically added buttons can run the C# method I have defined within the script tag at the top of the document?
Here is the jsfiddle: http://jsfiddle.net/2XwRJ/
Thanks.
You can give all buttons that must save changes a common class (e.g. class="ajaxButton") and have one jQuery method that responds to click events on elements matching that class (use live so that updates to the DOM are reflected).
$("button.ajaxButton").live("click", function(){
// Perform your Ajax callback to run server-side code
});
What you need to do is use something like ..
$(document).ready(function() {
$('button.buttonGenerator').click(function() {
$('.buttonContainer').append(
'<button id="#dynamicCommentButton" onclick="SaveAllChanges">' +
'Save All Changes!' +
'</button>'
);
});
$(document).on('click', '#dynamicCommentButton', function() {
alert($(this).attr('id'));
});
});
You are not going to be able to add the buttons like you have it there as this code here is just adding it as an HTML DOM element and the onclick attribute will be the on the client element. As a result clicking the button will try fire a SaveAllChanges javascript function
$('.buttonContainer').append(
'<button onclick="SaveAllChanges">' +
'Save All Changes!' +
'</button>'
);
What would be best would be to create that SaveAllChanges function in javascript and then you can handle it from there. Two of the ways I see you being able to do this are:
Have a http endpoint setup (script service, web api or just posting to a page) that you call using Ajax from your javascript. You can then pass through any needed arguments.
You could have a hidden element and hidden button on the page so that when the javascript is called it populates any arguments you need and then clicks the hidden button and posts the page back.
Personally I would choose the first approach from a user experience stand point as the page will not be posting back each time. I have used something similar to the second approach and it works fine but just feels very clunky.

How to stop browser back button showing a page I have left

I am using MVC2 and VS2010.
We have created a web application but want to stop any browser re-visiting pages after the page has been left.
We want to do this so that someone who is using a public computer who then leaves can feel safe. We dont want the scenario that a following user can just use the back button to view the first uses pages.
I have tried [OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
This seems to work fine and I get a Web Page Expired. But if I press the browser back button again, the page will be displayed.
I have quite a similar situation myself in wanting to prevent a browser back situation and have researched a few different solutions. The first and worst being a Java script function which takes the user back to the page they were on if they click the back button in the browser. It hides the problem rather than solving it but thought id mention it. The code as follows:
<script type="text/javascript" language="javascript">
function disableBackButton() {
window.history.forward()
}
disableBackButton();
window.onload = disableBackButton();
window.onpageshow = function (evt) { if (evt.persisted) disableBackButton() }
window.onunload = function () { void (0) };
</script>
This works for Firefox, Chrome and IE ok. You can just put this in your master page.
Many people will tell you this is not the way to do things however as it intrudes on the well known browser behaviour etc etc
So my second suggestion is something I have seen here:
Disable browser cache for entire ASP.NET website
Which will not cache anything which is more inline with what you are wanting I think.
Another idea would be to pass a page or session token around and on actions check the token - if its invalid reroute to an error page. That would at least prevent a new user doing anything with the previous page.
Id be interested to know how you solved this, if you have solved it.

Javascript event like window.onload for subsequent loads

We have a function that changes the iframe height at the window.onload event so we can adjust it to the page contents. The problem is that after clicking in an asp:menu the height its restored to its default and the window.onload event doesnt fire...so we need the event that would fire in subsequent loads (tried window.unload but didnt trigger)
The resize function cant be called on the asp:menu click because the window wouldnt have finished loading so the height calculation would fail...
Any ideas??
ASP.Net AJAX exposes a client event model. To execute code after the content is refreshed, use this to bind to the pageLoaded event:
Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(pageLoadedFunction);
Learn more about all of the ASP.Net AJAX JavaScript events here: http://msdn.microsoft.com/en-us/library/bb386417.aspx
ASPNet uses background calls via AJAX and then updates the interface.
You should use servr-side code. Inspect the AJAX resolver you're using and look for its declared events. I'm sure there's one event that triggers after updating a webpage and you can attach an eventListener to it.
I had this same problem with a similar script 2 years ago. I solved it using JavaScript in the newly loaded page's window.onload to call up to the parent document and execute the script. In the child page we had this script:
function goSetHeight(){
if (parent == window) return;
else parent.setIframeHeight('iframe_name');
}
// Edit: Forgot to add the window.onload call
window.onload = goSetHeight;
This script called up to the parent page where we had a script file included that had this function:
function setIframeHeight(iframename) {
var iframeEl = document.all[iframename];
var iframeWin = window.frames[iframename];
if(iframeEl && iframeWin) {
//var docHt = getDocHeight(iframeWin.document);
//if(docHt) iframeEl.style.height = docHt + 30 + "px";
iframeEl.style.height = iframeWin.document.body.offsetHeight + 30 + "px";
}
}
Please note that the above function was written solely with IE in mind (it was an application specification), so to be usable cross browser it would need modification. The only real problem we encountered with it were 2 particular cases:
We had a couple of instances where the pages that were loaded in the iframe were from a different domain than the page holding the iframe. This causes a JavaScript security error because the browser thinks this is an XSS attack and denies it.
We also encountered several situations where the iframe was nested 2 deep. It was a hack-job work-around that I came up with that I was extremely unhappy about, but it worked while we refactored from classic asp into .Net. I have since lost the script that was used to perform the pass through, but it wasn't complicated, it simply performed a similar parent check and kept going.
In the end we used a hiddenfield where we saved the height calculated in the window.onload
document.getElementById("iframex").value = document.getElementById("iframeheight").height;
...then in the Menu1_MenuItemClick(object sender, MenuEventArgs e) we reassigned the height to the iframe: iframex.Attributes["height"] = iframeheight.Value;
This works for us (Because in our case luckily the page height doesnt change on each option selected) but doesnt resolve the original question about getting fired the window.onload event or something similar after subsequent loads in order to recalculate the new height...
We will wait so someone can give the best answer to this problem...

How do I generate JavaScript during an AJAX callback (postback) and then execute it on the browser?

In summary:
I have an ASP.NET web page that causes an AJAX postback to the server. When this event handler runs (in the code behind) it will generate some JavaScript that I then want to run in the client. Not sure how to achieve this.
In Detail:
I have an ASP.NET web page with multiple items displayed on the page.
As a "nice to have", I want to display either a green circle or a red cross next to each item (these differ depending upon each item). Since it isn't vital for the User to see these icons and also because it takes several seconds to work out which icon should be shown for each item, I want to perform this after the page has loaded, so in an AJAX callback.
My thought therefore was this. When creating the page, I would create both icons next to each object and create them with the style of "hidden". I would also make a note of each one's client ID.
Then, when the callback occurs, I fetch the necessary data from the database and then create a JavaScript function that changes the display for each of the icons I want to show from "hidden" to "visible".
I thought I could achieve this using the ScriptManager object.
Here's a very trivial version of my server side code (C#)
void AjaxHandler(object sender, EventArgs e)
{
// call to database
string jscript = "alert('wibble');";
ScriptManager.RegisterStartupScript(this, this.GetType(), "uniqueKey", jscript);
}
Obviously, here I'm just trying to get an alert to fire after the postback has occurred...in real life I'd have my JavaScript function to change the display of all the icons I want to display.
When I run this, the serverside code runs and yet nothing happens in the server.
I have also tried:
ScriptManager.RegisterClientScriptBlock()
Page.RegisterStartupScript()
Page.RegisterClientScriptBlock()
Page.ClientScript.RegisterStartupScript()
Page.ClientScript.RegisterClientScriptBlock()
but none of them work....
FireFox shows the following JavaScript error:
Error: uncaught exception: [Exception... "Node cannot be inserted at the specified point in the hierarchy" code: "3" nsresult: "0x80530003 (NS_ERROR_DOM_HIERARCHY_REQUEST_ERR)" location: "http://localhost/MyWebSiteName/Telerik.Web.UI.WebResource.axd?_TSM_HiddenField_=ctl00_RadScriptManager1_TSM&compress=1&_TSM_CombinedScripts_=%3b%3bSystem.Web.Extensions%2c+Version%3d3.5.0.0%2c+Culture%3dneutral%2c+PublicKeyToken%3d31bf3856ad364e35%3aen-US%3a3de828f0-5e0d-4c7d-a36b-56a9773c0def%3aea597d4b%3ab25378d2%3bTelerik.Web.UI%2c+Version%3d2009.3.1314.20%2c+Culture%3dneutral%2c+PublicKeyToken%3d121fae78165ba3d4%3aen-US%3aec1048f9-7413-49ac-913a-b3b534cde186%3a16e4e7cd%3aed16cbdc%3a874f8ea2%3af7645509%3a24ee1bba%3a19620875%3a39040b5c%3af85f9819 Line: 1075"]
Does anyone know if what I am trying to do is even allowed?
If not - what's my alternative?
Thank you
Since your script doesn't have enclosing <script> tags, you need to use this form of RegisterStartupScript:
ScriptManager.RegisterStartupScript(this, this.GetType(), "uniqueKey", jscript, true);
You said your initial goal was:
The idea was that the page would load, data would be sent (AJAX) to the server. The server would then generate some JavaScript based upon this data and send that back to the page. That JavaScript would then run updating the page in a specific way.
Here's a way you can do that:
given:
<asp:ScriptManager runat="server" ID="scriptManager">
</asp:ScriptManager>
<script type="text/javascript">
function endRequestHandler(sender, args) {
var dataItems = args.get_dataItems();
for(var key in dataItems){
if(/^javascript:/.test(dataItems[key])){
eval(dataItems[key].substring("javascript:".length));
}
}
}
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(endRequestHandler);
</script>
<asp:UpdatePanel runat="server" ID="pnl">
<ContentTemplate>
<asp:Button runat="server" ID="btnClick" Text="Click me!" OnClick="btnClick_Click" />
</ContentTemplate>
</asp:UpdatePanel>
You can create a click handler that does this:
protected void btnClick_Click(object sender, EventArgs e)
{
ScriptManager.GetCurrent(Page).RegisterDataItem(this, "javascript:alert('hello world!');");
}
What's happening is during the postback, the page request manager is sent a data item your code-behind. That data-item happens to be a javascript command. After the postback, the client side script manager's endRequest handler is checking for data items. Normally you'd want to see who those items are for, which is apparent by the key of the item (it's the client ID of the control that is the target of the data being sent). In your case, you could load this up with the javascript that you want to fire, tell yourself that it's a javascript because it's prepended, then dynamically evaluate the script.
So in this example, clicking the "Click Me!" button will generate a Hello World prompt whose script was actually created by the code-behind during the postback.
You'll have to be very cautious with this approach until you're comfy - I'd avoid references to "this"...
Happy coding.
B
Okay
The idea was that the page would load, data would be sent (AJAX) to the server. The server would then generate some JavaScript based upon this data and send that back to the page. That JavaScript would then run updating the page in a specific way.
Couldn't get that to work....
I got around this in the following way:
When the page loads, data is sent (AJAX) to the server. This processes the data and serialises the results updating a hidden text element, which goes back to the browser. Meanwhile, I have a JavaScript timer on the page that runs a JavaScript function that was generated when the page first loads. This function looks at the hidden text element. If that element has text (the result of the postback) then it shuts down the timer, deserialises the data and then works out how to update the page.

Categories

Resources