UpdatePanel Breaks JQuery Script - c#

This is a simplified version of what I want to do. Basically I have a datalist with a bunch of stuff in it and when you mouseover items in the datalist I want jquery to hide/show stuff. The problem is that after I databind my gridview/repeater/datalist jquery quits working if the gridview/repeater/datalist is in an update panel.
After you click the button in the sample below, the jquery that makes the span show up when you mouse over quits working.
Any ideas of why this is happening, how to fix it or a better way to do this?
<script type="text/javascript">
$(document).ready(function() {
$('.comment-div').mouseenter(function() {
jQuery("span[class=mouse-hide]", this).fadeIn(50);
});
$('.comment-div').mouseleave(function() {
jQuery("span[class=mouse-hide]", this).fadeOut(50);
});
});
</script>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<div class="comment-div">
<asp:GridView ID="GridView1" runat="server">
</asp:GridView>
<span class="mouse-hide" style="display: none;">sdfgsdfgsdfgsdfg</span>
</div>
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
</ContentTemplate>
</asp:UpdatePanel>
And the code-behind:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
BindStuff();
}
}
public void BindStuff()
{
TestDB db = new TestDB();
var x = from p in db.TestFiles
select new { p.filename};
x = x.Take(20);
GridView1.DataSource = x;
GridView1.DataBind();
}
protected void Button1_Click(object sender, EventArgs e)
{
BindStuff();
}

The reason this is happening is because the controls get recreated on a partial postback. Use the 'live' feature of jQuery so rewrite your code like:
$(document).ready(function() {
$('.comment-div').live('mouseenter',function() {
jQuery("span[class=mouse-hide]", this).fadeIn(50);
});
$('.comment-div').live('mouseleave', function() {
jQuery("span[class=mouse-hide]", this).fadeOut(50);
});
});

When the UpdatePanel refreshes, it completely replaces all of the DOM elements that you had previously attached event handlers to. The easiest fix is to initialize your event handlers in pageLoad() instead of $(document).ready(). Its code will be executed both on the initial page load, but also after every UpdatePanel refresh.
The better solution is to change your code to use live() or delegate(), so that the event handlers aren't impacted by periodic changes in the page's contents.

When you do a AJAX postback using an update panel the DOM within it's removed and re-created when the AJAX response arrive.
The handlers you attached are lost unless you use the live method or the livequery library

See below for different jQuery versions:
$( selector ).live( events, data, handler ); // jQuery 1.3+
$( document ).delegate( selector, events, data, handler ); // jQuery 1.4.3+
$( document ).on( events, selector, data, handler ); // jQuery 1.7+

Related

How to prevent postback on asp button while displaying a popup using JQuery

I have the following ItemTemplate in my GridView:
<ItemTemplate>
<asp:Button UseSubmitBehavior="false" runat="server" ID="btnShow" CssClass="btnSearch" Text="View All" CommandName="ViewAll" OnClientClick="myfunction(); return false;" OnCommand="btnShow_Command" CommandArgument='<%#((GridViewRow)Container).RowIndex%>' />
</ItemTemplate>
For the ItemTemplate I have a button which opens a popup window when clicked by using the following JQuery:
$(document).ready(function () {
$(".btnSearch").click(function (e) {
e.preventDefault();
//centering with css
centerPopup();
//load popup
loadPopup();
});
});
function myfunction() {
}
my Command code-behind:
protected void btnShow_Command(object sender, CommandEventArgs e)
{
int index = 0;
if (e.CommandName == "ViewAll")
{
index = Convert.ToInt32(e.CommandArgument);
DataTable cacheTable = HttpContext.Current.Cache["ResultsTable"] as DataTable;
string column = cacheTable.Rows[index].Field<string>("Guideline");
string test = BookingResults.Rows[index].Cells[7].Text;
string html = HttpUtility.HtmlDecode(column);
ResultsDiv.InnerHtml = html;
//tbGL.Text = html;
//upData.Update();
//MessageBox.Show(index.ToString());
}
}
I added the OnClientClick="myfunction(); return false;" because it was doing a postback each time I clicked. If I have multiple rows, it only works the first time I click but any time after, the popup is not displayed when another or the same button is clicked.
How do I resolve it so no matter which button is clicked the popup is displayed without doing a postback?
Actually you have not showed up the implementation of your method myfunction(), in case the myfunction() method have any syntactical error then the OnClientClick event will be void and it will post-back/submit the form to the server.
Try to remove the call from OnClientClick and just implement your logic at jquery on click event by using class selector as follows
$(document).ready(function () {
$(".btnSearch").click(function (e) {
e.preventDefault();
alert($(this).val() + " Clicked"); // you can put your method mymethod() here
// you can put youe popup logic here
return false;
});
});
You can also see this example of js fiddle
Put it out on the tag or <%: Html.BeginForm %> tag
OnClientClick="return myfunction();
function myfunction(){
// you can put youe popup logic here
return false;
}
Using like this your button never do post back.

