How to use material design text fields in rails - ruby-on-rails

I am looking to use material design text field in rails in order to have the field's placeholder shifting to the top when the user start typing.
I do get the field to show up properly in rails straight from the example, but I DO NOT KNOW HOW TO ADAPT IT TO RAILS simple_form component.
application.html.erb
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<link rel="stylesheet" href="https://code.getmdl.io/1.3.0/material.indigo-pink.min.css">
<script defer src="https://code.getmdl.io/1.3.0/material.min.js"></script>
in my form.html.erb
<%= f.input :title, label: false %>
<%= f.collection_select(:color, Color.all, :id, :name) %>
It shoudl look like this:
<form action="#">
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
<input class="mdl-textfield__input" type="text" id="sample3">
<label class="mdl-textfield__label" for="sample3">Text...</label>
</div>
</form>

I haven't use simple_form before, but looking at the docs, something like this should work.
<%= simple_for_form #user do |f| %>
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
<%= f.input_field :username, input_html: { class: 'mdl-textfield__input'} %>
<%= f.label :username, input_html: { class: 'mdl-textfield__label'} %>
</div>
<% end %>
If you want to create the whole div with just f.input_field you could look into custom inputs
You might be able to do something like this inside of a custom input
template.content_tag(:div class: 'mdl-textfield mdl-js-textfield mdl-textfield--floating-label') do
# text_field_input_code
# label_input_code
end

When I get you right, you are looking for "Float Labels"
This can normally be achieved with a mixture of JS and CSS, like described here.
In my own Rails application, where I also use simple_form, I have used the following code to achieve this pattern:
JS (jQuery):
// FLOATING LABLES:
$(document).on('turbolinks:load', function () {
$('.form-group.string').addClass('float-labels'); // removes all labels from the form (removing with js due to old browsers & disabled JS)
$('.form-group.string input.form-control').each( function (index, value) {
addRemoveFloatLable($(this)); // bring back labels for already filled forms (edit).
});
});
$(document).on('input keyup', '.form-group.string input', function () {
if( $(this).val().length <= 1 ) { // change only needed in case first char gets added (or latest gets removed)
addRemoveFloatLable($(this));
}
});
function addRemoveFloatLable($element) {
if ( $element.val() == '' ) { // input field is empty.
$element.parents('.form-group').removeClass('show-label');
} else {
$element.parents('.form-group').addClass('show-label');
}
}
CSS:
.form-group.string.float-labels {
label {
opacity: 0;
}
}
.form-group.string.float-labels.show-label {
label {
opacity: 1;
-webkit-transition: opacity 0.3s linear;
transition: opacity 0.3s linear;
}
}

I would like to recommend this tutorial, I have followed it and it works fine for me... hope this helps,
https://www.webascender.com/blog/tutorial-using-materialize-ruby-rails-simple-form/
Also have a look at
how to style simple_form with material design or custom css

Related

Open a text box when other is selected in dropdown list in rails

