How to Refresh Table after ajax request in laravel - ajax

I am working on exchange project using laravel and want to refresh my table after a
<tbody class="fixed-header">
#foreach($transactionsCustomer as $transaction)
<tr>
<td>{{ $transaction->description }}</td>
#foreach($accounts as $account)
#if($transaction->code == 0)
#if($account->currency->id==$transaction->currency_id)
<td>{{ $transaction->amount }}</td>
<td></td>
#else
<td></td>
<td></td>
#endif
#else
#if($account->currency->id==$transaction->currency_id)
<td></td>
<td>{{ $transaction->amount }}</td>
#else
<td></td>
<td></td>
#endif
#endif
#endforeach
<td><a href="{{ route('transaction.edit',$transaction->id)}}" class="btn btn-primary" >سمون</a></td>
</tr>
#endforeach
</tbody>
and here is my ajax code to store the data
$("#transaction-form").submit(function(stay){
var formdata = $(this).serialize(); // here $(this) refere to the form its submitting
$.ajax({
type: 'POST',
url: "{{ route('transaction.store') }}",
data: formdata, // here $(this) refers to the ajax object not form
success: function (data) {
$('input[type="text"],textarea').val('');
updateTable();
},
});
stay.preventDefault();
});
and here is my controller method to represent the data
public function singleCustomer(Request $request)
{
$customer = Customer::find($request->id);
$accounts = Account::where('customer_id', $request->id)->get();
$currencies = Currency::all();
$transactionsCustomer = DB::table('transactions')->
join('accounts','transactions.account_id' ,'=','accounts.id')->join('customers','accounts.customer_id','=','customers.id')->join('currencies','accounts.currency_id','=','currencies.id')->select('transactions.*','currencies.id as currency_id')->where('customers.id',$request->id)->get();
return view('transaction.index',compact('currencies','customer','accounts','transactionsCustomer'));
}
now i want to refresh my table after this ajax request

You need to separate the table in different view.
Here's the flow, you get all data from your Controller , pass it to the table view, in the main view you include the table view using #include('table-view-route').
And don't forget on your success ajax, call updateTable() which has functionality to load the table view using jquery
$("#tableContainerId").load("{{url('table-view-route')}}");

Related

Laravel and Vuejs axios delete gives no error but doesnt delete

I created a web route that must delete a contact based on a specific id and it looks like this:
Route::delete('/api/deleteContact/{id}', 'ContactController#destroy');
Then inside the controller, I have the following:
public function destroy($id)
{
// delete a contact by id
return response()->json(Contact::whereId($id), 200);
}
Inside one of my blade template files, I call the Vue component which displays the list of contacts:
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Name</th>
<th scope="col">Phone</th>
</tr>
</thead>
<tbody>
<tr v-for="contact in contacts">
<td> {{ contact.id }} </td>
<td> {{ contact.name }} </td>
<td> {{ contact.phone }} </td>
<td><button class="btn btn-secondary">Edit</button></td>
<td><button #click="deleteContact(contact.id)" class="btn btn-danger">Delete</button></td>
</tr>
</tbody>
</table>
The delete button calls the deleteContact method and received the contact id in question.
The method looks like this:
deleteContact(id){
axios.delete('/api/deleteContact/' + id)
.then(res => {
for(var i = 0; i < this.contacts.length; i++) {
if(this.contacts[i].id == id) {
this.contacts.splice(i, 1);
}
}
})
.catch(err => console.log(err));
}
When I click to delete, the promise(then) occurs, however, after refreshing the page, I noticed that nothing was deleted and I see no errors in the console.
How can I successfully delete the contact based on the id passed in the deleteContact function ?
You have to append delete at the end of query like this:
public function destroy($id)
{
// delete a contact by id
return response()->json(Contact::where('id',$id)->delete(), 200);
}

Ajax and Django

I have a jquery ajax code that looks like below,Its working on a delete button and a checkbox.
$(".delete-row").click(function(){
$("table
tbody").find('input[name="record"]').each(function(){
if($(this).is(":checked")){
var value = $('chk').val();
$(this).parents("tr").remove();
$.ajax({
url: "/delete/",
// type: "post", // or "get"
data: value
});
});
});
});
This jquery call should delete the checked row in a table and the added ajax call will call a django view.
My doubt is I am passing the checkbox value to django view in the above AJAX call. In this case how do django view come to know what table row to delete based on the checkbox value?
below is how my table is getting created in a for loop
{% for x in dirs %}
<tr id='this_row' style="text-align: center;">
<td>
<input type="checkbox" id="chk" value="this_row" name="record"></td>
<td>
{{ x.name }}
</td>
<td>
{{ x.created_date }}
</td>
<td>
{{ x.description }}
</td>
</tr>
{% endfor %}
below is the delete button
<button type="submit" name="erase" class="delete-row">Delete Row</button>
Just add the id of the row as value attribute to the checkbox, so your ajax will send a list of ID. Instead of this_row, add {{x.id}} the instance id
{% for x in dirs %}
<tr id='tr-{{x.id}}' style="text-align: center;">
<td><input type="checkbox" id="chk-{{x.id}}" value="{{x.id}}" name="record"></td>
<td>
{{ x.name }}</td>
<td>{{ x.created_date }}</td>
<td>{{ x.description }}</td>
</tr>
{% endfor %}
And in your ajax, you have access to it with
// send this array via ajax
$(".delete-row").click(function(){
var id_list = new Array();
$("input[name=record]:checked").each(function(){
id_lists.push($(this).val());
$(this).parent("tr").remove(); // Remove the row,
// the correct is parent() without 's', not parents()
});
// with type:'post', don't forget the csrf_token
$.ajax({
url: "/delete/",
type: "post",
data: {
id_list:id_list,
csrfmiddlewaretoken:"{{ csrf_token }}"
},
});
});
And in your view, you can retrieve the id_list containing all the selected rows with reqest.POST.getlist('id_list[]'). In case it was a GET request reqest.GET.getlist('id_list[]')

