I'm trying to get the height/width of an image using JQuery.
It won't work until the image is fully loaded by using $(window).load.
When doing an asp.net UpdatePanel, the events are unbind from the elements. I've tried using ScriptManager.RegisterStartupScript to call a Javascript function to bind all of the events again, but it won't run the $(window).load. Please help.
External JS Code
$(window).load(function () {
WindowLoad();
});
function WindowLoad() {
alert($("#test").width());
}
C# Code
protected void Page_PreRender(object sender, EventArgs e)
{
if (IsPostBack)
{
ScriptManager.RegisterStartupScript(this, this.GetType(), "WindowLoad" + DateTime.Now.Ticks, "WindowLoad();", true);
}
}
protected void Previous_Click(Object sender, ImageMapEventArgs e)
{
String value = e.PostBackValue;
if (value == "test")
{
imgTest.ImageUrl = IMAGEPATH;
}
}
When the page first loads. The $(window).load gets the height/width of the image just fine because it waits for the image to finish loading onto the page before it displays the width/height.
When you click on the imagepath, it'll do a partial postback. When that occurs, the JS are unbind from the elements. Previous_Click will run first and then the Page_PreRender to register the JS on the elements. This is where I need to make sure I get the height/width of the image again. So that JS can do some recalculations. On the partial postback, the results ends up being 0. I do notice that the UpdatePanel takes a while to update the image path, so they may have some cause as to why the results become 0, but I would assume the UpdatePanel will finish loading everything first before trying to run the WindowLoad function.
Related
I am trying to add a basic switch to my site in order to switch between static and responsive layouts.
I have two linkbuttons at the bottom of my page:
<div id="toggleView">
<asp:linkbutton ID="lbtnMobile" runat="server" Visible="false">Switch to Mobile site</asp:linkbutton>
<asp:linkbutton ID="lbtnFull" runat="server" >Switch to Full site</asp:linkbutton>
</div>
They both have a very similar OnClick event.
protected void lbtnFull_Click(object sender, EventArgs e)
{
c.ViewChange = true;
Session["Customer"] = c;
}
protected void lbtnMobile_Click(object sender, EventArgs e)
{
c.ViewChange = false;
Session["Customer"] = c;
}
The events should set a boolean in a class file (User.vb) between true or false and then save the session, on postback the Page_Load event is supposed to read this boolean and use it to adjust the Viewport meta tag:
protected void Page_Load(object sender, System.EventArgs e)
{
//Other Stuff in here, irrelevant to current question
HtmlMeta view = new HtmlMeta();
view.Name = "viewport";
if (c.ViewChange = false)
{
view.Content = "width=device-width, initial-scale=1";
lbtnFull.Visible = true;
lbtnMobile.Visible = false;
}
else
{
view.Content = "width=1040px, initial-scale=1";
lbtnFull.Visible = false;
lbtnMobile.Visible = true;
}
MetaPlaceHolder.Controls.Add(view);
}
However, when I click on the "Switch to Full Site" linkbutton, the page will postback but nothing will have changed. Does the postback get triggered too early somehow?
The page load event will happen BEFORE your click event. Reference this here.
This means your check for the ViewChange will happen before you set it in the OnClick handler.
You should change
if (c.ViewChange = false)
to
if (c.ViewChange == false)
for something to happen. But I think it won't be what you expect. Because page_load is executed before click event. You may move some code from page_load to click event handlers.
When ever you postback the Page_Load always get called. So, the code mentioned inside Page_Load would always get executed.
protected void Page_Load(object sender, System.EventArgs e)
{
... All your mentioned code will be executed.
}
Therefore, you won't find any change in your HTML page currently viewed in a browser because at postback initial content also got executed. You need to wrap your content inside !IsPostBack to make it work properly.
Thus, modify you code in following way.
protected void Page_Load(object sender, System.EventArgs e)
{
if(!IsPostback)
{
... All your mentioned code will be executed during normal load.
}
}
Also, you need to add some extra code in LinkButton click event i.e. what to show and what to hide.
Firstly your implementation in the Page_Load isn't very clear.
Nevertheless this is what I recommend, from what I've understod:
As the page load will get executed before the post-back event like the buton or link click, you need persist the value of the class object
Make a protected property of type of your class (where you store/manage the ViewChange atribute)
The property should internally (in the get & set), hold/persist the value in session/viewstate (similar to what you've written)
The setting and reading should only be by referring the property directly (and not how you've done the click-event)
On clicking of the button and post setting the new value, you will have to redirect to the same page, as only then the Page_Load event will get the new boolean value that you've just changed in the click-event; (Page_Load occurs befoer the any other post-back event)
An alternative to the fresh redirection is that, you could make a function that has the view changing logic (as depicted in your Page_Load code), and this function should be called on your button/link click event (post boolean value change) and also in the Page_Load event, but within the "!IsPostBack" block
Hope this helps you.
I have a xaml page in which I have used a webbrowser control.I need to scroll down to the web page and once the bottom is reached,I have to enable a button.
Thanks in advance!
There's two part to this. The first is to detect, in Javascript, the moment when the browser reaches the bottom of the page. The second is to forward the event to the C# code.
Say you ask your WebBrowser control to navigate to a given page. First, in the C# code, subscribe to the Navigated event to inject the proper Javascript code:
private void WebBrowser_Navigated(object sender, NavigationEventArgs e)
{
const string Script = #"window.onscroll = function() {
if ((window.innerHeight + document.documentElement.scrollTop) >= document.body.offsetHeight) {
window.external.notify('bottom');
}
};";
this.WebBrowser.InvokeScript("eval", Script);
}
This Javascript code uses the window.external.notify method to notify the C# code. To receive the notification, you need to subscribe to the ScriptNotify event of the WebBrowser:
private void WebBrowser_ScriptNotify(object sender, NotifyEventArgs e)
{
if (e.Value == "bottom")
{
// Reached the bottom of the page
}
}
I have been scratching my head on this one for a few hours now and the issue seems to be interesting. I seem to be missing the __doPostBack event that should come with my control but it does not. Some have suggested adding:
ClientScript.GetPostBackEventReference(this, string.Empty);
this however, while it does create a function definition I am looking for, no matter what I do the page reloads on the postback event. As some have mentioned in:
__doPostBack is not defined
this is because the control ID does not match/not found.
I am obviously doing something wrong considering that 1) The postback function does not render without being brute forced in 2) Even when brute forced in, the postback cannot find the appropriate setup. Here are the snippets of code:
Class definition
[ParseChildren(true)]
[PersistChildren(true)]
[ToolboxData("<{0}:Accordion runat=server></{0}:Accordion>")]
public class Accordion : DataBoundControl, IPostBackEventHandler
Events
public event JQUI_Event ItemClick;
Click handler, RaisePostBackEvent, and the OnLoad which appends the __doPostBack
public void RaisePostBackEvent(string eventArgument)
{
ItemClick(null, null);
}
protected override void OnLoad(EventArgs e)
{
Page.ClientScript.GetPostBackEventReference(this, string.Empty);
base.OnLoad(e);
}
protected virtual void OnClick(EventArgs e)
{
if (ItemClick != null)
{
ItemClick(null, null);
}
}
Finally the code which generates the the postback:
if (ItemClick != null)
{
outPut += "<script> $(function() { $('#" + ClientID + "').find('div').on('click', function() { __doPostBack('" + UniqueID + "', '') }); }); </script>";
}
writer.Write(outPut);
Let me know if you need more code. I didn't want to just throw a long page of code and just tell people to figure it out.
EDIT:
Ok, got the RaisePostBackEvent(string eventArgument) to get called. However, the issue I am having is that the page still decides to reload. I have tested to make sure that it calls the correct function in the correct control (not just because it's a postback). Is there a way to limit this to a partial postback rather than a full postback?
See the GetPostBackEventReference documentation, which shows it returns a string, which contains the __doPostBack method call. It's not a registration method for the control. You then render this string with your control. The __doPostBack is not an automatic output when you are using custom controls.
Having just added a new button in my web application, I get an error when clicking on it, and I'm wondering if this is related to misplaced code. I will describe what/where I did, briefly. Thanks very much.
In ascx file:
<asp:Button ID="btn_rezerv" runat="server" Text="Reserve film" OnClick="btn_rezerv_Click"/>
In the ascx.cs file:
namespace CinProj.UserControls
{
public partial class FilmsList : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
PopulateControls();
}
private void PopulateControls()
{
string categId = Request.QueryString["CategID"];
string filmId = Request.QueryString["FilmID"];
....
if (categId != null)
{
.....
}
if (filmId != null)
{
......
Button btn_rezerv = (Button)item.FindControl("btn_rezerv");
}
}
protected void btn_rezerv_Click(object sender, EventArgs e)
{
string fid = Request.QueryString["FilmID"];
ShoppingCartAccess.AddItem(fid);
}
}
}
"Server Error in '/' Application.
Invalid postback or callback argument. Event validation is enabled using in configuration or <%# Page EnableEventValidation="true" %> in a page. For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them. If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation. "
Another problem could be because your PopulateControls method should probably only be called when during the Page Load when it's not a PostBack. I can't tell from above, but to me it looks like it only needs done on Load. Try wrapping that call with this:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
PopulateControls();
}
}
It's likely the result of making some sort of client change that the server doesn't know about. Many times this is the result of changing values in a dropdown in JavaScript, for example.
To fix, you could:
Do away with using JavaScript for said modification
Use an UpdatePanel and add your control to it. If the client needs to make a change, trigger the UpdatePanel's update in order for the control's viewstate to update.
I have a problem with a webform.
My Goal: Intially when a page is loading, it has to load every textbox empty. After filling the info and click submit, it has to get submitted(UpdatePaymentInfo())
Problem: Here, When the user fills the info and clicks Submit,it calls onload function even before the submit button and makes all text box empty.
Here is the code:
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
string QueryStringupdatecreditcard1 = Request.QueryString.ToString();
if (String.Equals(QueryStringupdatecreditcard1, "tabID=B"))
{
divTitle.Visible = false;
trmain.Visible = false;
tdOrderSummary.Visible = false;
trCCandBilling.Visible = true;
trtest2.Visible = false;
divUpdatecreditcard.Visible = true;
trusecompaddress.Visible = false;
txtFirstName.Text = "";
txtLastName.Text = "";
txtAddress1.Text = "";
txtAddress2.Text = "";
txtCity.Text = "";
txtZip.Text = "";
txtCardNo.Text = "";
txtVccNumber.Text = "";
trAmountCharged.Visible = false;
}
}
protected void imgbtnSubmit_Click(object sender, ImageClickEventArgs e)
{
try
{
UpdatePaymentInfo();
}
}
Wrap the current contents of your OnLoad method in:
if (!Page.IsPostBack)
{
// Code in here will only be executed when the page is *not* being loaded by a postback
}
This is because, as per the ASP.NET Page Life Cyle, the things that you care about in this instance happen in this order:
Load - During load, if the current request is a postback, control
properties are loaded with information
recovered from view state and control
state.
Postback event handling - If the request is a postback, control event
handlers are called. After that, the
Validate method of all validator
controls is called, which sets the
IsValid property of individual
validator controls and of the page.
So what happens is (somewhat simplified):
You click the image button, triggering the postback.
The data from your form is loaded into your controls.
Your OnLoad method overwrites the values in the controls to clear them.
Your click handler is run, but because of step 3 it sees empty values.
As others have sort-of mentioned, it wouldn't necessarily be a bad thing to refactor your OnLoad method whilst you're doing this. At the moment you seem to have it doing two distinct things:
Clearing the text fields
Setting the visibility of fields
It might be worth separating this into one or two (depending on if the visibility setting and field clearing will be done independently) separate methods and adjusting your OnLoad method so it looks like this:
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (!Page.IsInPostBack)
{
SetFieldVisibility();
ClearFields();
}
}
Page_Load always occurs.
See the documentation on the Page Lifecycle
What you need to do is check to see if the Page_Load is being triggered by a Postback.
private void Page_Load(object sender, System.EventArgs e)
{
if(!Page.IsPostBack)
{
///do stuff in here that you want to occur only on the first lad.
}
else
}
// code that you want to execute only if this IS a postback here.
{
}
// do stuff you want to do on Page_Load regardless of postback here.
}
You can use the IsPostBack property of the Page as follows:
protected override void OnLoad(EventArgs e) {
if (!Page.IsPostBack) {
EmptyTextBoxes();
}
}
Have you tried wrapping the form reset code in a check to see if the page is a postback?
if(!Page.IsPostback) {
// Do form reset here
}
You thought about using the IsPostBack page variable?
protected override void OnLoad(EventArgs e)
{
if(!IsPostBack){
//all your logic here.
}
}
if it's the case, you might use a databound control and set it to insert mode