simple_form selected: by name - ruby-on-rails-3

I have a simple_form collection which contains a list of languages. I want to select 'German' by default, but the selected: option in simple_form requires an id. I could obtain the id of 'German' but would hope that wasn't necessary.
= f.association :language, selected: // not sure what to put here
This works, but stinks (I will NOT be using such atrocious code):
= f.association :language, selected: Language.where("name = 'German'").first.id
I would hope for something like:
= f.association :language, selected: { |lan| lan.name == 'German' }
Every example I've found during the last hour involves the id. Not one example of how to select via the name.

Yeah, SimpleForm can accept proc for selected option. In your case the code is:
= f.association :language, selected: lambda { |lan| lan.name == 'German' }

Related

Filter nil and empty values from an array in rails 3.2

I have a table called Materials and I have created a search form. In the form I want to have select boxes containing the names of the search options. So for example, if you want to search by subject, I want a dropdown with one of each of the subjects. I have code for this that works:
#subject = Material.unscoped.select(:subject).where("materials.subject IS NOT NULL
and materials.subject != '' ").uniq
This gives me what I want with the following form helper:
<%= select_tag "subject", options_from_collection_for_select(#subject, "subject",
"subject"), :include_blank => true, :class => "input_field" %>
BUT - I now want to select only those subjects from Materials that are shared. So I selected the shared Materials using:
#shared = Material.where(:status => 'shared')
And then ran this code:
#subject = #shared.unscoped.select(:subject).where("#shared.subject IS NOT NULL
and #shared.subject != '' ").uniq
Which doesn't work. I assume it's because the sql code can't understand the #shared object. But how to do this?
Note:
I tried using:
#subject = #shared.uniq.pluck(:subject).reject! { |s| s.empty? }
This gives an array of the right fields but then that doesn't work with options_from_collection_for_select.
You can create a scope for the shared query like this:
scope :shared, where(:status => 'shared')
And then you can chain ActiveRecord methods to your liking:
#subject = Material.select(:subject).where("materials.subject IS NOT NULL
AND materials.subject != '' ").shared.uniq
More on scopes here: http://guides.rubyonrails.org/active_record_querying.html#scopes
Try this
#subject = Material.unscoped.select(:subject).where("subject IS NOT NULL and materials.subject != '' and status = 'shared'").uniq

Netzke Grid filtering

I have an issue related to filtering data in Netzke Grid.
column :user_id do |c|
c.editor = {xtype: :combobox, editable: false, min_chars: 2}
end
It is mentioned in the doc that,
A hash that will override the automatic editor configuration. For example, for one-to-many association column you may set it to {min_chars: 1}, which will be passed to the combobox and make it query its remote data after entering 1 character (instead of default 4).
Seems {min_chars: 1} is not working as expected.
Please see example below for simple Customers grid and let me know if it works for you. Netzke way is to use __ (double underscore) to define one-to-many associations. This gives you combobox and all necessary data bindings. I tried different ways to make min_chars property work, but it all failed. Could be a bug. In the end, the only thing that worked is to do it from init_component method.
class Customers < Netzke::Basepack::Grid
def configure(c)
super
c.model = 'Customer'
c.columns = [
{ name: :name, header: 'Customer Name' },
{ id: :country__name, name: :country__name, header: 'Country' }
]
end
js_configure do |c|
c.init_component = <<-JS
function() {
this.callParent();
Ext.ComponentManager.get('country__name').editor.minChars = 2;
}
JS
end
end

Can I add logic to a rails 3 hidden field?

I have a form to submit data and I want to automatically set one field depending on whether all the other fields are filled out or not. If they are all completed, the field will be "complete", if not it will be set to "draft".
So I have the hidden field like this:
<%= f.hidden_field :status, :value => "draft" %>
to make it default to draft. BUT, can I add logic that says it will be "complete" if all the other fields are filled out and if so how?
Here is how to do it on the client-side with jquery, assuming your model is named foo:
<script type='text/javascript'>
$(document).ready(function() {
$('input[name*="otherfields"]').on('change', function() {
var othercount = 0;
$('input[name*="otherfields"]').each(function() {
if ( $(this).is(':checked') )
othercount += 1;
});
if ( othercount == 2 )
$('#foo_status').attr('checked',true)
else
$('#foo_status').attr('checked',false)
});
});
</script>
<%= check_box_tag :item1 , '1', false, :name=>'otherfields[1]' %>
<%= check_box_tag :item2 , '2', false, :name=>'otherfields[2]' %>
<%= f.hidden_field :status, :value => "draft" %>
Assuming no other client-side events have to take place when the the status changes, it would be best practice to place this kind of business logic inside of your model as a callback, e.g. (replace Foo and fieldx with your model and field names):
class Foo < ActiveRecord::Base
before_save :default_status
def default_status
if field1 && field2 && field3 && field4
self.status = 'completed'
else
self.status = 'draft'
end
end
end
Yes, you can do that in the controller.
Lets say the form directs you to the create action.
In the create action of the controller, you can check if all the fields are completed by looking at params and then use if statement to assign appropriate value to status before saving
This would be done with javascript, possibly jQuery. However, why would you design it this way? Could you not do this on the server side?

Rails 3 Load Edit view for a selected row from a DataTable

