Skip to content

Instantly share code, notes, and snippets.

@victorluissantos
Created June 10, 2014 19:17
Show Gist options
  • Save victorluissantos/03bd635fdbc46cebcab0 to your computer and use it in GitHub Desktop.
Save victorluissantos/03bd635fdbc46cebcab0 to your computer and use it in GitHub Desktop.
Media Manager Suported IE8
(function($, window, undefined){
function bytesToSize(bytes){
var sizes = ['Bytes', 'KB', 'MB'];
if (bytes == 0) return 'n/a';
var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
return (bytes / Math.pow(1024, i)).toFixed(1) + ' ' + sizes[i];
}
var bind = function (func, thisValue) {
return function () {
return func.apply(thisValue, arguments);
}
}
/*
* Parametros:
* data-multiple: true ou false - Habilita/desabilita seleção de vários arquivos
* data-name: string - Atributo name dos campos com o id da imagem
* data-files: string - Ids dos arquivos que serão selecionados por padrão, seperados por virgula
* data-text: string - Texto a ser exibido no botão
*
* @todo: multiplo upload
* @todo: criação de pastas
* @todo: aplicar jquery ui selectable no modal
* @todo: diminuir a quantidade de requisições
* @todo: ordenar as imagens na lista(modal)
*/
var mediaManagerDefaults = {
options: {
/* habilita a seleção e upload de vários arquivos */
multiple: false,
/* nome do input file */
name: 'media_id[]',
/* evento ao abrir modal */
onOpen: undefined,
/* evento ao fechar modal */
onClose: undefined,
/* evento ao selecionar imagem */
onChange: undefined,
/* texto do botão */
text: ''
},
/* templates */
tmpl: {
button: '<button class="btn"><i class="icon-picture"></i> %text%</button>',
listWrapper: '<div class="list-images"></div>',
image: '<div class="image ui-state-default" data-id="%id%">\
<div class="btn-toolbar">\
<div class="btn-group">\
<div class="btn btn-danger btn-mini btn-delete"><i class="icon-remove"></i></div>\
</div>\
</div>\
<img src="%src%" alt="%alt%" title="%title%" />\
<p>%description%</p>\
<input type="hidden" name="%name%" value="%id%" />\
</div>',
modalImage: '<li rel="tooltip" data-toggle="tooltip" data-placement="bottom" title="%title%" data-id="%id%">\
<div class="btn-cheched">\
<button class="btn btn-mini">\
<i class="icon icon-ok"></i>\
</button>\
</div>\
<div class="btn-toolbar">\
<div class="btn-group">\
<div class="btn btn-danger btn-mini btn-delete"><i class="icon-remove"></i></div>\
</div>\
</div>\
<div title="%title%">\
<img src="%src%" alt="%alt%" title="%title%" data-id="%id%" title="%title%" />\
</div>\
<p title="%title%">%name%</p>\
</li>',
modal: '<div class="media-manager-modal">\
<div class="modal-header">\
<button type="button" class="close btn-fechar" data-dismiss="modal" aria-hidden="true">&times;</button>\
<h3>Inserir mídia </h3>\
</div>\
<div class="modal-body">\
<div class="modal-loader"></div>\
<ul class="thumbnails"></ul>\
</div>\
<div class="modal-footer">\
<div class="input-upload-file float-left">\
<form id="upload_form" action="" method="post" enctype="multipart/form-data">\
<label class="btn">\
<i class="icon-upload"></i> Fazer upload\
<input type="file" name="file[]" />\
</label>\
</form>\
</div>\
<div class="float-right">\
<a href="#" class="btn btn-fechar">Cancelar</a>\
<a href="#" class="btn btn-primary btn-inserir">Inserir</a>\
</div>\
<div class="message-area">\
</div>\
</div>\
<div id="modal_legenda" class="modal fade">\
<div class="modal-dialog">\
<div class="modal-content">\
<div class="modal-header">\
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>\
<h4 class="modal-title">Alterar legenda da foto</h4>\
</div>\
',
Iframemodal: '<div class="media-manager-modal">\
<div class="modal-header">\
<button type="button" class="close btn-fechar" data-dismiss="modal" aria-hidden="true">&times;</button>\
<h3>Inserir mídia (Navegador sem suporte upload ajax) </h3>\
</div>\
<div class="modal-body">\
<div class="modal-loader"></div>\
<ul class="thumbnails"></ul>\
</div>\
<div class="modal-footer">\
<div class="input-upload-file float-left">\
<form id="upload_form" target="iframe_upload" action="painel/medias/upload/" method="post" enctype="multipart/form-data">\
<label class="btn">\
<i class="icon-upload"></i> Fazer upload\
<input type="file" id="file" name="file[]" />\
</label>\
</form>\
<iframe id="iframe_upload" name="iframe_upload" width="0" height="0" style="display:none;"></iframe>\
</div>\
<div class="float-right">\
<a href="#" class="btn btn-fechar">Cancelar</a>\
<a href="#" class="btn btn-primary btn-inserir">Inserir</a>\
</div>\
<div class="message-area">\
</div>\
</div>\
</div>\
'
}
};
function MediaManager(element, options){
window.ie_handler = this;
this.options = $.extend({}, mediaManagerDefaults.options, options);
this.$wrapper = $(element);
this.options.multiple = this.$wrapper.data('multiple') || this.options.multiple;
this.options.name = this.$wrapper.data('name') || this.options.name;
this.options.text = this.$wrapper.data('text') || this.options.text;
this.prepareButton();
this.events();
}
MediaManager.prototype = {
prepareButton: function(){
this.$button = $(mediaManagerDefaults.tmpl.button.replace('%text%', this.options.text));
this.$wrapper.html('').append(this.$button);
this.$list = $(mediaManagerDefaults.tmpl.listWrapper);
this.$list.sortable();
this.$list.disableSelection();
this.selectedImages = new String(this.$wrapper.data('files')).split(',') || [];
this.media.insertImages.call(this);
this.$wrapper.append(this.$list);
},
events: function(){
/* abre o modal */
this.$button.click(bind(this.modal.open, this));
},
upload: {
start: function(){
var $input = this.$modal.find('input[type="file"]');
if(manager.options.multiple){
$input.attr('multiple', true);
}
var _this = this;
$input.change(bind(function(){
if(window.FormData == undefined){
/*ALTERNATIVA PARA SUPORTE IE9 */
$('#upload_form').submit();
$('#iframe_upload').load(function(){
var response_ie = ($('#iframe_upload').contents().text());
var x = {target:{
responseText:response_ie
}};
manager.upload.finish(x);
});
}else{
/* PARA NAVEGADORES 'NORMAIS' UPLOAD C/ DATAFORM */
if(!$input[0].files.length){
return;
}
this.$modal.find('.message-area').html('<div class="progress progress-striped active"><div class="bar" style="width: 0;"></div></div>');
var vFD = new FormData(document.getElementById('upload_form'));
// create XMLHttpRequest object, adding few event listeners, and POSTing our data
var oXHR = new XMLHttpRequest();
oXHR.upload.addEventListener('progress', bind(this.upload.progress, this), false);
oXHR.addEventListener('load', bind(this.upload.finish, this), false);
oXHR.addEventListener('error', bind(this.upload.fail, this), false);
oXHR.addEventListener('abort', bind(this.upload.fail, this), false);
oXHR.open('POST', 'painel/medias/upload');
oXHR.send(vFD);
}
}, this));
},
progress: function(e){
if(e.lengthComputable){
iBytesUploaded = e.loaded;
iBytesTotal = e.total;
var iPercentComplete = Math.round(e.loaded * 100 / e.total);
var iBytesTransfered = bytesToSize(iBytesUploaded);
$('.media-manager-modal').find('.progress .bar').stop().animate({width:iPercentComplete.toString() + '%'});
}
},
finish: function(e){
var response = JSON.parse(e.target.responseText);
/* verifica se foi feito o upload (200 == sim) */
if(response.status == 200){
/* deseleciona qualquer imagem que tenha sido selecionada */
ie_handler = this;
/* adiciona a imagem upada à lista */
$('.media-manager-modal').remove();
manager.modal.open();
/* adicionar mensagem de sucesso */
$('.media-manager-modal').find('.message-area').html('<div class="alert alert-success">\
<button type="button" class="close" data-dismiss="alert">&times;</button>\
Arquivo adicionado com sucesso\
</div>');
/* remove a mensagem de sucesso */
window.setTimeout(bind(function(){
$('.media-manager-modal').find('.message-area .alert').fadeOut(function(){
$(this).remove();
});
}, this), 2500);
}else{
/* caso tenha dado erro, exibe a mensagem */
$('.media-manager-modal').find('.message-area').html('<div class="alert alert-error">\
<button type="button" class="close" data-dismiss="alert">&times;</button>'+response.data.error+'</div>');
}
},
fail: function(e){
$('.media-manager-modal').find('.message-area').html('<div class="alert alert-error">\
<button type="button" class="close" data-dismiss="alert">&times;</button>\
Erro ao fazer upload\
</div>');
}
},
media: {
inArray: function(id, images){
if(!images.length){
return false;
}
var i = 0,
len = images.length;
for( ; i < len; i++){
if(images[i] == id){
return true;
}
}
return false;
},
/* cria a imagem */
create: function(options, prepend, active){
if(!manager.options.multiple){
$('.media-manager-modal').find('ul.thumbnails li.active').removeClass('active');
this.selectedImages = [];
}
var image = mediaManagerDefaults.tmpl.modalImage
.replace(/\%id\%/ig, options.id || '')
.replace(/\%src\%/ig, options.path+'/mini_thumb/'+options.name || '')
.replace(/\%name\%/ig, options.name || '')
.replace(/\%title\%/ig, options.title || '')
.replace(/\%alt\%/ig, options.alt || '')
.replace(/\%description\%/ig, options.description || options.title || '');
var $image = $(image);
if(active){
manager.selectedImages.push(options.id);
}
if(manager.media.inArray(manager.options.id, manager.selectedImages)){
$image.addClass('active');
}
this.$image = $image;
manager.media.append.call(this, $image, prepend);
},
/* insere a imagem na lista */
append: function(image, prepend){
var $this = this;
//image.click(bind(bind(manager.media.click, this), image));
//this.selectedImages.push(image.data('id'));
$(image).on( "click", function() {
if(image.hasClass('active')){
manager.media.unselect.call($this, image.data('id'));
//this.media.unselect.call(this, $image.data('id'));
image.removeClass('active');
}else{
$this.selectedImages.push(image.data('id'));
image.addClass('active');
}
return false;
});
image.dblclick(bind(function(){
this.$modal.find('li.active').removeClass('active');
image.addClass('active');
this.modal.insert.call(this);
}, this));
image.find('.btn-delete').click(function(){
image.fadeOut(function(){
image.remove();
});
$.ajax({
type: 'POST',
dataType: 'json',
url: 'painel/medias/delete',
data:{id:image.find('img').data('id')},
success: function(response){
if(response.status == 200){
}
}
})
});
//ALTERAR LEGENDA
image.find('.btn-edit-legenda').click(function(){
var id_legenda = $(this).attr("data-id");
var legenda_txt = $(this).attr('data-legenda');
var alt_txt = $(this).attr('data-alt');
var $this = $(this);
$('input:hidden[name="id_legenda"]').val(id_legenda);
$('input:text[name="legenda"]').val(legenda_txt);
$('input:text[name="alt"]').val(alt_txt);
$('#modal_legenda').modal('show');
$('.btn_save_lote').click(function(event) {
event.preventDefault();
$.ajax({
type: "POST",
dataType: "json",
url: "painel/medias/salva_legenda",
data: $('#form_legenda').serialize(),
success: function(response){
$('[data-id="'+ response.id +'"]').parent().parent().parent('li').attr('data-original-title', response.legenda);
$('[data-id="'+ response.id +'"]').attr('data-legenda', response.legenda);
$('[data-id="'+ response.id +'"]').attr('data-alt', response.alt);
$('#modal_legenda').modal('hide');
}
});
});
/**
Submit Legenda
**/
$('#form_legenda').validate({
rules: {
legenda: { required: true},
alt: { required: true}
}
});
});
//console.log(manager.media.append.$modal);
if(!prepend){
$('.media-manager-modal').find('.thumbnails').append(image);
}else{
$('.media-manager-modal').find('.thumbnails').prepend(image);
}
},
/* seleciona ou deseleciona imagem */
click: function($image){
if(this.options.multiple){
if($image.hasClass('active')){
this.media.unselect.call(this, $image.data('id'));
$image.removeClass('active');
}else{
this.selectedImages.push($image.data('id'));
$image.addClass('active');
}
}else{
$image.parent().children('.active').removeClass('active');
$image.addClass('active');
this.selectedImages = [$image.data('id')];
}
return false;
},
/* insere as imagens selecionadas */
insertImages: function(){
this.$list.html('');
var images = this.options.multiple ? this.selectedImages : [this.selectedImages[0]];
if(!images.length){
return;
}
var $container = [];
for(i = 0, len = images.length; i < len; i++){
$container[images[i]] = $('<div />');
this.$list.append($container[images[i]]);
$.ajax({
url: 'painel/medias/file',
data: {id:images[i]},
type: 'POST',
dataType: 'json',
success: bind(function(response){
if(response.status == 200 && response.data.id){
var html = mediaManagerDefaults.tmpl.image
.replace(/\%id\%/ig, response.data.id)
.replace(/\%name\%/ig, this.options.name)
.replace(/\%src\%/ig, response.data.path+'/mini_thumb/'+response.data.name)
.replace(/\%title\%/ig, response.data.title)
.replace(/\%alt\%/ig, response.data.alt)
.replace(/\%description\%/ig, response.data.name);
var $image = $(html);
$image.find('.btn-delete').click(bind(function(){
$image.fadeOut(bind(function(){
this.media.unselect.call(this, $image.data('id'));
$image.remove();
}, this));
return false;
}, this));
$image.insertAfter($container[response.data.id]);
$container[response.data.id].remove();
this.$list.append($image);
var page = document.getElementsByTagName('body')[0].id,
aux = page.split('_');
if(page == 'mapeamento'){
/*
Definição da imagem no mapeamento
*/
//Captura o segmento da url
var newURL = window.location.protocol + "://" + window.location.host + "/" + window.location.pathname;
//alert(newURL);
var pathArray = window.location.pathname.split( '/' );
var loteamento_id = pathArray[pathArray.length-1];
//Salva a media no loteamento
$.ajax({
url: 'painel/medias/imagem_lote',
data: {id:response.data.id,loteamento_id:loteamento_id},
type: 'POST',
dataType: 'json',
success: function(e){
var path_img = 'upload/media/loteamentos/'+response.data.name;
$("#map_img").attr("src", path_img);
$('.well .ui-state-default').css('display','none');
}
});
/*
Fim da inserção de imagem no mapeamento
*/
}
}
}, this)
});
}
},
unselect: function(id){
var index = -1;
for(i = 0, len = this.selectedImages.length; i < len; i++){
if(this.selectedImages[i] == id){
index = i;
break;
}
}
if(index > -1){
this.selectedImages.splice(index, 1);
}
}
},
modal: {
insert: function(){
this.media.insertImages.call(this);
this.modal.close.call(this);
return false;
},
/* fecha modal */
close: function(){
if(this.$modal){
this.$modal.fadeOut(bind(function(){
this.$modal.remove();
if(manager.options.onClose){
bind(this.options.onClose, (window));
}
}, this));
}
return false;
},
carregaThumbs: function(limitStart){
if(!limitStart){
limitStart = 0;
}
this.$modal.addClass('loading');
$.ajax({
type: 'POST',
data: {limitStart:window.mediasLimitStart},
url: 'painel/medias',
dataType: 'json',
success: bind(function(response){
if(response.status == 200){
$.loader.main.hide();
this.$modal.removeClass('loading').find('.modal-body ul').data('loading', false);
if(window.lastLimitStart < window.mediasLimitStart){
for(i = 0, len = response.data.files.length; i < len; i++){
manager.media.create.call(this, response.data.files[i]);
}
}
window.lastLimitStart = window.mediasLimitStart;
if(response.next && response.next.limitStart){
window.mediasLimitStart = response.next.limitStart;
//this.modal.carregaThumbs.call(this);
}
}
}, this)
});
},
/* abre modal */
open: function(){
window.modalOpen = this;
$.loader.main.show();
if(window.FormData != undefined){
this.$modal = $(mediaManagerDefaults.tmpl.modal);
manager.upload.start.call(this);
}else{
//ALTERNATIVA PARA SUPORTE IE9
this.$modal = $(mediaManagerDefaults.tmpl.Iframemodal);
manager.upload.start.call(this);
//this.upload.start.call(this);
}
/* exibe o modal */
this.$modal.appendTo('body').hide().fadeIn(bind(function(){
if(manager.options.onOpen){
bind(manager.options.onOpen, this.$modal);
}
}, this));
/* redimensiona para ocupar a tela toda */
var $body = this.$modal.find('.modal-body');
var $header = this.$modal.find('.modal-header');
var $footer = this.$modal.find('.modal-footer');
$body.height(this.$modal.outerHeight(true) - $header.outerHeight(true) - $footer.outerHeight(true) - 32);
$(window).resize(bind(function(){
$body.height(this.$modal.outerHeight(true) - $header.outerHeight(true) - $footer.outerHeight(true) - 32);
}, this));
window.mediasLimitStart = 0;
window.lastLimitStart = -1;
/* carrega os arquivos */
manager.modal.carregaThumbs.call(this);
var obj = this;
$body.scroll(function(){
if($body.find('ul').height() - ($(this).scrollTop() + 300) <= $body.height() && $body.find('ul').data('loading') !== true){
$body.find('ul').data('loading', true);
obj.modal.carregaThumbs.call(obj);
}
});
$('body').tooltip({
selector: '[rel=tooltip]'
});
/* seleciona imagem e fecha modal */
this.$modal.find('.btn-inserir').click(bind(manager.modal.insert, this));
/* fecha o modal */
this.$modal.find('.btn-fechar').click(bind(manager.modal.close, this));
/* faz o upload */
return false;
}
}
}
$.fn.mediaManager = function(){
$(this).each(function(){
manager = new MediaManager(this);
});
};
})(jQuery, window);
<fieldset>
<?php
foreach ($conteudos as $key => $c):
switch ($c->tipo) {
case 'media-single':
echo '<div class="control-group">
<label class="control-label" for="' . $c->identifier . '">' . $c->nome . '</label>
<div class="controls">
<div class="input-image-selection">
<div class="media-selection" data-multiple="false" data-name="pt[' . $c->identifier . ']" data-files="' . $c->valor . '" data-text="Selecionar Arquivo"></div>
</div>
<span class="help-block"></span>
</div>
</div>';
break;
case 'media-multiple':
$fotos = json_decode($c->valor);
$csv = '';
foreach ($fotos as $foto) {
$csv .= $foto . ",";
}
echo '<div class="control-group">
<label class="control-label" for="' . $c->identifier . '">' . $c->nome . '</label>
<div class="controls">
<div class="input-image-selection">
<div class="media-selection" data-multiple="true" data-name="media_' . $c->identifier . '[]" data-files="' . $csv . '" data-text="Selecionar Arquivo"></div>
</div>
<span class="help-block"></span>
</div>
</div>';
break;
}
endforeach
?>
</fieldset>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment