mvc3 - set focus to control from Controller - asp.net-mvc-3

Can I set focus to a control from a Controller when calling a View?
(I understand the typical best practice is to use jQuery to set focus to a control when the page is loaded.)

The controller's job (one of them) is to set up a view model which gives the view enough information to render correctly. In other words, the controller and the view should only be loosely coupled.
Here's one way to do it. This is somewhat decoupled though it could be done more elegantly. You still need JavaScript to perform the client-side scripting, but the script is generated based on a value in the view model.
Controller
public ActionResult Foo(){
var model = new MyViewModel();
model.SelectedItem = "FirstName";
return View( model );
}
View
#model MyViewModel
#Html.TextBoxFor( o => o.FirstName )
#if( Model.SelectedItem != default( string ) ){
<script>$("##(Model.SelectedItem)").focus();</script>
}

One thing you have to learn about web development is that you can have all the technologies in the world on the server, but in the end, those technologies have to generate standard (or what passes for it) Html, CSS, and JavaScript.
That means there is no special magic that can be done on the server to automatically do things on the client. Some frameworks can automatically generate code to do this for you, but it still must be done as standard html/css/js in the end.
MVC only renders standard, plain HTML. Webforms will do a lot of things for you, but in the end Webforms has to generate standard HTML as well. It does this by auto generating javacript that gets included in the page that, on load sets the focus.
MVC doesn't do any of those things for you, so you would basically have to do the same thing, but you would have to write it. It's relatively simple using some simple jquery.

Related

The point of MVC

