.
8 | .list-group {
9 | // No need to set list-style: none; since .list-group-item is block level
10 | margin-bottom: 20px;
11 | padding-left: 0; // reset padding because ul and ol
12 | }
13 |
14 | // Individual list items
15 | // -------------------------
16 |
17 | .list-group-item {
18 | position: relative;
19 | display: block;
20 | padding: 10px 15px;
21 | // Place the border on the list items and negative margin up for better styling
22 | margin-bottom: -1px;
23 | background-color: @list-group-bg;
24 | border: 1px solid @list-group-border;
25 |
26 | // Round the first and last items
27 | &:first-child {
28 | .border-top-radius(@list-group-border-radius);
29 | }
30 | &:last-child {
31 | margin-bottom: 0;
32 | .border-bottom-radius(@list-group-border-radius);
33 | }
34 |
35 | // Align badges within list items
36 | > .badge {
37 | float: right;
38 | }
39 | > .badge + .badge {
40 | margin-right: 5px;
41 | }
42 |
43 | // Linked list items
44 | a& {
45 | color: @list-group-link-color;
46 |
47 | .list-group-item-heading {
48 | color: @list-group-link-heading-color;
49 | }
50 |
51 | // Hover state
52 | &:hover,
53 | &:focus {
54 | text-decoration: none;
55 | background-color: @list-group-hover-bg;
56 | }
57 | }
58 |
59 | // Active class on item itself, not parent
60 | &.active,
61 | &.active:hover,
62 | &.active:focus {
63 | z-index: 2; // Place active items above their siblings for proper border styling
64 | color: @list-group-active-color;
65 | background-color: @list-group-active-bg;
66 | border-color: @list-group-active-border;
67 |
68 | // Force color to inherit for custom content
69 | .list-group-item-heading {
70 | color: inherit;
71 | }
72 | .list-group-item-text {
73 | color: lighten(@list-group-active-bg, 40%);
74 | }
75 | }
76 | }
77 |
78 | // Custom content options
79 | // -------------------------
80 |
81 | .list-group-item-heading {
82 | margin-top: 0;
83 | margin-bottom: 5px;
84 | }
85 | .list-group-item-text {
86 | margin-bottom: 0;
87 | line-height: 1.3;
88 | }
89 |
--------------------------------------------------------------------------------
/app/bower_components/bootstrap/less/media.less:
--------------------------------------------------------------------------------
1 | // Media objects
2 | // Source: http://stubbornella.org/content/?p=497
3 | // --------------------------------------------------
4 |
5 |
6 | // Common styles
7 | // -------------------------
8 |
9 | // Clear the floats
10 | .media,
11 | .media-body {
12 | overflow: hidden;
13 | zoom: 1;
14 | }
15 |
16 | // Proper spacing between instances of .media
17 | .media,
18 | .media .media {
19 | margin-top: 15px;
20 | }
21 | .media:first-child {
22 | margin-top: 0;
23 | }
24 |
25 | // For images and videos, set to block
26 | .media-object {
27 | display: block;
28 | }
29 |
30 | // Reset margins on headings for tighter default spacing
31 | .media-heading {
32 | margin: 0 0 5px;
33 | }
34 |
35 |
36 | // Media image alignment
37 | // -------------------------
38 |
39 | .media {
40 | > .pull-left {
41 | margin-right: 10px;
42 | }
43 | > .pull-right {
44 | margin-left: 10px;
45 | }
46 | }
47 |
48 |
49 | // Media list variation
50 | // -------------------------
51 |
52 | // Undo default ul/ol styles
53 | .media-list {
54 | padding-left: 0;
55 | list-style: none;
56 | }
57 |
--------------------------------------------------------------------------------
/app/bower_components/bootstrap/less/modals.less:
--------------------------------------------------------------------------------
1 | //
2 | // Modals
3 | // --------------------------------------------------
4 |
5 | // .modal-open - body class for killing the scroll
6 | // .modal - container to scroll within
7 | // .modal-dialog - positioning shell for the actual modal
8 | // .modal-content - actual modal w/ bg and corners and shit
9 |
10 | // Kill the scroll on the body
11 | .modal-open {
12 | overflow: hidden;
13 |
14 |
15 | // Account for hiding of scrollbar
16 | body&,
17 | .navbar-fixed-top,
18 | .navbar-fixed-bottom {
19 | margin-right: 15px
20 | }
21 | }
22 |
23 | // Container that the modal scrolls within
24 | .modal {
25 | display: none;
26 | overflow: auto;
27 | overflow-y: scroll;
28 | position: fixed;
29 | top: 0;
30 | right: 0;
31 | bottom: 0;
32 | left: 0;
33 | z-index: @zindex-modal-background;
34 |
35 | // When fading in the modal, animate it to slide down
36 | &.fade .modal-dialog {
37 | .translate(0, -25%);
38 | .transition-transform(~"0.3s ease-out");
39 | }
40 | &.in .modal-dialog { .translate(0, 0)}
41 | }
42 |
43 | // Shell div to position the modal with bottom padding
44 | .modal-dialog {
45 | margin-left: auto;
46 | margin-right: auto;
47 | width: auto;
48 | padding: 10px;
49 | z-index: (@zindex-modal-background + 10);
50 | }
51 |
52 | // Actual modal
53 | .modal-content {
54 | position: relative;
55 | background-color: @modal-content-bg;
56 | border: 1px solid @modal-content-fallback-border-color; //old browsers fallback (ie8 etc)
57 | border: 1px solid @modal-content-border-color;
58 | border-radius: @border-radius-large;
59 | .box-shadow(0 3px 9px rgba(0,0,0,.5));
60 | background-clip: padding-box;
61 | // Remove focus outline from opened modal
62 | outline: none;
63 | }
64 |
65 | // Modal background
66 | .modal-backdrop {
67 | position: fixed;
68 | top: 0;
69 | right: 0;
70 | bottom: 0;
71 | left: 0;
72 | z-index: (@zindex-modal-background - 10);
73 | background-color: @modal-backdrop-bg;
74 | // Fade for backdrop
75 | &.fade { .opacity(0); }
76 | &.in { .opacity(.5); }
77 | }
78 |
79 | // Modal header
80 | // Top section of the modal w/ title and dismiss
81 | .modal-header {
82 | padding: @modal-title-padding;
83 | border-bottom: 1px solid @modal-header-border-color;
84 | min-height: (@modal-title-padding + @modal-title-line-height);
85 | }
86 | // Close icon
87 | .modal-header .close {
88 | margin-top: -2px;
89 | }
90 |
91 | // Title text within header
92 | .modal-title {
93 | margin: 0;
94 | line-height: @modal-title-line-height;
95 | }
96 |
97 | // Modal body
98 | // Where all modal content resides (sibling of .modal-header and .modal-footer)
99 | .modal-body {
100 | position: relative;
101 | padding: @modal-inner-padding;
102 | }
103 |
104 | // Footer (for actions)
105 | .modal-footer {
106 | margin-top: 15px;
107 | padding: (@modal-inner-padding - 1) @modal-inner-padding @modal-inner-padding;
108 | text-align: right; // right align buttons
109 | border-top: 1px solid @modal-footer-border-color;
110 | .clearfix(); // clear it in case folks use .pull-* classes on buttons
111 |
112 | // Properly space out buttons
113 | .btn + .btn {
114 | margin-left: 5px;
115 | margin-bottom: 0; // account for input[type="submit"] which gets the bottom margin like all other inputs
116 | }
117 | // but override that for button groups
118 | .btn-group .btn + .btn {
119 | margin-left: -1px;
120 | }
121 | // and override it for block buttons as well
122 | .btn-block + .btn-block {
123 | margin-left: 0;
124 | }
125 | }
126 |
127 | // Scale up the modal
128 | @media screen and (min-width: @screen-tablet) {
129 |
130 | .modal-dialog {
131 | left: 50%;
132 | right: auto;
133 | width: 600px;
134 | padding-top: 30px;
135 | padding-bottom: 30px;
136 | }
137 | .modal-content {
138 | .box-shadow(0 5px 15px rgba(0,0,0,.5));
139 | }
140 |
141 | }
142 |
--------------------------------------------------------------------------------
/app/bower_components/bootstrap/less/pager.less:
--------------------------------------------------------------------------------
1 | //
2 | // Pager pagination
3 | // --------------------------------------------------
4 |
5 |
6 | .pager {
7 | padding-left: 0;
8 | margin: @line-height-computed 0;
9 | list-style: none;
10 | text-align: center;
11 | .clearfix();
12 | li {
13 | display: inline;
14 | > a,
15 | > span {
16 | display: inline-block;
17 | padding: 5px 14px;
18 | background-color: @pagination-bg;
19 | border: 1px solid @pagination-border;
20 | border-radius: @pager-border-radius;
21 | }
22 |
23 | > a:hover,
24 | > a:focus {
25 | text-decoration: none;
26 | background-color: @pagination-hover-bg;
27 | }
28 | }
29 |
30 | .next {
31 | > a,
32 | > span {
33 | float: right;
34 | }
35 | }
36 |
37 | .previous {
38 | > a,
39 | > span {
40 | float: left;
41 | }
42 | }
43 |
44 | .disabled {
45 | > a,
46 | > a:hover,
47 | > a:focus,
48 | > span {
49 | color: @pager-disabled-color;
50 | background-color: @pagination-bg;
51 | cursor: not-allowed;
52 | }
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/app/bower_components/bootstrap/less/pagination.less:
--------------------------------------------------------------------------------
1 | //
2 | // Pagination (multiple pages)
3 | // --------------------------------------------------
4 | .pagination {
5 | display: inline-block;
6 | padding-left: 0;
7 | margin: @line-height-computed 0;
8 | border-radius: @border-radius-base;
9 |
10 | > li {
11 | display: inline; // Remove list-style and block-level defaults
12 | > a,
13 | > span {
14 | position: relative;
15 | float: left; // Collapse white-space
16 | padding: @padding-base-vertical @padding-base-horizontal;
17 | line-height: @line-height-base;
18 | text-decoration: none;
19 | background-color: @pagination-bg;
20 | border: 1px solid @pagination-border;
21 | margin-left: -1px;
22 | }
23 | &:first-child {
24 | > a,
25 | > span {
26 | margin-left: 0;
27 | .border-left-radius(@border-radius-base);
28 | }
29 | }
30 | &:last-child {
31 | > a,
32 | > span {
33 | .border-right-radius(@border-radius-base);
34 | }
35 | }
36 | }
37 |
38 | > li > a,
39 | > li > span {
40 | &:hover,
41 | &:focus {
42 | background-color: @pagination-hover-bg;
43 | }
44 | }
45 |
46 | > .active > a,
47 | > .active > span {
48 | &,
49 | &:hover,
50 | &:focus {
51 | z-index: 2;
52 | color: @pagination-active-color;
53 | background-color: @pagination-active-bg;
54 | border-color: @pagination-active-bg;
55 | cursor: default;
56 | }
57 | }
58 |
59 | > .disabled {
60 | > span,
61 | > a,
62 | > a:hover,
63 | > a:focus {
64 | color: @pagination-disabled-color;
65 | background-color: @pagination-bg;
66 | border-color: @pagination-border;
67 | cursor: not-allowed;
68 | }
69 | }
70 | }
71 |
72 | // Sizing
73 | // --------------------------------------------------
74 |
75 | // Large
76 | .pagination-lg {
77 | .pagination-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @border-radius-large);
78 | }
79 |
80 | // Small
81 | .pagination-sm {
82 | .pagination-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @border-radius-small);
83 | }
84 |
--------------------------------------------------------------------------------
/app/bower_components/bootstrap/less/panels.less:
--------------------------------------------------------------------------------
1 | //
2 | // Panels
3 | // --------------------------------------------------
4 |
5 |
6 | // Base class
7 | .panel {
8 | margin-bottom: @line-height-computed;
9 | background-color: @panel-bg;
10 | border: 1px solid transparent;
11 | border-radius: @panel-border-radius;
12 | .box-shadow(0 1px 1px rgba(0,0,0,.05));
13 | }
14 |
15 | // Panel contents
16 | .panel-body {
17 | padding: 15px;
18 | .clearfix();
19 | }
20 |
21 |
22 | // List groups in panels
23 | //
24 | // By default, space out list group content from panel headings to account for
25 | // any kind of custom content between the two.
26 |
27 | .panel {
28 | > .list-group {
29 | margin-bottom: 0;
30 |
31 | .list-group-item {
32 | border-width: 1px 0;
33 |
34 | // Remove border radius for top one
35 | &:first-child {
36 | .border-top-radius(0);
37 | }
38 | // But keep it for the last one
39 | &:last-child {
40 | border-bottom: 0;
41 | }
42 | }
43 | }
44 | }
45 | // Collapse space between when there's no additional content.
46 | .panel-heading + .list-group {
47 | .list-group-item:first-child {
48 | border-top-width: 0;
49 | }
50 | }
51 |
52 |
53 | // Tables in panels
54 | //
55 | // Place a non-bordered `.table` within a panel (not within a `.panel-body`) and
56 | // watch it go full width.
57 |
58 | .panel {
59 | > .table {
60 | margin-bottom: 0;
61 | }
62 | > .panel-body + .table {
63 | border-top: 1px solid @table-border-color;
64 | }
65 | }
66 |
67 |
68 | // Optional heading
69 | .panel-heading {
70 | padding: 10px 15px;
71 | border-bottom: 1px solid transparent;
72 | .border-top-radius(@panel-border-radius - 1);
73 | }
74 |
75 | // Within heading, strip any `h*` tag of it's default margins for spacing.
76 | .panel-title {
77 | margin-top: 0;
78 | margin-bottom: 0;
79 | font-size: ceil((@font-size-base * 1.125));
80 | > a {
81 | color: inherit;
82 | }
83 | }
84 |
85 | // Optional footer (stays gray in every modifier class)
86 | .panel-footer {
87 | padding: 10px 15px;
88 | background-color: @panel-footer-bg;
89 | border-top: 1px solid @panel-inner-border;
90 | .border-bottom-radius(@panel-border-radius - 1);
91 | }
92 |
93 |
94 | // Collapsable panels (aka, accordion)
95 | //
96 | // Wrap a series of panels in `.panel-group` to turn them into an accordion with
97 | // the help of our collapse JavaScript plugin.
98 |
99 | .panel-group {
100 | // Tighten up margin so it's only between panels
101 | .panel {
102 | margin-bottom: 0;
103 | border-radius: @panel-border-radius;
104 | overflow: hidden; // crop contents when collapsed
105 | + .panel {
106 | margin-top: 5px;
107 | }
108 | }
109 |
110 | .panel-heading {
111 | border-bottom: 0;
112 | + .panel-collapse .panel-body {
113 | border-top: 1px solid @panel-inner-border;
114 | }
115 | }
116 | .panel-footer {
117 | border-top: 0;
118 | + .panel-collapse .panel-body {
119 | border-bottom: 1px solid @panel-inner-border;
120 | }
121 | }
122 |
123 | // New subcomponent for wrapping collapsable content for proper animations
124 | .panel-collapse {
125 |
126 | }
127 | }
128 |
129 |
130 | // Contextual variations
131 | .panel-default {
132 | .panel-variant(@panel-default-border; @panel-default-text; @panel-default-heading-bg; @panel-default-border);
133 | }
134 | .panel-primary {
135 | .panel-variant(@panel-primary-border; @panel-primary-text; @panel-primary-heading-bg; @panel-primary-border);
136 | }
137 | .panel-success {
138 | .panel-variant(@panel-success-border; @panel-success-text; @panel-success-heading-bg; @panel-success-border);
139 | }
140 | .panel-warning {
141 | .panel-variant(@panel-warning-border; @panel-warning-text; @panel-warning-heading-bg; @panel-warning-border);
142 | }
143 | .panel-danger {
144 | .panel-variant(@panel-danger-border; @panel-danger-text; @panel-danger-heading-bg; @panel-danger-border);
145 | }
146 | .panel-info {
147 | .panel-variant(@panel-info-border; @panel-info-text; @panel-info-heading-bg; @panel-info-border);
148 | }
149 |
--------------------------------------------------------------------------------
/app/bower_components/bootstrap/less/popovers.less:
--------------------------------------------------------------------------------
1 | //
2 | // Popovers
3 | // --------------------------------------------------
4 |
5 |
6 | .popover {
7 | position: absolute;
8 | top: 0;
9 | left: 0;
10 | z-index: @zindex-popover;
11 | display: none;
12 | max-width: @popover-max-width;
13 | padding: 1px;
14 | text-align: left; // Reset given new insertion method
15 | background-color: @popover-bg;
16 | background-clip: padding-box;
17 | border: 1px solid @popover-fallback-border-color;
18 | border: 1px solid @popover-border-color;
19 | border-radius: @border-radius-large;
20 | .box-shadow(0 5px 10px rgba(0,0,0,.2));
21 |
22 | // Overrides for proper insertion
23 | white-space: normal;
24 |
25 | // Offset the popover to account for the popover arrow
26 | &.top { margin-top: -10px; }
27 | &.right { margin-left: 10px; }
28 | &.bottom { margin-top: 10px; }
29 | &.left { margin-left: -10px; }
30 | }
31 |
32 | .popover-title {
33 | margin: 0; // reset heading margin
34 | padding: 8px 14px;
35 | font-size: @font-size-base;
36 | font-weight: normal;
37 | line-height: 18px;
38 | background-color: @popover-title-bg;
39 | border-bottom: 1px solid darken(@popover-title-bg, 5%);
40 | border-radius: 5px 5px 0 0;
41 | }
42 |
43 | .popover-content {
44 | padding: 9px 14px;
45 | }
46 |
47 | // Arrows
48 | //
49 | // .arrow is outer, .arrow:after is inner
50 |
51 | .popover .arrow {
52 | &,
53 | &:after {
54 | position: absolute;
55 | display: block;
56 | width: 0;
57 | height: 0;
58 | border-color: transparent;
59 | border-style: solid;
60 | }
61 | }
62 | .popover .arrow {
63 | border-width: @popover-arrow-outer-width;
64 | }
65 | .popover .arrow:after {
66 | border-width: @popover-arrow-width;
67 | content: "";
68 | }
69 |
70 | .popover {
71 | &.top .arrow {
72 | left: 50%;
73 | margin-left: -@popover-arrow-outer-width;
74 | border-bottom-width: 0;
75 | border-top-color: @popover-arrow-outer-fallback-color; // IE8 fallback
76 | border-top-color: @popover-arrow-outer-color;
77 | bottom: -@popover-arrow-outer-width;
78 | &:after {
79 | content: " ";
80 | bottom: 1px;
81 | margin-left: -@popover-arrow-width;
82 | border-bottom-width: 0;
83 | border-top-color: @popover-arrow-color;
84 | }
85 | }
86 | &.right .arrow {
87 | top: 50%;
88 | left: -@popover-arrow-outer-width;
89 | margin-top: -@popover-arrow-outer-width;
90 | border-left-width: 0;
91 | border-right-color: @popover-arrow-outer-fallback-color; // IE8 fallback
92 | border-right-color: @popover-arrow-outer-color;
93 | &:after {
94 | content: " ";
95 | left: 1px;
96 | bottom: -@popover-arrow-width;
97 | border-left-width: 0;
98 | border-right-color: @popover-arrow-color;
99 | }
100 | }
101 | &.bottom .arrow {
102 | left: 50%;
103 | margin-left: -@popover-arrow-outer-width;
104 | border-top-width: 0;
105 | border-bottom-color: @popover-arrow-outer-fallback-color; // IE8 fallback
106 | border-bottom-color: @popover-arrow-outer-color;
107 | top: -@popover-arrow-outer-width;
108 | &:after {
109 | content: " ";
110 | top: 1px;
111 | margin-left: -@popover-arrow-width;
112 | border-top-width: 0;
113 | border-bottom-color: @popover-arrow-color;
114 | }
115 | }
116 |
117 | &.left .arrow {
118 | top: 50%;
119 | right: -@popover-arrow-outer-width;
120 | margin-top: -@popover-arrow-outer-width;
121 | border-right-width: 0;
122 | border-left-color: @popover-arrow-outer-fallback-color; // IE8 fallback
123 | border-left-color: @popover-arrow-outer-color;
124 | &:after {
125 | content: " ";
126 | right: 1px;
127 | border-right-width: 0;
128 | border-left-color: @popover-arrow-color;
129 | bottom: -@popover-arrow-width;
130 | }
131 | }
132 |
133 | }
134 |
--------------------------------------------------------------------------------
/app/bower_components/bootstrap/less/print.less:
--------------------------------------------------------------------------------
1 | //
2 | // Basic print styles
3 | // --------------------------------------------------
4 | // Source: https://github.com/h5bp/html5-boilerplate/blob/master/css/main.css
5 |
6 | @media print {
7 |
8 | * {
9 | text-shadow: none !important;
10 | color: #000 !important; // Black prints faster: h5bp.com/s
11 | background: transparent !important;
12 | box-shadow: none !important;
13 | }
14 |
15 | a,
16 | a:visited {
17 | text-decoration: underline;
18 | }
19 |
20 | a[href]:after {
21 | content: " (" attr(href) ")";
22 | }
23 |
24 | abbr[title]:after {
25 | content: " (" attr(title) ")";
26 | }
27 |
28 | // Don't show links for images, or javascript/internal links
29 | .ir a:after,
30 | a[href^="javascript:"]:after,
31 | a[href^="#"]:after {
32 | content: "";
33 | }
34 |
35 | pre,
36 | blockquote {
37 | border: 1px solid #999;
38 | page-break-inside: avoid;
39 | }
40 |
41 | thead {
42 | display: table-header-group; // h5bp.com/t
43 | }
44 |
45 | tr,
46 | img {
47 | page-break-inside: avoid;
48 | }
49 |
50 | img {
51 | max-width: 100% !important;
52 | }
53 |
54 | @page {
55 | margin: 2cm .5cm;
56 | }
57 |
58 | p,
59 | h2,
60 | h3 {
61 | orphans: 3;
62 | widows: 3;
63 | }
64 |
65 | h2,
66 | h3 {
67 | page-break-after: avoid;
68 | }
69 |
70 | // Bootstrap components
71 | .navbar {
72 | display: none;
73 | }
74 | .table {
75 | td,
76 | th {
77 | background-color: #fff !important;
78 | }
79 | }
80 | .btn,
81 | .dropup > .btn {
82 | > .caret {
83 | border-top-color: #000 !important;
84 | }
85 | }
86 | .label {
87 | border: 1px solid #000;
88 | }
89 |
90 | .table {
91 | border-collapse: collapse !important;
92 | }
93 | .table-bordered {
94 | th,
95 | td {
96 | border: 1px solid #ddd !important;
97 | }
98 | }
99 |
100 | }
101 |
--------------------------------------------------------------------------------
/app/bower_components/bootstrap/less/progress-bars.less:
--------------------------------------------------------------------------------
1 | //
2 | // Progress bars
3 | // --------------------------------------------------
4 |
5 |
6 | // Bar animations
7 | // -------------------------
8 |
9 | // Webkit
10 | @-webkit-keyframes progress-bar-stripes {
11 | from { background-position: 40px 0; }
12 | to { background-position: 0 0; }
13 | }
14 |
15 | // Firefox
16 | @-moz-keyframes progress-bar-stripes {
17 | from { background-position: 40px 0; }
18 | to { background-position: 0 0; }
19 | }
20 |
21 | // Opera
22 | @-o-keyframes progress-bar-stripes {
23 | from { background-position: 0 0; }
24 | to { background-position: 40px 0; }
25 | }
26 |
27 | // Spec and IE10+
28 | @keyframes progress-bar-stripes {
29 | from { background-position: 40px 0; }
30 | to { background-position: 0 0; }
31 | }
32 |
33 |
34 |
35 | // Bar itself
36 | // -------------------------
37 |
38 | // Outer container
39 | .progress {
40 | overflow: hidden;
41 | height: @line-height-computed;
42 | margin-bottom: @line-height-computed;
43 | background-color: @progress-bg;
44 | border-radius: @border-radius-base;
45 | .box-shadow(inset 0 1px 2px rgba(0,0,0,.1));
46 | }
47 |
48 | // Bar of progress
49 | .progress-bar {
50 | float: left;
51 | width: 0%;
52 | height: 100%;
53 | font-size: @font-size-small;
54 | color: @progress-bar-color;
55 | text-align: center;
56 | background-color: @progress-bar-bg;
57 | .box-shadow(inset 0 -1px 0 rgba(0,0,0,.15));
58 | .transition(width .6s ease);
59 | }
60 |
61 | // Striped bars
62 | .progress-striped .progress-bar {
63 | #gradient > .striped(@progress-bar-bg);
64 | background-size: 40px 40px;
65 | }
66 |
67 | // Call animation for the active one
68 | .progress.active .progress-bar {
69 | -webkit-animation: progress-bar-stripes 2s linear infinite;
70 | -moz-animation: progress-bar-stripes 2s linear infinite;
71 | -ms-animation: progress-bar-stripes 2s linear infinite;
72 | -o-animation: progress-bar-stripes 2s linear infinite;
73 | animation: progress-bar-stripes 2s linear infinite;
74 | }
75 |
76 |
77 |
78 | // Variations
79 | // -------------------------
80 |
81 | .progress-bar-success {
82 | .progress-bar-variant(@progress-bar-success-bg);
83 | }
84 |
85 | .progress-bar-info {
86 | .progress-bar-variant(@progress-bar-info-bg);
87 | }
88 |
89 | .progress-bar-warning {
90 | .progress-bar-variant(@progress-bar-warning-bg);
91 | }
92 |
93 | .progress-bar-danger {
94 | .progress-bar-variant(@progress-bar-danger-bg);
95 | }
96 |
--------------------------------------------------------------------------------
/app/bower_components/bootstrap/less/scaffolding.less:
--------------------------------------------------------------------------------
1 | //
2 | // Scaffolding
3 | // --------------------------------------------------
4 |
5 |
6 | // Reset the box-sizing
7 |
8 | *,
9 | *:before,
10 | *:after {
11 | .box-sizing(border-box);
12 | }
13 |
14 |
15 | // Body reset
16 |
17 | html {
18 | font-size: 62.5%;
19 | -webkit-tap-highlight-color: rgba(0,0,0,0);
20 | }
21 |
22 | body {
23 | font-family: @font-family-base;
24 | font-size: @font-size-base;
25 | line-height: @line-height-base;
26 | color: @text-color;
27 | background-color: @body-bg;
28 | }
29 |
30 | // Reset fonts for relevant elements
31 | input,
32 | button,
33 | select,
34 | textarea {
35 | font-family: inherit;
36 | font-size: inherit;
37 | line-height: inherit;
38 | }
39 |
40 | // Reset unusual Firefox-on-Android default style.
41 | //
42 | // See https://github.com/necolas/normalize.css/issues/214
43 |
44 | button,
45 | input,
46 | select[multiple],
47 | textarea {
48 | background-image: none;
49 | }
50 |
51 |
52 | // Links
53 |
54 | a {
55 | color: @link-color;
56 | text-decoration: none;
57 |
58 | &:hover,
59 | &:focus {
60 | color: @link-hover-color;
61 | text-decoration: underline;
62 | }
63 |
64 | &:focus {
65 | .tab-focus();
66 | }
67 | }
68 |
69 |
70 | // Images
71 |
72 | img {
73 | vertical-align: middle;
74 | }
75 |
76 | // Responsive images (ensure images don't scale beyond their parents)
77 | .img-responsive {
78 | .img-responsive();
79 | }
80 |
81 | // Rounded corners
82 | .img-rounded {
83 | border-radius: @border-radius-large;
84 | }
85 |
86 | // Image thumbnails
87 | //
88 | // Heads up! This is mixin-ed into thumbnails.less for `.thumbnail`.
89 | .img-thumbnail {
90 | padding: @thumbnail-padding;
91 | line-height: @line-height-base;
92 | background-color: @thumbnail-bg;
93 | border: 1px solid @thumbnail-border;
94 | border-radius: @thumbnail-border-radius;
95 | .transition(all .2s ease-in-out);
96 |
97 | // Keep them at most 100% wide
98 | .img-responsive(inline-block);
99 | }
100 |
101 | // Perfect circle
102 | .img-circle {
103 | border-radius: 50%; // set radius in percents
104 | }
105 |
106 |
107 | // Horizontal rules
108 |
109 | hr {
110 | margin-top: @line-height-computed;
111 | margin-bottom: @line-height-computed;
112 | border: 0;
113 | border-top: 1px solid @hr-border;
114 | }
115 |
116 |
117 | // Only display content to screen readers
118 | //
119 | // See: http://a11yproject.com/posts/how-to-hide-content/
120 |
121 | .sr-only {
122 | position: absolute;
123 | width: 1px;
124 | height: 1px;
125 | margin: -1px;
126 | padding: 0;
127 | overflow: hidden;
128 | clip: rect(0 0 0 0);
129 | border: 0;
130 | }
131 |
--------------------------------------------------------------------------------
/app/bower_components/bootstrap/less/thumbnails.less:
--------------------------------------------------------------------------------
1 | //
2 | // Thumbnails
3 | // --------------------------------------------------
4 |
5 |
6 | // Mixin and adjust the regular image class
7 | .thumbnail {
8 | .img-thumbnail();
9 | display: block; // Override the inline-block from `.img-thumbnail`
10 |
11 | > img {
12 | .img-responsive();
13 | }
14 | }
15 |
16 |
17 | // Add a hover state for linked versions only
18 | a.thumbnail:hover,
19 | a.thumbnail:focus {
20 | border-color: @link-color;
21 | }
22 |
23 | // Images and captions
24 | .thumbnail > img {
25 | margin-left: auto;
26 | margin-right: auto;
27 | }
28 | .thumbnail .caption {
29 | padding: @thumbnail-caption-padding;
30 | color: @thumbnail-caption-color;
31 | }
32 |
--------------------------------------------------------------------------------
/app/bower_components/bootstrap/less/tooltip.less:
--------------------------------------------------------------------------------
1 | //
2 | // Tooltips
3 | // --------------------------------------------------
4 |
5 |
6 | // Base class
7 | .tooltip {
8 | position: absolute;
9 | z-index: @zindex-tooltip;
10 | display: block;
11 | visibility: visible;
12 | font-size: @font-size-small;
13 | line-height: 1.4;
14 | .opacity(0);
15 |
16 | &.in { .opacity(.9); }
17 | &.top { margin-top: -3px; padding: 5px 0; }
18 | &.right { margin-left: 3px; padding: 0 5px; }
19 | &.bottom { margin-top: 3px; padding: 5px 0; }
20 | &.left { margin-left: -3px; padding: 0 5px; }
21 | }
22 |
23 | // Wrapper for the tooltip content
24 | .tooltip-inner {
25 | max-width: @tooltip-max-width;
26 | padding: 3px 8px;
27 | color: @tooltip-color;
28 | text-align: center;
29 | text-decoration: none;
30 | background-color: @tooltip-bg;
31 | border-radius: @border-radius-base;
32 | }
33 |
34 | // Arrows
35 | .tooltip-arrow {
36 | position: absolute;
37 | width: 0;
38 | height: 0;
39 | border-color: transparent;
40 | border-style: solid;
41 | }
42 | .tooltip {
43 | &.top .tooltip-arrow {
44 | bottom: 0;
45 | left: 50%;
46 | margin-left: -@tooltip-arrow-width;
47 | border-width: @tooltip-arrow-width @tooltip-arrow-width 0;
48 | border-top-color: @tooltip-arrow-color;
49 | }
50 | &.top-left .tooltip-arrow {
51 | bottom: 0;
52 | left: 5px;
53 | border-width: @tooltip-arrow-width @tooltip-arrow-width 0;
54 | border-top-color: @tooltip-arrow-color;
55 | }
56 | &.top-right .tooltip-arrow {
57 | bottom: 0;
58 | right: 5px;
59 | border-width: @tooltip-arrow-width @tooltip-arrow-width 0;
60 | border-top-color: @tooltip-arrow-color;
61 | }
62 | &.right .tooltip-arrow {
63 | top: 50%;
64 | left: 0;
65 | margin-top: -@tooltip-arrow-width;
66 | border-width: @tooltip-arrow-width @tooltip-arrow-width @tooltip-arrow-width 0;
67 | border-right-color: @tooltip-arrow-color;
68 | }
69 | &.left .tooltip-arrow {
70 | top: 50%;
71 | right: 0;
72 | margin-top: -@tooltip-arrow-width;
73 | border-width: @tooltip-arrow-width 0 @tooltip-arrow-width @tooltip-arrow-width;
74 | border-left-color: @tooltip-arrow-color;
75 | }
76 | &.bottom .tooltip-arrow {
77 | top: 0;
78 | left: 50%;
79 | margin-left: -@tooltip-arrow-width;
80 | border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;
81 | border-bottom-color: @tooltip-arrow-color;
82 | }
83 | &.bottom-left .tooltip-arrow {
84 | top: 0;
85 | left: 5px;
86 | border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;
87 | border-bottom-color: @tooltip-arrow-color;
88 | }
89 | &.bottom-right .tooltip-arrow {
90 | top: 0;
91 | right: 5px;
92 | border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;
93 | border-bottom-color: @tooltip-arrow-color;
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/app/bower_components/bootstrap/less/utilities.less:
--------------------------------------------------------------------------------
1 | //
2 | // Utility classes
3 | // --------------------------------------------------
4 |
5 |
6 | // Floats
7 | // -------------------------
8 |
9 | .clearfix {
10 | .clearfix();
11 | }
12 | .pull-right {
13 | float: right !important;
14 | }
15 | .pull-left {
16 | float: left !important;
17 | }
18 |
19 |
20 | // Toggling content
21 | // -------------------------
22 |
23 | .hide {
24 | display: none !important;
25 | }
26 | .show {
27 | display: block !important;
28 | }
29 | .invisible {
30 | visibility: hidden;
31 | }
32 | .text-hide {
33 | .hide-text();
34 | }
35 |
36 |
37 | // For Affix plugin
38 | // -------------------------
39 |
40 | .affix {
41 | position: fixed;
42 | }
43 |
--------------------------------------------------------------------------------
/app/bower_components/bootstrap/less/wells.less:
--------------------------------------------------------------------------------
1 | //
2 | // Wells
3 | // --------------------------------------------------
4 |
5 |
6 | // Base class
7 | .well {
8 | min-height: 20px;
9 | padding: 19px;
10 | margin-bottom: 20px;
11 | background-color: @well-bg;
12 | border: 1px solid darken(@well-bg, 7%);
13 | border-radius: @border-radius-base;
14 | .box-shadow(inset 0 1px 1px rgba(0,0,0,.05));
15 | blockquote {
16 | border-color: #ddd;
17 | border-color: rgba(0,0,0,.15);
18 | }
19 | }
20 |
21 | // Sizes
22 | .well-lg {
23 | padding: 24px;
24 | border-radius: @border-radius-large;
25 | }
26 | .well-sm {
27 | padding: 9px;
28 | border-radius: @border-radius-small;
29 | }
30 |
--------------------------------------------------------------------------------
/app/bower_components/bootstrap/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "bootstrap"
3 | , "description": "Sleek, intuitive, and powerful front-end framework for faster and easier web development."
4 | , "version": "3.0.0"
5 | , "keywords": ["bootstrap", "css"]
6 | , "homepage": "http://twbs.github.com/bootstrap/"
7 | , "author": "Twitter Inc."
8 | , "scripts": { "test": "grunt test" }
9 | , "repository": {
10 | "type": "git"
11 | , "url": "https://github.com/twbs/bootstrap.git"
12 | }
13 | , "licenses": [
14 | {
15 | "type": "Apache-2.0"
16 | , "url": "http://www.apache.org/licenses/LICENSE-2.0"
17 | }
18 | ]
19 | , "devDependencies": {
20 | "grunt": "~0.4.1"
21 | , "grunt-contrib-clean": "~0.5.0"
22 | , "grunt-contrib-connect": "~0.3.0"
23 | , "grunt-contrib-concat": "~0.3.0"
24 | , "grunt-contrib-copy": "~0.4.0"
25 | , "grunt-contrib-jshint": "~0.6.0"
26 | , "grunt-contrib-uglify": "~0.2.2"
27 | , "grunt-contrib-qunit": "~0.2.2"
28 | , "grunt-contrib-watch": "~0.5.1"
29 | , "grunt-html-validation": "git://github.com/praveenvijayan/grunt-html-validation.git"
30 | , "grunt-jekyll": "~0.3.8"
31 | , "grunt-recess": "~0.3.3"
32 | , "browserstack-runner": "~0.0.11"
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/app/bower_components/jquery/.bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jquery",
3 | "version": "2.0.3",
4 | "description": "jQuery component",
5 | "keywords": [
6 | "jquery",
7 | "component"
8 | ],
9 | "main": "jquery.js",
10 | "license": "MIT",
11 | "homepage": "https://github.com/components/jquery",
12 | "_release": "2.0.3",
13 | "_resolution": {
14 | "type": "version",
15 | "tag": "2.0.3",
16 | "commit": "452a56b52b8f4a032256cdb8b6838f25f0bdb3d2"
17 | },
18 | "_source": "git://github.com/components/jquery.git",
19 | "_target": "~2.0.3",
20 | "_originalSource": "jquery",
21 | "_direct": true
22 | }
--------------------------------------------------------------------------------
/app/bower_components/jquery/.gitignore:
--------------------------------------------------------------------------------
1 | build
2 |
--------------------------------------------------------------------------------
/app/bower_components/jquery/README.md:
--------------------------------------------------------------------------------
1 | jQuery Component
2 | ================
3 |
4 | Shim repository for the [jQuery](http://jquery.com).
5 |
6 | Package Managers
7 | ----------------
8 |
9 | * [Bower](http://bower.io/): `jquery`
10 | * [Component](https://github.com/component/component): `components/jquery`
11 | * [Composer](http://packagist.org/packages/components/jquery): `components/jquery`
12 |
--------------------------------------------------------------------------------
/app/bower_components/jquery/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jquery",
3 | "version": "2.0.3",
4 | "description": "jQuery component",
5 | "keywords": [
6 | "jquery",
7 | "component"
8 | ],
9 | "main": "jquery.js",
10 | "license": "MIT"
11 | }
12 |
--------------------------------------------------------------------------------
/app/bower_components/jquery/component.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jquery",
3 | "repo": "components/jquery",
4 | "version": "2.0.3",
5 | "description": "jQuery component",
6 | "keywords": [
7 | "jquery",
8 | "component"
9 | ],
10 | "main": "jquery.js",
11 | "scripts": [
12 | "jquery.js"
13 | ],
14 | "license": "MIT"
15 | }
16 |
--------------------------------------------------------------------------------
/app/bower_components/jquery/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "components/jquery",
3 | "description": "jQuery JavaScript Library",
4 | "type": "component",
5 | "homepage": "http://jquery.com",
6 | "license": "MIT",
7 | "support": {
8 | "irc": "irc://irc.freenode.org/jquery",
9 | "issues": "http://bugs.jquery.com",
10 | "forum": "http://forum.jquery.com",
11 | "wiki": "http://docs.jquery.com/",
12 | "source": "https://github.com/jquery/jquery"
13 | },
14 | "authors": [
15 | {
16 | "name": "John Resig",
17 | "email": "jeresig@gmail.com"
18 | }
19 | ],
20 | "require": {
21 | "robloach/component-installer": "*"
22 | },
23 | "extra": {
24 | "component": {
25 | "scripts": [
26 | "jquery.js"
27 | ],
28 | "files": [
29 | "jquery.min.js",
30 | "jquery-migrate.js",
31 | "jquery-migrate.min.js"
32 | ]
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/app/bower_components/jquery/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "components-jquery",
3 | "version": "2.0.3",
4 | "description": "jQuery component",
5 | "keywords": ["jquery"],
6 | "main": "./jquery.js"
7 | }
8 |
--------------------------------------------------------------------------------
/app/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
angular-better-placeholders
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/app/scripts/app.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var app = angular.module('PlaceholderDemoApp', ['angularBetterPlaceholder'])
4 | .config(function ($routeProvider) {
5 | $routeProvider
6 | .when('/', {
7 | templateUrl: 'views/main.html',
8 | controller: 'MainCtrl'
9 | })
10 | });
--------------------------------------------------------------------------------
/app/scripts/controllers/Main.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('PlaceholderDemoApp')
4 | .controller('MainCtrl', function MainCtrl($scope) {
5 | $scope.user = {}
6 | })
--------------------------------------------------------------------------------
/app/scripts/directives/angular-better-placeholder.js:
--------------------------------------------------------------------------------
1 | angular.module('angularBetterPlaceholder', []).directive('betterPlaceholder', function() {
2 | return {
3 | restrict: 'C',
4 | require: '?ngModel',
5 | scope: {},
6 | link: function(scope, element, attrs, ngModel) {
7 | var activate, deactivate, isEmpty, placeholder;
8 | isEmpty = function(value) {
9 | if (value == null) {
10 | value = ngModel && (ngModel != null) ? ngModel.$viewValue : element.val();
11 | }
12 | return !element[0].validity.badInput && (!value || value === '');
13 | };
14 | if (attrs.ngPlaceholder != null) {
15 | scope.placeholder = scope.$parent.$eval(attrs.ngPlaceholder);
16 | element.attr('placeholder', scope.placeholder);
17 | scope.$parent.$watch(attrs.ngPlaceholder, function(val) {
18 | element.attr('placeholder', val);
19 | return placeholder.html(val);
20 | });
21 | } else if ((attrs.placeholder != null) && attrs.placeholder !== '') {
22 | scope.placeholder = attrs.placeholder;
23 | } else {
24 | throw "better-placeholder requires an ng-placeholder or placeholder attribute";
25 | }
26 | placeholder = angular.element("
" + scope.placeholder + " ");
27 | element.after(placeholder);
28 | placeholder.on('click', function() {
29 | return element[0].focus();
30 | });
31 | activate = function() {
32 | element.addClass('better-placeholder-active');
33 | return placeholder.addClass('active');
34 | };
35 | deactivate = function() {
36 | if (isEmpty()) {
37 | element.removeClass('better-placeholder-active');
38 | return placeholder.removeClass('active');
39 | }
40 | };
41 | element.on('focus', activate);
42 | element.on('blur', deactivate);
43 | element.on('change', function() {
44 | if (isEmpty()) {
45 | element.removeClass('better-placeholder-active');
46 | return placeholder.removeClass('active');
47 | } else {
48 | element.addClass('better-placeholder-active');
49 | return placeholder.addClass('active');
50 | }
51 | });
52 | if (ngModel != null) {
53 | return ngModel.$formatters.push(function(value) {
54 | if (isEmpty(value)) {
55 | element.removeClass('better-placeholder-active');
56 | placeholder.removeClass('active');
57 | } else {
58 | element.addClass('better-placeholder-active');
59 | placeholder.addClass('active');
60 | }
61 | return value;
62 | });
63 | } else if (!isEmpty()) {
64 | return activate();
65 | }
66 | }
67 | };
68 | });
69 |
--------------------------------------------------------------------------------
/app/views/main.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
angular-better-placeholders by @dmackerman
5 |
Better, more friendly implementation of placeholder
for form fields inside of Bootstrap. and elsewhere
6 | Inspired by a really cool Dribble concept.
7 |
Download
8 |
View on Github
10 |
11 |
Demo
12 |
Begin typing in a field to trigger the placeholder text. If an input ever becomes unfocused and is empty, the placeholder should disapear.
13 |
31 |
32 |
33 |
34 |
Usage
35 |
Simple include the better-placeholder
directive as a class on your input fields.
36 |
37 | <input type="text" ng-model="user.firstName" class="form-control better-placeholder" placeholder="First Name" />
38 |
Include the following CSS snipets:
39 |
40 | .better-placeholder {
41 | transition: all .2s ease;
42 | }
43 | .better-placeholder.better-placeholder-active {
44 | padding: 34px 12px 16px 12px;
45 | }
46 | .better-placeholder-text {
47 | position: absolute;
48 | top: 5px; left: 28px;
49 | font-size: 10px;
50 | font-weight: bold;
51 | }
52 |
53 |
54 |
55 | Todo
56 |
57 |
58 | Look into $templateCache
59 | Optimize terrible code
60 | Better CSS integration
61 | Include better transition for the actual placeholder label
62 |
63 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-better-placeholders",
3 | "version": "0.3.0",
4 | "authors": [
5 | "Dave Ackerman
",
6 | "SimeonC "
7 | ],
8 | "main": "src/angular-better-placeholders.js",
9 | "description": "Angular directive for enhanced placeholders that integrate with Bootstrap form fields.",
10 | "keywords": [
11 | "angular",
12 | "forms",
13 | "placeholder",
14 | "bootstrap"
15 | ],
16 | "license": "MIT",
17 | "ignore": [
18 | "**/.*",
19 | "node_modules",
20 | "bower_components",
21 | "test",
22 | "tests"
23 | ]
24 | }
25 |
--------------------------------------------------------------------------------
/src/angular-better-placeholders.coffee:
--------------------------------------------------------------------------------
1 | # version 0.3.0
2 | # Compile with coffee -c -b --no-header angular-better-placeholders.coffee > angular-better-placeholders.js
3 | angular.module('angularBetterPlaceholder', [])
4 | .directive 'betterPlaceholder', ->
5 | restrict: 'C'
6 | require: '?ngModel'
7 | link: (scope, element, attrs, ngModel) ->
8 | if not element.prev then element.prev = ->
9 | p = element
10 | loop
11 | p = p.previousSibling
12 | break unless p and p.nodeType isnt 1
13 | return p
14 | # if ngModel is invalid then it can occur that the viewValue is empty
15 | isEmpty = (value= if ngModel and ngModel? then ngModel.$viewValue else element.val()) ->
16 | (
17 | not element[0].validity.badInput and # empty if not badInput, if badinput model gets set to undefined but there IS content
18 | not ( # negate the following test which tests if it has content
19 | value? and #value is not null/undefined
20 | (
21 | not angular.isString(value) or value isnt '' # if it's a string it's not the empty stryng
22 | ) and
23 | (
24 | not angular.isArray(value) or not value.isEmpty() # if it's an array (case of using ng-list) it's more than length 0
25 | ) and
26 | (
27 | angular.isString(value) or angular.isArray(value) or (
28 | element.val().trim().length > 0 or # test if the actual content has length, to prevent false positives
29 | not isNaN(value) # otherwise check it is a number
30 | )
31 | )
32 | )
33 | )
34 | required = angular.element ' '
35 | placeholder = angular.element " "
36 | if element.attr('id')? then placeholder.attr 'for', element.attr 'id'
37 | else
38 | customId = 'placeholderid_' + (Math.random() * 10000000000000000)
39 | element.attr 'id', customId
40 | placeholder.attr 'for', customId
41 | element.after placeholder
42 |
43 | placeholder.html attrs.placeholder
44 | if not attrs.placeholder? or attrs.placeholder.trim() is '' # if there is no placeholder then don't show the animations
45 | placeholder.addClass 'ng-hide'
46 | element.removeClass 'better-placeholder'
47 | if attrs.required then placeholder.append required
48 | attrs.$observe 'placeholder', (val) ->
49 | placeholder.html val
50 | if attrs.required then placeholder.append required
51 | if not val? or val.trim() is '' # if there is no placeholder then don't show the animations
52 | placeholder.addClass 'ng-hide'
53 | element.removeClass 'better-placeholder'
54 | else # if there is a placeholder then make sure the class for the animations is re-added if it's been removed
55 | placeholder.removeClass 'ng-hide'
56 | element.addClass 'better-placeholder'
57 |
58 | placeholder.on 'click', -> element[0].focus()
59 |
60 | attrs.$observe 'required', (val) ->
61 | if val then placeholder.append required
62 | else required.remove()
63 |
64 | activate = ->
65 | if attrs.placeholder? and attrs.placeholder.trim() isnt ''
66 | element.addClass 'better-placeholder-active'
67 | placeholder.addClass 'active'
68 | if element.prev()? and element.prev().hasClass 'input-group-btn' then element.prev().addClass 'better-placeholder-button-active'
69 | deactivate = ->
70 | element.removeClass 'better-placeholder-active'
71 | placeholder.removeClass 'active'
72 | if element.prev()? and element.prev().hasClass 'input-group-btn' then element.prev().removeClass 'better-placeholder-button-active'
73 |
74 | # catch changes from the DOM
75 | element.on 'blur', -> if isEmpty() then deactivate()
76 | element.on 'change input', ->
77 | if isEmpty() then deactivate()
78 | else activate()
79 | if element.prev()? and element.prev().hasClass 'input-group-btn' then element.prev().addClass 'better-placeholder-button'
80 | if ngModel? then ngModel.$formatters.push (value) ->
81 | if isEmpty value then deactivate()
82 | else activate()
83 | value
84 | else if not isEmpty() then activate()
85 |
--------------------------------------------------------------------------------
/src/angular-better-placeholders.css:
--------------------------------------------------------------------------------
1 | .better-placeholder{-webkit-transition:all .2s ease;transition:all .2s ease;}.better-placeholder::-webkit-input-placeholder{opacity:0}.better-placeholder::-moz-placeholder{opacity:0}.better-placeholder:-ms-input-placeholder{opacity:0}.better-placeholder::placeholder{opacity:0}.better-placeholder::-webkit-datetime-edit{-webkit-transition:all .2s ease;transition:all .2s ease;opacity:0}.better-placeholder.fixed-height{padding-top:18px;height:auto;}.better-placeholder.fixed-height:not(.better-placeholder-active) ~ .better-placeholder-text:not(.active){top:14px}.better-placeholder-active,.ui-select-bootstrap.dropdown.open .better-placeholder{padding-top:18px;height:auto;}.better-placeholder-active::-webkit-datetime-edit,.ui-select-bootstrap.dropdown.open .better-placeholder::-webkit-datetime-edit{opacity:1}.better-placeholder-active::-webkit-input-placeholder,.ui-select-bootstrap.dropdown.open .better-placeholder::-webkit-input-placeholder{opacity:0}.better-placeholder-active::-moz-placeholder,.ui-select-bootstrap.dropdown.open .better-placeholder::-moz-placeholder{opacity:0}.better-placeholder-active:-ms-input-placeholder,.ui-select-bootstrap.dropdown.open .better-placeholder:-ms-input-placeholder{opacity:0}.better-placeholder-active::placeholder,.ui-select-bootstrap.dropdown.open .better-placeholder::placeholder{opacity:0}.input-group .better-placeholder ~ .input-group-btn .btn,.better-placeholder-button .btn{-webkit-transition:all .2s ease;transition:all .2s ease}.input-group .better-placeholder-active ~ .input-group-btn .btn,.better-placeholder-button-active .btn{padding:12px}.dropdown-menu .better-placeholder-text{z-index:1000}.better-placeholder-text,.help-block.better-placeholder-text{z-index:10;-webkit-transition:all .2s ease;transition:all .2s ease;position:absolute;top:2px;margin-left:12px;line-height:20px;height:20px;color:placeholder;-webkit-transform-origin:0 0;-ms-transform-origin:0 0;transform-origin:0 0;max-width:85%;margin-right:12px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.better-placeholder-text.active,.better-placeholder-active ~ .better-placeholder-text{max-width:110%;visibility:visible;-webkit-transform:scale(.8);-ms-transform:scale(.8);transform:scale(.8);-webkit-transform-origin:0 0;-ms-transform-origin:0 0;transform-origin:0 0;color:#428bca;top:-2px}.better-placeholder.disabled,.better-placeholder.disabled ~ .better-placeholder-text{color:#999}.fa-required{margin-left:6px;font-size:70%;vertical-align:super}td.input-group .better-placeholder-text,td.input-group .help-block.better-placeholder-text{top:11px}td.input-group .better-placeholder-text.active,td.input-group .better-placeholder-active ~ .better-placeholder-text{top:7px;}.ui-select-bootstrap.dropdown.open .better-placeholder.inverted,.better-placeholder-active.inverted{padding-bottom:18px;padding-top:6px}.better-placeholder.inverted ~ .better-placeholder-text.inverted,.better-placeholder.inverted ~ .help-block.better-placeholder-text.inverted,.better-placeholder-text.inverted,.help-block.better-placeholder-text.inverte{bottom:2px;top:auto}.better-placeholder-text.inverted.active,.better-placeholder-active.inverted ~ .better-placeholder-text{max-width:110%;visibility:visible;-webkit-transform:scale(.8);-ms-transform:scale(.8);transform:scale(.8);-webkit-transform-origin:0 0;-ms-transform-origin:0 0;transform-origin:0 0;color:#428bca;bottom:-8px;top:auto}td.input-group .better-placeholder.inverted ~ .better-placeholder-text.inverted,td.input-group .better-placeholder.inverted ~ .help-block.better-placeholder-text.inverted,td.input-group .better-placeholder-text.inverted,td.input-group .help-block.better-placeholder-text.inverte{top:auto;bottom:11px}td.input-group .better-placeholder-text.inverted.active,td.input-group .better-placeholder-active.inverted ~ .better-placeholder-text{top:auto;bottom:1px}
--------------------------------------------------------------------------------
/src/angular-better-placeholders.js:
--------------------------------------------------------------------------------
1 | // version 0.3.0
2 | angular.module('angularBetterPlaceholder', []).directive('betterPlaceholder', function() {
3 | return {
4 | restrict: 'C',
5 | require: '?ngModel',
6 | link: function(scope, element, attrs, ngModel) {
7 | var activate, customId, deactivate, isEmpty, placeholder, required;
8 | if (!element.prev) {
9 | element.prev = function() {
10 | var p;
11 | p = element;
12 | while (true) {
13 | p = p.previousSibling;
14 | if (!(p && p.nodeType !== 1)) {
15 | break;
16 | }
17 | }
18 | return p;
19 | };
20 | }
21 | isEmpty = function(value) {
22 | if (value == null) {
23 | value = ngModel && (ngModel != null) ? ngModel.$viewValue : element.val();
24 | }
25 | return !element[0].validity.badInput && !((value != null) && (!angular.isString(value) || value !== '') && (!angular.isArray(value) || !value.isEmpty()) && (angular.isString(value) || angular.isArray(value) || (element.val().trim().length > 0 || !isNaN(value))));
26 | };
27 | required = angular.element(' ');
28 | placeholder = angular.element(" ");
29 | if (element.attr('id') != null) {
30 | placeholder.attr('for', element.attr('id'));
31 | } else {
32 | customId = 'placeholderid_' + (Math.random() * 10000000000000000);
33 | element.attr('id', customId);
34 | placeholder.attr('for', customId);
35 | }
36 | element.after(placeholder);
37 | placeholder.html(attrs.placeholder);
38 | if ((attrs.placeholder == null) || attrs.placeholder.trim() === '') {
39 | placeholder.addClass('ng-hide');
40 | element.removeClass('better-placeholder');
41 | }
42 | if (attrs.required) {
43 | placeholder.append(required);
44 | }
45 | attrs.$observe('placeholder', function(val) {
46 | placeholder.html(val);
47 | if (attrs.required) {
48 | placeholder.append(required);
49 | }
50 | if ((val == null) || val.trim() === '') {
51 | placeholder.addClass('ng-hide');
52 | return element.removeClass('better-placeholder');
53 | } else {
54 | placeholder.removeClass('ng-hide');
55 | return element.addClass('better-placeholder');
56 | }
57 | });
58 | placeholder.on('click', function() {
59 | return element[0].focus();
60 | });
61 | attrs.$observe('required', function(val) {
62 | if (val) {
63 | return placeholder.append(required);
64 | } else {
65 | return required.remove();
66 | }
67 | });
68 | activate = function() {
69 | if ((attrs.placeholder != null) && attrs.placeholder.trim() !== '') {
70 | element.addClass('better-placeholder-active');
71 | placeholder.addClass('active');
72 | if ((element.prev() != null) && element.prev().hasClass('input-group-btn')) {
73 | return element.prev().addClass('better-placeholder-button-active');
74 | }
75 | }
76 | };
77 | deactivate = function() {
78 | element.removeClass('better-placeholder-active');
79 | placeholder.removeClass('active');
80 | if ((element.prev() != null) && element.prev().hasClass('input-group-btn')) {
81 | return element.prev().removeClass('better-placeholder-button-active');
82 | }
83 | };
84 | element.on('blur', function() {
85 | if (isEmpty()) {
86 | return deactivate();
87 | }
88 | });
89 | element.on('change input', function() {
90 | if (isEmpty()) {
91 | return deactivate();
92 | } else {
93 | return activate();
94 | }
95 | });
96 | if ((element.prev() != null) && element.prev().hasClass('input-group-btn')) {
97 | element.prev().addClass('better-placeholder-button');
98 | }
99 | if (ngModel != null) {
100 | return ngModel.$formatters.push(function(value) {
101 | if (isEmpty(value)) {
102 | deactivate();
103 | } else {
104 | activate();
105 | }
106 | return value;
107 | });
108 | } else if (!isEmpty()) {
109 | return activate();
110 | }
111 | }
112 | };
113 | });
114 |
--------------------------------------------------------------------------------
/src/angular-better-placeholders.styl:
--------------------------------------------------------------------------------
1 | // compile with stylus -u autoprefixer-stylus -c angular-better-placeholders.styl
2 |
3 | default-transition-duration = 0.2s
4 |
5 | .better-placeholder
6 | transition all default-transition-duration ease
7 | &::placeholder
8 | opacity 0
9 | &::-webkit-datetime-edit
10 | transition all default-transition-duration ease
11 | opacity 0
12 | &.fixed-height
13 | padding-top 18px
14 | height auto
15 | &:not(.better-placeholder-active) ~ .better-placeholder-text:not(.active)
16 | top 14px
17 |
18 | .better-placeholder-active, .ui-select-bootstrap.dropdown.open .better-placeholder
19 | padding-top 18px
20 | height auto
21 | &::-webkit-datetime-edit
22 | opacity 1
23 | &::placeholder
24 | opacity 0
25 |
26 | .input-group .better-placeholder ~ .input-group-btn .btn, .better-placeholder-button .btn
27 | transition all default-transition-duration ease
28 | .input-group .better-placeholder-active ~ .input-group-btn .btn, .better-placeholder-button-active .btn
29 | padding 12px
30 |
31 | .dropdown-menu .better-placeholder-text
32 | z-index 1000
33 | .better-placeholder-text, .help-block.better-placeholder-text
34 | z-index 10
35 | transition all default-transition-duration ease
36 | position absolute
37 | top 2px
38 | margin-left 12px
39 | line-height 20px
40 | height 20px
41 | color placeholder
42 | transform-origin 0 0
43 | max-width 85%
44 | margin-right 12px
45 | white-space nowrap
46 | overflow hidden
47 | text-overflow ellipsis
48 | .better-placeholder-text.active, .better-placeholder-active ~ .better-placeholder-text
49 | max-width 110%
50 | visibility visible
51 | transform scale(.8)
52 | transform-origin 0 0
53 | color #428bca
54 | top -2px
55 |
56 | .better-placeholder.disabled, .better-placeholder.disabled ~ .better-placeholder-text
57 | color #999
58 |
59 | .fa-required
60 | margin-left 6px
61 | font-size 70%
62 | vertical-align super
63 |
64 | td.input-group
65 | .better-placeholder-text, .help-block.better-placeholder-text
66 | top 11px
67 | .better-placeholder-text.active, .better-placeholder-active ~ .better-placeholder-text
68 | top 7px
69 |
70 | /* Inverted css */
71 |
72 | .ui-select-bootstrap.dropdown.open .better-placeholder.inverted, .better-placeholder-active.inverted
73 | padding-bottom 18px
74 | padding-top 6px
75 |
76 | .better-placeholder.inverted ~ .better-placeholder-text.inverted, .better-placeholder.inverted ~ .help-block.better-placeholder-text.inverted, .better-placeholder-text.inverted, .help-block.better-placeholder-text.inverte
77 | bottom 2px
78 | top auto
79 |
80 | .better-placeholder-text.inverted.active, .better-placeholder-active.inverted ~ .better-placeholder-text
81 | max-width 110%
82 | visibility visible
83 | transform scale(.8)
84 | transform-origin 0 0
85 | color #428bca
86 | bottom -8px
87 | top auto
88 |
89 | td.input-group
90 | .better-placeholder.inverted ~ .better-placeholder-text.inverted, .better-placeholder.inverted ~ .help-block.better-placeholder-text.inverted, .better-placeholder-text.inverted, .help-block.better-placeholder-text.inverte
91 | top auto
92 | bottom 11px
93 | .better-placeholder-text.inverted.active, .better-placeholder-active.inverted ~ .better-placeholder-text
94 | top auto
95 | bottom 1px
96 |
--------------------------------------------------------------------------------