Laravel function controller validation error - php

I have validation issue when I tried to apply the coupon code.
I have to apply on 4 condition
If I applied the correct coupon from the database then it will be fine.
If I applied the correct coupon again from the database then it will be
show the message 'This Coupon Have Already Used'.
If I just directly key in button (blank value) it will show the message 'Please Insert
The Coupon Code'
But the problem is what I key in the wrong coupon code, I need to
have 'Wrong Coupon Code Entered' message displayed
Below is the controller part for the function:-
public function checkCoupon(Request $res)
{
$code = $res->code;
$check = DB::table('coupons')
->where('coupon_code',$code)
->get();
if(count($check)=="1") {
$user_id = Auth::user()->id;
$check_used = DB::table('used_coupons')
->where('user_id', $user_id)
->where('coupon_id', $check[0]->id)
->count();
if($check_used=="0"){
$used_add = DB::table('used_coupons')
->insert([
'coupon_id' => $check[0]->id,
'user_id' => $user_id
]);
$insert_cart_total = DB::table('cart_total')
->insert([
'cart_total' => Cart::total(),
'discount' => $check[0]->discount,
'user_id' => $user_id,
'gtotal' => Cart::total() - (Cart::total() * $check[0]->discount)/100,
]);
}
else{
?>
<div class="alert alert-warning">This Coupon Have Already Used</div>
<?php
}
}
else if($code==$check){
?>
<div class="alert alert-danger">Wrong Coupon Code Entered</div>
<?php }
else{
?>
<div class="alert alert-danger">Please Insert The Coupon Code </div>
<?php }
}
JS file for apply coupon function button:-
$(document).ready(function(){
$('#coupon_btn').click(function(){
var coupon_id = $('#coupon_id').val();
$.ajax({
url:'{{url('/checkCoupon')}}',
data: 'code=' + coupon_id,
success:function(res){
$('#cartTotal').html(res);
}
})
});
});
View File
<div class="cart-total" >
<h4>Total Amount</h4>
<table>
<tbody>
<tr>
<td>Sub Total</td>
<td>$ <?php echo Cart::subtotal(); ?></td>
</tr>
<tr>
<td>Tax (%)</td>
<td>$ <?php echo Cart::tax(); ?></td>
</tr>
<tr>
<td>Grand Total new</td>
<td>$ <?php echo Cart::total(); ?></td>
</tr>
<tr>
<td>Discount(%) </td>
<td> <?php echo $disnew; ?></td>
</tr>
<tr>
<td>Grand Total (After discount) </td>
<td>$ <?php echo $gtnew; ?></td>
</tr>
</tbody>
</table>
<input type="submit" class="btn update btn-block" style="color: white;font-weight: bold;" value="Continue Shopping">
Checkout
</div>

To check used coupons better to use exists instead of count.
To get coupon better to use first instead of get (first - return first element, you dont need to use index on collection)
I think, in this situation better to use returns. Code and logic looks clearly.
public function checkCoupon(Request $res)
{
$code = $res->input('code');
$userId = Auth::user()->id;
if(!$code){
return ['error' => '<div class="alert alert-danger">Please Insert The Coupon Code </div>'];
}
$coupon = DB::table('coupons')
->where('coupon_code', $code)
->first();
if(!$coupon) {
return ['error' => '<div class="alert alert-danger">Wrong Coupon Code Entered</div>'];
}
$isUsed = DB::table('used_coupons')
->where('user_id', $userId)
->where('coupon_id', $coupon->id)
->exists();
if($isUsed){
return ['error' => '<div class="alert alert-warning">This Coupon Have Already Used</div>'];
}
DB::table('used_coupons')
->insert([
'coupon_id' => $coupon->id,
'user_id' => $userId
]);
DB::table('cart_total')
->insert([
'cart_total' => Cart::total(),
'discount' => $coupon->discount,
'user_id' => $userId,
'gtotal' => Cart::total() - (Cart::total() * $coupon->discount)/100,
]);
return [
'subtotal' => Cart::subtotal(),
'total' => Cart::total()
];
}
Jquery:
$(document).ready(function(){
$('#coupon_btn').click(function(){
var coupon_id = $('#coupon_id').val();
$.ajax({
url:'{{url('/checkCoupon')}}',
dataType: "json",
data: {code: coupon_id},
success:function(res){
if(res.error){
$('...error_selector...').html(res.error);
} else {
$('...total_selector...').html(res.total);
$('...subtotal_selector...').html(res.subtotal);
}
}
})
});
});

Related

I am getting 500 Internal Error when trying to pass named route with two parameter in my controller

