I have a time field which stores an integer(minutes). I want the user to be able to enter in days, hours and minutes in the form rather than entering minutes.
.form-group
= f.label :time, class: "col-sm-2 control-label"
.col-sm-10
= f.text_field :time, class: "form-control"
Is there an easy way to do this via the form so that I would have...?
.form-group
= f.label :days, class: "col-sm-2 control-label"
.col-sm-10
= f.text_field :days, class: "form-control"
.form-group
= f.label :hours, class: "col-sm-2 control-label"
.col-sm-10
= f.text_field :hours, class: "form-control"
.form-group
= f.label :minutes, class: "col-sm-2 control-label"
.col-sm-10
= f.text_field :minutes, class: "form-control"
I realise I could just have days,hours and minutes as database fields but I'd rather just keep my single time field.
Came across a similar situation, this is what helped me.
gem time_splitter
Looks like this will accomplish the job for you as well, simply runs on top of whatever datetime fields you have for your model.
You could hide the time field and have your days, hours and minutes field showing and use javascript to calculate the time in minutes based on the values provided on the fields that are showing and just submit that.
so it would be something like (and this is pseudo code):
time.value = (days.value * 1440) + (hours.value * 60) + minutes.value.
Related
I'm building a rails application and want to add a time tracker. The users should be able to log a time (I worked for 3 hours) and submit, or they should be able to start a timer, wait, and then submit. I picked VueJS to build it out, and successfully have integrated Vue with my Rails 5 application.
I built out a simple timer (start, stop, display current time) within Vue and embedded in my page. Now I want the user to fill out some additional fields and save the time entry.
I've attempted to just take the values for the hours, minutes, and seconds from the Vue data and connect it using v-models to a basic simple_form time field, but since rails automagically generates the input fields as time_entry_duration_4i and time_entry_duration_5i, I'm struggling to connect the data.
Should I even go about pushing the JS data into a rails form? Should I just rebuild the form so it's all in Vue and always submitted that way?
Thanks.
#time_entries/_form.html.haml
= simple_form_for(#time_entry) do |f|
= f.error_notification
= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present?
.form-inputs.row
.col
= f.association :project, collection: Project.joins(:assigned_roles).where(assigned_roles: {team_member: current_user}).distinct, hint: "If this is blank, you're not currently assigned to any projects."
= f.input :task, collection: TaskType::TASK_TYPES.sort {|a, b| a <=> b }
.form-inputs.row
// This is the Rails way of doing things and works, but I can't connect it to the v-model
= f.input :duration, as: :time, wrapper_html: { class: 'col-6'}, default: Time.parse('0:00')
.col-6.form-group
.d-flex.flex-row.justify-content-between
= f.label :duration, label: "Hours"
= f.label :duration, label: "Minutes"
= f.label :duration, label: "Seconds"
.d-flex.flex-row.justify-content-between.align-items-center
// This is my attempt to recreate the hours/min/seconds and bind to the v-model, but it doesn't submit
= f.text_field :duration, "v-model" => "hours", class: 'form-control mx-1'
= f.text_field :duration, "v-model" => "minutes", class: 'form-control mx-1'
= f.text_field :duration, "v-model" => "seconds", class: 'form-control mx-1'
= f.input :date, wrapper_html: { class: 'col-6'}
.form-inputs.row
.col
= f.input :notes, placeholder: "What were you working on?"
.form-actions
= f.button :submit, class: 'btn btn-primary btn-block'
You can mix rails and Vue by writing the inputs with plain html:
.col-6.form-group
.d-flex.flex-row.justify-content-between
= f.label :duration, label: "Hours"
= f.label :duration, label: "Minutes"
= f.label :duration, label: "Seconds"
.d-flex.flex-row.justify-content-between.align-items-center
input type="text" name='time_entry[duration(4i)]' v-model="hours" class='form-control mx-1'
input type="text" name='time_entry[duration(5i)]' v-model="minutes" class='form-control mx-1'
input type="text" name='time_entry[duration(6i)]' v-model="seconds" class='form-control mx-1'
Hi in Rails how to display text_field values. In my index file I am trying display my values in text_field_tag but here is i am getting values in this format
considering bellow code
1) {:value=>2}
2) {:value=>0.3e2}
But I just want to display in text_field_tag values as
considering bellow code
1) 2
2) 300
How should i reformat it?
is there any other text_field(I don't want to use it in form field this is just index file for display values I don't want to submit it)
<div class="col-xs-4 col-sm-3"><%= text_field_tag :amount, value: 2 %></div>
//or
<div class="col-xs-4 col-sm-3"><%= text_field_tag :amount, value: expense.amount %></div>
Thanks a lot for your valuable answer :)
As mentioned here, text_field_tag accepts the second argument as the value to field. So, pass the value directly (instead of passing it as a hash):
<%= text_field_tag :amount, 2 %>
Because you are getting hash value as {:value=>2}
also you can convert it to integer
expense[:value].to_i
2.3.4 :003 > 0.3e2.to_i
=> 30
<%= text_field_tag :amount, expense[:value].to_i, class: "your_class", placeholder: 'some placeholder' %>
In case if you want static value
<%= text_field_tag :amount, 2, class: "your_class", placeholder: 'some placeholder' %>
In case if you want to put it in form but not to be submitted make is disable
<%= text_field_tag :amount, expense[:value].to_i, disabled: true, class: "your_class", placeholder: 'some placeholder' %>
Note: disabled field are not to be subjected to submit with form data, however :readonly => true will be wrapped with form datas
in other case just put this field outside the form
I am trying to add a boolean attribute (third_party) to my current collection_select that currently just shows name:
<div class='form-group'>
<%= f.label :project_component_id, class: "form-label" %>
<%= f.collection_select :project_component_id, issue.project.project_components.order("LOWER(name)"), :id, :name, {include_blank:true}, class: "form-control input-sm" %>
</div>
How would I append third_party so that each select option is shown as "name(third_party)"?
Thanks!
You can create an instance method in your model which interpolates the attribute you need with the extra text and pass it as the fourth option to your collection_select helper:
I assume is called ProjectComponent, so:
class ProjectComponent < ApplicationRecord
def name_with_thirdparty
"#{name}(#{third_party})"
end
So in your view:
<%= f.collection_select(
:project_component_id,
issue.project.project_components.order("LOWER(name)"),
:id,
:name_with_thirdparty,
{ include_blank: true },
class: 'form-control input-sm') %>
I have problem with showing an error to date field with simple_form.
I have the following code in my registration form:
.row
.col-md-6.col-md-offset-3
%fieldset
%h2 Rejestracja
%hr.colorgraph/
= simple_form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f|
= f.error_notification
.form-group
= f.input :username
.form-group
= f.label "Birthdate"
%br
= f.date_select :birth_date, end_year: 1950, start_year: (Time.now.year - 18)
.form-group
= f.input :email
.form-group
= f.input :password
.form-group
= f.input :password_confirmation, :required => false
.row.center
.col-xs-6.col-sm-6.col-md-6.center
= f.button :submit, "Submit", class: "btn btn-lg btn-success btn-block"
And the following validation of age in my user model:
validate :at_least_18
def at_least_18
if self.birth_date
errors.add(:birth_date, 'You must be 18 years or older.') if self.birth_date > 18.years.ago.to_date
end
end
The problem is that when i submit the form with valid birth_date, simple_form does not show the error like on the other fields:
But when i change
= f.date_select :birth_date, end_year: 1950, start_year: (Time.now.year - 18) to
= f.input :birth_date
It is working but now i have three ugly fields...
Any ideas?
This is caused by the CSS styling of inputs with errors.
You could fix this by adding some CSS to correctly style the dropdowns, however I think that fundamentally you would be better off replacing the 3 dropdown boxes with a single text field and using something like jquery's date picker to populate it.
Not only will that give your users a far better date-inputting experience, but your error layout issue will also be fixed.
When user clicks AddDate in my event planning app, I add a row as seen below so user can add a date and start/end time, and AM/PM.
But in my form using nested attributes, it seems my select controls need a reference to the model field they set (:start_time and :end_time). But the start and end times are create from TWO select controls, one for the hours and one for the minutes. So I'm not sure how the values chosen in the two selects will be combined to form the start and end times.
<div class="user_event_inline_container margin_left_ten padding_right_gone">
<%= f.label :start_time, "Start", class: 'info_inline_control info_label five_margin_right' %>
<%= f.select :start_time, options_for_select([['1',1],['2',2],['3',3],['4',4],['5',5],['6',6],['7',7],['8',8],['9',9],['10',10],['11',11],['12',12]]), class: (field_class(#user_event, :start_time) + 'info_inline_control') %>
<%= f.select :start_time, options_for_select([['00',1],['15',2],['30',3],['45',4]]), class: (field_class(#user_event, :start_time) + 'info_inline_control') %>
<%= f.select :start_am_pm, options_for_select([['am',1],['pm',2]]), class: (field_class(#user_event, :start_am_pm) + 'info_inline_control') %>
</div>
<div class="user_event_inline_container margin_left_ten padding_right_gone">
<%= f.label :end_time, "End", class: 'info_inline_control info_label five_margin_right' %>
<%= f.select :end_time, options_for_select([['1',1],['2',2],['3',3],['4',4],['5',5],['6',6],['7',7],['8',8],['9',9],['10',10],['11',11],['12',12]]), class: (field_class(#user_event, :end_time) + 'info_inline_control') %>
<%= f.select :end_time, options_for_select([['00',1],['15',2],['30',3],['45',4]]), class: (field_class(#user_event, :end_time) + 'info_inline_control') %>
<%= f.select :end_am_pm, options_for_select([['am',1],['pm',2]]), class: (field_class(#user_event, :end_am_pm) + 'info_inline_control') %>
</div>
Why don't you use a time_select instead?
Doing it this way, you'll need to merge them manually in your controller using params[] values and Date.parse().
You can also try using f.time_select, which should function as a normal field after you submit.
Might find this useful: Where is the Rails method that converts data from `datetime_select` into a DateTime object?
Personally, I write custom interfaces for my date fields using jQuery plugins and then use javascript to merge all the fields into a hidden field that actually gets submitted.