.Ajax with jQuery and MVC2 - asp.net-mvc

Im trying to create an ajax (post) event that will populate a table in a div on button click.
I have a list of groups, when you click on a group, I would like the table to "disappear" and the members that belong to that group to "appear".
My problem comes up when using jQuery's .ajax...
When I click on the button, it is looking for a controller that doesnt exist, and a controller that is NOT referenced. I am, however, using AREAS (MVC2), and the area is named Member_Select where the controller is named MemberSelect. When I click on the button, I get a 404 stating it cannot find the controller Member_Select. I have examined the link button and it is set to Member_Select when clicked on, but here's the ajax call:
$.ajax({
type: "POST",
url: '/MemberSelect/GetMembersFromGroup',
success: function(html) { $("#groupResults").html(html); }
});
I havent been able to find any examples/help online.
Any thoughts/suggestions/hints would be greatly appreciated.
Thanks!

Have you tried navigating to /MemberSelect/GetMembersFromGroup to see what you get? - if it's 404'ing it's because the route can't be matched to a controller/ action.
I've not used the new areas functionality, but I'm not sure that the URL you've got is correct...I would have thought it would have been /AREANAME/MemberSelect/GetMembersFromGroup...but I could be wrong..!

When I did this, it worked fine. I didn't use POST and I don't know what AREAS means.
$("#item").autocomplete({
source: function(req, responseFn) {
addMessage("search on: '" + req.term + "'<br/>", true);
$.ajax({
url : ajaxUrlBase1 + "GetMatchedCities/" + req.term,
cache : false,
type : "GET", // http method
success : function(msg){
// ajax call has returned
var result = msg;
var a = [];
if (result !== null){
for(var i=0; i < result.length; i++) {
a.push({label: result[i].prop1, id: result[i].prop2});
}
}
responseFn(a);
}
});
}
});

Use:
area_name/controller_name/action_name
Instead of doing $.ajax I would use jQuery Form Plugin.
and have my form set as:
Html.BeginForm("Index","AdminArea/Admin",FormMethod.Post,
new { id="form-user", name="form-user"})
To use jQuery Form Plugin have a look here:
http://arturito.net/2010/12/02/asp-net-mvc2-jquery-form-post-tutorial/

You cold save your url in a Hidden Form element in (Html.HiddenForm()) and use the #id javascript operator to retrieve it. Just found this out today.

Related

PagedList parameter too long

