jquery append + code-behind - asp.net

I dynamically add rows to divStaff using jquery:
$("span[id$='lblAddStaff']").click(function() {
//$(".staff_tpl").find("input[id$='txtRate']").val("0,00");
var staff_row = $(".staff_tpl");
staff_row.find(".staff_row").attr("id", "Emp" + counter);
$("div[id$='divStaff']").append(staff_row.html());
counter += 1;
});
the row that I'm adding is inside the hidden div with class=".staff_tpl"
I append the contents of this div to divStaff
When I submit the page (postback), the resulting divStaff is always empty if I try to display it like this:
lblTest.Text = divStaff.innerHtml.ToString
basically, I'm manipulating a div client side, and I want to access it server side via the code-behind of my aspx page. I think I'm missing a basic principle here.

This cannot be done.
If you want to access data you've created pn the page, you have to place it inside input fields (possibly hidden), and access it after it was posted using Request.Form["MyHiddenFieldName"].
<div>s aren't posted to the server. runat="server" elements are enechoded in the ViewState (a big string, really - you can see it in the source of your page), giving the abstraction of continuity (or the illusion of it). However, that sting isn't aware of changes you make in the DOM.
When dealing with runat="server" elements, you will see the last changes you've made on the server side, but client side changes are gone.
Only <input> (and text area, option, etc) values are posted to the server on submit, so changing these on the client will be seen on the server, after the page was posted.

Related

Generate aspx file one below other in single tab

I am having a complete .aspx page which contains header,footer,textbox,tables everything. Values in these all fields come from code behind .cs file.
For different set of data i am generating different .aspx page file in tabs. so that user can take print of it.
i was doing something like this to open multiple tabs
var cust_prop_id = $('#hdnPropertyNo').val().split(',');
$.each(cust_prop_id, function (i, val) {
var myWindow = window.open('UserInfo.aspx?Prop=' + val, '', '');
});
PROBLEM STATEMENT
All of sudden client said user wont go to each tab and say "Print".
Instead generated all .aspx one below other in single tab. so in one single click user can able to print all generated .aspx files
What is the best way to do it ?
You can do this in many ways here are two most common.
Method 1
Create user control for each page which you want to be printed add these user controls in the page where user will print the page.Load each user control in separate div and place in main container and at print time get css of container div which will include all data.
Method 2
Create div for each page which you were opening in new window in a main container .Load data in divs at page load and when user press Print get all html of container div and print it.

How do make a tag cloud link to a specific paragraph or picture in asp.net

I've just started using the tag cloud feature for a new site i'm developing.
but now I've run into some problems
I can set the links in my tag cloud to go to a page, but I have many pages with a tab container.
so for instance, I have a tab container. one of its panels is a sports panel. the tab container has three other panels, say food, travel and drinks.
how do I make a tag that goes directly to that panel in the tab container?
really stuck here.
tried creating a normal a id="something" name="something", and tried creating the tags a href to that name with a #, but that didn't work.
could somebody please help me
would, of course, be greatly appreciated
A # is your best bet. So for example if you set up your link to appear as:
Link text
Then you can bind to the "hash change" event using javascript. jQuery example below.
// on load
jQuery(document).ready(function(){
// bind window hashchange event
jQuery(window).bind("hashchange", function(){
// get hash selected
var hash = window.location.hash;
// *** now do something with that information *** //
// *** eg, show hide panels where a nested element, attribute or data matches hash *** //
});
});
If you're doing it this way you should make all the "tab clicks" simply bound hash changes too, forgetting any previous functionality. Then it will be solid, and consistent.
You could also do the same using query strings. And if you're not a fan of the "hashchange" then do it another way. The key is that you would have a javascript function that looks for something in the url, then does something about it!
EDIT
Add to the "do something section" assuming all your tabs are of the same class and the hash is the same name as the ID
jQuery(".tabs").hide();
jQuery("#" + hash).show();

ASPxClientListBox loses values and the first item can not be selected

