How to update votes client side using WebForms - javascript

I'm trying to implement voting very similar to Stack Overflow's. There are multiple items that all have a vote button next to it. Currently, I have it working, but it's done server side, posts back, and takes a while to reload the data. Here is the flow:
You click the vote button,
it fires a javascript function which clicks a hidden ASP.NET button (did it this way because there are multiple vote buttons per page),
the button fires,
it updates the database, and then
the page posts back and refreshes, showing the update.
How do I leverage javascript and AJAX to eliminate this bad user experience? I want it to work like Stack Overflow's, but I'm not using MVC. Any help, examples, suggestions would be great. Thanks.
Update:
I have this implemented, but when I place breakpoints on the Web Method it doesn't even fire and I always get the error alert. Any ideas?
javascript:
<script type="text/javascript">
$(document).ready(function () {
$("[id^=VoteMeUp]").click(function (event) {
var dta = '{ "VoteId":' + $(event.target).val() + '}';
$.ajax(
{
type: 'POST',
data: dta,
url: 'Default.aspx/SaveUpVote',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
//$(event.target).text("Vote Casted");
alert("Vote Casted");
},
error: function (x, y, z) {
alert("Oops. An error occured. Vote not casted! Please try again later.");
}
}
);
});
});
</script>
Code Behind (you can use C#, I'm familiar with both):
Imports System.Web.Services
Imports System.Web.Script.Services
<WebMethod()>
Public Shared Function SaveUpVote(ByVal VoteID As Integer) As Boolean
Dim test As Boolean = False
Dim mySQL As New SQLHandler
test = mySQL.UpdateVoteByID(VoteID)
Return test
End Function
HTML:
<input type="image" src="images/vote.png" id="VoteMeUp1" value="321" />

When a vote is cast for a given button, call the server method using ajax (for aspx) as follows:
$(document).ready(function() {
$("[id^=VoteMeUp]").click(function(event) {
var dta = '{ "VoteId":' + $(event.target).val() + '}';
$.ajax(
{
type: 'POST',
data: dta,
url: 'Default.aspx/SaveUpVote',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(data) {
$(event.target).text("Vote Casted");
},
error: function(x, y, z) {
alert("Oops. An error occured. Vote not casted! Please try again later.");
}
}
);
});
});
In Default.aspx.cs
[WebMethod]
public static void SaveUpVote(int VoteId)
{
string UpdateSQL = "UPDATE TableName SET Votes = Votes + 1 WHERE PKID = #VoteId";
//do DB stuff
return;
}
Sample HTML:
...
<body>
<button id="VoteMeUp1" value="817">1 - Vote for this</button>
<button id="VoteMeUp2" value="818">2 - Vote for that</button>
</body>
...

the easiest method to do this would be WebMethods.
Add a ScriptManager to your page with EnablePageMethods set to true
aspx page:
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true" />
Assign a web method attribute to the method which increments the votes in your (c# here) code behind:
c# code behind:
[System.Web.Services.WebMethod]
[System.Web.Script.Services.ScriptMethod]
public string ChangeVote(string Arg){
...logic to change votes
}
in your javascript event, you can then access the code behind via pagemethods, and define functions to call on success and fail cases:
javascript:
PageMethods.ChangeVote("sent item", OnChangeVoteComplete,OnChangeVoteFail);
function OnChangeVoteComplete(arg){
//arg is the returned data
}
function OnChangeVoteFail(arg){
//do something if it failed
}
the success function receives the data returned by the WebMethod. You can use this to update the display on the page.

When use clicks on the UpVote button, make an ajax call to the server where you execute a query againist the database to increment the vote.
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
</head>
<body>
Vote UP
</body>
<script type="text/javascript">
$(function(){
$("#aUpVote").click(function(){
$.post("myajaxserverpage.aspx?qid=12",function(data){
alert(data);
});
});
});
</script>
</head>
and in the server page (myajaxsever.aspx), read the values and execute your query to increment the Vote column value. value of qid is the question id this you can read from the page because it is going to be dynamic.

Related

AJAX indicates that WEBMETHOD was successful, but it never actually triggers the webmethod on code behind

I've been through countless posts and cant figure out what I am doing wrong. I have a asp.net website with C# code behind. In it, I need for a javascript function on the .aspx page to trigger a method on the aspx.cs page. I wrote the following code:
.aspx page (my ScriptManager):
</head>
<body id="bodycontainer">
<asp:ScriptManager ID="ScriptManager2" runat="server" EnablePartialRendering="false" EnablePageMethods="true"/>
The Javascript function using ajax on the .aspx page:
function ValidateForm() {
$.ajax({
type: "POST",
url: "default.aspx/Save",
data: {},
contentType: "application/json; charset=utf=8",
// dataType: "json", // NOT NEEDED IF NO RETURN VALUE
async: true, // OPTIONAL
success: function (msg) {
alert("success");
},
error: function (msg) {
alert("failed");
}
});
}
The aspx.cs page (Code Behind page):
[WebMethod]
public static void Save()
{
// throw new DivideByZeroException(); // USED THIS TO VERIFY IF WEBMETHOD IS HIT.
_default obj = new _default();
obj.Show("Save Method Works"); // THIS IS A POPUP MESSAGE BOX
obj.btnSave_Click(); // THIS IS THE SAVE METHOD ON THIS PAGE THAT WE WANT TO RUN
}
public void btnSave_Click()
{
// METHODS CODE HERE
}
The ValidateForm function responds with "success", however, it doesn't seem like it is even triggering the WebMethod on the Code Behind page. If I use the I.E. Console Network tab, I can see the POST request. However, on the code behind method, it never triggers the breakpoints in debug (Not sure if it should according to some posts). At one point I inserted line to throw a DivideByZero exception and it never raised the exception.
So, to summarize, I get confirmation that he Javascript call to the WEBMETHOD worked by virtue of the success message and the POST message in the F12 Console Network tab. However, it doesn't seem that the WEBMETHOD ever fires. Any help would be appreciated !
You could try this to test an error instead of throwing an exception
Response.Clear();
Response.StatusCode = 500;
Response.End;
Not sure what I did, but I think adding "UseHttpGet = false" allowed it to finally execute the webmethod.
[WebMethod(EnableSession = true)]
[System.Web.Script.Services.ScriptMethod(UseHttpGet = false)]
public static void Save()
{
// throw new DivideByZeroException(); // USED THIS TO VERIFY IF WEBMETHOD IS HIT.
_default obj = new _default(); // SINCE THIS METHOD IS STATIC, WE HAVE TO INSTANTIATE AND INSTANCE OF THE DEFAULT PAGE CLASS TO ACCESS METHODS ON THIS PAGE
obj.Show("Save Method Works"); // THIS IS A POPUP MESSAGE BOX
obj.btnSave_Click(); // THIS IS THE SAVE METHOD ON THIS PAGE THAT WE WANT TO RUN
}
function ValidateForm() {
var text = "This is a Test";
$.ajax({
type: "POST",
contentType: "application/json; charset=utf=8",
data: "{}",
url: "default.aspx/Save",
dataType: "json",
success: function (msg) {
alert("success");
},
error: function (XMLHttpRequest, textStatus, errorThrown){
alert("status: " + textStatus);
alert("Error: " + XMLHttpRequest.responseText);
}
});
}

ASP.net: AJAX Result Not Kicking Off

I think this will be a weird one for you as I am at my wits end with this. On a screen I have in a table, I have a link being clicked that is setting off a javascript/ajax request. I have similar code in another screen that works perfectly as it heads down into the success part of the ajax call and runs code in the success portion of the call. For some reason though I can't seem to get this to work and when I debug it in chrome, I lose my breakpoints and it never seems to get into the success portion of the Ajax call.
#section scripts{
<script>
// Get the bond ID Data from the row selected and return that to the program.
function getIDData(el) {
var ID = $(el).closest('tr').children('td:first').text();
var iddata = {
'ID': ID
}
console.log(iddata);
return iddata;
}
// Submit the data to a function in the .cs portion of this razor page.
$('.updatelink').click(function () {
var bondid = JSON.stringify(getIDData(this));
$.ajax({
url: '/Maintenance/Bond_Maint?handler=UpdateandReloadData',
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
type: 'POST',
dataType: 'json',
data: { bondid: bondid },
success: function (result) {
if (result.pass != undefined) {
document.forms[0].submit();
}
},
});
});
</script>
}
The ASP.net code behind that is calling does an update to the database and then passes back a variable containing Success as its message.
//-------------------------------------------------------------------------------
// Try to get and insert the data from a selected row and copy it
//-------------------------------------------------------------------------------
public ActionResult OnPostUpdateandReloadData(string bondid)
{
return new JsonResult(new { pass = "Success" });
}
I'm not sure how else to describe my issue other than when I debug my other code via the browser, it appears to take a different path than this code does and I cannot fathom why. For reference my other code looks like this:
#section scripts{
<script>
// Get the offender ID Data from the row selected and return that to the program.
function getIDData(el) {
var ID = $(el).closest('tr').children('td:first').text();
var iddata = {
'ID': ID
}
console.log(iddata);
return iddata;
}
// Submit the data to a function in the .cs portion of this razor page.
$('.copybtn').click(function () {
var offenderid = JSON.stringify(getIDData(this));
$.ajax({
url: '/Copy_Old_Account?handler=CopyData',
beforeSend: function (xhr) {
            xhr.setRequestHeader("XSRF-TOKEN",
                $('input:hidden[name="__RequestVerificationToken"]').val());
        },
type: 'POST',
dataType: 'json',
data: { offenderid: offenderid },
success: function (result) {
if (result.path != undefined) {
window.location.replace(result.path);
}
},
});
});
</script>
}
Any help would be appreciated.
Okay guys so first off, thank you everyone for responding to my question. Frank Writte and Alfred pointed me into the right direction by looking for the status in the network tab for my calls. I found out that I was getting cancellations for my requests. After looking into that I found this article What does status=canceled for a resource mean in Chrome Developer Tools? that has an answer from FUCO that gave me what I needed to do. Apparently I needed to add event.preventDefault(); in front of my ajax call and all of a sudden my code worked. I'm not sure I completely understand why this works but I can't complain about the results. Again thank you everyone for trying to help. This one has been boggling my mind all morning.