I have an MVC PagedList which works just fine. I am filtering that list and the filter predicate is sent to the client during roundtrips. I use unobtusive ajax replacing. My pager code looks as:
#Html.PagedListPager((IPagedList)Model.Items,
page => Url.Action("Filter",
new ClientSearch
{
Page = page,
PageSize = Model.PageSize,
Predicate = Model.Predicate
}),
PagedListRenderOptions.EnableUnobtrusiveAjaxReplacing(
new AjaxOptions
{
HttpMethod = "POST",
UpdateTargetId = "clients-list",
}))
The problem is, that the Predicate parameter is too long. And it should be. I get the following exception:
"The request filtering module is configured to deny a request where the query string is too long."
I do not want to alter the web.config in order to allow long parameters. I would like to pass the model in a POST header instead of query string parameter. Is it possible with PagedList?
Thanks in advance.
I still couldn't figure out whether PagedList supported posting large data, however I ended up with the following workaround.
I have a post method which posts the model to the controller function and replaces the partial view content with the results.
function postToPage(url, size, predicate, replace) {
var data = {
size: size,
predicate: predicate
};
$.ajax({
url: url,
data: data,
type: 'POST',
success: function (result) {
$('#' + replace).html(result);
}
});
}
I also have another function to replace the URLs in the pagination-container div and wire up the click event to call the post method. The click event stops event propagation, so the URL in the href attribute won't be used.
function replaceHrefs() {
$('div[class = pagination-container').find('a').each(function (index, value) {
var url = value.href.toString();
value.addEventListener('click', function (event) {
event.stopPropagation();
post(url);
});
value.href = '#';
});
I created a custom version of post method in order to generate the pagesize and predicate from the model.
function post(url) {
postToPage(url, #Model.PageSize, '#Model.Predicate', 'clients-list');
}
I had to wire up the URL replacing procedure to two places: when the document becomes ready and when the ajax call completes. These covered all the cases I needed.
$( document ).ajaxComplete(function() {
replaceHrefs();
});
$( document ).ready(function() {
replaceHrefs();
});
I hope it helps someone.

give dynamic action name in Url.action javascript

I want to give dynamic action name in Url.action through javascript.
// I want to change Index name by dynamic
$.ajax({
url: '#Url.Action("Index", "Home")',
type: "Post",
data: { Surveyid: surveyid, Category: catcode },
success: function (data) {
window.location.href = data.Url
}
like
var x="xxxx";
#Url.Action(x,"Home") -> not working throws error
#Url.Action(x.toString(),"Home") -> not working
then how can i ?
Url.Action is server generated, whereas it seems you want to change the action on the browser. What you can do is tokenize the Action, get Url.Action to generate the tokenized URL, and then substitute this in js:
var jsUrl = '#Url.Action("##", "Home")'; // ## is the token
$.ajax({
url: jsUrl.replace('##', someDynamicAction),
...
(You may need to do the same for the controller)
Edit
My conscience has gotten the better of me - doing this isn't a good idea, given that any invalid action name (or a change in the Controller or Action names) will only be picked up at run time e.g. with 404 errors.
The number of controllers and actions that you need to ajax to should be finite, and T4MVC has already solved this kind of issue.
You can create the urls to the various links:
var urlToIndex = '#Url.Action(MyControllerAssembly.Index.Home())))';
var urlToOtherAction = ...
... etc for all actions needed in the 'switch' for ajax call.
and then choose the appropriate URL for your ajax call. (T4MVC also has methods Url.JavaScriptReplacableUrl and Ajax.ActionLink although for slightly different scenarios)
Best way to use urls in your mvc application is that you define a global app_url in layout page like following:
_Layout.cshtml
<script>
var app_root = '#Url.Content("~/")';
</script>
and use in content page
any_page that inherited from _Layout.cshtml
$.ajax({
url: app_root + 'Home/Index', // or url: app_root + 'Home/' + x
something odd in your example, but I believe what you are trying to do is this
function axajThis(numberthing,path) {
var newUrl = "htttp://somplace/"+path;
/* and what ever the number x is doing */
$.ajax({
url: newUrl,
type: "Post",
data: ....
});
};
}
axajThis(x,"Home");
Little more info needed on what 'x' is.

Rails 3: update URL params with AJAX request

I have a filter and a list of products (id, name, creation_date).
I can filter by id, name or creation_date. With an AJAX request I update a content div... but obviously the URL not change.
How can I append params to URL? For example:
localhost:3000/dashboard/catalog?name=radio&?date_creation=23-06-2013
I know that history.pushState(html5) exists... but I need that my app works in html4 browsers like IE9.
I tried Wiselinks (https://github.com/igor-alexandrov/wiselinks) which it uses History.js but it doesn´t use AJAX request.
Any ideas?
thanks
Finally I follow those RailsCasts tutorials:
http://railscasts.com/episodes/240-search-sort-paginate-with-ajax?language=es&view=asciicast
http://railscasts.com/episodes/246-ajax-history-state?language=es&view=asciicast
You are doing some AJAX call means, you must have invoked the AJAX part on radio button change
So I am assuming, you have done it using by radio button and the radio button name is 'choose_product'
You can add a hidden field in your view, where you can store your current date.
<div id='parentDiv'>
<%= hidden_field_tag 'current_date', Time.now.strftime('%d-%m-%Y') %>
Your radio button code
</div>
In the javascript add the following code. It is just a sample not complete solution.
$(document).ready(function(){
var showProducts = function(){
$("#parentDiv").on('click', "input[name='choose_product']", function(){
var ajax_url = 'localhost:3000/dashboard/catalog';
var url_param = '';
switch($(this).val()){
case 'creation_date':
var param_date = $('#current_date').val();
url_param = '?name=radio&date_creation=' + param_date;
break;
case 'name':
// Your code goes here
default:
//Your code goes here
}
// Here you will get the modified url dynamically
ajax_url += url_param
$.ajax({
url: ajax_url,
// your code goes here
});
});
}
showProducts();
});
A lot of time has passed, but it may be useful.
The code is also updated so if you have more then one ajax\remote link you will be able to merge the params of multiple urls.
Based on user1364684 answer and this for combine urls.
# change ".someClassA" or "pagination" to the a link of the ajax elemen
$(document).on('click', '.someClassA a, .pagination a', function(){
var this_params = this.href.split('?')[1], ueryParameters = {},
queryString = location.search.substring(1), re = /([^&=]+)=([^&]*)/g, m;
queryString = queryString + '&' + this_params;
#Creates a map with the query string parameters
while m = re.exec(queryString)
queryParameters[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
url = window.location.href.split('?')[0] + "?" + $.param(queryParameters);
$.getScript(url);
history.pushState(null, "", url);
return false;
});
# make back button work
$(window).on("popstate", function(){
$.getScript(location.href);
});

use dojo tooltipDialog for every link in the page using parameters

anyone know how to open a tooltipDialog from extlib using parameters.
in csjs I find all links in a webapage and bind them to mouseover. using a key in the link I know which link is clicked, I want to send this key to the toolTipDialog so that I can use that to find the document and display document data in the tooltipDialog.
Currently the only way I have found to open a tooltip dialog is by using XSP.openTooltipDialog("tooltipid",'linkid') which does not seem to allow parameters.
any ideas how to resolve this
Hows this?
require(["dijit/TooltipDialog", "dijit/popup",
"dojo/on", "dojo/dom", "dojo/_base/lang"],
function(ready, TooltipDialog, popup, on, dom, lang){
var myTooltipDialog = new TooltipDialog({
id: 'myTooltipDialog',
style: "width: 300px;",
contentTemplate: "<p>Key is: {key}</p>",
content: 'empty',
onMouseLeave: function(){
popup.close(myTooltipDialog);
},
onOpen: function(pos) {
this.set("content", lang.replace(this.contentTemplate, this.replaceObject));
}
});
/
query('a.hasSelectorClass').on('mouseover', function(){ //
myTooltipDialog.replaceObject = { //
key : this.innerHTML // (inner text in anchor node)
}
popup.open({
popup: myTooltipDialog,
around: this // anchor
});
});
});
Try it and tell if any errors (untested code) :)

jquerymobile and AJAX

seems to me that I didn't fully understand the concept behind jquerymobile, because I have no idea how to solve this issue.
What I want to do is load some HTML Content via AJAX, according to location.hash, put it into a new page and load this page.
But if I create a page myself by using the pagebeforechange event, jquerymobile just ignores it, creates its own div and my content won't be displayed.
How do I have to do it?
Edit:
This is how I am currently doing it, but it wont't work.
$(function() {
getPageContent(top.location.href, false);
$(document).bind( "pagebeforechange", function( e, data ) {
getPageContent(data.toPage, true);
});
});
function getPageContent(pageUrl, changedPage) {
var re = /.*\/#(.*)/;
var result;
result = re.exec(pageUrl);
window.page = result[1].substr(0,3);
window.id = result[1].substr(3);
window.ajaxUrl = "request.php?page="+window.page+"&id="+window.id;
$.ajax({
url: window.ajaxUrl,
success: function(data) {
if(data.error) {
alert(data.error);
}
else if(data.data) {
if(changedPage) {
changePage(data.data));
}
else {
$('#content[role="main"]').html(atob(data.data));
setupPage();
}
}
else {
alert("UNKNOWN ERROR: "+data);
}
}
});
}
function changePage(html) {
var div = "<div></div>";
var newPage = $(div).attr("data-role", "page").attr("data-url", window.page+window.id);
var header = $(div).attr("data-role", "header");
var content = $(div).attr("data-role", "content");
var footer = $(div).attr("data-role", "footer");
$("body").append(newPage);
newPage.append(header, content, footer);
content.html(html);
newPage.page();
}
Complete edit of the whole answer:
First. Set your body id to id=body. Then when you want to load the new page and change to it, use an ajax call like this:
$.get(window.ajaxUrl, function(data){
$('#body').append("<div id='newPage' data-role='page'></div>"); //Creates a new page.
$('#newPage').html(data); //Loads the html content into the new page.
$.mobile.changePage('#newPage'); //Navigates to the new page.
}
This sends an ajax call with the method GET to the url found in your window.ajaxUrl. If the call is successful, it creates a new page named "newPage", and fills it with the data received from the ajax call. Then redirects to the newly created page.
This jsFiddle shows the basics of how it works. However, it doesn't use any ajax call.
You have to refresh the page with jQueryMobile :
$("#your-page").trigger("create");
--Edit
<script>
$("#thepage").live("pageshow", function(){
$("#thepage).trigger("create");
});
</script>
Change the content of #thepage before 'pageshow' event
It does this for you automatically - just make a regular link to the page and jquery mobile will shwo the loading spinner, load it in the background via ajax, then transition to the new page.
Make sure all your pages are decide with unique IDs and data-role='page'. Check out the start guide here:
http://jquerymobile.com/demos/1.1.0/docs/about/getting-started.html

Resources