[AJAX] refresh te vroeg?

Pagina: 1
Acties:

  • jsiegmund
  • Registratie: Januari 2002
  • Laatst online: 23:27
Ik heb een formulier dat met behulp van AJAX wordt verzonden wanneer de pagina verlaten wordt. Het volgende stukje code zorgt hiervoor:

code:
1
2
3
4
5
6
function unload () {
    if (veranderingen && !errors) {
        if (confirm("Wilt u de gemaakte wijzigingen opslaan?"))
            saveForm();
    }
} window.onunload = unload;


Werkt prima totdat je dezelfde pagina opnieuw aanroept. De pagina wordt dan verlaten, de vraag komt in beeld, je kiest voor "ja" en de veranderingen worden opgeslagen. Echter is de refresh zo snel (tijdens unload?) dat de oude gegevens weer ingevuld worden. Pas bij een nieuwe handmatige refresh komen de opgeslagen gegevens netjes naar voren.

Hoe kun je ervoor zorgen dat de pagina wacht met laden totdat alles afgehandelt is? Een soort van timer zou misschien een optie zijn, maar je kunt in dat geval moeilijk 100% zekerheid bieden dat de juiste gegevens verschijnen denk ik.

  • Wim Leers
  • Registratie: Januari 2004
  • Laatst online: 23:11
Kun je niet een bevesting laten versturen door je saveForm functie?

EDIT:
Of misschien nog gemakkelijker: de saveForm functie niet laten eindingen voordat het in die functie bevestigd is dat je form inderdaad gesaved is.

[ Voor 54% gewijzigd door Wim Leers op 06-11-2005 16:01 ]


  • jsiegmund
  • Registratie: Januari 2002
  • Laatst online: 23:27
Dat heb ik geprobeerd, maar ik heb het idee dat de "volgende" pagina al geladen wordt wanneer de vorige pagina nog in de unload functie zit. Beforeunload geeft dan wel een oplossing maar daarin wilde ik een andere check uitvoeren. Die vallen misschien wel te combineren overigens, eens proberen.

  • wizzkizz
  • Registratie: April 2003
  • Laatst online: 19-12-2025

wizzkizz

smile...tomorrow will be worse

Let wel dat onBeforeUnload geen deel uitmaakt van W3C recommendations en dientengevolge ook eigenlijk niet gebruikt zou moeten worden, vanwege incompatibiliteit met (o.a.) Opera.

wat je zou kunnen overwegen is om veranderingen direct al te saven, bijvoorbeeld bij een onblur. Het hangt natuurlijk wel van je app (en zelfs specifiek van je pagina) af of je dat wilt. Je zou ook kunnen overwegen om het optioneel te maken, dus dat de gebruiker hierin zelf kan kiezen.

Wat je ook zou kunnen doen is de mogelijke acties (ie. links etc) door een functie af te laten handelen, die in dit specifieke geval bijvoorbeeld vraagt of het form gesaved moet worden. Moet je natuurlijk wel zorgen dat je history object leeg is en daarvoor een alternatief aanbieden, maar dan wordt je app best wel weer ingewikkeld ;)

[ Voor 64% gewijzigd door wizzkizz op 06-11-2005 17:07 ]

Make it idiot proof and someone will make a better idiot.
Real programmers don't document. If it was hard to write, it should be hard to understand.


  • Varienaja
  • Registratie: Februari 2001
  • Laatst online: 14-06-2025

Varienaja

Wie dit leest is gek.

Ik snap eerlijk gezegd niks van je verhaal.

Maar staat de 'A' in Ajax niet voor asynchroon? Je hangt nu functionaliteit aan het moment dat je van pagina verandert; waarom pak je dan niet gewoon POST- of GET-parameters?

En waarom doe je zo moeilijk, en hang je het submitten van gegevens niet gewoon aan een submit-knop? Volgens mij is het GUI-technisch gezien zeer onlogisch om gewijzigde gegevens op te slaan zonder dat een gebruiker daarvoor op een knop duwt. En niets is zo irritant als een applicatie of webpagina die zeurt om on-opgeslagen gegevens als ik het window wegklik. Ik klik toch niet voor niks zo'n windows weg?

