jQuery topic - Szoftverfejlesztés fórum

üzenetek

hozzászólások


jeges
(senior tag)

nem biztos, hogy jól értem. mi lenne az elvárt működés? php küld levelet valami jq-s admin felületen történt gombnyomás hatására?


martonx
(veterán)

Te most valamiféle progress bar-t akarsz jquery-vel mutatni, ami jelzi a usernek, hogy mondjuk 3000-ből 45%-nál tart a feldolgozás?
Vagy miért kell a js-nek szinkronban lennie a php-vel? Az Ajax-nak a nevében is benne van, hogy aszinkron :N


Speeedfire
(nagyúr)
Blog

Az elvárt működés annyi lenne, hogy van pl 3000 email cím egy táblában. Admin felületen megírom a formban a levél törzsét majd rányomok a küldésre. Ekkor az ajax meghívja a kuld.php fájlt ami 50-esével elküldi a levelet. Lekérdez 50 email címet, megcsinálja, majd a következő 50-et és így tovább, amíg el nem fogynak az email címek.

Közben az admin felületen majd jelzi egy kis számláló, hogy a 3000-ból x van elküldve már. Ha 3000/3000 lesz a vége akkor meg szépen kiírja, hogy vége. :)

Azért van erre szükség, mert ha nagyon sok email cím van akkor a php egy idő után megakar időtúllépés miatt. Sok tárhelynél meg nincs cron se.


martonx: Lehet progress bar is, de az már csak hab lenne a tortán. :)
Azért akarom, hogy a js is tudja az i értékét, hogy amikor ismét meghívja az elkuld.php oldalt akkor már a paramban nem i=0 legyen hanem i+50 és így tovább. Szóval folyamatosan változna az i értéke. Agyaltam, hogy megoldani session-nel, de utána gondolkoztam, hogy valami más megoldás is biztos van erre. :K


jeges
(senior tag)

ezt úgy lehetne megoldani, hogy a php-kód minden csomag elküldése után küld egy jelet a kliensnek (ez a "jel" aztán megjelenik a kliens valami div-jében). a kliensen mondjuk másodpercenként lekérdezed, hogy mi van a php-kód kimenetén, és ha változás van, jelzed a felhasználó felé, ha meg nincs, akkor valami timeout (mondjuk 15 másodperc) után leállítod a programot.
setInterval() fv alkalmas kliens oldalon az ütemezett lekérdezésre

a kódok felépítése valahogy így nézne ki:

js:
1) szöveg küldése a php-nak, php-kód indítása - ez az ajax hívás
2) felület tiltás (modális ablak vagy fedőréteg)
3) ütemezett lekérdezés, mi van a php-kód kimeneti div-jében
4) a. ha a kimenet változik, elküldött levelek újraszámolása, frissítés a felhasználó felé
4) b. ha elértük a 3000-et (100%-ot), örülünk és leállítjuk a kódot
4) c. ha nem értük el a 100%-ot és timeouton túl nincs változás, leállítjuk a futást és megkérjük a júzert, hogy később próbálja újra vagy vegye fel a kapcsolatot a helpdesk-kel

php:
1) a js hívására a kapott szöveg alapján tömbönként elkezdjük kiküldeni a leveleket
2) minden elküldött tömböt tárolunk adattáblában, és minden elküldött tömb után küldünk jelet a kliensnek az elküldött levelek vagy tömbök számáról
3) a. ha végeztünk, leállunk (valami spec "vége" jel a kliensnek)
3) b. timeout - ez asszem automatikus szerver-oldalon (legalábbis php/apache esetében emlékeim szerint van valami automatizmus, ami leállítja a végtelen ciklusba került kódot), de őszintén megmondom, nem tudom most fejből.


martonx
(veterán)

mondjuk én adatbázis buzi vagyok, én beletenném egy táblába az email címeket, melléjük pedig egy oszlopban jelezném, hogy elküldtük-e.
A js csak annyit csinálna, hogy ajax-al meghívja a kuld.php-t, ami egyenként elkezdi küldeni a leveleket, egyúttal egy sessionbe beteszi a PHP, hogy éppen hol tart a küldéssel.

