Knockout asyncCommand / Ajax MVC ActionResults - javascript

I am pretty new to front end development and also the project I’m working on (bug fixes). I am using Knockout/MVC ActionResults.
I have been tasked to alter a form so that it doesn't allow double click submission, I added basic Jquery to disable to button, but have been told it needs to use asyncCommand.
What I have noted about it however is that all examples using this they return a Json result etc. where mine will be an action result.
I was wondering if I need to alter the MVC actionresult or whether there is another way that I’m just not seeing.
I was hoping I could do something like:
HTML
<button class="btn btn-action" data-bind="command: create, activity: create.isExecuting">Create</button>
JS
model.create = ko.asyncCommand({
execute: function (complete) {
$.ajax({
type: 'POST',
url: "/account/create",
data: ko.toJSON(data),
contentType: 'application/json; charset=utf-8',
});
complete();
},
canExecute: function (isExecuting) {
return !isExecuting;
}
});
CONTROLLER
public ActionResult Create(Model model, int versionId)
{
if (success)
{
return Redirect("/accounts");
}
else
{
return View(model);
}
}
Can this actually happen or not?
Thanks,
Clare

The solution for me was to alter the ActionResult to return a value to AJAX.

Related

How to pass the data recieved via AJAX to ASP MVC partial views?

