Bootstrap styled button not being applied to Phoenix delete link - npm

Elixir version: 1.3.2
Phoenix version: 1.2.1
NodeJS version: 4.4.6
NPM version: 3.10.6
Brunch version: 2.7.4
Operating system: Mac OSX
I am trying to create what suppose to be a simple link using Phoenix's link helper function.
<li><%= link "Logout", to: session_path(#conn, :delete, user), method: :delete %></li>
renders
<form action="/logout/1" class="link" method="post">
<input name="_method" type="hidden" value="delete">
<input name="_csrf_token" type="hidden" value="VhxiLApJElIS...removed for clarity">
<a data-submit="parent" href="#" rel="nofollow">Logout</a>
</form>
The button works fine and the user logs out but the styling of the button isn't being applied. See below:
The "logout" button should be aligned with and contain hover effects like the "Home" button . What is removing the styling of the logout button?
When a user logs out the styling returns:
Here are other related issues on the delete link functionality.
Delete link not working phoenix
https://github.com/phoenixframework/phoenix/issues/1204
https://github.com/phoenixframework/phoenix/issues/1408
https://github.com/phoenixframework/phoenix/issues/1319
Here's what I've tried based on the other issues I've found:
run brunch build- compilation succeeds
change the link function to button
Hopefully this is enough information to get some input.

The delete links do create a form and this is expected. If you look at what the generators create, its something like below:
<%= link "Delete", to: schedule_path(#conn, :delete, schedule), method: :delete, data: [confirm: "Are you sure?"], class: "btn btn-danger btn-xs" %>
You cannot call a delete or post method from a anchor directly, so Phoenix makes a form for you. It's a convenience feature, but can be confusing at first. So if the form is not working the problem may be in your controller not with the form itself.

Related

How can I submit a form on input change with Turbo Streams?

I have a form I want to submit automatically whenever any input field is changed. I am using Turbo Streams, and if I use onchange: "this.form.submit()" it isn't captured by Turbo Streams and Rails uses a standard HTML response. It works fine when clicking the submit button. How can I work around this?
There is a discussion on the hotwire forum, where Mark Godwin figured out why form.submit() isn't working with turbo:
Turbo intercepts form submission events, but weirdly, the JS formElement.submit() method does not trigger the submit event.
And Jacob Daddario figures out that you can use form.requestSubmit() instead:
It turns out that the turbo-stream mechanism listens for form submission events, and for some reason the submit() function does not emit a form submission event. That means that it’ll bring back a normal HTML response. That said, it looks like there’s another method, requestSubmit() which does issue a submit event.
So you can change your code slightly, and use requestSubmit() if a browser supports it, and use submit() if not:
onchange: "this.form.requestSubmit ? this.form.requestSubmit() : this.form.submit()"
Update:
As BenKoshy pointed out, in Turbo 7.1.0, a polyfill was added so you can use form.requestSubmit() without checking for browser support, so you can add this to your input field:
onchange: "this.form.requestSubmit()"
I need to implement this for an app with lots of forms. I wound up using Stimulus. Below is the whole controller:
import { Controller } from "stimulus"
const _ = require("lodash")
export default class extends Controller {
connect() {
let that = this;
that.element.addEventListener('change', _.debounce(that.handleChange, 500))
}
handleChange(event) {
event.preventDefault()
// event.target.name // => "user[answer]"
// event.target.value // => <user input string>
event.target.form.requestSubmit()
}
}
and here it's used in a form with a single text input. NOTE the controller is attached to the form, not to the inputs.
<%= turbo_frame_tag dom_id(form_model) do %>
<%= form_with model: form_model,
format: :turbo_stream,
html: { data: { controller: "buttonless-form" } } do |f| %>
<%= f.hidden_field :question_id, value: question.id %>
<%= f.text_field :answer_value, class: "input shadow wide", placeholder: "Enter your answer here" %>
<% end %>
<div id=<%= "question_#{question.id}_output" %>>
<p> <!-- feedback to the user shows up here via Turbo -->
</div>
<% end %> <!-- end turbo frame -->

Re-using a stimulus action elsewhere on the page?

I am wiring up a slack clone (html/css) and have it so that the reference drawer opens/closes when I click on the x. I am wanting to also open/close it from the navigation area and thought I could just take the same link_to and call it from a different part of the page.
But when I do that, if I'm calling it from within a different target, I get an error
Error invoking action "click->navigation#toggle_reference_drawer"
Error: Missing target element "navigation.referenceDrawer"
How can I use code inside a data-target to trigger a different data-target?
i.e. what I'm trying to get working is
--navigation partial (link_to doesn't work) --
<div data-navigation-target="storyNavLinks">
<div class ="story">
<%= link_to "[x]", "#", data: { action: "click->navigation#hide_reference_drawer" } %>
</div>
</div>
-- application partial (link_to works) --
<div data-navigation-target="referenceDrawer">
<div class='reference box'>
<%= link_to "[x]", "#", data: { action: "click->navigation#hide_reference_drawer" } %>
</div>
</div>
Not sure where I'm going wrong.. I figured as long as the target being referenced is unique and on the page it shouldn't matter where it's being called from?
You have to make sure your data-controller attribute is on an element that wraps both targets. If that is not possible you can always include the controller twice but the targets will only be scoped to each instance so you will need to add them twice as well.

Google+ Sign-In button custom image

I've implemented Sign-In using Google's tutorials, but the button doesn't really fit in with the design of the website I'm using it in. I'd like to use an image my graphic designer made instead. Is it currently possible to use a custom image for Sign-In buttons?
You can use gapi.signin.render to render a specified container as a sign-in button.
For example if in your HTML code you have:
<button id="mySignIn">SignIn</button>
The Javascript call would be something like:
gapi.signin.render("mySignIn", {
'callback': signinCallback,
'clientid': 'CLIENT_ID',
'cookiepolicy': 'single_host_origin',
'requestvisibleactions': 'http://schemas.google.com/AddActivity',
'scope': 'https://www.googleapis.com/auth/plus.login'
});
Also, remember to follow the branding guidelines.
The following code is used to add the login button to the page right?
<span id="signinButton">
<span
class="g-signin"
data-callback="signinCallback"
data-clientid="CLIENT_ID"
data-cookiepolicy="single_host_origin"
data-requestvisibleactions="http://schemas.google.com/AddActivity"
data-scope="https://www.googleapis.com/auth/plus.login">
</span>
</span>
Have you tried to simply replace the class "g-signin" with your own class??
If g-signin is required for google themselves, to determine which is the actual signin button, you could always add a subclass to it.
<span class="g-signin custom" ...></span>
In your CSS this would be shown as:
.g-signin .custom {
/*properties*/
}

rendering a partial Rails3.x + coffeescript

I have the following requirement. I have a 'school' drop down and as the last options I have add new school, so if the user selects that option I want to load the new_school form as a partial via ajax.
I'm on
gem 'rails', '3.2.9'
gem 'coffee-rails', '~> 3.2.1'
Jquery via gem 'jquery-rails'
Earlier with rails < 3 and prototype I used to do it with
Ajax.Updater (aka Rails link_to_remote :update => 'some_div')
and with rails > 3 + JQuery I'm familiar with *.js.erb, and having something like
$("#school_form").html("<%= escape_javascript(render(:partial => "form"))%>");
But I'm new to coffeescript and I have no idea on how to do this with coffeescript, can someone help me :), (because I believe you shouldn't have to do a server request for this)
So far I have done following to catch the select_tag change event
$ ->
$('#school_name_select').change ->
unless $(this).val()
$('school_name').html([I want to have the _new_school_form partial here])
Use a hidden div.
In general, you don't want to bother trying to mix JS and HTML. The escaping can be complicated, error-prone, and flat out dangerous due to the possibility of cross-site scripting attacks.
Simply render your form partial in a div that's not displayed by default. In ERB:
<div id="school_name_form" style="display: none;">
<%= render 'form' %>
</div>
In your CoffeeScript:
$ ->
$('#school_name_select').change ->
if $(this).val()
$('#school_name_form').slideUp()
else
$('#school_name_form').slideDown()
I recommend using a small, tasteful transition like slide or fade. It gives your app a more polished feel.
No AJAX is required. This pattern is so common that I have an application-wide style defined as follows.
.not-displayed {
display: none;
}
Then using HAML (if you're into that), the HTML template becomes simply:
#school_name_form.not-displayed
= render 'form'
You can try to render the form partial inside hidden div (not too correct from semantic point of view), or put the form html as data attribute of any relevant element, something like
f.select school_name, ... , data: {form: escape_javascript(render(:partial => "form"))}
And the Coffeescript
$ ->
$('#school_name_select').change ->
unless $(this).val()
$('school_name').html($('#school_name_select').data('form'))

In Rails 3, how can you make a div a button (a clickable div that links to a new page)

I know that there are options to do this manually, such as here : How do you make the entire DIV clickable to go to another page?
However, in Rails 3 we make links like this:
<%= link_to "name", url %>
And I am wondering -- is there a proper Rails way to make a whole div a button. I realize I could make a button. However, let's say I want to fill it with content like text and a picture - then how would I make that whole div clickable in a rails way?
For example:
<%= #story.title %>
<%= #story.blurb %>
In this example, I would want to make #story clickable, with the rails generated content that I specified.. Any ideas?
For those interested, the answer is:
<div class="class_name">
<%= link_to content_tag(:span, "Text for the LInk"), route %>
</div>
And then, in the CSS set .class_name to position:relative; and:
.class_name span {
width:100%;
height:100%;
position:absolute;
z-index:2;
top:0px;
left:0px;
}
The link will now assume the size of its parent container, and thus give the impression the whole container is a link.
I think that button_to is what you need :
http://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html#method-i-button_to
I might use jquery if you really wanted to do this
$(document).ready(function() {
$('#somediv').click(function(event){
document.location = 'http://someplace.com';
});
});
You can't make a "clickable" raw div like that in a rails way... the concept doesn't make any sense. That's just not how it works
(added missing close parens for click)
not tested