ASP.NET Gridview with JQuery Mobile Dialog - asp.net

I've been struggling trying to link an ASP.NET Gridview to a JQuery Mobile dialog, which would be used to edit data in the Gridview.
My goal was to use the GridView to display the data. The user would click on a row, and a dialog would open a dialog with a FormView, which the user could edit the data for the selected row. I got this to work fine with a JQuery UI dialog, but when I switched to Jquery Mobile, things fell apart.
Right now the dialog flashes on the screen for a second if I run it on an iOS device, or a Blackberry. It works okay if I run it in Windows. I'm not sure what I'm doing wrong.
Here is my code for the aspx page:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="MyTest.aspx.cs" Inherits="MySite.MyTest" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Test</title>
<style type="text/css">
.hover
{
background-color: Gray;
}
</style>
<script type="text/javascript">
function clickRow() {
//Had to put in $(document).ready or I got PostBack errors.
$(document).ready(function () {
$.mobile.changePage("#dialogPage", 'pop', true, true);
});
}
</script>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<div data-role="page" id="mainpage">
<div data-role="content">
...GridView goes here...
Click Me
</div>
</div>
<div data-role="dialog" id="dialogPage">
<div data-role="content">
... FormView goes here....
</div>
</form>
</body>
</html>
And here is some of the code behind:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
//Allows user to click/tap anywhere on gridview row to trigger SelectIndexChange
e.Row.Attributes["onmouseover"] = "this.oldClass = this.className;this.className='hover';";
e.Row.Attributes["onmouseout"] = "this.className=this.oldClass;";
e.Row.Attributes["onclick"] = Page.ClientScript.GetPostBackClientHyperlink(GridView1, "Select$" + e.Row.RowIndex.ToString());
}
}
protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{
//This should open dialog
ClientScript.RegisterStartupScript(typeof(Page), "test", "clickRow()",true);
}
I think the problem is with the way I wrapped the $.mobile.changePage() function in the $(document).ready() function. If I didn't do that, I got postback errors. I'm not sure the right way to do this.
If I try to open the dialog using a <a data-rel="dialog"></a> link, it works fine on all devices.
Thanks for any advice.

I remember encountering a similar situation. The thing to remember is that when dealing with jQuery mobile, the script tags located within the head are not loaded on subsequent pages. Try moving your script block to within the tag that serves as the page.

Related

asp LinkButton inside html Button tag

I have some Html code that contains the button tag "<button></button>".
I have noticed that if I place a linkbutton inside this element, the postback of the linkbutton will never occur.
So this is not working :
<button><asp:LinkButton ID="lnkExample" OnClick="lnkExampleBtn_Click"runat="server">Text</asp:LinkButton></button>
The server method "lnkExampleBtn_Click" will never be launched.
How come the postback doesn't work ?
Is there a way to have a linkbutton work inside the "button" tag ?
I also tried putting an href element with javascript _doPostback specific method, but that is not working either.
I've tried to reproduce your case.
Here's code behind:
public partial class Test : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnTest_Click(object sender, EventArgs e)
{
lblTest.Text = "Test";
}
protected void btnTest2_Click(object sender, EventArgs e)
{
lblTest.Text = "Test2";
}
}
And here's aspx:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Test.aspx.cs" Inherits="WebApplication1.Test" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:LinkButton ID="btnTest" runat="server" OnClick="btnTest_Click">Test</asp:LinkButton>
<button><asp:LinkButton ID="btnTest2" runat="server" OnClick="btnTest2_Click">Test2</asp:LinkButton></button>
<button>test</button>
<asp:Label ID="lblTest" runat="server"></asp:Label>
</div>
</form>
</body>
</html>
What I found is - it depends on browser. In Chrome it's possible to place LinkButton inside tags. In Firefox and IE 10 it's not.
The reason why it's not working is simple - it's not allowed by the HTML 5 standard. You just can't embed a link inside a button.
http://www.w3.org/TR/2011/WD-html5-20110525/the-button-element.html#the-button-element
Link inside a button not working in Firefox

ASP.NET webforms postback weirdness with Safari 5.1.7 on Windows [duplicate]