Use both Telerik RadGrid's OnRowClick as well as custom User Control Event Handler

I have a Telerik RadGrid populated in a Web User Control in C#, and it has a client OnRowClick event that occurs in Javascript on the client side of my User Control. This works nicely.
I also have an event called ControlClick that is associated with the User Control that I want to fire on the Web Form. ControlClick is bound in the CodeBehind of my UserControl to OnControlClick, and then bound to the User Control in my Web Form.
The OnRowClick event fires no problem, but the ControlClick event never triggers, so I never step into my Web Form function that handles the behavior when something in my RadGrid is clicked.
I'm not sure if I'm implementing my Event incorrectly or if it has to do with the fact that I'm already binding the click behavior to something with the RadControl. Anyone have any ideas?
Cheers!
Code Segments
RadGrid stuff:
<rad:RadGrid ID="gridRequests" EnableViewState="true" runat="server" OnNeedDataSource="gridRequests_NeedDataSource" OnItemDataBound="gridRequests_DataBound">
<MasterTableView>
<Columns>
<!-- The Column Stuff -->
</Columns>
</MasterTableView>
<ClientSettings EnableRowHoverStyle="true">
<ClientEvents OnRowClick="RowClickEvent" />
</ClientSettings>
</rad:RadGrid>
In the CodeBehind of my UserControl:
public event EventHandler ControlClick;
protected void OnControlClick(object sender, EventArgs e){
ControlClick(sender, e);
FilterId = Utils.NullSafeInt32(hdnFilterId.Value);
}
In my Main Page Markup
<ft:UserControl ID="ftUserControlInstance" runat="server" SharePoint="false" Visible="true" OnControlClick="ControlClick"/>
In my Main Page CodeBehind:
public void DRFGetQueryStrings(object sender, EventArgs e)
{
Mobile_WebControls_UserControlInstance getControl = (Mobile_WebControls_UserControlInstance)ftUserControlInstance;
_filterId = getControl.FilterId;
ScriptManager.RegisterStartupScript(this, this.GetType(), "script", "requestFulfillment()", true);
}
EDIT: This is my RowClickEvent:
function RowClickEvent(sender, eventArgs) {
var filterId = eventArgs.getDataKeyValue('FilterID');
document.getElementById("<%=hdnFilterId.ClientID %>").value = filterId;
}
Your RowClickEvent is taking the event, and its not bubbling to the postback
The first step is to just return true from your function.
function RowClickEvent(sender, eventArgs) {
var filterId = eventArgs.getDataKeyValue('FilterID');
document.getElementById("<%=hdnFilterId.ClientID %>").value = filterId;
return true;
}
This should ensure that the events continue and both are run.
If you still have problems however, you can call postback from within your javascript.
function RowClickEvent(sender, eventArgs) {
var filterId = eventArgs.getDataKeyValue('FilterID');
document.getElementById("<%=hdnFilterId.ClientID %>").value = filterId;
__doPostBack('__Page', 'MyCustomArgument');
}
The MyCustomArgument can be an empty string.
To do this the Telerik way, you would use the set_cancel method:
function RowClickEvent(sender, eventArgs) {
var filterId = eventArgs.getDataKeyValue('FilterID');
document.getElementById("<%=hdnFilterId.ClientID %>").value = filterId;
eventArgs.set_cancel(false);
}
Since you want a server event in the UC/Page, you need to POST the page in order to get them. The client-side RowClick event of the grid will not fire a custom server event by itself.
You can also consider using the server SelectedIndexChanged event of the grid to fire your custom event instead of raising a postback with some custom arguments. You can also use AJAX to avoid disposing the entire page.
Here is a very simple example (note that adding the RadAjaxManager to a user control is not a good idea, but you can create the AJAX setup programmatically or in some other fashion):
<telerik:RadAjaxManager ID="RadAjaxManager1" runat="server">
<AjaxSettings>
<telerik:AjaxSetting AjaxControlID="RadGrid1">
<UpdatedControls>
<telerik:AjaxUpdatedControl ControlID="RadGrid1" />
</UpdatedControls>
</telerik:AjaxSetting>
</AjaxSettings>
</telerik:RadAjaxManager>
<telerik:RadGrid ID="RadGrid1" runat="server" OnSelectedIndexChanged="RadGrid1_SelectedIndexChanged" OnNeedDataSource="RadGrid1_OnNeedDataSource">
<ClientSettings Selecting-AllowRowSelect="true" EnablePostBackOnRowClick="true">
<ClientEvents OnRowClick="doSomeClientWork" />
</ClientSettings>
</telerik:RadGrid>
<script type="text/javascript">
function doSomeClientWork(sender, eventArgs) {
var filterId = eventArgs.getDataKeyValue('FilterID');
alert(filterId);
}
</script>
protected void RadGrid1_SelectedIndexChanged(object sender, EventArgs e)
{
GridDataItem item = (GridDataItem)RadGrid1.SelectedItems[0];//get selected row
//make sure you pass the apporpriate arguments, sender is the grid already
ControlClick(sender, e);
}
protected void RadGrid1_OnNeedDataSource(object sender, GridNeedDataSourceEventArgs e)
{
RadGrid1.DataSource = "asdfg";
}