So when I put a route name with a single parameter it works flawlessly but when I pass named route with two parameters I get a 500 error in my console which looks like this:GET http://127.0.0.1:8000/admin/packages/package-programs/kathmandu/action?query= 500 (Internal Server Error).
<?php
namespace App\Http\Controllers\AdminVisible;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use App\Program;
use App\Package;
use DB;
class PackageProgramController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
public function index($packageSlug)
{
$showCounts = Program::count();
$packages = Package::firstOrFail();
return view('admin.pages.packageprogram',compact('showCounts','packageSlug','packages'));
}
function action($packageSlug,Request $request)
{
if($request->ajax())
{
$output = '';
$query = $request->get('query');
if($query != '')
{
$data = DB::table('programs')
->where('id', 'like', '%'.$query.'%')
->orWhere('day', 'like', '%'.$query.'%')
->orWhere('Package_Type', 'like', '%'.$query.'%')
->orWhere('title', 'like', '%'.$query.'%')
->orderBy('id', 'desc')
->get();
}
else
{
$data = DB::table('programs')
->orderBy('id', 'desc')
->get();
}
$total_row = $data->count();
if($total_row > 0)
{
foreach($data as $row)
{
$packageProgram = ['packageProgram' => $row->id];
$route = route('PackageProgram.edit',['packageSlug' => $packageSlug, 'packageProgram' => $packageProgram]);
$output .= '
<tr>
<th scope="row"><input type="checkbox" name="ids[]" class="selectbox" value="'.$row->id.'" onchange="change()"></th>
<td onClick="location.href=\''.$route.'\' " style="cursor: pointer">'.$row->id.'</td>
<td onClick="location.href=\''.$route.'\' " style="cursor: pointer">'.$row->day.'</td>
<td onClick="location.href=\''.$route.'\' " style="cursor: pointer">'.$row->title.'</td>
<td onClick="location.href=\''.$route.'\' " style="cursor: pointer">'.$row->description.'</td>
</tr>
';
}
}
else
{
$output = '
<tr>
<td align="center" colspan="12">No Data Found</td>
</tr>
';
}
$data = array(
'table_data' => $output,
'total_data' => $total_row
);
echo json_encode($data);
}
}
public function create($packageSlug, Package $package)
{
return view('admin.create.createPackageProgram',compact('packageSlug','package'));
}
public function store($packageSlug,Request $request)
{
$packages = Package::where('slug', $packageSlug)->firstOrFail();
$data = request()->validate([
'day' => 'required',
'title' => 'required',
'description' => 'required',
]);
$packages->program()->create($data);
switch ($request->input('action')) {
case 'preview':
return redirect()->intended(route('PackageProgram',$packageSlug))->with('message', 'Package Program has been added.');
break;
default:
return redirect()->back()->with('message', 'Package Program has been added.');
break;
}
}
public function edit($packageSlug,Program $packageProgram,Package $package)
{
return view('admin.edit.editPackageProgram',compact('packageSlug','packageProgram','package'));
}
public function update($packageSlug, Program $packageProgram)
{
$data = request()->validate([
'day' => 'required',
'title' => 'required',
'description' => 'required',
]);
$packageProgram->update($data);
return redirect()->intended(route('PackageProgram',$packageSlug))->with('message', 'Package Program has been updated.');
}
public function delete(Request $request) {
$data = request()->validate([
'deleteSelected' => 'required',
]);
$id = $request->get('ids');
$data = DB::delete('delete from programs where id in ('.implode(",",$id).')');
return redirect()->back()->with('message', 'Testimony has been deleted.');
}
}
My blade file looks something like this:
#extends('layouts.app')
#section('style')
<link href="{{ asset('css/Admin/sql-data-viewer.css') }}" rel="stylesheet">
<style></style>
#endsection
#section('content')
<section class="data-viewer">
<div class="d-flex justify-content-between px-3">
<h3 class="text-white">Select {{$package->Package_Name}} {{$package->Package_Type}} Days to change</h3>
<button type="button" class="btn add-data text-white rounded-pill">Add Day <i class="fas fa-plus"></i></button>
</div>
<form>
#csrf
#method('DELETE')
#if(session()->has('message'))
<div class="alert alert-success">
{{ session()->get('message') }}
</div>
#endif
<div class="d-flex justify-content-between selectDelete">
<div class="delete pl-3 mt-3 mb-3">
<label for="deleteSelected">Action:</label>
<select name="deleteSelected" id="deleteSelected" class="#error('deleteSelected') is-invalid #enderror" name="deleteSelected" >
<option disabled selected>---------</option>
<option>Delete Selected Package Program</option>
</select>
<button formaction="{{ route('PackageProgram.delete',$package) }}" formmethod="POST" type="submit" class="go" id="deleleGo" onclick="deleteBtn()">Go</button>
<span id="selected">0</span> of {{$showCounts}} selected
#error('deleteSelected')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
#enderror
<strong id="selectError">You must check at least one checkbox</strong>
</div>
<div class="search pr-3 mt-3 mb-3">
<label for="search">Search:</label>
<input id="search" type="text" color="#000" class="rounded #error('search') is-invalid #enderror" name="search" value="{{ old('search') }}" autocomplete="search" placeholder="Search">
#error('search')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
#enderror
</div>
</div>
<table class="table table-hover table-striped table-dark">
<thead>
<tr>
<th scope="col"><input type="checkbox" id="checkHead" class="selectall"></th>
<th scope="col">Id</th>
<th scope="col">Day</th>
<th scope="col">Title</th>
<th scope="col">Description</th>
</tr>
</thead>
<tbody></tbody>
</table>
</form>
</section>
#endsection
#section('script')
<script src="{{ asset('/js/sqlData.js') }}"></script>
<script>
$(document).ready(function(){
fetch_data();
function fetch_data(query = '')
{
$.ajax({
url:"{{ route('PackageProgram.action',$packageSlug) }}",
method:'GET',
data:{query:query},
dataType:'json',
success:function(data)
{
$('tbody').html(data.table_data);
}
})
}
$(document).on('keyup', '#search', function(){
var query = $(this).val();
fetch_data(query);
});
});
function checkboxError(){
var number = document.querySelectorAll('.selectbox:checked').length;
if(number == 0) {
var a = document.getElementById("selectError").style.display = "block";
return false;
}
}
window.addEventListener('DOMContentLoaded', (event) => {
var deleteBtn = document.getElementById("deleleGo");
deleteBtn.onclick = checkboxError;
});
</script>
#endsection
So my route file looks something like this:
Route::prefix('package-programs')->group(function() {
Route::get('/', 'AdminVisible\packagePackageProgramController#index')->name('PackagePrograms');
Route::get('/action', 'AdminVisible\packagePackageProgramController#action')->name('PackagePrograms.action');
Route::prefix('{packageSlug}')->group(function() {
Route::get('/', 'AdminVisible\PackageProgramController#index')->name('PackageProgram');
Route::get('/action', 'AdminVisible\PackageProgramController#action')->name('PackageProgram.action');
Route::get('/create', 'AdminVisible\PackageProgramController#create')->name('PackageProgram.create');
Route::post('/create', 'AdminVisible\PackageProgramController#store')->name('PackageProgram.store');
Route::delete('/delete','AdminVisible\PackageProgramController#delete')->name('PackageProgram.delete');
Route::get('/{packageProgram}/edit', 'AdminVisible\PackageProgramController#edit')->name('PackageProgram.edit');
Route::patch('/{packageProgram}', 'AdminVisible\PackageProgramController#update')->name('PackageProgram.update');
});
});
It might be I do not know how to pass named route with two parameters but in my blade file, I been doing it like this, and there it works. Is it something different that must be done in the controller.
First start from blade (please check comments):
#extends('layout')
#section('content')
<div class="row">
<table class="table table-hover table-striped table-dark" id="slugTb">
<thead>
<tr>
<th scope="col"><input type="checkbox" id="checkHead" class="selectall"></th>
<th scope="col">Id</th>
<th scope="col">Day</th>
<th scope="col">Title</th>
<th scope="col">Description</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
#endsection
#section('scripts')
<script>
$(document).ready(function() {
var query = 'damnSon';
$.ajax({
url: "{{ route('test.action') }}",
method: 'GET',
data: {
'slug': '{{ $packageSlug }}',
'query': query
},
dataType: 'json',
})
.done(function(data) {
console.log(data) //use console.log to debug
$('#slugTb tbody').html(data.table_data); //set table id so that you don't miss the right one
})
.fail(function(err) {
console.log(err) //in case if error happens
})
.always(function() {
console.log( "complete" ); //result despite the response code
});
});
</script>
#endsection
You used deprecated jquery method like success check
Better use this three: done,fail,always
Next route web.php:
Route::get('action', ['as' => 'test.action', 'uses' => 'TestController#action']);
In your case better to use Request params bag so that you can add as much params as you want.
Next controller:
function action(Request $request)
{
$total_row = 1;
$packageSlug = $request->get('slug'); //names that you set in ajax data tag: {'slug': '{{ $packageSlug }}','query': query}
$query = $request->get('query');
$output = '<tr>
<td align="center" colspan="1">' . $packageSlug . '</td>
<td align="center" colspan="1">' . $query .'</td>
</tr>';
$data = array(
'table_data' => $output,
'total_data' => $total_row
);
return response()->json($data);
}
You should return something from the controller so blade can show that data and json encode it so that js could parse it. That is why return response()->json($data);
Other way:
route:
Route::get('/action/{slug}/{query}',['as' => 'test.action', 'uses' => 'TestController#action']);
blade script:
<script>
$(document).ready(function() {
var query = 'damnSon';
$.ajax({
url: 'action/{{ $packageSlug }}/' + query,
method: 'GET',
dataType: 'json',
})
.done(function(data) {
console.log(data) //use console.log to debug
$('#slugTb tbody').html(data.table_data); //set table id so that you don't miss the right one
})
.fail(function(err) {
console.log(err) //in case if error happens
})
.always(function() {
console.log( "complete" ); //result despite the response code
});
});
</script>
and controller:
function action($slug, $query)
{
$total_row = 1;
$packageSlug = $slug;
$query = $query;
$output = '<tr>
<td align="center" colspan="1">' . $packageSlug . '</td>
<td align="center" colspan="1">' . $query .'</td>
</tr>';
$data = array(
'table_data' => $output,
'total_data' => $total_row
);
return response()->json($data);
}
Not recommended just because you manually type route in ajax request: url: 'action/{{ $packageSlug }}/' + query if your route changes you have to change it in js.