How to pass a string from javascript to server? and then get a return value from server in asp.net webforms

I have this modal. inside a form tag
<div id="Incoming_Call" class="modal fade" role="document">
<asp:Label runat="server" id="Caller_id" Text="Incoming Call"</asp:Label>
</div>
I want to change the label text when the modal will show
<script>
string id = "temporary value"//javascript has this value on clientside.
// i don't have this value on page load but after some event triggers.
$('#Incoming_call').on('shown', function(){
id="zetawars#hotmail.com";
var text = '<%= generatestring(id)%>';
$('#<%=Caller_id.ClientID%>').html = id;
});
</script>
I need to send that id variable to server side to a function generateString() after the string has changed from id="temporary Value" to id="zetwars#hotmail.com" or something
This is on server side.
public string generateString(string id)
{
id = // does some processing;
return id;
}
So, I want to send a variable of javascript to the server side then server has to do some processing and return the value. the javascript variable is not ready at page load time. So I can't pass it inside <%%> these tags and get a newer value. It will only pass "temporary value" as a string not the new value.
Calling a server side method from javascript is really simple.You can do this with jQuery $.ajax function and a [WebMethod]
Code behind:
protected void Page_Load(object sender, EventArgs e)
{
}
[System.Web.Services.WebMethod]
public static string generateString(string id)
{
System.Diagnostics.Debugger.Break();
return String.Format("Response from server for - {0}.Call time - {1}",id,DateTime.Now.ToString("HH:mm:ss"));
}
.ASPX:
<head runat="server">
<title></title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.3/jquery.min.js"></script>
<script type="text/javascript">
$(function () {
var id = "temporary value";
$("#btnMakeAjaxCall").click(function () {
MakeAjaxCall();
});
function MakeAjaxCall() {
$.ajax({
type: "POST",
url: "AjaxCallExample.aspx/generateString",
contentType: "application/json;charset=utf-8",
data: '{id:"' + id + '"}',
dataType: "json",
success: function (data) {
var caller = '<%: Caller_id.ClientID %>';
$("#" + caller).text(data.d)
},
error: function (errordata) {
console.log(errordata);
}
});
}
});
</script>
</head>
<body>
<form id="form1" runat="server">
<input type="button" id="btnMakeAjaxCall" value="Make AJAX call" />
<asp:Label ID="Caller_id" runat="server" Text="Incoming Call"></asp:Label>
</form>
</body>
You can make an ajax call to server and use the returned value.
you can make ajax call each time the modal is shown
or
you can make ajax call whenever you are ready to get result from server, this way you can make ajax call and store the result in a hidden variable on page or some other already defined variable and use the variable in modal.
jQuery code to make ajax call to server
To make ajax call you need to add reference to jQuery in your page.
$.ajax({
url: "/controller_name/method_name",
type: "POST",
data: { var1:var1},
success: function (response) {
//use response here
},
error: function () {
alert("Some unexpected error occured. Please try again.");
}
});
This is the way you can accomplish what you want, lets us know id you need help in coding also.

