Rails web application control panel with ajax tabs and validation - ruby-on-rails

I'm looking to build a rails web app with an admin control panel. I'd like the control panel to use a tabbed interface for controlling users, projects, tasks etc, and I'd like to switch between tabs using jquery tab UI controls with ajax. Also using restful authentication for users and my own code for projects, tasks etc.
Here's what I can't wrap my head around. Normally, I'd have a controller for each tab, so validation is simple, if there's an error (say in the user) i just render the proper action with the object and it's errors and we're set. However, if I'm not refreshing (to different controllers between tabs) how does this work? Do I need to have one massive controller with all the user, project, task validation and controls (ie. crud operations)? Seems like not the greatest design.
Or is there some way I can use an 'admin' controller that encompasses separate controllers for proper crud/error checking etc.
Hope this makes sense?

I would make the contents of each tab be called in by a separate ajax request. This would give you the following benefits
Now each tab can easily be a different view/controller
You only need to load the contents for a tab when it is used; you won't be processing code/downloading html for tabs that the user doesn't use.
If you don't want to use this route, (i.e. you feel you need to load all the contents of the tabs on page download in a single request) then you could separate out the code using helper methods and partials. See my answer here: Rails Sub-controllers?

I would personally use inline validation in the forms. Jquery does that pretty well , but there are a lot of library that can help you with that.
I guess it's not exactly what you were looking for, but it would make your job easier. Of course still keep validation in the models so that no one can bypass the validation (using firebug or something like this)

Related

Rails best practice when embedding a signup form on every page

I have a User model with some validations behind it.
What I'd like to do is have a signup form on every page of the app, even the mostly static ones.
I figured the best way to do this would be through helper methods in application_helpers.rb, which works fine, but validations don't seem to work.
I can also serve the form through an iframe, but that seems a bit hacky.
I'm using partials now, but my client side validation (github.com/bcardarella/client_side_validations) only works on the /new page, not the application page.
What's the best practice in this case?
I would recommend extracting the signup form into a shared partial, which you then explicitly could render wherever you want it.
One could render the signup form directly in the layout file (app/views/layout/application.html.erb) if the placement is static no matter of what page you're currently on.
One of the basic solutions is to use partial. The benefit is: it's built in, it's simple. The downside is: You'll be busy to feed it some session details for proper rendering.
Another solution is to use Cells for this kind of case.
Cells works like a lightweight controller which can do anything a controller can do, and it's independent on any controller. One good use case of Cells is shopping cart, and login form is also a good use case in my opinion.

Writing modular pages with ASP.NET MVC 4

I'm developing ASP.NET MVC 4 application, that will be used to configure a complex application. I want to have one configuration page, with multiple tabs. Each tab will be used to configure a different part in the system, and when you click on it the right form (each configuration tab will be a different partial view) will be loaded with AJAX. I want to have "Save Changes" button in the bottom of the page, that will save the changes from the whole tabs.
Since the system itself is modular, I want to make the configuration site modular too. Which means, that i want each tab to be some kind of a plugin that expose to me the following methods (by inheriting from an interface): GetConfigurationPartialView (which will return the partial view with the view model for this tab), SaveChanges (which will save the configuration to the DB as a draft), and GetConfigurationXml which will export the full XML configuration and apply it on the system.
My questions are:
What do you think about that design? do you have better ideas?
How do you recommend to implement this one "Save Changes" button in the main view? How can I iterate all of my plugins and call each plugin's SaveChanges method, pass it the correct model object (which is the partial view's model) filled with all the data without having intimate knowledge of each plugin object in the main controller/view so i can keep this system easy to extend?
Some of the tabs includes grids with data. i started looking into Kendo UI grid. I want to let the user do everything on the grid, in the client (deleting and add new rows), and then i want in the SaveChanges method i wrote about to get list in the server side of all the changes that the client did (for example, in pseudo code: changes[0]={Action = Delete, ProductID = 1}, changes[1]={Action=New, ProductID=1, Name="aaa" }). How can i do it?
Thanks.
Just make a partial view for each configuration page and load it as needed. I concur KISS is best.

ASP.NET MVC structure and how to use the Actions and Controllers

I am developing an application in ASP.NET MVC structure.
I was wondering, I am trying to create a site that only has one page, it has a navigation bar on the left (Which is a list of user input), and then the main content in the middle.
My question is, can I make the navigation bar (The user input list) static, and make the main content change, based on the user input, with an asynchronous AJAX postback? I would have multiple controllers which would set different results to the main content, based on the user input.
How would I go around doing so, partial views and calling actions with asyncpostback's?
Yes, I would do exactly as you have suggested - have actions that render PartialView([name]) and use, probably, jQuery's ajax to fetch the content.
You can then use jQuery to inject the html into the content panel.
Where it might get interesting is if you need to have css added to the head section of the page.
But then, with diligent use of a single CSS, or at least a single group of CSS files, you can sidestep that.
Be aware though, that it does complicate form post-backs if the dynamically injected content has forms. You would need to hijack the form submit process and turn it into another ajax call to get the resulting html into your content panel - you might even need to hand-crank the form submission because I don't think you can trigger form submission as an Ajax operation.
I've done a similar thing with named iframes (doesn't necessarily need script), as you can render a form with a target which is equal to the name of an IFrame; and it means that the iframe content can be a full view instead of a partial (and therefore has full control over its own script and css). Of course, then you have issues with sharing data between the host page and that frame.

