Web programming
Horváth Győző
Associate professor
1117 Budapest, Pázmány Péter sétány 1/c., 2.408-as szoba
Tel: (1) 372-2500/8469
horvath.gyozo@inf.elte.hu
Variations
Form data, traditional
<pre><?php print_r($_POST) ?></pre>
<form action="" method="post">
Data1: <input type="text" name="data1"> <br>
Data2: <input type="text" name="data2"> <br>
<button>Send</button>
</form>
Form data, AJAX
<form action="" method="post">
Data1: <input type="text" name="data1"> <br>
Data2: <input type="text" name="data2"> <br>
<button>Send</button>
</form>
document.querySelector('form').addEventListener('submit', onSubmit)
function onSubmit(e) {
e.preventDefault()
const formData = new FormData(this)
const xhr = new XMLHttpRequest()
xhr.open('post', 'server-ajax.php')
xhr.addEventListener('load', function () { console.log(this.responseText) })
xhr.send(formData)
}
<?php print_r($_POST);
Form data + JSON, traditional
<pre><?php print_r($_POST) ?></pre>
<form action="" method="post">
Data1: <input type="text" name="data1"> <br>
Data2: <input type="text" name="data2"> <br>
<input type="hidden" name="json">
<button>Send</button>
</form>
const data = {
prop1: 'value1',
prop2: [1, 2, 3]
}
document.querySelector('form').addEventListener('submit', onSubmit)
function onSubmit(e) {
this.querySelector('[name=json]').value = JSON.stringify(data)
}
Form data + JSON, AJAX
<form action="" method="post">
Data1: <input type="text" name="data1"> <br>
Data2: <input type="text" name="data2"> <br>
<button>Send</button>
</form>
const data = { prop1: 'value1', prop2: [1, 2, 3] }
document.querySelector('form').addEventListener('submit', onSubmit)
function onSubmit(e) {
e.preventDefault()
const formData = new FormData(this)
formData.append('json', JSON.stringify(data))
const xhr = new XMLHttpRequest()
xhr.open('post', 'server-ajax.php')
xhr.addEventListener('load', function () { console.log(this.responseText) })
xhr.send(formData)
}
<?php print_r($_POST);
JSON, traditional
Data1: <input type="text" name="data1"> <br>
Data2: <input type="text" name="data2"> <br>
<form action="" method="post">
<input type="hidden" name="json">
<button>Send</button>
</form>
document.querySelector('form').addEventListener('submit', onSubmit)
function onSubmit(e) {
const data = {}
data.data1 = document.querySelector('[name=data1]').value
data.data2 = document.querySelector('[name=data2]').value
this.querySelector('[name=json]').value = JSON.stringify(data)
}
JSON, AJAX
Data1: <input type="text" name="data1"> <br>
Data2: <input type="text" name="data2"> <br>
<button>Send</button>
document.querySelector('button').addEventListener('click', onSubmit)
function onSubmit(e) {
e.preventDefault()
const data = {
data1: document.querySelector('[name=data1]').value,
data2: document.querySelector('[name=data2]').value
}
const xhr = new XMLHttpRequest()
xhr.open('post', 'server-ajax-body.php')
xhr.addEventListener('load', function () { console.log(this.responseText) })
xhr.send(JSON.stringify(data))
}
<?php
$json = file_get_contents('php://input');
$data = json_decode($json, true); print_r($data);
JSON, traditional
<?php
$par = $_GET['par'] ?? 'default';
$data = [
'data1' => $par,
'data2' => [1, 2, 3],
];
$json = json_encode($data);
?>
<h3>Some page</h3>
<script>
const data = JSON.parse('<?= $json ?>')
</script>
<script>
console.log(data)
</script>
JSON, traditional
<?php $par = $_GET['par'] ?? 'default'; ?>
<h3>Some page</h3>
<script src="get-data.php?par=<?= $_GET['par'] ?>"></script>
<script>
console.log(data)
</script>
<?php
$par = $_GET['par'];
$data = [
'data1' => $par,
'data2' => [1, 2, 3],
];
$json = json_encode($data);
?>
const data = JSON.parse('<?= $json ?>')
JSON, AJAX
<h3>Some page</h3>
<script>
var url = new URL(window.location.href)
const par = url.searchParams.get('par')
const xhr = new XMLHttpRequest()
xhr.open('get', `get-data-ajax.php?par=${par}`)
xhr.addEventListener('load', function () { console.log(this.response) })
xhr.responseType = 'json'
xhr.send(null);
</script>
<?php
$par = $_GET['par'];
$data = [
'data1' => $par,
'data2' => [1, 2, 3],
];
echo json_encode($data);
JSON, AJAX
<h3>Some page</h3>
<button>Get data</button>
document.querySelector('button').addEventListener('click', onClick)
function onClick(e) {
var url = new URL(window.location.href)
const par = url.searchParams.get('par')
const xhr = new XMLHttpRequest()
xhr.open('get', `get-data-ajax.php?par=${par}`)
xhr.addEventListener('load', function () { console.log(this.response) })
xhr.responseType = 'json'
xhr.send(null);
}
<?php
$par = $_GET['par'];
$data = [ 'data1' => $par, 'data2' => [1, 2, 3] ];
echo json_encode($data);
Unit tests, integration tests
include('./functions.php');
describe('Filtering positive numbers', function () {
it('returns an empty array to an empty array', function () {
expect(kivalogatas([]))->toBe([]);
});
it('returns positive to all positive arrays', function () {
expect(kivalogatas([1, 3, 5, 7]))->toBe([1, 3, 5, 7]);
});
});
DEMO
(The order of execution is arbitrary)
<?php
include('avengersrepository.php');
include('missionsrepository.php');
function dash_name($name) {
return str_replace(" ", "-", strtolower($name));
}
$avengersRepsoitory = new AvengersRepository();
$missionsRepsoitory = new MissionsRepository();
$avengers = $avengersRepsoitory->all();
?>
<?php foreach($avengers as $av) : ?>
<li class="list-group-item" data-id="<?= $av['_id'] ?>">
<div class="d-flex align-items-center p-1">
<span class="avenger <?= dash_name($av['name']) ?>"></span>
<h5 class="m-2 flex-fill">
<a href="card.php?id=<?= $av['_id'] ?>">
<?= $av['name'] ?>
</a>
<small class="text-muted">
<?= $av['real_name'] ?: '' ?>
<i class="fas <?= $av['terrial'] ? 'fa-globe-africa' : 'fa-rocket' ?>"></i>
</small>
</h5>
<div class="d-flex flex-nowrap">
<span class="mx-1 badge badge-primary"><?= $av['strength'] ?></span>
<span class="mx-1 badge badge-success"><?= $av['speed'] ?></span>
<span class="mx-1 badge badge-danger"><?= $av['durability'] ?></span>
</div>
</div>
<img src="http://webprogramozas.inf.elte.hu/webfejl2/zh/avengers/noise.png">
</li>
<?php endforeach ?>
<?php
include('avengersrepository.php');
function dash_name($name) {
return str_replace(" ", "-", strtolower($name));
}
$id = $_GET['id'];
$avengersRepsoitory = new AvengersRepository();
$avengers = $avengersRepsoitory->all();
$avenger = $avengers[$id];
?>
<div class="container">
<div class="row">
<div class="col-lg">
<h2>Avengers</h2>
<div class="card">
<div class="row no-gutters">
<div class="col-md-3">
<span class="card-img avenger <?= dash_name($avenger['name']) ?>" style="width: 180px; height: 240px;">
</div>
<div class="col-md-9">
<div class="card-body">
<h3 class="card-title"><?= $avenger["name"] ?></h3>
<dl class="row">
<dt class="col-sm-3">Real name</dt>
<dd class="col-sm-9">
<?= $avenger["real_name"] ?>
</dd>
<dt class="col-sm-3">Terrial</dt>
<dd class="col-sm-9">
<?= $avenger["terrial"] ? "Yes" : "No" ?>
</dd>
<dt class="col-sm-3">Strength</dt>
<dd class="col-sm-9">
<span class="badge badge-primary"><?= $avenger["strength"] ?></span>
</dd>
<dt class="col-sm-3">Speed</dt>
<dd class="col-sm-9">
<span class="badge badge-success"><?= $avenger["speed"] ?></span>
</dd>
<dt class="col-sm-3">Durability</dt>
<dd class="col-sm-9">
<span class="badge badge-danger"><?= $avenger["durability"] ?></span>
</dd>
</dl>
</div>
</div>
</div>
</div>
<a href="index.php" class="btn btn-primary">Back to the main page</a>
</div>
</div>
</div>
// 4/a
document.querySelector("form [type=range][name=strength] + *").innerHTML = document.querySelector("form [type=range][name=strength]").value
document.querySelector("form [type=range][name=speed] + *").innerHTML = document.querySelector("form [type=range][name=speed]").value
document.querySelector("form [type=range][name=durability] + *").innerHTML = document.querySelector("form [type=range][name=durability]").value
// 4/b
document.querySelector("form").addEventListener("input", onRangeInput);
function onRangeInput(e) {
if (e.target.matches("[type=range]")) {
const out = e.target.nextElementSibling;
out.innerHTML = e.target.value;
}
}
document.querySelector(".thanos").addEventListener("click", onStoneClick);
function onStoneClick(e) {
if (e.target.matches(".stone")) {
e.target.classList.add("collected")
}
}
document.querySelector(".thanos").addEventListener("click", onStoneClick);
function onStoneClick(e) {
if (e.target.matches(".stone")) {
const place = e.target.parentNode;
const {x, y} = place.getBoundingClientRect();
e.target.style.left = x + "px";
e.target.style.top = y + "px";
}
}
document.querySelector(".thanos").addEventListener("transitionend", onTransitionEnd)
function onTransitionEnd(e) {
if (e.target.matches(".stone")) {
const place = e.target.parentNode;
const {x, y} = place.getBoundingClientRect();
if (Math.abs(x - parseInt(e.target.style.left)) < 10 &&
Math.abs(y - parseInt(e.target.style.top)) < 10) {
e.target.classList.add("collected")
}
}
}
function onTransitionEnd(e) {
if (e.target.matches(".stone")) {
const place = e.target.parentNode;
const {x, y} = place.getBoundingClientRect();
if (Math.abs(x - parseInt(e.target.style.left)) < 10 &&
Math.abs(y - parseInt(e.target.style.top)) < 10) {
e.target.classList.add("collected")
}
if (checkGauntlet()) {
document.querySelector(".gauntlet").classList.add("activated")
}
}
}
function checkGauntlet(e) {
return Array.from(document.querySelectorAll(".stone")).every(st => st.classList.contains("collected"))
}