Siditamentis astuentis pactum.


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 23-04 02:19
Ik ben het helemaal eens met Varienaja. Invoer bevestigen kun je het beste met een 'echte' request doen. onunload-handlers zijn ook ontzettend lastig, om de reden die je al noemt, en hun functionaliteit wordt vaak door browsers beperkt om spam-achtig gedrag te voorkomen (nieuwe pop-ups openen als je een oude sluit enzo).

Verder is het vragen van een bevestiging bij het sluiten van een venster typisch een handeling die browser kan uitvoeren. Konqueror doet dat bijvoorbeeld standaard ook. Jouw mechanisme zou dan nogal dubbelop zijn.

Tenslotte heb ik misschien nog wel een oplossing voor je probleem: zorg dat je de gegevens in je formulier opslaat (in een variabele) zodra ze gewijzigd worden (met een onchanged-handler). Op het moment dat je unload-event plaatsvindt heb je dan altijd de up-to-date gegevens beschikbaar.

  • wizzkizz
  • Registratie: April 2003
  • Laatst online: 19-12-2025

wizzkizz

smile...tomorrow will be worse

Varienaja schreef op zondag 06 november 2005 @ 17:09:
Ik snap eerlijk gezegd niks van je verhaal.

Maar staat de 'A' in Ajax niet voor asynchroon? Je hangt nu functionaliteit aan het moment dat je van pagina verandert; waarom pak je dan niet gewoon POST- of GET-parameters?

En waarom doe je zo moeilijk, en hang je het submitten van gegevens niet gewoon aan een submit-knop? Volgens mij is het GUI-technisch gezien zeer onlogisch om gewijzigde gegevens op te slaan zonder dat een gebruiker daarvoor op een knop duwt. En niets is zo irritant als een applicatie of webpagina die zeurt om on-opgeslagen gegevens als ik het window wegklik. Ik klik toch niet voor niks zo'n windows weg?
I agree met je laatste stukje, met de kanttekening dat het soms helemaal niet de bedoeling is om het window weg te klikken en dat zoon melding dan wel handig kan zijn. En als het om complexe invoer gaat, bijvoorbeeld een artikel in een CMS, is het toch wel handig dat er een mogelijkheid is om het alsnog op te slaan (trouwens, als je dan toch met AJAX bezig bent, zou ik persoonlijk een auto-save functie maken ala GMail oid.)

Dat eerste komt denk ik omdat hij zn GUI en zn logica losgekoppeld heeft en alles wat met 1 handeling te maken heeft, ook op die ene pagina wil houden. Bijvoorbeeld iemands adresgegevens wijzigen, dan moet je alle functionaliteit daarvoor op die ene pagina houden en kun je niet, wanneer de gebruiker op een willekeurige link klikt, op de volgende pagina die gegevens alsnog gaan saven :)

Make it idiot proof and someone will make a better idiot.
Real programmers don't document. If it was hard to write, it should be hard to understand.


  • jsiegmund
  • Registratie: Januari 2002
  • Laatst online: 23:27
Het overzicht waarin gewerkt wordt kan ten alle tijden opgeslagen worden door de submit knop. Dat gebeurt via AJAX zodat je daarna niet terug hoeft naar dezelfde pagina (of een refresh oid). Echter wanneer er veranderingen gemaakt zijn en de gebruiker wil de pagina verlaten (onunload) wil ik alsnog vragen of die veranderingen wel of niet opgeslagen moeten worden. In het geval dat de gebruiker "ja" antwoord wordt het formulier nog een keer verzonden, en anders word er niks opgeslagen.

Het idee van de onunload hierboven was dus ook mijn idee, ware het niet dat dat dus niet goed werkt. Op het moment dat het laatste POST request (met de form gegevens) verstuurd en geprocessed wordt vraagt de browser alweer de(zelfde) pagina op. Die krijgt dus nog eentje terug met de oude gegevens erin. Pas na een refresh klopt het dan weer.

Het makkelijkste zou zijn om de gebruiker op een of andere manier te verbieden om weer naar dezelfde pagina te gaan, maar dat vind ik niet netjes. Een andere oplossing is inderdaad wachten op een antwoord van de AJAX structuur, maar daar moet ik dan maar eens grondig over na gaan denken (of dat uberhaupt waterdicht te krijgen is).

  • jsiegmund
  • Registratie: Januari 2002
  • Laatst online: 23:27
