I have a jquery based bespoke lookup control that works well, but I wish to encapsulate it into a neater solution. The below is the code included in the Razor view. Behind the scenes there is also a bespoke jquery function called 'InitLookup' that does the majority of the work at runtime.
<script type="text/javascript">
$(document).ready(function () {
InitLookup('#txtDelegatedToLookup', '#Delegated_To_ID', '#Url.Action("ContactLookup", "marMIS")');
});
</script>
#Html.HiddenFor(m => m.Delegated_To_ID)
<input id="txtDelegatedToLookup" type="text" />
Ideally, I would like to whittle this down to a neater and more re-usable solution, where the javascript InitLookup() is dynamically created and encapsulated within, possibly as below...
#Html.DynamicLookupFor(m => m.Delegated_To_ID, "ContactLookup", "marMIS")
...where "marMIS" is the controller, and "ContactLookup" is a controller method. These being the address to use to get the data during a lookup.
I tried to create an Editor Template called DynamicLookup in the /Views/Shared/EditorTemplates folder, but the wasn't recognised when using #Html.DynamicLookup(...
Any takers on this one? Cheers!
------------ App_Code suggestion below! Addendum to original question! -------------------------
OK, so I have copied my code into a new App_Code folder file called CustomHelpers.cshtml. How do I pass the lambda expression into here and then use it?
#using System.Security.Policy
#using System.Web.Mvc.Html
#helper DynamicLookup(LAMBDAEXPR, CtrlId, Controller, Method) {
#Html.HiddenFor(LAMBDAEXPR)
<input id="txtDelegatedToLookup" type="text" />
#Html.ValidationMessageFor(LAMBDAEXPR)
<script type="text/javascript">
$(document).ready(function () {
InitLookup(txtCtrlId, idCtrlId, '#Url.Action(Controller, Method)');
});
</script>
}
If you want to encapsulate the javascript portion you could create an HtmlHelper that will generate the desired content.
An example of what one would look like is as follows:
public static MvcHtmlString DynamicLookupFor(this HtmlHelper htmlHelper, string txtCtrlId, string idCtrlId, string controllerName, string actionName)
{
// create script tag
var script = new TagBuilder("script");
// generate script content
var result = new StringBuilder();
result.AppendLine("$(document).ready(function () {");
result.Append("InitLookup(");
result.Append("'" + txtCtrlId + "',");
result.Append("'" + idCtrlId + "',");
// generate action link
var url = new UrlHelper(HttpContext.Current.Request.RequestContext);
result.Append("'" + url.Action(actionName, controllerName));
result.AppendLine("'});");
script.InnerHtml = result.ToString();
return MvcHtmlString.Create(script.ToString());
}
Within your view you can call the helper as follows:
#Html.DynamicLookupFor("#txtDelegatedToLookup", "#Delegated_To_ID", "ContactLookup", "marMIS")
Don't forget to register the helper within the Views folder web.config:
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="Names Space Of Helper"/>
</namespaces>
OK, here's what I ended up doing in the end. It works very very well indeed! It will need a little polish in the future, and it leaves the door open to extend this a little too. For example, the control validates, but it doesn't color itself as per the rest of my validation, rather it just shows the textual validation message.
The functionality is called as such...
#Html.CustomLookupFor(m => m.Task_History.Delegated_To_ID, "txtDelegatedToLookup", #Url.Action("ContactLookup", "marMIS"), new { width = "250px" })
...and requires a using statement at the top of the razor view page...
#using Custom.MVC.Helpers;
BTW, two things...
jquery 1.7.2+ and jquery ui 1.8.16+ is what was used whilst I was developing this!
Also, the functionality in the first code section below includes both a minified version of the
javascript functionality within the code, and also a commented section containing the original
javascript code formatted nicely.
There are then two peices of code in the background. The first one here is the re-usable code that I was seeking to develop with regards to my initial question. The second one below it is the controller method on the server.
using System;
using System.Linq.Expressions;
using System.Text;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Web.Routing;
namespace Custom.MVC.Helpers
{
public static class CustomHtmlHelperExtensions
{
public static MvcHtmlString CustomLookupFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> exp, string id, string url, object options)
{
var hidCtrlId = id + "_id";
//Options
var opt = new RouteValueDictionary(options);
var textBoxWidth = (opt["width"] != null) ? opt["width"].ToString() : "";
var textBoxVisibility = (opt["visibility"] != null) ? opt["visibility"].ToString() : "";
//Construct the script fired when the document is fully loaded
var sbScript = new StringBuilder();
sbScript.Append("<script type='text/javascript'>");
sbScript.Append(" function InitDynamicLookupFor(e,f){var g='#'+e;var h='#'+e+'_id';$(g).click(function(){$(g).val('');$(h).val('');$(h).trigger('change')});$(g).autocomplete({minLength:3,delay:100,autoFocus:true,autofill:true,mustMatch:true,matchContains:true,width:220,source:function(c,d){$.ajax({url:f,type:'POST',dataType:'json',data:{searchId:0,searchTerm:c.term,searchLimit:10},success:function(b){d($.map(b,function(a){return{id:a.id,value:a.value}}))}})},create:function(b,c){if($(h).val()!=''){$.ajax({url:f,type:'POST',dataType:'json',data:{searchId:$(h).val(),searchTerm:'',searchLimit:1},success:function(a){$(g).val(a[0].value);$(g).removeClass('DynamicLookupForNotSelected');$(g).addClass('DynamicLookupForSelected')}})}},select:function(a,b){$(h).val(b.item.id);$(g).val(b.item.value);$(g).removeClass('DynamicLookupForNotSelected');$(g).addClass('DynamicLookupForSelected');$(h).trigger('change');return false},open:function(a,b){$(h).val(null);$(g).removeClass('DynamicLookupForSelected');$(g).addClass('DynamicLookupForNotSelected')}});if($(h).val()==''){$(g).val('Type here to search!');$(g).removeClass('DynamicLookupForSelected');$(g).addClass('DynamicLookupForNotSelected')}}");
sbScript.Append(" ");
sbScript.Append(" $(document).ready(function () {");
sbScript.Append(" InitDynamicLookupFor('" + id + "', '" + url + "');");
sbScript.Append(" });");
sbScript.Append("</script>");
//Construct the HTML controls for the DynamicLookup and its validation
var sbCtrls = new StringBuilder();
sbCtrls.Append(html.HiddenFor(exp, new { id=hidCtrlId }));
sbCtrls.Append("<input id='" + id + "' type='text' style='width:" + textBoxWidth + "; visibility:" + textBoxVisibility + ";' />");
sbCtrls.Append(html.ValidationMessageFor(exp));
//Return the lot back to the interface
var retString = sbScript.ToString() + sbCtrls.ToString();
return new MvcHtmlString(retString);
}
}
}
//*** This is the original javascript code before it is minified for use above! DON'T DELETE! ***
//
// function InitDynamicLookupFor(textBox, url) {
// var $textBox = '#' + textBox;
// var $hiddenId = '#' + textBox + '_id';
// $($textBox).click(function () {
// $($textBox).val('');
// $($hiddenId).val('');
// $($hiddenId).trigger('change');
// });
// $($textBox).autocomplete({
// minLength: 3,
// delay: 100,
// autoFocus: true,
// autofill: true,
// mustMatch: true,
// matchContains: true,
// width: 220,
// source: function (request, response) {
// $.ajax({
// url: url, type: 'POST', dataType: 'json',
// data: { searchId: 0, searchTerm: request.term, searchLimit: 10 },
// success: function (data) {
// response($.map(data, function (item) {
// return {
// id: item.id,
// value: item.value
// };
// }));
// }
// });
// },
// create: function (event, ui) {
// if ($($hiddenId).val() != '') {
// $.ajax({
// url: url, type: 'POST', dataType: 'json',
// data: { searchId: $($hiddenId).val(), searchTerm: '', searchLimit: 1 },
// success: function (data) {
// $($textBox).val(data[0].value);
// $($textBox).removeClass('DynamicLookupForNotSelected');
// $($textBox).addClass('DynamicLookupForSelected');
// }
// });
// }
// },
// select: function (event, ui) {
// $($hiddenId).val(ui.item.id);
// $($textBox).val(ui.item.value);
// $($textBox).removeClass('DynamicLookupForNotSelected');
// $($textBox).addClass('DynamicLookupForSelected');
// $($hiddenId).trigger('change');
// return false;
// },
// open: function (event, ui) {
// $($hiddenId).val(null);
// $($textBox).removeClass('DynamicLookupForSelected');
// $($textBox).addClass('DynamicLookupForNotSelected');
// }
// });
// //If no value selected by now, indicate to the user how to use the control
// if ($($hiddenId).val() == '') {
// $($textBox).val('Type here to search!');
// $($textBox).removeClass('DynamicLookupForSelected');
// $($textBox).addClass('DynamicLookupForNotSelected');
// }
//}
The controller method on the server...
public JsonResult ContactLookup(int searchId, string searchTerm, int searchLimit)
{
//Prepare search filter from criteria entered
var p = PredicateBuilder.True<vw_Contact_Verbose>();
if (searchId != 0) p = p.And(x => x.Contact_ID == searchId);
if (searchTerm != "") p = p.And(x => x.Fullname.Contains(searchTerm));
//Grab data
var results =
(from x in _mDb.ent.vw_Contact_Verbose.AsExpandable().Where(p).OrderBy("Fullname Desc").Take(searchLimit)
select new { id = x.Contact_ID, value = x.Fullname + " (" + x.Company + ")" }).ToArray();
return Json(results, JsonRequestBehavior.AllowGet);
}
I do hope that this re-useable code is found to be as useful to anybody else as it is to me. It's certainly made my code less verbose in razor views.
Related
I have a simple page with an input text-box. The text box is bound to jquery ui autocomplete that makes an AJAX call to the server. My server side code is an ASP.NET MVC site. The only difference I have as compared to most examples found over the Internet is that my Server side code returns a PartialView (html code) as results instead of JSON. I see the AJAX call happening and I see the HTML response in the AJAX success event as well.
My question is how do I bind this HTML data to show in the AutoComplete?
The code I have so far is:
$("#quick_search_text").autocomplete({
minLength: 3,
html: true,
autoFocus: true,
source: function (request, response) {
$.ajax({
type: "POST",
url: "serversideurl",
data: "{ 'SearchTerm': '" + request.term + "', 'SearchCategory': '" + $("#quick_search_category").val() + "' }",
contentType: "application/json; charset=utf-8",
dataType: "html",
error: function (jqXHR, textStatus, errorThrown) {
console.log(jqXHR);
},
success: function (data) {
//THIS IS WHERE MY HTML IS RETURNED FROM SERVER SIDE
//HOW DO I BIND THIS TO JQUERY UI AUTOCOMPLETE
}
});
},
select: function (event, ui) {
},
response: function (event, ui) {
console.log(ui);
console.log(event);
}
});
This works:
1) Create an action in your controller and set the RouteConfig to start this action
public class HomeController : Controller
{
public ActionResult Index20()
{
MyViewModel m = new MyViewModel();
return View(m);
}
Create a view without any type of master page
Add this view model:
public class MyViewModel
{
public string SourceCaseNumber { get; set; }
}
Go to Manage Nuget Packages or PM Console and add to MVC 5 project - Typeahead.js for MVC 5 Models by Tim Wilson
Change the namespace for the added HtmlHelpers.cs to System.Web.Mvc.Html and rebuild
Add this class:
public class CasesNorm
{
public string SCN { get; set; }
}
Add these methods to your controller:
private List<Autocomplete> _AutocompleteSourceCaseNumber(string query)
{
List<Autocomplete> sourceCaseNumbers = new List<Autocomplete>();
try
{
//You will goto your Database for CasesNorm, but if will doit shorthand here
//var results = db.CasesNorms.Where(p => p.SourceCaseNumber.Contains(query)).
// GroupBy(item => new { SCN = item.SourceCaseNumber }).
// Select(group => new { SCN = group.Key.SCN }).
// OrderBy(item => item.SCN).
// Take(10).ToList(); //take 10 is important
CasesNorm c1 = new CasesNorm { SCN = "11111111"};
CasesNorm c2 = new CasesNorm { SCN = "22222222"};
IList<CasesNorm> aList = new List<CasesNorm>();
aList.Add(c1);
aList.Add(c2);
var results = aList;
foreach (var r in results)
{
// create objects
Autocomplete sourceCaseNumber = new Autocomplete();
sourceCaseNumber.Name = string.Format("{0}", r.SCN);
sourceCaseNumber.Id = Int32.Parse(r.SCN);
sourceCaseNumbers.Add(sourceCaseNumber);
}
}
catch (EntityCommandExecutionException eceex)
{
if (eceex.InnerException != null)
{
throw eceex.InnerException;
}
throw;
}
catch
{
throw;
}
return sourceCaseNumbers;
}
public ActionResult AutocompleteSourceCaseNumber(string query)
{
return Json(_AutocompleteSourceCaseNumber(query), JsonRequestBehavior.AllowGet);
}
credit goes to http://timdwilson.github.io/typeahead-mvc-model/
I have a form with a dropdownlist. When selecting an option, I make an ajax call to dynamically add a list of links in the view. When I click on one of the links, I want to update the existing page with a partial view returned by the PostListSubCategory() method.
Currently, clicking on one of the links does a redirect and shows the partial view in a new page. How can I update the the existing page?
<script language="javascript" type="text/javascript">
function GetSubCategory(_categoryId) {
var procemessage = "<a='0'> Please wait...</a>";
$("#SubCategoryID").html(procemessage).show();
var url = "/Posts/GetSubCategoryById/";
$.ajax({
url: url,
data: { categoryid: _categoryId },
cache: false,
type: "POST",
success: function (data) {
var markup = "";
for (var x = 0; x < data.length; x++) {
var num = data[x].Text;
markup += "<a href='/posts/postlistsubcategory?subcategoryid=" + data[x].Text + "'>" + data[x].Text + "</a><br />";
// markup += "<a href=" + Url.Action("postlistsubcategory", new { subcategoryid = num });
}
$("#SubCategoryID").html(markup).show();
},
error: function (reponse) {
alert("error : " + reponse);
}
});
$.ajax({
url: "/Posts/PostListCategory",
data: { categoryid: _categoryId },
cache: false,
type: "POST",
success: function (data) {
$("#postList").html(data).show();
},
error: function (reponse) {
alert("error : " + reponse);
}
});
}
</script>
#using (Html.BeginForm())
{
#Html.ListBoxFor(m => m.CategoryModel, new SelectList(Model.CategoryModel, "CategoryId", "Name"), new { #id = "ddlcategory", #style = "width:200px;", #onchange = "javascript:GetSubCategory(this.value);" })
<br />
<br />
<div id="SubCategoryID" name="SubCategoryID" style="width: 200px"></div>
<br /><br />
}
In the controller
public PartialViewResult PostListSubCategory(string subcategoryid)
{
if (subcategoryid == null)
{
return PartialView(db.Posts.ToList());
}
return PartialView("PostList", db.Posts.Include(i => i.SubCategory).Where(p => p.SubCategory.Name == subcategoryid));
}
You currently dyamically generating links with an href attribute so clicking on them will do a redirect. You need to handle the click event of those links using event delegation and then use ajax to update the existing DOM. There a some other bad practices in your code and I suggest you use the following
#using (Html.BeginForm())
{
// no need to override the id attribute and use Unobtrusive Javascript (don't pollute markup with behavior)
#Html.ListBoxFor(m => m.CategoryModel, new SelectList(Model.CategoryModel,"CategoryId", "Name"))
}
<div id="SubCategoryID"></div> // no point adding a name attribute
<div id="postList"></div>
var subcategories = $('#SubCategoryID');
$('#CategoryModel').change(function() {
var url = '#Url.Action("GetSubCategoryById", "Posts")'; // don't hard code url's
var category = $(this).val();
subcategories.empty(); // clear any existing links
$.post(url, { categoryid: category }, function(data) { // this could be a GET?
$.each(data, function(index, item) {
subcategories.append($('<a></a>').text(item).attr('href','#').addClass('subcategory')); // see note below
});
});
});
Note: Since your ajax only needs one property to generate the links (the value to display in the link), then your GetSubCategoryById() should be returning IEnumerable<string> not a collection of complex objects (you current code suggest your returning other data which you never use). If you do need to return a collection of objects, then change the above to use .text(item.Text). The above code will generate
.....
for each item you return. Then add an additional script to handle the .click() event of the links (since the links are dynamically added, you need event delegation using the .on() method)
var posts = $('#postList');
$('#SubCategoryID').on('click', '.subcategory', function() {
var url = '#Url.Action("postlistsubcategory", "posts")';
var subcategory = $(this).text();
posts.load(url, { subcategoryid: subcategory });
});
I've just introduced SSL to my MVC website. I made the whole default AccountContorller use it. It works fine unless I'm currently on http page and try to log on with ajax (the logon action is vredirected to httpS). This popup logon window doesn't even show up.
For the controller a used a custom attribute:
public class RequireSSL : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext.ActionDescriptor.IsDefined(typeof(NoSSL), true) ||
filterContext.ActionDescriptor.IsDefined(typeof(OptionalSSL), true))
{
base.OnActionExecuting(filterContext);
return;
}
HttpRequestBase req = filterContext.HttpContext.Request;
HttpResponseBase res = filterContext.HttpContext.Response;
//Check if we're secure or not and if we're on the local box
if (!req.IsSecureConnection && (!req.IsLocal || Properties.Settings.Default.UseSSLForLocalRequests))
{
var builder = new UriBuilder(req.Url)
{
Scheme = Uri.UriSchemeHttps,
Port = Properties.Settings.Default.HttpsPort,
};
res.Redirect(builder.Uri.ToString());
}
base.OnActionExecuting(filterContext);
}
}
How can I make it work?
EDIT
The whole rest was generated by MVC. (Project with built in authentications)
That's the link.
#Html.ActionLink(#Labels.LogOn, "LogOn", "Account", routeValues: null, htmlAttributes: new { id = "logonLink", data_dialog_title = "Identification" })
JS somehow hooks into that link and performs ajax logon . Probably with this code: (JajaxLogin.js - also out of the box)
/// <reference path="jquery-1.6.2.js" />
/// <reference path="jquery.validate.js" />
$(function () {
// Cache for dialogs
var dialogs = {};
var getValidationSummaryErrors = function ($form) {
// We verify if we created it beforehand
var errorSummary = $form.data('validation-summary-errors');
if (!errorSummary) {
errorSummary = $('<div class="validation-summary-errors"><span>Please correct the errors and try again.</span><ul></ul></div>')
.insertBefore($form);
// Remember that we created it
$form.data('validation-summary-errors', errorSummary);
}
return errorSummary;
};
var formSubmitHandler = function (e) {
var $form = $(this);
// We check if jQuery.validator exists on the form
if (!$form.valid || $form.valid()) {
$.post($form.attr('action'), $form.serializeArray())
.done(function (json) {
json = json || {};
// In case of success, we redirect to the provided URL or the same page.
if (json.success) {
location = json.redirect || location.href;
} else if (json.errors) {
var errorSummary = getValidationSummaryErrors($form);
var items = $.map(json.errors, function (error) {
return '<li>' + error + '</li>';
}).join('');
var ul = errorSummary
.find('ul')
.empty()
.append(items);
}
});
}
// Prevent the normal behavior since we opened the dialog
e.preventDefault();
};
var loadAndShowDialog = function (id, link, url) {
var separator = url.indexOf('?') >= 0 ? '&' : '?';
// Save an empty jQuery in our cache for now.
dialogs[id] = $();
// Load the dialog with the content=1 QueryString in order to get a PartialView
$.get(url + separator + 'content=1')
.done(function (content) {
dialogs[id] = $('<div class="modal-popup">' + content + '</div>')
.hide() // Hide the dialog for now so we prevent flicker
.appendTo(document.body)
.filter('div') // Filter for the div tag only, script tags could surface
.dialog({ // Create the jQuery UI dialog
title: link.data('dialog-title'),
modal: true,
resizable: true,
draggable: true,
width: link.data('dialog-width') || 300
})
.find('form') // Attach logic on forms
.submit(formSubmitHandler)
.end();
});
};
// List of link ids to have an ajax dialog
var links = ['logonLink', 'registerLink'];
$.each(links, function (i, id) {
$('#' + id).click(function (e) {
var link = $(this),
url = link.attr('href');
if (!dialogs[id]) {
loadAndShowDialog(id, link, url);
} else {
dialogs[id].dialog('open');
}
// Prevent the normal behavior since we use a dialog
e.preventDefault();
});
});
});
i have the following ajax.actionlink which calls a Delete action method for deleting an object:-
#if (!item.IsAlreadyAssigned(item.LabTestID))
{
string i = "Are You sure You want to delete (" + #item.Description.ToString() + ") ?";
#Ajax.ActionLink("Delete",
"Delete", "LabTest",
new { id = item.LabTestID },
new AjaxOptions
{ Confirm = i,
HttpMethod = "Post",
OnSuccess = "deletionconfirmation",
OnFailure = "deletionerror"
})
}
but is there a way to include #Html.AntiForgeryToken() with the Ajax.actionlink deletion call to make sure that no attacker can send a false deletion request?
BR
You need to use the Html.AntiForgeryToken helper which sets a cookie and emits a hidden field with the same value. When sending the AJAX request you need to add this value to the POST data as well.
So I would use a normal link instead of an Ajax link:
#Html.ActionLink(
"Delete",
"Delete",
"LabTest",
new {
id = item.LabTestID
},
new {
#class = "delete",
data_confirm = "Are You sure You want to delete (" + item.Description.ToString() + ") ?"
}
)
and then put the hidden field somewhere in the DOM (for example before the closing body tag):
#Html.AntiForgeryToken()
and finally unobtrusively AJAXify the delete anchor:
$(function () {
$('.delete').click(function () {
if (!confirm($(this).data('confirm'))) {
return false;
}
var token = $(':input:hidden[name*="RequestVerificationToken"]');
var data = { };
data[token.attr('name')] = token.val();
$.ajax({
url: this.href,
type: 'POST',
data: data,
success: function (result) {
},
error: function () {
}
});
return false;
});
});
Now you could decorate your Delete action with the ValidateAntiForgeryToken attribute:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Delete(int id)
{
...
}
Modifying the answer by Bronx:
$.ajaxPrefilter(function (options, localOptions, jqXHR) {
var token, tokenQuery;
if (options.type.toLowerCase() !== 'get') {
token = GetAntiForgeryToken();
if (options.data.indexOf(token.name)===-1) {
tokenQuery = token.name + '=' + token.value;
options.data = options.data ? (options.data + '&' + tokenQuery)
: tokenQuery;
}
}
});
combined with this answer by Jon White
function GetAntiForgeryToken() {
var tokenField = $("input[type='hidden'][name$='RequestVerificationToken']");
if (tokenField.length == 0) { return null;
} else {
return {
name: tokenField[0].name,
value: tokenField[0].value
};
}
Edit
sorry - realised I am re-inventing the wheel here SO asp-net-mvc-antiforgerytoken-over-ajax/16495855#16495855
How do i update textbox using MVC Ajax UpdateTargetId option.?
I am new to MVC Ajax applications. Please any one help me out.
Thanks,
Pon Kumar Pandian .T
you can achieve that simple concept using
1- Post\Get
2- Ajax
Note: just replace the $("#myform").html() with $("#mytext").text = "data"
1- Using Get\Post
/////// Controller post and get simple text value
[HttpPost]
public string Contact(string message)
{
return "<h1>Hi,</h1>we got your message, <br />" + message + " <br />Thanks a lot";
}
//// in the view add reference to the Javascript (jQuery) files
#section Scripts{
<script src="~/Scripts/modernizr-2.6.2.js"></script>
<script src="~/Scripts/jquery-1.8.2.intellisense.js"></script>
<script src="~/Scripts/jquery-1.8.2.js"></script>
<script src="~/Scripts/jquery-1.8.2.min.js"></script>
}
/// then add the Post method as following:
<script type="text/javascript">
/// post and get text value
$("#send").on("click", function () {
$.post('', { message: $('#msg').val() })
//// empty post('') means post to the default controller,
///we are not pacifying different action or controller
/// however we can define a url as following:
/// var url = "#(Url.Action("GetDataAction", "GetDataController"))"
.done(function (response) {
$("#myform").html(response);
})
.error(function () { alert('Error') })
.success(function () { alert('OK') })
return false;
});
</script>
2-Also you can use Get only as following:
/////Controller = Home
//// Action = FullName
///// get only simple text message
[HttpGet]
public string FullName()
{
return "full Name: Mahmoud Sayed";
}
/// in the view:
$("#getfullname").on("click", function () {
var url = "#(Url.Action("FullName", "Home"))"
$.get(url, { })
.done(function (response) {
$("#myform").html(response)
})
.error(function () { alert('Error') })
.success(function () { alert('OK') })
return false;
});
</script>
3- Now let's say you want to do it using $.Ajax and JSON:
// Post JSON data add using System.Net;
[HttpPost]
public JsonResult JsonFullName(string fname, string lastname)
{
var data = "{ \"fname\" : \"" + fname + " \" , \"lastname\" : \"" + lastname + "\" }";
//// you have to add the JsonRequestBehavior.AllowGet
//// otherwise it will throw an exception on run-time.
return Json(data, JsonRequestBehavior.AllowGet);
}
Then, inside your view: add the event click on a an input of type button, or even a from submit:
Just make sure your JSON data is well formatted.
$("#jsonGetfullname").on("click", function () {
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "#(Url.Action("JsonFullName", "Home"))",
data: "{ \"fname\" : \"Mahmoud\" , \"lastname\" : \"Sayed\" }",
dataType: "json",
success: function (data) {
var res = $.parseJSON(data);
$("#myform").html("<h3>Json data: <h3>" + res.fname + ", " + res.lastname)
},
error: function (xhr, err) {
alert("readyState: " + xhr.readyState + "\nstatus: " + xhr.status);
alert("responseText: " + xhr.responseText);
}
})
});
</script>
cheers,
Mahmoud Sayed
You can simply wrap all you want to update in some div with id same that you're putting in UpdateTargetId property, and return new content(new textbox with new value). And also don't forget to set Ajax updating type to replace(not append).
We can't give the textbox control id directly in UpdateTargetId property. Bur we can do work around to achieve this. Please fine the blow mention code for the same.
//This the call back method once the ajax request has been successes.
function fnOnSuccess(context) {
alert(context); //this context having all the current ajax req & res information.
var response = context.get_data(); //Using this get_data() method we can get the response from server.
$('#txtajaxResponse')[0].value = response;
}
<!-- Code in .aspx page -->
<%=Ajax.ActionLink("TextBox in UpdateTargetId","GetInfo","Ajax",new AjaxOptions{OnSuccess = "fnOnSuccess"}) %>
<%=Html.TextBox("txtajaxResponse")%>
Thanks,
Pon Kumar Pandian .T