I'm trying to post a new object to my api array using axios and Vue.js. I'm trying to add the functionality to add a new object and display it on the timeline. I can see that when I post a new title I get a console.log of the object but it is not added to the correct array from the api, there is no new id associated with the new object.
Index.html
<body>
<div id="app">
<template>
<form #submit.prevent>
<input type="text" v-model="postBody"/>
<button type="button" class="btn btn-primary pull-right" data-toggle="modal" #click="postPost()">Post Title</button>
</form>
<ul v-if="errors && errors.length">
<li v-for="error of errors">
{{error.message}}
</li>
</ul>
</template>
<br>
<!-- <p>{{ status }}</p> -->
<template v-for="(results, index) in result">
<div class="card" style="width: 20rem; display:inline-block;">
<div class="card-block">
<p>{{ results.id }}</p>
<p>{{ results.title }}</p>
<!-- <button type="button" class="btn btn-danger pull-right" data-toggle="modal" v-on:submit.prevent="deleteData(index)" #click="deleteData(results, index) in result">Delete</button> -->
<button type="button" class="btn btn-danger pull-right" data-toggle="modal" #click="deleteData(results, index)">Delete</button>
<h1> {{ results.comments}} </h1>
</div>
</div>
</template>
</div>
</body>
Main.js
var vm = new Vue ({
el: '#app',
data: {
result: '',
title: '',
data: '',
postBody: '',
User: { title: '' },
errors: []
},
created: function(){
this.getResult();
},
methods: {
getResult: function() {
// this.results = 'Loading...';
axios.get('https://my-json-server.typicode.com/shaneogrady/json/db')
.then(response => {
// console.log(response.data);
this.result = response.data.posts;
console.log(this.result);
});
},
deleteData: function(result, id) {
axios.delete('https://my-json-server.typicode.com/shaneogrady/json/posts/' + result.id)
.then(response => {
this.result.splice(id, 1)
console.log(this.result);
});
},
postPost() {
axios.post('https://my-json-server.typicode.com/shaneogrady/json/posts/', {
// id: 4,
// title: 'Shane',
body: this.postBody
})
.then(response => { console.log(response.data); this.result.push(response.data) })
.catch(e => {
this.errors.push(e)
})
}
}
});
Try adding #submit.prevent on the form element
<div id="app">
<form #submit.prevent>
<h4> Add Title</h4>
<div class="form-group">
<label class="pull-left"> Title </label>
<input type="text" class="form-control" placeholder="Title " v-model="User.title">
</div>
<button type="submit" class="btn btn-large btn-block btn-primary" #click="postPost">Submit</button>
</form>
...
if u need to get results after creation of new object u just need to call ur getResult function inside postPost function
like this :
postPost() {
axios.post('https://my-json-server.typicode.com/shaneogrady/json/posts/', {
// id: 4,
// title: 'Shane',
body: this.postBody
})
.then(response => {
this.getResult();
console.log(response.data);
})
.catch(e => {
this.errors.push(e)
})
Related
I am trying to hide a modal after submitting a form. I am using bootstrap 5, vue 2 and django 3.2. I am a beginner in javascript and vue.
I can asynchronously submit the form with fetch and clear the fields, but I can't close the modal.
I report part of my code (bootstrap and vue only) which unfortunately does not provide a minimum reproducible example, but I hope it is sufficient.
The html template is:
<div style="margin-right: 230px" id="app">
<h4 style="text-align:left;float:left;">User Managment</h4>
<a
href="#"
data-bs-toggle="modal"
data-bs-target="#add_userModal"
class="btn btn-sm btn-outline-primary px-4"
style="text-align:right; float:right;">
Add
</a>
<hr style="clear:both; border-top: 1px solid grey;"/>
<table class="table" id="userTable">
<thead>
<tr>
<th class="col-md-4">First name</th>
<th class="col-md-8">Last name</th>
</tr>
</thead>
<tbody>
<tr v-for="userdb in usersdb">
<td>{% verbatim %}{{ userdb.first_name }}{% endverbatim %}</td>
<td>{% verbatim %}{{ userdb.last_name }}{% endverbatim %}</td>
</tr>
</tbody>
</table>
<div class="modal fade" id="add_userModal" tabindex="-1" aria-labelledby="add_userModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="staticBackdropLabel">Utente</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<form #submit.prevent="createUserdb">
<div class="modal-body">
<div class="form-group mb-3">
<label>First name*</label>
<input
type="text"
class="form-control"
id="first_name"
v-model="userdb.first_name"
required>
</div>
<div class="form-group mb-3">
<label>Last name*</label>
<input
type="text"
class="form-control"
id="last_name"
v-model="userdb.last_name"
required>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-sm btn-outline-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-sm btn-outline-primary">Add</button>
</div>
</form>
</div>
</div>
</div>
</div>
The javascript code is
var app = new Vue({
el: '#app',
data: {
csrf: null,
userdb: {
first_name: '',
last_name: '',
full_name: ''},
usersdb: []
},
methods: {
async sendRequest(url, method, data) {
var myHeaders = new Headers({
'Content-Type': 'application/json',
'X-Requested-With': 'XMLHttpRequest'
})
if (method !== 'get') {
myHeaders.set('X-CSRFToken', await this.getCsrfToken())
};
var response = await fetch(url, {
method: method,
headers: myHeaders,
body: data
});
return response
},
async getCsrfToken() {
if (this.csrf === null) {
var response = await this.sendRequest(mainUrl + 'csrf', 'get')
var data = await response.json();
this.csrf = data.csrf_token;
};
return this.csrf;
},
async getUserdb() {
var response = await this.sendRequest(mainUrl, 'get');
this.usersdb = await response.json();
},
async createUserdb() {
await this.getUserdb();
await this.sendRequest(mainUrl, 'post', JSON.stringify(this.userdb));
this.userdb.first_name = '';
this.userdb.last_name = '';
await this.getUserdb();
}
},
async created() {
await this.getUserdb();
}
})
I made many attempts to add code in createUserdb, but without success. For example
document.getElementById("add_userModal").hide();
How can I hide the modal after submitting the form?
Any help is truly appreciated
You'll want to entirely manage the Bootstrap modal instance in the Vue app...
1 - First, add a new data var for the modal..
data: {
csrf: null,
userdb: {
first_name: '',
last_name: '',
full_name: ''},
usersdb: [],
myModal: null
},
2 - And a new method (ie: showModal()) to get an instance of the Bootstrap.modal and show it...
showModal(){
this.myModal = new bootstrap.Modal(document.getElementById('add_userModal'), {})
this.myModal.show()
},
3 - Bind the new method to #click handler to show the modal (instead of using data-bs attributes)...
<a
#click="showModal()"
class="btn btn-sm btn-outline-primary px-4"
style="text-align:right; float:right;">
Add
</a>
4 - Finally, call the hide() method after the async processing...
async createUserdb() {
await this.getUserdb();
await this.sendRequest(mainUrl, 'post', JSON.stringify(this.userdb));
this.userdb.first_name = '';
this.userdb.last_name = '';
this.myModal.hide()
}
Demo
I'm learning vue. js .I'm trying to make simple form by using vue.js but I got above error while making a form. I tried but unable to fix the problem.
Please help me.
<div id="app">
<form name="form" #submit.prevent="handleLogin">
<input
v-model="fiscal_year"
v-validate="'required'"
type="text"
class="form-control"
name="fiscal_year"
/>
<button class="btn btn-primary btn-block" :disabled="loading">
<span v-show="loading" class="spinner-border spinner-border-sm"></span>
<span>Submit</span>
</button>
</form>
<script>
var app = new Vue({
el: '#app',
data: {
fiscal_year: 2000,
loading: false,
},
mount:function(){},
methods: {
handleLogin(){
console.log('handle login');
this.loading = true;
}
}
})
</script>
UPDATE
If you are using cli-vue : https://cli.vuejs.org/
Assume you put file in App.vue :
<template>
<div id="app">
<h1>hello</h1>
<form name="form" #submit.prevent="handleLogin">
<input v-model="fiscal_year" type="text" class="form-control" name="fiscal_year">
<button class="btn btn-primary btn-block" :disabled="loading">
<span v-show="loading" class="spinner-border spinner-border-sm"></span>
<span>Submit</span>
</button>
</form>
</div>
</template>
<script>
export default {
data() {
return {
fiscal_year: 2000,
loading: false
};
},
methods: {
handleLogin() {
console.log("handle login");
this.loading = true;
}
}
};
</script>
Dont use jquery in Vue project. If you want to use bootstrap you can use bootsrap-vue : https://bootstrap-vue.js.org/
But if you are using vue in html use this : https://v2.vuejs.org/v2/guide/
-- Previous --
First, have you read vuejs introduction in https://v2.vuejs.org/v2/guide/ and Vue Lesson on Scrimba ?
About the question. <template> are used in component. You can replace it to <div id="app"> :
<div id="app"> <!-- Replace <template> with <div> -->
<div class="col-md-12">
<form name="form" #submit.prevent="handleLogin">
<div class="form-group col-md-6">
<label for="fiscal_year">Fiscal Year</label>
<input
v-model="fiscal_year"
v-validate="'required'"
type="text"
class="form-control"
name="fiscal_year"
/>
</div>
<div class="form-group">
<button class="btn btn-primary btn-block" :disabled="loading">
<span v-show="loading" class="spinner-border spinner-border-sm"></span>
<span>Submit</span>
</button>
</div>
</form>
</div>
</div>
Then you create vue instance in the <script> tag :
var app = new Vue({
el: '#app',
data: {
fiscal_year: 2000,
loading: false,
},
methods: {
handleLogin(){
console.log('handle login');
this.loading = true;
}
}
In the script of your component or vue instance try to add fiscal_year :
export default{
...
data(){
return{
fiscal_year:null,
....
}
}
....
}
or in a Vue instance :
new Vue ({
el:"#app",
data(){
return{
fiscal_year:null,
....
}
}
...
})
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<div id="app">
<form name="form" #submit.prevent="handleLogin">
<input
v-model="fiscal_year"
v-validate="'required'"
type="text"
class="form-control"
name="fiscal_year"
/>
<button class="btn btn-primary btn-block" :disabled="loading">
<span v-show="loading" class="spinner-border spinner-border-sm"></span>
<span>Submit</span>
</button>
</form>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
fiscal_year: 2000,
loading: false,
},
mount:function(){},
methods: {
handleLogin(){
console.log('handle login');
this.loading = true;
}
}
})
</script>
I am trying to create an edit function for my data table. The data table is created using Yajra Data tables. Everything working fine unless when I try to load existing data into the edit modal it fails. No error is showing but the modal does not launch. I have only included a little portion of my code here for easy reference.
Modal:
<!-- Update Status Model Box -->
<div id="updateStatusModal" class="modal fade" role="dialog">
<div class="modal-dialog modal-lg">
<div class="modal-content bg-default">
<div class="modal-body">
<form class="form-horizontal" id="updateStatus">
#csrf
#method('PUT')
<div class="row">
<div class="col">
<div class="form-group text-center">
<h6 class="font-weight-bold">Stage 1</h6>
<label for="stage_1" class="switch">
<input type="checkbox" class="form-control" id="stage_1">
<div class="slider round"></div>
</label>
</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="form-group">
<div class="col-md">
<label for="firstname">Coding</label>
<input type="text" class="form-control" id="first_name" value="" placeholder="Enter Completed Page Count">
</div>
</div>
</div>
</div>
</form>
</div>
<div class="modal-footer justify-content-between">
<button type="button" name="update_btn" id="update_btn" class="btn btn-outline-warning">Update</button>
</div>
</div>
</div>
</div>
jquery funtion:
// Edit action
$(document).on('click', '.updateStatus', function(){
$tr = $(this).closest('tr');
var data = $tr.clidren("td").map(function(){
return $(this).text();
}).get();
console.log(data);
$('#id').val(data[0]);
$('#job_id').val(data[2]);
$('#stage_1').val(data[3]);
$('#conversion').val(data[4]);
$('#updateStatusModal').modal('show');
});
I tried this method I found but this is not working. Can anyone provide me any pointers here?
I've just didn't seen your front scripts (also back-end codes), but instead I can share my implementation for that you need. It works perfectly like showed in this (screenshot).
Here I'll put front and back codes. There is functionality for editing existsing Datatable record, also record deletion.
FRONT
<!--HERE ATTACH NECESSARY STYLES-->
<!--VIEW end-->
<link rel="stylesheet" type="text/css" href="{{ asset('css/admin/datatables.min.css') }}"/>
<table id="yajra_datatable" class="table table-bordered">
<thead>
<tr>
<th>Name</th>
<th>Options</th>
</tr>
</thead>
</table>
<div class="modal modal-danger fade" id="modal_delete">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span></button>
<h4 class="modal-title">Delete Language</h4>
</div>
<div class="modal-body">
<p>Are You sure You want to delete this Language?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline pull-left" data-dismiss="modal">Cancel</button>
<button id="delete_action" type="button" class="btn btn-outline">Submit</button>
</div>
</div>
</div>
</div>
<div class="modal modal-warning fade" id="modal_edit">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span></button>
<h4 class="modal-title">Edit Language</h4>
</div>
<div class="modal-body">
<div class="form-group">
<label for="language_name">Language Name</label>
<input name="language_name" id="language_name" type="text" value="" class="form-control" placeholder="Language Name">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline pull-left" data-dismiss="modal">Cancel</button>
<button id="edit_action" type="button" class="btn btn-outline">Submit</button>
</div>
</div>
</div>
</div>
<input type="hidden" id="item_id" value="0" />
<!--VIEW end-->
<!--HERE ATTACH NECESSARY SCRIPTS-->
<!--SCRIPTS start-->
<script src="{{ asset('js/admin/jquery.dataTables.min.js') }}"></script>
<script type="text/javascript">
var YajraDataTable;
function delete_action(item_id){
$('#item_id').val(item_id);
}
function edit_action(this_el, item_id){
$('#item_id').val(item_id);
var tr_el = this_el.closest('tr');
var row = YajraDataTable.row(tr_el);
var row_data = row.data();
$('#language_name').val(row_data.name);
}
function initDataTable() {
YajraDataTable = $('#yajra_datatable').DataTable({
"processing": true,
"serverSide": true,
"ajax": "{{ route('admin.book_languages.ajax') }}",
"columns":[
{
"data": "name",
"name": "name",
},
{
"data": "",
"name": ""
},
],
"autoWidth": false,
'columnDefs': [
{
'targets': -1,
'defaultContent': '-',
'searchable': false,
'orderable': false,
'width': '10%',
'className': 'dt-body-center',
'render': function (data, type, full_row, meta){
return '<div style="display:block">' +
'<button onclick="delete_action(' + full_row.id + ')" type="button" class="delete_action btn btn-danger btn-xs" data-toggle="modal" data-target="#modal_delete" style="margin:3px"><i class="fa fa-remove"></i> Delete</button>' +
'<button onclick="edit_action(this, ' + full_row.id + ')" type="button" class="edit_action btn btn-warning btn-xs" data-toggle="modal" data-target="#modal_edit" style="margin:3px"><i class="fa fa-edit"></i> Edit</button>' +
'</div>';
}
}
],
});
return YajraDataTable;
}
$(document).ready(function() {
var YajraDataTable = initDataTable();
$('#delete_action').on('click', function (e) {
e.preventDefault();
$.ajax({
url: "{{ route('admin.book_languages.delete') }}",
data: {
'item_id': $('#item_id').val(),
'_token': "{{ csrf_token() }}"
},
type: "POST",
success: function (data) {
$('#modal_delete').modal('hide');
YajraDataTable.ajax.reload(null, false);
console.log(data.message);
}
})
});
$('#edit_action').on('click', function (e) {
e.preventDefault();
$.ajax({
url: "{{ route('admin.book_languages.edit') }}",
data: {
'item_id': $('#item_id').val(),
'language_name': $('#language_name').val(),
'_token': "{{ csrf_token() }}"
},
type: "POST",
success: function (response) {
$('#modal_edit').modal('hide');
YajraDataTable.ajax.reload(null, false);
console.log(data.message);
}
})
});
$('#modal_delete').on('hidden.bs.modal', function () {
$('#item_id').val(0);
});
$('#modal_edit').on('hidden.bs.modal', function () {
$('#item_id').val(0);
$('#language_name').val("");
});
});
</script>
<!--SCRIPTS end-->
BACK
public function index() {
return view('admin.book-languages.index');
}
public function ajax() {
$items = BookLanguage::latest('id');
return DataTables::of($items)->make(true);
}
public function delete(Request $request) {
$item_id = $request->get('item_id');
$item = BookLanguage::find($item_id);
if(empty($item)) {
return response()->json([
'success' => false,
'message' => 'Item not found!',
], 200); // 404
} else {
$item->delete();
return response()->json([
'success' => true,
'message' => 'Item successfully deleted.',
], 200);
}
}
public function update(Request $request) {
$item_id = $request->get('item_id');
$item = BookLanguage::find($item_id);
if(empty($item)) {
return response()->json([
'success' => false,
'message' => 'Item not found!',
], 404);
} else {
$item->name = $request->get('language_name');
$item->save();
return response()->json([
'success' => true,
'message' => 'Item successfully updated.',
], 200);
}
}
ROUTES
// ...
// book_languages
Route::group(['prefix' => 'book-languages', 'as' => 'admin.book_languages.',], function () {
Route::get('all', 'BookLanguageController#index')->name('index');
Route::get('ajax', 'BookLanguageController#ajax')->name('ajax');
Route::post('update', 'BookLanguageController#update')->name('edit');
Route::post('delete', 'BookLanguageController#delete')->name('delete');
});
// ...
I think this can help you and others to build wanted functionality. Here this could be also with more hint-comments, but as it not small, I can answer later via post comments.
i am building a Laravel ERP-like web application and am implementing a CRUD function modal like you. I have made mine a server-side processing application with resource APIs in Laravel. Well, please be reminded that i have cut the #extends(layout.app) & #section('stylesheet') parts to go right into the answer. You should extend them in your own application to make everything work.
View.blade script
<script>
$(document).ready(function() {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
var table = $('#customertable').DataTable({
processing: true,
serverSide: true,
dom: 'B<"top"frli>tp',
ajax: {
url: "{{ route('customer.index') }}", //Accessing server for data
columns: [
{data: 'id'}, //data refers to DB column name
{data: 'name'},
{data: 'chiname'},
{data: 'type'},
{data: 'action'}, //this is an addColumn item from Controller
]
});
$('#createNewcustomer').click(function () {
$('#saveBtn').val("create customer");
$('#customerid').val('');
$('#customerForm').trigger("reset");
$('#modelHeading').html("Create New Customer");
$('#customermodal').modal('show');
});
//Control the modal behavior when clicking the edit button.
$('body').on('click', '.editcustomer', function () {
var customerid = $(this).data('id');
$.get("{{ route('customer.index') }}" +'/' + customerid +'/edit', function (data) {
$('#modelHeading').html("Edit Customer");
$('#saveBtn').val("edit-user");
$('#customermodal').modal('show');
$('#customerid').val(data.id);
$('#name').val(data.name);
$('#chiname').val(data.chiname);
$('#type').val(data.type);
})
});
//Create a brand-new record
$('#createNewcustomer').click(function () {
$('#saveBtn').val("create customer");
$('#customerid').val('');
$('#customerForm').trigger("reset");
$('#modelHeading').html("Create New Customer");
$('#customermodal').modal('show');
});
//Update
$('body').on('click', '.editcustomer', function () {
var customerid = $(this).data('id');
$.get("{{ route('customer.index') }}" +'/' + customerid +'/edit', function (data) {
$('#modelHeading').html("Edit Customer");
$('#saveBtn').val("edit-user");
$('#customermodal').modal('show');
$('#customerid').val(data.id);
$('#name').val(data.name);
$('#chiname').val(data.chiname);
$('#type').val(data.type);
})
});
//Save
$('#saveBtn').click(function (e) {
e.preventDefault();
$(this).html('Sending..');
$.ajax({
data: $('#customerForm').serialize(),
url: "{{ route('customer.store') }}",
type: "POST",
dataType: 'json',
success: function (data) {
$('#customerForm').trigger("reset");
$('#customermodal').modal('hide');
table.draw();
},
error: function (data) {
console.log('Error:', data);
$('#saveBtn').html('Error');}
});
});
//Delete
$('body').on('click', '.deletecustomer', function () {
var id = $(this).data("id");
confirm("Are You sure?");
$.ajax({
type: "DELETE",
url: "{{ route('customer.store') }}"+'/'+id,
success: function (data) {
table.draw();
},
error: function (data) {
console.log('Error:', data);
}
});
});
</script>
View.blade html-table & modal part
#section('content')
<div class="container">
<div class="card-header border-left"><h3><strong> Customer overview</strong></h3></div>
<br>
<div class="row">
<div class="col-md text-right">
<button type="button" class="btn btn-success" data-toggle="modal" href="javascript:void(0)" id="createNewcustomer">Create Record</button>
</div>
</div>
{{-- Modal --}}
<div id="customermodal" class="modal fade" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="modelHeading"></h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span></button></div>
<div class="modal-body">
<form id="customerForm" name="customerForm" class="form-horizontal">
<input type="hidden" name="customerid" id="customerid">
<div class="form-group">
<label for="name" class="col-sm-6 control-label">Customer Name</label>
<div class="col-sm-12">
<input type="text" class="form-control" id="name" name="name" placeholder="Name" value="" maxlength="50" required="">
</div>
</div>
<div class="form-group">
<label class="col-sm-6 control-label">Customer Name</label>
<div class="col-sm-12">
<input type="text" class="form-control" id="chiname" name="chiname" placeholder="Customer Name" value="" maxlength="50" required="">
</div>
</div>
<div class="form-group">
<label class="col-sm-6 control-label">Contract type</label>
<div class="col-sm-12">
<select name="type" id="type" class="form-control">
<option value="" disabled>Type</option>
<option value="Government">Government Contract</option>
<option value="Private">Private Contract</option>
</select>
</div></div>
<br>
<div class="col-sm text-right">
<button type="submit" class="btn btn-outline-secondary" id="saveBtn" value="create">Save changes</button>
</div>
</form>
</div>
</div>
</div>
</div>
{{-- Table --}}
<br>
<div class="row">
<br/>
<br/>
<div class="form-group col-md-12 align-content-center">
<table class="table-fluid center-block" id="customertable">
<thead>
<tr>
<th>id</th>
<th>ChiName</th>
<th>Name</th>
<th>Type</th>
<th>Action</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
#endsection
CustomerController
public function index(Request $request)
{
$customers = Customer::all();
}
return Datatables::of($customers)
->addColumn('action', function($customer){
$btn = 'Edit';
$btn = $btn.' Delete';
return $btn;})
->rawColumns(['action'])
->make(true);
}
return view('customer.Customer'); //my view blade is named Customer under customer dir. put your blade destination here.
}
public function store(Request $request)
{
Customer::updateOrCreate(['id' => $request->customerid],
['name' => $request->name, 'chiname' => $request->chiname,'type' =>$request->type]);
return response()->json(['success'=>'Product saved successfully.']);
}
public function edit($id)
{
$customer = Customer::findorfail($id);
return response()->json($customer);
}
public function destroy($id)
{
Customer::findorfail($id)->delete();
return response()->json(['success'=>'Product deleted successfully.']);
}
Model (pick either A.) $guarded = [] OR B.) $fillable = ['fields','fields'] as you like)
class Customer extends Model
{
protected $fillable = ['name','chiname','type'];
}
web.api (route setting)
Route::resource('customer', 'CustomerController')->middleware('auth');
Migration / DB schema structure
class CreateCustomersTable extends Migration
{
public function up()
{
Schema::create('customers', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('chiname');
$table->string('type');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('customers');
}
I have not included any protection in it like gate, auth or so. But basically this is the skeleton of doing CRUD with dataTable in Laravel framework with both JS, Ajax, Jquery, PHP all in one. Kindly be reminded that the queries for such CRUD actions are directly linked to the Database server. If you want to show data processed by the DataTable, use your own jquery function to fetch and show them on the modal. My answer is not the best but i hope it helps you >:)
(I could not post a picture to show you here as i dont have enough reputation lol. gg)
I'm trying to dynamically add or remove input fields on the go.
I got a simple solution from here https://smarttutorials.net/dynamically-add-or-remove-input-textbox-using-vuejs/, which works. However saving input values in the database stops it's functionality.
Component Code:
<div class="form-group" v-for="(input,k) in inputs" :key="k">
<input type="text" class="form-control" v-model="input.name" />
<input type="text" class="form-control" v-model="input.party" />
<span>
<i
class="fas fa-minus-circle"
#click="remove(k)"
v-show="k || ( !k && inputs.length > 1)"
></i>
<i
class="fas fa-plus-circle"
#click="add(k)"
v-show="k == inputs.length-1"
></i>
</span>
</div>
<button #click="addCandidate">
Submit
</button>
<script>
export default {
data() {
return {
inputs: [
{
name: "",
party: ""
}
]
};
},
methods: {
add(index) {
this.inputs.push({ name: "", party: "" });
},
remove(index) {
this.inputs.splice(index, 1);
},
addCandidate() {
axios
.post("/candidates", this.inputs)
.then(response => {})
.catch(error => {});
}
}
};
</script>
I always get a 422 error, saying the input field is empty.
This is not a Vue problem. Before you send an array you'll need to call JSON.stringify() on it, then decode it on the server with Laravel. Example:
foreach(json_decode($request -> input('my_prop_name ')) as $my_object_in_array)
{
print_r($my_object_in_array); // this is your object name/party
}
Vue code working like magic. :)
new Vue({
el: '#app',
data () {
return {
inputs: [{
name: '',
party: ''
}]
}
},
methods: {
add () {
this.inputs.push({
name: '',
party: ''
})
console.log(this.inputs)
},
remove (index) {
this.inputs.splice(index, 1)
},
addCandidate () {
axios
.post('/candidates', {
my_prop_name: JSON.stringify(this.inputs)
})
.then(response => {})
.catch(error => {})
}
}
})
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id=app>
<div class="form-group" v-for="(input,k) in inputs" :key="k">
<input type="text" class="form-control" v-model="input.name">
<input type="text" class="form-control" v-model="input.party">
<span>
<i class="fas fa-minus-circle" #click="remove(k)" v-show="k || ( !k && inputs.length > 1)">Remove</i>
<i class="fas fa-plus-circle" #click="add(k)" v-show="k == inputs.length-1">Add fields</i>
</span>
</div>
<button #click="addCandidate">
Submit
</button>
</div>
I have a vue component that takes care of showing all my records and make it possible to edit every record. I have 100+ records so i'm working with pagination.
problem: as example I would like to edit a record that is located on page 3 of the pagination. I can edit the record, but after the update my pagination starts at page 1 again. This happens because I'm fetching my data again after the update.
question: How can I improve my code that this doesn't happen? Do I really need to fetch my data again to display the changes?
Vue component
<template>
<div>
<h2> Quest template </h2>
<div class="container">
<div class="row">
<div class="col-md-7">
<form class="form-inline mb-3">
<input class="form-control mr-sm-2" style='width:55%;' type="search" placeholder="Search"
aria-label="Search">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>
<nav aria-label="Page navigation example">
<ul class="pagination">
<li v-bind:class="[{disabled: !pagination.prev_page_url}]" class="page-item"><a class="page-link" href="#"
#click="fetchQuests(pagination.prev_page_url)">Previous</a></li>
<li class="page-item"><a class="page-link disabled text-dark" href="#">Page {{pagination.current_page}} of {{pagination.last_page}}</a></li>
<li v-bind:class="[{disabled: !pagination.next_page_url}]" class="page-item"><a class="page-link" href="#"
#click="fetchQuests(pagination.next_page_url)"
>Next</a></li>
</ul>
</nav>
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Name</th>
<th scope="col">Price</th>
<th scope="col">Actions</th>
</tr>
</thead>
<tbody>
<tr v-for="quest in quests" v-bind:key="quest.id">
<th scope="row">{{quest.id}}</th>
<td>{{quest.name}}</td>
<td>No price set</td>
<td><a #click="editQuest(quest)" href="#" class=" btn btn-outline-dark"> Edit</a></td>
</tr>
</tbody>
</table>
</div>
<div class="col-md-4">
<h2 class="text-center">EDIT PANEL</h2>
<p class="text-center"> </p>
<form #submit.prevent="updateQuest">
<div class="form-group">
<div class="input-group mb-3">
<div class="input-group-prepend">
<div class="input-group-text">Quest name</div>
</div>
<input type="text" class="form-control" v-model="quest.name" placeholder="" :disabled="!this.edit">
</div>
<div class="input-group">
<div class="input-group-prepend">
<div class="input-group-text">
Quest price
</div>
</div>
<input type="text" class="form-control" v-model="quest.price" placeholder="" :disabled="!this.edit">
<div class="input-group-prepend">
<div class="input-group-text">
M
</div>
</div>
</div>
</div>
<button v-bind:class="[{disabled: !this.edit}]" class="btn btn-outline-dark float-right"> Update</button>
</form>
</div>
</div>
</div>
</div>
</template>
Vue component script
<script>
export default {
data() {
return {
quests: [],
quest: {
id: '',
name: '',
price: '',
},
quest_id: '',
pagination: {},
edit: false
}
},
created() {
this.fetchQuests();
},
methods: {
fetchQuests(page_url) {
let vm = this;
page_url = page_url || '/api/quests'
fetch(page_url, {
headers : {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
})
.then(res => res.json())
.then(res => {
this.quests = res.data;
vm.makePagination(res.meta, res.links);
})
.catch(error => console.log(error));
},
makePagination(meta,links) {
let pagination = {
current_page: meta.current_page,
last_page: meta.last_page,
next_page_url: links.next,
prev_page_url: links.prev,
}
this.pagination = pagination;
},
updateQuest() {
if(this.edit) {
fetch( `/api/quests/${this.quest.id}`, {
method:'put',
body: JSON.stringify(this.quest),
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
})
.then(res => res.json())
.then(data => {
this.quest.name = "";
this.quest.price = "";
this.fetchQuests();
})
.catch(error => console.log(error));
}
},
editQuest(quest) {
this.edit = true;
this.quest.id = quest.id;
this.quest.quest_id = quest.id;
this.quest.name = quest.name;
this.quest.price = quest.price;
}
}
}
</script>
This question is vague. And if you wrote this yourself, you're obviously not a noob, so I'm gonna keep this simple. Why not just reload the current page? Keep a track of the current page in a data variable and when you make an update, rather than loading the from the start, reload the current page url.
data: function() {
current_page_url: '/api/quests
},
methods: {
fetchQuests: function(page_url) {
let vm = this;
page_url = page_url || this.current_page_url;
this.current_page_url = page_url;
fetch(page_url, {
headers : {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
})
.then(res => res.json())
.then(res => {
this.quests = res.data;
vm.makePagination(res.meta, res.links);
})
.catch(error => console.log(error));
}
}