Sinatra dropdown list - ruby

Im glad you answered my question about my dev issue, I'll try to be more self-explanatory this time.
I have a main app.rb where I use several endpoints redirecting to my Sinatra Haml views.My project is about a Software Portfolio, so I have this class: Software, and Category, which relationship is: one software has one category, and a category has many softwares. In the form where you create a new Software entry, I put a dropdown list where you can choose between 3 different categories: Desktop, Web and App.
Until there, everything is going well. The thing is, when the Software list shows up, I want to put a dropdown list to filter by created categories (I already have the "add category" form with its Class) and I can't figure out how to add the filter within a Filter button in the software list form. Can you guys help me please? Of course I know how to put the button there, but I want to show only the software entries where the selected category matches. Here's the list form.
%select{:name => "category"}
%option Desktop
%option Web
%option Device
%input{:type => "submit", :value => "Filter", :class => "btn"}
%ul.list
- #sware.each do |software|
%div{:class =>"list-group"}
%a{:href =>"/software/edit/#{software.id}", :class =>"btn btn-lg btn-primary"}
= software.title
%a.pull-right(href="/software/delete/#{software.id}" class="btn btn-lg btn-danger") Delete
Thanks a lot in advance!

You're calling the index method like this:
post '/all' do
index(:category)
end
You're passing an argument to the index call, but the index method doesn't take any arguments.
Please include the full error with your question.

index action can be DRY'ed:
def index
category = case
when params[:Web] then :Web
when params[:Desktop] then :Desktop
when params[:Device] then :Device
end
#sware = Software.title.where(categorization: { Software.categorization => category })
end
"It just doesn't work" is not a good place to start investigation of the problem. More debug information is required.

Beside the point that #max pleaner made, you're not actually calling the right object in params. It should be params[:category] and you should be able to rewrite that much simpler:
get '/all' do
halt(401,'Not Authorized, please login to continue') unless session[:admin]
#sware = Software.all
haml :sware
end
post '/:category' do
#sware = Software.title.where(categorization: {Software.categorization => params[:category]}
haml :index # assuming index.haml is where you want to go
end
Then, assuming your file is properly indented, your Haml file should work as well:
%select{:name => 'category'}
%option Desktop
%option Web
%option Device
%input{:type => 'submit', :value => 'Filter', :class => 'btn'}
%ul.list
- #sware.each do |software|
%div{:class =>'list-group'}
%a{:href =>"/software/edit/#{software.id}", :class =>'btn btn-lg btn-primary'}
= software.title
%a.pull-right{:href=>"/software/delete/#{software.id}" :class=>'btn btn-lg btn-danger'} Delete
Of course, the more information you can provide, the better the problem can be understood.

Related

Sinatra param filter

I am about to finnish my Sinatra Haml School project but I need a couple of things to get solved (I tried really hard but cannot solve the issues). I have a Software portfolio CMS where I can create new software entries (Title, Description, Language and Github link), being language a dropdown list filled from the database. Thing is I want to let the user select a filter from the list and filter by categories in the software list, but when I press the filter button it only shows the first entry. Here's the code in app.rb
get '/softwares/:filter' do
halt(404,'Forbidden') unless session[:admin]
#sware = Software.all
#categ = Category.all
haml :sware
end
post '/softwares/:filter' do
#sware = Software.find(category: params[:category])
haml :sware
end
And here is the HAML code that shows the list of softwares
%form{:action => "/softwares/:filter", :method => "post", :role => 'form'}
%select{:name => "category"}
- #categ.to_a.each do |category|
%option= category.name
%input{:type => "submit", :value => "Filter", :class => "btn"}
%ul.list
- #sware.each do |software|
%li(class="glyphicon glyphicon-search" aria-hidden="true")
%a{:href =>"/software/edit/#{software.id}", :class =>"btn btn-lg btn-primary"}= software.title
%a.pull-right(href="/software/delete/#{software.id}" class="btn btn-lg btn-danger") Delete
%li(role="separator" class="divider") ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Thanks a lot for your answers. I really appreciate every information you can provide about what am I doing wrong.
It is a bit hard to tell from your question because you don't provide much info, e.g. what ORM you are using.
Supposing you're using ActiveRecord:
Software.find(...)
#=> returns the first match
Software.where(...)
#=> returns all matches

How do you establish the parent of an object as an object in page object?

In a page object file:
class ThisPage
include PageObject
I can establish an object like this:
div(:user_dialog, :class => 'ud_dialog')
However, in the domain of the website, there are many windows with :class => 'ud_dialog' that popup in various workflows.
I can get to the object in binding.pry like this:
on(ThisPage).div_elements(:text => 'Are you sure you want to do this action?').first.parent.html
How can I establish the window like this in the page file?
i.e. is there some syntax like this:
div(:user_dialog, parent(:text => 'Are you sure you want to do this action?'))
For complex locators, such as locating the parent element, you can use a block to get the element.
If you define the div in your page object as:
div(:user_dialog){
div_elements(:text => 'Are you sure you want to do this action?').first.parent
}
Then your page can do:
on(ThisPage).user_dialog_element.html
Note that since you want the first matching div, you could simplify it to:
div(:user_dialog){
div_element(:text => 'Are you sure you want to do this action?').parent
}
It might also be possible to be more direct by using multiple locators (depending on what your html is). You could locate the div that has the ud_dialog class and contains the specified text (a partial match since there is likely other text):
div(:user_dialog, :class => 'ud_dialog',
:text => /Are you sure you want to do this action?/)

What is the best way use link_to in my scenario

