how to style and customize the rails date time select field? - css

i am having a datetime field in my table, in user view to select the date time i am using datetime_select view helper. i want to style this with bootstrap classes and i don't want the default date format that it is showing. how can i format this date time select and how can i style this field?
this is the code i am using now.
<%= f.datetime_select :check_out_req , ampm: true , :class => "form-control"%>
it's displaying datetime select drop downs in the format year,month, date,hours, minutes. but i want it to display the dropdowns in the format day,month,year,hours,minutes .
and when i apply styling like this :class => "form-control" the styling is not applyig. how to style this field?

The datetime_select method has two hashes, one for options and one for html_options. You need to tell Ruby explicitly which keys belong to which hash. Since ampm belongs in the options hash and class belongs in the html_options hash, you need to separate the hashes. In addition, if you want to re-order the drop downs, provide the order option:
<%= f.datetime_select :check_out_req, { ampm: true, order: [:day, :month, :year] }, { class: "form-control" } %>

Easily insert your datetime select field inside a span element and assign a CSS class to it. Take this snippet as an example;
HTML:
<span class="datetime"><%= f.datetime_select :check_out_req , ampm: true , :class => "form-control"%><span/>
CSS:
.datetime select:nth-child(1) {
width: 130px;
text-indent: 15px;
}

You can change the order by passing order parameter.
example:
date_select("article", "written_on", order: [:day, :month, :year])
for more detail please refer the the link:
http://apidock.com/rails/ActionView/Helpers/DateHelper/date_select

Related

How to add styling to a rails f.input styling?

I'm working on a rails form in which I have multiples options to ask for a customer. Of which one has multiple options to select from. I was able to have the list of options generated through a collection, however my problem is that I would like the list to stretch out the entire width of the container it is located in. No matter what I try, I'm not able to get anything within it to respond. What is happening is I continue to get the default styles that come with the inputs. I was wondering if anyone could take a look and help me with this situation.
= f.input :recognition, class: "recognitionStyling", collection: %w{article, blog_post, linkedin, magazine_ad, online_search, referral, twitter, other}, required: false
.recognitionStyling{
width: 100%;
}
Since you use Simple Form, you should pass your css class name into input_html options if you want set class to input:
= f.input :recognition, input_html: { class: 'recognitionStyling' }
If you want to set css class to label:
= f.input :recognition, label_html: { class: 'recognitionStyling' }
If you want to wrap both your input and label (set css class to default Simple Form wrapper):
= f.input :recognition, wrapper_html: { class: 'recognitionStyling' }

Changing the style of the 'include_blank' text using a rails collection_select form helper

