I'm trying to style my devise forms. So far I have done so by adding classes and IDs into the forms found in app/views/devise. However, I haven't been able to find where the form for /users/password/new (new_password_path) exists. It renders a button with "send me reset password instructions" on it; I did a search through my app and can't find where that comes from... Would that be in the Devise gem itself?
TL/DR: How can I style the forgot password view?
Thanks in advance.
Similar to the Registrations and Sessions behaviour Devise provides a default Passwords view and controller that isn't automatically generated in your own application folder structure.
To override the Forgotten Password view create new.html.erb in a views/devise/passwords folder. You can see the default views on Devise's GitHub: https://github.com/plataformatec/devise/tree/master/app/views/devise/passwords
To override the PasswordsController create passwords_controller.rb in your app/controllers folder that inherits from the Devise controller and override whatever you need. For example to supply a non-default layout.
class PasswordsController < Devise::PasswordsController
include ApplicationHelper
layout "minimal"
end
You then need to change your routes.rb file to specify the custom controller should be used by devise:
devise_for :users, :controllers => {:registrations => "registrations", :sessions => "sessions", :passwords => "passwords"}
In you development.rb
config.action_mailer.raise_delivery_errors = true
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
config.action_mailer.perform_deliveries = true
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
:address => 'smtp.gmail.com',
:port => your_port_num,
:domain => 'site.com',
:user_name => 'admin#site.com',
:enable_starttls_auto => true,
:password => 'none' }
Your path with be redirected in mail.
Related
I have CSS file that needs to be embedded by the user. Now for the user to customize the CSS file as he/she wishes (change the colors and font-size mainly) I have to store that information in database file, append that information to specfic CSS file and then enable that user to embed it.
I would get the id of the User that I wish to change. So color codes stored are basically extracted from,
User.find(params[:id]).main_color
# This would return => #fffff
This what my embed code looks like right now,
<link href="link.com/initial.css" type="text/css" rel="stylesheet" />
<script type="text/javascript" data-user="18" src="link.com/some_file.js" />
Here data-user is the id of the user who is modifying the CSS file. (The IFrame is being embedded using the javascript file)
How should I modify my embed code and fetch the custom variables from my database in order to make the CSS cstomizable as the user wants?
Thanks in advance.
P.S I have thought of rewriting the CSS in the view(.html.erb file) and using !important there along with proper color codes selected by the user but that approach is not exactly very efficient.
I think the best way is to keep your script file at the server side, So you can easily modify your script depending on user database options
for example:
place a new route in routs.rb
post '/users/modify_style', :to => 'users#modify_style', :as => modify_style
then allow the route to respond to user by JavaScript file, for example if the user needs to change the main color of HTML template using a button or a link; so the form button in template may look like:
<%= button_to 'apply style', modify_style_path, :data => {:user_id => current_user.id}, :remote => true %>
or
<%= link_to 'apply style', modify_style_path(:user_id => current_user.id), :method => :post, :remote => true %>
so remote: true option will allow sending data to server through AJAX without refreshing the page.
at users_controller.rb
def modify_style
user = User.find(params[:user_id])
#main_color = user.main_color
respond_to do |format|
format.js { render 'some_file.js.erb' }
end
end
and in your js file:
$('#some_element_id_to_change_color_for').css('color', '<%= #main_color %>')
or you can add modify_style action code directly to the original action which load your page to appy user style once the page is loaded.
I would suggest you to directly use it in the erb file something like
my.html.erb
<html>
<!-- my html -- >
</html>
<style>
<%= my_css.html_safe %>
</style>
I have used data-confirm attribute with Html::a tags in datagrids and it worked. But now I want to use it with a button like this:
<?php echo Html::button("<span class='icon delete'></span>", [
"class" => "delete",
"title" => Yii::t("app-upload-list", "delete"),
"data-confirm" => Yii::t("yii", "Are you sure you want to delete this item?"),
])
I don't use anchor here because this button doesn't do anything in server-side.
But when I attach a click event to the button, it precedes the confirm box. I can get round it by write the confirm code myself in the click event and use a data-my-confirm (or so) attribute to prevent the double confirm boxes, but it is not so nice. Can I do that with data-confirm?
I had the same problem. Here is Yii's listener (yii.js, line 486):
// handle data-confirm and data-method for clickable and changeable elements
$(document).on('click.yii', pub.clickableSelector, handler)
.on('change.yii', pub.changeableSelector, handler);
It uses Event Delegation
Event delegation allows us to attach a single event listener, to a
parent element, that will fire for all descendants matching a
selector, whether those descendants exist now or are added in the
future.
In this case, the listener is attached to the document node, which is listening for clicks to bubble up from the clicked element. Listeners placed on the clickable elements themselves or anything that is a child of the document node will fire before those on the document node i.e. before Yii's listener.
To ensure Yii's listener fires before your listener you will have to attach your listener to the document node as Yii has done; Listeners on the same node are invoked in the order of their registration.
$(document).on('click', '.delete', yourHandlerFunction);
Note: Event delegation is used when you need a listener for elements that don't necessarily exist when the listener is added or to listen to a single node rather than several. It is usually recommended to use the nearest parent element that exists at the time of adding the listener and that continues to exist while needed. I wouldn't suggest putting listeners on the document node without good reason.
Even if it's an old question I'd like to contribute what I know.
In case you want to use html::button() instead of html::a()
Here is an example
<?php echo Html::button("<span class='icon delete'></span>", [
"class" => "delete",
"title" => Yii::t("app-upload-list", "delete"),
"onclick" => 'if(confirm("Are you sure you want to delete this item?")){
return true;
}else{
return false;
}',
]) ?>
I'm sure it should work.
I think you can find an example of something similar to that in the Yii2 template of a View.
In my view I have the following code:
<?= Html::a('Delete', ['delete'], [
'class' => 'btn btn-danger',
'data' => [
'confirm' => 'Are you sure you want to delete this item?',
'method' => 'post',
],
]) ?>
I have to admit that I have not try to use it with Html::button. But you can try something like this:
<?php echo Html::button("<span class='icon delete'></span>", [
"class" => "delete",
"title" => Yii::t("app-upload-list", "delete"),
"data" => [
'confirm' => 'Are you sure you want to delete this item?',
'method' => 'post',
],
]) ?>
EDIT:
Yes, this way do not Work.
What is recommended is to use a link (Html::a) and style it as you wish.
If you want to submit a Form you should use: Html::submitButton()
If you want to use a button... you can make it work with jQuery as mentioned by Stu here: https://stackoverflow.com/a/12697511/2437857
I can't seem to be able to use translations with variables in Sonata as I do in normal symfony controllers.
In my controller:
$this->setSonataFlashSuccess(
$this->get('translator')->trans('flash_create_success', [
'%link%' => 'abcd',
'%id%' => '1234'
])
);
My template:
{{ message|trans|raw }}
My translations file 'SonataAdminBundle.yml':
flash_create_success: Created with success: #%id%
The rendered HTML:
Created with success: #%id%
So the translation worked but not the replacement of the expressions Link and Id. Is there something especial about translations in Sonata? Everything works fine in the rest of the app.
When you write a translations file, you have to name it differently than the original (e.g. admin_messages.[langage].yml), otherwise the original SonataAdminBundle.[locale].yml will be used.
So, you should create a file in your bundle like :
# YourBundle/Resources/translations/admin_messages.en.yml`
flash_create_success: Created with success: #%id%
And specify it in your controller :
$this->get('translator')->trans(
'flash_create_success',
array(
'%link%' => 'abcd',
'%id%' => '1234'
),
'admin_messages', // By default looks for a "messages.[_locale].yml"
);
Note that you don't need to translate the message one more time in your template, as it is already translated in your controller.
I have an MVC 4 application with a Kendo UI grid that I am using for user management. I display the users information in the grid and have a custom command button that when clicked opens a new page to edit the users information. For various reasons (one being there is too much information to be edited to display in the grid) I need to edit the users on a new page and not with inline or popup or incell editing. My grid looks like this... very simple
#(Html.Kendo().Grid<WebSiteNew.Models.ManageUsersViewModel>()
.Name("grid")
.HtmlAttributes(new { style = "margin-top: 5px" })
.Columns(c =>
{
c.Bound(model => model.UserName);
c.Bound(model => model.FirstName);
c.Bound(model => model.LastName);
c.Bound(model => model.Email);
c.Bound(model => model.Phone);
c.Bound(model => model.Extension);
c.Bound(model => model.JobTitle);
c.Command(com => { com.Custom("Edit").Click("edit"); com.Destroy(); });
})
.Pageable()
.Sortable()
.Selectable()
.DataSource(d => d
.Ajax()
.PageSize(20)
.Model(m => m.Id(i => i.UserName))
.Read(r => r.Action("ManageUsers_Read", "ManageUsers"))
.Destroy(o => o.Action("ManageUsers_Destroy", "ManageUsers"))
))
The issue I have here is that I need to pass the ID of the user that the edit button has been clicked on to the edit screen so that I can bring up the information for the selected user. The only way I know of to get this information is through javascript, something like this in my command button click function...
function edit() {
var grid = $("#grid").data("kendoGrid");
var row = grid.select();
var dataItem = grid.dataItem(row);
var id = dataItem.UserId;
location = "#Url.Action("EditUser")";
}
This gives me the id that I need but I have no way (that I know of) to pass this back to my controller. So my question is... how do I get this information back to the server side? Is there another way to get the information I need or is this just something that is not possible in Kendo UI MVC?
To make this a more general question.. when I look at the Kendo UI documentation and it tells me how to get a value in javascript... how, in general, does one go about using this value in an MVC application when it is needed on the server side? I can't seem to find an alternative "MVC" way to do this in their documentation.
You should form additional parameters to url string:
location = "#Url.Action("EditUser")" + "?id="+id;
I want to disable the "Advanced ..." (content_status_history) link in the workflow status menu for other roles except Managers and Site Administrators. Is there a permission that I can use to do this? Or is this link's permission coupled with the presence of a transition?
The link's presence is coupled to there being a workflow transition. The form it links to offers additional options to set for the transitions that are available on the current object. There is no permission that controls it's presence; the menu item is hardcoded.
From the plone.app.contentmenu.menu source:
if len(results) > 0:
results.append({ 'title' : _(u'label_advanced', default=u'Advanced...'),
'description' : '',
'action' : url + '/content_status_history',
'selected' : False,
'icon' : None,
'extra' : {'id': 'advanced', 'separator': 'actionSeparator', 'class': 'kssIgnore'},
'submenu' : None,
})
To provide your own implementation (perhaps using a subclass that removes the last option again if certain conditions are met), you'd have to use an override to redefine the browser:menu registration.
In your overrides.zcml you'd have to point to your own implementation using the following browser:menu declaration:
<browser:menu
id="plone_contentmenu_workflow"
title="The 'workflow' menu - allows the user to execute workflow transitions"
class=".yourmodule.YourWorkflowMenu"
/>
then in yourmodule.py create a YourWorkflowMenu class, something like:
from plone.app.contentmenu.menu import WorkflowMenu
class YourWorkflowMenu(WorkflowMenu):
def getMenuItems(self, context, request):
results = super(YourWorkflowMenu, self).getMenuItems(context, request)
if len(results) > 0 and someothercondition:
# Remove status history menu item ('Advanced...')
results = [r for r in results
if not r['action'].endswith('/content_status_history')]
return results
You should be able to hide the menu item by adding
a#advanced {
display: none;
}
to your styles.
That's a pragmatic solution compared the bloated former clean solution.