How to insert and delete record in database which is using dynamic fields Laravel?

I am using Laravel 5. In this application, the staff name can be added and deleted dynamically. For creating new records, all functions run smoothly. However, I have some difficulties in updating the records. In 'edit' page, the staff names created are displayed and can be changed. These names can be updated. But, I put add button and delete button to enable user to add new staff name or delete existing staff name.
My function just can update existing record in database. But the new added staff name not inserted in database. This is my function to update in controller.
public function update(Request $request, $id)
{
$demo = Demo::findOrFail($id);
$demo->tajuk_demo = $request->tajuk_demo;
$demo->syarikat_id = $request->nama_syarikat;
$demo->peralatan_sistem = $request->peralatan_sistem;
$demo->tarikhmasa = $request->tarikhmasa;
$demo->tarikhmasa_tamat = $request->tarikhmasa_tamat;
$demo->tempat_demo = $request->tempat_demo;
$demo->ulasan_demo = $request->ulasan_demo;
$demo->komen_demo = $request->komen_demo;
$demo->update();
$pegawai = $request->all();
// $rekod_id = $pegawai['rekod_id'];
$itemRegistrationID = $pegawai['nama'];
$OperasiID = $pegawai['pangkat'];
$SectionID = $pegawai['bahagian'];
$pegawai_semasa = Pegawai::where('rekod_id', '=', Input::get('rekod_id'))->exists();
$peg_hadir = Pegawai::where('demo_id', '=', $id)
->get();
// Update the existing record
foreach($peg_hadir as $peg){
$key = array_search($peg->rekod_id, $pegawai['rekod_id']);
$peg->itemRegistrationID = $itemRegistrationID[$key];
$peg->OperasiID = $OperasiID[$key];
$peg->SectionID = $SectionID[$key];
$peg->save();
}
if (is_null($pegawai_semasa))
{
// Insert new record into database
$count = count(Input::get('nama'));
// get data
$itemRegistrationID = Input::get('nama');
$OperasiID = Input::get('pangkat');
$SectionID = Input::get('bahagian');
//loop through and save data
for($i = 0; $i < $count; ++$i) {
$pegawai = new Pegawai;
$pegawai->demo_id = $id;
$pegawai->itemRegistrationID = $itemRegistrationID[$i];
$pegawai->OperasiID = $OperasiID[$i];
$pegawai->SectionID = $SectionID[$i];
$pegawai->save();
}
}
else
{
return redirect('demo');
}
}
This is the code in view blade for edit page:
<div class="form-group">
<div class="row">
<input type="button" class="add-row" value="Add">
<button type="button" class="delete-row">Delete</button>
</div>
</div>
<!--mula table -->
<div class="form-group">
<div class="row">
<div class="col-lg-10">
<table class="table table-striped table-bordered" id="pegawaihadir_table" >
<thead>
<tr>
<td class="text-center col-lg-1"><strong>Pilih</strong></td>
<td class="text-center col-lg-1"><strong>Pangkat</strong></td>
<td class="text-center col-lg-3"><strong>Nama</strong></td>
<td class="text-center col-lg-2"><strong>No Badan</strong></td>
<td class="text-center col-lg-2"><strong>Seksyen</strong></td>
<td class="text-center col-lg-2"><strong>No Tel</strong></td>
<td class="text-center col-lg-2"><strong>Ext</strong></td>
</tr>
</thead>
<tbody>
#foreach($PegawaiHadir as $value)
<tr>
<td><input type="checkbox" name="rekod" style="width:20px">
{!! Form::hidden('rekod_id[]', $value['rekod_id'], ['class' => 'form-control']) !!}
</td>
<td class="text-center">{{ Form::text('pangkat[]', $value['OperasiID'], ['class' => 'form-control pangkat', 'readonly' => 'true']) }}</td>
<td>
{{ Form::select('nama[]', $pegawai, $value['itemRegistrationID'], ['class' => 'form-control nama', 'required' => '']) }}
</td>
<td class="text-center">{{ Form::text('no[]', $value['Nobadan'], ['class' => 'form-control no', 'readonly' => 'true']) }}</td>
<td class="text-center">{{ Form::text('bahagian[]', $value['SectionID'], ['class' => 'form-control bahagian', 'readonly' => 'true']) }}</td>
<td class="text-center">{{ Form::text('telefon[]', $value['notelttp'], ['class' => 'form-control telefon', 'readonly' => 'true']) }}</td>
<td class="text-center">{{ Form::text('ext[]', $value['ext'], ['class' => 'form-control ext', 'readonly' => 'true']) }}</td>
</tr>
#endforeach
</tbody>
</table>
</div>
</div>
For dynamic fields, I am using js code to add and delete the record displayed in the page.
<script>
count=1;
$(document).ready(function(){
$(".add-row").click(function(){
var markup = '<tr><td><input type="checkbox" name="rekod" style="width:20px"></td>';
markup += '<td><input type="text" class="form-control pangkat" name="pangkat[]" style="width:100px" readonly></td>';
markup += '<td><select class="form-control select2 nama" name="nama[]" style="width:300px"><option value="">Pilih</option><?php foreach($pegawai as $key => $value):echo '<option value="'.$key.'">'.addslashes($value).'</option>'; endforeach; ?></select></td>';
markup += '<td><input type="text" class="form-control no" name="no[]" style="width:100px" readonly></td>';
markup += '<td><input type="text" class="form-control bahagian" name="bahagian[]" style="width:100px" readonly></td>';
markup += '<td><input type="text" class="form-control telefon" name="telefon[]" style="width:100px" readonly></td>';
markup += '<td><input type="text" class="form-control ext" name="ext[]" style="width:100px" readonly></td></tr>';
$("table tbody").append(markup);
count++;
});
$(document).on('change', 'select.form-control.nama', function() {
var PegID = jQuery(this).val();
var row = $(this);
// alert(PegID);
if(PegID)
{
jQuery.ajax({
context: this,
url : 'get_pegawai/'+PegID,
type : "GET",
dataType : "json",
success:function(data)
{
console.log(data);
$(this).closest('tr').find('td .form-control.pangkat').val(data.operasiname);
$(this).closest('tr').find('td .form-control.no').val(data.Nobadan);
$(this).closest('tr').find('td .form-control.bahagian').val(data.sectionname);
$(this).closest('tr').find('td .form-control.telefon').val(data.notelttp);
$(this).closest('tr').find('td .form-control.ext').val(data.ext);
}
});
}
else
{
$(this).closest('tr').find('td .form-control.pangkat').empty();
$(this).closest('tr').find('td .form-control.no').empty();
$(this).closest('tr').find('td .form-control.bahagian').empty();
$(this).closest('tr').find('td .form-control.telefon').empty();
$(this).closest('tr').find('td .form-control.ext').empty();
}
});
// Find and remove selected table rows
$(".delete-row").click(function(){
$("table tbody").find('input[name="rekod"]').each(function(){
if($(this).is(":checked")){
$(this).parents("tr").remove();
}
});
});
});
</script>
I also doesn't know how to identify the selected staff name to be deleted from existing record in database. I am providing a complete code to ease anyone who want to help to understand better. Thank you.
Make this ajax call into an IIFE
$(function(){
$(document).on('change', 'select.form-control.nama', function() {
var PegID = jQuery(this).val();
var row = $(this);
// alert(PegID);
if(PegID)
{
jQuery.ajax({
context: this,
url : 'get_pegawai/'+PegID,
type : "GET",
dataType : "json",
success:function(data)
{
console.log(data);
$(this).closest('tr').find('td .form-control.pangkat').val(data.operasiname);
$(this).closest('tr').find('td .form-control.no').val(data.Nobadan);
$(this).closest('tr').find('td .form-control.bahagian').val(data.sectionname);
$(this).closest('tr').find('td .form-control.telefon').val(data.notelttp);
$(this).closest('tr').find('td .form-control.ext').val(data.ext);
}
});
}
else
{
$(this).closest('tr').find('td .form-control.pangkat').empty();
$(this).closest('tr').find('td .form-control.no').empty();
$(this).closest('tr').find('td .form-control.bahagian').empty();
$(this).closest('tr').find('td .form-control.telefon').empty();
$(this).closest('tr').find('td .form-control.ext').empty();
}
});
});
And also change update() method to save() method in your controller.