What I'm trying to achieve is to update some part of a page containing partial views. My attempt on doing so is below:
$.ajax({
type: 'GET',
url: actionUrl,
success: function (data) {
$("#results").html("");
$("#results").append(#Html.Partial("_FirstPartial", data.FirstDataSet));
$("#results").append(#Html.Partial("_SecondPartial", data.SecondDataSet));
}
});
Of course I couldn't pass JS variables to ASP MVC methods like that, so how could I? Or probably there is a completely different, better approach for the way I could update the page?
View (Javascript):
$.ajax({
type: 'GET',
url: actionUrl,
success: function (data) {
$("#results").html("");
$.post('#Url.Action ("FirstPartial")',{data:data.FirstDataSet},function(ret){
$("#results").append(ret);
$.post('#Url.Action ("SecondPartial")',{data:data.SecondDataSet},function(ret2){
$("#results").append(ret2);
}
}
}
});
Controller:
public ActionResult FirstPartial(string data)
{
return PartialView("_FirstPartial", data);
}
public ActionResult SecondPartial(string data)
{
return PartialView("_SecondPartial", data);
}
You need to use Partial Actions (that returns a partial view). In javascript, after getting datasets you call another partial action to render datasets.
I nested two ajax calls to render the second view below the first view. If you remove the nesting then the second one may render before the first one.
Make in your controller method which returns partial you want, then in your Index.cshtml file make something like this:
<script>
var Services = {
linkToPartial: '#Url.Action('MethodName', 'Controller')'
}
</script>
This code will provide an action link which you can use in your $ajax success method and provide arguments.
$("#results").html("");
$.ajax({
method: 'GET',
url: Services.linkToPartial,
data: {
argumentName: data.FirstDataSet
}
}).done(function (html) {
$('#results').append(html);
});

Jsonresult is failing with parameter in my Ajax Call. Why is it happening?

That's my script on my view.
$(function () {
$('#buttonx').on("click", function (e) {
e.preventDefault();
$.ajax({
url: 'Ficha/VerificarPatrocinador',
contentType: 'application/json; charset=utf-8',
type: 'GET',
dataType: 'json',
data: {i: 100036},
success: function (data) {
$(data).each(function (index, item) {
//$('#NomePatr').append(item.Nome)
$("#NomePatr").val(item.Nome);
});
}
});
});
});
</script>
That's my action on my controller.
public JsonResult VerificarPatrocinador(int i)
{
var db = new FMDBEntities();
db.Configuration.ProxyCreationEnabled = false;
db.Configuration.LazyLoadingEnabled = false;
var consulta = db.Tabela_Participante.Where(p => p.ID_Participante == i);
return Json(consulta.
Select(x => new
{
Nome = x.Nome
}).ToList(), JsonRequestBehavior.AllowGet);
}
I'm a newbie in Ajax/Jquery, when I exclude the parameter it is ok, however, when I try to put the data: {i: 100036} in my script and the parameter in my action. It doesn't work. Why is it happening?
The controller is going fine. The parameter even passes, but I can't return this result in my View.
Thank you.
use [HttpPost] attribute on your controller method
[HttpPost]
public JsonResult VerificarPatrocinador(int i)
{
//Write Your Code
}
and change the ajax type attribute from "GET" to "POST" and use JSON.stringify. Also check the url carefully. your ajax should look like this
$(function () {
$('#buttonx').on("click", function (e) {
e.preventDefault();
$.ajax({
url: 'Ficha/VerificarPatrocinador',
contentType: 'application/json; charset=utf-8',
type: 'POST',
dataType: 'json',
data: JSON.stringify({i: 100036}),
success: function (data) {
$(data).each(function (index, item) {
//$('#NomePatr').append(item.Nome)
$("#NomePatr").val(item.Nome);
});
}
});
});
});
Hope it will help you
I think that #StephenMuecke may be on to something, because I was able to reproduce the (intended) logic with a new project.
The first thing to determine is where the code is going wrong: the server or the client.
Try using the Visual Studio debugger, and placing a breakpoint in VerificarPatrocinador. Then run the client code to see if the breakpoint is hit. When this succeeds, this means the problem is on the client end.
From there use the web browser's debugger in order to determine what is happening. Use the .fail function on the return result from .ajax in order to determine if there was a failure in the HTTP call. Here is some sample code that you can use to analyze the failure:
.fail(function (jqXHR, textStatus, errorThrown) {
alert(textStatus);
});
For more information check out http://api.jquery.com/jquery.ajax/
Change following code when ajax success
$.each(data, function (index, item) {
$("#NomePatr").val(item.Nome);
});
because when you are getting data as object of array, array or collection you can iterate using this syntax and then you can pass to var,dom...and so on where you want to display or take.
jQuery.each() means $(selector).each() you can use for dom element like below syntax: for example
<ul>
<li>foo</li>
<li>bar</li>
</ul>
<script>
$("li").each(function( index ) {
console.log( index + ": " + $( this ).text() );
});
</script>
Using GET is working fine but if it is not secure because data is visible to user when it submit as query string.
while post have
Key points about data submitted using HttpPost
POST - Submits data to be processed to a specified resource
A Submit button will always initiate an HttpPost request.
Data is submitted in http request body.
Data is not visible in the url.
It is more secured but slower as compared to GET.
It use heap method for passing form variable
It can post unlimited form variables.
It is advisable for sending critical data which should not visible to users
so I hope you understand and change ajax type:'GET' to 'POST' if you want.
$.each() and $(selector).each()
Change this line
url: 'Ficha/VerificarPatrocinador'
to:
url: '/Ficha/VerificarPatrocinador'
Because when you use this url "Ficha/VerificarPatrocinador", it will call the API from url: current url + Ficha/VerificarPatrocinador,so it isn't correct url.

Binding table in MVC 4 after Ajax call

I have an HTML able, which I bind by using the following Action in MVC controller:
public ActionResult BindTable(int ? page)
{
int pageSize = 4;
int pageNumber = 0;
List<Users> _users = query.ToList();
return View(_users.ToPagedList(pageNumber, pageSize));
}
Below the table I have the following HTML:
<textarea class="form-control" style="resize:none;" rows="9" placeholder="Enter value here..." id="txtValue"></textarea>
<br />
<button style="float:right; width:100px;" type="button" onclick="CallFunction()" class="btn btn-primary">Update specific record</button>
The Javascript function responsible for calling the action is as following:
function CallFunction() {
if ($('#txtValue').val() !== '') {
$.ajax({
url: '/User/UpdateUser',
type: 'POST',
data: { txt: $('#txtValue').val() },
success: function (data) {
$('#txtValue').val('');
alert('User updated!');
},
error: function (error) {
alert('Error: ' + error);
}
});
}
And here is the Action responsible for updating the user:
public ActionResult UpdateUser(string txtValue)
{
var obj = db.Odsutnost.Find(Convert.ToInt32(1));
if(obj!=null)
{
obj.Text= txtValue;
obj.Changed = true;
db.SaveChanges();
return RedirectToAction("BindTable");
}
return RedirectToAction("BindTable");
}
Everything works fine. But the table doesn't updates once the changes have been made ( it doesn't binds ?? )...
Can someone help me with this ???
P.S. It binds if I refresh the website.. But I want it to bind without refreshing the website...
I created a BIND function with Javascript, but it still doesn't binds:
function Bind() {
$(document).ready(function () {
var serviceURL = '/User/BindTable';
$.ajax({
type: "GET",
url: serviceURL,
contentType: "application/json; charset=utf-8",
});
});
}
You're not actually updating the page after receiving the AJAX response. This is your success function:
function (data) {
$('#txtValue').val('');
alert('User updated!');
}
So you empty an input and show an alert, but nowhere do you modify the table in any way.
Given that the ActionResult being returned is a redirect, JavaScript is likely to quietly ignore that. If you return data, you can write JavaScript to update the HTML with the new data. Or if you return a partial view (or even a page from which you can select specific content) then you can replace the table with the updated content from the server.
But basically you have to do something to update the content on the page.
In response to your edit:
You create a function:
function Bind() {
//...
}
But you don't call it anywhere. Maybe you mean to call it in the success callback?:
function (data) {
$('#txtValue').val('');
Bind();
alert('User updated!');
}
Additionally, however, that function doesn't actually do anything. For starters, all it does is set a document ready handler:
$(document).ready(function () {
//...
});
But the document is already loaded. That ready event isn't going to fire again. So perhaps you meant to just run the code immediately instead of at that event?:
function Bind() {
var serviceURL = '/User/BindTable';
$.ajax({
type: "GET",
url: serviceURL,
contentType: "application/json; charset=utf-8",
});
}
But even then, you're still back to the original problem... You don't do anything with the response. This AJAX call doesn't even have a success callback, so nothing happens when it finishes. I guess you meant to add one?:
function Bind() {
var serviceURL = '/User/BindTable';
$.ajax({
type: "GET",
url: serviceURL,
contentType: "application/json; charset=utf-8",
success: function (data) {
// do something with the response here
}
});
}
What you do with the response is up to you. For example, if the response is a completely new HTML table then you can replace the existing one with the new one:
$('#someParentElement').html(data);
Though since you're not passing any data or doing anything more than a simple GET request, you might as well simplify the whole thing to just a call to .load(). Something like this:
$('#someParentElement').load('/User/BindTable');
(Basically just use this inside of your first success callback, so you don't need that whole Bind() function at all.)
That encapsulates the entire GET request of the second AJAX call you're making, as well as replaces the target element with the response from that request. (With the added benefit that if the request contains more markup than you want to use in that element, you can add jQuery selectors directly to the call to .load() to filter down to just what you want.)

How to add dynamic javascript alert box in asp.net?

Please help me .I am new to asp.net .How can I write dynamic javascript in asp.net web forms ? What I want to do is as the following code .
The follow code is in button click event of server side ,written in c# . Please help me .
if(Email.send()){
//show javascript alert box
}else{
//show javascript alert box
}
Create a webmethod that you call via AJAX and pop the javascript alert based on the result of that function.
example (in your .aspx page):
function doSomething() {
$.ajax({
type: "POST",
url: "Do_Something.aspx/DoSomething",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
alert(response);
}
});
In Do_Something.aspx.cs:
[WebMethod]
public static string DoSomething()
{
if (Email.Send)
{
return "success";
}
return "not a success";
}
With asp.net, all server side code is going to run before the Web Page is sent to the end user, and then the result of that code is injected into the HTML/Javascript.
Also, when injecting server side code into javascript, you are required to do it within a string literal (quotes).
So, if you have in a javascript click handler:
if ("#Email.Send()") {
// stuff
} else {
// other stuff
}
The Email.Send() command will run, and the results of that command will be placed in the Html. If your Send function returned a boolean, which I am assuming it does, the Html returned to your end user would look like this:
if ("true") {
// stuff
} else {
...
I'm assuming this is not your desired outcome. The correct way to do this, is to trigger another command on your server via AJAX inside your click command, and use the result of that AJAX command for your logic. It would look like this:
function clickHandler() {
$.ajax({
type: "POST",
url: "UrlToYourServerSideAction",
data: {
WebParam1: "value",
WebParam2: "value"
},
success: function (response) {
if (response == "true") {
// code if Web Method returns true
} else {
// code if Web Method returns false
}
}
});
}

Asp.net MVC 2 - Returned Json object not being picked up in javascript?

Update: I've removed the datatype="html" completely and hoping the return value will always get evaluated - but right now nothing happens.
I've also added the code that calls the "openModal" function. It is in the LogOn UserControl contained in the Site.Master. Hope this clears up a few things
It seems like from the Controller is not returning the json object back to the ajax caller, something is lost somewhere - i am never hitting that break point..it skips it entirely
I have a simple modal for logins, so i call the LogOn Action like this:
<div id="logonForm">
<% using (Ajax.BeginForm("LogOn", "Account", new AjaxOptions{UpdateTargetId = "logonForm"})) { %>
//my login form
<% } %>
</div>
And the Action looks like this:
[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
//success login
if (Request.IsAjaxRequest())
return Json(new { Url = Url.Action("Index", "Home") }, JsonRequestBehavior.AllowGet);
else
return RedirectToAction("Index", "Home");
}
At this point it retursthe new Json object with the Url to the User Control (in Site.Master), to the javascript here:
<script type="text/javascript">
function openModel() {
$.ajax({
type: "get",
url: '/Account/LogOn',
contentType: "application/x-www-form-urlencoded;charset=utf-8",
// async: true,
success: function (result) {
debugger;
if (typeof result == 'string') {
$.modal(result, {
closeHTML: "",
containerId: "login-container",
overlayClose: true
});
}
else if (result.Url) {
debugger;
window.location.href = result.Url;
}
}
});
}
</script>
<% if (Request.IsAuthenticated) { %>
Welcome <b><%: Page.User.Identity.Name %></b>!
<%: Html.ActionLink("Log Out", "LogOff", "Account") %>
<% } else { %>
Log In
<% } %>
...but the javacript never catches it..i cannot see whats in the "result", the screen renders an "{Url: /}" - just weird behavior
What am i missing? the debugger; break is triggered when i first click the link, but when i try to submit form, it goes thru the LogOn Controller - tries to return the json object, but never goes back to the javascript
Thanks much
JQuery will not treat the call as returning json, because you have told it the call is returning html. You need to change your dataType to json.
However it isn't clear where you expect openModel to be called from. The code as it is will use the Microsoft AJAX code and insert the returned data into the page, which is why you are seeing your json appear on the page.
You need to overwrite the submit click to call your custom jQuery ajax function. Right now it will use the Microsoft ajax. This is why your ajax function never gets called.
Do something like:
$('form').unbind('submit').submit(function(){
$.ajax({ type:'post', url: '/Account/LogOn', data: $(this).serialize(),
success: function(){
if (result.Url)
window.location.href = result.Url;
}
});
});
dataType: "html", should be be dataType: "json",, and this should solve the problem.
Well jQuery will never trigger the success callback, since you specified dataType: "html",, so it will wait for an text/html response, but you're sending JSON.
You need to use "json" as the dataType.
See: http://api.jquery.com/jQuery.ajax/

Categories