Cannot access id being passed in vue.js and laravel

I am having hard time inserting the values which is the id that is being passed from the form into the controller of my enrollment system. To achieve this I make use of vue.js and vue-resource library. In my all.js file I am gettting the correct id value when I console.log the id being passed. However, when passing it to the route address of my application I am getting 500 error. Also, upon debugging I' m getting this error SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'section_subject_id' cannot be null (SQL: insert into reservations. How can I solve this?
ReservationController.php
class ReservationController extends Controller
{
public function create($id)
{
$subjects = Subject::with('sections')->get();
return view('reservation.form',compact('subjects'));
}
public function store(Request $request)
{
$subject = new Reservation();
$subject->section_subject_id = $request->input('id');
$subject->student_id = 1;
$subject->save();
}
}
all.js
Vue.http.headers.common['X-CSRF-TOKEN'] = document.querySelector('#token').getAttribute('value');
new Vue({
el: '#app-layout',
data: {
subject: {
id : ''
},
subjects: []
},
ready: function(){
},
methods:{
addSubject: function(id){
this.subject = id;
this.$http({url: 'http://localhost:8000/reservation', id, method: 'POST'}).then(function(response){
}, function (response){
console.log('error');
});
}
}
});
form.blade.php
<body>
#foreach($subjects as $subject)
#foreach($subject->sections as $section)
<tr>
<td>{{ $section->section_code }}</td>
<td>{{ $subject->subject_code }}</td>
<td>{{ $subject->subject_description }}</td>
<td>{{ $section->pivot->schedule }}</td>
<td>{{ $subject->units }}</td>
<td>{{ $section->pivot->room_no }}</td>
<td>
<button
v-on:click="addSubject( {{ $section->pivot->id }} )"
class="btn btn-xs btn-primary">Add
</button>
<button class="btn btn-xs btn-info">Edit</button>
</td>
</tr>
#endforeach
#endforeach
</body>
Try formatting the data being sent like this: {id: this.id}
So your Vue addSubject Method looks like this:
addSubject: function(id){
this.subject = id;
this.$http({url: 'http://localhost:8000/reservation', {id: this.id}, method: 'POST'}).then(function(response){
}, function (response){
console.log('error');
});
}

Django form in every row of a table