I have a table "fundings" in which there is a field "status", for which i have a select field in the form. The options for this select field are ["approved", "declined", "pending"]. What i want is when "declined" is selected, a further text box shows to explain the reason for decline. Please help how can this be done.
<%= form_for([#parent, #child, #funding], :html => {class: "form-horizontal",role: "form"}) do |form| %>
<div class = "form-group">
<div class="control-label col-sm-2">
<%= form.label :status %>
</div>
<% if current_user.admin? %>
<div class="col-sm-8">
<%= form.select :status,['Pending', 'Approved', 'Declined'], class: "form-control" %>
</div>
<% else %>
<!-- Disabled for non-admin users -->
<% end %>
</div>
<!-- Submit button here -->
<% end %>
Update
<div class="form-group">
<%= "Status" %>
<%= form.select :status, ['Pending', 'Approved', 'Declined'], {}, id: "sample-status-select", class: "form-control" %>
</div>
<div class="form-group">
<%= "Decline Reason" %>
<%= form.text_area :decline_reason, class: "form-control hidden", id: "decline-reason-textarea" %>
</div>
</div>
<div class="form-group">
<div class="col-sm-10">
<%= form.submit "Apply", class: 'btn btn-primary btn-lg' %>
</div>
</div>
</div>
</div>
<% end %>
<script type="text/javascript">
<plain>
$(function() {
$("#sample-status-select").on("change", function() {
var select_val = $(this).val();
console.log(select_val);
if (select_val === 'Declined') {
$("#decline-reason-textarea").removeClass("hidden");
} else {
$("#decline-reason-textarea").addClass("hidden");
$("#decline-reason-textarea").val("");
}
});
});
</plain>
</script>
$(function() {
$("#sample-status-select").on("change", function() {
var select_val = $(this).val(); // this gets the value of the dropdown menu
console.log(select_val); // this just displays the selected value in the browser console (if you have the browser console open)
if (select_val === 'Declined') {
// if the 'Declined' option is chosen
// we remove the 'hidden' class from the textarea
$("#decline-reason-textarea").removeClass("hidden");
} else {
// if any other option is chosen
// we put back the 'hidden' class to the textarea
// also, we update the textarea value to BLANK (this part is optional, it depends if you want to keep the value of the textarea)
$("#decline-reason-textarea").addClass("hidden");
$("#decline-reason-textarea").val("");
}
});
});
.hidden {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form action="https://httpbin.org/post" method="post">
Status
<select id="sample-status-select">
<option value="Pending">Pending</option>
<option value="Approved">Approved</option>
<option value="Declined">Declined</option>
</select>
<br>
<br> Decline Reason
<textarea id="decline-reason-textarea" class="hidden">
</textarea>
</form>
Check this snippet I made. It should work for you as well.
This is a basic html form so this works even without ruby on rails.
After you get the gist of this, you should be able to port for it to work with your rails app.
<script type="text/javascript">
$(function() {
$("#sample-status-select").on("change", function() {
var select_val = $(this).val();
console.log(select_val);
if (select_val === "Declined") {
$("#decline-reason-textarea").removeClass("hidden");
} else {
$("#decline-reason-textarea").addClass("hidden");
$("#decline-reason-textarea").val("");
}
});
});
</script>

How to display the button in one line after the input tag, which is embedded in a div block?

For nested forms I use gem coocon.
I have next view
_poll_item_field.html.erb
.poll_row
.poll_item
= f.input :answer, input_html: { class: 'ctrlenter expanding' }, label: false, placeholder: 'Введите вариант ответа'
= button_tag 'Up', class: 'btn btn-bg', id: 'up_id', type: 'button'
= button_tag 'Down', type: 'button', class: 'btn btn-bg', id: 'down_id'
= link_to_remove_association "delete", f, { wrapper_class: 'poll_item' }
Generated html
<div class="poll_item">
<div class="control-group string required blog_post_poll_poll_items_answer">
<div class="controls"><input class="string required ctrlenter expanding" display="inline" id=" blog_post_poll_attributes_poll_items_attributes_0_answer" margin="0" name="blog_post[poll_attributes][poll_items_attributes][0][answer]" placeholder="Введите вариант ответа" size="50" type="text">
</div>
</div>
<button class="btn btn-bg" display="inline" id="up_id" name="button" type="button">up</button>
<button class="btn btn-bg" display="inline" id="down_id" name="button" type="button">down</button>
<input id="blog_post_poll_attributes_poll_items_attributes_0__destroy" name="blog_post[poll_attributes][poll_items_attributes][0][_destroy]" type="hidden" value="false">delete
</div>
There is a field for input with class ctrlenter expanding, after two buttons "up" and "down" to be added . At the moment, these buttons are displayed after the input field on the next line, and it is necessary that they were in one line in place with input field. What styles I should add in order to realize this?
I added in _layout.sass
#up_id, #down_id
display: inline-block
But dont wotk
CSS is an angry beast you must wrestle into submission. Fortunately, things became a lot easier once CSS flexboxes came into existence. If you want things in a line, simply do
.things-in-a-line{
display: flex;
flex-direction: row; /* this is actually the default, but I put it here for clarity reasons */
}
And then wrap all of the elements in an element with a .things-in-a-line class.
For more information, see MDN's "Using flexible boxes"

How to use radio button to not send data to the server?

I am able with the radio button and a little javascript to toggle between the two categories, but even if one category is hidden it's data still sends.
challenge.rb
class Challenge < ActiveRecord::Base
scope :oneshot, -> { where(categories: 'One-Shot') }
scope :ongoing, -> { where(categories: 'Ongoing') }
_form
<%= form_for(#challenge) do |f| %>
<%= f.text_field :action %>
<% Challenge::CATEGORY.each do |c| %>
<%= label(c, c) %>:
<%= f.radio_button(:category, c, :class => "date-format-switcher", checked: (c=='One-Shot')) %>
<% end %>
<div id='id_of_first_div'>
<%= f.date_select :deadline %>
</div>
<div id='id_of_second_div'>
<%= f.date_select :date_started %>
</div>
<% end %>
<script>
$(function(){
$('#id_of_second_div').hide();
$('#challenge_category_one-shot').click(function(){
$('#id_of_first_div').show().attr('disabled', false);
$('#id_of_second_div').hide().attr('disabled', true);
});
$('#challenge_category_ongoing').click(function(){
$('#id_of_first_div').hide().attr('disabled', true);
$('#id_of_second_div').show().attr('disabled', false);
});
});
</script>
Radio Button HTML
<input class="date-format-switcher" type="radio" value="One-Shot" checked="checked" name="challenge[category]" id="challenge_category_one-shot" />
<input class="date-format-switcher" type="radio" value="Ongoing" name="challenge[category]" id="challenge_category_ongoing" />
Adapting Fiddle
<input id='a-selector' type='radio' name='selector' value='A' checked/> A
<input id='b-selector' type='radio' name='selector' value='B'/> B
<div id='details'>
<div id='for-a'>
<%= f.date_select :deadline, include_blank: true, selected: Date.current %>
</div>
<div id='for-b'>
<%= f.date_select :date_started, include_blank: true, selected: Date.current %>
</div>
</div>
<script>
var removed = $('#for-b').detach();
$('#a-selector').click(function() {
$('#details').append(removed);
removed = $('#for-b').detach();
})
$('#b-selector').click(function() {
$('#details').append(removed);
removed = $('#for-a').detach();
})
</script>
Setting a form element as disabled only disables user interaction with it; it doesn't remove it from the form's data (although your jQuery code is actually setting the div to disabled, which does nothing, but fixing that wouldn't help at all). What you want to do instead is clear the value of the date elements, e.g.,
<script>
$(function(){
$('#id_of_second_div').hide();
$('#challenge_category_one-shot').click(function(){
$('#id_of_first_div').show();
$('#id_of_second_div').hide();
$('#id_of_second_div select').value('')
});
$('#challenge_category_ongoing').click(function(){
$('#id_of_second_div').show();
$('#id_of_first_div').hide();
$('#id_of_first_div select').value('')
});
});
</script>
Though for that to work, you will need to add include_blank: true as an option to your date_select tags:
<%= f.date_select :deadline, include_blank: true %>
This will add the empty value as an option to your date selects, so that the above code can reset them to that empty value.
I'd also like to note -- all of this is just front-end logic, which any malevolent (or curious) user can circumvent. Your backend code (i.e., your controller) should handle discarding the fields you don't need based on your business logic, too.

bootstrap datapicker component using simple form

I am struggling to add a f.input simple form line of code to add a bootstrap datepicker with component.
Following the datepicker examples I can add the bootstrap datepicker with component using the following code:
<div class="input-append date" id="datepicker" data-date-format="dd-mm-yyyy">
<input class="span2" size="16" type="text" value="12-02-2013" readonly>
<span class="add-on"><i class="icon-th"></i></span>
</div>
<script type="text/javascript">
$(document).ready(function(){
$('[data-behaviour~=datepicker]').datepicker();
})
</script
how can I rewrite the above div as a f.input simple_form line of code
application.js or any .js file
$(function() {
$(".datepicker" ).datepicker({dateFormat: "dd/mm/yyyy"});
});
view file
<div class="input-append date">
<%=f.text_field :field_name, :class=>'datepicker'%>
<span class="add-on"><i class="icon-th"></i></span>
</div>
For my project, i used this : https://github.com/Nerian/bootstrap-datepicker-rails.
It's a good gem and easy to use
In my project, i create a date_time_input.rb file in app/inputs/date_time.input.rb for override simple form date time input.
class DateTimeInput < SimpleForm::Inputs::DateTimeInput
def input
#template.content_tag(:div, super)
"#{#builder.text_field(attribute_name, input_html_options)}".html_safe
end
end
Into the view :
= f.input :date, :required => true, :input_html => { “data-behaviour” => “datepicker” }
And JS :
$(document).ready(function(){
$(document).on(“focus”, “[data-behaviour~=’datepicker’]”, function(e){
$(this).datepicker({“format”: “dd/mm/yyyy”, “weekStart”: 1, “autoclose”: true});
});
});
This is my article for do that in french :-D
http://blog.jumboweb.fr/post/42841191962/datepicker-bootstrap-simple-form-avec-rails

How do i use different CSS options for different pages using gmaps4rails?

I want to have different size maps on differernt pages...but i can't see to figure it out. When I disable css, the whole map disappears.
<%= gmaps({ map_options: {
zoom: 8,
auto_zoom: false },
markers: { data: #json } },
enable_css: false) %>
and then i put CSS around it:
<div id="sidebar">
<div id="map_canvas" style="width: 294px; height: 370px; position: relative">
<%= gmaps({ map_options: {
zoom: 8,
auto_zoom: false },
markers: { data: #json } },
enable_css: false) %>
</div>
</div>
but that makes the map disappear. what am i doing wrong?
Just have a look at the wiki (or at the html page). The html generated is by default:
<div class="map_container">
<div id="map" class="gmaps4rails_map"></div>
</div>
So if you want to style, simply:
edit or disable gmaps4rails css
style the classes/id presented above, no need to add extra markup

Resources