i am not sure if my design have flaw but would like to know what others have to say, i am in a situation where i am trying to acheive two things in one click.
using : asp.net web form
i have a web form with few textbox and a gridview control and a button.
if i click on the button i am executing two things
1) asynchronously get data from server to client (working great) and able to display the data in the textboxes.
2) same click i want to bind the gridview.
<asp:Content ID="Content2" ContentPlaceHolderID="cphMaster" runat="server">
<asp:Label runat="server" ID='Label1' >Id:</asp:Label>
<asp:TextBox ID="txtId" runat='server'></asp:TextBox>
<asp:Button ID="btnSubmit" OnClientClick="LoadDataById();" runat="server" Text="Submit"
onclick="btnSubmit_Click" />
<br />
<br />
<asp:TextBox ID="txtName" runat='server'></asp:TextBox> <br />
<asp:TextBox ID="txtPurpose" runat='server'></asp:TextBox> <br />
<br />
<asp:GridView ID="GridView1" runat="server">
</asp:GridView>
</asp:Content>
server side
protected void btnSubmit_Click(object sender, EventArgs e)
{
GridView1.DataSource = laodData(int.Parse(txtId.Text));
GridView1.DataBind();
}
Jquery:
function LoadVisitBasicByVisitId() {
ContactServiceProxy.invoke({ serviceMethod: "GetDataById",
data: { request: request },
callback: function(response) {
processCompletedContactStore(response);
},
error: function(xhr, errorMsg, thrown) {
postErrorAndUnBlockUI(xhr, errorMsg, thrown);
}
});
return false;
}
recap:
1) jquery script execute asynchronously to get data from server to client and display in the textboxes
2) server side code to bind the gridview.
PROBLEM:
if i have onClientClick="return LoadDataById(); then it executes ONLY ajax code and does not execute server side
but if have onClientClick="LoadDataById(); then it executes client and server but textbox value wipeout. (the textbox value popuplate through ajax)
if your jquery function would return true, your server side code would process. Returning false prevents the page from posting back to the server.
also, set your onClientClick="return LoadDataById();"
I've developed something in past with this way of think and as I remember, I have no troubles with this.
But if you return false in jQuery, postback will not happen.
Related
Iam newbie to ASP.NET, and this is my first question on this forum.
Here is my code:
protected void Button1_Click(object sender, EventArgs e)
{
for (int i = 0; i < 10; i++)
{
Label2.Text = i.ToString();
UpdatePanel1.Update();
Thread.Sleep(3000);
}
}
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Label ID="Label1" runat="server" Text=""></asp:Label>
<asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click"/>
<asp:Label ID="Label2" runat="server" Text=""></asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
I want to display the value of i each time when its get updated, but I got the value 9.
Please help me how can achieve my goal... No luck so far
You can't update the page in the browser directly from server code. Any updates to the page are sent back to the page when the server code ends.
The Update method only tells the update panel that it should be included in the data that is sent back to the browser when the page is complete, it doesn't send the update directly to the browser.
To periodically update content in the browser using server code you have to control it from the browser, and the server code should just do one update and then exit so that the update is sent back to the browser. You can user a timer control that will make requests to the server for every tick, or you could use Javascript code to request data from a server page.
I'm building a very simple chat page on my website, here is what I have so far:
And this is the code:
<asp:Content ID="Content2" ContentPlaceHolderID="maincontent" Runat="Server">
<script language="javascript" type="text/javascript">
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(EndRequestHandler);
function EndRequestHandler(sender, args) {
document.getElementById('<%=FormView1.FindControl("chattxt").ClientID%>').focus();
}
</script>
<div id="chatbg">
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<div id="chatmessages">
<asp:Repeater ID="Repeater1" runat="server" DataSourceID="SqlDataSource1">
<ItemTemplate>
<asp:Literal ID="Literal1" runat="server" Text='<%# Eval("Username") %>'></asp:Literal>: <asp:Literal ID="Literal2" runat="server" Text='<%# Eval("Message") %>'></asp:Literal><br />
</ItemTemplate>
</asp:Repeater>
</div>
<asp:ListBox ID="ListBox1" runat="server" Rows="16" CssClass="memberlist"></asp:ListBox>
</ContentTemplate>
</asp:UpdatePanel>
<asp:UpdatePanel ID="UpdatePanel2" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:FormView ID="FormView1" runat="server" DefaultMode="Insert"
OnItemInserted="fv_ItemInserted" RenderOuterTable="False"
DataSourceID="SqlDataSource1">
<InsertItemTemplate>
<asp:Panel ID="Panel1" runat="server" DefaultButton="Button1">
<asp:TextBox ID="chattxt" runat="server" CssClass="chattxtbox"
Text='<%# Bind("Message") %>' autocomplete="off"></asp:TextBox>
<asp:Button ID="Button1" runat="server" CommandName="insert" style="display:none" Text="Button"/>
</asp:Panel>
</InsertItemTemplate>
</asp:FormView>
</ContentTemplate>
</asp:UpdatePanel>
</div>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:orangefreshConnectionString1 %>"
InsertCommand="INSERT INTO [Chat] ([Username], [Message]) VALUES (#Username, #Message)"
SelectCommand="SELECT [Id], [Username], [Message], [Date] FROM [Chat] ORDER BY [Id]" >
<InsertParameters>
<asp:Parameter Name="Message" Type="String" />
<asp:Parameter Name="Date" Type="DateTime" />
<asp:SessionParameter Name="Username" SessionField="Username" Type="String" />
</InsertParameters>
</asp:SqlDataSource>
<script type="text/javascript">
function scrollpos() {
var objDiv = document.getElementById("chatmessages");
objDiv.scrollTop = objDiv.scrollHeight;
}
</script>
</asp:Content>
The script at the top of the page puts the focus back on my Textbox
after a postback.
The script at the bottom of the page makes sure the scroll on the message window is always at the bottom through post backs.
This is my codebehind:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Security;
using orangefreshModel;
public partial class chat : BasePage
{
protected void Page_Load(object sender, EventArgs e)
{
Session["Username"] = User.Identity.Name;
ListBox1.Items.Clear();
foreach (MembershipUser myuser in Membership.GetAllUsers())
if (myuser.IsOnline == true)
{
ListBox1.Items.Add(myuser.ToString());
}
ScriptManager.RegisterStartupScript(
UpdatePanel1,
this.GetType(),
"ScrollPos",
"scrollpos();",
true);
}
protected void fv_ItemInserted(object sender, FormViewInsertedEventArgs e)
{
this.FormView1.DataBind();
}
}
So all of this is working pretty good, the UpdatePanel ensures my messages popup straight away, the problem now is seeing other user messages. This is my first ever ASP.NET project, so I thought about cheesing it a bit and trying a Timer every second to repopulate my repeater... but to no success, and I don't think it's a wise solution at all:
First of all, the Timer affecting my Repeater window made it impossible for a user to scroll back up to read messages, seeing as it refreshed every second scrolling was just not possible.
Secondly, I never got it to work anyway, this is the event I tried for my Timer:
protected void Timer1_Tick(object sender, EventArgs e)
{
this.Repeater1.DataSource = SqlDataSource1;
this.Repeater1.DataBind();
}
But yeah, no success.
This is where I'm at right now with this chat: I can see my messages popping up fine, but now I need to figure out a way for my window to update as other users type their message, if some other user types a new message in, I need to send in my own message in order to see theirs.
I've been browsing the web for a bit, read a few things about Signal R, but I was wondering if someone had simpler idea on where I should go with this, how to implement real time updates on my message window?
I suggest looking into SignalR - http://nuget.org/packages/signalr
SignalR is a library that keeps persistent connection open and allows the server to "push" data to the client.
You can also look at http://www.slideshare.net/adammokan/introduction-to-signalr-10082193 as a decent overview of SignalR
It
One option is to do this outside of the ASP.Net lifecycle and makea manual AJAX request to the server. The server method can hold on to the connection for a max of 30 secs, returning any new messages as soon as they arrive. This is then returned to the client and handled in JS, and they then open another connection and wait again. I've heard this called the reverse AJAX poll.
However you detect new messages is up to you, you could poll the DB every second, or maintain in memory message etc.
Note that this can cause problems if thousands of clients are holding open connections to the server.
I agree with KingPancake that SignalR would be a very good way to approach something like this. You could "back-end" this with something like the new .Net Web API in conjunction with SignalR if you want to persist the data at all
Check out this presentation by Brad Wilson which might help you:
SignalR is a good option.
However if you do want to do it yourself for some reason, this is how you should go about it.
The most efficient method to build a chat in asp.net is to use a IHttpAsyncHandler and ajax requests.
An async request allows you to delay the response of a request till an external event occurs.
A user makes a call to this handler and waits till someone sends him a message.
Messages are delivered as soon as you send them to a user.
On receiving a message the client makes another request and waits for the next message.
This is how you keep a persistent connection open and allows the server to push data to the client.
This is a lot more efficient than polling the site to check if messages have arrived.
Using the async handler also ensures that no asp.net threads are wasted while a user waits for messages to come. Polling with a timer you will quickly run out of threads to process requests in asp.net.
This ensures that your chat can scale well even as the number of users of the site goes up.
Here is a completely working project that implements this, along with ajax.
im trying to build a form+attachment that needs to be send to email.
Im using a VB background code (attachementemail.aspx.vb)
and my front (b-16.aspx)
I want the page to check that the user entered a email, name, phonenumber and attachment.
what command do I put in the axp.vb
and what on the .aspx
tried just about anything.
The simplest way is to use validators eg RequiredFieldValidator for mandatory fields. You can also implement CustomValidators for custom logic.
See http://msdn.microsoft.com/en-us/e5a8xz39.aspx for the available validators
At it's basic level you could use RequiredFieldValidator and CustomValidation in your form. You can use some regex logic for email, I use this but there are many out there:
Regex(#"\w+([-+.]\w+)#\w+([-.]\w+).\w+([-.]\w+)*")
Personally I use client side javascript before it hits the server and then I re-validate the entries once it hits the server. If your using the postback events then you'll need update panels and a scriptmanager (not sure if you are aware of this already, so apologies if teaching you to suck eggs!).
Here is an example:
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server"
ErrorMessage="RequiredFieldValidator" ControlToValidate="TextBox1"></asp:RequiredFieldValidator>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="Button" />
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
Code behind (sorry this is in c#)
protected void Button1_Click(object sender, EventArgs e)
{
if (RequiredFieldValidator1.IsValid)
{
Label1.Text = "Has content";
}
else
{
Label1.Text = "Not valid";
}
}
Note that the required field validator has it's own methods to display a "hey you haven't entered content here my friend" message, but i have added that to the label instead.
Hi I found code similiar to the following online. It's seems really great for getting a button buried in a repeater control to trigger a full cycle back to the server.
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<%=DateTime.Now.ToString() %>
</ContentTemplate>
<Triggers>
<asp:PostBackTrigger ControlID="HiddenButton" />
</Triggers>
</asp:UpdatePanel>
<!--Make a hidden button to treat as the postback trigger-->
<asp:Button ID="HiddenButton" runat="server" Style="display: none" Text="HiddenButton" />
<asp:Repeater ID="Repeater1" runat="server" DataSourceID="SqlDataSource1">
<ItemTemplate>
<!--when cick the button1, it will fire the hiddenButton-->
<asp:Button ID="Button1" Text="Trigger" CommandArgument='<%# Eval("Id") %>' OnClientClick="$get('HiddenButton').click();return false;"
runat="server" />
</ItemTemplate>
</asp:Repeater>
It uses a hiddenButton to achieve this by hooking the click event of the original button to this one. However my addition to this was the setting of the CommandArgument for the button. I would also need it to be set for the HiddenButton.
Does anyone know a way of going about this?
First I will like to explain the Disadvantage of using the Update Panel using the very same example posted by you.
Below is the Original Code
Output
To display the 22 character string you can check how much data is being received and sent to server. Just imagine following
If you would consider send each request to Database using Update Panel and your GridView is in Update Panel!!!!!!
Suppose you would use ViewState data for each request and with GridView Inside the Update Panel.
Both the above techniques are worst as per my understanding.
Now I will describe you Page Methods
Page Method over Update panel
Page Methods allow ASP.NET AJAX pages to directly execute a Page’s Static Methods, using JSON (JavaScript Object Notation). Instead of posting back and then receiving HTML markup to completely replace our UpdatePanel’s contents, we can use a Web Method to request only the information that we’re interested.
Sample Code
Output
Hope this clearly explains the difference of usage.
Answer to the original Query
You have to register the ItemDataBound event of the below Repeater and use below code for it.
Code Behind
protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item ||
e.Item.ItemType == ListItemType.AlternatingItem)
{
Button btn = (Button)e.Item.FindControl("Button1");
btn.OnClientClick = string.Format("SubmitButton('{0}');return false;"
, HiddenButton.ClientID);
}
}
JavaScript
<script type="text/javascript">
function SubmitButton(btn)
{
$("#" + btn).click();
}
</script>
//Alternative
<script type="text/javascript">
function SubmitButton(btn)
{
document.getElementById(btn).click();
}
</script>
Reference & Here
Your HiddenButton control is a server control but you are trying to access it in JQuery using it's ASP.Net ID,
<asp:Button ID="Button1" Text="Trigger" CommandArgument='<%# Eval("Id") %>' OnClientClick="$get('**HiddenButton**').click();return false;"
runat="server" />
A quick way to fix it is to make a separate function,
<script type="text/javascript">
function SubmitButton(btn)
{
$get("#" . btn).click();
}
</script>
and change your button code to ,
<asp:Button ID="Button1" Text="Trigger" CommandArgument='<%# Eval("Id") %>'
runat="server" />
In code behind, in repeater's ItemDataBound event, find the button and HiddenControl and set Button1's OnClientClick property,
Button1.OnClientClick= string.Format("SubmitButton('{0}');return false;",HiddenButton.ClientID);
I am creating a ModalPopupExtender inside a Web User Control.
When i click on the OK Button in the panel, which is showing as model popup, the Event Handeler of the button is not executing.
This problen does not occure when i do not use the Web User Control.
Here is the user control (.ascx) file code.
<script type="text/javascript" language="javascript">
function OkClicked(sender, e) {
__doPostBack('Button1', e);
}
</script>
<asp:Button ID="Button2" runat="server" Text="Show" />
<asp:Panel ID="Panel1" runat="server">
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />
</asp:Panel>
<asp:ModalPopupExtender ID="ModalPopupExtender1" runat="server"
DropShadow="True" OkControlID="Button1" PopupControlID="Panel1"
TargetControlID="Button2" onokscript="OkClicked()">
</asp:ModalPopupExtender>
<p>
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
</p>
And the Event Handeler for the click event of the 'Button1' is
protected void Button1_Click(object sender, EventArgs e)
{
Label1.Text = TextBox1.Text;
}
In the javascript you shouldn't put 'Button1' as the name of the control. Instead, on the PreRender event of your control, fill that out with this.Button1.ClientID .
ClientID is the unique identifier across the entire generated page of your button control, allowing the server to pinpoint exactly what control triggered the postback.
If this wasn't like that, you wouldn't be able to place multiple instances of a same control on one page.
In code:
<script type="text/javascript" language="javascript">
function OkClicked(sender, e) {
__doPostBack('<%= this.Button1.ClientID %>', e);
}
Couple of suggestions:
Do you have any kind of validation on this page. If so, then it's possible that when you click the ok button, that validation is failing. When you click the button, likely the ModalPopup Extender will close, and if validation fails it may cancel the event happening. If this is the case, add an attribute: CausesValidation="false"
If that doesn't work, you may add an attribute to MAKE it post back, I believe there's an attribute -> AutoPostBack="true".
#Joachim is correct that you'll need to use the clientID, but at the same time, I don't think you'll need to call javascript to run the backend code.
Also, you may consider putting this into an UpdatePanel so that you do an AJAX postback without sending the entire page back and forth when the page is posted back.