I have a typical CRUD app, I would like to add a link next to the f.submit that allows you to go back to the index without saving changes. I thought it would be as simple as just making a link to the index, but it's saving changes anyway.
<%= button_to 'Close Without Saving', users_path %>
<%= f.submit %>
What's the rails way of handling this?
From the fine manual:
[button_to] Generates a form containing a single button that submits to the URL created by the set of options.
So using button_to inside a form will attempt to create a nested form but HTML forms don't nest. The result will be an HTML structure something like this:
<form>
<form><!-- from button_to -->
<input type="submit">
</form>
<input type="submit"><!-- from f.submit -->
</form>
But the browser will ignore the inner <form> and assume you meant this:
<form>
<input type="submit"><!-- from button_to -->
<input type="submit"><!-- from f.submit -->
</form>
Then pressing either <input type="submit"> will submit the outer form.
You can either create another submit button in the outer form and the controller can check which button was pressed or you can use link_to and style the link to match your submit button (or leave it styled like a link depending on your preference).
<button type="button" onClick="location.href='<%= users_path %>'">Close Without Saving</button>
<%= f.submit %>
This also worked... went back to basics and used good old fashioned HTML.
Related
So I have a form that is working when I don't use Materialize to stylize it. It submits and the info is saved into the database, but the problem arises when I use materialize to stylize the button. It randomly saves the data into the database when it is using the materialize styling(e.g. like 7 times in a row and then it stops and will randomly start working again). Is there a known error with this gem or am I missing something?
gem 'materialize-sass'
View
<%= form_for(#user) do |f| %>
<div class="action btn waves-effect waves-light actions">
<%= f.submit "Create my account" %>
</div>
<% end %>
Check your styling. In your example button will always work when you click on button caption only.
<button class="btn waves-effect waves-light" type="submit" name="action">Submit
<i class="material-icons right">send</i>
Let's say I have my Home page and a Post model.
If I want to add a new Post, I go to /posts/new and create a new object of a Post class. That is a standard way.
Can I include, for example, in my Home Page, a + button that will open a small window asking me to type title and content and have the same effect as the standard way ?
Short answer is yes.
You would have to follow next steps:
your form for adding Post should be in partial
Display this partial when + button is clicked
Because you used the partial, action will be sent to Post#create
Now you only have to consider redirect. If you have redirect on Post#create
You can inside request send redirect page to homepage, if this is not done by ajax for some reason
This way you do not need to create anything new, just use the existing structure, that is what Rails is about. Place everything in small peaces and reuse them as often as you can.
It is not very clear what you are asking but if I got it right you want to add Post from anywhere in your app. That is very easy you should either create an instance of model and create a partial _form.html.erb and render in your app
so inside controller
def index
#new_post = Post.new
end
inside view:
<%= render partial: "form", locals: {page: #new_post} %>
inside _form partial
<%= form_for(page, remote: true) %>
...etc
<% end %>
If you generate scaffold Page you will get this partial by generator. There you can check how the partial is created.
Inside your view you can use what ever you want model...etc to display from for adding new. You can also check UJS to load the page with ajax so it does not refresh (remote: true) whole page
EDIT
here is the example if you want to use modal. I am using a bootstrap here but you can apply this anywhere. So inside your view (index for example) wrap the partial form inside markup of bootstrap) like this
app/views/pages/index.html.erb
<button type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#new-page-modal"> Add Page</button>
<div class="modal fade" id='new-page-modal'>
<div class="modal-content">
<%= render partial: "form", locals: {page: #new_post} %>
</div>
You can include other part and have the button inside footer what will just trigger submit on form like $('#new-page').submit(); You would place this inside application.js
So inside view there is button that will trigger modal (data-target="#new-page-model"). I named the modal with this id so it opens if you have included bootstrap.js files inside asset pipeline. After that you can trigger form submit once the modal is visible.
EDIT 2
Here is how you can inside footer of bootstrap form have OK button trigger submit event
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn ban-primary" onclick="javascript:$('#new_form').submit();$('#new-page-modal').modal('hide');return false;">Save changes</button>
</div>
So here submit button since it is outside of the form I am triggering submit and closing the modal. You way want to one tune this if for example you want to handle errors, like Page Title is required...etc...for that it is best to use JS response with remote form.
Let me know if it is not clear.
For the small window you can use Bootstrap Modal. There's sample code here.
You can write the form in a way that automatically sends the query via AJAX. You can write callbacks using the listeners in order to display success or act otherwise.
I am confused between the controller and views interaction. I have this initial form which validates the csv file uploaded. (POST form).
After this form is validated successfully, I give the user the option to confirm the details which, and this confirm button acts as another form.
The thing is I want to keep the details from the previous form values saved in the params hash. So basically I want to perform a merge with the second form.
Is this possible? If so, can you help me with the code for the second form cause currently it overrides the previous form. Both forms point to the same function in the controller.
<% unless #contents.blank? || #errors.present? %>
<form name="confirm_bulk_order" method="post" enctype="multipart/form-data" class="search line" action="/orders/create_bulk_order" id="confirm_bulk_order">
<div class="search-btn-align" id="confirmButton">
<input type="submit" name="confirm_bulk_order" value="Confirm Order" class="lmargin10 uiButton">
</div>
</form>
<% else %>
<form name="upload_bulk_order_csv" method="post" enctype="multipart/form-data" class="search line" action="/orders/create_bulk_order" id="upload_bulk_order_csv">
<div class="fileformField">
<span class="formlabel"> Upload CSV File: </span>
<input class="required" required="true" type="file" name="datafile"/>
</div>
<div class="search-btn-align" id="uploadButton">
<%= submit_tag 'Validate Bulk Order', :class => 'lmargin10 uiButton' %>
</div>
</form>
<% end %>
In controller orders
def create_bulk_corder
if #errors.blank? and params[:confirm_bulk_order]=="Confirm Order"
#Send the final REST order call
else
#contents = read_csv_file(params[:datafile]) if params[:datafile].present?
validate_order(#contents)
#Populate #errors etc, etc
....
....
end
render
end
What all changes must I make for this to be possible?
You're losing your params when the confirm button is pressed because they're not part of the confirm form. You could avoid this by adding a hidden field:
<form name="confirm_bulk_order" method="post" enctype="multipart/form-data" class="search line" action="/orders/create_bulk_order" id="confirm_bulk_order">
<!-- This assumes that #contents is a simple value... it's probably not, so you might need several hidden_field_tags here, one for each part of #contents that you want in your params -->
<%= hidden_field_tag "contents", #contents %>
<!-- You probably also want to show the user some info about their submission here -->
<div class="search-btn-align" id="confirmButton">
<input type="submit" name="confirm_bulk_order" value="Confirm Order" class="lmargin10 uiButton">
</div>
</form>
If you go with this approach, be sure to re-validate params[:datafile] after submission, since a malicious user could change this param value to get around your validation logic.
Also, I suggest factoring your action into two separate actions, and likewise for the views. You've got if-else blocks where you really ought to have separate files.
I suggest maybe using a gem that deals with multi paged forms or wizards: https://www.ruby-toolbox.com/categories/rails_wizards
In Rails is it possible to achieve an HTML output like this using button_to?
<button type="submit" value="1" name="id">Type 1</button>
<button type="submit" value="2" name="id">Type 2</button>
What are the reasons for using button_to over manually entering the HTML in my form?
...
EDIT:
Perhaps I should rephrase this? Seems the better way would be to add some hidden fields to the button_to form. It doesn't seem like I can do this.
So what is the correct Rails solution to pass extra hidden fields to a dynamic form generated via a button_to? Or should I just build a form manually?
e.g. I have:
button_to "Download", items_path(:release_id => release), :remote => true
and I want to pass an extra parameter in the form POST format => "download"
Seems my answer was to use the form_tag helper
I have an ASP.NET MVC 2 form that is working perfectly, doing client side validation (using Data Annotations). Whenever users click on the submit button, client side validation kicks in before the form is actually posted back to the server.
This is the actual code, really basic stuff:
<% Html.EnableClientValidation(); %>
<% using (Html.BeginForm()) { %>
<%= Html.ValidationSummary(true) %>
<%: Html.EditorForModel() %>
<p>
<input type="submit" value="Save" />
</p>
<% } %>
Now here is my problem: I want to submit the form using a button that is not inside the < FORM > < /FORM > like the one in the sample above. This button needs to be placed inside a separate < DIV > on the page that works like a toolbar for all buttons and actions in my application.
I'm able to submit the form using something like this (using jQuery):
<asp:Content ID="Content2" ContentPlaceHolderID="ToolBarContent" runat="server">
<input type="submit" value="Save" onclick="$('#form0').submit();" />
</asp:Content>
The only problem is that this will not trigger the client side validation, as if the user was clicking in the normal submit button. The whole form is posted back, server side validation is performed and the view is rendered again showing the validation errors.
I don't want to have this regular submit button together with the form, just need to have this one in the toolbar, so is there a way to accomplish this? Having a separate button call the submit of the form while still triggering client side validation for the form?
Try this hack:
<input type="submit" value="Save" onclick="$('#dummy').click();" />
where dummy is a hidden submit button inside your form.
Also the Save button doesn't need to be a submit button if it is not placed inside a form.
Validation methods are attached to the submit event of the form, which means you should be able to call form.submit() from javascript and the submit events should still fire.
You could try jQuery's Ajax Form plugin.
http://jquery.malsup.com/form/
You can also just attach to the submit event of the form via $('#form').submit(function() { })
Try $("#yourform").validate("submit"); in case you use MicrosoftMvcValidation.js
or $("#yourform").validate() if you use jquery.validate.js