I have been struggling with this for a while. As well as some specific help I would be grateful for some pointers how I may fill some of the gaps in my knowledge. BTW I am new to Rails and web development.
I have used DataTables to display a table records and have some code which shows me the id of the row selected by the user. From within my index view I want to use that row id to load the edit view for that data row. My .js code is as follows:
$(document).ready(function() {
/* Init the table */
TableTools.DEFAULTS.aButtons = [];
oTable = $("#highways").dataTable({
sPaginationType: "full_numbers",
bJQueryUI: true,
"bProcessing": true,
"bServerSide": true,
iDisplayLength: 25,
sAjaxSource: $('#highways').data('source'),
"aoColumns": [
null,
null,
null,
null,
null
],
"sDom": 'T<"clear">lfrtip',
"oTableTools": {
"sRowSelect": "single",
"fnRowSelected": function ( node ) {
var oTT = TableTools.fnGetInstance('highways');
var aData = oTT.fnGetSelectedData();
var n = '/highways/' + aData[0][4] + '/edit'
alert(n);
var jqxhr = $.get(n, function() {
alert("success");
})
}
},
});
} );
The development log shows:
Started GET "/highways/8/edit" for 127.0.0.1 at 2012-08-21 07:57:14 +1000
Processing by HighwaysController#edit as /
Parameters: {"id"=>"8"}
[1m[35mHighway Load (0.3ms)[0m SELECT highways.* FROM highways WHERE highways.id >= 8 LIMIT 1
Highway BARKLY HIGHWAY
Rendered highways/_form.html.erb (67.1ms)
Rendered highways/edit.html.erb within layouts/highways (258.5ms)
Completed 200 OK in 276ms (Views: 274.6ms | ActiveRecord: 0.3ms)
I have tried various things in the controller code, and in some cases the log says the edit view has been renedered but it does not show in the browser. Current controller code:
class HighwaysController < ApplicationController
respond_to :html, :json
def index
# #highways = Highway.all
# logger.debug "Highway Count: #{#highways.size}"
respond_to do |format|
format.html
format.json { render json: HighwaysDatatable.new(view_context) }
end
end
def edit
# logger.debug "Edit (render :layout => false) Highway ID #{params[:id]}"
#highway = Highway.find(params[:id])
logger.debug "Highway #{#highway.name}"
# render
respond_to do |format|
format.html
format.json { render json: HighwaysDatatable.edit(view_context) }
end
Is the $.get returning JSON ?
I have also tried a different approach. I have a link_to in the index view:
<div id ="highway_edit" >
<% #n = 11.to_s %>
<%= link_to "Edit 2", edit_highway_path(#n), :remote => true %>
</div>
This hard coded version works but I could not find a way to modify that link from within the javascript code so that it reflected the selected row id, or to call a function which would return the row id into the variable #n.
I realize that there must be some fundamentals I am missing so some suggested starting points for my education would be appreciated. I have read many other related questions but do not have enough knowledge to extract what I need.
PS I see that DataTables has an Editor feature which does pretty much what I want to achieve in the long run, but it is not 'Rails ready'.
Thanks!
EDIT:
In preparing this question I did not properly restore my code to the stage I wanted to discuss. So I have changed the controller code and the subsequent development log. So instead of a template error the problem is that the view is not rendered.
EDIT
I have proceeded with this problem and now have a result. I added a new div (class of 'result') to the top of my index view and changed my js code as follows:
var n = '/highways/' + aData[0][4] + '/edit'
$.get(n, function(data) {
$('.result').html(data);
and the edit view is rendered in that div. The result is ugly as it pushes the table down and doubles up the DataTable headers and footer. But at least it renders. I don't understand why this works when both ways go via the Edit method in the controller. I can now work on the cosmetics, or better still have the edit view appear as a modal overlay.
I would prefer to be able to click (or preferably double-click) a row and the edit view for that row be loaded. I will continue to look to do it that way. In the meantime I have added a link to the view:
<div id="EditLink">
<%= link_to "Edit Highway", :controller => :highways, :action => :edit, :id => 1 %>
</div>
and have the following code in the call back function:
"oTableTools": {
"sRowSelect": "single",
"fnRowSelected": function(node) {
var oTT = TableTools.fnGetInstance('highways');
var aData = oTT.fnGetSelectedData();
$("div#EditLink a").attr('href','/highways/' + aData[0][4] + '/edit')
}
},
which modifies the link based on the id of the selected row. Using this method the user has to know to first select a row and then click the link. If they do not first select a row they will go to the default (id = 1). You have to make sure that such an id exists in the table.

jQuery UI Autocomplete in Rails, updating hidden field with ID attribute

I have this in my form, it's really simple:
<script>
$(function() {
var availableProducts = [
<% #products.each do |p| %>"<%= p.id %> <%= p.title %> (<%= p.product_type.name %>)",<% end %>
""
];
$( "#tags" ).autocomplete({
source: availableProducts
});
});
</script>
That gives me lists of things like 1 Title (Trade Paperback). All rails needs of course, is the id attribute. I'd planned on updating a hidden field with the attribute, using the select: event, but I'm not quite sure how to extract just the id from the data source to update the hidden field with. Should I change the data source to something that can have keys? Like JSON? I still wouldn't know how to extract from that.
Here's what the above code looks like in straight html:
<script>
$(function() {
var availableProducts = [
"1 Test Title (eBook)",
"2 Another Test Title (eBook)",
""
];
$( "#products" ).autocomplete({
source: availableProducts
});
});
</script>
Your source should be an array of {value: , label: } pairs. The labels are what will be displayed and autocompleted on, but then you can store the value in a hidden input.
Here's an example:
http://jsfiddle.net/vZeHr/4/
and check out this sample on the jquery-ui docs page
http://jqueryui.com/demos/autocomplete/#custom-data
To generate the array from rails, you can do something like
var availableProducts = <%= #products.collect { :label => p.title, :value => p.id }.to_json ->;