I add this in my Render method (custom webcontrol):
Me.Attributes.Add("onkeypress", "chang(event,this);")
If affects some textboxes if they have some properties. But there are times that i don't want this property to be set, so no javascript will be executed. I've tried to remove it in code-behind on page_load and i was going to try to remove it on prerender method but it happens before my controls Render method.
How can i remove this property?
Take a look at the ASP Events Lifecycle. As you can see, the render event is at the bottom of the execution list. Since no events are fired after render, and render is where you are adding this functionality, then render is also where you must remove this functionality.
You could try to move the function that adds it into a higher event (load for example) and then remove it on render. Either that, or when you are applying it, perform any checks to see if the objects requires it or not.
Related
All controls involved are within the same update panel.
On the initial page load, I am moving controls in the DOM as such:
DIV_Child.Parent.Controls.Remove(DIV_Child) 'Remove from original parent'
DIV_NewParent.Controls.Add(DIV_Child)
On the initial page load, I am also manipulating these controls by adding styles.
DIV_Child.Style("position") = "absolute"
DIV_Child.style("background-color") = "black"
'etc.
When a partial postback occurs, DIV_Child goes back to its original state: unmoved and unstyled.
This problem only occurs for those controls that are moved within the DOM. If I remove those lines that move the controls, the controls maintain styling and DOM-positioning between partial postbacks.
How do I prevent moved-controls from losing their styles and new positions within the DOM upon partial postback?
You need to use ContentTemplateContainer property to programmatically add or remove controls inside an UpdatePanel's ContentTemplate.
In your scenario you should add both containing DIV's (DIV_Child's parent and DIV_NewParent) as well as DIV_Child to the ContentTemplateContainer's Controls collection in PageLoad: -
upd.ContentTemplateContainer.Controls.Add(DIV_OldParent);
upd.ContentTemplateContainer.Controls.Add(DIV_NewParent);
upd.ContentTemplateContainer.Controls.Add(DIV_Child);
The problem is occurring because your markup contains the div in its original position and style, and because it differs to what is submitted in a partial postback, the UpdatePanel is returning it as a change (simplified explanation).
Please give that a try.
I would usually recommend using an UpdatePanel for something quick and dirty, but for better performance instead use jQuery Ajax and a server-side HttpHandler. While this is (a bit) more work, it does give you better flexibility and you are guaranteed that nothing is going to interfere with the DOM section that is not inside an UpdatePanel.
I will concur that using UpdatePanels is a quicker development experience but they have a number of issues, not least of which is the fact that they post the ViewState back and forth with every partial postback, which is not very efficient.
I want to assign values to server control properties in my code behind to "initialize" a form. I don't need/want these values to be added to the viewstate. (I know I can disable viewstate for a specific control, but I need viewstate as some values may change and need to be persisted during postbacks.)
At the moment for me it seems its not possible to load these values in code without having them added to the viewstate.
As I understand the following happens:
Page: PreInit
I could add values to SOME controls (its working for example with a literal control to set the text value) here BUT since control's init methods are executed later I cannot for example find a RegisterUser control and its child controls at this stage yet, they are still null. > so no solution in this specific case, there's more cases
Control: Init
I cannot reach this point from within my page, this can only be used inside the user control code for example when you write your own usercontrol and want to initialize its values, I ofcourse dont want to create my own control for each control I need to initialize with executing some logic first.
Control: TrackViewState
Viewstate Tracking is enabled so from here on after anything I set will be marked as 'dirty' and therefore added to the viewstate.
Page:Init
Page:TrackViewState
So am I right in saying:
In code behind, without disabling a controls viewstate property..
You can initialize "1st level" child control properties from the page control in the PreIinit method without having the value being added to the viewstate.
You cannot initialize Child control properties from controls that are "1st level" child controls of the page without having the value added to the viewstate.
?
Then,
You can initialize control properties declaratively by using resources, but this does not circumvent the scenario where you need to execute logic
You can execute logic by using databinding syntax but you would have to manually call databind on the control having the same issues as above
Is there no way to iterate a set of controls/child controls and initiate values in code behind withouth having these values added to the viewstate?
With no reactions here and some further research, I am now at the point to conlude that you can indeed NOT iterate a set of controls/childcontrols and initiate values in code behind without having these values added to the viewstate, because of reasons mentioned in the question.
There are some partial solutions however as made clear here: http://weblogs.asp.net/infinitiesloop/archive/2006/08/03/Truly-Understanding-Viewstate.aspx
One possibility is to hook into the init event of the control itself declaratively, you would have to do that for each control. In code behind, inside the event handler you can set the property and since viewstate is not tracking yet it will not be saved in viewstate.
There are more options for different scenario's for example initializing dynamically added child controls inside a custom control by overriding the CreateChildControls method. Definately worth reading the above mentioned 'Truly Understanding Viewstate' link.
Problem: Content Page with Wizard Control with UpdatePanel and Placeholder. Above the UpdatePanel is a DropDownList. I need to display different input controls below the drop-down list when the user changes the selection in the drop-down list. When the user clicks 'Next' on the wizard control, I need to be able to get the data out of those dynamic controls as well.
I know all the dynamic controls have to be created in the OnInit method in order to get the data back from those controls during the postback. However, when the drop-down list's SelectedIndexChanged event is fired, the OnInit method is called... then the PageLoad... and finally the handler for the SelectedIndexChanged event is called. ViewState hasn't been restored until well after the OnInit & PageLoad methods have been called, so there is no way to know what the user chose in the list box at the time OnInit is called... which exactly when I'm required to create the dynamic controls.
So... how do you solve this problem? Do you just have to write the entire page, or most of it, using JavaScript?
Thanks in advance.
I tend to use an old school method for this type of requirement. I would write all of the controls that are needed in the update panel, with their Visible property set to false. Then, on post back read the drop down's state and set the approperate controls Visible property to true. This way there is no "dynamic" controls, and due to the fact that controls whose Visible property is false are not rendered, they are not downloaded until the user should see them.
you can also use an asp:hiddenfield and set the value to a case var you mentally create. then run a small jQuery script on top to look at
$(document).on("change", "#ddlSelector", setControls);
then just make a function, for instance:
function setControls(event) {
event.preventDefault();
var selector = hiddenfield.val();
}
then any item to show/hide can be done with getting the tag:
$("#elementName").css("display", "inline");
or display, none to hide.
I used this at work because at times you need to change without firing the postback, but still collect data when they engage the form.
I typically avoid jQuery for many events for strength of code and security, but DOM element manipulation can be much easier at times with jQuery.
If you have an update panel, that displays a number in its Load method, and a button as a trigger, and you make the button have an onclick method that increments the number, the update panel will not update when you click it.
This is because the update panels Load method runs before the OnClick method, so it draws the number on the screen before it increments it.
At the moment I get around this by using the scriptmanager to tell me which button or whatever caused the update panel to trigger, and then I use that to run the increment method before it renders, which works.
It sucks though because it renders onclick methods for buttons obselete if you want immediate feedback from them, and fills your load method with IF statements.
Am I missing something or is this the intended way update panels work?
That's just the order of the events in the page cycle, and that is the same regardless if you are using update panels or not.
You can use the Page_PreRender event instead to put the number in the page. It occurs after
the click event but before the page is rendered as HTML.
I have a page results page (you get there after submitting your search query elsewhere) whit a whole bunch of gridviews for different type of data objects.
Obviously, some of the queries take longer than the others. How can I make each gridview render as soon as it has the data it needs?
This has been tricky for me because it must work on a postback as well as a pageload. Also, the object data sources just fire automatically on page load/postback; I'm not calling any methods programatically to get the data. Will I have to change this?
#Gareth Jenkins
The page will execute all of the queries before returning even the first update panel, so he won't save any time there.
The trick to do this is to move each of your complex gridviews into a user control, in the user control, get rid of the Object DataSource crap, and do your binding in the code behind.
Write your bind code so that it only binds in this situation:
if (this.isPostBack && ScriptManager.IsInAsyncPostback)
Then, in the page, programaticly refresh the update panel using javascript once the page has loaded, and you'll get each individual gridview rendering once its ready.
Could you put the DataGrids inside panels that have their visibility set to false, then call a client-side javascript function from the body's onload event that calls a server side function that sets the visibility of the panels to true?
If you combined this with an asp:updateProgress control and wrapped the whole thing in an UpdatePanel, you should get something close to what you're looking for - especially if you rigged the js function called in onload to only show one panel and call a return function that showed the next etc.