Merge commit '1392bd3a96045302b60d845a90901a4b2234c475' as 'seatmap-webapi'

This commit is contained in:
zino
2021-01-20 12:59:59 +01:00
261 changed files with 39680 additions and 0 deletions

View File

@@ -0,0 +1,24 @@
<html>
<head>
<script src= "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script>
var app = angular.module('myApplication', []);
app.controller('postController', function($scope, $http) {
var url = '/api.php/records/posts';
$http.post(url, {user_id: 1, category_id: 1, content: "from angular"}).success(function() {
$http.get(url).success(function(response) {
$scope.posts = response.records;
});
});
});
</script>
</head>
<body>
<div ng-app="myApplication" ng-controller="postController">
<ul>
<li ng-repeat="x in posts">{{ x.id + ', ' + x.content }}</li>
</ul>
</div>
</body>
</html>

View File

@@ -0,0 +1,31 @@
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/2.0.0-beta.14/angular2-polyfills.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/2.0.0-beta.14/Rx.umd.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/2.0.0-beta.14/angular2-all.umd.min.js"></script>
<script>
AppComponent =
ng.core.Component({
selector: 'my-app',
providers: [ng.http.HTTP_PROVIDERS],
template: '<ul><li *ngFor="#x of posts">{{ x.id + ", " + x.content }}</li></ul>'
})
.Class({
constructor: [
ng.http.Http, function(http) {
var url = "/api.php/records/posts";
http.post(url,JSON.stringify({user_id:1,category_id:1,content:"from angular2"})).subscribe();
http.get(url).map(res => res.json()).subscribe(res => this.posts = res.records);
}
]
});
document.addEventListener("DOMContentLoaded", function(event) {
ng.core.enableProdMode();
ng.platform.browser.bootstrap(AppComponent);
});
</script>
</head>
<body>
<my-app>Loading...</my-app>
</body>
</html>

View File

@@ -0,0 +1,33 @@
<html>
<head>
<meta charset="utf-8" />
<script>
var authUrl = 'auth.php'; // url of 'auth.php' from php-api-auth
var clientId = 'default'; // client id as defined in php-api-auth
var audience = 'api.php'; // api audience as defined in php-api-auth
window.onload = function () {
var match = RegExp('[#&]access_token=([^&]*)').exec(window.location.hash);
var accessToken = match && decodeURIComponent(match[1].replace(/\+/g, ' '));
if (!accessToken) {
document.location = authUrl+'?audience='+audience+'&response_type=token&client_id='+clientId+'&redirect_uri='+document.location.href;
} else {
document.location.hash = '';
var req = new XMLHttpRequest();
req.onreadystatechange = function () {
if (req.readyState==4) {
console.log(req.responseText);
document.getElementById('output').innerHTML = JSON.stringify(JSON.parse(req.responseText), undefined, 4);
}
}
url = 'api.php/records/posts?join=categories&join=tags&join=comments&filter=id,eq,1';
req.open("GET", url, true);
req.setRequestHeader('X-Authorization', 'Bearer '+accessToken);
req.send();
}
};
</script>
</head>
<body>
<pre id="output"></pre>
</body>
</html>

View File

@@ -0,0 +1,49 @@
<html>
<head>
<meta charset="utf-8" />
<script>
var authUrl = 'https://php-crud-api.auth0.com/authorize'; // url of auth0 '/authorize' end-point
var clientId = ''; // client id as defined in auth0
var audience = 'https://your-php-crud-api/api.php'; // api audience as defined in auth0
var url = '/api.php/records/posts?join=categories&join=tags&join=comments&filter=id,eq,1';
function requestAPI() {
var match = RegExp('[#&]access_token=([^&]*)').exec(window.location.hash);
var accessToken = match && decodeURIComponent(match[1].replace(/\+/g, ' '));
if (!accessToken) {
document.location = authUrl+'?audience='+audience+'&response_type=token&client_id='+clientId+'&redirect_uri='+document.location.href;
} else {
document.location.hash = '';
var req = new XMLHttpRequest();
req.onreadystatechange = function () {
if (req.readyState==4) {
console.log(req.responseText);
try {
document.getElementById('output').innerHTML = JSON.stringify(JSON.parse(req.responseText), undefined, 4);
} catch (error) {
document.getElementById('output').innerHTML = req.responseText;
}
}
}
req.open("GET", url, true);
req.setRequestHeader('X-Authorization', 'Bearer '+accessToken);
req.send();
}
};
window.onload = function() {
requestAPI()
document.getElementById('request-btn').onclick = function(e) {
e.preventDefault()
requestAPI()
}
}
</script>
</head>
<body>
<p>
<button type="button" id="request-btn">Request API</button>
</p>
<pre id="output"></pre>
</body>
</html>

