esqueleto basico
This commit is contained in:
parent
8eb441e5f5
commit
0dc723713d
350 changed files with 90726 additions and 0 deletions
174
bower_components/jbox/Demo/Playground/Playground.Avatars.css
vendored
Normal file
174
bower_components/jbox/Demo/Playground/Playground.Avatars.css
vendored
Normal file
|
@ -0,0 +1,174 @@
|
|||
|
||||
.AvatarsModal .jBox-footer button {
|
||||
width: 50%;
|
||||
height: 50px;
|
||||
border: 0;
|
||||
padding: 0;
|
||||
display: block;
|
||||
float: left;
|
||||
background: center center no-repeat;
|
||||
transition: background-color .2s;
|
||||
}
|
||||
|
||||
.AvatarsModal .jBox-footer button:active {
|
||||
box-shadow: inset 0 1px 3px rgba(0, 0, 0, .2);
|
||||
}
|
||||
|
||||
#AvatarsComplete.AvatarsModal .jBox-footer button {
|
||||
width: 100%;
|
||||
float: none;
|
||||
}
|
||||
|
||||
.AvatarsModal .jBox-footer .button-cross {
|
||||
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA1MTIgNTEyIj4KPHBhdGggZmlsbD0iI2ZmZmZmZiIgZD0iTTUwNy4zLDQxMS4zQzUwNy4zLDQxMS4zLDUwNy4zLDQxMS4zLDUwNy4zLDQxMS4zTDM1MiwyNTZsMTU1LjMtMTU1LjNjMCwwLDAsMCwwLDBDNTA5LDk5LDUxMC4yLDk3LDUxMSw5NQpjMi4xLTUuNywwLjktMTIuMy0zLjctMTYuOUw0MzQsNC43QzQyOS40LDAuMSw0MjIuNy0xLjEsNDE3LDFjLTIuMSwwLjgtNCwyLTUuNywzLjdjMCwwLDAsMCwwLDBMMjU2LDE2MEwxMDAuNyw0LjdjMCwwLDAsMCwwLDAKQzk5LDMsOTcsMS44LDk1LDFjLTUuNy0yLjEtMTIuMy0wLjktMTYuOSwzLjdMNC43LDc4QzAuMSw4Mi42LTEuMSw4OS4zLDEsOTVjMC44LDIuMSwyLDQsMy43LDUuN2MwLDAsMCwwLDAsMEwxNjAsMjU2TDQuNyw0MTEuMwpjMCwwLDAsMCwwLDBDMyw0MTMsMS44LDQxNSwxLDQxN2MtMi4xLDUuNy0wLjksMTIuMywzLjcsMTYuOWw3My40LDczLjRjNC42LDQuNiwxMS4yLDUuOCwxNi45LDMuN2MyLjEtMC44LDQtMiw1LjctMy43YzAsMCwwLDAsMCwwCkwyNTYsMzUybDE1NS4zLDE1NS4zYzAsMCwwLDAsMCwwYzEuNywxLjcsMy42LDIuOSw1LjcsMy43YzUuNywyLjEsMTIuMywwLjksMTYuOS0zLjdsNzMuNC03My40YzQuNi00LjYsNS44LTExLjIsMy43LTE2LjkKQzUxMC4yLDQxNSw1MDksNDEzLDUwNy4zLDQxMS4zTDUwNy4zLDQxMS4zeiIvPgo8L3N2Zz4K);
|
||||
background-color: #e33;
|
||||
background-size: 24px auto;
|
||||
border-radius: 0 0 0 4px;
|
||||
}
|
||||
|
||||
.AvatarsModal .jBox-footer .button-cross:hover {
|
||||
background-color: #f33;
|
||||
}
|
||||
|
||||
.AvatarsModal .jBox-footer .button-cross:active {
|
||||
background-color: #e33;
|
||||
}
|
||||
|
||||
.AvatarsModal .jBox-footer .button-heart {
|
||||
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0NDggMzg0Ij4KPHBhdGggZmlsbD0iI2ZmZmZmZiIgZD0iTTIyNCwzODRjLTQsMC04LTEuNS0xMS00LjVMNTcsMjI5Yy0yLTEuOC01Ny01Mi01Ny0xMTJDMCw0My44LDQ0LjgsMCwxMTkuNSwwYzQzLjgsMCw4NC44LDM0LjUsMTA0LjUsNTQKYzE5LjgtMTkuNSw2MC44LTU0LDEwNC41LTU0QzQwMy4yLDAsNDQ4LDQzLjgsNDQ4LDExN2MwLDYwLTU1LDExMC4yLTU3LjIsMTEyLjVMMjM1LDM3OS41QzIzMiwzODIuNSwyMjgsMzg0LDIyNCwzODR6Ii8+Cjwvc3ZnPg==);
|
||||
background-color: #7d0;
|
||||
background-size: 30px auto;
|
||||
border-radius: 0 0 4px 0;
|
||||
}
|
||||
|
||||
.AvatarsModal .jBox-footer .button-heart:hover {
|
||||
background-color: #8e0;
|
||||
}
|
||||
|
||||
.AvatarsModal .jBox-footer .button-heart:active {
|
||||
background-color: #7d0;
|
||||
}
|
||||
|
||||
.AvatarsModal .jBox-footer .button-close {
|
||||
background-color: #ddd;
|
||||
border-radius: 0 0 4px 4px;
|
||||
}
|
||||
|
||||
.AvatarsModal .jBox-footer .button-close:hover {
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
.AvatarsModal .jBox-footer .button-close:active {
|
||||
background-color: #ddd;
|
||||
}
|
||||
|
||||
.AvatarsModal .jBox-content {
|
||||
padding: 0;
|
||||
background: center -10px no-repeat;
|
||||
}
|
||||
|
||||
#AvatarsComplete.AvatarsModal .jBox-content {
|
||||
font-style: italic;
|
||||
text-align: center;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
#AvatarsComplete.AvatarsModal .jBox-content > div {
|
||||
position: absolute;
|
||||
top: calc(50% - 23px);
|
||||
left: 25px;
|
||||
right: 25px;
|
||||
}
|
||||
|
||||
.AvatarsModal .jBox-title {
|
||||
font-size: 26px;
|
||||
color: #000;
|
||||
font-weight: 300;
|
||||
text-align: center;
|
||||
padding: 0;
|
||||
line-height: 60px;
|
||||
}
|
||||
|
||||
.AvatarsModal .jBox-footer {
|
||||
border-top: 0;
|
||||
background: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.AvatarsTooltip .jBox-content {
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.AvatarsTooltip .jBox-container,
|
||||
.AvatarsTooltip .jBox-pointer:after {
|
||||
background: #000;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.AvatarsTooltipLike .jBox-container,
|
||||
.AvatarsTooltipLike .jBox-pointer:after {
|
||||
border-color: #7d0;
|
||||
}
|
||||
|
||||
.AvatarsTooltipDislike .jBox-container,
|
||||
.AvatarsTooltipDislike .jBox-pointer:after {
|
||||
border-color: #e33;
|
||||
}
|
||||
|
||||
.AvatarsCollection {
|
||||
width: 50%;
|
||||
position: fixed;
|
||||
bottom: 5px;
|
||||
z-index: 11000;
|
||||
}
|
||||
|
||||
.AvatarsCollection#DislikedAvatars {
|
||||
left: 4px;
|
||||
}
|
||||
|
||||
.AvatarsCollection#LikedAvatars {
|
||||
right: 4px;
|
||||
}
|
||||
|
||||
.AvatarsCollection > div {
|
||||
width: 47px;
|
||||
height: 45px;
|
||||
padding: 0 1px;
|
||||
}
|
||||
|
||||
.AvatarsCollection#DislikedAvatars > div {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.AvatarsCollection#LikedAvatars > div {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.AvatarsCollection > div > div {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
width: 45px;
|
||||
height: 45px;
|
||||
border: 2px solid red;
|
||||
border-radius: 50%;
|
||||
background: #000;
|
||||
}
|
||||
|
||||
.AvatarsCollection#DislikedAvatars > div > div {
|
||||
border-color: #e33;
|
||||
}
|
||||
|
||||
.AvatarsCollection#LikedAvatars > div > div {
|
||||
border-color: #7d0;
|
||||
}
|
||||
|
||||
.AvatarsCollection > div > div > img {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
margin-top: -27px;
|
||||
margin-left: -30px;
|
||||
}
|
272
bower_components/jbox/Demo/Playground/Playground.Avatars.js
vendored
Normal file
272
bower_components/jbox/Demo/Playground/Playground.Avatars.js
vendored
Normal file
|
@ -0,0 +1,272 @@
|
|||
|
||||
/* Playground Demo: Avatars */
|
||||
|
||||
|
||||
// All data we are using for this demo we will store in the variable DemoAvatars
|
||||
|
||||
var DemoAvatars = {
|
||||
Avatars: ['Stephan', 'Susan', 'Jack', 'Elizabeth', 'Fungus', 'Donald', 'Gary', 'Trixi', 'Samuel', 'Maria'],
|
||||
Modals: {}
|
||||
};
|
||||
|
||||
|
||||
// All the magic happens in the function generateAvatarJBox
|
||||
|
||||
function generateAvatarJBox(initial)
|
||||
{
|
||||
// We only need to initialize the tooltips for the avatar collection once
|
||||
// We can later refer to this jBox instance with DemoAvatars.AvatarsTooltip
|
||||
|
||||
!DemoAvatars.AvatarsTooltip && (DemoAvatars.AvatarsTooltip = new jBox('Tooltip', {
|
||||
theme: 'TooltipBorder', // We are using the border theme...
|
||||
addClass: 'AvatarsTooltip', // ...and add a class so we can adjust the theme with CSS
|
||||
attach: '[data-avatar-tooltip]', // We attach the tooltip to the elements with the attribute data-avatar-tooltip...
|
||||
getContent: 'data-avatar-tooltip', // ... and also get the content from the same attribute
|
||||
zIndex: 12000, // These tooltips have the highest z-index
|
||||
animation: 'move',
|
||||
|
||||
// Adding the liked or disliked class depending on the container the avatar is in
|
||||
onOpen: function () {
|
||||
this.wrapper.removeClass('AvatarsTooltipLike AvatarsTooltipDislike').addClass('AvatarsTooltip' + (this.source.parent().attr('id') == 'LikedAvatars' ? 'Like' : 'Dislike'));
|
||||
}
|
||||
}));
|
||||
|
||||
|
||||
// When we are creating the initial jBox, reset global variables
|
||||
|
||||
if (initial) {
|
||||
DemoAvatars.clicked = false;
|
||||
DemoAvatars.current = -1;
|
||||
}
|
||||
|
||||
|
||||
// Increase current avatar index
|
||||
|
||||
DemoAvatars.current++;
|
||||
|
||||
|
||||
// When we looped through all the avatars, show a jBox Modal with a hint that there are no more avatars nearby
|
||||
|
||||
if (DemoAvatars.current >= DemoAvatars.Avatars.length) {
|
||||
|
||||
DemoAvatars.Modals.AvatarsComplete = new jBox('Modal', {
|
||||
|
||||
// We use similar options to our Avatar modal so they look similar
|
||||
id: 'AvatarsComplete',
|
||||
addClass: 'AvatarsModal',
|
||||
width: 300,
|
||||
height: 250,
|
||||
animation: 'zoomIn',
|
||||
overlay: false,
|
||||
blockScroll: false,
|
||||
closeButton: false,
|
||||
closeOnEsc: false,
|
||||
adjustDistance: {
|
||||
top: 40,
|
||||
right: 5,
|
||||
bottom: 55,
|
||||
left: 5
|
||||
},
|
||||
footer: '<button class="button-close">Close</button>',
|
||||
title: 'Whoops',
|
||||
content: '<div>There are currently no more avatars near you</div>',
|
||||
zIndex: 10000,
|
||||
|
||||
// Once this jBox is created, we tel the close button to close the initial avatar modal
|
||||
onCreated: function () {
|
||||
this.footer.find('button').on('click', function () {
|
||||
DemoAvatars.Modals.AvatarsInitial.close();
|
||||
});
|
||||
}
|
||||
}).open();
|
||||
|
||||
// Nothing more to do, abort here
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// We are creating a new jBox Modal with the avatars each time this function gets called
|
||||
|
||||
var jBoxAvatar = new jBox('Modal', {
|
||||
addClass: 'AvatarsModal',
|
||||
width: 300,
|
||||
height: 250,
|
||||
animation: 'zoomIn',
|
||||
zIndex: 10000,
|
||||
|
||||
// Adjusting the distance to the viewport so we have space for the avatar collection at the bottom and the close button of the modal at the top
|
||||
adjustDistance: {
|
||||
top: 40,
|
||||
right: 5,
|
||||
bottom: 55,
|
||||
left: 5
|
||||
},
|
||||
|
||||
// We are setting these options differently for the initial and the following jBoxes
|
||||
id: initial ? 'AvatarsInitial' : 'AvatarsModal' + DemoAvatars.current,
|
||||
overlay: initial ? true : false, // Only one overlay is needed
|
||||
blockScroll: initial ? true : false, // The initial jBox will block scrolling, no need for the others to o the same
|
||||
closeButton: initial ? 'overlay' : false, // The initial jBox will have the close button in the overlay, the others won't need one
|
||||
closeOnEsc: initial ? true : false, // Only the inital jBox can be closed with [ESC] button
|
||||
|
||||
// Placing the buttons in the footer area
|
||||
footer: '<div class="clearfix"><button class="button-cross cross"></button><button class="button-heart heart"></button></div>',
|
||||
|
||||
// Open this jBox when it is being initialized
|
||||
onInit: function () {
|
||||
this.open();
|
||||
|
||||
// Here we store the index we used for this jBox
|
||||
this.AvatarIndex = DemoAvatars.current;
|
||||
},
|
||||
|
||||
// When the jBox is created, add the click events to the buttons
|
||||
onCreated: function () {
|
||||
|
||||
// Create the containers for the liked or disliked avatars
|
||||
if (initial) {
|
||||
$('<div id="LikedAvatars" class="AvatarsCollection"/>').appendTo($('body'));
|
||||
$('<div id="DislikedAvatars" class="AvatarsCollection"/>').appendTo($('body'));
|
||||
}
|
||||
|
||||
$.each(this.footer.find('button'), function (index, el) {
|
||||
|
||||
// Adding the click events for the buttons in the footer
|
||||
$(el).on('click', function () {
|
||||
|
||||
// Storing a global var that the user clicked on a button
|
||||
DemoAvatars.clicked = true;
|
||||
|
||||
// When a user clicks a button close the tooltips
|
||||
DemoAvatars.AvatarsTooltipLike && DemoAvatars.AvatarsTooltipLike.close();
|
||||
DemoAvatars.AvatarsTooltipDislike && DemoAvatars.AvatarsTooltipDislike.close();
|
||||
|
||||
// When we click a button, the jBox disappears, let's tell this jBox that we removed it
|
||||
this.AvatarRemoved = true;
|
||||
|
||||
// Did we like or dislike the avatar?
|
||||
var liked = $(el).hasClass('button-heart');
|
||||
|
||||
// Slide the jBox to the left or right depending on which button the user clicked
|
||||
this.animate('slide' + (liked ? 'Right' : 'Left'), {
|
||||
|
||||
// Once the jBox is removed, hide it and show the avatar in the collection
|
||||
complete: function () {
|
||||
this.wrapper.css('display', 'none');
|
||||
|
||||
// Which container to use
|
||||
var collectionContainer = liked ? $('#LikedAvatars') : $('#DislikedAvatars');
|
||||
|
||||
// If there if not enough space for the avatars to show in one line remove the first one
|
||||
if (collectionContainer.find('div[data-avatar-tooltip]').length && ((collectionContainer.find('div[data-avatar-tooltip]').length + 1) * $(collectionContainer.find('div[data-avatar-tooltip]')[0]).outerWidth(true) > collectionContainer.outerWidth())) {
|
||||
$(collectionContainer.find('div[data-avatar-tooltip]')[0]).remove();
|
||||
}
|
||||
|
||||
// Add the avatar to the collection
|
||||
this.animate('popIn', {
|
||||
element: $('<div data-avatar-tooltip="You ' + (liked ? 'liked' : 'disliked') + ' ' + DemoAvatars.Avatars[this.AvatarIndex] + '"/>').append($('<div/>').html('<img src="https://stephanwagner.me/img/jBox/avatar/' + DemoAvatars.Avatars[this.AvatarIndex] + '.svg"/>')).appendTo(collectionContainer)
|
||||
});
|
||||
|
||||
// Attach the avatar tooltip
|
||||
DemoAvatars.AvatarsTooltip && DemoAvatars.AvatarsTooltip.attach();
|
||||
|
||||
}.bind(this)
|
||||
});
|
||||
|
||||
// Open another Avatar jBox
|
||||
generateAvatarJBox();
|
||||
|
||||
}.bind(this));
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
// When we open the jBox, set the new content and show the tooltips if it's the initial jBox
|
||||
onOpen: function () {
|
||||
|
||||
// Set title and content depending on current index
|
||||
this.setTitle(DemoAvatars.Avatars[DemoAvatars.current]);
|
||||
this.content.css({backgroundImage: 'url(https://stephanwagner.me/img/jBox/avatar/' + DemoAvatars.Avatars[DemoAvatars.current] + '.svg)'});
|
||||
|
||||
// If it's the inital jBox, show the tooltips after a short delay
|
||||
initial && setTimeout(function () {
|
||||
|
||||
// We are creating the two tooltips in a loop as they are very similar
|
||||
$.each(['Dislike', 'Like'], function (index, item) {
|
||||
|
||||
// We store the tooltips in the global var so we can refer to them later
|
||||
DemoAvatars['AvatarsTooltip' + item] = new jBox('Tooltip', {
|
||||
theme: 'TooltipBorder',
|
||||
addClass: 'AvatarsTooltip AvatarsTooltip' + item,
|
||||
minWidth: 110,
|
||||
content: item,
|
||||
position: {
|
||||
y: 'bottom'
|
||||
},
|
||||
offset: {
|
||||
y: 5
|
||||
},
|
||||
target: '#AvatarsInitial .jBox-footer .button-' + (item == 'Like' ? 'heart' : 'cross'),
|
||||
animation: 'move',
|
||||
zIndex: 11000,
|
||||
|
||||
// Abort opening the tooltips when we clicked on a like or dislike button already
|
||||
onOpen: function () {
|
||||
DemoAvatars.clicked && this.close();
|
||||
}
|
||||
}).open();
|
||||
|
||||
});
|
||||
|
||||
}, 500);
|
||||
}
|
||||
});
|
||||
|
||||
// If it's the inital jBox add onClose events
|
||||
initial && (jBoxAvatar.options.onClose = function ()
|
||||
{
|
||||
// Loop through all avatar jBoxes and close them if they are not removed yet
|
||||
$.each(DemoAvatars.Modals, function (index, jBox) {
|
||||
jBox.id != 'AvatarsInitial' && !jBox.AvatarRemoved && jBox.close();
|
||||
}.bind(this));
|
||||
|
||||
// Remove the collection containers with a sliding animation
|
||||
$.each(['Liked', 'Disliked'], function (index, item) {
|
||||
this.animate('slide' + (item == 'Liked' ? 'Right' : 'Left'), {
|
||||
element: $('#' + item + 'Avatars'),
|
||||
complete: function () {
|
||||
$('#' + item + 'Avatars').remove();
|
||||
}
|
||||
});
|
||||
}.bind(this));
|
||||
|
||||
// Close the tooltips
|
||||
DemoAvatars.AvatarsTooltipLike && DemoAvatars.AvatarsTooltipLike.close();
|
||||
DemoAvatars.AvatarsTooltipDislike && DemoAvatars.AvatarsTooltipDislike.close();
|
||||
});
|
||||
|
||||
// If it's the inital jBox add onCloseComplete events
|
||||
initial && (jBoxAvatar.options.onCloseComplete = function ()
|
||||
{
|
||||
// Loop through all modal jBoxes and remove them from DOM
|
||||
$.each(DemoAvatars.Modals, function (index, jBox) {
|
||||
jBox.destroy();
|
||||
delete DemoAvatars.Modals[jBox.id];
|
||||
});
|
||||
|
||||
// Remove the tooltips from DOM
|
||||
DemoAvatars.AvatarsTooltipLike && DemoAvatars.AvatarsTooltipLike.destroy();
|
||||
DemoAvatars.AvatarsTooltipDislike && DemoAvatars.AvatarsTooltipDislike.destroy();
|
||||
});
|
||||
|
||||
// Store the jBox in the modal collection
|
||||
DemoAvatars.Modals[jBoxAvatar.id] = jBoxAvatar;
|
||||
}
|
||||
|
||||
|
||||
// On domready, add the click event to the button
|
||||
|
||||
$(document).ready(function() {
|
||||
|
||||
$('#DemoAvatars').click(function () { generateAvatarJBox(true); });
|
||||
|
||||
});
|
269
bower_components/jbox/Demo/Playground/Playground.Login.css
vendored
Normal file
269
bower_components/jbox/Demo/Playground/Playground.Login.css
vendored
Normal file
|
@ -0,0 +1,269 @@
|
|||
|
||||
/* Restyle jBoxes */
|
||||
|
||||
#jBoxLogin .jBox-content {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#jBoxLogin .jBox-title {
|
||||
text-align: center;
|
||||
line-height: 1.6;
|
||||
padding: 15px 0;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.jBox-TooltipSmall.LoginTooltipSmall .jBox-content,
|
||||
.jBox-TooltipError.LoginTooltipError .jBox-content {
|
||||
font-size: 13px;
|
||||
padding: 5px 10px;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
.jBox-TooltipSmall.LoginTooltipSmall .jBox-container,
|
||||
.jBox-TooltipError.LoginTooltipError .jBox-container {
|
||||
border-radius: 2px;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.jBox-TooltipSmall.LoginTooltipError .jBox-container {
|
||||
background: #d00;
|
||||
}
|
||||
|
||||
.jBox-TooltipSmall.LoginTooltipSmall .jBox-container {
|
||||
background: #246bb3;
|
||||
}
|
||||
|
||||
.jBox-TooltipSmall.LoginTooltipSmall .jBox-pointer:after {
|
||||
background: #246bb3;
|
||||
}
|
||||
|
||||
/* Content */
|
||||
|
||||
.login-container {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.login-container.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.login-body {
|
||||
padding: 0 25px;
|
||||
}
|
||||
|
||||
.login-container button {
|
||||
margin: 25px 0 0;
|
||||
}
|
||||
|
||||
.login-textfield-wrapper {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.login-remember {
|
||||
margin: 25px 0 0;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
#LoginWrapper.request-running .login-footer a,
|
||||
#LoginWrapper.request-running .login-footer span {
|
||||
cursor: default !important;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
/* Form elements */
|
||||
|
||||
.login-textfield {
|
||||
width: 100%;
|
||||
border: 0;
|
||||
border-bottom: 2px solid #ddd;
|
||||
padding: 6px 2px;
|
||||
font-size: 18px;
|
||||
margin-top: 25px;
|
||||
transition: border-color .2s;
|
||||
}
|
||||
|
||||
.login-textfield:hover {
|
||||
border-bottom-color: #ccc;
|
||||
}
|
||||
|
||||
.login-textfield:focus {
|
||||
border-bottom-color: #246bb3;
|
||||
}
|
||||
|
||||
.login-textfield.textfield-error {
|
||||
border-bottom-color: #d00;
|
||||
}
|
||||
|
||||
.login-checkbox {
|
||||
float: left;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 3px;
|
||||
background: #eee;
|
||||
box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .05);
|
||||
transition: background .2s;
|
||||
}
|
||||
|
||||
.login-checkbox.login-checkbox-active {
|
||||
box-shadow: none;
|
||||
background: #7d0;
|
||||
}
|
||||
|
||||
.login-checkbox-check {
|
||||
opacity: 0;
|
||||
background: no-repeat center center;
|
||||
background-size: 14px;
|
||||
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0MjQuNTMgMzE1LjczIj4KPHBhdGggZmlsbD0iI2ZmZmZmZiIgZD0iTTQ2NS4wNywxNTMuNmExMC4zMSwxMC4zMSwwLDAsMCwwLTE0LjkzTDQyOC44LDEwMi40YTEwLjMxLDEwLjMxLDAsMCwwLTE0LjkzLDBMMjAwLjUzLDMxNS43Myw5OC4xMywyMTMuMzNhMTAuMzEsMTAuMzEsMCwwLDAtMTQuOTMsMEw0Ni45MywyNDkuNmExMC4zMSwxMC4zMSwwLDAsMCwwLDE0LjkzbDE0Ny4yLDE0Ny4yYTEwLjMxLDEwLjMxLDAsMCwwLDE0LjkzLDBsMjU2LTI1OC4xM1oiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC00My43MyAtOTkuMikiLz4KPC9zdmc+);
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin-top: -10px;
|
||||
margin-left: -10px;
|
||||
transition: opacity .2s;
|
||||
}
|
||||
|
||||
.login-checkbox.login-checkbox-active .login-checkbox-check {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.login-checkbox-label {
|
||||
float: left;
|
||||
cursor: pointer;
|
||||
width: calc(100% - 20px);
|
||||
line-height: 20px;
|
||||
font-size: 17px;
|
||||
padding: 0 0 0 12px;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.login-button {
|
||||
width: 100%;
|
||||
border: 0;
|
||||
color: #fff;
|
||||
background: #246bb3;
|
||||
border-radius: 4px;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
font-size: 20px;
|
||||
padding: 0;
|
||||
transition: background .2s;
|
||||
}
|
||||
|
||||
.login-button:hover {
|
||||
background: #3878c1;
|
||||
}
|
||||
|
||||
.login-button:active {
|
||||
background: #246bb3;
|
||||
}
|
||||
|
||||
.login-button[disabled] {
|
||||
cursor: default !important;
|
||||
color: #ccc !important;
|
||||
background: #eee !important;
|
||||
}
|
||||
|
||||
.loading-bar,
|
||||
.login-button[disabled].loading-bar {
|
||||
background-image: linear-gradient(-45deg, rgba(255, 255, 255, .4) 25%, rgba(255, 255, 255, .0) 25%, rgba(255, 255, 255, .0) 50%, rgba(255, 255, 255, .4) 50%, rgba(255, 255, 255, .4) 75%, rgba(255, 255, 255, .0) 75%, rgba(255, 255, 255, .0)) !important;
|
||||
background-size: 32px 32px !important;
|
||||
background-repeat: repeat !important;
|
||||
transition: background-position 60000s linear !important;
|
||||
background-position: 4000000px !important;
|
||||
}
|
||||
|
||||
/* Footer */
|
||||
|
||||
.login-footer {
|
||||
background: #fafafa;
|
||||
border-top: 1px solid #eee;
|
||||
border-radius: 0 0 4px 4px;
|
||||
font-size: 17px;
|
||||
line-height: 1.6;
|
||||
padding: 15px 0 15px 25px;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.login-footer span {
|
||||
cursor: pointer;
|
||||
color: #297acc;
|
||||
}
|
||||
|
||||
.login-footer span:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
TODO
|
||||
|
||||
.password-strength {
|
||||
width: 10px;
|
||||
height: 6px;
|
||||
top: 39px;
|
||||
right: 11px;
|
||||
}
|
||||
|
||||
.password-strength:before,
|
||||
.password-strength:after {
|
||||
content: '';
|
||||
width: 10px;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.password-strength,
|
||||
.password-strength:before,
|
||||
.password-strength:after {
|
||||
position: absolute;
|
||||
background: #eee;
|
||||
transition: background .15s;
|
||||
}
|
||||
|
||||
.password-strength:before {
|
||||
right: calc(100% + 1px);
|
||||
border-radius: 2px 0 0 2px;
|
||||
}
|
||||
|
||||
.password-strength:after {
|
||||
left: calc(100% + 1px);
|
||||
border-radius: 0 2px 2px 0;
|
||||
}
|
||||
|
||||
.password-strength.level1:before {
|
||||
background: #e00;
|
||||
}
|
||||
|
||||
.password-strength.level2,
|
||||
.password-strength.level2:before {
|
||||
background: #fc0;
|
||||
}
|
||||
|
||||
.password-strength.level3,
|
||||
.password-strength.level3:before,
|
||||
.password-strength.level3:after {
|
||||
background: #7d0;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/* Common */
|
||||
|
||||
.noselect {
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
399
bower_components/jbox/Demo/Playground/Playground.Login.js
vendored
Normal file
399
bower_components/jbox/Demo/Playground/Playground.Login.js
vendored
Normal file
|
@ -0,0 +1,399 @@
|
|||
|
||||
/* Playground Demo: Login */
|
||||
|
||||
/*
|
||||
|
||||
This playground demo is still in production
|
||||
|
||||
I will improve this shortly and add the options to recover and reset the password
|
||||
|
||||
Let me know if you have questions or ideas how to improve this login modal:
|
||||
|
||||
stephanwagner.me@gmail.com
|
||||
|
||||
*/
|
||||
|
||||
|
||||
// We are ssetting up a global variable where we can adjust html and texts
|
||||
|
||||
var jBoxLogin = {
|
||||
jBox: null,
|
||||
|
||||
|
||||
// The html of each of the content containers
|
||||
|
||||
html: {
|
||||
login: '<div id="LoginContainer-login" class="login-container"><div class="login-body"><input type="text" id="loginUsername" class="login-textfield" placeholder="Username" autocorrect="off" autocapitalize="off" spellcheck="false"><input type="password" id="loginPassword" class="login-textfield" placeholder="Password" autocorrect="off" autocapitalize="off" spellcheck="false"><div class="login-remember"><div class="login-checkbox"><div class="login-checkbox-check"></div></div><div class="login-checkbox-label">Remember me</div><input type="hidden" name="login-remember" value="1"></div><button class="login-button">Login</button></div><div class="login-footer"><span onclick="jBoxLogin.jBox.showContent(\'register\')">Create new account</span><br><span style="display: none" onclick="jBoxLogin.jBox.showContent(\'password-recovery\')">Forgot password?</span></div></div>',
|
||||
register: '<div id="LoginContainer-register" class="login-container"><div class="login-body"><input type="text" id="registerUsername" class="login-textfield" placeholder="Username" maxlength="24" autocorrect="off" autocapitalize="off" spellcheck="false"><input type="text" id="registerEmail" class="login-textfield" placeholder="Email address" maxlength="128" autocorrect="off" autocapitalize="off" spellcheck="false"><div class="login-textfield-wrapper"><input type="password" class="login-textfield" id="registerPassword" placeholder="Password" maxlength="32" autocorrect="off" autocapitalize="off" spellcheck="false"><div class="password-strength" style="display: none"></div></div><button class="login-button">Create account</button></div><div class="login-footer"><span onclick="jBoxLogin.jBox.showContent(\'login\')">Already registered? Login!</span></div></div>',
|
||||
passwordRecovery: '', // TODO '<div id="LoginContainer-password-recovery" class="login-container"><div class="login-body"><input type="text" class="login-textfield" placeholder="Email address" autocorrect="off" autocapitalize="off" spellcheck="false"><button class="login-button">Reset password</button></div><div class="login-footer"><span onclick="jBoxLogin.jBox.showContent(\'login\')">Already registered? Login!</span></div></div>',
|
||||
passwordReset: '' // TODO '<div id="LoginContainer-password-reset" class="login-container"><div class="login-body"><input type="text" placeholder="Recovery Code"><input type="password" placeholder="Password" autocorrect="off" autocapitalize="off" spellcheck="false"><button class="login-button">Reset password</button></div><div class="login-footer"><span onclick="jBoxLogin.jBox.showContent(\'login\')">Already registered? Login!</span></div></div>'
|
||||
},
|
||||
|
||||
|
||||
// Corresponding titles for content elements
|
||||
|
||||
title: {
|
||||
login: 'Login',
|
||||
register: 'Create new account',
|
||||
// TODO passwordRecovery: 'Recover password',
|
||||
// TODO passwordReset: 'Reset password'
|
||||
},
|
||||
|
||||
|
||||
// These tooltips will show when a textelemet gets focus
|
||||
|
||||
textfieldTooltips: {
|
||||
loginUsername: 'For this demo the username is "username"',
|
||||
loginPassword: 'For this demo the password is "password"',
|
||||
registerUsername: 'Choose a unique username',
|
||||
registerEmail: 'Your email address',
|
||||
registerPassword: 'Be tricky, use numbers and special characters'
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
$(document).ready(function() {
|
||||
|
||||
|
||||
// On domready create the login modal
|
||||
|
||||
jBoxLogin.jBox = new jBox('Modal', {
|
||||
|
||||
// Unique id for CSS access
|
||||
id: 'jBoxLogin',
|
||||
|
||||
// Dimensions
|
||||
width: 320, // TODO move to global var
|
||||
height: 350,
|
||||
|
||||
// Attach to elements
|
||||
attach: '#DemoLogin',
|
||||
|
||||
// Create the content with the html provided in global var
|
||||
content: '<div id="LoginWrapper">' + jBoxLogin.html.login + jBoxLogin.html.register + jBoxLogin.html.passwordRecovery + jBoxLogin.html.passwordReset + '</div>',
|
||||
|
||||
// When the jBox is being initialized add internal functions
|
||||
onInit: function () {
|
||||
|
||||
// Internal function to show content
|
||||
this.showContent = function (id, force) {
|
||||
|
||||
// Abort if an ajax call is loading
|
||||
if (!force && $('#LoginWrapper').hasClass('request-running')) return null;
|
||||
|
||||
// Set the title depending on id
|
||||
this.setTitle(jBoxLogin.title[id]);
|
||||
|
||||
// Show content depending on id
|
||||
$('.login-container.active').removeClass('active');
|
||||
$('#LoginContainer-' + id).addClass('active');
|
||||
|
||||
// Remove error tooltips
|
||||
// TODO only loop through active elements or store tooltips in global var rather than on the element
|
||||
$.each(jBoxLogin.textfieldTooltips, function (id, tt) {
|
||||
$('#' + id).data('jBoxTextfieldError') && $('#' + id).data('jBoxTextfieldError').close();
|
||||
});
|
||||
};
|
||||
|
||||
// Initially show content for login
|
||||
this.showContent('login', true);
|
||||
|
||||
// Add focus and blur events to textfields
|
||||
$.each(jBoxLogin.textfieldTooltips, function (id, tt) {
|
||||
|
||||
// Focus an textelement
|
||||
$('#' + id).on('focus', function () {
|
||||
|
||||
// When there is an error tooltip close it
|
||||
$(this).data('jBoxTextfieldError') && $(this).data('jBoxTextfieldError').close();
|
||||
|
||||
// Remove the error state from the textfield
|
||||
$(this).removeClass('textfield-error');
|
||||
|
||||
// Store the tooltip jBox in the elements data
|
||||
if (!$(this).data('jBoxTextfieldTooltip')) {
|
||||
|
||||
// TODO create a small jbox plugin
|
||||
|
||||
$(this).data('jBoxTextfieldTooltip', new jBox('Tooltip', {
|
||||
width: 310, // TODO use modal width - 10
|
||||
theme: 'TooltipSmall',
|
||||
addClass: 'LoginTooltipSmall',
|
||||
target: $(this),
|
||||
position: {
|
||||
x: 'left',
|
||||
y: 'top'
|
||||
},
|
||||
outside: 'y',
|
||||
offset: {
|
||||
y: 6,
|
||||
x: 8
|
||||
},
|
||||
pointer: 'left:17',
|
||||
content: tt,
|
||||
animation: 'move'
|
||||
}));
|
||||
}
|
||||
$(this).data('jBoxTextfieldTooltip').open();
|
||||
|
||||
// Loose focus of textelement
|
||||
}).on('blur', function () {
|
||||
$(this).data('jBoxTextfieldTooltip').close();
|
||||
});
|
||||
});
|
||||
|
||||
// Internal function to show errors
|
||||
this.showError = function (element, message) {
|
||||
|
||||
if (!element.data('errorTooltip')) {
|
||||
|
||||
// TODO add the error class here
|
||||
|
||||
element.data('errorTooltip', new jBox('Tooltip', {
|
||||
width: 310,
|
||||
theme: 'TooltipError',
|
||||
addClass: 'LoginTooltipError',
|
||||
target: element,
|
||||
position: {
|
||||
x: 'left',
|
||||
y: 'top'
|
||||
},
|
||||
outside: 'y',
|
||||
offset: {
|
||||
y: 6
|
||||
},
|
||||
pointer: 'left:9',
|
||||
content: message,
|
||||
animation: 'move'
|
||||
}));
|
||||
}
|
||||
|
||||
element.data('errorTooltip').open();
|
||||
};
|
||||
|
||||
// Internal function to change checkbox state
|
||||
this.toggleCheckbox = function () {
|
||||
// Abort if an ajax call is loading
|
||||
if ($('#LoginWrapper').hasClass('request-running')) return null;
|
||||
|
||||
$('.login-checkbox').toggleClass('login-checkbox-active');
|
||||
};
|
||||
|
||||
// Add checkbox events to checkbox and label
|
||||
$('.login-checkbox, .login-checkbox-label').on('click', function () {
|
||||
this.toggleCheckbox();
|
||||
}.bind(this));
|
||||
|
||||
// Parse an ajax repsonse
|
||||
this.parseResponse = function(response) {
|
||||
try {
|
||||
response = JSON.parse(response.responseText || response);
|
||||
} catch (e) {}
|
||||
return response;
|
||||
};
|
||||
|
||||
// Show a global error
|
||||
this.globalError = function () {
|
||||
new jBox('Notice', {
|
||||
color: 'red',
|
||||
content: 'Oops, something went wrong.',
|
||||
attributes: {
|
||||
x: 'right',
|
||||
y: 'bottom'
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Internal function to disable or enable the form while request is running
|
||||
this.startRequest = function() {
|
||||
this.toggleRequest();
|
||||
}.bind(this);
|
||||
|
||||
this.completeRequest = function() {
|
||||
this.toggleRequest(true);
|
||||
}.bind(this);
|
||||
|
||||
this.toggleRequest = function (enable) {
|
||||
$('#LoginWrapper')[enable ? 'removeClass' : 'addClass']('request-running');
|
||||
$('#LoginWrapper button')[enable ? 'removeClass' : 'addClass']('loading-bar');
|
||||
$('#LoginWrapper input, #LoginWrapper button').attr('disabled', enable ? false : 'disabled');
|
||||
}.bind(this);
|
||||
|
||||
// Bind ajax login function to login button
|
||||
$('#LoginContainer-login button').on('click', function () {
|
||||
$.ajax({
|
||||
url: 'https://stephanwagner.me/PlaygroundLogin/login',
|
||||
data: {
|
||||
username: $('#loginUsername').val(),
|
||||
password: $('#loginPassword').val(),
|
||||
remember: $('.login-checkbox').hasClass('login-checkbox-active') ? 1 : 0
|
||||
},
|
||||
method: 'post',
|
||||
beforeSend: function () {
|
||||
this.startRequest();
|
||||
}.bind(this),
|
||||
|
||||
// Ajax call successfull
|
||||
success: function (response) {
|
||||
this.completeRequest();
|
||||
response = this.parseResponse(response);
|
||||
|
||||
// Login successfull
|
||||
if (response.success) {
|
||||
|
||||
this.close();
|
||||
|
||||
new jBox('Notice', {
|
||||
color: 'green',
|
||||
content: 'You are now logged in',
|
||||
attributes: {
|
||||
x: 'right',
|
||||
y: 'bottom'
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Redirect or own login behavior here
|
||||
|
||||
|
||||
// Login failed
|
||||
} else {
|
||||
// Shake submit button
|
||||
this.animate('shake', {element: $('#LoginContainer-login button')});
|
||||
|
||||
if (response.errors) {
|
||||
// Show error on textfields, for login no error tooltips neccessary, username or password is wrong
|
||||
$('#loginUsername, #loginPassword').addClass('textfield-error');
|
||||
} else {
|
||||
// Backend error
|
||||
this.globalError();
|
||||
}
|
||||
}
|
||||
}.bind(this),
|
||||
|
||||
// Ajax call failed
|
||||
error: function () {
|
||||
this.completeRequest();
|
||||
this.animate('shake', {element: $('#LoginContainer-login button')});
|
||||
this.globalError();
|
||||
}.bind(this)
|
||||
});
|
||||
|
||||
}.bind(this));
|
||||
|
||||
// Bind ajax register function to register button
|
||||
$('#LoginContainer-register button').on('click', function () {
|
||||
$.ajax({
|
||||
url: 'https://stephanwagner.me/PlaygroundLogin/register',
|
||||
data: {
|
||||
username: $('#registerUsername').val(),
|
||||
email: $('#registerEmail').val(),
|
||||
password: $('#registerPassword').val()
|
||||
},
|
||||
method: 'post',
|
||||
beforeSend: function () {
|
||||
this.startRequest();
|
||||
}.bind(this),
|
||||
|
||||
success: function (response) {
|
||||
this.completeRequest();
|
||||
response = this.parseResponse(response);
|
||||
|
||||
// Registration successfull
|
||||
if (response.success) {
|
||||
|
||||
this.close();
|
||||
|
||||
new jBox('Notice', {
|
||||
color: 'green',
|
||||
content: 'Your account was created',
|
||||
attributes: {
|
||||
x: 'right',
|
||||
y: 'bottom'
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Redirect or own register behavior here
|
||||
|
||||
|
||||
// Registration failed
|
||||
} else {
|
||||
// Shake submit button
|
||||
this.animate('shake', {element: $('#LoginContainer-register button')});
|
||||
|
||||
if (response.errors) {
|
||||
|
||||
// Loop through errors and open tooltips
|
||||
$.each(response.errors, function (id, error) {
|
||||
|
||||
// TODO Only one tooltip at a time
|
||||
|
||||
var id_selector = 'register' + (id).substr(0,1).toUpperCase() + (id).substr(1);
|
||||
|
||||
$('#' + id_selector).addClass('textfield-error');
|
||||
|
||||
if (!$('#' + id_selector).data('jBoxTextfieldError')) {
|
||||
$('#' + id_selector).data('jBoxTextfieldError', new jBox('Tooltip', {
|
||||
width: 310,
|
||||
theme: 'TooltipError',
|
||||
addClass: 'LoginTooltipError',
|
||||
target: $('#' + id_selector),
|
||||
position: {
|
||||
x: 'left',
|
||||
y: 'top'
|
||||
},
|
||||
outside: 'y',
|
||||
offset: {
|
||||
y: 6,
|
||||
x: 8
|
||||
},
|
||||
pointer: 'left:17',
|
||||
//content: error,
|
||||
animation: 'move'
|
||||
}));
|
||||
}
|
||||
|
||||
$('#' + id_selector).data('jBoxTextfieldError').setContent(error).open();
|
||||
|
||||
});
|
||||
|
||||
// Backend error
|
||||
} else {
|
||||
this.globalError();
|
||||
}
|
||||
}
|
||||
}.bind(this),
|
||||
|
||||
// Ajax call failed
|
||||
error: function () {
|
||||
this.completeRequest();
|
||||
this.animate('shake', {element: $('#RegisterContainer-login button')});
|
||||
this.globalError();
|
||||
}.bind(this)
|
||||
});
|
||||
|
||||
}.bind(this));
|
||||
|
||||
},
|
||||
onOpen: function () {
|
||||
|
||||
// Go back to login when we open the modal
|
||||
this.showContent('login', true);
|
||||
|
||||
},
|
||||
onClose: function () {
|
||||
|
||||
// TODO reset form completely
|
||||
// TODO only close jBox with close button, not on overlay click
|
||||
|
||||
// Remove error tooltips
|
||||
// TODO Better to reset the form, this loop is also in showContent
|
||||
$.each(jBoxLogin.textfieldTooltips, function (id, tt) {
|
||||
$('#' + id).data('jBoxTextfieldError') && $('#' + id).data('jBoxTextfieldError').close();
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue