Adding disable to certain select options in simple_form - ruby-on-rails-3

A user can chose 5 options. Once they choose one, they can not choose it again. Currently, I simply remove previously used options from the list...so, they can only choose from previously unused ones. The only thing I don't like about this is that as the user is adding a new record to the database, they might wonder why options seem to be missing from the list.
One idea I had was to leave previously used options in the list but cross them out and make them disabled.
Is it possible to disable (and/or add a class) to only certain options in a select? Simple_form seems to have an option_html helper but, didn't see it documented.

Turns out this is quite easy to do. Rails supports it...
<%= f.association :ying, collection: #yangs, :disabled => #used_yangs %>

It works for me only when I pass ids into disabled option. Like this:
= f.association :stuff, disabled: Stuff.where(enabled: false).map(&:id)
Using Rails 4.2.3
It's correct regarding Rails docs. Check :disabled description here: http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html

Related

Redmine: Copy issue multiple times

Copying one issue and its child issues is a natively built-in feature and thus works just fine.
But is there a way to do this multiple times?
Like re-creating one issue (including its children) twenty or fifty times?
Edit 2
This new functionality should be accessible via the Redmine interface and compatible to any browser.
It does not matter whether it is a completely new Plugin, an extension to the built-in copy feature, a call to a PHP-script or anything else.
Due to compatibility (networking, browsers etc.) I guess a completely server-side modification is the only way to go here.
What parts of the default plugin (as created in the voting tutorial) or a core element would have to be changed?
Where can I find the code for the native issue copy function?
Or - if all this is too complicated - how would I write my plugin to point to a PHP file that manipulates the SQL database directly?
Edit:
To clarify: just like the normal copy function (either in the context menu or the top-right link, I don't care) I want to copy one issue and its sub-issues n times.
To let the user set the amount n, any user number input may suffice, like a textbox, a pop-up etc.
I think the simplest way to do this is to start with redmine source modification.
Once it works you can move on and try to extract this feature into plugin.
Note, that I am not a ruby developer, so some things below are just my guesses. But I did few small redmine modifications like this before and hope that my thoughts can be useful.
It will also be easier if you familiar with some of MVC frameworks (for any language), because they mostly have a similar structure with routes, controllers, views and models.
The Idea
The link to copy single issue looks like this: //redmine.myserver.com/projects/myapp/issues/12407/copy.
My idea is to add a num_copies parameter to this link and use it in the code to create many copies.
You need no UI for that, once implemented the feature will work like this:
find the issue you need
choose the copy action for it
once the form opened, manually add ?num_copies=XX parameter into the URL (//redmine.myserver.com/projects/myapp/issues/12407/copy?num_copies=50) and press 'Enter' to reload the form
check the details and submit the form - it will create multiple copies according to the num_copies parameter
The Implementation Plan
Now, how to do this.
I am referring to the redmine mirror on github which looks fresh.
1) Find where the .../copy link is handled
When you open the form to copy the issue, you'll see form like this:
<form action="/projects/myapp/issues" class="new_issue" id="issue-form" method="post">
<input id="copy_from" name="copy_from" type="hidden" value="12407">
<div class="box tabular">
<div id="all_attributes">
...
</form>
Note the form action, it points to the /issues link and it will submit the copy_from parameter (this is ID of the issue we are copying).
2) Find the code which handles the form submission
We could first go and check through the config/routes.rb, but we can just guess that we need the controllers/issues_controller.rb
Search for the place where copy_from parameter is used.
You'll see the build_new_issue_from_params method.
Now search for its usages and you'll find this:
before_filter :build_new_issue_from_params, :only => [:new, :create]
From how it looks, I guess that it is called before both new and create actions.
Looking at new and create definitions, the new action renders the new issue form and the create action handles the form post.
3) Add the num_copies parameter to the form
Find the view file used by new issue action.
Here there is a template for the new issue form, try to add num_copies parameter similar to the copy_from:
<%= title l(:label_issue_new) %>
<%= call_hook(:view_issues_new_top, {:issue => #issue}) %>
...
<%= error_messages_for 'issue' %>
<%= hidden_field_tag 'copy_from', params[:copy_from] if params[:copy_from] %>
Here I am not 100% sure if it will just work if you add a similar line for `num_copies. You may also need to modify the route.
When done, you should have the new issue form like this:
<form action="/projects/myapp/issues" class="new_issue" id="issue-form" method="post">
<input id="copy_from" name="copy_from" type="hidden" value="12407">
<input id="copy_from" name="num_copies" type="hidden" value="50">
<div class="box tabular">
<div id="all_attributes">
...
</form>
4) Handle the num_copies parameter
It should be done in the create action:
def create
...
call_hook(:controller_issues_new_before_save, { :params => params, :issue => #issue })
#issue.save_attachments(params[:attachments] || (params[:issue] && params[:issue][:uploads]))
if #issue.save
...
end
Here you already have the #issue variable created in the build_new_issue_from_params method and what you need to do is to check if num_copies parameter is set and if it is set then copy / save the #issue in a loop to create additional copies.
I can't provide the exact code snippet for this, but it should not be very complex.
Check this code in the bulk_update method, it looks like what you need:
issue = orig_issue.copy({},
:attachments => copy_attachments,
:subtasks => copy_subtasks,
:link => link_copy?(params[:link_copy])
)
I think this specific plugin is not high priority for Redmine community.
But, you can write very easy API calling for Java, Python or other language to do what you exactly want.
Here, you can see API documentation how to list, create, update issues.
Issue API documentation
PS: You can leave your request in redmine community,
maybe you are lucky https://redmine.org/projects/redmine/issues

How do you edit Devise error messages?

To be clear, I know how to edit the error messages in config/locales/devise.en.yml but I'm referring to styling these type of error messages:
2 errors prohibited this user from being saved:
Email can't be blank
Password can't be blank
--
All i see is <%= devise_error_messages! %> on the sign-up page, but I don't know how to actually edit the error messages themselves.
In my case the messages appear on the left, and my sign up is centred (which looks odd), I also don't like the red color of the messages and would prefer a different color.
So my question is, how can I style the error message? centre it, and change the color.
Not sure which other controllers or contents to include so as soon as you ask, i'll update the OP with them if need be.
See the sources for the devise_error_messages! method at https://github.com/plataformatec/devise/blob/master/app/helpers/devise_helper.rb.
All the errors are inside
<div id="error_explanation">
so you can use that fact in your CSS. Inside it uses only basic styling: h2 for the header message, ul for the individual errors. See this SO example for #errorExplanation styling, for example: how to beautify validations in rails. Just don't forget to replace #errorExplanation with #error_explanation in the example.
But your best approach would probably still be to rewrite this method or write and use your own, and there apply all the styling you like.
I'd personally recommend displaying errors next to the fields they belong to. See this SO thread, for example, on how to do that: Rails: Errors close to particular fields in forms.
Another improvement would be switching to simple_form for your forms (and getting errors-next-to-fields for free). See, for example, an excellent Railscast on that: http://railscasts.com/episodes/234-simple-form. There's a more recent revised Railscast, but not sure if you're a Pro subscriber there.

Creating a Rails partial that is model-agnostic

I have the two Ruby on Rails models SafetyTest and TeamDue, and want to create a partial called _seasonal.html.erb that can work with either models.
The real problem is adding a link to create a new instance. For example, it would be this code for just SafetyTest:
<%= link_to new_safety_test_path %>
Now I want to be able to specify in my view, when I'm rendering _seasonal.html.erb, whether I want such a link for SafetyTest or TeamDue . I'm not sure what local to pass to this partial so that it creates the right new link without making a mess.
How should I go about doing this?
Take a look at Polymorphic URL helpers.

Rails 3.1 simple_form renaming fields w/o i18n

I've been starting to use simple_form in my rails application, which is quite nice. But I was not able to find a function which allows me to rename a field, without the use of i18n.
I have a radio button in my formular, which allows to choose the delivery type. Controlled by that a few fields need a different naming (but its still the same field with the same information).
(e.g. there's a delivery note which is called weight note or notification depending on the delivery type, but contains the same information).
I checked the readme, the railscast and searched a lot but didn't find a build-in way to do that. One option of course would be to create a special locales file just for that, but that feels a little over the top.
I found my answer in a different question regarding simple_form. After looking for that part in the readme, I also found it there.
<%= simple_form_for #user do |f| %>
<%= f.input :username, :label => 'Whatever name you want..' %>
<% end %>
This also overwrites the name given in the i18n file.

Setting Formtastic as Rails 3 default form builder, is it possible?

Something like this in application.rb:
# Configure application generators
config.app_generators do |g|
g.form_builder Formtastic::SemanticFormBuilder
end
If I do so I get an error when I try to scaffold a model:
Expected Thor class, got Formtastic::SemanticFormBuilder
Is it possible to set Formtastic as default form builder?
Updated.
I have tried Simple forms and it's really awesome (Thanks to nathanvda). The DSL is almost the same as Formtastic has. The only important difference for me is in customizing button labels. In formtastic it's possible to use resource file (formtastic.yml) to set different labels for the same model and action. Sometimes it's necessary, for example in Devise views. But it costs nothing to switch from formtastic to simple forms even in this case as it's possible to do it in this pretty simple way:
= f.submit t("customized_button_label")
Now about the original question. When I installed simple forms it creates template in lib/templates/haml/scaffold directory which will be used with scaffold. Straightforward.
I am not entirely sure about formtastic, either it does this straight out of the box, so not configuration needed; or not at all.
But what i do know: simple_form does provide scaffolding, even configurable which is totally awesome. The DSL between formtastic and simple_form is close to identical, but with simple_form the level of configuration is much better. You have total control how a form should be scaffolded, you have total control how a single field is turned into html. Pretty awesome.
You can find a quick introduction here.