Hmmm ik heb nu zitten kloten maar IE doet erg moeilijk!

In FF is het allemaal geen probleem, die doet gewoon wat er van 'm verwacht wordt. Echter het volgende stukje code werkt in IE alleen de eerste keer:

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
function createRequestObject() {
    var xmlhttp;
    
    if (window.XMLHttpRequest) { // Mozilla, Safari, ...
        xmlhttp=new XMLHttpRequest()
    } else if (window.ActiveXObject) { // IE
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
    
    if (xmlhttp)
        return xmlhttp;
    else 
        alert ("Uw browser ondersteund de functionaliteit van deze pagina niet!");
}

function sendEmptyRequest(request) { 
    if (window.XMLHttpRequest) { // Mozilla, Safari, ...
        request.send(null);
    } else if (window.ActiveXObject) { // IE
        request.send();
    }
}

function sndRequest(location){
    req = createRequestObject();
    done = false;
    req.open("GET",location,true);
    req.onreadystatechange= function(){ done = true; }
    sendEmptyRequest(req);
    while (!done) { }
    return false;
}


Je zult zeggen: huh :? Inderdaad ja, zo dacht ik er ook over. Met een "vers" browser scherm werkt het goed. Je ziet de vertraging en de request wordt netjes uitgevoerd, dat kan ik controleren natuurlijk. Echter de keren daarop gebeurd er niks meer, geen wachten, geen request, niks. Na een middagje "wtf-en" snap ik er niks meer van!

[ Voor 45% gewijzigd door jsiegmund op 13-11-2005 14:20 ]


Verwijderd

geef eens als 3e parameter naar XMLHTTPRequest.open false mee ipv true, dan wordt de request niet meer asynchroon en wacht hij in de onunload functie op de http request.
while (!done) { }
dit is trouwens echt "not done" :P beetje 100% CPU innemen met niks doen.

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 01:13

crisp

Devver

Pixelated

inderdaad; binnen een unload handler wil je zeker geen async request sturen.
En als je al async gebruikt is het ook wel handig om op readyState te checken aangezien de onreadystatechange handler meerdere keren zal worden aangeroepen, en de eerste keer dat hij aangeroepen wordt nog niet wil zeggen dat het request al verstuurd is:

readyState 0 = Uninitialized
readyState 1 = Loading (send() has not been called yet)
readyState 2 = Loaded (send() has been called, headers and status are available)
readyState 3 = Interactive (Downloading, responseText contains partial data)
readyState 4 = Completed

Intentionally left blank


  • jsiegmund
  • Registratie: Januari 2002
  • Laatst online: 23:27
Jaja, die while-lus was even tijdelijk heren, dat snapt u zelf toch ook wel lijkt me :)

Dat die laatste parameter stond voor asynchrone calls wist ik niet (didn't read the correct fucking manual I guess), zal er eens wat mee experimenteren. Is overigens nog geen echt geldige rede waarom het dan de eerste keer wel werkt?

Update: Er simpelweg false van maken verandert niks. Op naar Google dan maar weer...

[ Voor 13% gewijzigd door jsiegmund op 14-11-2005 10:28 ]


  • crisp
  • Registratie: Februari 2000
  • Laatst online: 01:13

crisp

Devver

Pixelated

clientside --> Webdesign & Graphics

Intentionally left blank


  • jsiegmund
  • Registratie: Januari 2002
  • Laatst online: 23:27
Ok het een en ander werkt nu al wat beter, bedankt daarvoor... echter heb ik het nog steeds niet voor elkaar dat eerst de wijzigingen opgeslagen worden, en daarna pas de volgende pagina (zelfde pagina!) opgevraagd wordt. Het gebeurd nog steeds tegelijkertijd (heb ik tenmminste het idee), ook met false als argument...

Hoe kun je netjes wachten op een 4 status zodat je zeker weet dat het een en ander goed aangekomen is?

[ Voor 3% gewijzigd door jsiegmund op 15-11-2005 15:59 ]

Pagina: 1