Created
December 9, 2015 18:53
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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