Updating Database Field with AJAX Laravel

I am trying to update my stock level by subtracting the cart item quantity from the product quantity in the database when a user completes an order using the POST method. Everytime I run the method the success function occurs but the field doesnt update doesnt update.
Could anyone tell me why?
My Controller:
public function index ()
{
$products = Product::all();
return view('products', compact('products'));
}
public function cart()
{
return view('cart');
}
public function addToCart($id)
{
$product = Product::find($id);
if(!$product) {
abort(404);
}
$cart = session()->get('cart');
// if cart is empty then this will be the first product
if(!$cart) {
$cart = [
$id => [
"name" => $product->name,
"quantity" => 1,
"price" => $product->unit_price
]
];
session()->put('cart', $cart);
return redirect()->back()->with('success', 'Product added to cart successfully!');
}
// if cart isnt empty then check if this product exist then increment quantity
if(isset($cart[$id])) {
$cart[$id]['quantity']++;
session()->put('cart', $cart);
return redirect()->back()->with('success', 'Product added to cart successfully!');
}
// if item doesnt exist in cart then add to cart with quantity = 1
$cart[$id] = [
"name" => $product->name,
"quantity" => 1,
"price" => $product->unit_price
];
session()->put('cart', $cart);
return redirect()->back()->with('success', 'Product added to cart successfully!');
}
public function update(Request $request)
{
if($request->id and $request->quantity)
{
$cart = session()->get('cart');
$cart[$request->id]["quantity"] = $request->quantity;
session()->put('cart', $cart);
session()->flash('success', 'Cart updated successfully');
}
}
public function remove(Request $request)
{
if($request->id) {
$cart = session()->get('cart');
if(isset($cart[$request->id])) {
unset($cart[$request->id]);
session()->put('cart', $cart);
}
session()->flash('success', 'Product removed successfully');
}
}
public function stock (Request $request)
{
if($request->id and $request->quantity)
{
$cart = session()->get('cart');
$cart[$request->id]['quantity'] = $request->quantity;
$products = Product::all();
$stock = $products->unit_stock;
$quantity = $stock - $cart;
return $quantity;
}
}
My Route:
Route::post('stock', 'ProductController#stock');
My view cart.blade.php:
#extends('layout')
#section('content')
<table id="cart" class="table table-hover table-condensed">
<thead>
<tr>
<th style="width:50%">Product</th>
<th style="width:10%">Price</th>
<th style="width:8%">Quantity</th>
<th style="width:22%" class="text-center">Subtotal</th>
<th style="width:10%"></th>
</tr>
</thead>
<tbody>
<?php $total = 0 ?>
#if(session('cart'))
#foreach(session('cart') as $id => $details)
<?php $total += $details['price'] * $details['quantity'] ?>
<tr>
<td data-th="Product">
<div class="row">
<div class="col-sm-9">
<h4 class="nomargin">{{ $details['name'] }}</h4>
</div>
</div>
</td>
<td data-th="Price">${{ $details['price'] }}</td>
<td data-th="Quantity">
<input type="number" value="{{ $details['quantity'] }}" class="form-control quantity" />
</td>
<td data-th="Subtotal" class="text-center">${{ $details['price'] * $details['quantity'] }}</td>
<td class="actions" data-th="">
<button class="btn btn-info btn-sm update-cart" data-id="{{ $id }}"><i class="fa fa-refresh"></i></button>
<button class="btn btn-danger btn-sm remove-from-cart" data-id="{{ $id }}"><i class="fa fa-trash-o"></i></button>
</td>
</tr>
#endforeach
#endif
</tbody>
<tfoot>
<tr class="visible-xs">
<td class="text-center"><strong>Total {{ $total }}</strong></td>
</tr>
<tr>
<td><i class="fa fa-angle-left"></i> Continue Shopping</td>
<td colspan="2" class="hidden-xs"></td>
<td class="hidden-xs text-center"><strong>Total ${{ $total }}</strong></td>
</tr>
</tfoot>
<div class="row">
<div class="btn col-md-12">
Test
</div>
</div>
</table>
<script type="text/javascript">
$("#order-complete").click(function (e){
e.preventDefault();
var ele = $(this);
$.ajax({
url: '{{ url('stock') }}',
method: "post",
data: {_token: '{{ csrf_token() }}'},
success: function () {
window.location.reload();
}
});
});
</script>
#endsection
I can see a couple of potential issues that might be causing this. Firstly, it looks like you're trying to set stock against all of the products in your database in one go by loading a collection containing them all, rather than looping/loading the ones contained in the order ($request). You do this here;
$products = Product::all();
Then you try to change the stock for all products in the collection here;
$stock = $products->unit_stock;
$quantity = $stock - $cart;
I imagine you should have a collection of products in your $cart variable that you should loop over and load to manipulate. Some pseudo code to illustrate my point;
foreach($product in $cart){
$loadedProduct = Product::find($product);
$loadedProduct->stock = $loadedProduct->stock - $product["quantity"];
$loadedProduct->save();
}
You also aren't saving any products in the code you provided. There's an example of this in the pseudo code above.
I can spot a few mistakes from your code.
Lets focus on the function that the ajax request calls.
This line here tells me that there is a data id and quantity being sent.
if($request->id and $request->quantity)
From the look of your Route, it is in the body. But in the ajax function, you're didn't include any data except the csrf token. Try adding id and quantity data. This is just an assumption of the value.
data: {_token: '{{ csrf_token() }}', id: 6, quantity: 2},
Secondly, this function returns a collections of product.
$products = Product::all();
So if you would like to modify a product you must access its index. e.g.
$products[0]->unit_stock = 3;
$products[0]->save();
Or what Lewis has stated, you can use a foreach loop to iterate every object in the collection

