<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ajax &#8211; Roy Duineveld</title>
	<atom:link href="https://royduineveld.nl/tag/ajax/feed/" rel="self" type="application/rss+xml" />
	<link>https://royduineveld.nl</link>
	<description>Waarom moeilijk doen als het makkelijk kan?</description>
	<lastBuildDate>Tue, 27 Jan 2026 07:48:00 +0000</lastBuildDate>
	<language>nl</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.9.26</generator>
	<item>
		<title>Waardes behouden na verzenden van dynamisch formulier</title>
		<link>https://royduineveld.nl/waardes-behouden-na-verzenden-van-dynamisch-formulier/</link>
		<comments>https://royduineveld.nl/waardes-behouden-na-verzenden-van-dynamisch-formulier/#respond</comments>
		<pubDate>Mon, 13 May 2013 18:19:53 +0000</pubDate>
		<dc:creator><![CDATA[Roy Duineveld]]></dc:creator>
				<category><![CDATA[Tips & Trucs]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Local Storage]]></category>
		<category><![CDATA[Session Storage]]></category>

		<guid isPermaLink="false">https://royduineveld.nl/?p=449</guid>
		<description><![CDATA[<p>Na het verzenden én vervolgens op de &#8220;vorige knop&#8221; geklikt te hebben zijn alle ingevulde waardes van een dynamisch formulier verdwenen. Ofwel, een formulier waarbij met Javascript elementen toegevoegd worden....</p>
<p>Het bericht <a rel="nofollow" href="https://royduineveld.nl/waardes-behouden-na-verzenden-van-dynamisch-formulier/">Waardes behouden na verzenden van dynamisch formulier</a> verscheen eerst op <a rel="nofollow" href="https://royduineveld.nl">Roy Duineveld</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>Na het verzenden én vervolgens op de &#8220;vorige knop&#8221; geklikt te hebben zijn alle ingevulde waardes van een dynamisch formulier verdwenen. Ofwel, een formulier waarbij met Javascript elementen toegevoegd worden. Om dit op te lossen zijn er meerdere mogelijkheden:</p>
<ul>
<li><span style="line-height: 13px;">Formulier middels Ajax verzenden, zodat de pagina niet opnieuw geladen hoeft te worden</span></li>
<li>De waardes middels Ajax opslaan en opnieuw inladen</li>
<li>De gegevens lokaal opslaan, dit voor het verzenden</li>
</ul>
<p>Ik heb recent gekozen voor de laatste optie. Voordat ik de oplossing hiervoor laat zien, eerst wat materiaal om mee te werken. Laten we een eenvoudig formulier nemen:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;form action=&quot;&quot; method=&quot;POST&quot;&gt;
	&lt;table&gt;
		&lt;tr id=&quot;eerste-regel&quot;&gt;
			&lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;name[]&quot; placeholder=&quot;Naam...&quot;&gt;&lt;/td&gt;
			&lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;number[]&quot; placeholder=&quot;Nummer...&quot;&gt;&lt;/td&gt;
		&lt;/tr&gt;
	&lt;/table&gt;
	&lt;a href=&quot;#&quot; id=&quot;regel-toevoegen&quot;&gt;Regel toevoegen&lt;/a&gt; &lt;input type=&quot;submit&quot; value=&quot;Verzenden!&quot;&gt;
&lt;/form&gt;
</pre>
<p>Het volgende stukje Javascript in samenwerking met jQuery zorgt ervoor dat wanneer er op &#8220;Regel toevoegen&#8221; geklikt wordt er een nieuwe regel bij komt:</p>
<pre class="brush: jscript; title: ; notranslate">
// Regel toevoegen geklikt?
$('#regel-toevoegen').click(function()
{
	// Eerste regel ophalen
	var regel = $('#eerste-regel').clone();

	// ID verwijderen
	regel.removeAttr('id');

	// Ingevulde waardes verwijderen
	regel.find('input').val('');

	// Nieuwe regel toevoegen en het ID en de ingevulde waardes verwijderen
	$('table').append( regel );

	// False terug sturen zodat de pagina niet verspringt
	return false;
});
</pre>
<p>Hier kunnen we op verder bouwen! Want wanneer je meerdere regels toevoegt, deze invult en na het klikken op &#8220;Verzenden!&#8221; terug gaat; is al je kostbare werk verloren gegaan. Om de gegevens voordat deze verzonden worden op te slaan, dienen we dit af te vangen waarna we deze gestructureerd op kunnen slaan. Zie het volgende stukje code:</p>
<pre class="brush: jscript; title: ; notranslate">
// Form versturen?
$('form').submit(function()
{
	// Object met array's maken
	var array           = {};
	array['name']       = [];
	array['number']		= [];
	array['counter']    = 0;

	// Door alle tabel regels loopen
	$('tr').each(function()
	{
		array['name'].push( $(this).find('input[name=&quot;name[]&quot;]').val() );
		array['number'].push( $(this).find('input[name=&quot;number[]&quot;]').val() );
		array['counter']++;
	});

	// Opslaan in session storage
	sessionStorage.setItem('input', JSON.stringify(array));
});
</pre>
<p>Eerst vangen we de &#8220;submit&#8221; af, hierna bouwen we een object op met array&#8217;s gevolgd door alle ingevulde waardes hierin te zetten. Tevens draait er een tellertje mee om het aantal velden te bepalen. Als laatste worden de gegevens opgeslagen in &#8220;Session Storage&#8221;. In cookies kan je weinig kwijt en &#8220;Local Storage&#8221; bewaard de gegevens ook nadat het browser venster gesloten is, vandaar deze keuze. Let daarbij wel op dat je geen object of array in session of local storage kan opslaan. Hiervoor dient deze eerst omgezet te worden naar een &#8220;string&#8221;, vandaar de &#8220;stringify&#8221; functie. Hartstikke mooi dat het opgeslagen is, maar het moet er ook weer uit natuurlijk! Zie:</p>
<pre class="brush: jscript; title: ; notranslate">
// Iets in session storage aanwezig?
if(sessionStorage.getItem('input'))
{
	// Gegevens ophalen
	var array = JSON.parse( sessionStorage.getItem('input') );

	// Nieuwe regels toevoegen, minus de al aanwezige
	for (var n = 0; n &lt; (array['counter'] - 1); ++ n)
	{
		$('#regel-toevoegen').click();
	}

	// Door alle tabel regels loopen
	$('tr').each(function(index,value)
	{
		// Waarde plaatsen
		$(this).find('input[name=&quot;name[]&quot;]').val( array['name'][index] );
		$(this).find('input[name=&quot;number[]&quot;]').val( array['number'][index] );
	});

	// Waardes weer verwijderen
	sessionStorage.removeItem('input');
}
</pre>
<p>Eerst maar kijken of er iets aanwezig is, wanneer dat het geval is de gegevens ophalen en van de &#8220;string&#8221; weer een object met array&#8217;s maken. De teller laten lopen en elke keer even op de &#8220;Regel toevoegen&#8221; knop klikken. Vervolgens het zelfde stukje als bij het opslaan, enkel plaatsen we nu de gegevens terug in plaats van dat we deze uitlezen. Als toetje de gegevens nog even verwijderen en klaar!</p>
<p><a href="https://royduineveld.nl/demos/waardes-behouden-na-verzenden/" class="demo-button" target="_blank">Klik hier voor een online demo</a></p>
<p>Het bericht <a rel="nofollow" href="https://royduineveld.nl/waardes-behouden-na-verzenden-van-dynamisch-formulier/">Waardes behouden na verzenden van dynamisch formulier</a> verscheen eerst op <a rel="nofollow" href="https://royduineveld.nl">Roy Duineveld</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://royduineveld.nl/waardes-behouden-na-verzenden-van-dynamisch-formulier/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Altijd weten door wie je gebeld wordt</title>
		<link>https://royduineveld.nl/altijd-weten-door-wie-je-gebeld-wordt/</link>
		<comments>https://royduineveld.nl/altijd-weten-door-wie-je-gebeld-wordt/#comments</comments>
		<pubDate>Sat, 11 May 2013 14:37:40 +0000</pubDate>
		<dc:creator><![CDATA[Roy Duineveld]]></dc:creator>
				<category><![CDATA[Ideeën & Concepten]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[Cordova]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Phonegap]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">https://royduineveld.nl/?p=437</guid>
		<description><![CDATA[<p>Is het niet super handig als je gebeld wordt, je altijd weet door wie? Met uitzondering van echte onbekende nummers natuurlijk. Ofwel; je wordt gebeld en er staat een nummer...</p>
<p>Het bericht <a rel="nofollow" href="https://royduineveld.nl/altijd-weten-door-wie-je-gebeld-wordt/">Altijd weten door wie je gebeld wordt</a> verscheen eerst op <a rel="nofollow" href="https://royduineveld.nl">Roy Duineveld</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>Is het niet super handig als je gebeld wordt, je altijd weet door wie? Met uitzondering van echte onbekende nummers natuurlijk. Ofwel; je wordt gebeld en er staat een nummer in het scherm welke je niet kent. Vervolgens zorgt een app ervoor dat er een popupje komt met de naam van de persoon. Goed nieuws! Zo&#8217;n app is er al: <a title="Ga naar de Truecaller app in de Play Store" href="https://play.google.com/store/apps/details?id=com.truecaller&amp;hl=nl" target="_blank">Truecaller</a>. Maar, helaas herkent deze app heel erg weinig telefoon nummers en mocht het op 06 nummers aankomen kan je het helemaal vergeten. Dat kan beter!</p>
<h2>Het idee</h2>
<p>WhoApp! Na het downloaden en starten van de app wordt je gehele adressenboek (enkel namen en telefoon nummers) geüpload naar de server. Dit klinkt misschien gek of eng maar waarom niet? Het zijn maar telefoon nummers en namen en anders kan er nooit een (om te beginnen, landelijk) telefoonboek gemaakt worden met ook mobiele nummers. Mocht je dit niet willen eventueel een tweede betaalde app waarbij dit niet hoeft. Dit is dan gelijk een klein verdien patroon. In de app zelf kan er op telefoon nummer gezocht worden naar namen. Dit aan de hand van de gegevens in de database op de server. Mocht het betreffende telefoon nummer nog niet in de database staan eventueel een koppeling met bijvoorbeeld <a title="Ga naar nummerzoeker.com" href="http://nummerzoeker.com" target="_blank">nummerzoeker.com</a> waar het mogelijk is te zoeken op vaste telefoon nummers naar (bedrijfs)namen en adressen. Daarnaast kan de achtergrond taak aangezet worden welke zorgt voor de volgende functionaliteit:</p>
<p>Wanneer je gebeld wordt komt er bovenin het scherm een venstertje te staan met daarin de naam van diegene met dat telefoon nummer. Dit enkel in het geval dat het nummer niet in je eigen adressenboek staat en uiteraard enkel wanneer aanwezig in de database.</p>
<p><a href="https://royduineveld.nl/wp-content/uploads/2013/05/truecaller.jpg"><img class="aligncenter size-medium wp-image-439" src="https://royduineveld.nl/wp-content/uploads/2013/05/truecaller-179x300.jpg" alt="Truecaller" width="179" height="300" srcset="https://royduineveld.nl/wp-content/uploads/2013/05/truecaller-179x300.jpg 179w, https://royduineveld.nl/wp-content/uploads/2013/05/truecaller.jpg 307w" sizes="(max-width: 179px) 100vw, 179px" /></a></p>
<h2>Uitvoering</h2>
<p>Enige tijd geleden kwam dit idee en heb hiervoor de naam WhoApp bedacht. Deze naam zodoende geregistreerd, zowel bij de KvK als de domeinnaam (<a title="Ga naar WhoApp.nl" href="http://whoapp.nl" target="_blank">whoapp.nl</a>) en de naam als app voor de Google Play Store. Nu de app nog maken! Op het moment van schrijven ben ik nog niet zo ver met Java en dus native Android apps. Daarin tegen kan ik aardig wat maken met Phonegap waar ik eerder een artikel over heb geschreven: <a title="App maken met Phonegap en Phonegap Build" href="https://royduineveld.nl/overige/413/app-maken-met-phonegap-en-phonegap-build/" target="_blank">App maken met Phonegap en Phonegap Build</a>. De te ontwikkelen functionaliteiten:</p>
<ul>
<li><span style="line-height: 13px;">Contacten van de telefoon naar de server versturen. Met Phonegap werk je voornamelijk met Javascript, dat in combinatie met de <a title="Ga naar de Phonegap Contacts API documentatie" href="http://docs.phonegap.com/en/2.7.0/cordova_contacts_contacts.md.html#Contacts" target="_blank">Phonegap API</a> en vervolgens middels Ajax versturen. Dit heb ik inmiddels getest en functioneert.</span></li>
<li>Het telefoonboek. Op de server zal een PHP script in combinatie met een MySQL database alle telefoon nummers moeten verwerken. Deze dienen uiteraard gestandaardiseerd en gegroepeerd te worden. Dit wordt nog even uitzoeken maar is zeker te doen. Ook moet er een algoritme toegepast worden om de juiste naam te tonen. De één heeft in zijn adressenboek simpelweg &#8220;Roy&#8221; staan, de ander &#8220;Roy Duineveld&#8221; en weer iemand anders &#8220;Roy uit Heiloo&#8221;. Aan de hand van de meest voorkomende naam zal deze getoond worden. Dan hopen dat zoveel mogelijk mensen &#8220;Roy Duineveld&#8221; in hun telefoonboek hebben staan.</li>
<li>Van de app een service maken welke op de achtergrond draait. Dit is vanuit Phonegap nog niet mogelijk maar er is wel al een plugin voor gemaakt: <a title="Ga naar de background service plugin voor Phonegap" href="https://github.com/Red-Folder/Cordova-Plugin-BackgroundService" target="_blank">Cordova-Plugin-BackgroundService</a>. Ik heb hier nog niet mee geëxperimenteerd maar ik verwacht geen problemen.</li>
<li>De service automatisch starten wanneer de telefoon aan gezet wordt. Dit wordt waarschijnlijk in de native code duiken worden maar hoop in de &#8220;Background Service&#8221; plugin wat te vinden wat dit mogelijk maakt.</li>
<li>Wanneer gaat de telefoon over? Ook daar heeft iemand al een plugin voor Phonegap voor gemaakt! <a title="Ga naar de PhoneListener github pagina" href="https://github.com/devgeeks/PhoneListener" target="_blank">PhoneListener</a>. Helaas functioneert deze plugin niet meer met de nieuwere versies van Phonegap maar ook nu heeft een nieuwe plugin zich aangeboden die dit mogelijk maakt: <a title="Ga naar de PhoneStateChangeListener github pagina" href="https://github.com/madeinstefano/PhoneStateChangeListener" target="_blank">PhoneStateChangeListener</a>. Hierbij krijg je de status &#8220;idle&#8221;, &#8220;ringing&#8221; of &#8220;offhook&#8221; door. Getest en werkt perfect!</li>
<li>Wanneer de telefoon gaat; het telefoon nummer bemachtigen. In de extended versie van de verouderde PhoneListener plugin was deze optie beschikbaar: <a title="Ga naar de Extended PhoneListener github pagina" href="https://github.com/devgeeks/PhoneListener/tree/extended" target="_blank">PhoneListener Extended</a>. Na contact te hebben gehad met de maker van de PhoneStateChangeListener plugin is versie 1.1 uitgebracht waar deze functionaliteit is toegevoegd! Ook dit getest en werkt perfect.</li>
<li>Als laatste misschien wel een van de belangrijkste elementen, de popup op het scherm weergeven! Na veel zoek werk ben ik hier vast gelopen. Mede door mijn nihile kennis van Java. Momenteel heb ik op <a title="Ga naar Freelancer.com" href="http://freelancer.com" target="_blank">Freelancer.com</a> een project lopen en iemand gevonden in China die dit voor mij gaat realiseren voor weinig geld. De verwachtingen zijn laag, maar niet geschoten is altijd mis. Wordt vervolgd!</li>
</ul>
<h2>Vooruitgang</h2>
<p>Momenteel draait er een simpele website welke enkel gekoppeld is aan nummerzoeker.com. Wat de app betreft heb ik twee varianten, één op grafisch gebied compleet en met de functionaliteit om alle contactpersonen naar de server te versturen en nummers op te zoeken. De tweede app is enkel om te testen, hierin zit momenteel de PhoneStateChangeListener plugin verwerkt. Het is nog even verder experimenteren met de &#8220;Background Service&#8221;, het automatisch starten hiervan en de popup.</p>
<blockquote><p>Het project zit niet heel veel druk achter maar lijkt mij leuk om door te zetten. Mocht er nieuws zijn zal ik dit toevoegen aan dit artikel.</p></blockquote>
<p><em>Eventueel geïnteresseerden voor samenwerking is bespreekbaar. Ook aan- of opmerkingen zijn van harte welkom!</em></p>
<h2>Updates</h2>
<ul>
<li>13-05-2013 &#8211; Inmiddels is bekend dat het met de &#8220;Background Service&#8221; plugin het mogelijk is een automatisch startende service te maken. Tevens een aantal test apps mogen ontvangen van &#8220;de Chinees&#8221; met goede resultaten!</li>
<li>01-09-2013 &#8211; Ik heb het aardig druk op het moment, dus dit project staat even op een zijspoor. Inmiddels is wel alles in huis om het project te voltooien.</li>
<li>05-01-2014 &#8211; Google heeft een soortgelijke functionaliteit in de nieuwe Android versie 4.4 Kitkat gestopt (<a title="Ga naar Tweakers.net" href="http://tweakers.net/nieuws/92420/google-breidt-nummerherkenning-android-uit-met-google+-informatie.html" target="_blank">zie dit nieuwsbericht op Tweakers.net</a>), ik zal er dus niet meer mee verder gaan.</li>
<li>19-07-2016 &#8211; De domeinnaam wordt niet verlengt en komt weer vrij op de markt.</li>
</ul>
<p>Het bericht <a rel="nofollow" href="https://royduineveld.nl/altijd-weten-door-wie-je-gebeld-wordt/">Altijd weten door wie je gebeld wordt</a> verscheen eerst op <a rel="nofollow" href="https://royduineveld.nl">Roy Duineveld</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://royduineveld.nl/altijd-weten-door-wie-je-gebeld-wordt/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Ajax request annuleren</title>
		<link>https://royduineveld.nl/ajax-request-annuleren/</link>
		<comments>https://royduineveld.nl/ajax-request-annuleren/#respond</comments>
		<pubDate>Wed, 02 Jan 2013 19:15:00 +0000</pubDate>
		<dc:creator><![CDATA[Roy Duineveld]]></dc:creator>
				<category><![CDATA[Tips & Trucs]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">https://royduineveld.nl/?p=175</guid>
		<description><![CDATA[<p>Ajax werkt asynchroon. Dit houd in dat er meerdere verzoeken tegelijk uitgevoerd kunnen worden en de één niet wacht op de ander. Stel dat je een website hebt met product filters....</p>
<p>Het bericht <a rel="nofollow" href="https://royduineveld.nl/ajax-request-annuleren/">Ajax request annuleren</a> verscheen eerst op <a rel="nofollow" href="https://royduineveld.nl">Roy Duineveld</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>Ajax werkt asynchroon. Dit houd in dat er meerdere verzoeken tegelijk uitgevoerd kunnen worden en de één niet wacht op de ander. Stel dat je een website hebt met <a href="http://telbat.nl/tablets-vergelijken" target="_blank">product filters</a>. Je kiest een aantal filters en je krijgt het gewenste resultaat. Prachtig, maar wanneer je op een langzame internet verbinding zit (3G) en er een filter gekozen wordt met heel veel resultaten en snel daarop volgend een filter welke maar één resultaat oplevert. Dan willen we dit in de gekozen volgorde zien. De filter met één resultaat is natuurlijk veel sneller klaar dan die met meerdere resultaten wat als resultaat geeft dat je uiteindelijk meerdere resultaten krijgt te zien, wat natuurlijk niet de bedoeling is!</p>
<p>Om dit op te lossen dient het eerste verzoek (ajax request) geannuleerd te worden wanneer deze nog bezig is. Mocht je foutmeldingen weergeven wanneer deze optreden bij een ajax verzoek dienen de geannuleerde verzoeken niet weergegeven te worden.</p>
<p>Het voorbeeld:</p>
<pre class="brush: jscript; title: ; notranslate">

//Self invoking anonymous function
//Ofwel een naamloze functie welke automatisch gestart wordt
(function()
{
	//Wachten tot een checkbox veranderd
	$('input[type=checkbox]').change(function()
	{
		//Wanneer er al een request is deze annuleren
		if ( typeof request !== &quot;undefined&quot; &amp;&amp; request) {
			request.abort();
		}

		//Ajax request
		request = $.ajax({
			url: 		'http://website.nl/',
			data: 		{ naam: 'Roy Duineveld' },
			dataType: 	'json'
			type: 		'POST',
			error: 		function(jqXHR, textStatus, errorThrown)
			{
				//Wanneer de ajax request geannuleerd wordt dit niet weergeven
				if(errorThrown != 'abort')
				{
					alert('Er ging iets fout! ' + errorThrown);
				}
			},
			succcess: 	function(data)
			{
				$('body').html(data);
			}
		});
	});
})();

</pre>
<p>Het bericht <a rel="nofollow" href="https://royduineveld.nl/ajax-request-annuleren/">Ajax request annuleren</a> verscheen eerst op <a rel="nofollow" href="https://royduineveld.nl">Roy Duineveld</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://royduineveld.nl/ajax-request-annuleren/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP 5.4</title>
		<link>https://royduineveld.nl/php-5-4/</link>
		<comments>https://royduineveld.nl/php-5-4/#respond</comments>
		<pubDate>Wed, 12 Dec 2012 11:27:05 +0000</pubDate>
		<dc:creator><![CDATA[Roy Duineveld]]></dc:creator>
				<category><![CDATA[Tips & Trucs]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">https://royduineveld.nl/?p=164</guid>
		<description><![CDATA[<p>Net een weekje met PHP 5.3 aan de gang en gelijk door naar 5.4! Nog meer leuks en dus hierbij weer een sommering van de wijzigingen en toevoegingen die mij...</p>
<p>Het bericht <a rel="nofollow" href="https://royduineveld.nl/php-5-4/">PHP 5.4</a> verscheen eerst op <a rel="nofollow" href="https://royduineveld.nl">Roy Duineveld</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>Net een weekje met <a href="https://royduineveld.nl/php/152/php-5-3/">PHP 5.3</a> aan de gang en gelijk door naar 5.4! Nog meer leuks en dus hierbij weer een sommering van de wijzigingen en toevoegingen die mij opvielen:</p>
<ul>
<li><a href="http://php.net/safe_mode" target="_blank">Safe mode</a>, <a href="http://php.net/magic_quotes" target="_blank">magic quotes</a> en <a href="http://php.net/register_globals" target="_blank">register globals</a> zijn weg</li>
<li>Korte array syntax. Simpelweg: $arr = [&#8216;item1&#8242;,&#8217;item2&#8242;,&#8217;item3&#8242;,&#8217;item4&#8217;];</li>
<li>In anonieme functies kan $this gebruikt worden</li>
<li>Short tags zijn altijd bruikbaar (&lt;?= in plaats van &lt;?php echo)</li>
<li>Stel een function geeft een array terug kan een waarde uit de array direct aangesproken worden:</li>
</ul>
<pre class="brush: php; title: ; notranslate">function test(){
return ['item1','item2','item3'];
}
echo test()[1]; //item2</pre>
<ul>
<li>UTF-8 is de standaard charset voor <a href="http://php.net/htmlspecialchars" target="_blank">htmlspecialchars</a></li>
<li><a href="http://php.net/manual/en/session.upload-progress.php" target="_blank">Session upload progress</a> wat tijdens het uploaden van een bestand ervoor zorgt dat er een array gemaakt wordt met de status van de upload. Middels Ajax is het dan mogelijk, live een mooie &#8220;progress bar&#8221; te maken of een percentage te laten zien.</li>
</ul>
<p>Uiteraard is het complete verhaal te lezen op <a href="http://php.net/manual/en/migration54.php" target="_blank">PHP.net</a>.</p>
<p>Het bericht <a rel="nofollow" href="https://royduineveld.nl/php-5-4/">PHP 5.4</a> verscheen eerst op <a rel="nofollow" href="https://royduineveld.nl">Roy Duineveld</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://royduineveld.nl/php-5-4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Website offline beschikbaar maken met een submit fallback</title>
		<link>https://royduineveld.nl/website-offline-beschikbaar-maken-met-een-submit-fallback/</link>
		<comments>https://royduineveld.nl/website-offline-beschikbaar-maken-met-een-submit-fallback/#comments</comments>
		<pubDate>Thu, 15 Nov 2012 16:42:12 +0000</pubDate>
		<dc:creator><![CDATA[Roy Duineveld]]></dc:creator>
				<category><![CDATA[Tips & Trucs]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Local Storage]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">https://royduineveld.nl/?p=47</guid>
		<description><![CDATA[<p>Een website met formulier offline beschikbaar maken en de ingevoerde data verzenden wanneer weer online, dat kan middels HTML5 i.c.m. Javascript! Om de pagina offline beschikbaar te maken kan je...</p>
<p>Het bericht <a rel="nofollow" href="https://royduineveld.nl/website-offline-beschikbaar-maken-met-een-submit-fallback/">Website offline beschikbaar maken met een submit fallback</a> verscheen eerst op <a rel="nofollow" href="https://royduineveld.nl">Roy Duineveld</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>Een website met formulier offline beschikbaar maken en de ingevoerde data verzenden wanneer weer online, dat kan middels HTML5 i.c.m. Javascript! Om de pagina offline beschikbaar te maken kan je gebruik maken van de standaard cache methodes. Nadeel hiervan is dat wanneer je de pagina opnieuw laad je toch ineens een foutpagina krijgt. Beter gebruik je een <a href="http://www.w3.org/TR/html5/offline.html#manifests">cache manifest</a> (werkt in alle browsers en helaas, zoals gewoonlijk, weer niet in Internet Explorer). Een voorbeeld pagina met een formulier (index.php) waarvan de inhoud simpelweg naar een tekst bestand geschreven wordt:</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php
//Form &quot;gesubmit&quot;?
if($_POST)
{
	//Velden scheiden door een komma en achteraan data.txt toevoegen
	file_put_contents('data.txt', implode(', ',$_POST).&quot;\n&quot;, FILE_APPEND);

	//Pagina opnieuw laden
	header('Location: index.php');
}
?&gt;
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
	&lt;meta charset=&quot;utf-8&quot;&gt;
	&lt;title&gt;Pagina naam&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;

	&lt;form method=&quot;post&quot; action=&quot;&quot;&gt;

		&lt;input type=&quot;text&quot; name=&quot;inputname1&quot; /&gt;
		&lt;input type=&quot;text&quot; name=&quot;inputname2&quot; /&gt;

		&lt;input type=&quot;submit&quot; value=&quot;Opslaan!&quot; /&gt;

	&lt;/form&gt;

	&lt;p&gt;Data:&lt;/p&gt;
	&lt;hr /&gt;
	&lt;?php
	//Gegevens ophalen uit data.txt, om XSS te voorkomen door htmlspecialchars halen en als laatste middels nl2br ervoor zorgen dat de &quot;enters&quot; ofwel nieuwe lijnen/regels zichtbaar zijn.
	echo nl2br(htmlspecialchars(file_get_contents('data.txt')));
	?&gt;

&lt;/body&gt;
&lt;/html&gt;
</pre>
<h2>Manifest bestand</h2>
<p>Een cache manifest daaraan toevoegen, simpelweg de html tag vervangen door:</p>
<pre class="brush: xml; title: ; notranslate">&lt;html manifest=&quot;manifest.php&quot;&gt;</pre>
<p>Het cache manifest maken (manifest.php):</p>
<pre class="brush: xml; title: ; notranslate">
CACHE MANIFEST
index.php
</pre>
<p>En klaar! De pagina is nu offline beschikbaar (mits deze al eenmalig bezocht is). Nadeel nu is dat wanneer de pagina (of data.txt veranderd), laten we zeggen dat er een input veld bij komt, wordt dit niet zichtbaar omdat de pagina altijd vanuit de cache geladen wordt. Wanneer wordt de pagina opnieuw opgehaald? Enkel als het manifest bestand veranderd. Dus zorgen we ervoor dat het manifest bestand veranderd als index.php en data.txt veranderen door bijvoorbeeld een md5 hash van de bestanden te maken, zodra de index.php of data.txt veranderd zal die hash ook veranderen. Laten we er een stukje commentaar in zetten met die hash.</p>
<pre class="brush: php; title: ; notranslate">
CACHE MANIFEST
index.php
# data.txt md5 hash: &lt;?=md5_file('data.txt');?&gt;
# index.php md5 hash: &lt;?=md5_file('index.php');?&gt;
</pre>
<h2>Localstorage als cache</h2>
<p>Top! Probleem opgelost! Maar als we het formulier &#8220;submitten&#8221; wanneer offline zal er niet veel gebeuren. Wat zijn de mogelijkheden om data tijdelijk bij de bezoeker op te slaan? Cookies! Prachtig maar veel gegevens kunnen we er niet in kwijt. <a href="http://www.w3.org/TR/webdatabase/">WebSQL</a>, wordt beperkt ondersteund en zoals bij W3C te lezen niet meer door ontwikkeld. <a href="http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html">IndexedDB</a>, helaas ook beperkt ondersteund. Houden we <a href="http://www.w3.org/TR/webstorage/">local storage</a> over! Wordt zelfs ondersteund door Internet Explorer (8+)! En&#8230; de code in! Laten we voor het gemak jQuery erbij pakken en eerst de form submit (wanneer offline) afvangen en de gegevens in localstorage stoppen:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;script type=&quot;text/javascript&quot; src=&quot;http://code.jquery.com/jquery-1.8.2.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
	//Naamloze functie maken
	(function()
	{
		//Form gesubmit?
		$('form').submit(function()
		{
			//Offline?
			if( ! navigator.onLine )
			{
				//De bezoeker vertellen wat er gebeurd
				alert('Je bent niet verbonden met het internet, de gegevens worden tijdelijk lokaal opgeslagen tot je weer verbonden bent met het internet.')

				//Nieuw item met alle ingevoerde gegevens uit het form aan localstorage toevoegen
				localStorage.setItem(new Date().getTime(), $(this).serialize() );

				//Alle ingevoerde velden leeg maken
				$('input[type=text]').val('');

				//Zorgen dat het form niet echt gesubmit wordt
				return false;
			}
		});

	//Naamloze functie direct uitvoeren
	})();
&lt;/script&gt;
</pre>
<p>Vervolgens moeten we ervoor zorgen dat wanneer er iets in localstorage zit dit de volgende keer verzonden wordt. Gezien dit allemaal javascript is en we dit middels ajax gaan doen eerst het &#8220;ajax afhandel script&#8221; maken, save.php:</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php
if($_POST){
	//Index echo'en zodat we deze kunnen verwijderen uit localstorage
	echo $_POST['index'];
	unset($_POST['index']);
	file_put_contents('data.txt', implode(', ',$_POST).&quot;\n&quot;, FILE_APPEND);
}
?&gt;
</pre>
<p>En weer door met javascript:</p>
<pre class="brush: jscript; title: ; notranslate">
//Online?
if( navigator.onLine )
{
	//Zijn er items in localstorage?
	if(localStorage.length)
	{
		//Door alle items in localstorage &quot;loopen&quot;
		for(var i in localStorage)
		{
			//Item versturen naar save.php
			$.ajax({
				url: 'save.php',
				data: 'index=' + i + '&amp;' + localStorage.getItem(i),
				type: 'POST',
				success: function(data){
					//Wanneer succesvol verzonden verwijderen uit localstorage
					localStorage.removeItem(data);
				}
			});
		}
	}
}
</pre>
<p>En klaar! Maar zoals je wellicht gemerkt hebt dien je eerst de pagina twee maal opnieuw te laten voordat de cache overschreven wordt. Om dit probleem op te lossen een kleine &#8220;hotfix&#8221; of &#8220;hack&#8221; om het zo maar te noemen:</p>
<pre class="brush: jscript; title: ; notranslate">
//Manifest bestand veranderd? (en dus index.php of data.txt)
window.applicationCache.addEventListener('updateready', function(e)
{
	if (window.applicationCache.status == window.applicationCache.UPDATEREADY)
	{
		//Cash verwijderen en nieuwe items laden
		window.applicationCache.swapCache();

		//Pagina opnieuw laden
		window.location.reload();
	}
}, false);
</pre>
<p>Best leuk dit! Waar kan je dit toepassen? Het is erg handig voor mobiele websites, komt wel eens voor dat de bezoeker geen internet heeft of dat het internet langzaam is (hopen dat het straks met 4G sneller gaat). Dan is het wel zo makkelijk dat de website bezocht kan worden én de ingevoerde gegevens verwerkt worden!</p>
<p><a class="demo-button" href="https://royduineveld.nl/demos/website-offline/" target="_blank">Klik hier voor een online demo</a></p>
<p>Het bericht <a rel="nofollow" href="https://royduineveld.nl/website-offline-beschikbaar-maken-met-een-submit-fallback/">Website offline beschikbaar maken met een submit fallback</a> verscheen eerst op <a rel="nofollow" href="https://royduineveld.nl">Roy Duineveld</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://royduineveld.nl/website-offline-beschikbaar-maken-met-een-submit-fallback/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>