Dynamic Div creation asp.net

I am trying to create Div dynamically on the press of button click.
For that i refered this link>> http://forums.asp.net/t/1349244.aspx
and made code on server side(.cs page) as follows>>
public static int i = 0;
protected void Button1_Click(object sender, EventArgs e)
{
i++;
HtmlGenericControl newControl = new HtmlGenericControl("div");
newControl.ID = "NEWControl"+i;
newControl.InnerHtml = "This is a dynamically created HTML server control.";
PlaceHolder1.Controls.Add(newControl);
}
This code was giving me just one div each time when i press the button., I wanted to have addition of divs.
On client side using javascript also i tried>>
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="Button" OnClientClick="addDiv();" />
</div>
<asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
</form>
</body>
</html>
<script type="text/javascript">
function addDiv() {
alert("Control comming in function");
var r = document.createElement('Div');
r.style.height = "20px";
r.style.width = "25px";
r.appendChild("div");
alert("Control going out of function");
}
</script>
Both of these didnt work.
What mistake am i making?
Is there any thing wrong?
Use this
public int Index
{
get
{
if(ViewState["Index"]==null)
{
ViewState["Index"]=0;
}
else
{
ViewState["Index"]=int.Parse(ViewState["Index"].ToString())+1;
}
return int.Parse(ViewState["Index"].ToString());
}
}
protected void Button1_Click(object sender, EventArgs e)
{
HtmlGenericControl newControl = new HtmlGenericControl("div");
newControl.ID = "NEWControl"+Index;
newControl.InnerHtml = "This is a dynamically created HTML server control.";
PlaceHolder1.Controls.Add(newControl);
}
It is giving you one div, cause you are adding one div.
Remember that asp.net needs you to create all dynamically added controls on very PostBack after that.
If you want two controls you have to add two to the PlaceHolder.
Just use one parent div with some ID(predefined lets say id="dvDynamic") and runat="server"
and then use it the dvDynamic.innerHTML = "<div> /* dynamic div contents */ </div>"
Its the simplest way, as if you are using html element in ASP.net use dom controls for better generation. Dynamic creation of control will require handled, interface and many things to co-ordinate with that control. As its not predefined by system. you have to create it.
SO choose the DOM element option. that is faster and better :)
I hope this will help :)

