dziś postanowiłem spróbować swych sił w napisaniu pluginu jQuery. Jest to mój pierwszy plugin tak więc wszelkie uwagi mile widziane. Docelowo planuję dołożyć obsługę zdarzeń by móc dowolnie reagować na określone sytuacje.
Zadaniem pluginu jest upload plików graficznych z podglądem pliku po wgraniu. Całość działa na zasadzie wysyłania dynamicznie tworzonych formularzy do ramek pływających (oba elementy ukryte). Skrypt cyklicznie sprawdza zawartość ramki, w której pojawia się odpowiedź w postaci JSON. Odpowiedź błędna zawiera komunikat błędu, natomiast poprawna ścieżkę do wgranego zdjęcia.
Po wgraniu plików na serwer ich nazwy zawarte są w ukrytych polach o takich samych nazwach, jak nazwy pól typu file. Zatem po wysłaniu formularza (uzupełnionego np. o inne dane) otrzymujemy również ścieżki do wcześniej wgranych plików, dzięki czemu można je przenieść w konkretne miejsce.
Demo znajduje się tutaj:
http://notifero.pl/ntfrUploadPreview/
Kod pluginu:
/** * Plugin uploadu plików graficznych z podglądem. * * @author Michał "phpion" Płonka */ (function($){ var counter = 0; var methods = { init: function(options) { var settings = $.extend( { field: 'ntfrUploadPreview_file', // Nazwa pola z plikiem. preview: 'img/t.png', // Domyślny plik podglądu. uploader: 'ntfrUploadPreview_uploader.php', // Skrypt uploadu. timeout: 250 // Czas cyklicznego odczytywania zawartości ramki. }, options); return this.each(function() { var $this = $(this); // Ustalenie ID elementu. var id = $this.attr('id'); if (typeof id == 'undefined' || id == false) { id = 'ntfrUploadPreview_' + (++counter); $this.attr('id', id); } // // Utworzenie elementu podglądu. var preview = '<div id="' + id + '_preview" class="ntfrUploadPreview_preview">'; preview += '<img src="' + settings.preview + '" alt="' + settings.preview + '" id="' + id + '_uploader_preview" />'; preview += '<input type="hidden" name="' + $this.attr('name') + '" id="' + id + '_uploader_file" />'; preview += '</div>'; $(preview).insertAfter($this); // // Utworzenie elementów uploadera. var uploader = '<div id="' + id + '_uploader" class="ntfrUploadPreview_uploader">'; uploader += '<form action="' + settings.uploader + '" method="post" id="' + id + '_uploader_form" target="' + id + '_uploader_iframe" enctype="multipart/form-data">'; uploader += '<fieldset></fieldset>'; uploader += '</form>'; uploader += '<iframe src="" name="' + id + '_uploader_iframe" id="' + id + '_uploader_iframe"></iframe>'; uploader += '</div>'; $("body").append(uploader); // // Zmiana nazwy pola. $this.attr('name', settings.field); // // Przypisanie zdarzenia onchange. $this.change(function() { var $this = $(this); var id = $this.attr('id'); // Wyczyszczenie zawartości ramki. document.getElementById(id + '_uploader_iframe').contentWindow.document.body.innerHTML = ''; // // Utworzenie klona pola. var clone = $this.clone(); clone .val('') .attr('id', id + '_clone') .attr('disabled', 'disabled') ; clone.insertBefore('#' + id + '_preview'); // // Dodanie pola i wysłanie formularza do ramki. $('#' + id + '_uploader_form fieldset').append($this); $('#' + id + '_uploader_form').submit(); // // Odbieranie odpowiedzi jako zawartości ramki. catchUploadResponse = function() { var id = $this.attr('id'); var response = document.getElementById(id + '_uploader_iframe').contentWindow.document.body.innerHTML; if (response.length > 0) { response = $.parseJSON(response); if (response.status == 1) { // Aktualizacja podglądu wgranego zdjęcia. $('#' + id + '_uploader_preview') .attr('src', response.message) .attr('alt', response.message) ; // // Aktualizacja wartości pola z nazwą pliku. $('#' + id + '_uploader_file').val(response.message); // } else { alert(response.message); } // Przywrócenie pola do formy wyjściowej. $('#' + id + '_clone').remove(); $this.val(''); $this.insertBefore('#' + id + '_preview'); // } else { setTimeout('catchUploadResponse()', settings.timeout); } }; catchUploadResponse(); // }); }); } }; $.fn.ntfrUploadPreview = function(method) { if (methods[method]) { return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); } else if (typeof method === 'object' || !method) { return methods.init.apply(this, arguments); } else { $.error('Method ' + method + ' does not exist on jQuery.ntfrUploadPreview'); } }; })(jQuery);
Kod pliku uploadu:
<?php $file = 'ntfrUploadPreview_file'; // Nazwa pola z plikiem. 'status' => 0, 'message' => '' ); if (isset($_FILES[$file]) && is_array($_FILES[$file]) && array_key_exists('error', $_FILES[$file]) && $_FILES[$file]['error'] == UPLOAD_ERR_OK) { $path_abs = pathinfo(__FILE__, PATHINFO_DIRNAME).DIRECTORY_SEPARATOR.$path_rel; // Ścieżka absolutna. if (in_array(strtolower(pathinfo($_FILES[$file]['name'], PATHINFO_EXTENSION)), array('jpg', 'jpeg', 'png', 'gif'))) { 'status' => 1, 'message' => $path_rel ); } else { $response['message'] = 'Błąd podczas wgrywania pliku.'; } } else { $response['message'] = 'Wybrany plik powinien być plikiem typu *.jpg, *.png lub *.gif.'; } } else { $response['message'] = 'Brak pliku.'; }
Zapraszam do testowania i zgłaszania swoich uwag