Getting table control programmatically - asp.net

I have a table that I am creating programmatically and then adding some rows and data to it in the CreateChildControls() method.It has 2 columns with dropdownlist controls in it.Now on the client side based on selection in the dropdown I am adding more rows by copying the contents of the last row.There is a save button which when clicked invokes the below overriden function of the webpart to get the table object back..The issue is the rows that I am adding on the client side are not being retrieved..Only the rows that were created on the server side initially are being retrieved.Can someone please tell me what I am doing wrong here.
So doing this Table tab = FindControl("Main1") as Table;
tab.rows only give 3 which were initially generated on the server and does not include the 2 new that were created client side
Public Override Control FindControl(string id)
{
return base.FindControl(id);
}

Any rows added client side will not be passed to the server - that is the way in which the technology works. A better way to do this would be for the save button to generate a PostBack and add the new rows on the server.
If the new rows absolutely have to be added client side then you will need to write an ajax call to add the new rows to the viewstate server side after they have been added client side - seems like a lot of work when a PostBack should be perfectly adequate.

I believe the controls added server-side are stored in ViewState, and client-side DOM changes don't affect that. It would probably be easiest for you and the best user experience to add an UpdatePanel around your table and dropdowns, and add the rows server-side.

Related

How to validate controls inside editform template of ASPxGridView?

I have an ASPxGridView with edit form template and some bound controls inside. After update I want to validate, check the values in controls on server side. As far as I could find this is not possible. DevExpress recommends subscribing to the RowUpdating event, but this is plain wrong. Useless as is very much of their so called support.
The problem is, that if controls contains some invalid text and it raises an exception somewhere long before RowUpdating and it gets eaten by devexpress. All it comes back to client is some message like "Input string was not in a correct format".
I want to validate input controls on the server side.
And yes, I do row validating also, but this is useful only for validating business logic.
So, how to validate controls that are bound inside EditForm template on server side?
Could you please clarify? You want to validate the values after you update or actually before you write the values to the database or each control individually as it loses focus before you can initiate the update? If it is necessary to do server side validation then I would recommend doing it in the RowUpdating and RowInserting server side event handlers as was recommended by DevExpress. Why do you think this is wrong? You can validate each of the bound controls' values in the e.NewValues collection of grid's Updating and Inserting events. If any of the values do not pass validation you can cancel the update/insert action. Could you outline your desired workflow in a little more detail?
A previous poster said a hack was necessary, putting a container inside the edit form template, which is not true. You can use the edit form template itself via the .NamingContainer of any control in the edit form template. Put your validation routine in the server side _Validation event handler of the specific controls.
You can evaluate the template controls as a group:
EditFormValid = ASPxEdit
.AreEditorsValid(myGrid.FindEditFormTemplateControl("myControl")
.NamingContainer);
Or you can update a class variable during each control's validation routine
public class foo
{
bool EditFormValid = true;
.
.
.
void myControl_Validation(object sender, ValidationEventArgs e)
{
EditFormValid = EditFormValid && myControl.IsValid;
}
void myGrid_RowUpdating(object sender, ASPxDataUpdatingEventArgs e)
{
If(EditFormValid)
{
.
.
.
}
else e.Cancel = true;
}
}
I have found DevExpress extremely effective and flexible. However the flexibility can be a double edge sword as there are many ways to almost do everything you need most of the time but usually one way to do everything you need all of the time. A developer can easily build on top of what works in one instance but isn't necessarily right/best practice and get to a point where they have coded into a corner as they continue to build upon a project.
If you can provide more specifics, so can I.
As far as I know this is not possible to do. Devexpress controls leave a lot to wish for. There is no way to check if validation was successful. Clearly a big issue.
What you can do is to run validation again with ASPxEdit.AreEditorsValid(). But for this you would have to do a little hack (as always with devexpress).
Put a container inside your edit form, a simple div with runat="server" and ID would do. This is your container.
Than get his div with FindEditFormTemplate() and use it in ASPxEdit.AreDitorsValid().
This workaround has drawbacks:
clutters your aspx code with unnecessary elements
page execution on server side is slower
page rendering on browser side is slower
ValidateEditorsIncontainer() runs validation again so there is a big
performance hit
All of the above are trademarks of DevExpress controls. But look at it from the bright side. Their grid sometimes takes up to five unnnecesary server and database roundtrips just to start editing.

Problem getting list box items added through jquery in code behind

