I am trying to implement an autocomplete in ASP.NET MVC 3, following this post
but I really can't get it to work. I have looked at a series of other posts and blogs, but no success so far.
I have a DB table which contains regions (in Japanese), like so:
1 ハイチ; 2 ドミニカ共和国; 3 南アフリカ
basically a [key, Name] pair.
In my repository I am doing the following call:
public IQueryable<Region> GetAllRegions()
{
return db.Regions;
}
Getting the raw data, which I pass to the controller, pair down the data according to input and the concatenate to a string like so:
public class RegionsController : Controller
{
Region_Repository rr = new Region_Repository();
public string FindRegions(string q)
{
List<string> regions = rr.GetAllRegions().Select(r => r.Name).Where(s => s.StartsWith(q)).ToList();
return string.Join("\n", regions);
}
}
The controller when accessed via server/Regions/FindRegions/?q=ハ return a page with the single entry "ハイチ" as expected.
On the page I have a textbox with id "#NewRegion" and the script
<script type="text/javascript">
$(document).ready(function () {
$("#NewRegion").autocomplete('#Url.Action("FindRegions", "Regions")');
})
</script>
which I placed underneath the textbox.
I have references to JQuery and JQueryUI from Google API which work since I am executing other JQuery and using the JQueryUI datepicker successfully on this page.
I tried placing the script in a separate file and hardcoding the url as '/Regions/FindRegions', but no change. I had a look in firebug (second day only, so not very proficient at using it yet) and the script doesn't seem to get executed.
The controller is called fine when accessed via URL, but anything I enter into the textbox does not get passed to the controller...
Can anybody see anything wrong with this?
According to the dark depths of the jQuery UI documentation, the parameter used when passing the autocomplete string to the server is called term, not q.
Update: And also, initialize with autocomplete({source: "#(...url...)"}).
Update 2: And also, return the type of data the Autocomplete widget expects, a JSON array of strings or a JSON array of objects.
I got it working in the following way. I changed the controller to return Json data like this:
public ActionResult FindRegions(string term)
{
var regionNames = rr.GetAllRegions().Select(r => r.Name).Where(s => s.Contains(term)).ToList();
return Json(regionNames, JsonRequestBehavior.AllowGet);
}
note: the AllowGet is there so I could check the result via url, so for debug only.
And the autocomplete script became:
$(function () {
$('#NewRegion').autocomplete({ source: '/Regions/FindRegions' } );
});
Now it works, but I am still not sure why.
Related
I am working on a project built in ASP.Net MVC 3.
In the index page I have displayed the data and allow the user to do inline editing using jeditable (which also uses ajax function) and delete function.
In the create page, obviously it allows the user to enter new the data but now I need to add a feature to allow the delete from the create page itself if the data already exists on the database.
Shows confirmation box if the data already exists (in my case if Extension is not available) on Extension's textbox blur.
I was using the ajax function for this feature but was not working, after spending hours on it, I was able to figure out the what was causing the problem.
The ajax function was working only on the Index page, not the other page. I renamed the Create page as Index and the original Index to something else, well it worked this time but ajax stopped working on the original Index page which was renamed to something else.
In the url if I load the index page as "http://localhost:1234/Controller/Index", the page loads fine but ajax functions do not work.
In a simple way:
Ajax functions works on
localhost:1234/Controller
Ajax functions do not work on
localhost:1234/Controller/Create
localhost:1234/Controller/ViewPage1
localhost:1234/Controller/Index
If someone could explain why its behaving like this, it would be great to have solution for this and whats the alternative solution for this if it can be fixed.
Thanks
Javascript code
$('#Extension').blur(function () {
$.post("CheckPeople/checkDelete",
{
Extension: this.value
},
function (data) {
alert(data);
});
});
Controller: VB Code
//GET: /People/
Function Index() As ViewResult
ViewBag.CurrentPage = "People"
Return View(db.Peoples.ToList())
End Function
//GET: /People/Create
Function Create() As ViewResult
Return View()
End Function
//POST: /People/Create
<HttpPost()>
Function Create(ByVal people As People) As ActionResult
If ModelState.IsValid Then
db.Peoples.Add(people)
db.SaveChanges()
Return RedirectToAction("Index")
End If
Return View(people)
End Function
Public Function checkDelete(ByVal Extension As String) As JsonResult
Dim result As String = "I got you "
Return Json(result, JsonRequestBehavior.AllowGet)
End Function
Thanks for the comments, I added the code, its straight forward.
If I rename the Create.vbhtml to Index.vbhtml and commented the original Index routing and rename both post and get Create routing to Index, ajax works fine.
I think its a relative url issue.
try adding a / in front of the ajax request url, like
$.post("/CheckPeople/checkDelete",
{
Extension: this.value
},
function (data) {
alert(data);
});
});
hope this helps.
I'm using Fancybox 1.3.4 with ASP.NET MVC 3.
I have following link :
<a id="various" href="Like/List/#feed.Id" class="petlikeCount liked">#feed.LikeCount</a>
and also jquery :
<script type="text/javascript">
$(document).ready(function () {
$("#various").fancybox({
type: 'ajax'
});
});
</script>
Controller action in Like controller :
public JsonResult List(int id)
{
return Json("success", JsonRequestBehavior.AllowGet);
}
My problem is that Like/List is never called (checked with the breakpoint) and fancybox just appears and show content of "parent" page....
I also tried with iframe content returning pure html back, but I'm getting same strange behavior as above.
Thank you in advance!
I'd recommend you using HTML helpers instead of hardcoding anchors:
#Html.ActionLink(
feed.LikeCount,
"List",
"Like",
new { id = feed.Id },
new { id = "various", #class = "petlikeCount liked" }
)
Another thing that you should make sure is that the feed.Id is actually an integer variable so that when the List action is invoked it is correctly passed this id.
So your url should look something like this: /List/Like/123. And then assuming tat you have kept the default route and haven't messed up with some custom routes, the List action should be called and passed the correct id as argument.
Also I would very strongly recommend you using a javascript debugging tool in your browser such as FireBug in which you will be able to see any potential errors with your scripts as well as the actual AJAX requests being sent which will allow you to more easily debug such problems.
I have defined an action on my controller which accepts an integer and returns a string value:
public string SqlQuery(int listItemId)
{
return _sqlListSharePointList.GetSqlQueryFromCache(listItemId);
}
How could I call this action from my view? also what other options do I have apart from AJAX?
I tried the below but didn't work:
$.get('/SqlReportList/SqlQuery', 1, function (data) {
alert(data);
});
the "SqlReportList" is the name of my controller.
I also tried the below code:
$.get('/SqlReportList/SqlQuery/1', function (data) {
alert(data);
});
But it threw an exception on production that the listItemId is null.
Should I decorate my Action differently?
I also tried accessing it via fully qualified name but same error:
http://localhost:4574/SqlReportList/SqlQuery/1
Thanks,
If you do not want to use ajax (which is recommended) then only way to call the method is thru page refresh, only that way you are hitting your server side (controller) again from the view.
$.get('/SqlReportList/SqlQuery', { "listItemId": listItemId }, function (data) {
$('#tbSqlQuery').text(data); }
);
Is the parameter known at the time of rendering the surrounding page?
If so (and I've understood your question correctly) then you can use Html.RenderAction. See http://haacked.com/archive/2009/11/17/aspnetmvc2-render-action.aspx
If not, then you can only really use AJAX or a full page reload. For getting the URL right for AJAX, you should be able to use Url.Action with some placeholder value.
The T4MVC project offers strongly-typed support for various things including action URLs, even supporting explicit placeholders for Javascript code. See section 2.2.2 of http://t4mvc.codeplex.com/documentation
I am trying to load json data from web2py controller to jQuery dataTable via AJAX.
But only blank dataTable is rendered (with desired formatting, search box, etc.)
Can somebody pl. point out into my code as to where I have a mistake.
Data is not displayed (as returned by "get_data" method).
I have made sure that the database tables have been populated.
Controller
def show_data():
return dict()
def get_data():
custdata = db.executesql(qry, as_dict=True)
return custdata
For testing purpose, I returned response.json(custdata) in a separate method & validated the same on "jsonlint.com".
It is valid json.
View (show_data.html)
{{extend 'layout.html'}}
$(document).ready(function() {
var oTable = $('.smarttable').dataTable( {
"sScrollY": "200px",
"sAjaxSource": "{{=URL('MIS','get_data.json')}}",
"sDom": "frtiS",
"bDeferRender": true
} );
} );
Lastly, html table tags are defined for a table with class="smarttable"
Your get_data function should return a dictionary, like this:
def get_data():
custdata = db.executesql(qry, as_dict=True)
return dict(data=custdata)
In web2py, a view is only called if the controller action returns a dictionary -- otherwise, the controller output is simply returned to the client as is (and as is, custdata has not yet been converted to JSON).
When you call the URL /MIS/get_data.json, the .json extension tells web2py to look for a /views/MIS/get_data.json view file to use for rendering the JSON. If it doesn't find that view file, it will trying using /views/generic.json, though it will only use generic.json for local requests, unless you override that by specifying response.generic_patterns=['json'].
As an alternative to using a view to render the JSON, you could also do:
def get_data():
custdata = db.executesql(qry, as_dict=True)
return response.json(custdata)
EDIT: The jQuery DataTables plugin requires the JSON to include some special parameters, so you'll have to add those before returning the JSON. To make things easier, you might consider using PowerTable (a web2py plugin for DataTables), or the jqGrid widget included with web2py's plugin_wiki (the widget can be used on any web page, not just wiki pages).
you have to have the "key" values in the "dictionary" that you give for return .
iTotalRecords,iTotalDisplayRecords,sEcho and aaData. you can find the explanations in http://datatables.net/usage/server-side
I am having trouble with my form validation. I have a form class with the Required attribute on it and I have ClientValidationEnabled to true in my web.config. I also have this call on my page #{Html.EnableClientValidation();}
I am using ajax form with the before submit option to catch the validation. Here is what I have:
$(document).ready(function () {
var options = {
beforeSubmit: ensureValid
};
$('#applyForm').ajaxForm(options);
});
function ensureValid(formData, jqForm, options) {
var result = $('#applyForm').validate();
console.log(result.valid());
return result.valid();
}
The code hits the ensureValid function but keeps continuing to the action in the controller even when I know a property should fire.
Thank you for any insight,
Brenna
If you are using asp.net-mvc-3, I would recommend at looking at using jquery.validate to perform your validation. It's far easier to setup, and generates cleaner code. You can see how to set this up in my blog post (I also cover a possible problem you could run into).