I am new to Laravel and trying to add multiple record dynamically with images. If I keep only the image fields the records are getting saved to the database successfully but if I add other fields (subject) the record is not getting saved to database. Please help
UI and Error
Error Messages - Trying to access array offset on value of type null
UI and Error Image
The following is my Welcome.blade.php file
<!-- js -->
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta3/dist/js/bootstrap.bundle.min.js"></script>
<script type="text/javascript">
var i = 0;
$("#dynamic-ar").click(function() {
++i;
$("#dynamicAddRemove").append('<tr><td><input type="text" name="addMoreInputFields[' + i +
'][studentname]" placeholder="Enter your Name" class="form-control" /></td><td><input type="text" name="addMoreInputFields[' +
i +
'][subject]" placeholder="Enter your subject" class="form-control" /></td><td><input type="file" id="image" name="addMoreInputFields[' +
i +
'][image]" placeholder="Enter your image" class="form-control" /></td><td><button type="button" class="btn btn-danger remove-input-field">Remove</button></td></tr>'
);
});
$(document).on('click', '.remove-input-field', function() {
$(this).parents('tr').remove();
});
</script>
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Add Multiple records</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta3/dist/css/bootstrap.min.css" rel="stylesheet">
<style>.container { max-width: 600px;}</style>
</head>
<body>
<div class="container">
<form action="{{ url('store-input-fields') }}" method="POST" enctype="multipart/form-data">
#csrf
#if ($errors->any())
<div class="alert alert-danger" role="alert">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
#if (Session::has('success'))
<div class="alert alert-success text-center">
<p>{{ Session::get('success') }}</p>
</div>
#endif
<table class="table table-bordered" id="dynamicAddRemove">
<tr>
<th>studentname</th>
<th>Subject</th>
<th>Image</th>
<th>Action</th>
</tr>
<tr>
<td><input type="text" name="addMoreInputFields[0][studentname]" placeholder="Enter studentname" class="form-control" /></td>
<td><input type="text" name="addMoreInputFields[0][subject]" placeholder="Enter subject" class="form-control" /></td>
<td><input type="file" name="addMoreInputFields[0][image]" placeholder="Enter image" class="form-control" /></td>
<td><button type="button" name="add" id="dynamic-ar" class="btn btn-outline-primary">Add More</button></td>
</tr>
</table>
<button type="submit" class="btn btn-outline-success btn-block">Save</button>
</form>
</div>
</body>
</html>
The controller file code
namespace App\Http\Controllers;
use App\Models\Student;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
class StudentController extends Controller
{
public function index()
{
return view('welcome');
}
public function store(Request $request){$request->validate([
'addMoreInputFields.*.studentname' => 'required',
'addMoreInputFields.*.subject' => 'required',
'addMoreInputFields.*.image' =>
'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
]);
foreach ($request->addMoreInputFields as $key => $value) {
if ($files = $request->file('addMoreInputFields.*.image')) {
$destinationPath = public_path('/images/'); // upload path
foreach ($files as $img) {
// Upload Image
$profileImage = uniqid() . '_' . date('d-m-Y') . '_' . microtime(true) . '_' . $img->getClientOriginalName();
try {
if (!Storage::exists('images/' . $profileImage)) {
$img->move($destinationPath, $profileImage);
}
} catch (\Exception$e) {
return $e->getMessage();
}
$imagemodel = new Student();
$imagemodel->image = "$profileImage";
//$imagemodel->subject = "$subject";
//$imagemodel -> subject = $request->input('addMoreInputFields.*.subject.'.$value);
$imagemodel->subject = $request->subject[$value];
$imagemodel->studentname = $destinationPath . $profileImage;
$imagemodel->save();
}
}
}
return back()->with('success', 'New reord has been added.');
}
}
The following is my model file code
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Student extends Model
{
use HasFactory;
protected $fillable = [
'studentname',
'subject',
'image',
];
}
The migration file
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('students', function (Blueprint $table) {
$table->id();
$table->string('studentname');
$table->string('subject');
$table->string('image')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('students');
}
};
Related
I’ve just implemented a Livewire data table based on the Caleb’s tutorial on Laracasts. Everything works as expected when working with just one model. However I’m stuck trying to apply sorting and searching to a foreign model field.
User model:
namespace App;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable
{
use Notifiable;
use HasRoles;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
/**
* Get the user's email verified status.
*
* #param string $value
* #return string
*/
public function getEmailVerifiedAtAttribute($value)
{
if ($value == null) {
return "No";
}
return $value;
}
public function getRoleAttribute()
{
if($this->roles()->count() > 0) {
return $this->roles()->first()->name;
} else {
return "Usuario registrado";
}
}
public static function search($query)
{
return empty($query) ? static::query()
: static::where('name', 'like', '%'.$query.'%')
->orWhere('email', 'like', '%'.$query.'%');
}
}
Tried adding another orWhere() clause to the search() method in some ways. None worked. Now I left just the default ones.
Livewire controller:
namespace App\Http\Livewire\Users;
use Livewire\Component;
use Livewire\WithPagination;
class Table extends Component
{
use WithPagination;
public $perPage;
public $sortField;
public $sortAsc;
public $search;
public function mount()
{
$this->perPage = 10;
$this->sortField = 'name';
$this->sortAsc = true;
$this->search = '';
}
public function sortBy($field)
{
if ($this->sortField === $field) {
$this->sortAsc = ! $this->sortAsc;
} else {
$this->sortAsc = true;
}
$this->sortField = $field;
}
public function updatingPerPage()
{
$this->resetPage();
}
public function render()
{
return view('livewire.users.table', [
'users' => \App\User::search($this->search)
->with('roles')
->orderBy($this->sortField, $this->sortAsc ? 'asc' : 'desc')
->paginate($this->perPage),
]);
}
}
Livewire view:
<div>
<div class="row mb-4">
<div class="col form-inline">
Mostrar
<select wire:model="perPage" class="form-control form-control-sm custom-select custom-select-sm">
<option>10</option>
<option>100</option>
<option>1000</option>
</select>
registros
</div>
<div class="col-sm-3">
<input wire:model="search" class="form-control form-control-sm" type="text" placeholder="Buscar usuarios...">
</div>
</div>
<div class="table-responsive mb-4" >
<div class="table-header">
<table class="table table-sm text-nowrap" role="grid">
<thead>
<tr>
<th width="30%">
<a wire:click.prevent="sortBy('name')" role="button" href="#">
Nombre
#include('partials._sort-icon', ['field' => 'name'])
</a>
</th>
<th width="30%">
<a wire:click.prevent="sortBy('email')" role="button" href="#">
Correo electrónico
#include('partials._sort-icon', ['field' => 'email'])
</a>
</th>
<th width="30%">
<a wire:click.prevent="sortBy('')" role="button" href="#">
Rol
#include('partials._sort-icon', ['field' => ''])
</a>
</th>
<th></th>
</tr>
</thead>
</table>
</div>
<div class="table-body">
<table class="table table-sm table-hover text-nowrap" role="grid">
<tbody>
#foreach ($users as $user)
<tr>
<td width="30%">{{ $user->name }}</td>
<td width="30%">{{ $user->email }}</td>
<td width="30%">{{ $user->role }}</td>
<td>
<form method="POST" action="{!! route('backend.users.user.destroy', $user->id) !!}" accept-charset="UTF-8">
<input name="_method" value="DELETE" type="hidden">
{{ csrf_field() }}
<div class="btn-group btn-group-xs float-right" role="group">
#can('users.show')
<a href="{{ route('backend.users.user.show', $user->id ) }}" class="btn btn-outline-default btn-xs" title="{{ trans('users.show') }}">
<i class=" fas fa-fw fa-eye" aria-hidden="true"></i>
</a>
#endcan
#can('users.edit')
<a href="{{ route('backend.users.user.edit', $user->id ) }}" class="btn btn-outline-default btn-xs" title="{{ trans('users.edit') }}">
<i class=" fas fa-fw fa-pencil-alt" aria-hidden="true"></i>
</a>
#endcan
#can('users.destroy')
<button type="submit" class="btn btn-outline-default btn-xs" title="{{ trans('users.delete') }}" onclick="return confirm("{{ trans('users.confirm_delete') }}")">
<i class=" fas fa-fw fa-trash-alt" aria-hidden="true"></i>
</button>
#endcan
</div>
</form>
</td>
</tr>
#endforeach
</tbody>
</table>
</div>
</div>
<div class="table-footer">
<div class="text-muted">
Showing {{ $users->firstItem() }} to {{ $users->lastItem() }} out of {{ $users->total() }} results
</div>
<div>
{{ $users->links() }}
</div>
</div>
</div>
Tried also some ways to pass an argument to the sortBy() and [‘field’ => ‘’] on the role column. Now I left them with empty strings.
I know, this issue probably is more related to Laravel than Livewire, but I’ll really appreciate any help.
Update:
Solved using the Laravel Query Builder instead of Eloquent.
After creating a Laravel site with user login, I wanted to add file upload ability. I followed a simple tutorial but when it came to do php artisan migrate it didn’t work because Base table or view already exists so I created an images table manually in MySQL.
Finally, I navigated to my websites image upload page http://localhost/sites/mywebsite/public/image and attached an image. The error I got was The POST method is not supported for this route. Supported methods: GET, HEAD.
This is the line in my image.blade.php file:
<form action="{{ url('save') }}" method="post" accept-charset="utf-8" enctype="multipart/form-data">
Note; When I created an images table manually in MySQL I only added 'id' and 'image' columns and I wasn't 100% sure how to format them.
Any help very much appreciated.
Here's my ImageController
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Validator, Redirect, Response, File;
use App\Image;
class ImageController extends Controller
{
public function index()
{
return view('image');
}
public function save(Request $request)
{
request()->validate([
'image' => 'required',
'image.*' => 'image|mimes:jpeg,png,jpg,gif,svg|max:2048'
]);
if ($image = $request->file('image')) {
foreach ($image as $files) {
$destinationPath = 'public/image/'; // upload path
$profileImage = date('YmdHis') . "." . $files->getClientOriginalExtension();
$files->move($destinationPath, $profileImage);
$insert[]['image'] = "$profileImage";
}
}
$check = Image::insert($insert);
return Redirect::to("image")->withSuccess('Great! Image has been successfully uploaded.');
}
}
Image.blade.php
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>Laravel 5.7 Multiple Image Upload Example - Tutsmake.com</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css" />
<style>
.container {
padding: 10%;
text-align: center;
}
</style>
</head>
<body>
<div class="container">
<h2 style="margin-left: -48px;">Laravel 5.7 Multiple Image Upload Example - Tutsmake.com</h2>
<br>
<br>
#if ($message = Session::get('success'))
<div class="alert alert-success alert-block">
<button type="button" class="close" data-dismiss="alert">×</button>
<strong>{{ $message }}</strong>
</div>
<br>
#endif
#if (count($errors) > 0)
<div class="alert alert-danger">
<strong>Opps!</strong> There were something went wrong with your input.
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
<br>
#endif
<form action="{{ url('save') }}" method="post" accept-charset="utf-8" enctype="multipart/form-data">
#csrf
<div class="avatar-upload col-6">
<div class=" form-group avatar-edit">
<input type='file' id="image" name="image[]" accept=".png, .jpg, .jpeg" />
<label for="imageUpload"></label>
</div>
</div>
<div class="form-group col-3">
<button type="submit" class="btn btn-success">Submit</button>
</div>
</form>
</div>
</body>
</html>
Migration table
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateImagesTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('images', function (Blueprint $table) {
$table->increments('id');
$table->increments('image');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('images');
}
}
Follow Any Method :
<form action="{{ url('save') }}" method="get" accept-charset="utf-8" enctype="multipart/form-data">
And Change Migartion $table->text('image');
OR
Route::post('save', 'ImageController#save');
And Change Migartion $table->text('image');
You need to create a POST method route in routes/web.php.
A get route does not support posting form data
Route::post('save', 'ImageController#save');
Also, the image column in your database should be a string, an integer can't hold a path to a file
$table->string('image');
But you can't insert an array to a string column anyway so you should move the Model create method inside the foreach loop
foreach ($image as $files) {
$destinationPath = 'public/image/'; // upload path
$profileImage = date('YmdHis') . "." . $files->getClientOriginalExtension();
$files->move($destinationPath, $profileImage);
Image::insert($profileImage);
}
i am new to laravel and i want to ask how to display multiple images that is located in the database.
i have already inserted images in my database through this code
here is my try.blade.php.
<h3>Upload Image</h3>
<form name="form" action="imageupload" method="POST" enctype="multipart/form-
data">
<input type="hidden" name="_token" value="{{csrf_token()}}">
<input type="file" name="img[]" multiple="true">
<br><br>
<input type="submit" name="ok" value="Upload">
</form>
#if(Session::has('msg'))
{{ Session::get('msg')}}
#endif
and here is my web.php
Route::get('imageup','userLog#imageup');
Route::post('imageupload','userLog#imageupup');
and here is my controller
public function imageup(){
return view('try');
}
public function imageupup(Request $request){
if($request->hasFile('img')){
$image_array = $request->file('img');
$array_len = count($image_array);
for($i=0; $i<$array_len; $i++){
$image_size = $image_array[$i]->getClientSize();
$image_ext = $image_array[$i]->getClientOriginalExtension();
$new_image_name = rand(1234,9999).".".$image_ext;
$destination_path = public_path('/images');
$image_array[$i]->move($destination_path,$new_image_name);
$tab = new Tab1;
$tab->image_size = $image_size;
$tab->image_name = $new_image_name;
$tab->save();
}
return back()->with('msg','Images Uploade Successfully');
}
else{
return back()->with('msg','Please choose any image file');
}
}
this is the code in my table
Schema::create('tab1s', function (Blueprint $table) {
$table->increments('id');
$table->string('image_name');
$table->string('image_size');
$table->timestamps();
});
i hope someone can help me.
#foreach(json_decode($posts->images, true) as $images)
<div class="col-lg-2 col-md-2 col-sm-2">
<a href="{{ URL::to('img/offers/'.$images)}}"
class="portfolio-box">
<img src="{{ URL::to('img/offers/'.$images)}}"
class="img-responsive" alt="--">
<div class="portfolio-box-caption">
<div class="portfolio-box-caption-content">
<span class="glyphicon glyphicon-zoom-in"
style="font-size: 80px"></span>
</div>
</div>
</a>
</div>
#endforeach
I want to submit some form information into my table, but this error is showing, if i do Route::resource('userinfo','infoController#index'); the error gone, but i can't insert data, what will be the solution.
My controller
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\infomodel;
class infoController extends Controller
{
public function index()
{
$alldata = infomodel::all();
return $alldata;
}
public function create()
{
return view('userinfo.create');
}
public function store(Request $request)
{
$input = $request->all();
infomodel:: create($input);
return redirect('infomodel');
}
}
My model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class infomodel extends Model
{
Protected $table = "info";
protected $fillable = ['name', 'email', 'age', 'hometown'];
}
My route web.php
<?php
Route::resource('userinfo','infoController');
Route::get('/solid', function () {
return view('solid.index');
});
This is view create.blade.php
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<title>Userinfo</title>
</head>
<body>
<div class="container" style="width:350px; margin:0 auto;
margin-top:25px;">
{!! Form::open(['route' => 'userinfo.store']) !!}
<div class="form-group">
<label for="name">Enter Your name</label>
<input type="text" class="form-control" name="name" placeholder="Enter name">
</div>
<div class="form-group">
<label for="email">Email address</label>
<input type="email" class="form-control" name= "email" placeholder="Enter email">
</div>
<div class="form-group">
<label for="age">Age</label>
<input type="number" class="form-control" name="age" placeholder="Enter age">
</div>
<div class="form-group">
<label for="exampleInputEmail1">Hometown</label>
<input type="text" class="form-control" name="hometown" placeholder="Enter hometown">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</div>
{!! Form::close() !!}
</div>
</body>
</html>
The problem is in your store method
public function store(Request $request)
{
$input = $request->all();
infomodel:: create($input);
return redirect('infomodel');
}
You redirect user to non-existing route infomodel.
Try this
public function store(Request $request)
{
$input = $request->all();
infomodel:: create($input);
// You can try 'return back()' as well
return redirect()->route('userinfo.index');
}
I am working on this project from a tutorial but i get this TokenMismatchException in VerifyCsrfToken.php line 67 Error when i try to add new category to the view i tried everything on the internet as :-
adding
<input type="hidden" name="_token" value="{{ Session::token() }}">
or adding
<meta name="csrf-token" content="{{ csrf_token() }}" />
to my code also removed th CSRF middileware nothing worked
here is the original code
The View
#extends('layouts.admin-master')
#section('styles')
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
<link rel="stylesheet" href="{{ URL::secure('src/css/categories.css') }}" type="text/css" />
#endsection
#section('content')
<div class="container">
<section id="category-admin">
<form action="" method="post">
<div class="category-input">
<label for="name">Category Name</label>
<input type="text" name="name" id="name">
<button type="submit" class="btn">Create Category</button>
</div>
</form>
</section>
<section class="list">
#foreach($categories as $category)
<article>
<div class="category-info" data-id="{{ $category->id }}">
<h3>{{ $category->name }}</h3>
</div>
<div class="edit">
<nav>
<ul>
<li class="category-edit"><input type="text"></li>
<li>Edit</li>
<li>Delete</li>
</ul>
</nav>
</div>
</article>
#endforeach
</section>
#if($categories->lastPage() > 1)
<section class="pagination">
#if($categories->currentPage() !== 1)
<i class="fa fa-caret-left"></i>
#endif
#if($categories->currentPage() !== $categories->lastPage())
<i class="fa fa-caret-right"></i>
#endif
</section>
#endif
</div>
#endsection
#section('scripts')
<script type="text/javascript">
var token = "{{ Session::token() }}";
</script>
<script type="text/javascript" src="{{ URL::secure('src/js/categories.js') }}"></script>
#endsection
Here is the Controller
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Category;
use Illuminate\Support\Facades\Response;
class CategoryController extends Controller{
public function getCategoryIndex()
{
$categories = Category::orderBy('created_at', 'desc')->paginate(5);
return view('admin.blog.categories',['categories' => $categories]);
}
public function postCreateCategory(Request $request)
{
$this->validate($request, [
'name' => 'required|unique:categories'
]);
$category = new Category();
$category->name = $request['name'];
if($category->save()){
return Response::json(['message' => 'Category Created Successfully!'], 200);
}
return Response::json(['message' => 'Error During Creation'], 404);
}
}
thats the Js file
var docReady = setInterval(function(){
if (document.readyState !== "complete"){
return;
}
clearInterval(docReady);
document.getElementsByClassName('btn')[0].addEventListener('click',createNewCategory);
var _token = document.getElementsByName('_token')[0].value;
//and append the value to form data
formdata.append("_token", _token);
},100);
function createNewCategory(event) {
event.preventDefault();
var name = event.target.previousElementSibling.value;
if(name.length === 0) {
alert("Please A Valid Category Name!");
return;
}
ajax("POST","/admin/blog/category/create", "name=" + name, newCategoryCreated, [name]);
}
function newCategoryCreated(params, success, responseObj){
location.reload();
}
function ajax(method, url, params, callback, callbackParams){
var http;
if (window.XMLHttpRequest){
http = new XMLHttpRequest();
}else {
http = new ActiveXObject("Microsoft.XMLHTTP");
}
http.onreadystatechange = function(){
if (http.readyState == XMLHttpRequest.DONE){
if (http.status == 200){
var obj = JSON.parse(http.responseText);
callback(callbackParams, true, obj);
}else if(http.status ==400){
alert("Category Could Not Be Saved. Please Try Again");
callback(callbackParams, false);
}else {
var obj = JSON.parse(http.responseText);
if (obj.message){
alert(obj.message);
}else {
alert("Please Check The Name");
}
}
}
}
http.open(method, baseUrl + url, true);
http.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
http.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
http.send(params + "&_token=" + token);
}
and that`s the routes
Route::post('/blog/category/create',[
'uses' => 'CategoryController#postCreateCategory',
'as' => 'admin.blog.category.create'
]);
Route::get('/blog/categories',[
'uses' => 'CategoryController#getCategoryIndex',
'as' => 'admin.blog.categories'
]);
PLEASE Help me with this Error I have been stuck with it for three days Now
Set your post_max_size = 100 mb or as much you require.
Add <input type="hidden" name="_token" value="{{ csrf_token() }}"> before every input field like
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<input type="text" name="last_name" id="last_name" placeholder="Last Name" class="form-control">