ASP.NET MVC Controller design

I have a question about how to design my controllers properly.
Project is fairly simple: blog, immage gallery with categories and images inside them, news secion.
However I don't know how to organize my controllers for this because I want to make somewhat admin panel where administrators can edit, add and modify these things. I've came up with 3 scenariosu so far...
Admin panel will have links to site/controller/edit, but layout for these action results will be different from standard one.
Admin controller will have all these actions like BlogAdd, BlogEdit so that url will be something like /site/admin/blogedit.
Create copies of Blog controller in admin folder so url will be like /site/admin/blog/edit - i sense problems with routing since 2 controllers with same name does not sound like a good idea, however I like ho URL looks in this situation.
What I'm trying to make is CMS somewhat similar to wordpress, where blog creation,editing and deletion is completely separated from default blog itself.
I suggest you stop thinking about URLs and Controllers being a 1->1 relationship. This will make things MUCH easier and less confusing. You can make the URLs work however you want with MVC's routing mechanism and there's no reason to restrict your controller design/organization because of the URLs you want, because you can always adapt the routing to with with the URLs you have in mind.
While building the website, just focus on the controllers (and the general interface) and ignore the URLs until you get to that point, and then when you come up with a good URL scheme go into the routing system and add the routes to connect to your existing controller actions as you want.
Once you code out your blogging engine you will have a much better idea of the user workflow and will probably find different ways to organize your URLs, and you can then reorganize your URLs without touching the controllers themselves.
As to your first requirement:
There are two ways to do this depending on your end goal. If your goal is to display the same core content, but have different user options available (different overall layout, additional buttons on the page, etc..) then the best idea is really to just pass in an IsAdministrator property in your view model, and make the slight changes to the page based on if that's true or false. The reason is because you still (most likely) want the core of the page to be the same, and this keeps you from duplicating code that is related to the core data (data that's being displayed for both admins and non-admins).
Edit: So in summary, organize your controllers based on what makes it easier to develop with, not based on how the user interacts with the system with. You can always change the latter, changing the former is harder and will make maintenance annoying.
You can create Areas in your MVC project and have your admin functionality in a controller in your admin area.
This will allow you to easily seperate your administration functionality from your general blog functionality.
That's how I'd do it.
Why don't you keep the routes the same and handle the different roles via security? For example:
/blog/name-of-topic/view to view a topic (all users)
/blog/name-of-topic/edit to edit a topic (only enabled for logged in users)
/blog/add to create new topics (only enabled for logged in users)
You can handle these actions in a single controller and decorate the actions that require logged users via the [Authorize] attribute. Same thing with the links on your views, you would enable the links to edit and add topics only to visible users.
You could still have a separate panel to allow admins to hit the aforementioned add/edit links .

HTML Submit button vs AJAX based Post (ASP.NET MVC)

I'm after some design advice.
I'm working on an application with a fellow developer. I'm from the Webforms world and he's done a lot with jQuery and AJAX stuff. We're collaborating on a new ASP.MVC 1.0 app.
He's done some pretty amazing stuff that I'm just getting my head around, and used some 3rd party tools etc. for datagrids etc.
but...
He rarely uses Submit buttons whereas I use them most of the time. He uses a button but then attaches Javascript to it that calls an MVC action which returns a JSON object. He then parses the object to update the datagrid. I'm not sure how he deals with server-side validation - I think he adds a message property to the JSON object. A sample scenario would be to "Save" a new record that then gets added to the gridview.
The user doesn't see a postback as such, so he uses jQuery to disable the UI whilst the controller action is running.
TBH, it looks pretty cool.
However, the way I'd do it would be to use a Submit button to postback, let the ModelBinder populate a typed model class, parse that in my controller Action method, update the model (and apply any validation against the model), update it with the new record, then send it back to be rendered by the View. Unlike him, I don't return a JSON object, I let the View (and datagrid) bind to the new model data.
Both solutions "work" but we're obviously taking the application down different paths so one of us has to re-work our code... and we don't mind whose has to be done.
What I'd prefer though is that we adopt the "industry-standard" way of doing this. I'm unsure as to whether my WebForms background is influencing the fact that his way just "doesn't feel right", in that a "submit" is meant to submit data to the server.
Any advice at all please - many thanks.
The thing you need to take into consideration is how the application will work if javascript is not available. You should strive to ensure that the basic functionality works without it. This is called progressive enhancement or unobtrusive javascript and is considered a best practice.
http://en.wikipedia.org/wiki/Progressive_enhancement
The way you should do it is to use a form with a real submit button and then hijack that form to use ajax if the User Agent supports it. This is usually pretty trivial to do using the jquery forms plugin. In your action method, you can check to see if the incoming request is an ajax request by checking the Request.IsAjaxRequest property. This is set by MVC automatically on requests that have the X-Requested-With header set to XMLHttpRequest. Then you would return a full view or just some json based on that.
Here's a short screencast demonstrating this: http://www.youtube.com/watch?v=YQsFR1rkgMU&feature=player_embedded
Both solutions are viable, though using submit buttons will make your application more accessible (i.e. JavaScript will not be required in order to use it).
You could also do the both - start with a page that has all the necessary logic using postbacks, and "upgrade" it with nice AJAX-y requests and animations. This way, users with JavaScript will get the eye candy, and the page will gracefully degrade when when a user without JavaScript visits the page, falling back to the postback mechanism.

Resources