Jquery + Ajax 1 űrlappal 2 esemény kezelés
2019-06-04T19:34:10+02:00
2019-06-11T19:30:10+02:00
2022-08-11T13:05:30+02:00
M-anos
Sziasztok.

Érdeklődnék, hogy egy űrlap segítségével megvalósítható e, hogy fájlokat töltsek fel, és űrlap adatokat mentsek adatbázisba. 2 űrlap segítségével hibátlanul meg tudtam oldani, de egy űrlappal szeretném, persze ha ez kivitelezhető. A képfeltöltést Jquery + Ajax párossal oldottam meg, a kép/képek betallózása után a feltöltés gombra kattintva egy átmeneti mappába feltöltöm a képeket és a képekről előnézeti kép jelenik meg a tallózás alatt. Illetve az űrlap beviteli mezőit úgyszintén Jquery+Ajax párossal mentem az adatbázisba.

Így próbálkoztam, egy űrlappal:
JS:

$(document).ready(function() { $(document).on('submit', '#update-form', function(event){ event.preventDefault(); $('.help-block').remove(); $('.form-group').removeClass('has-error'); $.ajax({ type : 'POST', url : 'insert.php', data : $('#update-form').serialize(), dataType : 'json', encode : true, cache : false }) .done(function(data) { if(data.rendben == false) { $.each(data.hiba, function(mezo,uzenet) { $("#"+mezo+"-box").closest('.form-group').addClass('has-error'); $("#"+mezo+"-box").append('<div class="help-block">' + uzenet + '</div>'); }); } else { $(".adatmsg").html(data.adatf); location.assign(data.url); } }) .fail(function(data) { console.log(data); }); }); fileselect(); $(document).on('click', '#uploadimg', function(event) { event.preventDefault(); var files_names = $('#files').val(); if (files_names == '') { $('#files_box').html('<div class="alert alert-danger"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button><strong>Nem választott képet.</strong></div>'); AlertBoxClose(); return false; } else { $.ajax({ url: "imgup.php", method: "POST", data: files_names, contentType: false, cache: false, processData: false, dataType: 'json', beforeSend:function(){ $('#files_box').html('<i class="fa fa-spinner fa-spin fa-2x fa-fw"></i> Feltöltés folyamatban... Kérjük várjon!<span class="sr-only">Feltöltés folyamatban...</span>'); }, success:function(data) { setTimeout(function(){ $('#files_box').html(data.msg); fileselect(); AlertBoxClose(); }, 3000); }, error:function(data) { $('#files_box').html('<div class="alert alert-danger"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button><strong>Sikertelen</strong> képfeltöltés. Próbálja meg újra.</div>'); } }); } }); });