I have the following collection_select field in a form, and I would like the 'Select a Garage' text to be gray (#555555) like the placeholder text for my other fields. How can I change this?
<%= collection_select :car, :garage_id, #garages.order('name ASC'), :id, :name, {include_blank: 'Select a Garage'}, { :multiple => false, class: "form-control garage-select" } %>
I am using Ruby 2.1.2 and Rails 4.1.4, as well as the simple_form gem. Thanks!
You can style the first option of the select box in your CSS.
select.garage-select > option:nth-child(1) {
color:#555;
}
EDIT
The browser default styling cannot be overwritten. You will need a library that can generate a CSS based select box. Take a look at this.

Best_in_place gem, defining a fixed input field using css

I am using best_in_place gem which is awesome for inplace editing in rails apps.
But the problem with my implementation is the area that is defined as best in place wraps only around the text and so due to which there is some kind of wobbling[1] effect if I try to edit some desired field. So is there any way where in I can make the fixed text_area size so that it stays with the width that I want.
[1] By wobbling I mean when I click on the field i.e., when the field is focus it is of some width and when I tab-out it goes to default wrapper size.
The key is defining the inner class, rather than just the class. As in:
user/show.html.erb:
<%= best_in_place #user, :name, :inner_class => "css_class" %>
custom.css:
.css_class {
background:red;
}
Not sure if this helps, but I had kind of similar problem (same problem but with the text field), and this is how I've resolved it:
First add class to the best_in_place field:
<%= best_in_place #your_variable, :name, { :classes => "input_field" } %>
(I work with best_in_place 2.1.0, for older version you would need to depend on the id of the field, which seems to be unique)
Then apply styling to the input child of the class in your css:
.input_field input {
width: 400px;
}
and that should do it.

How do I conditionally apply CSS styles in AngularJS?

Q1. Suppose I want to alter the look of each "item" that a user marks for deletion before the main "delete" button is pressed. (This immediate visual feedback should eliminate the need for the proverbial "are you sure?" dialog box.) The user will check checkboxes to indicate which items should be deleted. If a checkbox is unchecked, that item should revert back to its normal look.
What's the best way to apply or remove the CSS styling?
Q2. Suppose I want to allow each user to personalize how my site is presented. E.g., select from a fixed set of font sizes, allow user-definable foreground and background colors, etc.
What's the best way to apply the CSS styling the user selects/inputs?
Angular provides a number of built-in directives for manipulating CSS styling conditionally/dynamically:
ng-class - use when the set of CSS styles is static/known ahead of time
ng-style - use when you can't define a CSS class because the style values may change dynamically. Think programmable control of the style values.
ng-show and ng-hide - use if you only need to show or hide something (modifies CSS)
ng-if - new in version 1.1.5, use instead of the more verbose ng-switch if you only need to check for a single condition (modifies DOM)
ng-switch - use instead of using several mutually exclusive ng-shows (modifies DOM)
ng-disabled and ng-readonly - use to restrict form element behavior
ng-animate - new in version 1.1.4, use to add CSS3 transitions/animations
The normal "Angular way" involves tying a model/scope property to a UI element that will accept user input/manipulation (i.e., use ng-model), and then associating that model property to one of the built-in directives mentioned above.
When the user changes the UI, Angular will automatically update the associated elements on the page.
Q1 sounds like a good case for ng-class -- the CSS styling can be captured in a class.
ng-class accepts an "expression" that must evaluate to one of the following:
a string of space-delimited class names
an array of class names
a map/object of class names to boolean values
Assuming your items are displayed using ng-repeat over some array model, and that when the checkbox for an item is checked you want to apply the pending-delete class:
<div ng-repeat="item in items" ng-class="{'pending-delete': item.checked}">
... HTML to display the item ...
<input type="checkbox" ng-model="item.checked">
</div>
Above, we used ng-class expression type #3 - a map/object of class names to boolean values.
Q2 sounds like a good case for ng-style -- the CSS styling is dynamic, so we can't define a class for this.
ng-style accepts an "expression" that must evaluate to:
an map/object of CSS style names to CSS values
For a contrived example, suppose the user can type in a color name into a texbox for the background color (a jQuery color picker would be much nicer):
<div class="main-body" ng-style="{color: myColor}">
...
<input type="text" ng-model="myColor" placeholder="enter a color name">
Fiddle for both of the above.
The fiddle also contains an example of ng-show and ng-hide. If a checkbox is checked, in addition to the background-color turning pink, some text is shown. If 'red' is entered in the textbox, a div becomes hidden.
I have found problems when applying classes inside table elements when I had one class already applied to the whole table (for example, a color applied to the odd rows <myClass tbody tr:nth-child(even) td>). It seems that when you inspect the element with Developer Tools, the element.style has no style assigned. So instead of using ng-class, I have tried using ng-style, and in this case, the new CSS attribute does appear inside element.style. This code works great for me:
<tr ng-repeat="element in collection">
[...amazing code...]
<td ng-style="myvar === 0 && {'background-color': 'red'} ||
myvar === 1 && {'background-color': 'green'} ||
myvar === 2 && {'background-color': 'yellow'}">{{ myvar }}</td>
[...more amazing code...]
</tr>
Myvar is what I am evaluating, and in each case I apply a style to each <td> depending on myvar value, that overwrites the current style applied by the CSS class for the whole table.
UPDATE
If you want to apply a class to the table for example, when visiting a page or in other cases, you can use this structure:
<li ng-class="{ active: isActive('/route_a') || isActive('/route_b')}">
Basically, what we need to activate a ng-class is the class to apply and a true or false statement. True applies the class and false doesn't. So here we have two checks of the route of the page and an OR between them, so if we are in /route_a OR we are in route_b, the active class will be applied.
This works just having a logic function on the right that returns true or false.
So in the first example, ng-style is conditioned by three statements. If all of them are false, no style is applied, but following our logic, at least one is going to be applied, so, the logic expression will check which variable comparison is true and because a non empty array is always true, that will left an array as return and with only one true, considering we are using OR for the whole response, the style remaining will be applied.
By the way, I forgot to give you the function isActive():
$rootScope.isActive = function(viewLocation) {
return viewLocation === $location.path();
};
NEW UPDATE
Here you have something I find really useful. When you need to apply a class depending on the value of a variable, for example, an icon depending on the contents of the div, you can use the following code (very useful in ng-repeat):
<i class="fa" ng-class="{ 'fa-github' : type === 0,
'fa-linkedin' : type === 1,
'fa-skype' : type === 2,
'fa-google' : type === 3 }"></i>
Icons from Font Awesome
This works well when ng-class can't be used (for example when styling SVG):
ng-attr-class="{{someBoolean && 'class-when-true' || 'class-when-false' }}"
(I think you need to be on latest unstable Angular to use ng-attr-, I'm currently on 1.1.4)
I have published an article on working with AngularJS+SVG. It talks about this issue and numerous others. http://www.codeproject.com/Articles/709340/Implementing-a-Flowchart-with-SVG-and-AngularJS
span class="circle circle-{{selectcss(document.Extension)}}">
and code
$scope.selectcss = function (data) {
if (data == '.pdf')
return 'circle circle-pdf';
else
return 'circle circle-small';
};
css
.circle-pdf {
width: 24px;
height: 24px;
font-size: 16px;
font-weight: 700;
padding-top: 3px;
-webkit-border-radius: 12px;
-moz-border-radius: 12px;
border-radius: 12px;
background-image: url(images/pdf_icon32.png);
}
This solution did the trick for me
<a ng-style="{true: {paddingLeft: '25px'}, false: {}}[deleteTriggered]">...</a>
You can use ternary expression. There are two ways to do this:
<div ng-style="myVariable > 100 ? {'color': 'red'} : {'color': 'blue'}"></div>
or...
<div ng-style="{'color': (myVariable > 100) ? 'red' : 'blue' }"></div>
Another option when you need a simple css style of one or two properties:
View:
<tr ng-repeat="element in collection">
[...amazing code...]
<td ng-style="{'background-color': getTrColor(element.myvar)}">
{{ element.myvar }}
</td>
[...more amazing code...]
</tr>
Controller:
$scope.getTrColor = function (colorIndex) {
switch(colorIndex){
case 0: return 'red';
case 1: return 'green';
default: return 'yellow';
}
};
See the following example
<!DOCTYPE html>
<html ng-app>
<head>
<title>Demo Changing CSS Classes Conditionally with Angular</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<script src="res/js/controllers.js"></script>
<style>
.checkboxList {
border:1px solid #000;
background-color:#fff;
color:#000;
width:300px;
height: 100px;
overflow-y: scroll;
}
.uncheckedClass {
background-color:#eeeeee;
color:black;
}
.checkedClass {
background-color:#3ab44a;
color:white;
}
</style>
</head>
<body ng-controller="TeamListCtrl">
<b>Teams</b>
<div id="teamCheckboxList" class="checkboxList">
<div class="uncheckedClass" ng-repeat="team in teams" ng-class="{'checkedClass': team.isChecked, 'uncheckedClass': !team.isChecked}">
<label>
<input type="checkbox" ng-model="team.isChecked" />
<span>{{team.name}}</span>
</label>
</div>
</div>
</body>
</html>
As of AngularJS v1.2.0rc, ng-class and even ng-attr-class fail with SVG elements (They did work earlier, even with normal binding inside the class attribute)
Specifically, none of these work now:
ng-class="current==this_element?'active':' ' "
ng-attr-class="{{current==this_element?'active':' '}}"
class="class1 class2 .... {{current==this_element?'active':''}}"
As a workaround, I've to use
ng-attr-otherAttr="{{current==this_element?'active':''}}"
and then style using
[otherAttr='active'] {
... styles ...
}
One more (in the future) way to conditionally apply style is by conditionally creating scoped style
<style scoped type="text/css" ng-if="...">
</style>
But nowadays only FireFox supports scoped styles.
There is one more option that I recently discovered that some people may find useful because it allows you to change a CSS rule within a style element - thus avoiding the need for repeated use of an angular directive such as ng-style, ng-class, ng-show, ng-hide, ng-animate, and others.
This option makes use of a service with service variables which are set by a controller and watched by an attribute-directive I call "custom-style". This strategy could be used in many different ways, and I attempted to provide some general guidance with this fiddle.
var app = angular.module('myApp', ['ui.bootstrap']);
app.service('MainService', function(){
var vm = this;
});
app.controller('MainCtrl', function(MainService){
var vm = this;
vm.ms = MainService;
});
app.directive('customStyle', function(MainService){
return {
restrict : 'A',
link : function(scope, element, attr){
var style = angular.element('<style></style>');
element.append(style);
scope.$watch(function(){ return MainService.theme; },
function(){
var css = '';
angular.forEach(MainService.theme, function(selector, key){
angular.forEach(MainService.theme[key], function(val, k){
css += key + ' { '+k+' : '+val+'} ';
});
});
style.html(css);
}, true);
}
};
});
well i would suggest you to check condition in your controller with a function returning true or false .
<div class="week-wrap" ng-class="{today: getTodayForHighLight(todayDate, day.date)}">{{day.date}}</div>
and in your controller check the condition
$scope.getTodayForHighLight = function(today, date){
return (today == date);
}
One thing to watch is - if the CSS style has dashes - you must remove them. So if you want to set background-color, the correct way is:
ng-style="{backgroundColor:myColor}"
Here's how i conditionally applied gray text style on a disabled button
import { Component } from '#angular/core';
#Component({
selector: 'my-app',
styleUrls: [ './app.component.css' ],
template: `
<button
(click)='buttonClick1()'
[disabled] = "btnDisabled"
[ngStyle]="{'color': (btnDisabled)? 'gray': 'black'}">
{{btnText}}
</button>`
})
export class AppComponent {
name = 'Angular';
btnText = 'Click me';
btnDisabled = false;
buttonClick1() {
this.btnDisabled = true;
this.btnText = 'you clicked me';
setTimeout(() => {
this.btnText = 'click me again';
this.btnDisabled = false
}, 5000);
}
}
Here's a working example:
https://stackblitz.com/edit/example-conditional-disable-button?file=src%2Fapp%2Fapp.component.html