Az ajax hívás kezdetén pedig indítanék egy setinterval-t, ami mondjuk x másodpercenként lekérdezi a PHP által írt session-t, és megjeleníti a sessionben lévő darabszámot.

Így szépen fog látszódni, hogy hány darabnál tartasz, és erre a visszakapott darabszámra bármilyen jquery-s progressbar-t játszva rá lehet húzni.

Mondjuk mindez nem oldja meg a php timeout-ot. Ha valami rendesebb tárhelyed van (vagy van ráhatásod a php.ini-re), akkor azért a php-d akár több 10 percig is futhat.


Speeedfire
(nagyúr)
Blog

jeges & martonx: Na ez így elsőre még bonyolúltabb, mint gondoltam. Pénteken lesz rá időm, szerintem akkor jobban belevetem magam a dologba.
Csak az a kérdés, hogy hogyan csinálom azt, hogy a php visszaküld egy jelet egy adott divbe?
Az hittem egyszerűbb lesz, valami subrutinnal mindig meghívja majd magát az ajax függvény és a param értékét megváltoztatja. :)


jeges
(senior tag)

"hogyan csinálom azt, hogy a php visszaküld egy jelet egy adott divbe"

kliensen csinálsz egy átmeneti tároló div-et, és abba írod az eredményt a szerverről (semmi különösre nem kell gondolni, ahogy a $.load()-nak is megadsz egy "kimenet" elemet - jellemzően div -, úgy értem itt is.)
szerver-oldalon ez print vagy echo.


Speeedfire
(nagyúr)
Blog

Nos! Dolgozgattam az ajaxos levélküldésen, de nem kerek még.

index.php

<?php
session_start();

//email címek megszámlálása
$max = 20;
?>

<html>
<head>
<script type="text/javascript" src="js/jquery.js" ></script>
<script type="text/javascript" >

$(document).ready(function() {
var i = 1;
var max = <?php echo $max; ?>;
for (i; i<=max; i++) {
$.ajax({
type: "POST",
url: "kuld.php",
cache: false,
async: true,
data: "i="+i,
success: function(html){
$("#szamol").append(html);
}
});
if (i==max) {
$("#szamol").append('Kész!');
}
}
});

</script>
</head>
<body>

<h1>Hirlevel</h1>



<div id="szamol">
szamolas<br/>
</div>

</body>
</html>

kuld.php

<?php

$i = mysql_real_escape_string($_POST['i']);

//adatbázis lekérdezés
//.....

echo $i.'<br>';

//üzenet küldése
//....

?>

A kimeneten a kész szöveg előrébb van, mint a számok. Illetve az összes szám megjelenik a kimeneten, de nem jó sorrendben.
A lényeg annyi lenne, hogy inkább egyesével küldöm el a leveleket, az adatbázisban meg a limittel fogok játszani. limit $i, 1

Meglehet oldani, hogy a kész csak akkor jelenjen meg ha már elküldte az összes levelet? Illetve csak akkor növelje a js az i értékét ha a success-nak van visszatérési értéke? Jobban mondva van értéke. :))

[ Szerkesztve ]


Speeedfire
(nagyúr)
Blog

A js részt így próbáltam megcsinálni, de nem akar összejönni. Most egy egyet csinál meg, nem megy tovább a program...

$(document).ready(function() {
var i = 1;
var max = <?php echo $max; ?>;
for (i; i<=max; i++) {
var idofolyam = setInterval(ajaxkeres(i),5000);
}

function ajaxkeres(i) {
$.ajax({
type: "POST",
url: "kuld.php",
cache: false,
async: true,
data: "i="+i,
success: function(msg){
$(".szamol").replaceWith(msg);
}
});
if (i==max) {
$("#kesz").append('Kesz!');
clearInterval(idofolyam);

}
}

});


martonx
(veterán)

úgy gondolom, hogy kaptál jeges-től és tőlem is egy-egy konkrét megoldási javaslatot. Ezek alapján már megoldható a feladat.


Speeedfire
(nagyúr)
Blog

Közben sikerült megoldani teljesen.