This question already has an answer here:
Postback is not working in Safari in Windows 7
(1 answer)
Closed 3 years ago.
I have a simple ASP.NET webforms page with a button and a label. When using Safari 5.1.7 on Windows, clicking the button causes a postback, but does NOT actually cause the button click event to fire for some bizarre reason.
There are no javascript errors. There are no UpdatePanels or AJAX of any kind. This is literally the page I'm testing with:
<!doctype html>
<html lang="en">
<head runat="server">
<meta charset="utf-8">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
</form>
</body>
</html>
And the code behind is simply:
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
Label1.Text = "test";
}
When the button is clicked, the Page_Load event does fire one time, but Page.IsPostBack returns FALSE instead of true, and the Label1.Text is never set.
Note this problem ONLY happens in Safari. Everything works fine in IE8+, FF15+, Chrome 21+, and Opera 12+.
I've read numerous posts about Safari weirdness regarding hidden field size limitations (and therefore viewstate) - but this page should barely even be using viewstate (if at all). There are also many posts about javascript errors relating to UpdatePanels and/or AJAX calls, but as you can see there are none of those here.
I believe this question is also related, but I wanted to start a new one with example html/cs so you could reproduce the problem.
Am I missing something or is Safari on Windows really this weird?
I cannot duplicate this in Safari 5.1.7. Can you provide more information on how you are binding your events? Your manual assignment of onclick="Button1_Click" implies you are doing manual event wire up. Does your page declaration match this?
Are you sure your Page_Load event is firing; your example has it empty.
Maybe a more verbose event binding is in order, the below worked for me:
ASPX test page:
<%# Page Language="C#" AutoEventWireup="false"
CodeFile="default.aspx.cs" Inherits="PgSafari" %>
<!doctype html>
<html lang="en">
<head runat="server">
<meta charset="utf-8">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div><asp:Literal runat="server" ID="litTimeStamp" EnableViewState="false" /></div>
<div><asp:Button ID="Button1" runat="server" Text="Button" /></div>
<div><asp:Label ID="Label1" runat="server" Text="Default Label Text" /></div>
<div>
<h6>Log:</h6>
<asp:PlaceHolder runat="server" ID="plcOut" />
</div>
</form>
</body>
</html>
Code behind:
using System;
using System.Web.UI;
public partial class PgSafari : System.Web.UI.Page
{
public PgSafari()
{
//Bind Page Events
this.Init += new EventHandler(PgSafari_Init);
this.Load += new EventHandler(PgSafari_Load);
}
protected void PgSafari_Init(object sender, EventArgs e)
{
Log("_Init()");
//Bind Page Control Events
Button1.Click += new EventHandler(Button1_Click);
}
protected void PgSafari_Load(object sender, EventArgs e)
{
Log("_Load()");
Log("Page.IsPostBack = " + (Page.IsPostBack));
litTimeStamp.Text = "TimeStamp: " + DateTime.Now.ToString("mm:ss.fff");
}
protected void Button1_Click(object sender, EventArgs e)
{
Log("Button1_Click()");
Label1.Text = "test";
}
//===============\\
private void Log(String msg)
{
plcOut.Controls.Add(new LiteralControl("<div>" + msg + "</div>"));
}
}
The initial page hit in Safari looked like it should:
TimeStamp: 58:44.452
<button>
Default Label Text
Log:
_Init()
_Load()
Page.IsPostBack = False
Clicking the it looked like it should also:
TimeStamp: 59:48.869
<button>
TEST!
Log:
_Init()
_Load()
Page.IsPostBack = True
Button1_Click()

Page_load fires twice for UpdatePanel refresh whilst having a jQuery bound change event on a drop down list

