Send a string parameter to a controller (MVC3) from javascript (no ajax) - javascript

I have this simple javascript code:
var value = "I love programming";
window.location="Controller/Action/"+value;
In controller page, I have this:
public ActionResult(string value) {
// do something
}
The problem is value parameter from controller. This is always null.
Why ?
Is the parameter type is restricted to int? (without using ajax)
I can send an int to controller and it process the information correctly. But not string.

You may need to set up a route in global.asax to handle the string parameter, i.e:
RouteTable.Routes.MapRoute(
"ValueRoute",
"{controller}/{action}/{value}",
new
{
controller = "Yourcontroller",
action = "Youraction",
value = UrlParameter.Optional
}
);
this is all top of the head stuff, so it may not happen for you.
[update 1] as you say in the comment below, changing the parameter name from value=>id should resolve the problem without recourse to addtional routes.
[update 2] - you could also, as per sandeep's comment, opt for the name-value pair on the url, i.e. window.location="Controller/Action?value="+yourValue

Related

How to get url parameters in Backbone?

I'm using Backbone with Marionette.
I have a link <a> tag where I'm passing few parameters, how can I extract those values in other pages using Backbone?
View Details
Address Bar url:
http://localhost.com:8080/help/?name=matth&age=25&email=matt#gmail.com 44
Using Php, this is straightforward:
$Url = $_GET['state']."#".$_GET['city'];
How can I achieve it within my Backbone app?
If the route is defined with something like this:
'help/:name&:age&:email' : 'help'
Then you can access those params in the help function just by defining them in the signature of the method (within the backbone router),
help: function(name, age, email) {
// do whatever you want with the params
}
In your case, this will give you params like this:
name="XXX" age="XXX"
So the proper routing would be
'help/?(name=:name)(&age=:age)(&email=:email)' : 'help'
Where parentheses make a part optional.
Backbone docs
Routes can contain parameter parts, :param
Note that the order is important and the following url wouldn't trigger the route callback. Notice the email and age params placement.
help/?name=test&email=test%40example.com&age=6
In order to trigger a route regardless of the number of params and their ordering, take a look at how to parse the query string in the route function, but that won't always work.

get angular ui router $location.search() to use Basic URL Parameters

I have ui-router set up as follows
.state('root.event', {
url : '/event/:id',
templateUrl : 'templates/event.html'
})
(the controller is initiated in the template)
which gives nice looking Basic URL Parameters like:
www.mysite.com/event/1234
When a user navigates directly to my www.mysite.com/event path (ie param is missing) the template controller looks the most recent id parameter from either:
- a js variable stored in a value
- localstorage / cookie etc
I then return this to my state using $location.search('id', 1234)
...however, this results in URLs which have Query URL Parameters like:
www.mysite.com/event/?id=1234
Is there a technique to ensure that $stateparams updates present the url in basic format on update ?
...or is it possible to get the URL parameter & update the $state before the state change ?
(I looked at Resolve but this seems mostly to be about passing parameters to controllers)
I've had a look here, here and here - but most of the questions relate to how to avoid reload on update of $state params
$location.search does exactly that. It adds query URL parameter. I think what you're looking for is
$state.go('root.event', {id: 1234})

Load Partial View on ajax success method in MVC 4

