Accessing gridview row data CONSISTENTLY from javascript - javascript

I have an asp.net webpage that contains a gridview with SQL data bound to it using the DataSourceID property. I want to be able to launch JavaScript from various user events (like button clicks and row clicks in a second gridview) and use JavaScript to read the gv1 data and perform some simple actions. My problem is, some of my JavaScript calls see the data in the gridview, but many times all I see in the gridview is a header (no rows of data!).
For example, if I put a call to JavaScript inside Page_Load() using
ScriptManager.RegisterStartupScript(Me, Page.GetType, "Script", "jsPageLoadFirst();", True)
then I always see the gridview data on the initial page load, and also on some postbacks. On other postbacks however the gridview has been stripped and all I see is the gridview header (rows are undefined).
Similarly, if I setup a call to JavaScript in the html body as
<body id="mybody" onload="JavaScript:myJSsub();">
the JavaScript sub never sees the gridview data; only the header, but no rows. I THOUGHT that the client onload event only occurred after the page was fully loaded (including all data binding!) but apparently not! Note that I always see the gridview data showing on the webpage, even right before I click a button to invoke JavaScript, so it's a mystery to me as to why the gridview data sometimes gets stripped!
I've been pulling my hair out for days trying to figure this one out. Can anyone tell me what I'm doing wrong, and how I can make sure the gridview row data is always available to my JavaScript subs, no matter where (or how) I launch them?
Thanks!
-tom
10/7 update: Here's a little bit more info, plus a possible work around I've come up with today using a hidden field. First, I'm primarily accessing the gridview data in JavaScript using calls to document.getElementById("gv1"). So to start things off, since all the gridview data is available to the JavaScript sub I fire from the first server PageLoad event, I tried saving the gridview data in both a global variable "gvar1" and also in a hidden field on my page "hf1". Here is what my JavaScript looks like:
function jsPageLoadFirst() {
// Save gv1 to a global variable
gvar1 = document.getElementById("gv1");
// *** Also save gv1's html to a hidden field
document.getElementById("hf1").value = document.getElementById("gv1").innerHTML;
}
Now in the JavaScript sub I trigger from the onload() event of the body, I check the values of all three. I always find that 1) document.getElementById("gv1") shows only the gridview header (but no rows), 2) gvar1 is undefined and 3) hf1 looks fine - all row data is present. Similarly when firing javascript from server Postback pageloads, sometimes document.getElementById("gv1") shows all the gridview data, but sometimes it only shows the gridview header but no row data. Can someone explain to me why document.getElementById("gv1") does not always show the row data? I think if I understood this, I could see my way clear to get the rest of my code working. Thanks!!!

Related

How to show devexpress popup control inside a user control from client side

I am using devExpress 11.2 and ASP.NET 4.0. Please bear with me for lengthy problem description.
I have created a user control which contains a ASPxPopupControl (ID = "myPopup")
<dx:ASPxPopupControl ID="myPopup" runat="server" ... </dx:ASPxPopupControl>
and other controls. I also implemented a public method ShowPopup() in which it executes the myPopup.ShowOnPageLoad = true in order to show this popup. This user control is then registered and referenced in my ASPX page. I put this user control into a cell of a table within ASPxRoundPanel with ID="myUC"
In this page, I have a ASPxGridView in which I created a custom command button as follows:
<dx:GridViewCommandColumn VisibleIndex="0" Width="30px" Caption="" ButtonType="Image">
<CustomButtons>
<dx:GridViewCommandColumnCustomButton ID="cmd">
<Image Url="~/Images/OK.png" />
</dx:GridViewCommandColumnCustomButton>
</CustomButtons>
</dx:GridViewCommandColumn>
ClientSideEvents is defined as
<ClientSideEvents BeginCallback="OnDevExpressBeginCallback" EndCallback="OnDevExpressEndCallback">
I would like to popup my user control when this image button is clicked. Please note that this ASPxGridView also provide Insert/Editing/Delete function.
There are two ways to deal with this requirement.
1 In order to ensure ASPxGridView handling its built-in commands (Insert and etc) correctly, I need to set EnableCallBacks="True" then I set OnCustomButtonCallback="OnmyASPxGridView_CustomButtonCallback" to handle the clicking event of the image button from code behind. I called myUC.ShowPopup() from code behind and I debugged up to here. However, the popup is not shown. If I set EnableCallBacks="False" then the popup is shown exactly what I expected.
The problem of this approach is not acceptable because the built-in commands do not work properly. So the question is how can I show the popup control within my user control from code behind while EnableCallBacks="True" ?
2 Second approach is to show popup from client side.
I set EnableCallBacks="True" first to ensure my built-in commands work properly. then I defined ClientSideEvents as
<ClientSideEvents BeginCallback="OnDevExpressBeginCallback" EndCallback="OnDevExpressEndCallback" CustomButtonClick="jsfnShowPopUpControl"/>
and removed OnCustomButtonCallback event.
I implemented javascript function jsfnShowPopUpControl like this:
function jsfnShowPopUpControl(s, e) {
// next, find access control inside user control
**var myPopupName = document.getElementById('<%=myUC.FindControl("myPopup").ClientID %>');**
if (myPopupName != null) {
myPopupName.Show();
myPopupName.PerformCallback(e);
}
else {
alert("Data error encountered"); // cannot find popup
return; //
}}
The key part of this approach is to find the devexpress popup control which resides within a user control. Unfortunately that getElementById function could not find the underneath control in my user control and thus popup is not shown either.
Please help and let me know what I did wrong in my two different approaches.
Thanks a lot.
Reference these- Showing a DevExpress AspxPopUpControl when user clicks a button
How to show ASPxPopupControl's window on the client side
To solve this issue, I suggest you use the ASPxClientPopupControl.ShowWindow method.
For this same scanerio as you want to implement what i have done.
Assigned ClientInstanceName property to some unique name on the page
including the user control now you free to access that object anywhere
in the html through javascript.
Let you set the popup's ClientInstanceName to "MainASPxClientPopupControl". Thus, it should be possible to use it on you main page as follows:
MainASPxClientPopupControl.Show();
Reference on this topic: ASPxPopupControl - Cannot get an instance of the popup from a page