I've tried to wrap up my problem with a complete example below - the original problem is part of a jQuery plug-in that I'm writing to extend the behaviour of an ASP.NET ajax application I already have.
The aspx page below has one drop down list which is marked for auto post back. I've also bound a change event using jquery (which ultimately I will swap for a .live() event to maintain the binding after the update panel refresh.) The problem is, when the jQuery event is bound I see two ajax begin requests and page_loads fire but only one ddlTest_OnselectedIndexChanged event. One of the page loads is malformed too - the content-length states it's about 300 bytes long whilst the totalBytes is 0 and form data empty. This does not happen if I bind to the click event of a button.
Can someone explain why the erroneous page_load event is firing please??
<%# Page Language="C#" AutoEventWireup="true" %>
<%# Import Namespace="System.Diagnostics" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<script runat="server">
private void Page_Load(object sender, EventArgs e)
{
Debug.WriteLine(Request.Headers["Content-Length"]);
Debug.WriteLine(Request.TotalBytes);
Debug.WriteLine(Request.Form.ToString());
Debugger.Break();
}
private void ddlTest_OnSelectedIndexChanged(object sender, EventArgs e)
{
Debugger.Break();
}
</script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js"></script>
<script type="text/javascript" language="javascript">
$(document).ready(function() {
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(beginRequestHandler);
$("#<%=ddlTest.ClientID%>").change(function() { alert('jQuery binding fired'); });
});
function beginRequestHandler() {
alert("Started ajax call");
}
</script>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="SciptManager" runat="server" />
<asp:UpdatePanel ID="updTest" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:DropDownList ID="ddlTest" runat="server" AutoPostBack="true" OnSelectedIndexChanged="ddlTest_OnSelectedIndexChanged" >
<asp:ListItem>First</asp:ListItem>
<asp:ListItem>Second</asp:ListItem>
</asp:DropDownList>
</ContentTemplate>
</asp:UpdatePanel>
</form>
</body>
</html>
Update : I've narrowed the problem down even further. Firefox and Chrome both work as I would expect whilst IE is having a problem. I've also simplified the erroneous code to the example below. It's hard to believe it's this simple but the jQuery .change() method on the drop down list triggers the onchange event on the select element twice! I'll look for other people who've had this problem and report back my findings!
<%# Page Language="C#" AutoEventWireup="true"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js"></script>
<script type="text/javascript" language="javascript">
$(document).ready(function() {
$('#ddlTest').change(function() { alert('jQuery event fired'); });
});
</script>
</head>
<body>
<form id="form1" runat="server">
<asp:DropDownList id="ddlTest" runat="server" onchange="alert('element event');">
<asp:ListItem Text="First" />
<asp:ListItem Text="Second" />
</asp:DropDownList>
</form>
</body>
</html>
The call of $("#<%=ddlTest.ClientID%>").change(... is probably trigger your drop down list and because of your autopostBack, you get an second refresh of your page.
It looks like I've uncovered a bug in the latest version of jQuery :(. If I change the test back to version 1.3.2 it works fine! I've also found a reference to a bug raised with jQuery.
Take out the autopostback=true = it is firing one postback and the change event is another.

How to dynamically render a control?

How do I go about rendering an asp.net control on a web page from a string in code behind?
For example, say I have the aspx page below:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="nrm.FRGPproposal.Questionnaire1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
//want to render a text box here
</div>
</form>
</body>
</html>
What could I do in my Page_Load event to render a TextBox into the div?
protected void Page_Load(object sender, EventArgs e)
{
//what do i do here to render a TextBox in the div from the aspx page?
}
Caution there may be compilation problems here. But basically add a placeholder control to the code in front as such.
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="nrm.FRGPproposal.Questionnaire1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:placeholder id="placeHolder" runat="server"/>
</div>
</form>
</body>
</html>
Then create a TextBox in the code behind programmatically. You will need to include System.Web.UI in order to get the textbox.
Then Add the control to the controls collection on the placeHolder. Set whatever properties you like on the text box programmatically
protected void Page_Load(object sender, EventArgs e)
{
TextBox tb = new TextBox();
placeHolder.Controls.Add(tb); //tb is referring to the name that you want to name your element. in this example given was TextBox. so the name of text box is tb.
}
Easy.
Add two attributes to your div element : <div runat="server" id="myDiv"></div>
Then
TextBox tb = new TextBox();
this.myDiv.Controls.Add(tb);
If you want to render a Custom UserControl you can use the above code
MyUserControl control = (MyUserControl)Page.LoadControl("~/My_VirtualPathToControl");
this.myDiv.Controls.Add(control);
(You must register your control in the aspx file)
One more think.
Be cautious when you execute code on Page_Load event.
You will also need to rebuild the controls in the Page_Init method in order to read the controls' state/values on PostBack.
protected void Page_Init(object sender, System.EventArgs e)
{
TextBox tb = new TextBox();
placeHolder.Controls.Add();
}

ASP.NET TextBox OnTextChanged triggered twice in Firefox

Hi I'm facing a weird problem that only happens in FF. I have a TextBox control with OnTextChanged handler. The event handler is working fine most of the time, but when the user changed the text and press Enter in FF, the OnTextChanged event is called twice. I observed the problem in Firebug that the first request is actually canceled because of the second event.
Test.aspx
<%# Page Language="C#" AutoEventWireup="True" CodeFile="~/Test.aspx.cs" Inherits="T.Test" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Custom TextBox - OnTextChanged - C# Example</title>
</head>
<body>
<form id="Form1" method="post" runat="server">
<asp:ScriptManager runat="server" ID="SM">
</asp:ScriptManager>
<h3>Custom TextBox - OnTextChanged - C# Example</h3>
<asp:UpdatePanel runat="server" ID="Panel1">
<ContentTemplate>
<asp:Panel runat="server" ID="Panel2">
<asp:TextBox ID="TextBox1" AutoPostBack="true" OnTextChanged="OnTextChanged" runat="server">Hello World!
</asp:TextBox>
</asp:Panel>
</ContentTemplate>
</asp:UpdatePanel>
</form>
</body>
</html>
Test.aspx.cs
using System;
using System.Web.UI;
namespace T
{
public partial class Test : Page
{
protected void OnTextChanged(object sender, EventArgs e)
{
var a = 0;
}
}
}
Put a break point # var a, and you'll be able to see that after changing text and press enter in FF (v3.5.7), the OnTextChanged event is invoked twice.
So my question is, what's the best way to properly handle OnTextChanged event so that hitting enter in the textbox doesn't trigger double postback.
Regards,
I don't know why it's isolated to FireFox, but if you remove the AutoPostBack property, that will solve the problem.
There is also an explanation here of why it's posting back twice.
I know its an old thread but maybe helpful for others.
I had the same issue when validating the text entered. I was getting 2 events fired so I put this script at the top of the page which causes the enter to just tab to the next control instead of submitting the form. The text box remained the same AutoPostBack="true" OnTextChanged="xxx_TextChanged"
''''
<script type="text/javascript">
$('body').on('keydown', 'input, select', function (e) {
if (e.key === "Enter") {
var self = $(this), form = self.parents('form:eq(0)'), focusable, next;
focusable = form.find('input,a,select,button,textarea').filter(':visible');
next = focusable.eq(focusable.index(this) + 1);
if (next.length) {
next.focus();
} else {
form.submit();
}
return false;
}
});
</script>
''''

Resources