I am working with rails, So I have got a problem here
link_to 'Movie Title', {:action=> 'sort', :checks=>"#{#temp.join('_')}"}, :id => 'title_header'
This is my code snippet and on hovering or clicking on this link what I get is,
/movies/sort?checks=G_PG_NC-17
But I need it to be like movies/sort/G_PG_NC-17 , See the difference there is no "checks?" in second url, Anyway I can make that happen with the help of javascript and some changes in routs.rb , but I think there is something else , I can easily get it done.
Your inputs are highly appreciated.
Cheers.
Jossie.
I don't think there's an easier way than to edit the routes.rb file and add something like:
match 'movies/sort/:checks
add this in routes
get '/movies/sort/:checks' => 'movies#sort', as: :movies_sort_checks
then
link_to 'Movie Title', movies_sort_checks_path(#temp.join('_'))
Finally It is done by myself, Anyway I am quite new to rails, I think other wise I would not have come up with this question.
So this part link_to 'Movie Title', {:action=> 'sort', :checks=>"#{#temp.join('_')}"}, :id => 'title_header' changes to link_to 'Movie Title',returm_link(#temp), :id => 'title_header'
See now return_link is a helper method.
go to controller and add
def return_link(kick)
'/'+shot+'/'+kick.join('_')
end
helper_method :stringo
Finally as you expect change routes.rb
match '/sort/:checks', :to => 'movies#sort'
Done everything works as expected, so a custom helper is really helpful here
Cheers .
Jossie.

Datamapper, Sinatra, Haml : attaching and rendering Comments from a post

I have a model Ticket which has n Comments belonging to it (many to one relationship).
The issue is that I can not render any of the comments nor does the form post the comments to the database.
I can kinda sorta do this from irb. I can add comments to tickets.comments, but I cannot pull individual comments - I can pull up the collection but have not figured out how to do anything with it. It is a Class: DataMapper::Associations::OneToMany::Collection and documentation says "A Collection should act like an Array in every way"
So 2 issues needing reading and input:
1) posting from the web form
2) iterating over and rendering the collection through haml, which I can't seem to do.
More gory details:
I have a Sinatra method that pulls up
get '/:thisticket' do
#ticket=Ticket.first(:slug=>params[:slug])
if #ticket
haml :showticket
Haml template
%div{:class => "ticket"}
%h1
= #ticket.slug
= #ticket.comments.all (returns the # symbol to any html page)
- #ticket.comments.all do |comment|
%h4
= comment.a_comment
%h4
= comment.created_at
%h4
= comment.id (this block shows nothing on a rendered page)
%center
%form{:action => "/#{#thisticket.slug}/update", :enctype => "text/plain", :method => "post"}
comments
%br/
%textarea{:id => "a_comment",:name => "a_comment", :rows => "5"}
:preserve
%br/
%input{:type => "submit", :value => "post"}/
For anyone paying attention or having the same:
This works
Sinatra
get '/:thisticket' do
#ticket=Ticket.first(:thisticket=>params[:thisticket])
#comments=#ticket.comments.all(:order => [ :created_at.desc ])
if #ticket
haml :showticket
Haml
#comments.each do |comment|
comment.comment
etc, etc, et. al.

How do I get an array of check boxes in haml?

I have an array of strings, called #theModels, in a routine implemented as part of a Sinatra server. These models are options for the user to select, and are obtained by the back end (the idea being, as new models are added, then the front end code should not change).
I'm using haml to render html.
How can I enumerate each element in the list of #theModels such that each element is a checkbox? And how can I obtain which checkboxes the user has selected?
I see that just putting
= #theModels
will give me the list of strings contained in #theModels, but without spacing or the like, and certainly not in checkboxes. I've found this question that appears to be similar, but my haml-fu isn't good enough to convert that into what I need.
UPDATE:
These are options associated with a file upload, such that now the code looks like:
%form{:action=>"/Upload",:method=>"post",:enctype=>"multipart/form-data"}
- #theModelHash.each do |key,value|
%br
%input{:type=>"checkbox", :name=>"#{key}", :value=>1, :checked=>value}
=key
%input{:type=>"file",:name=>"file"}
%input{:type=>"submit",:value=>"Upload"}
Problem is, that puts a file upload button on each option, instead of at the end. I only want one submit button in the end; should I have two forms that both report their results when the 'Upload' button is pressed?
UPDATE2:
After a moment's thought, the above can be modified to:
Thanks!
%form{:action=>"/Upload",:method=>"post",:enctype=>"multipart/form-data"}
- #theModelHash.each do |key,value|
%br
%input{:type=>"checkbox", :name=>"#{key}", :value=>1, :checked=>value}
=key
%form{:action=>"/Upload",:method=>"post",:enctype=>"multipart/form-data"}
%input{:type=>"file",:name=>"file"}
%input{:type=>"submit",:value=>"Upload"}
And that appears to do what I want.
I think you should send the content as an hash instead.
This will give you the opportunity to set initial values in the form.
The hash #params will give you the result.
E.g. {"oranges"=>"1"}
#app.haml
%form{:method => 'post', :action => "/"}
- #models.each do |key,value|
%br
%input{:type=>"checkbox", :name=>"#{key}", :value=>1, :checked=>value}
=key
%input{:type => :submit, :value => "Save"}
#app.rb
require 'sinatra'
require 'haml'
get '/' do
#models = {"oranges" => true, "bananas" => false}
haml :app
end
post '/' do
#params.inspect
end
The link you provided linked to a rails solution where you have a function returning the proper html.
You can define this function yourself:
Input: key, value
Output: %input{:type=>"checkbox", :name=>"#{key}", :value=>1, :checked=>value}
def check_box(key, value)
...
end
and call it in haml with
=check_box(key,value)

Resources