How to redirect to different controller? - javascript

I have an application in ASP.MVC. The requirement is that I select a person from a list of people and click 'Info' and it should load the details of the person in that page. I have the Info controller and everything works fine if I go to the Info page from a different controller. In the page I am trying to make it work with JavaScript and it doesn't seem to take me to the desired page but to a different controller.
I have a ToDoList controller and in the .cshtml I have this code on click of the Info link.
function DoInfo#(i.ToString())() {
$("#sessionid").val("#Model.cSessionId[i]");
alert("hey");
$("#PageController").val(66);
$("#formID").submit();
}
I go to the ToDoList controller to do the redirection like this
if (viewModel.PageController == 66)
{
pass = new PassingData();
pass.personid = TSSessionService.ReadPersonId(viewModel.SessionId);
TempData["pass"] = pass;
return RedirectToAction("Index", "Info");
}
It never goes there and instead goes to a different controller. I cannot seem to find how they are linked and why is it not going back to controller where the Info link button is i.e. back to the ToDoList controller.
Let me know if it is not clear and I will try to explain again and I will give any other details.

I guess I'm confused as to why you are doing this as a combination of form and JavaScript. Are there other properties that you need to pass along that you are not posting above? Why do you need to use JavaScript to do this if you are just returning a new view?
You indicate in your post that when a person is selected from a list you need to go to a controller and display a view. This seems fairly straightforward, and I would like to suggest simplifying the problem.
Start with this: change your link to not use a form or JavaScript. Just make it a link. If it is text, you can use #Html.ActionLink() and even pass in the parameters you need.
If you're not displaying text, just use #Url.ActionLink() in your href property of the anchor you're wrapping your element with. Both of these allow you to leverage routing to ensure the correct path is being constructed.
If the controller that you are trying to get to has access to whatever TSSessionService is, then you don't need to pass through the TempData["pass"] you are trying to push through, so it makes it cleaner in that way as well.
If you do need to submit a more complicated value set, I would recommend coming up with a generic .click() event handler in jQuery that can respond to any of the clicks, bound by a common class name. You can use a data-val attribute in your link and read from $(this).attr('data-val') in your handler to store/fetch other important info. This allows you to more easily build up an object to POST to a controller.
Hope this helps some, but if I'm missing a critical point then please update the question above.

Related

How can I send a html selector's option into Controller using JavaScript?

I have multiple city options in my Selector in view, and I need to use the city name in a Controller method. The JavaScript function I want to use will be trigered when clicked on a button. before, I used
window.location = "/results";
in my JavaScript, the "/results" being the route I use my Controller in. but you clearly can't send any data to Controller this way (or can you?). The only method I could find online was using ajax, but I want to stay out of ajax as far as I can. So how can I accomplish this?
As no one answered this question, I tried my luck and found the solution. So what we need to do is first, getting the value of the selector we need, and then sending it into our controller using a URL. Here's the JavaScript function that triggers with the click of a button:
var city = document.getElementById('citypicker').value;
window.location.href = "/results/"+city;
The first line retrieves the value of selector with the id of 'citypicker', stores it in city variable and then we redirect to a URL consisting of that city variable. So this URL changes every time we select another value.
In the route, we define this URL as such:
Route::get('/results/{city}', 'ResultsController#city');
the {city} is variable, meaning that it can change AND can be used as input of city method in ResultsController. So the method looks like this:
public function city($city) {
//code here
}
No ajax was used either. Hope this helps.

Go to parent route in Angular 2

Let's say I have a component that creates or edits a thing.
The url for the creation is /things/create and the url for edition is /things/edit/4. These routes have the same parent.
Once I fill in the form, I call some webservice and then I go back to my previous state which was /things.
How do I tell angular to go back to the parent route?
I could use this.router.navigate(['../'], {relativeTo : this.route}); but ['../'] would only work for /things/create. For /things/edit/4 it would go back to /thing/edit which doesn't exist.
This component is used in two different places, one of which has an extra step before the creation so I can't use back().
Logic based on the current url
if(router.url.indexOf('create')>= 0){
this.router.navigate(['../'], {relativeTo : this.route});
}else {
this.router.navigate(['../../'], {relativeTo : this.route});
}
so if your current URL path contains the create you know you just have to go back one level, otherwise you go back two levels for the edit.
Use Input to get base URL
Another approach might be to have an #Input for the base URL to go back to. So each component that initializes your component has to pass it the parent url.
{
#Input
parentUrl;
this.router.navigate[parentUrl];
}
You can use
this.router.navigate['/things']
So you should be able to check for the id of the thing in the ActivatedRoute params to get the context if the component is creating or editing a component. If there is a param['thingId'] then go to ../../ otherwise go to ../
May be this idea a bit old school but I am sure it will work and is quite simplistic to implement. You can add query param called 'source' and navigate to 'source once the operation is done.

Get controller not working with Ember.textfield

App.PhotoUpload = Ember.TextField.extend
type: "file"
change: (evt) ->
# #get('controller') gives - App.PhotoUpload
#get('controller').send('uploadImage')
In above code,if I debug it and check #get('controller').constructor it returns App.PhotoUpload, which is not right and it doesn't call uploadImage action which is in my route.
When I change Ember.TextField to Ember.View, #get('controller') works as expected and uploadImage action is called. But, as Im doing auto update to server on image upload, I need to stick with TextField.
I have these questions:
1. What are ways to access another controller from Emberview ?
2. How can I get access to right controller from Ember.TextField ??
The problem here is that the included input fields were recently modified to extend Ember.Component instead of Ember.View. One of the primary differences between a component and a view is that the controller property of a component is itself. Honestly, I'm not totally sure why that change was made. Having said that, it's still possible to access the controller from the context of where the text field was defined using the targetObject property.
Update:
I looked into this a bit more and it turns out that not all input fields were turned into components, only the TextField and TextArea. It appears the primary reason for turning them into components was to expose some helpful action handlers since components provide that capability.