Problem Statement:View not able to load on ajax success method.
Description:
I'm having couple of dropdowns as cascaded(second binding based on the value of first).
On change of the first dropdown I'm binding second dropdown and again on change of the second dropdown,now on right side I want to display a list of record based on the two dropdown values.
For this,I'm using the following JS code in onchange event for the dropdown 2:
function ShowDocsList() {
var teamId = $('#TeamID').val();
var projectId = $("#ProjectID").val();
var Url = "#Url.Content("~/DocsHome/DocsList")";
$.ajax({
url: Url,
type:'POST',
dataType: 'html',
data: { TeamID: teamId ,ProjectID : projectId},
success: function (data) {
return data;
$('.docs-detail').html(data);
}
});
Here,in DocsHome Controller,DocsList method is getting hit on change of second dropdown which is project dropdown.But the view is not getting rendered .Following is my Controller Code:
public ActionResult DocsList(int teamId, int projectId)
{
List<CustomerViewModel> customerViewsModels = SmartAdminHelper.GetCustomers(db1);
if (Request.IsAjaxRequest())
return PartialView("DocsList");
else
return View("DocsList");
}
Again ,I'm getting record in List but while debugging it does not pass to the DocsList view which according to me is correct.
Here DocsList is the view I want to render as a partial view on change of the second dropdown.
According to my knowledge,while debugging it comes to the point return PartialView("DocsList") but then again it goes back to the ajax success method and finally I find that there I'm doing something wrong.
Earlier I have Json to get data but here I'm calling actionmethod from ajax. So, not sure that also might be a problem as I'm new to this.
What and where exactly I'm doing wrong?
Saroj, I see that this is an old question and that you needed to get it done quickly, but if you happend to come back to this, I'll add my two cents. You need to remove the return statement that David and Ehsan mention above. The rest of the callback function does what it should. In your action method it doesn't look like you're doing anything with the parameters you pass in. I'm assuming that you are going to figure that out after you get the view down to the client. So, lets get that view down to the client.
I like to pass the rendered partial view back to the client as a string of HTML. I do this using a method that I keep in a controller base class that each of my controllers inherit from. To use the method you will need to reference System.Web.Mvc and System.IO namespaces.
The method looks like this:
private string RenderViewToString( string viewName, object model ) {
ViewData.Model = model;
using ( var sw = new StringWriter() ) {
var viewResult = ViewEngines.Engines.FindPartialView( ControllerContext, viewName );
var viewContext = new ViewContext( ControllerContext, viewResult.View, ViewData, TempData, sw );
viewResult.View.Render( viewContext, sw );
viewResult.ViewEngine.ReleaseView( ControllerContext, viewResult.View );
return sw.GetStringBuilder().ToString();
}
}
You pass your model and the name of the view to the method and it returns the rendered view HTML as a string which you can return to the client as a ContentResult.
Update your action method like so:
public ActionResult DocsList(int teamId, int projectId)
{
List<CustomerViewModel> customerViewsModels = SmartAdminHelper.GetCustomers(db1);
if (Request.IsAjaxRequest())
var viewContents = RenderViewToString("DocsList", customerViewsModels);
return Content(viewContents);
else
return View("DocsList");
}
Assuming that the element that you want the rendered view to appear in has the css class '.docs-detail' on it you'll be in business. Hope this helps!

Get returned object from controller into the javascript

In my controller, I send an object list into the view (index.cshtml)
return View(AdsPrevModel);
in my index.cshtml:
<div id ="ele">
<ul>
<li> name1<input id="a1" type="checkbox"/></li>
</ul>
</div>
when the user clicks the checkbox, I use jquery to know if the user checked the box or not:
My javascript file:
$('#ele :checkbox').click(function () {
if ($(this).is(':checked')) {
alert($(this).attr('id'));
} else {
alert('unchecked');
}
});
How can I get my AdsPrevModel into my js file?
I know I can do something like this:
In my html, add:
<input type="hidden" id="AdsPrevModel" value="#Model.AdsPrevModel" />
and in the js:
var adsPrevModel = JSON.parse(document.getElementById('AdsPrevModel').value);
Is there another option without adding a hidden input in my html?
Maybe something like the following in the js file:
var adsPrevModel = JSON.parse(Model.AdsPrevModel));
The best practise is
do an ajax call to that controller and that controller should return json results
return JSON( model ) ;
In the code you've shared there's nothing emitting the model to the client, so there's currently no direct way for the JavaScript code to access it.
Since you're binding the view to the model, the view can include it in various ways. It could be a series of hidden fields for the members of the model (not the model in its entirety, unless it can be represented as a string in its entirety). Something like this:
#Html.HiddenFor(x => x.SomeField)
#Html.HiddenFor(x => x.AnotherField)
This would create two hidden inputs for two fields on the model. Depending on how complex the model is, this could get cumbersome.
You might also emit the model to the JavaScript code directly in a similar fashion:
var someField = #Model.SomeField;
var anotherField = #Model.AnotherField;
Again, if the model is complex, this gets cumbersome quickly. Even if you try to build an actual JavaScript object from it:
var theModel = {
someField : #Model.SomeField,
anotherField : #Model.AnotherField
};
(Note also that I've seen Visual Studio get very confused when you mix razor syntax and JavaScript like this. Not so much in 2012 anymore, but a lot in 2010.)
You might use something like the JavaScriptSerializer to add a property on the model for a serialized version of itself. I've never done this before, but it should work. Something like this on the model:
public string SerializedCopy
{
get
{
return new JavaScriptSerializer().Serialize(this);
}
}
It might take some tweaking to get it to work, though.
Finally, a particularly clean option which only requires another request to the server would be to have another action which just returns the JSON version of that model. Something like this:
public ActionResult SomeActionName()
{
// get the model somehow, then...
return Json(AdsPrevModel);
}
Your JavaScript code would then just need to call this action to get the JSON object representing the whole model:
var theModel = {};
$.get('#Url.Action("SomeActionName", "SomeController")', function (data) {
// maybe do some error checking here?
theModel = data;
});
Then if your actual view isn't actually binding anything to the model then the action which returns that view doesn't need to fetch the model and supply it to the view. The JavaScript code would get the model by calling this other action which returns JSON data instead of a view.

Angularjs $location service apparently not parsing url?

I'm using angular in an application which is, basically, a table with search results.
Access to this table can be achieved via an url like http://myapp/?client=clientName
An angular controller is instantiated for the table, among other things, for opening a modal dialog (also angular-based with bootstrap-ui) with the row details.
These row details are brought via a service which has some common functionality for both controllers: the one for the table and the one for the modal.
Now, within this service, I have the following snippet to retrieve:
service.fetchRelatedElements = function(element, cb) {
var url = '/search.json?results=20&type='+element.type;
if ($location.search()['client']) {
url += '&client=' + $location.search('client');
}
return doFetch(url, cb); // actual server json GET
};
The goal is to know if the table already has this specific client parameter set as a filter.
If I put a breakpoint at the beginning of this call, I see that $location.absUrl() returns the current browser URL (which, in my case, has the client parameter I'm interested in).
But $location.search() returns an empty object.
I am injecting the $location service within my service with the defaults (that is, not configuring it by a .config() call).
And, as doc says:
The $location service parses the URL in the browser address bar (based
on the window.location) and makes the URL available to your
application.
Am I missing something? Shouldn't the URL, at this point, be parsed?
Thanks!
UPDATE: I've managed to make it work. The problem was exactly that I wasn't configuring at all the service. I did so because I assumed that in that way it would take defaults, but it seems that that's not the way it works.
I was having the same problem before I configured $locationProvider in my app's module config:
appModule.config(['$locationProvider', function($locationProvider) {
$locationProvider.html5Mode(true);
}]);
If you don't want to specify the base tag, you can specify require base false.
myapp.config(function($locationProvider) {
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
});
When I encountered this problem, another thing that worked for me besides setting the configuration is to add "#" in front of the query string.
So if you are the one creating the query string, then changing
myapp/?client=clientName
to
myapp/#?client=clientName
allowed $location.search() to give me a non-empty object which you can then access each parameter using $location.search()['client']
The API for $location.search is pretty confusing. Calling
$location.search('client');
will set the search object to {client: true} and return $location. Furthermore, you have a typo client instead of 'client', so it's setting search to an empty object. So you probably want:
url += '&client=' + $location.search()['client'];
You can write a function that parses the $window.location.search based on this comment https://github.com/angular/angular.js/issues/7239#issuecomment-42047533
function parseLocation(location) {
var pairs = location.substring(1).split("&");
var obj = {};
var pair;
var i;
for (i in pairs) {
if (pairs[i] === "")
continue;
pair = pairs[i].split("=");
obj[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
}
return obj;
}
$scope.query = parseLocation($window.location.search)['query'];

Categories