I want to have a simple text form on every row of a table.
Fiddle illustration of expected result: https://jsfiddle.net/wstg759f/1/
My Models.py:
class Person(models.Model):
name = models.CharField(max_length=30)
class Quality(models.Model):
name = models.CharField(max_length=30)
person=models.ForeignKey(Person)
I have a queryset that returns aggregated list of all persons, count of qualities for each person, one random quality of this person:
[
{'the_count': 5, u'randomquality': u'Nice’, u'person__name': u'Joe'},
{'the_count': 4, u'randomquality': u'Generous’,u'person__name': u'Mike'},
{'the_count': 4, u'randomquality': u'Healthy’,u'person__name': u'John’'},
..
]
My view.html (qualities is my queryset)
<table>
<thead>
<tr>
<th>Person</th>
<th>Qualities count</th>
<th>One random quality</th>
<th>Add a Quality?</th>
</tr>
</thead>
<tbody>
{%for obj in qualities%}
<tr>
<td>{{ obj.person__name }}</td>
<td>{{ obj.the_count }}</td>
<td>{{ obj.randomquality }}</td>
<td>text form to submit a quality for this person</td>
</tr>
{% endfor %}
</tbody>
</table>
The user should be able to input a quality in the text field, and once submitted it will be added to the model, and the text field is replaced by "thanks, submitted"
The submit form have to be independent.
I have no clear direction where to look at.
How would you do?
From my reading, I understand that formset could be a solution, but they are really unclear for me.
Should I even use django form in this case?
If yes, I believe the form should take an argument form the template: I don't need the user to tell me about the person name as it's already here.
Let me know if I can clarify.
Thanks in advance.
As a bonus, maybe for later, I want to avoid page refresh.
Is ajax the only way?
You can do this with ajax, form and views
template.html
<table>
<thead>
<tr>
<th>Person</th>
<th>Qualities count</th>
<th>One random quality</th>
<th>Add a Quality?</th>
<th>Button</th>
</tr>
</thead>
<tbody>
{% for obj in qualities %}
<tr id="row_{{ obj.id }}">
<td>{{ obj.person__name }}</td>
<td>{{ obj.the_count }}</td>
<td>{{ obj.randomquality }}</td>
<td>{{ form.quality }}</td>
<td><button value="{{ obj.id }}" onclick="addQuality(this.value)">Add</button></td>
</tr>
{% endfor %}
</tbody>
</table>
<script>
function addQuality(id_object) {
const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value
let data_to_backend = new FormData()
let qualityToAdd = document.getElementById(`id_${id_object}-quality`).value
if (qualityToAdd !== '') {
data_to_backend.append('quality', qualityToAdd)
data_to_backend.append('object_index', id_object)
} else return
const request = new Request("./",
{
method: 'POST',
headers: {'X-CSRFToken': csrftoken},
body: data_to_backend
})
fetch(request, {
method: 'POST',
mode: 'same-origin'
}).then(
function(response) {
if (response.status === 200) {
let tableRow = document.getElementById(`row_${ id_object }`)
tableRow.innerHTML = "<p>thanks, submitted</p>"
} else {
alert("Error")
console.log(response)
}
}
)
}
</script>
Set your views to receive a post request or just create a new urls path and another views
views.py
def addQuantity(request, codigo_orcamento):
if request.method == "POST":
form = formAddQuantity(request.POST)
if form.is_valid():
id_object = form.cleaned_data['object_index']
quality = form.cleaned_data['quality']
# get the object and add this quality
return HttpResponse(status=200)
else:
return HttpResponse(status=400)
else:
return HttpResponse(status=405)
In this view we simply check if the form is valid, get the object from db and add the quality on it
forms.py
class formAddQuantity(forms.Form):
object_index = forms.IntegerField(min_value=0)
quality = forms.CharField(max_length=100)
A simple check, but i recommend you to add more requirements to this fields
(Not tested, if throws a error let me know)

laravel delete is not working

I am wondering how to put a csrf token in a form so that delete will work?
Here is my code:
Route:
Route::delete('category_delete/{id}',['as'=>'category_delete','uses'=>'CategoryController#destroy']);
index.blade.php
#section('adminContent')
{!! Form::token() !!}
<div class="table-responsive art-content">
<table class="table table-hover table-striped">
<thead>
<th> NAME</th>
<th> ACTIONS</th>
</thead>
<tbody>
#foreach($categoriesView as $category)
<tr>
<td>{!! $category->name!!}</td>
<td>{!! link_to_route('categories.edit', '', array($category->id),array('class' => 'fa fa-pencil fa-fw')) !!}</td>
<td><button type="button" id="delete-button" class="delete-button" data-url = "{!! url('category_delete')."/".$category->id !!}"><i class="fa fa-trash-o"></i></button>
</td>
</tr>
#endforeach
</tbody>
</table>
<div class="pagination"> {!! $categoriesView->render() !!}</div>
</div>
#stop
CategoryController:
public function destroy($id,Category $category)
{
$category = $category->find ( $id );
$category->delete ();
Session::flash ( 'message', 'The category was successfully deleted!.' );
Session::flash ( 'flash_type', 'alert-success' );
}
If I used ajax, javascript or jquery, how should the code be?
Using jquery I would do something like the following.
Add the line below in the header of your home view
<meta name="csrf-token" content="{{ csrf_token() }}" />
Now in your javascript
function deleteMe(button)
{
// You might want to put the ajaxSetup function where it will always load globally.
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
if(confirm("Are you sure?"))
{
$.get(
'category_delete/'+button.id,
function( response )
{
// callback is called when the delete is done.
console.log('message = '+ response.message);
}
)
}
}
In index.blade.php, make your id more specific.
...
<td><button type="button" id=".$category->id" class="delete-button" data-url = "{!! url('category_delete')."/".$category->id !!}"><i class="fa fa-trash-o" onlick="deleteMe(this);></i></button>
...
In your controller
public function destroy($id,Category $category){
$category = $category->find ( $id );
$category->delete ();
return response()->json(
'message' => 'Deleted',
)
}
Note: No need to add
Form::token in your view
Hope this helps.....
Updated...........
If you were to do it using laravel only, I will suggest you use a link rather than the button you are using.
In index.blade.php, make your id more specific.
...
<td><a href="category_delete/".$category->id class="delete-button" data-url = "{!! url('category_delete')!!}"><i class="fa fa-trash-o"></i></td>
...
In your controller
public function destroy($id,Category $category){
$category = $category->find ( $id );
$category->delete ();
return view('index');//important.
}
If you want your link to look like a button, use css or a css framework like bootstrap
That should be it. hope this helps again.

Resources