How do I perform an action before any view(or partial) is rendered?

My problem is simple. I want to know if there is a method(or something) that is automatically called by default(by ASP.Net engine) before any view(or partial) is rendered. I like to intercept it to perform an action, e.g generate a random number.
I will explain my scenario in case of somebody have a better idea.
My app's views and partials renders elements with an id pattern like this: Model_Id. In some cases, when user brings up a modal window with a view that repeats the id of any element of the main window, my jquery selectors get confused. I've already create custom helpers to do that behavior, so I thought about generate random number(and store it on session) and concat it in the id, to get something like Model_Id_1234 or 1234_Model_Id.
If there is a better way, it will be really nice to know.
you could write a custom action filter to allow you to intercept ahead of the action performing. This would then be called using the method:
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
// do your pre action display stuff here!!
// if the code is added to basecontroller -
// also optionally defer back to base.OnActionExecuting(filterContext);
base.OnActionExecuting(filterContext);
}
I'll add to the answer with further detail as literally in transit just now.
See this post on MSDN, it covers the controller pipeline for MVC.
[Edit] - in response to comment, see also this SO answer: Calling the Session before any Controller Action is run in MVC. In effect, in this example, we don't create an actionfilter, we only override the OnActionExecuting inside the base controller.

Where does data returned by ember-data 'live'?

ya'll I have a bit of a structural/procedural question for ya.
So I have a pretty simple ember app, trying to use ember-data and I'm just not sure if I'm 'doing it right'. So the user hits my index template, I grab their location coordinates and encode a hash of it (that part works). Then on my server I have a db that stores 'tiles' named after there hash'd coords (if i hit my #/tiles/H1A2S3H4E5D route I get back properly formatted JSON).
What I would like to happen next, if to display each of the returned tiles to the user on the bottom of the first page (like in a partial maybe? if handlebars does that).
I have a DS.Model for the tiles, if I hard code the Hash'd cords into a App.find(H1A2S3H4E5D); I can see my server properly responding to the query. However, I cannot seem to be able to figure out how to access the returned JSON object, or how to display it to the user.
I did watch a few tutorial videos but they all seem to be outdated with the old router.
Mainly I would like to know:
1. Where does the information returned by App.find(); live & how to access it?
2. what is the 'correct' way to structure my templates/views to handle this?
3. how should I pass that id (the hash'd coords) to App.find? as a global variable? or is there a better way?
the biggest problem(to me) seems to be that the id I search by doesn't exist until the user hit the page tho first time. (since its dynamically generated) so I can't just grab it when the page loads.
I can post a fiddle if required, but I'm looking for more of a conceptual/instructional answer rather then some one to just write my code for me
I'm still learning a lot with Ember as well, but this is my understanding. When you follow the guides and the tutorials out there, you'll have something like this:
App.TileController = Ember.ObjectController.extend();
App.TileRoute = Ember.Route.extend({
setupController: function(controller) {
controller.set('content', App.Tile.find(MYHASH));
}
});
What it does is set the special content object to the result. So since we're declaring an object controller, and calling find with a parameter, it knows that a single result is expected. So a view & template that follow the naming convention of Tile will be loaded. And in there you can access properties on the Tile object:
<p>{{lat}}</p><p>{{lng}}</p>
I have to admit that this feels a bit mystical at times. The core to it is all in the naming convention. You need to be pretty specific in how you name all your various controllers, routes, etc. Once that's nailed down, it's a matter of binding what data you want to the controller's content.
1) Aside from the generic answer of "in memory", the .find() calls live where ever you return it to. Generally speaking, this is meant to be set on a 'content' property of a controller.
2) I more or less answered this, but generally speaking you take the name of your route, and base it off that. So for a route TileRoute, you have:
TileController = Ember.ObjectController.extend
Tile = DS.Model.extend
TileView = Ember.View.extend
tile.handlebars
I generally store all my handlebars files in a templates/ folder. If you nest them deeper, just specify the path in your view object:
App.TileView = Ember.View.extend({
templateName: "tiles/show"
});
3) This really depends on your app. Generally speaking its better for the id to be either obtained from the URL, or constructed locally in a function. Since you are encoding a hash, i imagine you're doing this in a function, and then calling find. I do something a bit similar for an Array controller.
I don't know at what point you are generating a hash, so let's say it's onload. You should be able to generate the hash just in the setupController function.
App.TileRoute = Ember.Route.extend({
generateHashBasedOnCoords: function() {
// ...
},
setupController: function(controller) {
var MYHASH = this.generateHashBasedOnCoords();
controller.set('content', App.Tile.find(MYHASH));
}
});
I hope that helps.
I believe that you can make use of the data binding in ember and basically have an array controller for tiles and set the content initially to an empty array. Then we you get back your response do a App.find() and set the content of the tiles controller with the data that is returned. This should update the view through the data binding. (Very high level response)
The data itself is stored in a store that is setup with ember data. You access it with the same method you are using the model methods App.Tile.find() ect. It checks to see if the data that is needed is in the store if so it returns the data otherwise it makes a call to the api to get the data.

Categories