On a server control I have a DevExpress ASPxClientListBox which is populated dynamically on the client. The server does not need to know anything about it but it is initialized on the server. Normally this server control does not have any problems... however, if I put it in an ASPxCallbackPanel it will work on the first page load but, after a callback, if the ListBox's client side selected index changed event is fired, the selected items values are lost and "undefined" though the keys or "texts" are intact.
On a side note... after a callback the first item in the ListBox can not be selected.... what I mean is that the first item is not highlighted on mouseover or mouseclick.
Links which are slightly relevant but not what I need:
http://www.devexpress.com/Support/Center/p/Q312536.aspx
I had another link that talked about the "unable to select first item" issue and said that it had something to do with adding the items prior to the control hierarchy being established so the solution was to add the items in the ListBox client side Init event as opposed to the page_load event. I am adding the items after the ListBox has been initialized so I don't see this as a solution ... and I can't find the link now anyways...
Edit: I just found that other link again: http://www.devexpress.com/Support/Center/p/Q367021.aspx
Part of the problem is addressed in the second link you provided. What happens is that...
...this function is called immediately when a page is loaded. However,
an ASPxListBox hierarchy is not yet ready. The correct way to call the
getList function is to handle the ASPxClientListBox event...
To cut the long story short, something like the following won't execute properly if you run it e.g. on load...
yourListbox.AddItem("Test1");
yourListbox.AddItem("Test2");
yourListbox.AddItem("Test3");
yourListbox.AddItem("Test4");
...but the following should work...
s.Properties.ClientSideEvents.Init =
#"function(s, e) { yourListbox.AddItem('Test1'); yourListbox.AddItem('Test2'); yourListbox.AddItem('Test3'); yourListbox.AddItem('Test4'); }";
I guess the first selected-items-problem could have happened for the same or similar reason.

Performance issue with ASP.NET page with many (hundreds of) CollapsiblePanelExtenders

I'm maintaining an ASP.NET site where users can log on to register some set of data (for statistical purposes). One user registers data for a set of units, and for each of these units a set of forms are to be filled out (with a handful of fields in each form, but that doesn't matter here). One scenario is that a user has 12 units, and in each of these units there is 25 forms to be filled, meaning a total of 300 forms.
The ASP.NET page for registering these data is made the following way: each form is in a panel that can be collapsed using an AjaxControlToolkit CollapsiblePanelExtender, and all forms in a unit is inside another panel that also can be collapsed. The result is that you have a tree view-like structure with the units on the top, and under each unit you can expand a set of forms, and further each form can be expanded to fill data (the page is loaded with all panels collapsed by default).
The page is generated completely dynamically (as forms can be added in a database), and for generating the CollapsiblePanelExtenders I have the following code:
private CollapsiblePanelExtender GenerateCollapsiblePanelExtender(string id, Panel headerPanel, Panel contentPanel)
{
CollapsiblePanelExtender collapsiblePanel = new CollapsiblePanelExtender();
collapsiblePanel.ID = id + ID_COLLAPSIBLE_PANEL_POSTFIX;
collapsiblePanel.TargetControlID = contentPanel.ID;
collapsiblePanel.CollapseControlID = headerPanel.ID;
collapsiblePanel.ExpandControlID = headerPanel.ID;
collapsiblePanel.Collapsed = true;
collapsiblePanel.BehaviorID = collapsiblePanel.ID + ID_BEHAVIOUR_POSTFIX;
return collapsiblePanel;
}
With one user having 12 units each with 25 forms, this means a total of 312 CollapsiblePanelExtenders. As I said, they are all set to be collapsed by default, but here's the problem:
When the page loads, they all appear to be expanded, and then the browser "starts collapsing them". This however takes a very long time (in Firefox I even get a warning about an unresponsive script, IE and Chrome only takes forever but without the warning). When all the "collapsing" is complete it works smooth to open and close single panels, but users have complained about the extremely slow initial loading.
So my question is simple: is there a way to optimize this so that the loading goes smoother? Is it for instance possible to only load the header panels in each CollapsiblePanelExtender initially, and then load the content panel asynchronously in some way?
One final clarification:
I know I could simply change the design of the page to only include one unit and thus reducing size of the contents drastically, but I hope to avoid this (users prefer the way with everything in one page). It would also mean a rather large change to the logic of the page (yes, I know - it's a poor code base at that point)
After asking some more around other places, I finally managed to solve this issue. The solution was to skip the CollapsiblePanelExtenders altogether, and instead use jQuery to handle the collapsing/extending.
In my structure, all header panels use the css class HeaderPanel, and all content panels use the css class ContentPanel (all of these are hidden by default). I can then use the following script to handle all the collapse/expand logic:
<script language="javascript">
$(document).ready(function() {
$("div.HeaderPanel").toggle(
function() {
$(this).next("div.ContentPanel").show("slow");
},
function() {
$(this).next("div.ContentPanel").hide("slow");
});
});
</script>
The solution was really quite simple, and it works like a charm! The collapsing/extending is soo much smoother and nicer than what it looked like when I used the CollapsiblePanelExtenders, and the page loads really fast as well :)

