i need to create a progress bar for my form ,
i want when the user click on submit button a progress bar appear and start uploading the mp3
i m using ruby on rails and paperclip gem
here is my code
<% provide(:title, "Upload") %>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_for(#song, url: upload_path ) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.label :title, t('song.title') %>
<%= f.text_field :title, class: 'form-control', required: true %>
<%= f.label :artist, t('song.artist') %>
<%= f.collection_select :artist_id, #artists, :id, :name, {prompt: "Select a Artist"}, {class: "form-control selectpicker", "data-live-search" => "true", "required" => "true" } %>
<%= f.label :mp3, t('song.mp3') %>
<%= f.file_field :mp3 %>
</br>
<%= f.submit t('song.submit'), class: "btn btn-primary", data: { disable_with: 'Uploading'} %>
<% end %>
</div>
</div>
thanks
Edit 1 :
<% provide(:title, "Upload") %>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_for(#song, url: upload_path ) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.label :title, t('song.title') %>
<%= f.text_field :title, class: 'form-control', required: true %>
<%= f.label :artist, t('song.artist') %>
<%= f.collection_select :artist_id, #artists, :id, :name, {prompt: "Select a Artist"}, {class: "form-control selectpicker", "data-live-search" => "true", "required" => "true" } %>
<%= f.label :mp3, t('song.mp3') %>
<%= f.file_field :mp3, required: true, multiple: true, name: 'song' %>
<div class="progress-wrapper">
<p>Bitrate: <span class="bitrate"></span></p>
<div class="progress">
<div class="progress-bar" role="progressbar">
0%
</div>
</div>
</div>
</br>
<%= f.submit t('song.submit'), class: "btn btn-primary", data: { disable_with: 'Uploading'} %>
<% end %>
</div>
</div>
<script>
$(document).ready(function() {
var upload = $('#new_song');
var wrapper = upload.find('.progress-wrapper');
var progress_bar = wrapper.find('.progress-bar');
var bitrate = wrapper.find('.bitrate');
upload.fileupload({
dataType: 'script',
add: function (e, data) {
types = /(\.|\/)(mp3)$/i;
file = data.files[0];
if (types.test(file.type) || types.test(file.name)) {
data.submit();
}
else { alert(file.name + " must be mp3 file"); }
}
});
upload.on('fileuploadstart', function() {
wrapper.show();
});
upload.on('fileuploaddone', function() {
wrapper.hide();
progress_bar.width(0); // Revert progress bar's width back to 0 for future uploads
});
upload.on('fileuploadprogressall', function (e, data) {
bitrate.text((data.bitrate / 1024).toFixed(2) + 'Kb/s');
var progress = parseInt(data.loaded / data.total * 100, 10);
progress_bar.css('width', progress + '%').text(progress + '%');
});
});
</script>
this is my try but not working
it give me error :
undefined method `permit' for # Did you mean? print
and the Bitrat not showing
http://img3.stooorage.com/images/669/20501499_screenshot-14--2016-west-08-02-14.png
Related
Below is code extract from my file Users/JBossman/sites/discussions/app/views/discussions/_form.html.erb where line #20 raised this error undefined method 'map' for nil:NilClass
enter code here
<%= simple_form_for(#discussion) do |f| %>
<%= f.error_notification %>
<div class="field">
<div class="control">
<%= f.input :title, required: true, input_html: { class: 'input' }, wrapper: false, label_html: { class: "label" } %>
</div>
</div>
<div class="field">
<div class="control">
<%= f.input :content, required: true, input_html: { class: 'textarea' }, wrapper: false, label_html: { class: "label" } %>
</div>
</div>
<div class="field">
<label class="label">Channel</label>
<div class="control has-icons-left">
<span class="select">
<%= f.input_field :channel_id, collection:#channels.map { |c| [c.channel, c.id] }, prompt: "Select channel" %>
</span>
<span class="icon is-small is-left">
<i class="fa fa-tag"></i>
</span>
</div>
</div>
<div class="field">
<div class="control">
<%= f.button :submit, class:"button is-info" %>
</div>
</div>
<% end %>
the error is here: #channels.map { |c| [c.channel, c.id] }
your #channels variable is nil.
make sure you set #channels in your create action.
Looks like #channels is nil. Ideally, it should be initialized as [] empty array.
Alternatively, you can also use (#channels || []).map { |c| [c.channel, c.id] } to render empty form.
change #channels.map { |c| [c.channel, c.id] } to below, as #channels is not set(nil).
Assuming that you are having Channel model.
i. If you want to display all the channels in collection, then you can do it as below:
Channel.pluck(:channel, :id)
ii. If you want to display specific channels in collection, then define scope in Channel like favorites
Channel.favorites.pluck(:channel, :id)
I fixed a similar problem with a little change .map to .collect function, you may give it a try..
I'd like to apply bootstrap to the input fields as following.
<div class="input-group">
<span class="input-group-addon">Title</span>
<input type="text" class="form-control">
</div>
My current code is as following.
_form.html.erb
<%= simple_nested_form_for #event do |f| %>
<%= f.input :title %>
<%= f.input :description, input_html: { rows: 5, cols: 30 } %>
<%= f.input :charge_person %>
.
.
.
<% end %>
It would be appreciated if you could give me the best way in Rails.
This should do the trick:
<%= simple_nested_form_for #event do |f| %>
<div class="input-group">
<span class="input-group-addon">Title</span>
<%= f.input :title, class: 'form-control' %>
</div>
<div class="input-group">
<span class="input-group-addon">Description</span>
<%= f.input :description, class: 'form-control' %>
</div>
<div class="input-group">
<span class="input-group-addon">Charge Person</span>
<%= f.input :charge_person, class: 'form-control' %>
</div>
...
<% end %>
You shouldl read more detail SIMPLE FORM DOCS
<%= simple_nested_form_for #event, , wrapper_html: { class: 'input-group' } do |f| %>
<%= f.label :title, wrapper_html: { class: 'input-group-addon' } %>
<%= f.input_field :title, wrapper_html: { class: 'form-control' } %>
.
.
.
<% end %>
I can't submit my post without refreshing edit page, I am using turbolinks gem and simple_form here is the source code:
<div class = "row">
<div class = "col-lg-9 col-md-8">
<%= simple_form_for #post do |f| %>
<div class = "form-group">
<%= f.input :title, :label => false %>
<%= f.input :content, :as => :ckeditor, :input_html => { :ckeditor => {:toolbar => 'MyToolbar', :height => 465} } %>
<%= f.input :cat_list, :label => "Type your tags here" %>
</div>
<%= link_to 'Show', #post %> |
<%= link_to 'Back', posts_path %>
</div>
<div class = "col-lg-3 col-md-4 ">
<div class = "form-group" data-no-turbolink >
<p>
<%= image_tag(#post.thumbnail.url(:original), :class => "img-thumbnail") %>
</p>
<p>
<%= f.file_field :thumbnail %>
</p>
<p>
<%= f.select :tag_list, Post::Months, { }, { :multiple => true, :size => 10, :class => "form-control" } %>
</p>
<p>
<%= f.button :submit, class: "btn btn-primary" %>
</p>
</div>
</div>
</div>
<% end %>
How can I solve this issue?
Please correct me if I have misunderstood your problem.
By default, Turbolinks works only for GET requests.
So, in your case, you are not using turbolinks to submit the page.
Notice the data-no-turbolink attribute added to <div class = "form-group">
<div class = "form-group" data-no-turbolink >
<p>
<%= image_tag(#post.thumbnail.url(:original), :class => "img-thumbnail") %>
</p>
<p>
<%= f.file_field :thumbnail %>
</p>
<p>
<%= f.select :tag_list, Post::Months, { }, { :multiple => true, :size => 10, :class => "form-control" } %>
</p>
<p>
<%= f.button :submit, class: "btn btn-primary" %>
</p>
</div>
Whenever turbolinks finds a data-no-turbolink attribute, it ensures that all anchor tags within it fallback to the default behavior i.e. ignore turbolinks
The 'edit' page however may have been rendered using turbolinks.
Hi i hava a Rails app that uses nested forms, so for example on a section you can add, as many links as you want.. also i have this other code for citizen as some user have two citizens.
My problem here is that at least you need to enter 1 citizen.. this i can make it with jquery validate, im already running that.. The problem is the Delete button that Rails insert for each field.. So i can literaly delete all fields in the form
Is there a way so just the fields added by user have the delete button.. and not all of them?
Is there any documentation about this.. i cant found it.
Here is my code in view..
<div id="nacionalidad">
<%= f.fields_for :citizens do |citizen_form| %>
<div>
<%= citizen_form.label :citizen, t('generales.citizen') %>
<%= citizen_form.select :country_id , Country.all.collect {|p| [ t("generales."+p.iso), p.id ] }, { :include_blank => true } , { :class => 'pca33' } %>
<div id="delerr"><%= citizen_form.link_to_remove t('generales.delete') %></div>
</div>
<% end %>
<%= f.link_to_add t('generales.add'), :citizens %>
</div>
The model citizen.rb
class Citizen < ActiveRecord::Base
attr_accessible :country_id
belongs_to :player
end
Thanks
Here is the full view code. Everything is working just 2 issues:
1) The delete button is present always even for first item, need to remove this delete btn for 1st item
2) If i select a country for citizen, it adds a second option, is there a way to avoid this.. and Only add the new field if the user clics on this.. add button..
Thanks!!!
Full View Code
<!-- Información personal y de contacto -->
<div id="wrapper_signup">
<%= link_to image_tag("espanol/logo.jpg", :border => 0), root_path , :class => 'logoo' %>
<div id="loggeddiv">
<%= link_to "#{current_user.email}", '#' %> |
<%= link_to (t ('generales.salir')), destroy_user_session_path, :method => :delete %>
</div>
<div id="navsteps" >
</div>
<div id="signupdiv">
<%= nested_form_for #player, :url => wizard_path do |f| %>
<div id="nombre">
<%= f.label :name %>
<%= f.text_field :name , :value => "#{current_user.name}"%>
</div>
<div id="apellidos">
<%= f.label :lastname %>
<%= f.text_field :lastname, :value => "#{current_user.lastname}" %>
</div>
<div id="cumple">
<%= f.label :birthday %>
<%= f.date_select :birthday, :start_year => 1950, :include_blank => true %>
</div>
<div id="altura">
<%= f.label :height %>
<%= f.select :height, Player::HEIGHT.each {|h| [ h, h ] } , :include_blank => true %> <%= f.select :height_measure, Player::HEIGHT_MEASURE.each {|h| [ h, h ] } %>
<%= f.select :inches, Player::INCH.each {|h| [ h, h ] }, {}, :style => (#player.inches.present? && #player.height_measure == 'pies' ? 'display: inline ' : 'display: none') %>
<%= f.label :inches, :id => 'inch_label', :style => (#player.inches.present? && #player.height_measure == 'pies' ? 'display: inline ' : 'display: none') %>
</div>
<div id="peso">
<%= f.label :weight %>
<%= f.select :weight, Player::WEIGHT.each {|w| [ w, w ] }, :include_blank => true %> <%= f.select :weight_measure, Player::WEIGHT_MEASURE.each {|h| [ h, h ] } %>
</div>
<div id="ciudad">
<%= f.label :city %>
<%= f.text_field :city %>
</div>
<div id="cnatal" >
<%= f.label :birthplace %>
<%= f.text_field :birthplace %>
</div>
<div id="nacionalidad">
<%= f.fields_for :citizens do |citizen_form| %>
<div>
<%= citizen_form.label :citizen, t('generales.citizen') %>
<%= citizen_form.select :country_id , Country.all.collect {|p| [ t("generales."+p.iso), p.id ] }, { :include_blank => true } , { :class => 'pca33' } %>
<div id="delerr"><%= citizen_form.link_to_remove t('generales.delete') %></div>
</div>
<% end %>
<%= f.link_to_add t('generales.add'), :citizens %>
</div>
<div id="idiomlen">
<%= f.label :languages %>
<% for language in Language.find(:all) %>
<div class="idiomlenbox"><%= check_box_tag "player[language_ids][]", language.id, #player.languages.include?(language) %>
<%= t("languages.#{language.name}") %></div>
<% end %>
<div id="idiomlenotro">
<%= f.label :other_languages %><br>
<%= f.text_field :other_languages %>
</div>
</div>
<div id="cargafoto">
<button type="button" class="photo-button" onclick="document.getElementById('files').click();"><p> <%= t('generales.photo') %> </p></button>
<div id="upload-wrap">
<%= f.file_field :avatar , id: "files" %>
</div>
<div class="thumbperwrap">
<output id="list">
<div class="wraptocenter"><span></span>
<% if #player.avatar.present? %>
<%= image_tag #player.avatar.url(:profile), :class => "thumbper" %>
<% else %>
<img src="../assets/espanol/playersample.png" class="thumbper">
<% end %>
</div>
</output>
</div>
</div>
<script>
function handleFileSelect(evt) {
var files = evt.target.files; // FileList object
// Loop through the FileList and render image files as thumbnails.
for (var i = 0, f; f = files[i]; i++) {
// Only process image files.
if (!f.type.match('image.*')) {
continue;
}
var reader = new FileReader();
// Closure to capture the file information.
reader.onload = (function(theFile) {
return function(e) {
// Render thumbnail.
document.getElementById('list').innerHTML = "";
var span = document.createElement('span');
span.innerHTML = ['<div class="wraptocenter"><span></span><img class="thumbper" src="', e.target.result,
'" title="', escape(theFile.name), '"/></div>'].join('');
document.getElementById('list').insertBefore(span, null);
};
})(f);
// Read in the image file as a data URL.
reader.readAsDataURL(f);
}
}
document.getElementById('files').addEventListener('change', handleFileSelect, false);
</script>
<div id="videosyt">
<%= f.fields_for :links do |link| %>
<div id="videosytin">
<%= link.label :url %>
<%= link.text_field :url %>
<%= link.link_to_remove t('generales.delete') %>
</div>
<% end %>
<%= f.link_to_add t('generales.add'), :links %>
</div>
<div id="direc">
<%= f.label :cp %>
<%= f.text_field :cp %>
</div>
<div id="telef">
<%= f.label :phone %>
<%= f.text_field :phone %>
</div>
<div id="celu">
<%= f.label :cellphone %>
<%= f.text_field :cellphone %>
</div>
<div id="webpp">
<%= f.label :web_page %>
<%= f.text_field :web_page %>
</div>
<div id="next11">
<%= f.submit t('generales.next'), :class => 'siggreenc' %>
</div>
<% end %>
</div>
</div>
<%= javascript_tag do %>
$('#player_height_measure').on('change', function() {
if (this.value == 'pies') {
$('#player_inches').css('display', 'inline');
$('#inch_label').css('display', 'inline');
} else {
$('#player_inches').css('display', 'none');
$('#inch_label').css('display', 'none');
}
});
<% end %>
<style type="text/css">
#commentForm { width: 500px; }
#commentForm label { width: 250px; }
#commentForm label.error, #commentForm input.submit { margin-left: 253px; }
#signupForm { width: 670px; }
#signupForm label.error {
margin-left: 10px;
width: auto;
display: inline;
}
#newsletter_topics label.error {
display: none;
margin-left: 103px;
}
</style>
<%= javascript_tag do %>
window.onload = function() {
// validate signup form on keyup and submit
$(".edit_player").validate({ // initialize the plugin
errorElement: 'div'});
$("#player_name").rules("add", { required: true, minlength:2, messages: { required: "<%= t('generales.camporequerido') %>", minlength: "Mínimo 2 caracteres"}});
$("#player_lastname").rules("add", { required: true, minlength:2, messages: { required: "<%= t('generales.camporequerido') %>", minlength: "uh minlength?"}});
$("#player_birthday_1i").rules("add", { required: true, messages: { required: "<%= t('generales.camporequerido') %>"}});
$("#player_birthday_2i").rules("add", { required: true, messages: { required: "<%= t('generales.camporequerido') %>"}});
$("#player_birthday_3i").rules("add", { required: true, messages: { required: "<%= t('generales.camporequerido') %>"}});
$("#player_height").rules("add", { required: true, messages: { required: "<%= t('generales.camporequerido') %>"}});
$("#player_weight").rules("add", { required: true, messages: { required: "<%= t('generales.camporequerido') %>"}});
$("#player_city").rules("add", { required: true, messages: { required: "<%= t('generales.camporequerido') %>"}});
$("#player_birthplace").rules("add", { required: true, messages: { required: "<%= t('generales.camporequerido') %>"}});
$("#player_citizen").rules("add", { required: true, messages: { required: "<%= t('generales.camporequerido') %>"}});
$("#player_phone").rules("add", { required: true, messages: { required: "<%= t('generales.camporequerido') %>"}});
$("#player_cellphone").rules("add", { required: true, messages: { required: "<%= t('generales.camporequerido') %>"}});
$("#files").rules("add", { required: true, messages: { required: "<%= t('generales.camporequerido') %>"}});
};
jQuery.extend(jQuery.validator.messages, {
required: "<%= t('generales.camporequerido') %>",
remote: "Please fix this field.",
email: "Ingresa un correo electrónico válido.",
url: "Please enter a valid URL.",
date: "Please enter a valid date.",
dateISO: "Please enter a valid date (ISO).",
number: "Please enter a valid number.",
digits: "Please enter only digits.",
creditcard: "Please enter a valid credit card number.",
equalTo: "Please enter the same value again.",
accept: "Please enter a value with a valid extension.",
maxlength: jQuery.validator.format("Please enter no more than {0} characters."),
minlength: jQuery.validator.format("Please enter at least {0} characters."),
rangelength: jQuery.validator.format("Please enter a value between {0} and {1} characters long."),
range: jQuery.validator.format("Please enter a value between {0} and {1}."),
max: jQuery.validator.format("Please enter a value less than or equal to {0}."),
min: jQuery.validator.format("Please enter a value greater than or equal to {0}.")
});
<% end %>
You can use jquery first selector to remove the first delete button based on the id or classname of the parent div (which you aren't currently setting)
<div class="citizens_update">
<%= citizen_form.label :citizen, t('generales.citizen') %>
<%= citizen_form.select :country_id , Country.all.collect {|p| [ t("generales."+p.iso), p.id ] }, { :include_blank => true } , { :class => 'pca33' } %>
<div id="delerr"><%= citizen_form.link_to_remove t('generales.delete') %></div>
</div>
And then use jquery to find the first instance of delerr in the citizens_update div and remove it
$(".citizens_update").find("#delerr:first").remove
http://jsfiddle.net/tiri/ayTrw/
I need to ask to my user if will pay a service with credit card...if it checked the option pay_with_card? it must show the rest of the form, that ask for other data like card number, mail, etc. if the user don't checked it, it must show a message, the question is...how can I do this? thanks in advance
<%= form_for(#product) do |f| %>
<%= f.label :pay_with_card? %>
<%= f.check_box :pay_with_card,{}, "Yes", "No"%>
<div>
<%= f.label :card_number %> <%= f.text_field :card_number %>
</div>
<div>
<%= f.label :mail %> <%= f.text_field :mail %>
</div>
<% end %>
Make the card number/mail details div style="display:none;", then add some javascript to the checkbox to change it to display:block;
Something like this:
<%= form_for(#product) do |f| %>
<%= f.label :pay_with_card? %>
<%= f.check_box :pay_with_card,{}, "Yes", "No"%>
<div id="card_details" style="display:none;">
<%= f.label :card_number %> <%= f.text_field :card_number %>
<%= f.label :mail %> <%= f.text_field :mail %>
</div>
<% end %>
<script type="text/javascript">
var checkbox = document.getElementById('product_pay_with_card');
var details_div = document.getElementById('card_details');
checkbox.onchange = function() {
if(this.checked) {
details_div.style['display'] = 'block';
} else {
details_div.style['display'] = 'none';
}
};
</script>
How about using jQuery?
First, wrap your credit card fields in a div with class credit_card_fields and than add this JS code to your page:
$("input[type='checkbox']#pay_with_card").on('change', function(){
$('.credit_card_fields').toggle();
});
You can use JS for it or move pay_with_card out of form like:
<%= link_to 'pay with card', your_current_path(:pay_with_card => 1) %>
<%= form_for(...) do |f| %>
<% if params[:pay_with_card] %>
<%= # fields for card %>
<% end %>
<% end %>
You can do it through jQuery, for example:
$ ->
$('select#pay_with_card').change ->
if $(this).val() == 'yes'
$('.card_block').slideDown('fast')
else
$('.card_block').slideUp('fast')
assumed that part of the form with payment card is included in the div with .card_block class
Ok my solution is this: all the code in the view, if a user check pay_with_card...(mi code is in spanish) it shows the complete form...if is not checked don´t show nothing, just the same checkbox asking for payment... thanks guys.
function mostrar (){
var checkbox = document.getElementById('chk_tarjeta');
if (checkbox.checked)
document.getElementById("card_details").style.display = "block";
else
document.getElementById("card_details").style.display = "none";
</script>
<h1>Forma de Pago</h1>
<%= form_for(#product) do |f| %>
<div id="product_pay_with_card">
<div >
<%= f.label :paga_con_tarjeta? %></br>
<%= f.check_box :paga_con_tarjeta, :id => "chk_tarjeta", :onclick => "mostrar();" %>
<div>
</div>
</div>
<div id="card_details" >
<div>
<%= f.label :numero_de_tarjeta %></br>
<%= f.text_field :numerotarjeta %>
</div>
<div>
<%= f.label :codigo_de_seguridad %></br>
<%= f.text_field :codigoseguridad %>
</div>
This worked for me with a form_with model and bootstrap
Change my_hidden_form with an id that makes sense for your form.
Original code is haml
= form_with scope: :model, url: models_path, local: true do |form|
.row
.col-6
.form-group
%h5.mb0 THE CASE TO TICK
= form.check_box :form_value, {:data => {:aria => {controls: :my_hidden_form, expanded: false}, :toggle => "collapse", :type => "checkbox", :target => "#my_hidden_form" }}
.row
.col-6
.form-group.collapse#my_hidden_form
%h5.mb0 THE FORM TO SHOW WHEN CASE IS TICKED
= form.text_field :name, placeholder: "A name"
.row
.col-md-12.text-right
= form.submit 'Submit', class: "btn btn-primary"
Converted to erb/html with https://haml2erb.org/
<%= form_with scope: :model, url: models_path, local: true do |form| %>
<div class="row">
<div class="col-6">
<div class="form-group">
<h5 class="mb0">THE CASE TO TICK
<%= form.check_box :form_value, {:data => {:aria => {controls: :my_hidden_form, expanded: false}, :toggle => "collapse", :type => "checkbox", :target => "#my_hidden_form" }} %>
</h5>
</div>
</div>
</div>
<div class="row">
<div class="col-6">
<div class="form-group collapse" id="my_hidden_form">
<h5 class="mb0">THE FORM TO SHOW WHEN CASE IS TICKED
<%= form.text_field :name, placeholder: "A name" %>
</h5>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12 text-right">
<%= form.submit 'Submit', class: "btn btn-primary" %>
</div>
</div>
<% end %>
Since the approach suggested by #Unixmonkey didn't work for me, here's a slight variation I put together using an event listener.
<script type="text/javascript">
const checkbox = document.getElementById('product_pay_with_card');
const details_div = document.getElementById('card_details');
checkbox.addEventListener("change", (event) => {
if (event.currentTarget.checked) {
details_div.style['display'] = 'block';
}
else {
details_div.style['display'] = 'none';
}
});
</script>