I have a asp.net list box control in which i populate items using Jquery by using some code like ..
$("#MylistBox").append("<option value='somevalue'>Someitem</option>
dynamically .
but in code behind when i use
MylistBox.Items is always showing Count 0 no matter how much items add.
Can anybody help me with this?
Without knowing the actual scenario... I am assuming your goal is actually to get the dynamically added items either by iterating over them or something else...
Any dynamically added DOM element that is done on the client side using JavaScript / jQuery, will not be reflected automatically to the server side. You will need to serialize them in a different way and push them back to the server side during postback. One way you can do this is by serializing all the Options of the Select element in a hidden input. You can mark the hidden input as runat=server if you wish to make it easier for you to access, otherwise use Request.Form["...hidden input NAME attribute here... NOT ID..."] to get the value out. After you get it, you can do whatever you want with the values.
I imagine your hidden input should have some value like: "1:First Value,2:Second Value,3:...". Just do some string manipulation to split them up and iterate over them.
The code behind will only be aware of items that were added to the Listbox object when it was created on the server. These items will be held in ViewState and repopulated during postback.
Therefore items created dynamically on the client won't be visible to the server side code.
If you need to get the selected value in the server side code then you are going to need to query the Request.Form["<Listbox client id>"] value during the postback.
If you need to retrieve all items added to a list box on the client I would suggest adding them all to a hidden field value as a delimited array of strings and again retrieving them using Request.Form["<hidden field id>"].
string values = Request.Form[ListBox_SelectedSubject.UniqueID];

Listbox items client side reordering not reflected in server side (ASP.NET)

I reordered some items in a listbox using Javascript. When I read the items in a postback in the code behind (ASP.NET), the order is in the original order. How do I get the same order as shown in the screen after Javascript manipulation?
Only the selected items will be posted back to the server, the order will be pulled from the viewstate (which your javascript doesnt change). Im not sure you can do what you want in that way. You might have to have a separate [hidden] field that tells the server what order things are in.
Your JavaScript will have to notify the server of the rearrangement using AJAX, and then you have to keep track of order manually. This is fairly trivial, but it does mean regenerating the listbox items each page load instead of relying on the ViewState.
Using JavaScript code, you can store the order in a hidden variable (make the hidden variable the server HiddenField variable) and process the ordering when the page posts back to the server. Then, you can clear the items and reorder them appropriately using this sequence of numbers stored in the hiddenfield. This is what the AJAX controls do.

How to get child controls correct id to client side

I am working on ASP.NET and not using any ASP.NET's AJAX framework. Now I am trying to update the contents of the textboxes and dropdowns in the Grid controls cell on client side using (classic JavaScript way)AJAX. But problem I am facing is that controls (textbox, dropdown) which I would like to update when rendered on the client side get prefixed by the User Controls id and row ids.
So it becomes like UserContro_row_no_controlId. With this it is becoming difficult to keep track of controls ids on the client side to update them.
Please let me know how this can be simplified?
Can we get what exactly will be prefixed to control when it’s rendered on client side?
What is good way to get ID to client side ? I have tried using control.clientId but it’s giving me only _controlId part not the UserContro_row_no part.
Thanks all,
If you want the id of a control in the same control/page you can do that this way:
<%=txtControl.ClientID%>
If you want the id of a control inside a usercontrol you can do that like this:
<%=userControl.FindControl("txtControl").ClientID%>
Where "txtControl" is the server id of the control and "userControl" is the server id of the usercontrol.

ASP.NET Controls and Update Panels

I am creating a series of client side component controls on the fly that are nested inside a update panel. The first time I create the controls, everything works as desired, however, when i trigger an update on the update panel and it does a partial postback the controls come back with several javascript errors describing how the control is already registered on the page.
I get a series of errors that say something about like:
"Error: Sys.InvalidOperationException: Two components with the same id "master_ctl40_CCB_PALETTES" can't be added to the application"
Any ideas anyone?
Try these tricks:
On Page_Load put uxFailedControl.ID = DateTime.Now.ToString(); It will ensure your control has unique ID every time page reloads (fully or partially), so theoretically you shouldn't see anymore "same id" errors.
If you display your control in Modal Popup: Every time you hide the popup from the server, remove the control from it's container (Panel, Page, Control, etc.) Use uxModalPopupPanel.Controls.Clear(); or uxModalPopupPanel.Remove(uxFailedControl);
When you are done with debugging set ScriptMode property of your ScriptManager to "Release". It will prevent internal AJAX exceptions to be bubbled up to the browser.
In which event are you adding the components to the update panel? I.e. have you placed them inside the page load event without a postback check or have you placed them inside the update panel load event? etc...
Looks like your client object is being created more than once.
If you want your client side controls to be replaced when the update panel they're in refreshes, they should inherit from Sys.UI.Control, which takes takes an element in its constructor. When that element is replaced by the update panel, the client object will be disposed and then re-created. If you're currently using a ScriptComponentDescriptor on the server side to define the client control instance, you'll want to switch to a ScriptControlDescriptor.
By the sounds of it, your client objects just inherit from Sys.Component, which will hang around until they're manually disposed, which is why you're getting an error about having more than one component with the same ID.
I would advise against using a new ID every post back - this will just keep creating new client objects without ever cleaning up the old ones.

Resources