View File

@@ -0,0 +1,45 @@
<html>
<head>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.20/css/jquery.dataTables.min.css"/>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/1.10.20/js/jquery.dataTables.min.js"></script>
<script>
$(document).ready(function() {
$('#example').DataTable( {
ajax: {
url: '/api.php/records/posts?join=categories&join=users',
dataSrc: 'records'
},
columns: [
{ data: "id" },
{ data: "user_id.username" },
{ data: "category_id.name" },
{ data: "content" }
]
});
});
</script>
</head>
<body>
<table id="example" class="display" style="width:100%">
<thead>
<tr>
<th>ID</th>
<th>Username</th>
<th>Category</th>
<th>Content</th>
</tr>
</thead>
<tfoot>
<tr>
<th>ID</th>
<th>Username</th>
<th>Category</th>
<th>Content</th>
</tr>
</tfoot>
</table>
</body>
</html>

View File

@@ -0,0 +1,97 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Success</title>
<script src="https://www.gstatic.com/firebasejs/6.0.2/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/6.0.2/firebase-auth.js"></script>
<script>
// Your web app's Firebase configuration
var firebaseConfig = {
apiKey: "",
authDomain: "",
databaseURL: "",
projectId: "",
storageBucket: "",
messagingSenderId: "",
appId: ""
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
</script>
<script>
var url = '/api.php/records/posts?join=categories&join=tags&join=comments&filter=id,eq,1';
function requestAPI(accessToken) {
var req = new XMLHttpRequest();
req.onreadystatechange = function () {
if (req.readyState == 4) {
try {
document.getElementById('output').innerHTML = JSON.stringify(JSON.parse(req.responseText),
undefined, 4);
} catch (error) {
document.getElementById('output').innerHTML = req.responseText;
}
}
}
req.open("GET", url, true);
req.setRequestHeader('X-Authorization', 'Bearer ' + accessToken);
req.send();
}
function initApp() {
firebase.auth().onAuthStateChanged(function (user) {
if (user) {
// User is signed in.
var displayName = user.displayName;
var email = user.email;
var emailVerified = user.emailVerified;
var photoURL = user.photoURL;
var uid = user.uid;
var phoneNumber = user.phoneNumber;
var providerData = user.providerData;
user.getIdToken().then(function (accessToken) {
document.getElementById('sign-in-status').textContent = 'Signed in';
document.getElementById('account-details').textContent = JSON.stringify({
displayName: displayName,
email: email,
emailVerified: emailVerified,
phoneNumber: phoneNumber,
photoURL: photoURL,
uid: uid,
accessToken: accessToken,
providerData: providerData
}, undefined, 4);
requestAPI(accessToken)
});
} else {
// User is signed out.
document.getElementById('sign-in-status').textContent = 'Signed out';
document.getElementById('account-details').textContent = 'null';
}
}, function (error) {
console.log(error);
});
};
window.addEventListener('load', initApp);
</script>
</head>
<body>
<h1>Firebase Login Success (or not)</h1>
<div id="sign-in-status"></div>
<pre id="account-details"></pre>
<pre id="output"></pre>
</body>
</html>

View File

@@ -0,0 +1,68 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>
Firebase
</title>
<!-- The core Firebase JS SDK is always required and must be listed first -->
<script src="https://www.gstatic.com/firebasejs/6.0.2/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/6.0.2/firebase-auth.js"></script>
<script>
// Your web app's Firebase configuration
var firebaseConfig = {
apiKey: "",
authDomain: "",
databaseURL: "",
projectId: "",
storageBucket: "",
messagingSenderId: "",
appId: ""
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
</script>
<script src="https://cdn.firebase.com/libs/firebaseui/4.0.0/firebaseui.js"></script>
<link type="text/css" rel="stylesheet" href="https://cdn.firebase.com/libs/firebaseui/4.0.0/firebaseui.css" />
<script type="text/javascript">
// FirebaseUI config.
var uiConfig = {
signInSuccessUrl: './vanilla-success.html',
signInOptions: [
// Leave the lines as is for the providers you want to offer your users.
firebase.auth.GoogleAuthProvider.PROVIDER_ID,
firebase.auth.FacebookAuthProvider.PROVIDER_ID,
firebase.auth.TwitterAuthProvider.PROVIDER_ID,
firebase.auth.GithubAuthProvider.PROVIDER_ID,
firebase.auth.EmailAuthProvider.PROVIDER_ID,
firebase.auth.PhoneAuthProvider.PROVIDER_ID,
firebaseui.auth.AnonymousAuthProvider.PROVIDER_ID
],
// tosUrl and privacyPolicyUrl accept either url string or a callback
// function.
// Terms of service url/callback.
tosUrl: '<your-tos-url>',
// Privacy policy url/callback.
privacyPolicyUrl: function() {
window.location.assign('<your-privacy-policy-url>');
}
};
// Initialize the FirebaseUI Widget using Firebase.
var ui = new firebaseui.auth.AuthUI(firebase.auth());
// The start method will wait until the DOM is loaded.
ui.start('#firebaseui-auth-container', uiConfig);
</script>
</head>
<body>
<h1>Firebase login</h1>
<div id="firebaseui-auth-container"></div>
</body>
</html>

View File

@@ -0,0 +1,66 @@
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.5/handlebars.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/zepto/1.1.6/zepto.min.js"></script>
<script id="PostListTemplate" type="text/mustache">
<ul>
{{#records}}
<li>
<span class="id">{{id}}</span>, <span class="content">{{content}}</span>
<a href="javascript:void(0)" class="edit">edit</a>
<a href="javascript:void(0)" class="delete">del</a>
</li>
{{/records}}
<li>
<form>
<input name="content"/>
</form>
</li>
</ul>
</script>
<script>
function PostList(element, template) {
var self = this;
var url = '/api.php/records/posts';
self.edit = function() {
var li = $(this).parent('li');
var id = li.find('span.id').text();
var content = li.find('span.content').text();
content = prompt('Value',content);
if (content!==null) {
$.ajax({url:url+'/'+id, type: 'PUT', data: {content:content}, success:self.update});
}
};
self.delete = function() {
var li = $(this).parent('li');
var id = li.find('span.id').text();
if (confirm("Deleting #"+id+". Continue?")) {
$.ajax({url:url+'/'+id, type: 'DELETE', success:self.update});
}
};
self.submit = function(e) {
e.preventDefault();
var content = $(this).find('input[name="content"]').val();
$.post(url, {user_id:1,category_id:1,content:content}, self.update);
};
self.render = function(data) {
element.html(Handlebars.compile(template.html())(data));
};
self.update = function() {
$.get(url, self.render);
};
self.post = function() {
$.post(url, {user_id:1,category_id:1,content:"from handlebars"}, self.update);
};
element.on('submit','form',self.submit);
element.on('click','a.edit',self.edit)
element.on('click','a.delete',self.delete)
self.post();
};
$(function(){ new PostList($('#PostListDiv'),$('#PostListTemplate')); });
</script>
</head>
<body>
<div id="PostListDiv">Loading...</div>
</body>
</html>

View File

@@ -0,0 +1,70 @@
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/zepto/1.1.6/zepto.min.js"></script>
<script id="posts-template" type="text/html">
<ul>
<!-- ko foreach: posts -->
<li>
<span data-bind="text: id"></span>, <span data-bind="text: content"></span>
<a href="javascript:void(0)" data-bind="click: $parent.edit">edit</a>
<a href="javascript:void(0)" data-bind="click: $parent.delete">del</a>
</li>
<!-- /ko -->
<li>
<form data-bind="submit: submit">
<input name="content" data-bind="value: form"/>
</form>
</li>
</ul>
</script>
<script>
var url = '/api.php/records/posts';
function Post(id,content){
var self = this;
self.id = ko.observable(id);
self.content = ko.observable(content);
}
function PostList(){
var self = this;
self.posts = ko.observableArray([]);
self.form = ko.observable('');
self.bound = false;
self.edit = function(post) {
var content = prompt('Value',post.content());
if (content!==null) {
$.ajax({url:url+'/'+post.id(), type: 'PUT', data: {content:content}, success:self.update});
}
};
self.delete = function(post) {
if (confirm("Deleting #"+post.id()+". Continue?")) {
$.ajax({url:url+'/'+post.id(), type: 'DELETE', success:self.update});
}
};
self.submit = function(form) {
$.post(url, {user_id:1,category_id:1,content:self.form()}, self.update);
};
self.render = function(data) {
var array = data.records;
self.posts.removeAll();
for (i=0;i<array.length;i++) {
self.posts.push(new Post(array[i].id,array[i].content));
}
self.form('');
if (!self.bound){ ko.applyBindings(self); self.bound = true; }
};
self.update = function() {
$.get(url, self.render);
};
self.post = function() {
$.post(url, {user_id:1,category_id:1,content:"from knockout"}, self.update);
}
self.post();
};
$(function(){ new PostList(); });
</script>
</head>
<body>
<div data-bind="template: { name: 'posts-template'}">Loading...</div>
</body>
</html>

View File

@@ -0,0 +1,85 @@
/* global L */
(function() {
L.GeoJSONLayer = L.GeoJSON.extend({
includes: L.Evented.prototype,
url: null,
map: null,
//
// Leaflet layer methods
//
initialize(url, options) {
this.url = url;
L.GeoJSON.prototype.initialize.call(this, [], options);
},
onAdd(map) {
L.GeoJSON.prototype.onAdd.call(this, map);
this.map = map;
map.on('moveend zoomend refresh', this._reloadMap, this);
this._reloadMap();
},
onRemove(map) {
map.off('moveend zoomend refresh', this._reloadMap, this);
this.map = null;
L.GeoJSON.prototype.onRemove.call(this, map);
},
//
// Custom methods
//
_reloadMap: function() {
if (this.map) {
var url = this._expandUrl(this.url);
this._ajaxRequest('GET', url, false, this._updateLayers.bind(this));
}
},
_expandUrl: function(template) {
var bbox = this.map.getBounds();
var southWest = bbox.getSouthWest();
var northEast = bbox.getNorthEast();
var bboxStr = bbox.toBBoxString();
var coords = {
lat1: southWest.lat,
lon1: southWest.lng,
lat2: northEast.lat,
lon2: northEast.lng,
bbox: bboxStr
};
return L.Util.template(template, coords);
},
_ajaxRequest: function(method, url, data, callback) {
var request = new XMLHttpRequest();
request.open(method, url, true);
request.onreadystatechange = function() {
if (request.readyState === 4 && request.status === 200) {
callback(JSON.parse(request.responseText));
}
};
if (data) {
request.setRequestHeader('Content-type', 'application/json');
request.send(JSON.stringify(data));
} else {
request.send();
}
return request;
},
_updateLayers: function(geoData) {
this.clearLayers();
this.addData(geoData);
}
});
L.geoJSONLayer = function (url, options) {
return new L.GeoJSONLayer(url, options);
};
})();

View File

@@ -0,0 +1,144 @@
/* global L */
(function() {
L.GeoJSONTileLayer = L.GridLayer.extend({
includes: L.Evented.prototype,
url: null,
map: null,
layer: null,
features: null,
cache: null,
//
// Leaflet layer methods
//
initialize(url, options) {
this.url = url;
this.layer = new L.GeoJSON(null, options);
this.features = {};
this.cache = {};
L.GridLayer.prototype.initialize.call(this, options);
},
createTile(coords, done) {
var tile = L.DomUtil.create('div', 'leaflet-tile');
tile.style['box-shadow'] = 'inset 0 0 2px #f00';
var url = this._expandUrl(this.url, coords);
if (this.cache[coords]) {
done.call(this);
} else {
this._ajaxRequest('GET', url, false, this._updateCache.bind(this, done, coords));
}
return tile;
},
onAdd(map) {
L.GridLayer.prototype.onAdd.call(this, map);
map.addLayer(this.layer);
this.map = map;
map.on('zoomanim', this._onZoomAnim.bind(this));
this.on('loading', this._onLoading.bind(this));
this.on('tileload', this._onTileLoad.bind(this));
this.on('tileunload', this._onTileUnLoad.bind(this));
},
onRemove(map) {
this.off('tileunload', this._onTileUnLoad.bind(this));
this.off('tileload', this._onTileLoad.bind(this));
this.off('loading', this._onLoading.bind(this));
map.off('zoomanim', this._onZoomAnim.bind(this));
this.map = null;
map.removeLayer(this.layer)
L.GridLayer.prototype.onRemove.call(this, map);
},
//
// Custom methods
//
_expandUrl: function(template, coords) {
return L.Util.template(template, coords);
},
_updateTiles: function() {
this.layer.clearLayers();
this.features = {};
for (var coords in this.cache) {
if (this.cache.hasOwnProperty(coords)) {
this._drawTile(coords);
}
}
},
_drawTile(coords) {
var geoData = this.cache[coords];
if (geoData.type == 'FeatureCollection'){
geoData = geoData.features;
}
for (var i=0;i<geoData.length;i++) {
var id = geoData[i].id;
if (!this.features[id]) {
this.layer.addData(geoData[i]);
this.features[id] = true;
}
}
if (!this.cache[coords]) {
this.cache[coords] = geoData;
}
},
_updateCache: function(done, coords, geoData) {
this.cache[coords] = geoData;
done.call(this);
},
_ajaxRequest: function(method, url, data, callback) {
var request = new XMLHttpRequest();
request.open(method, url, true);
request.onreadystatechange = function() {
if (request.readyState === 4 && request.status === 200) {
callback(JSON.parse(request.responseText));
}
};
if (data) {
request.setRequestHeader('Content-type', 'application/json');
request.send(JSON.stringify(data));
} else {
request.send();
}
return request;
},
_onZoomAnim: function (e) {
var zoom = e.zoom;
if ((this.options.maxZoom && zoom > this.options.maxZoom) ||
(this.options.minZoom && zoom < this.options.minZoom)) {
this.map.removeLayer(this.layer);
this.cache = {};
this.layer.clearLayers();
} else {
this._updateTiles();
this.map.addLayer(this.layer);
}
},
_onLoading: function (e) {
this._updateTiles();
},
_onTileLoad: function (e) {
this._drawTile(e.coords);
},
_onTileUnLoad: function (e) {
delete this.cache[e.coords]
},
});
L.geoJSONTileLayer = function (url, options) {
return new L.GeoJSONTileLayer(url, options);
};
})();

View File

@@ -0,0 +1,37 @@
<!DOCTYPE html>
<html>
<head>
<title>Quick Start - Leaflet</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" type="image/x-icon" href="docs/images/favicon.ico" />
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.5.1/dist/leaflet.css"/>
<script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js"></script>
<script src="geojson-layer.js"></script>
<script src="geojson-tile-layer.js"></script>
</head>
<body>
<div id="mapid" style="width: 600px; height: 400px;"></div>
<script>
var mymap = L.map('mapid').setView([20, 30], 3);
L.tileLayer('https://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}', {
maxZoom: 18,
}).addTo(mymap);
L.geoJSONLayer('http://localhost:8000/api.php/geojson/users?bbox={bbox}', {
maxZoom: 18,
}).addTo(mymap);
L.geoJSONTileLayer('http://localhost:8000/src/geojson/countries?filter=id,lt,3&tile={z},{x},{y}', {
minZoom: 3,
maxZoom: 18,
}).addTo(mymap);
</script>
</body>
</html>

View File

@@ -0,0 +1,66 @@
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mustache.js/2.2.1/mustache.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/zepto/1.1.6/zepto.min.js"></script>
<script id="PostListTemplate" type="text/mustache">
<ul>
{{#records}}
<li>
<span class="id">{{id}}</span>, <span class="content">{{content}}</span>
<a href="javascript:void(0)" class="edit">edit</a>
<a href="javascript:void(0)" class="delete">del</a>
</li>
{{/records}}
<li>
<form>
<input name="content"/>
</form>
</li>
</ul>
</script>
<script>
function PostList(element, template) {
var self = this;
var url = '/api.php/records/posts';
self.edit = function() {
var li = $(this).parent('li');
var id = li.find('span.id').text();
var content = li.find('span.content').text();
content = prompt('Value',content);
if (content!==null) {
$.ajax({url:url+'/'+id, type: 'PUT', data: {content:content}, success:self.update});
}
};
self.delete = function() {
var li = $(this).parent('li');
var id = li.find('span.id').text();
if (confirm("Deleting #"+id+". Continue?")) {
$.ajax({url:url+'/'+id, type: 'DELETE', success:self.update});
}
};
self.submit = function(e) {
e.preventDefault();
var content = $(this).find('input[name="content"]').val();
$.post(url, {user_id:1,category_id:1,content:content}, self.update);
};
self.render = function(data) {
element.html(Mustache.to_html(template.html(),data));
};
self.update = function() {
$.get(url, self.render);
};
self.post = function() {
$.post(url, {user_id:1,category_id:1,content:"from mustache"}, self.update);
};
element.on('submit','form',self.submit);
element.on('click','a.edit',self.edit)
element.on('click','a.delete',self.delete)
self.post();
};
$(function(){ new PostList($('#PostListDiv'),$('#PostListTemplate')); });
</script>
</head>
<body>
<div id="PostListDiv">Loading...</div>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 KiB

View File

@@ -0,0 +1,47 @@
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/zepto/1.1.6/zepto.min.js"></script>
<script>
var PostList = React.createClass({
displayName: 'PostList',
url: '/api.php/records/posts',
getInitialState: function() {
return { records: [] };
},
retrieveServerState: function() {
this.serverRequest = $.get(this.url, function (data) {
this.setState(data);
}.bind(this));
},
componentDidMount: function() {
$.post(this.url, {user_id:1,category_id:1,content:"from react"}, this.retrieveServerState);
},
componentWillUnmount: function() {
this.serverRequest.abort();
},
render: function render() {
var createPost = function(post) {
return React.createElement(
'li',
{key: post.id},
post.id,
', ',
post.content
);
};
return React.createElement(
'ul',
null,
this.state.records.map(createPost)
);
}
});
$(function(){ ReactDOM.render(React.createElement(PostList, null), document.getElementById('myApplication')); });
</script>
</head>
<body>
<div id="myApplication">Loading...</div>
</body>
</html>

View File

@@ -0,0 +1,73 @@
<html>
<head>
<meta charset="utf-8" />
<script>
if (!window.File || !window.FileReader || !window.FileList || !window.Blob) {
alert("Your browser is too old to support HTML5 File API");
}
function showImagePreview() {
var demoImage = document.querySelector('img#preview');
var file = document.querySelector('input[type=file]').files[0];
var reader = new FileReader();
reader.onload = function (event) {
console.log(reader.result)
demoImage.src = reader.result;
}
console.log(file)
reader.readAsDataURL(file);
}
function uploadImageFile() {
var demoImage = document.querySelector('img#preview');
var req = new XMLHttpRequest();
req.onreadystatechange = function () {
if (req.readyState==4) {
console.log(req.responseText);
listImageFiles();
}
}
url = '/api.php/records/categories';
req.open("POST", url);
var icon = demoImage.src.split(";")[1].split(",")[1];
req.send(JSON.stringify({"name":"upload","icon":icon}));
}
function listImageFiles() {
var ul = document.querySelector('ul');
var req = new XMLHttpRequest();
req.onreadystatechange = function () {
if (req.readyState==4) {
console.log(req.responseText);
output.innerHTML = "";
var categories = JSON.parse(req.responseText).records;
for (var i=0;i<categories.length;i++) {
var li = document.createElement('li');
var img = document.createElement('img');
var span = document.createElement('span');
img.style = 'height:2em;margin:0 .5em;';
img.src = "data:image/png;base64," + categories[i].icon;
span.innerHTML = categories[i].name;
li.appendChild(img);
li.appendChild(span);
ul.appendChild(li);
}
}
}
url = '/api.php/records/categories';
req.open("GET", url);
req.send();
}
</script>
</head>
<body onload="listImageFiles()">
<ul id="output"></ul>
<hr>
<form onsubmit="uploadImageFile(); return false;">
<img src="" id="preview" style="height:2em;margin:0 .5em;" alt="PNG preview..."><br><br>
<input type="file" onchange="showImagePreview()" accept="image/png"><br><br>
<input type="submit" value="Upload PNG">
</form>
</body>
</html>

View File

@@ -0,0 +1,20 @@
<html>
<head>
<script>
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
console.log(this.responseText);
jsonObject = JSON.parse(this.responseText);
document.getElementById('output').innerHTML = JSON.stringify(jsonObject, undefined, 4);
}
};
xhttp.open("GET", "/api.php/records/posts?join=categories&join=tags&join=comments&filter=id,eq,1", true);
xhttp.send();
</script>
</head>
<body>
<pre id="output"></pre>
</body>
</html>

View File

@@ -0,0 +1,250 @@
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>Vue.js CRUD application</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-router/2.2.1/vue-router.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.15.3/axios.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap-theme.min.css">
<style>
.logo {
width: 50px;
float: left;
margin-right: 15px;
}
.form-group {
max-width: 500px;
}
.actions {
padding: 10px 0;
}
.glyphicon-euro {
font-size: 12px;
}
</style>
</head>
<body>
<div class="container">
<header class="page-header">
<div class="branding">
<img src="https://vuejs.org/images/logo.png" alt="Logo" title="Home page" class="logo"/>
<h1>Vue.js CRUD application</h1>
</div>
</header>
<main id="app">
<router-view></router-view>
</main>
</div>
<template id="post-list">
<div>
<div class="actions">
<router-link class="btn btn-default" v-bind:to="{path: '/add-post'}">
<span class="glyphicon glyphicon-plus"></span>
Add post
</router-link>
</div>
<div class="filters row">
<div class="form-group col-sm-3">
<label for="search-element">Filter</label>
<input v-model="searchKey" class="form-control" id="search-element" required/>
</div>
</div>
<table class="table">
<thead>
<tr>
<th>Content</th>
<th class="col-sm-2">Actions</th>
</tr>
</thead>
<tbody>
<tr v-if="posts===null">
<td colspan="4">Loading...</td>
</tr>
<tr v-else v-for="post in filteredposts">
<td>
<router-link v-bind:to="{name: 'post', params: {post_id: post.id}}">{{ post.content }}</router-link>
</td>
<td>
<router-link class="btn btn-warning btn-xs" v-bind:to="{name: 'post-edit', params: {post_id: post.id}}">Edit</router-link>
<router-link class="btn btn-danger btn-xs" v-bind:to="{name: 'post-delete', params: {post_id: post.id}}">Delete</router-link>
</td>
</tr>
</tbody>
</table>
</div>
</template>
<template id="add-post">
<div>
<h2>Add new post</h2>
<form v-on:submit="createpost">
<div class="form-group">
<label for="add-content">Content</label>
<textarea class="form-control" id="add-content" rows="10" v-model="post.content"></textarea>
</div>
<button type="submit" class="btn btn-primary">Create</button>
<router-link class="btn btn-default" v-bind:to="'/'">Cancel</router-link>
</form>
</div>
</template>
<template id="post">
<div>
<b>Content: </b>
<div>{{ post.content }}</div>
<br/>
<span class="glyphicon glyphicon-arrow-left" aria-hidden="true"></span>
<router-link v-bind:to="'/'">Back to post list</router-link>
</div>
</template>
<template id="post-edit">
<div>
<h2>Edit post</h2>
<form v-on:submit="updatepost">
<div class="form-group">
<label for="edit-content">Content</label>
<textarea class="form-control" id="edit-content" rows="3" v-model="post.content"></textarea>
</div>
<button type="submit" class="btn btn-primary">Save</button>
<router-link class="btn btn-default" v-bind:to="'/'">Cancel</router-link>
</form>
</div>
</template>
<template id="post-delete">
<div>
<h2>Delete post {{ post.id }}</h2>
<form v-on:submit="deletepost">
<p>The action cannot be undone.</p>
<button type="submit" class="btn btn-danger">Delete</button>
<router-link class="btn btn-default" v-bind:to="'/'">Cancel</router-link>
</form>
</div>
</template>
<script>
var posts = null;
var api = axios.create({
baseURL: '/api.php/records'
});
function findpost (postId) {
return posts[findpostKey(postId)];
};
function findpostKey (postId) {
for (var key = 0; key < posts.length; key++) {
if (posts[key].id == postId) {
return key;
}
}
};
var List = Vue.extend({
template: '#post-list',
data: function () {
return {posts: posts, searchKey: ''};
},
created: function () {
var self = this;
api.get('/posts').then(function (response) {
posts = self.posts = response.data.records;
}).catch(function (error) {
console.log(error);
});
},
computed: {
filteredposts: function () {
return this.posts.filter(function (post) {
return this.searchKey=='' || post.content.indexOf(this.searchKey) !== -1;
},this);
}
}
});
var post = Vue.extend({
template: '#post',
data: function () {
return {post: findpost(this.$route.params.post_id)};
}
});
var postEdit = Vue.extend({
template: '#post-edit',
data: function () {
return {post: findpost(this.$route.params.post_id)};
},
methods: {
updatepost: function () {
var post = this.post;
api.put('/posts/'+post.id,post).then(function (response) {
console.log(response.data);
}).catch(function (error) {
console.log(error);
});
router.push('/');
}
}
});
var postDelete = Vue.extend({
template: '#post-delete',
data: function () {
return {post: findpost(this.$route.params.post_id)};
},
methods: {
deletepost: function () {
var post = this.post;
api.delete('/posts/'+post.id).then(function (response) {
console.log(response.data);
}).catch(function (error) {
console.log(error);
});
router.push('/');
}
}
});
var Addpost = Vue.extend({
template: '#add-post',
data: function () {
return {post: {content: '', user_id: 1, category_id: 1}}
},
methods: {
createpost: function() {
var post = this.post;
api.post('/posts',post).then(function (response) {
post.id = response.data;
}).catch(function (error) {
console.log(error);
});
router.push('/');
}
}
});
var router = new VueRouter({routes:[
{ path: '/', component: List},
{ path: '/post/:post_id', component: post, name: 'post'},
{ path: '/add-post', component: Addpost},
{ path: '/post/:post_id/edit', component: postEdit, name: 'post-edit'},
{ path: '/post/:post_id/delete', component: postDelete, name: 'post-delete'}
]});
app = new Vue({
router:router
}).$mount('#app')
</script>
</body>
</html>

View File

@@ -0,0 +1,76 @@
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/zepto/1.1.6/zepto.min.js"></script>
<script id="PostListTemplate" type="text/html">
<ul>
<li>
<span class="id"></span>, <span class="content"></span>
<a href="javascript:void(0)" class="edit">edit</a>
<a href="javascript:void(0)" class="delete">del</a>
</li>
<li>
<form>
<input name="content"/>
</form>
</li>
</ul>
</script>
<script>
function PostList(element,template) {
var self = this;
var url = '/api.php/records/posts';
self.edit = function() {
var li = $(this).parent('li');
var id = li.find('span.id').text();
var content = li.find('span.content').text();
content = prompt('Value', content);
if (content!==null) {
$.ajax({url: url + '/' + id, type: 'PUT', data: {content: content}, success: self.update});
}
};
self.delete = function() {
var li = $(this).parent('li');
var id = li.find('span.id').text();
if (confirm("Deleting #" + id + ". Continue?")) {
$.ajax({url: url + '/' + id, type: 'DELETE', success: self.update});
}
};
self.submit = function(e) {
e.preventDefault();
var content = $(this).find('input[name="content"]').val();
$.post(url, {user_id: 1, category_id: 1, content: content}, self.update);
};
self.render = function(data) {
data = data;
element.html(template.html());
var item = element.find('li').first().remove();
for (var i=0;i<data.records.length; i++) {
var clone = item.clone();
clone.find('span').each(function(){
var field = $(this).attr("class");
$(this).text(data.records[i][field]);
});
clone.insertBefore(element.find('li').last());
}
};
self.update = function() {
$.get(url, self.render);
};
self.post = function() {
$.post(url, {user_id: 1, category_id: 1, content: "from zepto"}, self.update);
};
element.on('submit', 'form', self.submit);
element.on('click', 'a.edit', self.edit);
element.on('click', 'a.delete', self.delete);
self.post();
};
$(function(){
new PostList($('#PostListDiv'), $('#PostListTemplate'));
});
</script>
</head>
<body>
<div id="PostListDiv">Loading...</div>
</body>
</html>