First, just to say, this is not a troll posting, I'm genuinely completely and utterly at a loss as to why MVC is where the industry is going/gone. If MVC wasn't on every job advert I've seen for the last 4 years I'd not bother but as it is, it looks like I'm going to have to use it.
What is the point of MVC? Yes you get the pretty URL e.g. www.amazon.co.uk/books/horror/ but I can't see any other advantage. I was reading the ScorrGu blog where other's where asking the same
https://weblogs.asp.net/scottgu/introducing-razor
This is the copy+paste reasoning from the ScottGu blog concerning Razor
Some people like a controls model with code-behind for code/content separation, and others like a MVC model where there is separation between the controller and view. In an MVC model your application/business logic is contained within the controller and model layers - and does not live in your view. Your view file instead just focuses on generating HTML rendering.
In the controls model there is "separation between the controller and view" in that there is the code behind(controller) and the content (view).
Application/business logic is sprinkled throughout the view (depending on what's on that view obviously) from the examples and tutorials I've been looking at logic like "Does this user have permissions to see this link?"
"Your view file instead just focuses on generating HTML rendering."
It isn't
#foreach (var item in Model.Items) {
var style = item.IsArchived ? "archived-validation-item" : "";
#Html.DisplayFor(modelItem => item.Code)
their is logic here about how many times a loop is performed and retrieving the right item code.
In the controls model, a page has two files one containing the logic and one the layout.
In MVC, a page has three files, the controller and model containing logic and the view which contains layout and logic.
The reason classic ASP was left behind was so that the code and the markup were seperated, the front end developer could get on with making it look pretty while the back end developer worked on getting the right things onto that page. Their roles and responsibilities were clear and seperate. With MVC, both developers must know about the model (and viewmodel too if that's used) as well as the view and controller (as well as the routes, etc.) so that everything is linked up together. From the examples I've seen for example, the decision on when a link should be shown could be made by the view, the controller or the model. This adds layers of complexity and confusion.
What am I missing apart from some well paid jobs? ;)
Thanks
You are correct in that the old *.aspx + Code-Behind Class was an example of separating concerns and logic - however it was not true MVC separation because the code-behind class was still concerned with aspects of presentation, and similarly it's possible for the .aspx file to have business logic in it, as an example, this:
ASPX:
<!-- this data-source is arguably a piece of business logic in the view layer: -->
<asp:SqlDataSource runat="server" id="ds1" selectCommand="SELECT * FROM someTable" />
<asp:GridView runat="server" id="gv1" dataSource="ds1" />
<asp:Literal runat="server" id="lit1" />
Code-behind:
void Page_Load(Object sender, EventArgs e) {
this.lit1.Text = "<div class=\"something\"><p>some HTML goes here</p></div>"; // this is presentation logic in the code-behind
}
In MVC separation, you remove the "tight-coupling" between the two, as well as enforcing the separation of concerns because you cannot (feasibly) generate HTML from within a Controller Action, and similarly you should not be able to execute business rules in a View because for example, all database connections are closed at that point in the request lifecycle.
One core tenet of MVC is the "view-model" which is a class that encapsulates the entirety of data represented (and manipulated) by the view (alternatively, the tuple of the ViewModel with the ViewData). As this class is well-defined it means the page is almost self-describing, there is no need to manually examine the view to see what's going on and what data is being displayed.
In summary, it's this:
WebForms:
[query database] -> [populate view directly]
MVC:
[query database] -> [populate viewmodel] -> [view renders viewmodel]
One advantage to this approach is that you can turn a website into a web-service by only changing one line of code:
From this:
public ActionResult Index() {
IndexViewModel viewModel = new IndexViewModel();
// (populate ViewModel here)
return this.View( viewModel );
}
To this:
public ActionResult Index() {
IndexViewModel viewModel = new IndexViewModel();
// (populate ViewModel here)
return this.Json( viewModel );
}
You can't do that with WebForms :)
You can write good code, or bad code independent of the frameworks involved. IMHO MVC is a pattern that better lends itself to test-ability due the view separation. Putting logic in the correct places is still the responsibility of all the team members. MVC won't guarantee a great architecture.
And honestly if your application is correctly designed and your webforms are all calling logic in services, maybe MVC isn't that big of a deal for you personally. Also, I agree with what Vincent mentioned about the shift toward SPA's. Personally I've seen several applications written as spas that aren't interactive that would have been just fine as MVC apps. As always, "It depends" is still the best software dogma.

Is Ext JS's MVC an anti-pattern?

I work in a team of 25 developers. We use ExtJS MVC pattern of Sencha. But we believe that their definition of MVC is misleading. Maybe we might call their MVC an anti-pattern too.
AMAIK, in MVC controller only knows the name or the path of the view, and has no knowledge on the view's internal structure. For example, it's not the responsibility of the controller, whether view renders the list of customers a simple drop down, or an auto-complete.
However, in Ext JS's MVC, controller should know the rendering of view's elements, because controller hooks into those elements, and listens to their events. This means that if an element of the view change (for example a button become a link), then the relevant selector in the controller should change too. In other words, controller is tightly-coupled to the internal structure of the view.
Is this reason acceptable to denounce Ext JS's MVC as anti-pattern? Are we right that controllers are coupled to views?
UPDATE (March 2015): Ext 5.0 introduced ViewControllers that should address most of the concerns discussed in this thread. Advantages:
Better/enforced scope around component references inside the ViewController
Easier to encapsulate view-specific logic separately from application flow-control logic
ViewController lifecycle managed by the framework along with the view it's associated with
Ext 5 still offers the existing Ext.app.Controller class, to keep things backwards-compatible, and to give more flexibility for how to structure your application.
Original answer:
in Ext JS's MVC, controller should know the rendering of view's elements, because controller hooks into those elements, and listens to their events. This means that if an element of the view change (for example a button become a link), then the relevant selector in the controller should change too. In other words, controller is tightly-coupled to the internal structure of the view.
I actually agree that in most cases this is not the best choice for the exact reasons you cite, and it's unfortunate that most of the examples that ship with Ext and Touch demonstrate refs and control functions that are often defined using selectors that violate view encapsulation. However, this is not a requirement of MVC -- it's just how the examples have been implemented, and it's easy to avoid.
BTW, I think it definitely can make sense to differentiate controller styles between true application controllers (control app flow and shared business logic, should be totally uncoupled from views -- these are what you're referring to), and view controllers (control/event logic specific to a view, tightly-coupled by design). Example of the latter would be logic to coordinate between widgets within a view, totally internally to that view. This is a common use case, and coupling a view-controller to its view is not an issue -- it's simply a code management strategy to keep the view class as dumb as possible.
The problem is that in most documented examples, every controller simply references whatever it wants to, and that's not a great pattern. However, this is NOT a requirement of Ext's MVC implementation -- it is simply a (lazy?) convention used in their examples. It's quite simple (and I would argue advisable) to instead have your view classes define their own custom getters and events for anything that should be exposed to application controllers. The refs config is just a shorthand -- you can always call something like myView.getSomeReference() yourself, and allow the view to dictate what gets returned. Instead of this.control('some > view > widget') just define a custom event on the view and do this.control('myevent') when that widget does something the controller needs to know about. Easy as that.
The drawback is that this approach requires a little more code, and for simple cases (like examples) it can be overkill. But I agree that for real applications, or any shared development, it's a much better approach.
So yes, binding app-level controllers to internal view controls is, in itself, an anti-pattern. But Ext's MVC does not require it, and it's very simple to avoid doing it yourself.
I use ExtJS 4's MVC everyday. Rather than spaghetti code, I have an elegant MVC app that has tightly defined separation of concens and is ridiculously simple to maintain and extend. Maybe your implementation needs to be tweaked a bit to take full advantage of what the MVC approach offers.
Of course the controllers are bound to the views in some way. You need to target exactly which elements in your views you want to listen to.
eg: listen to that button clicks or to that form element change or to that custom component/event.
The goal of MVC is components decoupling and reusability and the Sencha MVC is awesome for that. As #bmoeskau says, you have to be careful in separation of the view controllers (builtin for the view/widgets itself) and the application controllers (top level views manipulations) to take full advantage of the MVC pattern. And this is something not obvious when your read http://docs.sencha.com/ext-js/4-1/#!/guide/application_architecture. Refactor your MVC approach, create different controllers, create custom component, and embrace the full ExtJS MVC architecture to take advantage of it.
There's still a slight problem in Sencha approach IMHO, the MVC refs system doesnt really work when you have multiple instances of the same views in an Application. eg: if you have a TabPanel with multiple instances of the same Component, the refs system is broken as it will always target the first element found in the DOM... There are workarounds and a project trying to fix that but i hope this will be adressed soon.
I'm currently undergoing the Fast Track to ExtJS 4 from Sencha Training. I have a strong background in ExtJS (since ExtJS 2.0) and was very curious to see how the MVC was implemented in ExtJS 4.
Now, previously, the way I would simulate kind of a Controller, would be to delegate that responsibility to the Main Container. Imagine the following example in ExtJS 3:
Ext.ns('Test');
Test.MainPanel = Ext.extend(Ext.Container, {
initComponent : function() {
this.panel1 = new Test.Panel1({
listeners: {
firstButtonPressed: function(){
this.panel2.addSomething();
},
scope: this
}
});
this.panel2 = new Test.Panel2();
this.items = [this.panel1,this.panel2];
Test.MainPanel.superclass.initComponent.call(this);
}
});
Test.Panel1 = Ext.extend(Ext.Panel, {
initComponent : function() {
this.addEvents('firstButtonPressed');
this.tbar = new Ext.Toolbar({
items: [{
text: 'First Button',
handler: function(){
this.fireEvent('firstButtonPressed');
}
}]
});
Text.Panel1.superclass.initComponent.call(this);
}
});
Test.Panel2 = Ext.extend(Ext.Panel, {
initComponent : function() {
this.items = [new Ext.form.Label('test Label')]
Test.Panel2.superclass.initComponent.call(this);
},
addSomething: function(){
alert('add something reached')
}
});
As you can see, my MainPanel is (besides the fact that is holding both panels) also delegating events and thus creating a communication between the two components, so simulating sort of Controller.
In ExtJS 4 there is MVC directly implemented in it. What really striked me was that the way the Controller actually fetches the components is through QuerySelector which in my opinion is very prone to error. Let's see:
Ext.define('MyApp.controller.Earmarks', {
extend:'Ext.app.Controller',
views:['earmark.Chart'],
init:function () {
this.control({
'earmarkchart > toolbar > button':{
click:this.onChartSelect
},
'earmarkchart tool[type=gear]':{
click:this.selectChart
}
});
}
});
So as we can see here, the way the Controller is aware of the earmarkchart button and tool is through selectors. Let's imagine now that I am changing the layout in my earmarkchart and I actually move the button outside of the toolbar. All of a sudden my application is broken, because I always need to be aware that changing the layout might have impact on the Controller associated with it.
One might say that I can then use itemId instead, but again I need to be aware if I delete a component I will need to scatter to find if there is any hidden reference in my Controllers for that itemId, and also the fact that I cannot have the same itemId per parent Component, so if I have an itemId called 'testId' in a Panel1 and the same in a Grid1 then I would still need to select if I want the itemId from Panel1 or from the Grid1.
I understand that the Query is very powerful because it gives you a lot of flexibility, but that flexibility comes at a very high price in my opinion, and if I have a team of 5 people developing User Interfaces and I need to explain this concepts I will put my hands on the fire that they will make tons of mistakes because of the points I referenced before.
What's your overall opinion on this? Would it be easier to just somehow communicate with events? Meaning if my Controller is actually aware of what views he's expecting events, then one could just fire an event dosomethingController and the associated Controller would get it, instead of all this Query problem.
I think if you use the Sencha Architect to produce the Views then Inherit from that View to create Your own View.
Now this View Can be responsible to hook up to any events and raise meaningful events.
This is just a thought...
//Designer Generated
Ext.define('MyApp.view.MainView', {
extend: 'Ext.grid.GridPanel',
alias: 'widget.mainview',
initComponent: function() {
}
});
//Your View Decorator
Ext.define('MyApp.view.MainView', {
extend: 'MyApp.view.MainViewEx',
alias: 'widget.mainviewex',
initComponent: function() {
this.mon(this, 'rowselect', function(){
this.fireEvent('userselected', arguments);
}, this);
}
});
I think there is a pretty bad problem here - its very difficult to shard isolated units within a page.
The approach I'm experimenting with (which makes it somewhat easier to write tests aswell) is to have a vanilla js context object for each page which contains the logic (and has the benefit of being very easy to break up and delegate to different objects). The controllers then basically call methods on the context objects when they receive events and have methods on them for retrieving bits of the view or making changes to the view.
I'm from a wpf background and like to think of the controllers as code-behind files. The dialog between presenter/context and view is a lot chattier than wpf (since you dont have binding + data templating) but its not too bad.
Theres also a further problem I haven't had to solve yet - the use of singletons for controllers causes problems for reuse of UI elements on the same page. That seems like a serious design flaw. The common solution I've seen is (yet again) to pile everything into one file and in this case to ditch the controller altogether. Clearly that's not a good approach as soon as things start to get complicated.
It seems like getting all the state out of the controller should help though and you'd then have a second level of context objects - the top level one would basically just assign a unique id to each view and have a map of context=>view and provide dispatch to the individual context methods - it'd basically be a facade. Then the state for each view would be dealt with in the objects dispatched to. A good example of why statics are evil!

Knockout JS, MVC 3 and View Model Server Side Data as JSON

So I have a problem...I am separating concerns in my web app: HTML in razor pages and JS in js files. My problem lies in the fact that I want to use data from my controller passed down in the view model from the server as the options of a select list. The problem lies in the fact that I have separated my js from my HTML and I can't access Razor inside the js files.
I have a list of items coming down into my view model...
public List Stuffs { get; set; }
I json encode it server side and make sure to take care of circular refrences, so it looks like this
[{"id":1,"name":"blah"},{"id":2,"name":"blah2"},{"id":3,"name":"blah3"},{"id":4,"name":"blah4"}]
The problem is, I want to keep my separation of concerns, so how do I get that array into my js file so I can bind it to a select list using knockout? I definitely don't want to do another round trip to the server.
So lets say you have some view that looks like this:
<div> (Some stuff) </div>
<script type="text/javascript">
var initialData = //Your JSON
<script>
And then in your javascript (which you have linked below your view, so that it loads after it), you have something like this:
var data = initialData || {} //Or some other default value, in case initialData wasn't set
This will load in the initialData if it was set, or use nothing (or a default your define) if it wasn't. Loosely coupled.
Of course, more complex data will require you to standardize the strucure, but this is essentially one method that allows you to pull in data from the razor generated View without tightly coupling it to your javascript file.
Does your Javascript file contain a view model in the form of an instantiable function, e.g. something like:
function MasterVM(data)
or an object literal, e.g.
var masterVM = { ...
? I tend to go for instantiable view models (partly because they chain down through a hierarchy of view models using the mapping plugin - the top level one builds its children) and that being the case I think it's nice for the Razor view to instantiate the view model with the JSON rendered from the MVC view model, e.g.:
var masterVM = new MasterVM(#(Html.Raw(JsonConvert.SerializeObject(Model.ProductViewModel))));
Or even have the Knockout view model "owned" by a revealing module and initialise it like:
productModule.init(#(Html.Raw(JsonConvert.SerializeObject(Model.ProductViewModel))));
Then productModule is also responsible for other things like mediating between your view model(s) and the server, watching for dirty state, etc.
Also, doing another round trip to the server is not necessarily bad if you are sourcing a massive set of reusable options which you'd like the browser to cache. If you are, you might want to have an MVC controller which emits a big object literal containing all of your commonly used options, which you can then use as the "options" property across multiple selects. But if your options are specific to the particular view model, then I guess they have to be part of your view model.

MVC3 Finding a control by its Name

I have a C#.Net web app and I am trying to access one of the HTML/ASP Text Boxes in the Controller for the Edit View of my Proposal model. In a non-MVC app, I was able to do this using Control.ControlCollection.Find(). Is there an equivalent for a MVC3 project?
You ask for an equivalent of Control.ControlCollection.Find() in MVC?
In MVC your controller is not aware of controls.
The controller just receives data via parameters and returns data via the function result.
What do you want to do with the control in your controller code?
If you want to access the value, you should bind it to a parameter:
View:
<input name="MyControl" type="text" />
Controller:
public ActionResult MyAction(string MyControl) {
// MyControl contains the value of the input with name MyControl
}
The MVC pattern was designed to keep things separated.
The View has no knowledge of the controller at all
The Controller only knows that a view exists and what kind of data that it needs. It do not know how the data is render.
Hence, you can never get information about controls/tags in the view from the controller. You need to use javascript/jQuery in the view and invoke the proper action in the controller.
In an MVC-application you don't have controls like in a webform-application.
In MVC you collect your required data in the controller and pass it to the view.
Typicaly the view is a HTML-page with embedded code.
In opposite to controls in webforms which produce HTML and handles the post-backs in MVC you have to do all this manually. So you don't have controls with properties and events wich you can access easily in the controller and you have to handle all your posts with your own code.
Thats sounds as it is a lot of more work - and indeed it could be if you implement the behaviour of complex controls - but MVC applications are much better to maintain and you have 100% influence to the produced HTML.
Well probably i am late for this but it should help others in future...u can store ur value in hidden field in view and then access that value in controller by following code..
Request.Form["hfAnswerOrder"].ToString();
Point - hfAnswerOrder is the ID of the hidden field
My Control in cshtml page..
#Html.Hidden("hfAnswerOrder", Model.Answers.ToList()[0].AnswerOrder)

How to load a Razor view and render it on the fly?

I have a custom CMS built with ASP.NET WebForms (you can see it in action at Thought Results). Now I want to build it using ASP.NET MVC 3 (or even 4). I don't want to change the architecture that much, therefore, I need to dynamically load a Razor View, and dynamically run a Model Loader method, and give the model to the view dynamically, then render the view, and return the result rendered string, all done in server.
In ASP.NET WebForms, my code is:
string renderedString = "LatestArticles.ascx".LoadControl().GetReneredString();
Now, I'd like to be able to write a code line like:
string renderedString =
"LatestArticles.cshtml".LoadView().BindModel("ModelBinderMethodName").Render();
I know about many questions about rendering a view (view to string), but I didn't find what I want.
You may checkout RazorEngine.

Resources