A Pen by Maurits van der Schee on CodePen.
Created
March 15, 2022 13:50
-
-
Save ivan131096/fbab9450439ae9aacdbe1603c45c3a2b to your computer and use it in GitHub Desktop.
Vue.js 2 CRUD application
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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"> | |
</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 2 CRUD application</h1> | |
<p>Ported from: <a href="https://codepen.io/-a/pen/amOYGp">Vue.js CRUD application</a></p> | |
</div> | |
</header> | |
<main id="app"> | |
<router-view></router-view> | |
</main> | |
</div> | |
<template id="product-list"> | |
<div> | |
<div class="actions"> | |
<router-link class="btn btn-default" v-bind:to="{path: '/add-product'}"> | |
<span class="glyphicon glyphicon-plus"></span> | |
Add product | |
</router-link> | |
</div> | |
<div class="filters row"> | |
<div class="form-group col-sm-3"> | |
<label for="search-element">Product name</label> | |
<input v-model="searchKey" class="form-control" id="search-element" requred/> | |
</div> | |
</div> | |
<table class="table"> | |
<thead> | |
<tr> | |
<th>Name</th> | |
<th>Description</th> | |
<th>Price</th> | |
<th class="col-sm-2">Actions</th> | |
</tr> | |
</thead> | |
<tbody> | |
<tr v-for="product in filteredProducts"> | |
<td> | |
<router-link v-bind:to="{name: 'product', params: {product_id: product.id}}">{{ product.name }}</router-link> | |
</td> | |
<td>{{ product.description }}</td> | |
<td> | |
{{ product.price }} | |
<span class="glyphicon glyphicon-euro" aria-hidden="true"></span> | |
</td> | |
<td> | |
<router-link class="btn btn-warning btn-xs" v-bind:to="{name: 'product-edit', params: {product_id: product.id}}">Edit</router-link> | |
<router-link class="btn btn-danger btn-xs" v-bind:to="{name: 'product-delete', params: {product_id: product.id}}">Delete</router-link> | |
</td> | |
</tr> | |
</tbody> | |
</table> | |
</div> | |
</template> | |
<template id="add-product"> | |
<div> | |
<h2>Add new product</h2> | |
<form v-on:submit="createProduct"> | |
<div class="form-group"> | |
<label for="add-name">Name</label> | |
<input class="form-control" id="add-name" v-model="product.name" required/> | |
</div> | |
<div class="form-group"> | |
<label for="add-description">Description</label> | |
<textarea class="form-control" id="add-description" rows="10" v-model="product.description"></textarea> | |
</div> | |
<div class="form-group"> | |
<label for="add-price">Price, <span class="glyphicon glyphicon-euro"></span></label> | |
<input type="number" class="form-control" id="add-price" v-model="product.price"/> | |
</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="product"> | |
<div> | |
<h2>{{ product.name }}</h2> | |
<b>Description: </b> | |
<div>{{ product.description }}</div> | |
<b>Price:</b> | |
<div>{{ product.price }}<span class="glyphicon glyphicon-euro"></span></div> | |
<br/> | |
<span class="glyphicon glyphicon-arrow-left" aria-hidden="true"></span> | |
<router-link v-bind:to="'/'">Back to product list</router-link> | |
</div> | |
</template> | |
<template id="product-edit"> | |
<div> | |
<h2>Edit product</h2> | |
<form v-on:submit="updateProduct"> | |
<div class="form-group"> | |
<label for="edit-name">Name</label> | |
<input class="form-control" id="edit-name" v-model="product.name" required/> | |
</div> | |
<div class="form-group"> | |
<label for="edit-description">Description</label> | |
<textarea class="form-control" id="edit-description" rows="3" v-model="product.description"></textarea> | |
</div> | |
<div class="form-group"> | |
<label for="edit-price">Price, <span class="glyphicon glyphicon-euro"></span></label> | |
<input type="number" class="form-control" id="edit-price" v-model="product.price"/> | |
</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="product-delete"> | |
<div> | |
<h2>Delete product {{ product.name }}</h2> | |
<form v-on:submit="deleteProduct"> | |
<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> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var products = [ | |
{id: 1, name: 'Angular', description: 'Superheroic JavaScript MVW Framework.', price: 100}, | |
{id: 2, name: 'Ember', description: 'A framework for creating ambitious web applications.', price: 100}, | |
{id: 3, name: 'React', description: 'A JavaScript Library for building user interfaces.', price: 100} | |
]; | |
function findProduct (productId) { | |
return products[findProductKey(productId)]; | |
}; | |
function findProductKey (productId) { | |
for (var key = 0; key < products.length; key++) { | |
if (products[key].id == productId) { | |
return key; | |
} | |
} | |
}; | |
var List = Vue.extend({ | |
template: '#product-list', | |
data: function () { | |
return {products: products, searchKey: ''}; | |
}, | |
computed: { | |
filteredProducts: function () { | |
return this.products.filter(function (product) { | |
return this.searchKey=='' || product.name.indexOf(this.searchKey) !== -1; | |
},this); | |
} | |
} | |
}); | |
var Product = Vue.extend({ | |
template: '#product', | |
data: function () { | |
return {product: findProduct(this.$route.params.product_id)}; | |
} | |
}); | |
var ProductEdit = Vue.extend({ | |
template: '#product-edit', | |
data: function () { | |
return {product: findProduct(this.$route.params.product_id)}; | |
}, | |
methods: { | |
updateProduct: function () { | |
var product = this.product; | |
products[findProductKey(product.id)] = { | |
id: product.id, | |
name: product.name, | |
description: product.description, | |
price: product.price | |
}; | |
router.push('/'); | |
} | |
} | |
}); | |
var ProductDelete = Vue.extend({ | |
template: '#product-delete', | |
data: function () { | |
return {product: findProduct(this.$route.params.product_id)}; | |
}, | |
methods: { | |
deleteProduct: function () { | |
products.splice(findProductKey(this.$route.params.product_id), 1); | |
router.push('/'); | |
} | |
} | |
}); | |
var AddProduct = Vue.extend({ | |
template: '#add-product', | |
data: function () { | |
return {product: {name: '', description: '', price: ''}} | |
}, | |
methods: { | |
createProduct: function() { | |
var product = this.product; | |
products.push({ | |
id: Math.random().toString().split('.')[1], | |
name: product.name, | |
description: product.description, | |
price: product.price | |
}); | |
router.push('/'); | |
} | |
} | |
}); | |
var router = new VueRouter({routes:[ | |
{ path: '/', component: List}, | |
{ path: '/product/:product_id', component: Product, name: 'product'}, | |
{ path: '/add-product', component: AddProduct}, | |
{ path: '/product/:product_id/edit', component: ProductEdit, name: 'product-edit'}, | |
{ path: '/product/:product_id/delete', component: ProductDelete, name: 'product-delete'} | |
]}); | |
app = new Vue({ | |
router:router | |
}).$mount('#app') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.logo { | |
width: 75px; | |
float: left; | |
margin-right: 15px; | |
} | |
.form-group { | |
max-width: 500px; | |
} | |
.actions { | |
padding: 10px 0; | |
} | |
.glyphicon-euro { | |
font-size: 12px; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" /> | |
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap-theme.min.css" rel="stylesheet" /> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment