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
}
Related
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!!!
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
I was thinking to my self if there is a better implementation to my approach in triggering functions from JavaScript to ASP.Net and viceversa.
Run JS code from ASP.Net
Create asp.net hidden value that will keep information of what
action was done. (Eg. id = hiddenFunctionality)
Behind ASP.NET code, do the functionality than
alter the asp.net hidden value (hiddenFunctionality.value = "AddedUser") to trigger the correct JS function later on.
From the JS aspect create pageLoad() method and within the pageLoad() method
read the asp.net hidden value if(document.getElementById('contentPage_hiddenFunctionality').value=="AddedUser"){...}
Run ASP.Net code from JS
Create a div that hides it's content yet leaves the ASP.Net elements still clickable.
Insert ASP.Net button within the div. (There should be a work around with the __doPostBack(eventTarget, eventArgument), this would remove the hidden div and ASP.Net button)
In JS trigger <li onclick="trigger('#contentPage_btn');">Click me to trigger ASP.Net function</li>) run a method to simply trigger click event on the ASP.Net button. function trigger(x){$(x).click();}
Passing of data from one side to another can be done with ASP.Net hidden values or query strings.
To inject JavaScript from ASP you can do RegisterClientScriptBlock:
Type myType = this.GetType();
if (!ClientScript.IsClientScriptBlockRegistered(someType, "_FROMASP"))
{
string script = "alert('FROM ASP!');";
ClientScript.RegisterClientScriptBlock(someType, "FROMASP", script, true);
}
I think you are on the right track if you want to run ASP code from JS and not use AJAX. I normally use a hidden field with __doPostBack to pass messages rather than a DIV.
I have an ASP.NET GridView and multiple ListBoxes as Departments, Categories, Faculties etc. ListBoxes and GridView are filled from a database (MSSQL) in codebehind.
I need a JS or jQuery function that takes selected item's value and filters gridview rows by this value. For example, when a department selected from department listbox, it will show only the entries in that department (hide others).
I know, it is not a proper question without sample codes but i really need some hints in this case.
Thanks for help.
This might get you started.
jQuery
$("#ListBoxID").change(function() {
$("#" + GridViewID).find('td').not(':contains("' + $(this).val() + '")').parents('tr').hide();
});
Not that if your ListBox.SelectionMode is set to Multiple, $(this).val() will contain an array of selected items and you have to handle that as well.
You have a couple of options:
You could utilize jQuery Datatables (which takes your existing <table> markup that your gridview generates and powers it up with various useful options). Then you could make use of their API to add in your filtering logic. Here is an example:
http://www.datatables.net/release-datatables/examples/plug-ins/range_filtering.html
Another option is to code your own jQuery ajax call, that will fire when clicking on a list box item. It would then call a static Web Method (that returns string) in your code behind (and send the selected list box option as a parameter). Your static web method would re-query the database using the parameter value to filter the result. Then you would build a gridview in your code behind, data bind it with the query results, turn the gridview into a html string and return it as a response to your initial jQuery Ajax call. In the success: callback of your AJAX call you would grab the response html string and place it into the container html element that holds your Gridview on the page. More about this approach:
http://encosia.com/using-jquery-to-directly-call-aspnet-ajax-page-methods/ (explains calling the page method with jQuery)
http://encosia.com/boost-aspnet-performance-with-deferred-content-loading/ (slightly different example, it uses ASP.NET AJAX instead of jQuery AJAX to populate html on the page - but pay attention to the static Web Method - it demonstrates how to create a html string.)
If this all seems complex, you can use regular postback (not AJAX), by creating a selected index changed event on your listbox, that will re-query the database with the filtered option and rebind the existing gridview.
Hope that this helps
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.