Skip to content

Instantly share code, notes, and snippets.

@klauskpm
Created December 9, 2015 18:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save klauskpm/f39f6bea2df4ef5459f4 to your computer and use it in GitHub Desktop.
Save klauskpm/f39f6bea2df4ef5459f4 to your computer and use it in GitHub Desktop.
Cria notificações simples para enviar ao seu usuário. Dependências: jQuery
.notificacao {
width: 100%;
min-height: 20px;
position: fixed;
top: -1000px;
left: 0;
z-index: 250;
min-width: 250px;
}
.notificacao .mensagem,
.notificacao .pergunta {
width: 100%;
min-height: 20px;
min-width: 250px;
text-align: center;
padding: 20px;
box-sizing: border-box;
}
.notificacao .pergunta {
background: #0095C7;
color: white;
}
.notificacao .conteudo {
font-size: 24px;
}
.notificacao .mensagem.informacao {
background: #0095C7;
color: white;
}
.notificacao .mensagem.alerta {
background: #FDC939;
color: white;
}
.notificacao .mensagem.erro {
background: #DA0000;
color: white;
}
.notificacao .mensagem.sucesso {
background: #669E00;
color: white;
}
.notificacao .notificacao-x {
position: absolute;
top: 0;
right: 0;
height: 45px;
width: 45px;
text-align: center;
line-height: 45px;
cursor: pointer;
background: url("/images/notificacao-x.png") 50% no-repeat;
}
.overlay-notificacao {
position: fixed;
background: rgba(255,255,255,0.5);
opacity: 0;
top: 0;
left: 0;
bottom: 0;
right: 0;
z-index: 150;
}
.notificacao .respostas-notificacao {
width: 100%;
}
.notificacao .notificacao-sim,
.notificacao .notificacao-nao{
width: 50%;
height: 50px;
text-align: center;
font-size: 24px;
display: block;
float: left;
cursor: pointer;
line-height: 50px;
}
.notificacao .notificacao-sim {
background: #669E00;
color: white;
}
.notificacao .notificacao-nao {
background: #DA0000;
color: white;
}
.notificacao .input-notificacao {
width: 100%;
height: 50px;
padding: 10px;
box-sizing: border-box;
border: none;
font-size: 24px;
text-align: center;
margin: 0;
line-height: 50px;
}
/**
* Created by klaus.machado on 08/12/2015.
*/
function Notificacao() {
var self = this;
var tiposMensagens = {};
var duracaoAnimacao = 1000;
var $templateNotificacao = $('<div class="notificacao"></div>');
var $templateMensagem = $('<div>' +
'<div class="fechar-notificacao notificacao-x"></div>' +
'<span class="conteudo"></span>' +
'</div>');
var $elementoAlvo = $('body');
/**
* Enum para os tipos de mensagens
* @enum {number}
*/
tiposMensagens.constantes = {
INFORMACAO: 0,
SUCESSO: 1,
ERRO: 2,
ALERTA: 3
};
/**
* Lista todos os tipos de mensagens
* @type {Array<string>}
*/
tiposMensagens.valores = [
'informacao',
'sucesso',
'erro',
'alerta'
];
function temNotificacaoAberta() {
if ($('.notificacao').length) {
console.warn('Já existe uma notificação aberta.');
return true;
}
return false;
}
/**
* Cria uma mensagen com apenas texto
*
* @param {number} tipoMensagem Tipo da mensagem para estilo de exibição
* @param {string} conteudo Conteudo da mensagem, também pode ter HTML
* @param {number=} duracao Duração do tempo de exibição da mensagem
* ou deixe como 0 para não sumir com o tempo (optional)
* @param {boolean=} overlay Se for true, exibirá um overlay (optional)
*/
function abrirMensagem(tipoMensagem, conteudo, duracao, overlay) {
// Verifica se já existe uma notificação aberta
// Se não tiver, pode criar uma nova
if (temNotificacaoAberta()) {
return;
}
var tipo = getTipoMensagem(tipoMensagem);
// Se não tiver duração, a mensagem ficará aberta até alguma
// ação de fechar manual
if (duracao) {
// Tempo de duração que a mensagem deve ficar aberta em segundos
setTimeout(fecharNotificacao, duracao * 1000 + duracaoAnimacao);
}
$notificacao = gerarTemplateNotificacao(['mensagem', tipo], conteudo);
$elementoAlvo.append($notificacao);
if (overlay) {
$elementoAlvo.append('<div class="overlay-notificacao fechar-notificacao"></div>');
}
animacaoAbrir();
}
/**
* Cria uma mensagen com dois botões de resposta
*
* @param {string} conteudo Conteudo da mensagem, também pode ter HTML
* @param {string=} conteudoSim Conteudo do primeiro botão, também pode ter HTML (optional)
* @param {string=} conteudoNao Conteudo do segundo botão, também pode ter HTML (optional)
* @param {string=} callbackSim Função de resposta ao clicar no primeiro botão (optional)
* @param {string=} callbackNao Função de resposta ao clicar no segundo botão (optional)
*/
function abrirPergunta(conteudo, conteudoSim, conteudoNao, callbackSim, callbackNao) {
// Verifica se já existe uma notificação aberta
// Se não tiver, pode criar uma nova
if (temNotificacaoAberta()) {
return;
}
$respostas = gerarTemplateResposta(conteudoSim, conteudoNao, callbackSim, callbackNao);
$notificacao = gerarTemplateNotificacao('pergunta', conteudo, $respostas);
$elementoAlvo
.append(
$notificacao,
'<div class="overlay-notificacao fechar-notificacao"></div>'
);
animacaoAbrir();
}
/**
* Cria uma mensagem com um formulário de um campo
*
* @param {string} conteudo Conteudo da mensagem, também pode ter HTML
* @param {string=} placeholder Conteudo a ser exibido no campo enquanto
* não tiver conteudo dentro (optional)
*/
function abrirFormulario(conteudo, placeholder) {
// Verifica se já existe uma notificação aberta
// Se não tiver, pode criar uma nova
if (temNotificacaoAberta()) {
return;
}
// Parte do template de formulário
placeholder = placeholder || 'Digite aqui';
$input = $('<input class="input-notificacao" type="text" name="retorno" placeholder="' + placeholder + '"/>');
$formulario = $('<div class="formulario-notificacao"></div>').append($input);
$input.keydown(function(event) {
if (event.keyCode == 13) {
var retorno = $('.input-notificacao').val();
enviarResposta(retorno);
}
});
// Parte do template com botões de respostas
$respostas = gerarTemplateResposta('Enviar', 'Cancelar', function() {
var retorno = $('.input-notificacao').val();
enviarResposta(retorno);
});
$notificacao = gerarTemplateNotificacao('pergunta', conteudo, [$formulario, $respostas]);
$elementoAlvo
.append(
$notificacao,
'<div class="overlay-notificacao fechar-notificacao"></div>'
);
animacaoAbrir();
}
/**
* Gera um objeto de jQuery com um template de notificacao
*
* @param {(array|string)} classes Classes de css para serem adicionadas
* ao elemento $mensagem
* @param {string} conteudo Conteudo para ser adicionado ao elemento
* $mensagem
* @param {(array|jQuery)=} $elements Elementos para serem inseridos
* na $notificacao (optional)
* @returns {jQuery}
*/
function gerarTemplateNotificacao(classes, conteudo, $elements) {
$notificacao = $templateNotificacao.clone();
$mensagem = $templateMensagem.clone();
$mensagem.find('.conteudo')
.html(conteudo);
if (typeof classes === 'object') {
classes.forEach(function(classe) {
$mensagem.addClass(classe);
});
} else if(classes) {
$mensagem.addClass(classes);
}
$notificacao.append($mensagem);
if ($elements) {
if ($elements.constructor == Array) {
$elements.forEach(function($element) {
$notificacao.append($element);
})
} else {
$notificacao.append($elements);
}
}
return $notificacao;
}
/**
* Gera um objeto de jQuery com um template de notificacao
*
* @param {string} conteudoSim Conteudo do primeiro botão, também aceita HTML
* @param {string} conteudoNao Conteudo do segundo botão, também aceita HTML
* @param {string=} callbackSim Resposta do primeiro botão (optional)
* @param {string=} callbackNao Resposta do segundo botão (optional)
* @returns {jQuery}
*/
function gerarTemplateResposta(conteudoSim, conteudoNao, callbackSim, callbackNao) {
$sim = $('<span class="notificacao-sim">' + conteudoSim + '</span>');
if (callbackSim) {
$sim.click(callbackSim);
}
$nao = $('<span class="notificacao-nao">' + conteudoNao + '</span>');
if (callbackNao) {
$nao.click(callbackNao);
}
$respostas = $('<div class="respostas-notificacao"></div>').append($sim, $nao);
return $respostas;
}
/**
* Retorna o tipo que a mensagem deve ter
* @param {number} tipo
* @returns {string}
*/
function getTipoMensagem(tipo) {
return tiposMensagens.valores[tipo];
}
/**
* Animação para exibir a mensagem
*/
function animacaoAbrir() {
$('.notificacao').animate({
top: 0
}, duracaoAnimacao);
if ($('.overlay-notificacao').length) {
$('.overlay-notificacao').animate({
opacity: 1
}, duracaoAnimacao);
}
}
/**
* Fecha a mensagem
*/
function fecharNotificacao(callback) {
callback = callback || false;
animacaoFechar(callback);
}
/**
* Animação para fechar a mensagem
*/
function animacaoFechar(callback) {
$('.notificacao').animate({
top: -1000
}, duracaoAnimacao - 1, function() {
$(this).remove();
if (callback.constructor == Function) {
callback();
}
});
if ($('.overlay-notificacao').length) {
$('.overlay-notificacao').animate({
opacity: 0
}, duracaoAnimacao - 1, function() {
$(this).remove();
});
}
}
/**
* Envia a resposta dada pelo usuário para o servidor
* @param {string} resposta Resposta da notificação
*/
function enviarResposta(resposta) {
var $mensagem = $('.notificacao').clone();
var $overlay = false;
if ($('.overlay-notificacao').length) {
$overlay = $('.overlay-notificacao').clone();
}
$.ajax({
url: '',
data: {
resposta: resposta
},
dataType: 'html',
type: 'POST',
success: function(data) {
console.log(data);
fecharNotificacao(function() {
self.sucesso("Resposta '" + resposta + "' foi enviada ", 1)
});
},
error: function() {
fecharNotificacao(function() {
self.erro('Ocorreu um erro ao enviar a resposta!<br/>Tente novamente.');
});
setTimeout(function() {
fecharNotificacao(function() {
reenviarNotificacao($mensagem, $overlay);
});
}, duracaoAnimacao + duracaoAnimacao + 1500);
}
});
}
/**
* Reabre uma notificação
*
* @param {jQuery} $notificacao Objeto jQuery de uma notificação
* @param {jQuery} $overlay Objeto jQuery de um overlay de notificação
*/
function reenviarNotificacao($notificacao, $overlay) {
$notificacao.css({
top: -1000
});
$elementoAlvo.append($notificacao, $overlay);
animacaoAbrir();
}
/**
* Cria uma mensagem do tipo alerta
*
* @param {string} conteudo Conteudo da mensagem, também pode ter HTML
* @param {number=} duracao Duração do tempo de exibição da mensagem
* ou deixe como 0 para não sumir com o tempo (optional)
* @param {boolean=} overlay Se for true, exibirá um overlay (optional)
*/
this.alerta = function(conteudo, duracao, overlay) {
abrirMensagem(tiposMensagens.constantes.ALERTA, conteudo, duracao, overlay);
};
/**
* Cria uma mensagem do tipo informacao
*
* @param {string} conteudo Conteudo da mensagem, também pode ter HTML
* @param {number=} duracao Duração do tempo de exibição da mensagem
* ou deixe como 0 para não sumir com o tempo (optional)
* @param {boolean=} overlay Se for true, exibirá um overlay (optional)
*/
this.informacao = function(conteudo, duracao, overlay) {
abrirMensagem(tiposMensagens.constantes.INFORMACAO, conteudo, duracao, overlay);
};
/**
* Cria uma mensagem do tipo erro
*
* @param {string} conteudo Conteudo da mensagem, também pode ter HTML
* @param {number=} duracao Duração do tempo de exibição da mensagem
* ou deixe como 0 para não sumir com o tempo (optional)
* @param {boolean=} overlay Se for true, exibirá um overlay (optional)
*/
this.erro = function(conteudo, duracao, overlay) {
abrirMensagem(tiposMensagens.constantes.ERRO, conteudo, duracao, overlay);
};
/**
* Cria uma mensagem do tipo sucesso
*
* @param {string} conteudo Conteudo da mensagem, também pode ter HTML
* @param {number=} duracao Duração do tempo de exibição da mensagem
* ou deixe como 0 para não sumir com o tempo (optional)
* @param {boolean=} overlay Se for true, exibirá um overlay (optional)
*/
this.sucesso = function(conteudo, duracao, overlay) {
abrirMensagem(tiposMensagens.constantes.SUCESSO, conteudo, duracao, overlay);
};
/**
* Cria uma mensagem de pergunta
*
* @param {string} pergunta Pergunta que o usuário deve responder
* @param {string=} conteudoSim Conteudo do primeiro botão (optional)
* @param {string=} conteudoNao Conteudo do segundo botão (optional)
*/
this.pergunta = function(pergunta, conteudoSim, conteudoNao) {
conteudoSim = conteudoSim || 'Sim';
conteudoNao = conteudoNao || 'Não';
abrirPergunta(pergunta, conteudoSim, conteudoNao, function() {
fecharNotificacao(function() {
self.sucesso('Clicou em ' + conteudoSim + '!', 1);
});
}, function() {
fecharNotificacao(function() {
self.erro('Clicou em ' + conteudoNao + '!', 1);
});
})
};
/**
* Cria uma mensagem de formulário
*
* @param {string} pergunta Pergunta que o usuário deve responder
* @param {string=} placeholder Conteudo que aparece no campo explicando
* o que o usuário deve digitar (optional)
*/
this.formulario = function(pergunta, placeholder) {
abrirFormulario(pergunta, placeholder);
};
// Comandos para fechar a mensagem
$(document)
.on('click', '.fechar-notificacao', fecharNotificacao)
.on('keydown', function(event) {
if (event.keyCode == 27 && $('.notificacao').length) {
fecharNotificacao();
}
});
}
var notificacao = new Notificacao();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment