Add client examples

This commit is contained in:
Maurits van der Schee 2018-09-02 09:16:08 +02:00
commit 3c81bc243d
10 changed files with 669 additions and 0 deletions

20
examples/client.html Normal file
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", "http://localhost/api.php/records/posts?join=categories,tags,comments&filter=id,eq,1", true);
xhttp.send();
</script>
</head>
<body>
<pre id="output"></pre>
</body>
</html>

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,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,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>

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>

250
examples/client_vue.html Normal file
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" requred/>
</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>

19
examples/index.html Normal file
View file

@ -0,0 +1,19 @@
<html>
<head>
<title>PHP-CRUD-API examples</title>
</head>
<body>
<h1>Examples</h1>
<h2>Clients</h2>
<ul>
<li><a href="/examples/client_angular.html">Angular</a></li>
<li><a href="/examples/client_angular2.html">Angular 2</a></li>
<li><a href="/examples/client_handlebars.html">Handlebars</a></li>
<li><a href="/examples/client_knockout.html">Knockout</a></li>
<li><a href="/examples/client_mustache.html">Mustache</a></li>
<li><a href="/examples/client_react.html">React</a></li>
<li><a href="/examples/client_vue.html">Vue</a></li>
<li><a href="/examples/client_zepto.html">Zepto</a></li>
</ul>
</body>
</html>