how can i get name from javascript to code behind from following

this is the method to get userinfo from gmail. i dont know how to pass username values to code behind can any one help ..
function getUserInfo() {
$.ajax({
url: 'https://www.googleapis.com/oauth2/v1/userinfo?access_token=' + acToken/acToken,
data: null,
success: function (resp) {
user = resp;
console.log(user);
$('#uName').text('Welcome ' + user.name);
$('#imgHolder').attr('src', user.picture);
},
dataType: "jsonp"
});
}
I think you need the response you got from ajax call in the code behind. For that you have to set the value to a hidden field. So that you can access the values in code behind using its ID.
You can use this code if you are working with ASP .net
HTML code --
<asp:hiddenfield ID="user" runat="server"></asp:hiddenfield>
Jquery
$("#user").val(user); // Add data to html field
CodeBehind
Object user = user.Value;

ASP.Net call codebehind on $.ajax success

I have a page (default.aspx) with codebehind. The a$.ajax url is getting a response from one place, and on its success I want to call the codebehind function.
(In case I made a mistake while obfuscating the code, the $.ajax works perfectly and I get the desired response).
How is this possible?
Code I'm using:
jQuery.support.cors = true; // force cross-site scripting (as of jQuery 1.5)
$.ajax({
type: "POST",
url: URL,
data: parameters,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
var resultCount = response.d
alert("*** RESULT ****" + resultFields);;
var string = StringReturn(); // the codebehind
alert(string);
},
error: function (e) {
alert("Unavailable");
}
});
Codebehind:
[WebMethod]
protected static string StringReturn()
{
return "StringReturn() success";
}
However, I'm getting error messages saying that StringReturn isn't a valid function.
Any help would be appreciated?
I've added the following lines of code to the page as advised:
<asp:ScriptManager ID="ScriptMgr" runat="server" EnablePageMethods="true"> </asp:ScriptManager>
I've also changed the code to call a javascript function on the Success event, the function being:
function HelloWorlds() {
alert("HelloWorld() method");
message = PageMethods.StringReturn();
message.toString();
alert(message);
}
however that doesn't appear to work. What am I missing?
You need to have a scripmanager on your page and then you can call it like this PageMethods.StringReturn()

Categories

Resources