User's Personal CSS Stylesheet in Ruby on Rails

I have looked around but I can't find a lead on what I need to do to make the following possible:
This question assumes I have all model controllers working properly and the named CSS attributes are defined in the default stylesheet.
I am wanting users to be able to select a few CSS attributes to personalize their own theme when they login. The basics attributes would be the "body" and "page-wrapper" colour. (foreground)
I am wanting them to be able to select these attributes (from a form?) in the user's edit page. (which is already created)
Any ideas as to how I could make this work or a good lead in the right direction?
Thanks for your help.
I think the best approach is via javascript, generating an style tag on the head with the desired styles. Jquery gives a simple way to do that, and you can store the styles on a column in your model.
Something like this:
class User
attr_accesible :styles
view.erb
<script>
// Assume the #styles attr has something like "body { background-color: #567;}"
$('head').append($('<style>').html('<%= #user.styles %>'))
</script>
#styles will be another column in your model, so you should add it with a migration
rails g migration addstylestousers styles:string
in your form.erb
<%= f.label :styles %>
<%= f.text_field :styles %>
I think it's simple enough for the user to put the css style here as long as you give him enough tips like "add body { background-color: red } in this field to make you background red!".
About serialization, consider this.
If you want to nest the styles, then the script will be
//Lets say that the user stored on #bgcolor and #fgcolor only css color codes, like '#222' or 'blue'
var bgc = '<%= #user.style.bgcolor %>'
var fgc = '<%= #user.style.fgcolor %>'
var style = 'body { background-color: ' + bgc + '; foreground-color: ' + fgc + ' }'
$('head').append($('<style>').html(style))
Remember that relationship should be User has_one :style on this case. However, nesting it's getting yourself into more problem, I don't think it's worth it at all.

Resources