Page with Ajax refreshes window title to be RGICLLayout3

I don't know if this is typical, SharePoint related or soemthing else, but I'm finding that with some simple Ajax on a page, after the code has finished executing, the page/window title is 'RGICLLayout3'.
i.e. I have an .aspx page with title "My Site - my page", and on there I have some controls, one of which lazy loads using JavaScript/Ajax. When that control finishes loading, the window/page title changed from 'My Site - my page' to be 'RGICLLayout3'.
Anyone seen this before? Googling 'RGICLLayout3' shows zero results.
QMKevin
[update]
here some general code to explain what I'm doing:
<asp:UpdatePanel ID="up" runat="server" UpdateMode="Conditional" OnPreRender="up_PreRender">
<ContentTemplate>
...
</ContentTemplate>
</asp:UpdatePanel>
<asp:UpdateProgress ID="updProgressTab" runat="server" AssociatedUpdatePanelID="up" >
<ProgressTemplate>
...
</ProgressTemplate>
</asp:UpdateProgress>
<script language="javascript" type="text/javascript">
function pageLoad(sender, e) {
if (!e.get_isPartialLoad()) {
__doPostBack('<%= up.ClientID %>', 'aaaa');
}
}
</script>
and then in the codefile
protected void up_PreRender(object sender, EventArgs e)
{
if (Request["__EVENTTARGET"] == up.ClientID && Request.Form["__EVENTARGUMENT"] == "aaaa")
{
System.Threading.Thread.Sleep(1000);
upPanel.Visible = true;
updProgressTab.Visible = false;
}
}
This does what I need, mostly, but as I said, once the JavaScript force Postback is complete, the page title is changed. Hopefully this make my situation clearer, but ask for further clarification if needed.

Prevent Postback after opening jQuery dialog box

Page:
<body>
<form id="frmLogin" runat="server">
<asp:Button ID="btnClick" OnClientClick="openConfirmDialog();" OnClick="PopulateLabel" runat="server"/>
<div id="divDialog"></div>
<asp:Label ID="lblText" runat="server"></asp:Label>
</form>
</body>
JS
<script type="text/javascript">
$(document).ready(function() {
$("#divDialog").dialog({autoOpen: false,
buttons: { "Ok": function()
{
$(this).dialog("close");
},
"Cancel": function()
{
$(this).dialog("close");
}
}
});
});
function openConfirmDialog()
{
$("#divDialog").dialog("open");
}
C#
protected void Page_Load(object sender, EventArgs e)
{
lblText.Text = "";
}
protected void PopulateLabel(object sender, EventArgs e)
{
lblText.Text = "Hello";
}
This code opens me a dialog box with Ok and Cancel button but it do not wait for user activity and post the page immediately and the label gets populated. I need to call the c# function based on user activity. If user clicks "Ok" label should get populated and if user clicks "Cancel" it should not call the c# function. How do I achieve this?
First, to prevent the page from immediately posting back to the server, you need to cancel the default behavior of the click event by returning false from your handler:
<asp:Button ID="btnClick" runat="server" OnClick="PopulateLabel"
OnClientClick="openConfirmDialog(); return false;" />
Next, you need to perform the postback yourself when your Ok button is clicked:
$("#divDialog").dialog({
autoOpen: false,
buttons: {
"Ok": function() {
$(this).dialog("close");
__doPostBack("btnClick", "");
},
"Cancel": function() {
$(this).dialog("close");
}
}
});
Note that the first argument to __doPostBack() is the name of the control (its UniqueID in ASP.NET terminology). Since the button is a direct child of the <form> element, we can hardcode its id in the __doPostBack() call, but things will get more complicated if it resides in a container hierarchy. In that case, you can use ClientScript.GetPostBackEventReference() to generate the appropriate call to __doPostBack().
EDIT: Since your page does not contain any postback-enabled control, __doPostBack() won't be defined on the client side. To work around that problem, you can use a LinkButton control instead of a Button control.
Added another button and used the jQuery click() event to trigger new button's click event which will in turn trigger the respective event handler in C#

Categories

Resources