Yii2: Nested Dynamic Form wbraganca added more fields

I am using wbragnaca dynamic form for yii2, add & remove button working properly on create, flawless. But when I update on the Instrument the nested form which is the Item is that when I click on the add button it adds 3 fields instead of just one.
Here is the form before I click on the Items - Statement button:
Instrument Form before
Here is after I click the add button on the Item:
Instrument Form after
Here is my database design:
DATABASE
Here is my code,
_form.php
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
use wbraganca\dynamicform\DynamicFormWidget;
/* #var $this yii\web\View */
/* #var $model app\models\Instrument */
/* #var $form yii\widgets\ActiveForm */
?>
<?php $form = ActiveForm::begin(['id' => 'dynamic-form']); ?>
<div>
<?= $form->field($modelInstrument, 'name')->textInput(['maxlength' => true,'style'=>'width: 50%', 'placeholder'=>'Name'])->label(false) ?>
<?= $form->field($modelInstrument, 'description')->textArea(['rows' => '6', 'placeholder'=>'Description'])->label(false) ?>
</div>
<div class="padding-v-md">
<div class="line line-dashed"></div>
</div>
<br/>
<?php DynamicFormWidget::begin([
'widgetContainer' => 'dynamicform_wrapper',
'widgetBody' => '.container-items',
'widgetItem' => '.section-item',
'min' => 1,
'insertButton' => '.add-section',
'deleteButton' => '.remove-section',
'model' => $modelsSection[0],
'formId' => 'dynamic-form',
'formFields' => [
'name',
'description',
],
]); ?>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th >Sections</th>
<th style="width: 650px; height: 30px;">Items</th>
<th class="text-center" style="width: 30px; height: 30px;">
<button type="button" class="add-section btn btn-success btn-xs"><span class="glyphicon glyphicon-plus" style="font-size: 10px"></span></button>
</th>
</tr>
</thead>
<tbody class="container-items">
<?php foreach ($modelsSection as $indexSection => $modelSection): ?>
<tr class="section-item">
<td class="vcenter">
<?php
// necessary for update action.
if (! $modelSection->isNewRecord) {
echo Html::activeHiddenInput($modelSection, "[{$indexSection}]id");
}
?>
<?= $form->field($modelSection, "[{$indexSection}]name")->label(false)->textInput(['placeholder'=>"Name"]) ?>
<?= $form->field($modelSection, "[{$indexSection}]description")->label(false)->textArea(['rows' => '6', 'placeholder'=>'Description']) ?>
</td>
<td>
<?= $this->render('_form-item', [
'form' => $form,
'indexSection' => $indexSection,
'modelsItem' => $modelsItem[$indexSection],
]) ?>
</td>
<td class="text-center vcenter" style="width: 40px; verti">
<button type="button" class="remove-section btn btn-danger btn-xs"><span class="glyphicon glyphicon-minus" style="font-size: 10px"></span></button>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php DynamicFormWidget::end(); ?>
<div class="form-group">
<?= Html::submitButton($modelInstrument->isNewRecord ? 'Create' : 'Update', ['class' => 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
_form-item.php
<?php
use yii\helpers\Html;
use wbraganca\dynamicform\DynamicFormWidget;
?>
<?php DynamicFormWidget::begin([
'widgetContainer' => 'dynamicform_inner',
'widgetBody' => '.container-rooms',
'widgetItem' => '.room-item',
'min' => 1,
'insertButton' => '.add-item',
'deleteButton' => '.remove-item',
'model' => $modelsItem[0],
'formId' => 'dynamic-form',
'formFields' => [
'statement'
],
]); ?>
<table class="table table-bordered">
<thead>
<tr>
<th >Statements</th>
<th class="text-center">
<button type="button" class="add-item btn btn-success btn-xs"><span class="glyphicon glyphicon-plus" style="font-size: 10px"></span></button>
</th>
</tr>
</thead>
<tbody class="container-rooms">
<?php foreach ($modelsItem as $indexItem => $modelItem): ?>
<tr class="room-item">
<td class="vcenter">
<?php
// necessary for update action.
if (! $modelItem->isNewRecord) {
echo Html::activeHiddenInput($modelItem, "[{$indexSection}][{$indexItem}]id");
}
?>
<?= $form->field($modelItem, "[{$indexSection}][{$indexItem}]statement")->label(false)->textInput(['maxlength' => true]) ?>
</td>
<td class="text-center vcenter" style="width: 40px;">
<button type="button" class="remove-item btn btn-danger btn-xs"><span class="glyphicon glyphicon-minus" style="font-size: 10px"></span></button>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php DynamicFormWidget::end(); ?>
InstrumentController.php actionUpdate
public function actionUpdate($id)
{
$modelInstrument = $this->findModel($id);
$modelsSection = $modelInstrument->sections;
$modelsItem = [];
$oldItems = [];
if (!empty($modelsSection)) {
foreach ($modelsSection as $indexSection => $modelSection) {
$items = $modelSection->items;
$modelsItem[$indexSection] = $items;
$oldItems = ArrayHelper::merge(ArrayHelper::index($items, 'id'), $oldItems);
}
}
if ($modelInstrument->load(Yii::$app->request->post())) {
// reset
$modelsItem = [];
$oldSectionIDs = ArrayHelper::map($modelsSection, 'id', 'id');
$modelsSection = Model::createMultiple(Section::classname(), $modelsSection);
Model::loadMultiple($modelsSection, Yii::$app->request->post());
$deletedSectionIDs = array_diff($oldSectionIDs, array_filter(ArrayHelper::map($modelsSection, 'id', 'id')));
// validate Instrument and Section models
$valid = $modelInstrument->validate();
$valid = Model::validateMultiple($modelsSection) && $valid;
$itemsIDs = [];
if (isset($_POST['Item'][0][0])) {
foreach ($_POST['Item'] as $indexSection => $items) {
$itemsIDs = ArrayHelper::merge($itemsIDs, array_filter(ArrayHelper::getColumn($items, 'id')));
foreach ($items as $indexItem => $item) {
$data['Item'] = $item;
$modelItem = (isset($item['id']) && isset($oldItems[$item['id']])) ? $oldItems[$item['id']] : new Item;
$modelItem->load($data);
$modelsItem[$indexSection][$indexItem] = $modelItem;
$valid = $modelItem->validate();
}
}
}
$oldItemsIDs = ArrayHelper::getColumn($oldItems, 'id');
$deletedItemsIDs = array_diff($oldItemsIDs, $itemsIDs);
if ($valid) {
$transaction = Yii::$app->db->beginTransaction();
try {
if ($flag = $modelInstrument->save(false)) {
if (! empty($deletedItemsIDs)) {
Item::deleteAll(['id' => $deletedItemsIDs]);
}
if (! empty($deletedSectionIDs)) {
Section::deleteAll(['id' => $deletedSectionIDs]);
}
foreach ($modelsSection as $indexSection => $modelSection) {
if ($flag === false) {
break;
}
$modelSection->instrument_id = $modelInstrument->id;
if (!($flag = $modelSection->save(false))) {
break;
}
if (isset($modelsItem[$indexSection]) && is_array($modelsItem[$indexSection])) {
foreach ($modelsItem[$indexSection] as $indexItem => $modelItem) {
$modelItem->section_id = $modelSection->id;
if (!($flag = $modelItem->save(false))) {
break;
}
}
}
}
}
if ($flag) {
$transaction->commit();
return $this->redirect(['view', 'id' => $modelInstrument->id]);
} else {
$transaction->rollBack();
}
} catch (Exception $e) {
$transaction->rollBack();
}
}
}
return $this->render('update', [
'modelInstrument' => $modelInstrument,
'modelsSection' => (empty($modelsSection)) ? [new Section] : $modelsSection,
'modelsItem' => (empty($modelsItem)) ? [[new Item]] : $modelsItem
]);
}
I copy the code from wbraganca's website. I change the code according to my need. But the update, just like I said when I want to update and add more Items on my Section the field adds 3 fields than just one.
I read the documentation and still I cant find the error.
Here is the Video to what happen when I click on the add button

save model and ajax in one action yii2

My problem, I don't know how to set $model->code_reg when I use Ajax post. I want save my model code_reg for looping for my ajax post. But its my controller create not work save it
This is my form:
<div class="form-group">
<?= $form->field($model, 'code_reg')->textInput(['readonly' => true]) ?>
</div> <!--I'm using random code and It's was display for this-->
<table id="sampleTbl", class="table table-striped table-bordered">
<thead>
<th>Name</th>
<th>Age</th>
</thead><tbody>
<tr>
<td>William</td>
<td>29</td>
</tr><tr>
<td>Nency</td>
<td>25</td>
</tr>
</tbody>
</table>
<div class="form-group">
<?= Html::submitButton('Create',['class' => 'btn btn-success', 'id' => 'idOfButton']) ?>
</div>
This is my jQuery function:
$('#idOfButton').click(function(){
var TableData = new Array();
$('#sampleTbl tr').each(function(row, tr){
TableData[row]={
'name' : $(tr).find('td:eq(0)').text(),
'age' : $(tr).find('td:eq(1)').text()
}
});
TableData.shift(); // first row will be empty - so remove
var jsonEncode = JSON.stringify(TableData);
// alert(jsonEncode);
$.ajax({
type: "POST",
data: "pTableData=" + jsonEncode,
success: function(msg){
// alert(msg);
},
});
});
This is my controller actionCreate():
$model = new Mutiplearray();
if(Yii::$app->request->isAjax) {
$tableData = stripcslashes($_POST['pTableData']);
$tableData = json_decode($tableData, true);
foreach ($tableData as $key) {
$model->isNewRecord = true;
$model->id = NULL;
$model->name = $key['name'];
$model->age = $key['age'];
$model->code_reg = $model->code_reg; // <---This is my problem I can't save it `code_reg` for ajax looping
$model->save();
}
return $this->redirect(['index']);
} else {
return $this->render('create', [
'model' => $model,
]);
}
I got not set for code_reg when I use like this. How to save model when I use ajax too?

Categories