jQuery event triggering multiple times because of multiple javascript inclusions/requires

I have a problem here and it's making me mad. I maintain a legacy php system. It's badly organized, no frameworks are used and a lot of other problems, for example, at least 5 different query versions are used in different parts of the system.
So my problem right now is this, I have a search form, when a button is clicked it shows a list of items, lets call this a list of "A" objects. In each A item, there is an expand /toggle button to show the B items that belong to A (this is done using ajax, by setting a specific div's html to the ajax response). Then each B also has an expand/toggle button to show the C items that belong to B.
What is happening: I click to search, all A are shown. I click on the expand to show the B items of one A object, they are shown. I click B to hide it, it hides and then show again. If I click it one more time, it hides, shows and hide. So it is like every ajax request is including the javascript code and running it.
I think this is pretty much an organization problem, I am not knowing how to include/require and insert the js correctly. I've been trying to solve this issue since yesterday and I think I've seen the code so many times that I can't think out of the box.
So here's some of the organization (I changed the names because there are some business rules):
SearchResults.php -> Declares a class that has static methods to print out HTML of each item A, B and C and some other helper methods. To make stuff "work", it has a require "js.php"; otherwise the A expand button does not work because it does not exist at the time the js is executed and no function is bound.
search.php -> the HTML form with all the search options, nothing important.
js.php -> the javascript stuff, why is it in a ".php"? I can't even remember, but I think it is because with the php I can require/include:
<script type="text/javascript" src="../util/js/jquery/1.8.1/jquery.min.js"></script>
<script>
var jQ = jQuery.noConflict(true);
jQ(document).ready(function() {
jQ(".loadBfromA").click( function(e) {
if (div.style.display == 'none')
alert("was hidden, now is showing");
//call ajax_B.php
//response is put into the div using .html(data)
else
alert("was showing, now is hidden");
...
ajax_B.php -> the ajax that access the database and echoes html code that will be put into the A items div. Here I have to require SearchResults.php, because I call some methods of the class.
Why is it including the jQ(document).ready being executed multiple times? How can I fix it? Is there any way I can reorganize the code?
Is the ajax_B.php, when requiring SearchResults.php, including the js again because SearchResults.php requires js.php? Does this gets echoed and then put into the div?
I can't make a fiddle of this because there is ajax included.
Edit:
I have tried unbind("click").bind("click", ()) and it didn't work.
It looks like the event is being bound multiple times on jQ(".loadBfromA")
I know this is not the cleanest solution out there, but you could rewrite the actual binding:
jQ(".loadBfromA").bind('click.loadbfroma', function(e) {
// Do your code
$(this).unbind('click.loadbfroma');
});
That way you can at least be sure that only one event is bound at all times, no matter how many times the code snippet is being included. I know this doesn't really help you with the underlying issue but it's a start.

How to reload JSP with changed actionbean variable using Stripes

I am new to working with Stripes. I have a dropdown ("show ## recordrs per page") and a paginated table on the JSP page and I want to display as many records per page in this table, as the value selected in the dropdown.
The action bean has a variable "recordsPerPage" and I am not able to figure out a way to set the value of this variable and reload the table, so as to change the number of records that are displayed per page. Please help.
---- Additional Info -----
The table that I use is a displaytag table, which accepts a PaginatedList. This table is within a stripes form.
-- EDIT:
What I did is, I added a <stripes:hidden/> with the name "recordsPerPage" and set the value to be the number of records I want to display. I also added a <stripes:submit> to the same form. The "name" attribute of this submit button is the method name of the action bean I have to call. When I click on this button, I am able to do what I want. But now, I am unable to do it through javascript. Please help.
Due to some reason, calling Dom.get('submitButton').submit() or Dom.get('myFormId').submit() does not fulfill the intended purpose. Taking a clue from being able to do what I wanted from the submit button click, I made this submit button hidden and the called click() on this button from javascript. Thus Dom.get('submitButton').click() produces the intended result. If someone can give me the explanation of why the submit method did not result in expected behavior, that'll be great.

Add items to dropdownlist with javascript and persist in postback

I'm pretty new to web development, and I've encountered the following problem I don't really understand. Working in VS2010 with visual basic.
I have a page (aspx), which has a gridview, and this has a few columns, including a column with tickboxes and a column 'action', which has an empty, hidden dropdownlist to begin with (every row has this).
Whenever a user ticks a box, I retrieve some values from the server with an AJAX-call (which is my first attempt at AJAX :-)) and with those values I populate a dropdownlist in the 'action' colum of the selected row. So far so good.
The user can then make a selection on the dropdownlist, en then he presses a button (upload), and a postback is done to process the information.
However, in the code behind, I can't retrieve the added items in the dropdownlist (let alone the selected value). I CAN retrieve the dropdownlist, but it has no items.
After googling for some time I realised that client-side changes are not persisted when the form is posted to the server, which I understand- but it also seems odd. The dropdown is created when the page is created, so why doesn't it store the javascipt-added items? Especially since a few work-arounds I found use a hiddenfield to store the added items or selectedvalue. If I can store them in a hiddenfield, why can't I store them in the actual dropdownlist?
I'm obviously not understanding how websites work... But this means that, after a page is initially loaded, you can change values in dropdowns and listboxes and such, but these will never be available serverside?
Edit: some code; the first a javascript-snippet how I add the different values I retrieved through the AJAX call:
var drop = row.findElement("ddlAction"); //find the dropdownelement in the DOM
for (j = 0; j < dropdownitems.length; j++) { //add all the options from xml
option = document.createElement("option");
option.text = dropdownitems[i].getAttribute("text");
option.value = dropdownitems[i].getAttribute("value");
drop.add(option, null);
}
This works fine, the dropdownlist is filled and I can select. But when the page gets posted I do the following in the server code:
Dim SelCount As Integer = LocalFilesGrid.SelectedItems.Count
If SelCount >= 0 Then
For Each dataItem In LocalFilesGrid.SelectedItems
Dim drop As DropDownList
drop = dataItem.FindControl("ddlAction")
If drop.Items.Count = 0 Then 'always zero
MsgBox("Nope")
End If
Next
End If
I'd like to be able to loop through the selected rows of the grid, get the corresponding dropdownlist and selectedvalue.
When you mix such different technologies you will end up in troubles like this. What you are trying to do is bit of Ajax and a bit of ASP.NET. Choose one and then use it. If you choose ASP.NET instead of AJAX call use UpdatePanel which will simplify your life.
If you want to Ajax stuff your self, then handle the button click and submit the request by ajax rather than postback.
The reason why you are able to retrieve the drop down but not the items because you must have declared the drop down in aspx but the items were added on client side, so server has no knowledge about the items.
The reason is ASP.NET uses view state and you can not mess with view state. So you can add the data to hidden field and read them at server but you can not write the data in view state.
The best way is use ASP.NET with UpdatePanels. If you mix, then you will have to keep doing some sort of trick at every step. If you want to do your own Ajax stuff better use MVC and Razor(not mvc with aspx) because it is made for such use.

ASP.Net multiple UpdatePanel refresh with JavaScript

I have a GridView and and some jQuery code that allows the user to expand individual rows. On row expansion I display a div which will contain more information relating to the row. Inside the div is an ASP.Net UpdatePanel. I make a call to the __doPostBack function passing the ID of the specific UpdatePanel I wish to refresh.
var updatePanel = $(expandContent).children("div[id$=UpdatePanel1]").attr("id");
__doPostBack(updatePanel, '');
However when debugging I notice that the *UpdatePanel_Load* method is getting called for each UpdatePanel on the page. As expanding the row will cause the system to go off and retrieve data I really only want to fetch this data for the specific row that has been expanded.
So my question is, does anyone know of a means to cause individual UpdatePanels to refresh using JavaScript.
Thanks
Alan.
If I pass the ID of the UpdatePanel to the __doPostBack function like:
var updatePanel = $(expandContent).children("div[id$=UpdatePanel1]").attr("id");
__doPostBack(updatePanel, updatePanel);
In the code behind I can do a test like this to ensure the retrieval is only carried out for the specific UpdatePanel:
UpdatePanel panel = sender as UpdatePanel;
// the ClientId of the UpdatePanel being update is passed in
// __EVENTARGUMENT this can be checked against the sender to ensure
// data is retrieved only for the row being expanded.
string panelID = Request.Params.Get("__EVENTARGUMENT");
if(panel.ClientID.Equals(panelID))
{
// retrieve data
}

Categories

Resources