$(document).ready(function() {
var i = 1;
var max = <?php echo $max; ?>;
ajaxkeres();

function ajaxkeres() {
$.ajax({
type: "POST",
url: "kuld.php",
data: "i="+i,
success: function(msg){
szam = msg;
$("#szamol").replaceWith("<span id='szamol'>"+szam+"</span>");
},
complete: function() {
if (i==max) {
$("#kesz").append('Kesz!');
}
i++;
ajaxkeres();
}
});
}
});


Speeedfire
(nagyúr)
Blog

A múltkor kódot kicsit modosítani akarom, de mindig elfut a kép, mert egy formot akarok postolni (hírlevél tárgya, szövegtörzse). Mi a megoldás erre?

$("#hirlevelformdiv form").submit(function() {
$("#hirlevelformdiv").hide("slow");
$(".hirleveladatok").show("slow");
ajaxkeres();
});

Ugye az lenne a lényeg, hogy amikor elküldöm az adatokat akkor a form eltűnik és helyette egy másik div "bukkan" fel amin mutatja, hogy mennyiből mennyi van hátra, illetve egy dinamikus progress bar is van, ami jelzik vizuálisan is.

A formnál az action-höz nincs írva semmi sem, szóval elvileg magát hívja meg a php. Ekkor kellene a .load() függvény?


Speeedfire
(nagyúr)
Blog

Még mindig a fenti hírlevéllel kapcsolatban lennének kérdéseim. :))

$(document).ready(function() {
var szoveg;
var targy;
var i = 1;
var max = <?php echo $max;?>;

$(".hirleveladatok").hide();

$("#hirlevelformdiv form").submit(function() {
var szoveg = $("#hirlevelformdiv input").val();
var targy = $("#hirlevelformdiv textarea").val();
$("#hirlevelformdiv").hide('slow');
$(".hirleveladatok").show('slow');
ajaxkeres();
return false;
});

function ajaxkeres() {
$.ajax({
type: "POST",
url: "kuld.php",
data: "i="+i+"&t="+targy+"&sz="+szoveg,
success: function(msg){
var szam = msg;
$("#szamol").replaceWith("<span id='szamol'>"+szam+"</span>");
$("#tolt").css("width",(100/max)*i+"%");
},
complete: function() {
if (i==max) {
$("#tolt").replaceWith("<p class='siker'>Kész!</p>");
}
else {
i++;
ajaxkeres();
}
}
});
}

});

Az ajaxkeres()-ben a szoveg és a targy részeknek nem adja át az értékeket, amikor a submit esemény van, pedig globálisan vannak megadva ezek. Mi a gond vele?

Illetve a szoveg egy tinymce-ből lenne kimerve, de nem tudom mert a tinymce teljesen átalakítja. Van erre valami megoldás?


jeges
(senior tag)

az elsőhöz egy kérdés: van minden input-nak érvényes 'name' tulajdonsága?


martonx
(veterán)

szerintem meg ez a változó deklarálás így nem globális. Illetve helyileg új változókat deklarálsz, és azoknak adsz értéket.

var szoveg = $("#hirlevelformdiv input").val();
var targy = $("#hirlevelformdiv textarea").val();

Helyesen:

szoveg = $("#hirlevelformdiv input").val();
targy = $("#hirlevelformdiv textarea").val();


Speeedfire
(nagyúr)
Blog

Igen.


martonx: Na ezt kipróbálom, ha hazaértem. :K


Speeedfire
(nagyúr)
Blog

Ez volt a jó megoldás. Nem kellett a var oda. :K

A másikra viszont nem tudok rájönni...

Itt próbálgattam őket, de nem akar egyik sem működni. Valamit nem jól csinálok... :W


martonx
(veterán)

Mi volt a másik?


Speeedfire
(nagyúr)
Blog

Illetve a szoveg egy tinymce-ből lenne kimerve, de nem tudom mert a tinymce teljesen átalakítja. Van erre valami megoldás?

Ezeket próbálgattam. [link]


martonx
(veterán)

ugyan nem próbáltam, de a tinymce is gondolom, hogy egy textarea fölé van húzva. Namost a textarea html-jét bármikor ki tudod olvasni jquery-vel. Nem kell ehhez semmi extra tinymce-s függvény.
Ez a módszer fckeditor-ral biztosan működik, nem hinném, hogy tinymce-vel ne működne.

üzenetek