How can you move ASP.Net controls to different places on the Web form at runtime?

Is there an accepted way to "move" a control.
My client wants to place a certain chunk of markup (representing some visual element) in one of several different places on the page. The locations are different to the point that I can't effect the change on CSS along (by floating it or something).
I considered just putting the control in multiple spots with Visible set to "false," then displaying the one in the place they wanted for that particular page.
However, the code for this control is not trivial -- there's a couple template sections, for instance. Having to dupe this in multiple places would get unwieldy. Also, I don't want to have to work with this control strictly from the code-behind for the same reason.
So, I'd like to put it in one place on the Web form, the move it around based on where I want it. Could I put Placeholders in different spots, have the control in one spot, then remove and add it to the right spot? I suspect this would work.
Does someone have a better idea? Is there a best practice for this?
I'd recommend using a placeholder control, moving your markup into a separate user control, then loading this at runtime and adding it to the relevant placeholder.
Eg.
// Load a user control
MyControl userCtrl = (MyControl) LoadControl("~/Controls/MyControl.ascx");
// Or create an instance of your control
SubclassedControl subclassedCtrl = new SubclassedControl();
// Do stuff with controls here
userCtrl.LoadData();
subclassedCtrl.Text = "Hello World";
// Check which placeholder to add controls to
PlaceHolder placeHolder = (foo=="bar") ? placeHolder1 : placeHolder2;
// Add the controls
placeHolder.Controls.Add(userCtrl);
placeHolder.Controls.Add(subclassedCtrl);
This will avoid cluttering up your page with unnecessary markup, and loading it at runtime will also avoid unnecessary confusion later, when another developer looks at the code and can't immediately see why a control is in one place in the markup, but renders on a completely different part of the page.
An alternative (and one I've seen done many times before) is through javascript and the DOM. Render your control inside a hidden div tag. So you would render your content here:
<div id='rendercontent' style='display:none'>
.. control here ..
</div>
Then, lets say you wanted to move it all here (the span tag is inside because that's what we're going to replace):
<div id='newlocation1'><span></span></div>
You would define the following javascript:
<script language="JavaScript">
function replaceNode(newElementID, targetElementID)
{
var targetElement=document.getElementById(targetElementID);
var newElement=document.getElementById(newElementID);
targetElement.replaceChild(newElement, targetElement.firstChild);
}
</script>
And when you want to move the content to the new location, call:
<script language="JavaScript">
replaceNode('rendercontent','newlocation1');
</script>
Do Web Parts do what you want to do?
Or, you can change the parent programmatically of your controls to move them into a separate area.
You can override the Render method and place the controls wherever you want in the html.
You only need to add controls to the Controls collection that must interact on the server. The rest of your HTML can just be written to the response stream. If you override Render you can create the html anyway you see fit, placing the controls in any order.
Below is an example of how to write out your html.
protected override void Render(HtmlTextWriter writer)
{
AddAttributesToRender(writer);
writer.RenderBeginTag(TagKey);
writer.RenderBeginTag(HtmlTextWriterTag.Div);
_control.RenderControl(writer);
writer.RenderEndTag();
writer.RenderEndTag();
}
You could always put panels in the pre-defined locations and add the control to the specific panel at runtime.. Here's an example adding a label (the label could be replaced with any control).
Dim lblDisplay As Label = New Label()
lblDisplay.ID = "myLabel"
lblDisplay.Text = "Some Text"
pnlDisplay.Controls.Add(lblDisplay)
As far as...
"Also, I don't want to have to work
with this control strictly from the
code-behind for the same reason."
I think you're going to have to do most of your work in the code behind.
PS.. a good example of the whole usercontrol setup can be downloaded here..
http://www.asp.net/downloads/starter-kits/time-tracker/

Resources