Why does HAML think I have content on the line and nested? (I don't) - haml

My HAML reads:
%table.screenshots
%thead
%trow
%td{:colspan => 12} Screenshots for #{element.name}
%tbody
- screenshots.each do |set|
%tr
- set[1].each do |shot|
- if shot == :blank_cell
%td{:colspan => set[0]}.twelfth
- else
%td{:colspan => set[0]}.twelfth
= image_tag(shot[1]) # <= ERROR APPEARS HERE
- if #redacted
%h1.blur
%span Image blurred in
%br
%span demo report only
%p #{shot[0]}
There are no invisible spaces or tabs after .twelfth.
Why, then, do I get this error?
Illegal nesting: content can't be both given on the same line as %td and nested within it.
BTW, I get the same exception when I run:
haml --debug print.html.haml

The class and id identifiers (. and #) must come after the tag name, and before any attribute hash.
In your code the problem is the line:
%td{:colspan => set[0]}.twelfth
This is interpreted as a td element with a colspan attribute, containing the content .twelfth, which would look like this when rendered, if it were by itself:
<td colspan='7'>.twelfth</td>
However this line also has content nested below, which Haml doesn’t allow.
You can fix this by using an explicit class entry in the attribute hash as you have in your answer, or by moving the .twelth class specifier in front of the attribute hash, like this:
%th.twelfth{:colspan => set[0]}

Fixed it by changing the offending line to:
%td{:colspan => set[0], :class => "twelfth"}
Looks like there's a bug in the HAML interpreter

Related

Get text from Capybara node element

I am trying get the text value of table header with a classname in Capybara. I getting the node element in Capybara but I am not able to get the text content of the class when I use the text attribute. How can I get the text of the Capybara node element here?
html.erb
<% #tests.each do |test| %>
<th class="test_name_header"><%= test.name %></th>
<% end %>
capybara_test.rb
all(:css, '.test_name_header', :visible => false).each do |el|
puts el.text
end
This code does not print the text of the element. Nothing is printed but when I puts el in the above code it prints the node element.
The docs for #text - https://www.rubydoc.info/github/teamcapybara/capybara/Capybara/Node/Element#text-instance_method - state that by default it only gets visible text. Since you're specifying visible: false in your all call I am assuming these headers are not actually visible on the page. If that is the case then, as mentioned in the docs, you'd need to do
el.text(:all)
to get non-visible text.

Placing a span tag within an anchor in Haml

I am new to Haml and am trying to simply place a span tag within an anchor link like so:
.text Here is some copy.
= link_to 'Visit website', 'https://websitelink.com/', class: 'link'
%span
This is throwing an error, "syntax error, unexpected keyword_ensure, expecting $end"
How Do I perform this simple task?
Rails’ link_to helper accepts either the link text as a parameter or as the result of a block.
In this case you probably want something like this:
= link_to 'https://websitelink.com/', class: 'link' do
%span Visit website
Note the do indicating a block, and that there are only two parameters to the method, the “Visit Website” text has been moved into the block.
This renders:
<a class="link" href="https://websitelink.com/"><span>Visit website</span>
</a>

rspec rendered view fails to include variable data

I have a failing rspec view test but the code works - I probably have a variable incorrectly setup but can't figure out what it is.
When I display the contents of #incident_report (pp #incident_report) in my spec, it properly displays the record created by FactoryGirl.
When I display the actual rendered content (puts rendered), it shows the values from the the record I created with FactoryGirl...
But the "rendered.should contain(work_order)" spec fails with:
1) incident_reports/show.html displays the work order number on the incident
Failure/Error: rendered.should contain(work_order)
expected the following element's content to include "54785":
and none of the data is displayed, only the HTML template
spec/views/incident_report/show.html.haml_spec.rb code
require 'spec_helper'
describe "incident_reports/show.html" do
before(:each) do
#incident_report = Factory(:incident_report)
end
it "displays the work order number on the incident" do
work_order = #incident_report.work_order
pp #incident_report #displays an incident_report, id => 1
assign(:incident_report, #incident_report)
render
puts rendered #this DOES have the content from #incident_report
rendered.should contain("Work Order:")
rendered.should contain(work_order)
end
end
show.html.haml code
%h1 Display Incident Report
.navigation
= link_to 'Edit', edit_incident_report_path(#incident_report)
|
\#{link_to 'Back', incident_reports_path}
= render 'form'
.navigation
= link_to 'Edit', edit_incident_report_path(#incident_report)
|
\#{link_to 'Back', incident_reports_path}
Gotta be something really simple I'm overlooking.
Turns out it's because I was using simple_form and when simple_form displays for a "show" action, it puts the field values into the html as a 'value="54785"' attribute. If you display it in a browser, the labels and values all show up correctly, but rspec can't see them.
I had to add
rendered.should have_tag 'input', :with => { :value => "54765", :name => 'incident_report[work_order]' }
to my example to get it to work.
Seems like there should be a better solution but at least now I can continue testing.

Rails: Template Error "dynamic constant assignment"

In my view I render a partial.
The name of the partial is constructed by the name of a product page.
<%= render :partial => "product_pages/" + selected.headline %>
In the test case the headline is "electronics".
So I also tried:
<%= render :partial => "product_pages/electronics"
For testing the partial view looks like this:
<p>Test</p>
Now I get this error I do not understand:
ActionView::Template::Error (/var/www/*****/app/views/product_pages/_Elektro
nik.html.erb:1: dynamic constant assignment
...r = #output_buffer;Elektronik = local_assigns[:Elektronik];;...
... ^):
1: <p>Test</p>
app/views/pages/_content.html.erb:13:in `_app_views_pages__content_html_erb__4
0580468132849538_266915680_1201196437383914942'
app/views/pages/index.html.erb:3:in `_app_views_pages_index_html_erb__43007964
38685262523_267219620_562910368159856764'
You need to downcase your headline:
selected.headline.downcase
This is because you're going to be rendering a partial like this: product_pages/Elektronik, and when you call render :partial it'll attempt to define a local variable that has the same name as the partial, which is why you're getting this error: the code isn't defining a local variable but is actually defining a constant.
If you downcase it, it will define a local variable rather than this constant.

adding size option to file_field tag in rails

ANSWERED
I actually found the answer while formulating the question but I'm posting it any way since some might find this useful(as said here: https://meta.stackexchange.com/questions/49922/should-i-continue-adding-a-question-if-i-have-found-the-answer-myself)
I'm having trouble adding size to a file field in ROR3. Here was my syntax:
= f.file_field :file, :size => "11"
this doesnt appear but creates an file input field with this:
<input type="file" name="soap_test_zip_file[file]" id="soap_test_zip_file_file">
now I KNOW I made it work before so I looked into some old code and found this:
= file_field_tag :file, :size => 11
which outputs this:
<input type="file" size="11" name="file" id="file">
which gives me the correct size, but the wrong file id and name. So I tried this:
<input type="file" size="11" name="soap_test_file_file" id="soap_test_file_file">
which gives me the RIGHT ID, but the WRONG NAME. Question is how do I reproduce that file_field but with the size?
I looked into this answer by Ryan Bigg btw: Problem showing the 'size' attribute for a 'file_field' using Ruby on Rails 3
and he's saying it's a cross browser thing that they render file fields differently. That is the case, but I would like to render a short file field IF the browser can handle it.
I used:
= file_field_tag :soap_test_zip_file, {:name => 'soap_test_zip_file[file]', :size => 11}
This made me override the name(for the controller) and the size
doesn't seem to work for me..
I thought of another alternative :
jquery ..
$('#user_photo_photo').attr('size', 1);
bingo!!
If you want to not rewrite the name attribute you can do something like this :
keep your form
= f.file_field :file, :size => "11"
add an override for the file_field method
# lib/my_override.rb
module ActionView
module Helpers
module FormHelper
def file_field(object_name, method, options = {})
InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("file", options.update({:size => options[:size]}))
end
end
end
end
And load it through an initializer
# config/initializers/load_lib.rb
require 'my_override'