Ez a megoldás sajnos nem működik. Esetleg valakinek valami ötlete lenne?
Mutasd a teljes hozzászólást!
$(document).ready(function() { var ajaxController = function(thatData, route) { let ajaxData = new FormData(); ajaxData.append(thatData); $.ajax({ url: route, type: "POST", data: ajaxData, contentType: false, processData: false, success: function(response) { alert(response); } }); }; $('#forms').on('submit', function() { return false; }); // Ez a rész elküldi az űrlap adatokat, beleértve a feltöltött fájlok adatait is $('#formsave').click(function(ev) { ev.preventDefault(); ajaxController($(this), "form_insert.php"); }); // Ez a rész csak a fájlok feltöltésére szolgál $('#fileupload').click(function(e) { e.preventDefault(); ajaxController($(this), "file_upload.php"); }); });

Nem teszteltem, ezért a $(this) rész kérdéses, máshogy oldanám meg, de a kódban ez volt, amire azt írtad, hogy neked ez így működik, so
Mutasd a teljes hozzászólást!

  • Szia,
    mit jelent az hogy nem működik? Elsőre, ami feltűnt, hogy ha fájlt, akarsz küldeni ajaxszal, akkor nem json lesz a datatype.  Itt találsz pár példakódot arra, amit szeretnél: Ajax Upload image
    Mutasd a teljes hozzászólást!
  • Akkor egy hiba megvan. Köszi.

    Pontosan azt értem alatta, ha külön-külön formmal kezelem a képfeltöltést és az adatok mentését, akkor minden működik rendesen. Ha a két funkciót egy <form></form> -ba szeretném megoldani, akkor a képfeltöltés már nem működik, mert nem kapja meg az értéket.
    Mutasd a teljes hozzászólást!
  • Nem kell feltöltened a képeket az előnézeti képhez, hozzáférhetsz a user inputolt fájlaihoz is, FileReader-rel, csak a küldés kicsit trükkös, viszont sokkal gyorsabb lesz az előnézeti képek betöltése, nem terheled a szervert feleslegesen és csak egyetlen ajax-ra lesz szükséged:

    (Ez egy egyszerű pattern az alapján, amit én használok, nincs időm rá, hogy teljesen a kérdésedre szabjam, de ez alapján megtudod csinálni magadnak...)

    $(document).ready( function() { var $Form = $("#your_form"); var $Container = $("#media_container"); var extensions = ['jpeg', 'jpg', 'png', 'webp', 'gif', 'bmp']; var PHOTOS = []; var simplePhotoPreview = function(input) { var files = input.files ? input.files : input; var filesCount = files.length; for(let i = 0; i < filesCount; i++) { var reader = new FileReader(); reader.onload = function(file) { var previewElem = '<div class="img_plan"><img src="' + file.target.result + '" /></div>'; $("#previews").append(previewElem); PHOTOS.push(file.target.fileName); } reader.fileName = files[i].name; reader.readAsDataURL(files[i]); } }; $Container.on("change", "input:file", function() { if($.inArray($(this).val().split(".").pop().toLowerCase(), extensions) === -1) { alert("Only image formats are allowed: " + extensions.join(", ")); } else { simplePhotoPreview(this); } }); $Form.on("click", "#send", function(ev) { ev.preventDefault(); var actionData = new FormData(); //PAKOLD BE A FormData()-ba az összes adatot, amit elakarsz küldeni, a képekkel //pl //var text = $("input#your_text").val() ? $("input#your_text").val() : null; //if(text !== null) actionData.append("text", text); //A KÉPEKET PEDIG ÍGY: if(PHOTOS.length > 0) $Form.find("input:file").each(function() { let file_data = $(this)[0].files; if(file_data.length > 0) for(let i = 0; i < file_data.length; ++i) actionData.append(file_data[i].name, file_data[i]); }); $.ajax({ url : 'insert.php', type : "POST", cache : false, contentType : false, processData : false, data : actionData, success : function() { alert("great!"); } }); }); });

    További előnye ennek, hogyha az előnézeti képekhez beszúrsz mondjuk egy spant, amire állítasz egy action-t, a user tudja törölni az előzőleg kiválasztott képeket... így szerkesztheti live-ban, hogy mit küld el végül, és mit nem (nem kell refreshelnie a formot, vagy ilyesmi)... ehhez én egy deletedPhotos tömböt használok, amibe begyűjtöm a form kitöltése közben törölt fájlok neveit, majd a két tömböt (deleted és sima PHOTOS) összevetem a fájlok FormData-ba appendelésekor.


    (Az én hozzászólásaimban miért nem tartja a tabokat a prog.hu? :/ amikor szerkesztem (akár utólag is, markup-ban és amúgy is tartja őket... hm))
    Mutasd a teljes hozzászólást!
  • jQuery Form Plugin
    Én ezt szoktam használni. Ez egy sima formot alakít át ajaxosra.
    Mutasd a teljes hozzászólást!
  • Szia, köszi, ezt ismerem, de saját kóddal szeretném megoldani.
    Mutasd a teljes hozzászólást!
  • Szia, ilyesmire gondolok igen. Én a következő képen építettem fel az űrlapomat.
    Az űrlapnak van egy fájlfeltöltő része és egy amivel adatokat lehet letárolni. A fájlfeltöltő ajax segítségével feltölti a fájlt/fájlokat egy átmeneti mappába, majd a fájl/fájlok nevét letárolom Sessionba (Ha valami oknál fogva oldalfrissítés történne akkor a sessionból mindig le tudom kérni az átmenetileg feltöltött adatokat). A kérdésem igazából arra irányulna, hogy egy form segítségével megoldható lenne e valamilyen eseménykezelővel, hogy ha betallózok egy fájlt és egy button gombra kattintok akkor lefutna a fájlfeltöltés JS része:

    $(document).on('click', '#uploadimg', function(event) { event.preventDefault(); var files_names = $('#files').val(); if (files_names == '') { $('#files_box').html('<div class="alert alert-danger"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button><strong>Nem választott képet.</strong></div>'); AlertBoxClose(); return false; } else { $.ajax({ url: "imgup.php", method: "POST", data: files_names, contentType: false, cache: false, processData: false, dataType: 'json', beforeSend:function(){ $('#files_box').html('<i class="fa fa-spinner fa-spin fa-2x fa-fw"></i> Feltöltés folyamatban... Kérjük várjon!<span class="sr-only">Feltöltés folyamatban...</span>'); }, success:function(data) { setTimeout(function(){ $('#files_box').html(data.msg); fileselect(); AlertBoxClose(); }, 3000); }, error:function(data) { $('#files_box').html('<div class="alert alert-danger"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button><strong>Sikertelen</strong> képfeltöltés. Próbálja meg újra.</div>'); } }); } });
    Ha pedig elküldöm a formot akkor pedig ennek a résznek kellene lefutnia:

    $(document).on('submit', '#update-form', function(event){ event.preventDefault(); $('.help-block').remove(); $('.form-group').removeClass('has-error'); $.ajax({ type : 'POST', url : 'insert.php', data : $('#update-form').serialize(), dataType : 'json', encode : true, cache : false }) .done(function(data) { if(data.rendben == false) { $.each(data.hiba, function(mezo,uzenet) { $("#"+mezo+"-box").closest('.form-group').addClass('has-error'); $("#"+mezo+"-box").append('<div class="help-block">' + uzenet + '</div>'); }); } else { $(".adatmsg").html(data.adatf); location.assign(data.url); } }) .fail(function(data) { console.log(data); }); });

    Én csak azt szeretném megvalósítani, hogy tudjam lefuttatni a fájlfeltöltést egy button gombbal és egy submittal pedig tudjam elküldeni az rögzítendő adatokat :) és mindezt egy form segítségével (viszont kát külön ajax rész futtatásával.)
    Mutasd a teljes hozzászólást!
  • Ha esetleg úgy is megfelel, hogy betallózás után automatikusan feltöltődjön => olvasd végig a következő leírás-t (demo is van és letölthető forráskód is).
    Mutasd a teljes hozzászólást!
  • FormData-t kell használnod és abba appendelni a fájlokat az inputból. Így tudod elküldeni őket ajaxal! Előző válaszomban ott van minden.
    Ezt próbáld ki (működni fog):

    $(document).on('click', '#uploadimg', function(event) { event.preventDefault(); var actionData = new FormData(); //Amennyiben a #files egy "input:file" elem!! Annak kell lennie var files = $('#files')[0].files; for(let i = 0; i < files.length; ++i) actionData.append(files[i].name, files[i]); $.ajax({ url : 'insert.php', type : "POST", cache : false, contentType : false, processData : false, data : actionData, success : function() { alert("great!"); } }); });

    php-ben $_FILES-al férsz hozzájuk.
    Mutasd a teljes hozzászólást!
  • Oké, ezzel fel tudom tölteni a képet/képeket. Eddig értem is. A fő kérdésem még mindig az lenne, hogy egy formban két művelet megoldása. Az egyik csak a fájlfeltöltésre vonatkozna a másik pedig az adatok küldésére az adatbázisba (ez a két dolog egymástól külön-külön ajax küldéssel történne).

    A form megjelenítése a következő lenne:

    <form method="post" id="forms" enctype="multipart/form-data"> <input type="text" name="elso_ertek" value=""> <input type="text" name="masodik_ertek" value=""> <input type="file" name="file" id="uploads"> <input type="submit" id="fileupload" value="Fájlfeltöltés"> <input type="submit" id="formsave" value="Űrlap mentése"> </form>

    A "Fájlfeltöltés" submittal a fájlt/fájlokat feltölteni.
    Az "Űrlap mentése" submittal pedig az ürlap adatok mentését (elso_ertek, masodik_ertek és a SESSION-ba mentett fájl adatok).

    Valahogy így gondoltam az összeállítását:

    $(document).ready(function() { $('#forms').on('submit', function() { return false; }); // Ez a rész elküldi az űrlap adatokat, beleértve a feltöltött fájlok adatait is $('#formsave').click(function() { $.ajax({ url: "form_insert.php", type: "POST", data: new FormData(this), contentType: false, processData: false, success: function(data) { alert(data); } }); }); // Ez a rész csak a fájlok feltöltésére szolgál $('#fileupload').click(function(e) { e.preventDefault(); $.ajax({ url: "file_upload.php", type: "POST", data: new FormData(this), contentType: false, processData: false, success: function(data) { alert(data); } }); }); });
    Mutasd a teljes hozzászólást!
  • $(document).ready(function() { var ajaxController = function(thatData, route) { let ajaxData = new FormData(); ajaxData.append(thatData); $.ajax({ url: route, type: "POST", data: ajaxData, contentType: false, processData: false, success: function(response) { alert(response); } }); }; $('#forms').on('submit', function() { return false; }); // Ez a rész elküldi az űrlap adatokat, beleértve a feltöltött fájlok adatait is $('#formsave').click(function(ev) { ev.preventDefault(); ajaxController($(this), "form_insert.php"); }); // Ez a rész csak a fájlok feltöltésére szolgál $('#fileupload').click(function(e) { e.preventDefault(); ajaxController($(this), "file_upload.php"); }); });

    Nem teszteltem, ezért a $(this) rész kérdéses, máshogy oldanám meg, de a kódban ez volt, amire azt írtad, hogy neked ez így működik, so
    Mutasd a teljes hozzászólást!
  • Szívesen fogadom az építő jellegű kritikákat, ha optimalizáltabb kódolással van jobb megoldás szerinted, akkor szívesen fogadom azt is igazából. De igen, ilyen megoldásra gondoltam amúgy.
    Mutasd a teljes hozzászólást!
  • Hát figyu, a $(this)-el mindkét submit-tal elküldöd a teljes form tartalmát, azokat is, amiket amúgy nem dolgozol fel a php-ben, vagyis a form_insert.php megkapja a fájlokat is, és fordítva. Plusz szerintem az sem jó ötlet, hogy több submit van. A FormData-ban az a jó, hogy bármit belepakolhatsz, szóval ha egyetlen submitod lenne (vagy egy random button, amivel meghívod az ajaxController-t), azzal eltudnád küldeni a text adatokat, amiket a form_insert.php fog feldolgozni, a file:input change event-en pedig meghívod a másik route-ot, így elég kiválasztania a képed a user-nek, az már megy is a szerverre, anélkül, hogy rákelle kattintania mégvalamire

    var extensions = ['jpeg', 'jpg', 'png', 'webp', 'gif', 'bmp']; var ajaxController = function(route) { let ajaxData = new FormData(); if (route === "form_insert.php") { ajaxData.append("elso_ertek", $("#elso_ertek").val()); ajaxData.append("masodik_ertek", $("#masodik_ertek").val()); } if (route === "file_upload.php") { ajaxData.append($('#uploads')[0].files); } $.ajax({ url: route, type: "POST", data: ajaxData, contentType: false, processData: false, success: function(response) { alert(response); } }); }; $('#formsave').click(function(ev) { ev.preventDefault(); ajaxController("form_insert.php"); }); $("#forms").on("change", "input:file", function(ev) { ev.preventDefault(); if($.inArray($(this).val().split(".").pop().toLowerCase(), extensions) === -1) { alert("Only image formats are allowed: " + extensions.join(", ")); } else { ajaxController("file_upload.php"); } });

    (Az extension teszt csak a béna userek miatt van, ellenőrizd a file kiterjesztést a szerver oldalon is, mert ha valaki szándékosan akar nem képet feltölteni, áttudja írni a js-edet a böngészőben)
    Mutasd a teljes hozzászólást!
  • Így már akkor értem ;) - Igen ez tényleg szebb és jobb megoldás. Nagyon köszönöm a segítséget.
    Mutasd a teljes hozzászólást!
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd