Jag driver forumet Flygfyren (https://www.flygfyren.nu) och har byggt upp allt från grunden. Ett problem som har uppstått är dubbelpostningar som uppstår då och då i forumet. Anledningen till att dessa dubbelpostningar uppstår är att en användare upplever att det tar lång tid att posta tråden och därför trycker ytterligare en gång på "Skicka"-knappen för att skynda på det hela. Det enda det gör är att det skapas en till tråd.
En funktion som finns i forumet är den där en medlem kan välja att få e-postutskick när det har startats en ny tråd i forumet. Jag inser nu efter lite felsökande i koden att det är denna del som gör att postandet av trådar upplevs segt och som i sin tur skapar ovanstående beteende hos en del medlemmar.
Varje gång en tråd skapas och skrivs till databasen loopas en vektor igenom med e-postadress till de medlemmar som vill få information om detta skickat till sig. Denna loop tar längre och längre tid ju fler medlemmar som registrerar sig och som väljer att få dessa e-postmeddelanden.
Nu har jag temporärt inaktiverat funktionen så att det tidigare beskrivna problemet inte skall uppstå igen. Det blev en markant skillnad i hastiget när jag tog bort den. Dock upplever jag nu, när funktionen är borttagen, att tiden innan en medlem svarar på en ny tråd har gått ner markant. Det talar för att funktionen fyller en viktig funktion.
Hur kan jag skapa en funktion som via ett e-post meddelar när ny tråd har skapats i forumet och som inte påverkar tiden det tar för en medlem att posta en tråd?!
Jag skulle föreslå dig att skapa ett separat script för mailutskicken som du kör t.ex var 10:e minut (schemaläggning alt. cron job) som kollar vilka trådar som är uppdaterade senaste 10 minuterna och skickar mailen.
Tack för förslaget. Just nu håller jag på och förbereder för en migrering bort från den aktuella plattformen till vBulletin.
Går det inte att göra så att knappen blir "disabled" under tiden som tråden postas, så att användaren inte kan trycka på den en gång till? hur skulle det i så fall se ut rent kodmässigt sett?
Jag väcker liv i den här tråden igen. Som rubriken beskriver så har trådutskicket till medlemmar blivit slöare i takt med att antal prenumeranter har ökat. Av prestandaskäl blev jag tvungen att ta bort den temporärt på grund av att användare trodde att skicka-processen hade hängt sig och försökte på nytt och på nytt. Detta resulterade i att mailutskicket gick iväg i flera kopior till prenumeranterna.
Som denna tråd visar bollade jag lite idéer hur man kunde disabla skicka-knappen tills mailutskicket och hela den processen var klar. Fick det inte helt att fungera. Nu klistrar jag in den kod som är relevant igen så får jag se om jag tillsammans med någon kan komma fram till varför den inte gör någon skillnad. Ursprungligen anropade jag bara en javaskriptfunktion i <form>-taggen. Nu när skicka-knappen ska disablas krävs det ytterligare en funktion (förutom validateNewThread(obj)). Jag fick tipset att baka ihop dessa två till en. Det är detta som jag inte upplever fungerar. Jag får inte något skriptfel när sidan laddas men jag får heller ingen kvittens på att det fungerar.
Någon som ser vad som kan vara fel?! :)
Kod i newthread.php (innehåller formulär för att skriva inlägg):
<script language="JavaScript" src="../inc/function.js"></script>
<script type="text/javascript">
function sessionKeepAlive(){
var img = new Image();
img.src = "/noop.php?foo="+Math.random();
}
function scheduleSessionKeepAlive(){
var delay = 1000 * 60 * 1; // antal millisekunder att vänta innan anrop till noop.php, t.ex. 55 minuter
setInterval(sessionKeepAlive, delay);
}
scheduleSessionKeepAlive();
function disableForm(theform) {
if (document.all || document.getElementById) {
for (i = 0; i < theform.length; i++) {
var tempobj = theform.elements[i];
if (tempobj.type.toLowerCase() == "submit")
tempobj.disabled = true;
}
setTimeout('alert("Your form was submitted. Submit and reset buttons were disabled.")', 4000);
return true;
}
}
function fn_onSubmit(form)
{
return validateNewThread(form) && disableForm(form);
}
</script>
....
<form action="newthread.php" method="post" name="newthread" onsubmit="return fn_onSubmit(this);" id="postMsg">
....
<tr style="background-color: #fff;">
<td width="15%" style="padding-left: 5px; font-weight: bold;"> </td>
<td colspan="3" width="85%"><input name="createthread" type="submit" value="Skapa tråden" /> <input name="previewthread" type="submit" value="Förhandsgranskning" /></td>
</tr>
function.js (länkas in i newthread.php):
function validateNewThread(obj) {
var elms = obj.elements;
if(trim(elms["threadsubject"].value).length == 0) {
alert("Fyll i en rubrik!");
elms["threadsubject"].focus();
return false;
}
if(trim(elms["forummessage"].value).length == 0) {
alert("Skriv ett meddelande!");
elms["forummessage"].focus();
return false;
}
return true;
}
Har försökt att slå ihop valideringsfunktionen med den som ska disabla skicka-knappen. Dock får jag inte det resultat jag vill ha.
function validateNewThreadNew(obj) {
var elms = obj.elements;
if(trim(elms["threadsubject"].value).length == 0) {
alert("Fyll i en rubrik!");
elms["threadsubject"].focus();
return false;
}
if(trim(elms["forummessage"].value).length == 0) {
alert("Skriv ett meddelande!");
elms["forummessage"].focus();
return false;
}
if(trim(elms["forummessage"].value).length == 1 AND trim(elms["threadsubject"].value).length == 1)
{
for (i = 0; i < obj.length; i++)
{
var tempobj = obj.elements[i];
if (tempobj.type.toLowerCase() == "submit")
tempobj.disabled = true;
}
setTimeout('alert("Your form was submitted. Submit and reset buttons were disabled.")', 4000);
return true;
}
return true;
}
De två första if-satserna kontrollerar om rubrik och content är tomma eller ej. Är de tomma returneras ett false-värde. Den sista if-satsen är den som ska inaktivera skicka-knappen i formuläret. Som jag sa får jag det inte att fungera. Har säkert gjort en tankevurpa någonstans. Om både första if-satserna returnerar 1 (sant) så ska forumtråden kunna skickas iväg och då ska knappen inaktiveras.
Hur får jag till detta?
Så här ser anropet av ovanstående funktion ut i <form>-taggen i HTML-koden:
När jag kör ursprungsfunktionen ensamt så fungerar det som det är tänkt med att formulärknapparna inaktiveras.
Koden ser ut som följer:
function disableForm(theform) {
if (document.all || document.getElementById) {
for (i = 0; i < theform.length; i++) {
var tempobj = theform.elements[i];
if (tempobj.type.toLowerCase() == "submit" || tempobj.type.toLowerCase() == "reset")
{
tempobj.disabled = true;
}
setTimeout('alert("Your form was submitted. Submit and reset buttons were disabled.")', 2000);
return true;
}
}
Koden som jag vill integrera i samma funktion ser ut så här:
var elms = obj.elements;
if(trim(elms["threadsubject"].value).length == 0) {
alert("Fyll i en rubrik!");
elms["threadsubject"].focus();
return false;
}
if(trim(elms["forummessage"].value).length == 0) {
alert("Skriv ett meddelande!");
elms["forummessage"].focus();
return false;
}
Jag tror att det som ställer till det lite är att det är två retur-värden som ska tillbaka till webbläsaren, eller?
if(trim(elms["forummessage"].value).length == 1 AND trim(elms["threadsubject"].value).length == 1)
Det här ser underligt ut på flera sätt... Vill du verkligen bara köra formulärinaktiveringen om både rubriken och meddelandet är exakt ett tecken vardera? Och AND borde nog vara && om du verkligen vill ha med detta vilkor.
Men det känns som att den sista if-satsen inte borde vara med alls eftersom du redan innan kollat så att det skrivits något i de båda fälten... Du borde dessutom kunna använda dig av din elms-variabel i din sista for-sats eftersom den variabeln redan innehåller formulärelementen. Typ:
for (var i = 0; i < elms.length; i++)
{
var tempobj = elms[i];
if (tempobj.type && tempobj.type.toLowerCase() == "submit")
{
tempobj.disabled = true;
}
}
Den här sista koden respresenterar mitt dåliga ihopkok :)
Funktionerna jag vill ha är att formulärknapparna inaktiveras varje gång man trycker på dem för att minimera risken för dubbelposter. Därefter vill jag kontrollera så att båda formulärfälten är ifyllda.
Jag utgick ifrån din näst sista post (den som var näst sist när jag skrev förra gången alltså: post #8), för den posten såg trots allt ut att ligga närmast det du försöker göra.
Om du byter ut den sista if-satsen (som jag skrev var fel) och dess innehåll och klistrar in koden jag skrev i mitt förra inlägg bör den väl göra det du vill tycker jag...
if(trim(elms["forummessage"].value).length == 1 AND trim(elms["threadsubject"].value).length == 1)
Det här ser underligt ut på flera sätt... Vill du verkligen bara köra formulärinaktiveringen om både rubriken och meddelandet är exakt ett tecken vardera? Och AND borde nog vara && om du verkligen vill ha med detta vilkor.
Det var jag som läste koden dåligt. Jag tolkade värdet 1 som boolskt. Men .lengt talar faktiskt om antal tecken i strängen. Såg det nu.
Nu har jag gjort om koden. Då ser den ut så här:
function validateNewThreadNew(obj) {
var elms = obj.elements;
if(trim(elms["threadsubject"].value).length == 0) {
alert("Fyll i en rubrik!");
elms["threadsubject"].focus();
return false;
}
if(trim(elms["forummessage"].value).length == 0) {
alert("Skriv ett meddelande!");
elms["forummessage"].focus();
return false;
}
for (var i = 0; i < elms.length; i++)
{
var tempobj = elms[i];
if (tempobj.type && tempobj.type.toLowerCase() == "submit")
{
tempobj.disabled = true;
return true;
}
}
//setTimeout('alert("Your form was submitted. Submit and reset buttons were disabled.")', 4000);
}
Nu fungerar varken validerings- eller inaktiveringsfunktionen. I den sista if-satsen tog jag bort "return true". Skickar jag tillbaka det blir det väl fel om någon av valideringssatserna samtidigt skickar tillbaka ett false-värde?
Funktionen returnerar alltid bara ett värde. Om någon av valideringarna misslyckas returneras false, så inget efter return false-raden kommer att köras i det fallet.
Du bör se till att funktionen alltid returnerar ett värde. Jag är inte säker på att det spelar någon roll - egentligen borde nog formuläret postas så länge funktionen inte returnerar false - så det _borde_ inte vara det som är fel i det här fallet, men man vet aldrig...
I övrigt ser jag inget uppenbart fel i funktionen, ditt fel kan nog ligga var som helst... Du får posta mer (eller helst _all_) kod om det ska gå att hitta något.
Jag skrev ihop ett exempel lite snabbt, med utgång från koden ovan, och det fungerar för mig:
<!doctype html>
<html lang="sv">
<head>
<meta charset="utf-8">
<title>Testformulär</title>
<script>
function trim(str) { return str.replace(/^\s+|\s+$/g, ''); }
function validateNewThreadNew(obj) {
var elms = obj.elements;
if (trim(elms["threadsubject"].value).length == 0) {
alert("Fyll i en rubrik!");
elms["threadsubject"].focus();
return false;
}
if (trim(elms["forummessage"].value).length == 0) {
alert("Skriv ett meddelande!");
elms["forummessage"].focus();
return false;
}
for (var i = 0; i < elms.length; i++)
{
var tempobj = elms[i];
if (tempobj.type && tempobj.type.toLowerCase() == "submit")
{
tempobj.disabled = true;
alert("knapp inaktiverad...");
}
}
return true;
}
</script>
</head>
<body>
<form action="" method="post" onsubmit="return validateNewThreadNew(this);">
<fieldset>
<legend>Skriv forummeddelande</legend>
<label for="threadsubject">Rubrik</label><br>
<input type="text" id="threadsubject" name="threadsubject">
<br>
<label for="forummessage">Meddelande</label><br>
<textarea id="forummessage" name="forummessage" rows="10" cols="40"></textarea>
<br>
<input type="submit" value="Skicka">
</fieldset>
</form>
</body>
</html>
Nu har jag testat ditt exempel ovan och allting fungerar bra med validering och inaktivering av knappar tills det är dags för formulärinnehållet att processas i php-filen. När jag trycker på skicka-knappen kommer jag hela tiden tillbaka till sidan med formuläret och det innehåll som finns i formuläret.
Nja, när du trycker på Skicka kommer du till den sida som är angiven i action-attributet i form-taggen. Jag har inte angivit någon sida alls i mitt exempel, så därför hamnar man på samma sida igen... Du får skriva in rätt php-sida i action-attributet helt enkelt...
I mitt fall så är det samma sida som formuläret återfinns på. Jag kör med en testfil nu och där står det exakt lika som i den skarpa. Ska felsöka ytterligare och se om jag kan komma på vad det beror på.
Inte lätt att veta utan att se hur koden (även i php-filen) ser ut... Men en gissning är att submit-knappen har ett namn (name="...") och att du kollar efter detta namn i din php-fil innan du sparar något till databasen. När knappen inaktiveras kommer dess namn inte skickas med till php-filen, så då får man trixa till det på annat sätt...
Men en gissning är att submit-knappen har ett namn (name="...") och att du kollar efter detta namn i din php-fil innan du sparar något till databasen. När knappen inaktiveras kommer dess namn inte skickas med till php-filen, så då får man trixa till det på annat sätt...
Varför tänker inte jag på sånt där?! Tur att det finnas andra som har huvudet med sig :)
Din teori låter logisk. Jag har en if-sats som drar igång hela processen med att spara ner informationen till databasen. Jag kör på submit-knappens värde som är "Skapa tråd". Är knappen inte aktiverad så kommer väl aldrig namnet med, som du sa?
Vilken tror du är den enklaste work-arounden för detta? Finns det någon annan variabel som jag kan använda mig av om vi pratar generella programmeringstermer?
255 ms totalt · 4 externa anrop · v20260731065814-full.86ec41c2