Added submit button calls the earlier button's function itself - ruby-on-rails-3

I'm working on Rails 3 app. Here a view displays all the excel files uploaded by user. A button to execute all the checkbox selected files was already present with delete for each file separately. Now I'm supposed to add a 'delete' button to delete the selected files. I've added the button n modified the function called by this form jus to display "in execute" and "in delete" for now to check if the second 'delete' button is functioanal. But every time delete is clicked it prints "in execute" only in cmd. I guess the AJAX related code written in the view 'list' is the problem.
Pls help!! Tell me why is it going to execute always?
The related code is here:
PS: I hav used if params[:commit]="Delete" & if params[:delete_button] also in controller.rb to but didnt help
list.html.erb (the view that displays all files)
<% if #files.length > 0 %>
<h2 id='comments'>Uploaded Excel Files are as listed below for Edit/Delete/Execution</h2>
<div id='checkone' class='hide'>Please check atleast one excel file to execute</div>
<% ajax_str = "new Ajax.Request('/account/execute_testcases', {asynchronous:true, evalScripts:true, onComplete:function(request){adjust_sidebar();Element.show('msg');Element.hide('waitid');Element.hide('disableexecuteid');Element.show('executeid');}, onLoading:function(request){Element.show('waitid');Element.hide('msg');Element.hide('executeid');Element.show('disableexecuteid');}, parameters:Form.serialize(this)}); return false;".html_safe %>
<%= form_for 'file_names', :url => {:controller => 'account', :action => 'execute_testcases'}, :remote => true, :html => {:name => 'frmExecute', :onsubmit => ajax_str }, :id =>'execute_tc' do |f| %>
<table>
<% if #file_count > 1 && #error_in_all_files == false %>
<tr>
<td>
<input type='checkbox' name='chkAll' onclick='checkAll();'>
<span class='text'>Check All/Decheck All</span>
</td>
</tr>
<% end %>
</table>
<table class='upload'>
<% for a in #files %>
<tr>
<td>
<% file_id = a.id.to_i %>
<% if(#excel_errors[file_id].nil? || #excel_errors[file_id].empty?) && a.file_type.to_i != 1 %>
<input type='checkbox' name = "excelfile[]" value="<%= a.excel_filename %>,<%= a.excel_filename_with_timestamp %>">
<% else %>
<input type='checkbox' name = "excelfile[]" value="<%= a.excel_filename %>,<%= a.excel_filename_with_timestamp %>" disabled=true>
<% end %>
<a href="open_excel_file/<%= a.id %>" title='Click to open' class='nodecoration'><%= a.excel_filename %></a>
</td>
<td>
<%= link_to(image_tag("/images/b_edit.png", :border => 0, :title => 'Edit'), :action => 'upload_file', :file_id => a.id) %>
</td>
<td>
<img src='/images/b_drop.png' border=0 title='Delete' onclick="return confirm('This will delete the related reports too. Are you sure to delete?');">
</td>
<td>
<%
if !#excel_errors[file_id].nil? && !#excel_errors[file_id].empty?
#joined_excel_errors = #excel_errors[file_id].join(', ')
%>
Error
<% end %>
</td>
</tr>
<tr id="excel_error_<%=file_id %>" style='display:none;'>
<td colspan=4>
<% if !#excel_errors[file_id].nil? && !#excel_errors[file_id].empty? %>
<div class="padder">
<% for error_value in #excel_errors[file_id] %>
<font color='maroon'><%= error_value %></font><br>
<% end %>
</div>
<% end %>
</td>
</tr>
<% end %>
<tr><td> </td></tr>
<tr>
<td>
<% if #error_in_all_files == false %>
<span class='executebutton' id='executeid'>
<%= f.submit "Execute", name: 'execute_button', :onclick =>"return checkSelected();" %>
</span>
<span class='deletebutton' id='deleteid'>
<%= f.submit "Delete", name: 'delete_button', :onclick =>"return checkSelected();" %>
</span>
<% end %>
<span id='disableexecuteid' class='executebutton' style='display:none;'>
<input type='submit' value="Execute" disabled="disabled">
</span>
<span id='waitid' style="display:none;" class='text'>
<br>Executing Test Cases...Please wait...<%= image_tag("/images/wait26trans.gif", :border => 0) %>
</span>
<span id='msg' style="display:none;" class='text'>
<br><br> Click here to <%= link_to 'View Test Results', {:controller => 'account', :action => 'recent_test_results'}, :class => 'brownlink' %>
</span>
</td>
</tr>
</table>
<span id='subject_list'>
</span>
<% end %>
<% else %>
No test case sheets found!
<br><br>
<%= link_to '>> Upload File', {:controller => 'account', :action => 'upload_file'}, :class => 'brownlink' %>
<% end %>
<% for i in 1..10 %>
<div> </div>
<% end %>
controller.rb
def execute_testcases
if !params[:execute_button].nil?
puts "in execute"
# file_names = []
# originalfile_filewithtime = []
# original_file_map = {}
# originalfile_filewithtime = params[:excelfile]
......
# SOME CODE HERE
......
# render :update do |page|
# page.replace_html :subject_list, :partial => 'show_output', :locals => {:new_file_map => #new_file_map}
# page.visual_effect :highlight, 'subject_list', :duration => 2
# flash[:display]=#execmsg
#end
# puts #execmsg
elsif !params[:delete_button].nil?
puts "in delete"
end
end

I realised it had to do something with the Form.serialize(this) of AJAX which serialises everything. ie It calls the function of first button in the view irrespective of no of submit buttons present

Related

link_to current page rails

I was wondering what the syntax is to link to an attribute on the same page
I have a list of dates
<ul>
<% #response.each_pair do |date, movie| %>
<li><%= link_to date_format(date), date, :class => 'scroll_to' %></li>
<% end %>
</ul>
These then have movies underneath each date like so
<% #response.each_pair do |date, movie| %>
<h3 class="resultTitle fontSize13">Available on <%= date_format(date) %></h3>
<% movie.each do |m| %>
<div class="thumbnail clearfix">
<img class="pull-left" src=<% if m.image_link %> <%= m.image_link %> <% else %> "/assets/noimage.jpg" <% end %>>
<div class="caption pull-right">
<%= link_to m.name, m.title_id, :class => 'resultTitle fontSize11' %>
<p class="bio"><%= m.bio %></p>
<p class="resultTitle">Cast</p>
<p class="bio"><%= m.cast.join(", ") unless m.cast.empty? %></p>
<%= link_to "Remind me", reminders_path(:title_id => m.title_id), :method => :post, :class => 'links button' %>
</div>
</div>
<% end %>
<% end %>
What i would like to achieve is that when a user clicks on a date in the list then it will take them to that date with movies on the same page
My attribute for each date is
"release_date"
Do i need to link to that, maybe a piece of Jquery aswell to scroll down to that date? or would it jump to the date in one step?
Any advice appreciated, I have linked to other pages before but not the same page like this
EDIT
I have tried this but the page just re renders
<li><%= link_to date_format(date), params.merge(:release_date => 'release_date'), :class => 'scroll_to' %></li>
Am i on the right track?
Thanks
All you need is to give your date a unique identifier and link to that in you list. For instance below we give the h3 for each date an id relative to the date object. The browser knows how to handle internal links and will simply jump to the corresponding identifier. Notice how the id of the field you're linking to gets appended to the end of the url when you click on the link.
<ul>
<%- index = 0 %>
<% #response.each_pair do |date, movie| %>
<%- index += 1 %>
<li><%= link_to date_format(date), "##{index}", :class => 'scroll_to' %></li>
<% end %>
</ul>
<%- index = 0 %>
<% #response.each_pair do |date, movie| %>
<%- index += 1 %>
<h3 class="resultTitle fontSize13" id="<%= index %>">Available on <%= date_format(date) %></h3>
<% movie.each do |m| %>
<div class="thumbnail clearfix">
<img class="pull-left" src=<% if m.image_link %> <%= m.image_link %> <% else %> "/assets/noimage.jpg" <% end %>>
<div class="caption pull-right">
<%= link_to m.name, m.title_id, :class => 'resultTitle fontSize11' %>
<p class="bio"><%= m.bio %></p>
<p class="resultTitle">Cast</p>
<p class="bio"><%= m.cast.join(", ") unless m.cast.empty? %></p>
<%= link_to "Remind me", reminders_path(:title_id => m.title_id), :method => :post, :class => 'links button' %>
</div>
</div>
<% end %>
<% end %>
For the added JQuery transition you can replace
<li><%= link_to date_format(date), "##{index}", :class => 'scroll_to' %></li>
with
<li><%= link_to_function date_format(date), "$('html, body').animate({scrollTop:$('##{index}').offset().top }, 'slow');", :class => 'scroll_to'%></li>
The above isn't exactly a DRY approach, but the important thing to abstract out of that is that you're linking to a unique ID elsewhere on the page and not the code itself.

re render fields_for with ajax

I have a problem refreshing a partial with fields_for inside.
Here is the code of the partial ('table_detalle')
<table class="table">
<thead>
<tr>
<th><%= t('.denominacion') %></th>
<th><%= t('.cantidad_ingreso') %></th>
<th><%= t('.importe') %></th>
</tr>
</thead>
<tbody>
<%= f.fields_for :operacion_detalles do |builder| %>
<tr>
<%= render 'table_detalle_operacion', f: builder %>
</tr>
<% end unless #operacion.nil? %>
</tbody>
</table>
<%= content_tag :h3, t('.total', :value=> number_to_currency(#operacion.R_IMPORTE)).html_safe, :class => 'pull-right', style: 'display:inline' %>
when the user change a value of a combo i would like to refresh the partial above (because the details objects must change and are editable)
Here is the javascript code:
$('#operacion_TIPOVALOR_ID').change(function(){
$.ajax({
url: '<%= cambiar_tipo_valor_movimientos_path %>',
data: {tipo_valor_id: $('#operacion_TIPOVALOR_ID').val()},
complete: function(){
$('#tipo_valor_loader').css('display','none');
},
beforeSend: function(){
$('#tipo_valor_loader').css('display','inline');
},
success: null,
dataType: 'script'
});
});
the controller code:
def cambiar_tipo_valor
#operacion = Operacion.new
denominaciones = TipoValorDenominacion.all_from_tipo_valor params[:tipo_valor_id]
denominaciones.each do |deno|
#operacion.operacion_detalles.build :tipo_valor_denominacion => deno, :I_CANTIDAD => 0, :R_IMPORTE => 0
end
end
as you can see the "operacion_detalles" change depending on the user selection.
the .js.erb code:
$('#detalle').html('<%= escape_javascript(render :partial => 'table_detalle') %>');
But, i get:
undefined local variable or method `f' for #<#<Class:0x45ae1c8>:0x5062338>
So, i need the f variable to render the partial. Is there any way to emulate the f variable?
Thanks in advance.
I had no other choice than resolve the problem by hand. What i mean?
Instead of a field_for => each_with_index:
<% #operacion.operacion_detalles.each_with_index do |detalle, index| %>
<tr>
<%= render 'table_detalle_operacion', detalle: detalle, index: index %>
</tr>
<% end -%>
The use the tags helpers like this:
<td>
<input type="hidden" value="<%= detalle.tipo_valor_denominacion.R_MULTIPLICADOR %>" class="multiplicador"/>
<%= hidden_field_tag "operacion[operacion_detalles_attributes][#{index}][TIPOVALORDENO_ID]", detalle.TIPOVALORDENO_ID %>
<%= detalle.tipo_valor_denominacion.CTIPOVALORDENO %></td>
<td>
<%= text_field_tag "operacion[operacion_detalles_attributes][#{index}][I_CANTIDAD]", detalle.I_CANTIDAD %>
<%= content_tag(:span, detalle.errors[:I_CANTIDAD].join(', '), class: 'help-block') if detalle.errors.has_key? :I_CANTIDAD %>
</td>
<td>
<%= hidden_field_tag "operacion[operacion_detalles_attributes][#{index}][R_IMPORTE]", detalle.R_IMPORTE %>
<%= content_tag :span, number_to_currency(detalle.R_IMPORTE), class: 'detalle-importe pull-right' %>
<%= content_tag(:span, detalle.errors[:R_IMPORTE].join(', '), class: 'help-block') if detalle.errors.has_key? :R_IMPORTE %>
</td>
In this case i had supply the names, so when this code is executed
$('#detalle').html('<%= escape_javascript(render :partial => 'table_detalle') %>')
It does not need the f variable.
Hope it helps.
pd: I know this is not a very good solution but it works.

Rails nested_form adding items to table rows

My goal is to use the nested_form gem: https://github.com/ryanb/nested_form
but instead of creating just a new set of labels and fields every time you add an object, I wanted to insert a row into an existing table.
= nested_form_for #transaction do |f|
%h3 Line Items
%table
%tr
%th Branch
%th Department
%th Invoice #
%th Amount
%th Transaction Type
%th Deposit (y/n)
%th
= f.fields_for :line_items do |line_item|
%tr
%td
= line_item.text_field :location_id
%td
= line_item.text_field :department_id
%td
= line_item.text_field :invoice_num
%td
= line_item.text_field :amount
%td
= line_item.text_field :transaction_type
%td
= line_item.text_field :deposit
%td= line_item.link_to_remove "Remove"
%p= f.link_to_add "Add", :line_items
The .link_to_add button just creates a bunch of fields in the first row, first td.
<h3>Line Items</h3>
<table>
<tr>
<th>Branch</th>
<th>Department</th>
<th>Invoice #</th>
<th>Amount</th>
<th>Transaction Type</th>
<th>Deposit (y/n)</th>
<th></th>
</tr>
<div class="fields"><tr>
<td>
<input id="transaction_line_items_attributes_0_location_id" name="transaction[line_items_attributes][0][location_id]" size="30" type="text" />
</td>
<td>
<input id="transaction_line_items_attributes_0_department_id" name="transaction[line_items_attributes][0][department_id]" size="30" type="text" />
</td>
<td>
<input id="transaction_line_items_attributes_0_invoice_num" name="transaction[line_items_attributes][0][invoice_num]" size="30" type="text" />
</td>
<td>
<input id="transaction_line_items_attributes_0_amount" name="transaction[line_items_attributes][0][amount]" size="30" type="text" />
</td>
<td>
<input id="transaction_line_items_attributes_0_transaction_type" name="transaction[line_items_attributes][0][transaction_type]" size="30" type="text" />
</td>
<td>
<input id="transaction_line_items_attributes_0_deposit" name="transaction[line_items_attributes][0][deposit]" size="30" type="text" />
</td>
<td><input id="transaction_line_items_attributes_0__destroy" name="transaction[line_items_attributes][0][_destroy]" type="hidden" value="false" />Remove</td>
</tr>
<td>Add</td>
</div>
</table>
I've tried placing the .link_to_add in a few places, but it doesn't put them in their own row.
Is there an easy way to go about adding a row of input boxes each time?
This helped me a lot: https://github.com/ryanb/nested_form/wiki/How-To:-Render-nested-fields-inside-a-table
By default fields_for inside nested_form_for adds <div class="fields"> wrapper around every nested object. But when you need to render nested fields inside a table you can disable default wrapper using :wrapper => false option and use the custom one:
<table>
<%= f.fields_for :tasks, :wrapper => false do |task_form| %>
<tr class="fields">
<td>
<%= task_form.hidden_field :id %>
<%= task_form.text_field :name %>
</td>
<td><%= task_form.link_to_remove 'Remove' %></td>
</tr>
<% end %>
<tr>
<td><%= f.link_to_add 'Add', :tasks %></td>
</tr>
</table>
Note: You need to specify id field. Otherwise fields_for will insert it after </tr>.
Also you need to override default behavior of inserting new subforms into your form using javascript:
window.NestedFormEvents.prototype.insertFields = function(content, assoc, link) {
var $tr = $(link).closest('tr');
return $(content).insertBefore($tr);
}
A similar technique can be used for lists, for compatibility with a jQuery UI sortable list.
If you are using simple_form then add the :wrapper => false option to the surrounding simple_nested_form_for call, otherwise it gets overwritten by the :wrapper => nil default.
I ended up putting my link_to_add as the last line of the table, added this to my application.js (mostly from the example on the wiki)
jQuery(function ($) {
window.NestedFormEvents.prototype.insertFields = function(content, assoc, link) {
if($(link).hasClass('insert_in_table')){
return $(content).insertBefore($(link).parent().parent());
}
else{
return $(content).insertBefore(link);
}
};
});
My form looks like this:
<table class="tab">
<tr>
<th>My Headers</th>
</tr>
<%= f.fields_for :line_items, :wrapper => false do |form| %>
<tr class="fields">
<td>MY FIELDS</td>
</tr>
<% end %>
<tr>
<td><%= f.link_to_add "Add more line items", :line_items, :class => 'insert_in_table' %></td>
</tr>
</table>

Rails logs me out when I run a query

I have a site built using the railstutorial as a template. I have added a search controller to allow me to perform site searches and redirect the user to a search view. When I go to the path '/search' it is as expected (no results) but if I actually use the search input box I get logged out and have to log back in. What would be causing this?
My form:
<form action="/search" method="POST" class="navbar-search pull-right">
<input name="query" type="text" class="search-query" placeholder="Search">
</form>
My search controller:
class SearchController < ApplicationController
def index
unless params[:query].nil?
#results = ThinkingSphinx.search params[:query]
else
#results = []
end
end
end
My view:
<% unless #results.empty? %>
<table class="table">
<% #results.each do |result| %>
<tr>
<% if result.class.name == "Event" %>
<td><%= link_to result.name, organisation_event_path(result.organisation, result.slug) %></td>
<td><%= result.summary %></td>
<% end %>
</tr>
<% end %>
</table>
<% else %>
<p>No results found.</p>
<% end %>
My route:
match '/search', to: 'search#index'
It's related to CSRF issues. You can read the details here, or this SO question/answer.

NoMethodError in Users#show

Everytime I try and access the user profile page, I get this error.
ActionView::Template::Error (undefined method `email' for nil:NilClass):
2: <tr>
3: <td class="main">
4: <h1>
5: <%= gravatar_for #user %>
6: <%= #user.name %>
7: </h1>
8: </td>
app/helpers/users_helper.rb:4:in `gravatar_for'
app/views/users/show.html.erb:5:in `_app_views_users_show_html_erb__222181804_33777120'
Below is what my users.controller.rb file looks like.
def show
#user = User.find(params[:id])
#microposts = #user.microposts.paginate(:page => params[:page])
#title = #user.name
For additional reference, below is a copy of my show.html.erb file.
<table class="profile" summary="Profile information">
<tr>
<td class="main">
<h1>
<%= gravatar_for #user %>
<%= #user.name %>
</h1>
</td>
<td class="sidebar round">
<strong>Name</strong> <%= #user.name %><br />
<strong>URL</strong> <%= link_to user_path(#user), #user %>
</td>
</tr>
</table>
Also provided is my users_helper.rb file.
module UsersHelper
def gravatar_for(user, options = { :size => 50 })
gravatar_image_tag(user.email.downcase, :alt => h(user.name),
:class => 'gravatar',
:gravatar => options)
end
end
The error is in your helper method. Please verify that the #user object is not nil.
Then in your view change the line number 5 like this:
<%= gravatar_for(#user) %>
define your users_helper#gravatar_for method like this
def gravatar_for(#user)
..........
#user.email
..........
rerurn somthing #if you want
end