In acest tutorial vom crea si testa o aplicatie simpla Laravel CRUD (Create-Read-Update-Delete) cu Ajax; avand sistem de Autentificare Admin si Paginare, Cu datele stocate in baza de date MySQL.
Detaliile sunt in comentariile din cod.
- Puteti folosi acest script ca punct de inceput pentru un CMS.

• Ca sa testati acest script, clic pe: Demo: Laravel Ajax MySQL CRUD.

• Pentru a descarca fisierele cu codurile prezentate aici, apasati pe: Download: Laravel Ajax MySQL CRUD.

1. Vom crea manual un "resource" controller numit CrudAjax.
Copiati urmatorul cod si salvati-l in fisierul "app/Http/Controllers/CrudAjax.php".
<?php
namespace App\Http\Controllers;

use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;

//resource controller to Insert, Update, Show, delete pages in mysql
class CrudAjax extends Controller {
 //HERE add your Name and Password for Admin authentication; and the table name
 protected $admin_name ='admin';
 protected $admin_pass ='pass';
 protected $table ='pages';

 function __construct(Request $request){
 $this->middleware(function ($request, $next){
 //check if admin logged-in; redirect to '/crud' if not session 'admin_logg'
 //else, if table not exist in database, display link to create it
 if($request->path() !='crud' && $request->path() !='crud/adminlogg' && $request->path() !='crud/adminloggout'){
 if(!session()->has('admin_logg') || session()->get('admin_logg') != ($this->admin_name .$this->admin_pass)){
 return redirect('/crud')->send();
 }
 }
 else if(session()->has('admin_logg') && !Schema::hasTable($this->table)){
 exit('<h4>The table: '. $this->table .' not exist in your database.</h4><a href="/crud/createtable">Click Here to Create the Table</a>');
 }

 return $next($request);
 });
 }

 //responds to /crud/adminlogg
 //sets session with 'admin_logg'
 //@return redirect to /crud
 public function adminLogg(Request $request){
 $resp ='Not valid request';
 if($request->has(['name', 'pass'])){
 if($request->name ==$this->admin_name && $request->pass ==$this->admin_pass){
 $request->session()->put('admin_logg', ($this->admin_name .$this->admin_pass));
 $resp ='Welcome Admin';
 }
 else $resp ='Not correct Name and Password.';
 }

 return redirect('/crud')->with('resp', $resp);
 }

 //responds to /crud/adminloggout
 //delete session with 'admin_logg'
 //@return redirect to /crud
 public function adminLoggOut(Request $request){
 if($request->session()->has('admin_logg')){
 $request->session()->forget('admin_logg');
 $resp ='By-By Admin';
 }
 else $resp ='Not Admin logged';

 return redirect('/crud')->with('resp', $resp);
 }

 //responds to /crud/createtable
 //create the table if not exists
 //@return string
 public function createTable(){
 $sql ='CREATE TABLE IF NOT EXISTS '. $this->table .' (id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, title VARCHAR(100), description VARCHAR(150), content MEDIUMTEXT, dtreg TIMESTAMP NOT NULL DEFAULT NOW()) CHARACTER SET utf8 COLLATE utf8_general_ci';
 if(DB::statement($sql)) return redirect('/crud')->with('resp', 'Table: '. $this->table .' successfully created');
 else return 'Unable to create table: '. $this->table;
 }

 //responds to post: /crud/pages
 //@return json with pages data
 public function getPages(){
 $pages = DB::table($this->table)->get();
 return response()->json($pages);
 }

 //@return view() with list of pages
 public function index(){
 $pages = session()->has('admin_logg') ? DB::table($this->table)->select(DB::raw('*, DATE_FORMAT(dtreg, "%Y-%m-%d") as dtreg'))->paginate(20) :[];
 return view('crud.index',['title'=>'Ajax CRUD', 'pages'=>$pages]);
 }

 //Not needed with Ajax
 //@return void
 public function create(){
 //
 }

 //Insert /Store a newly created page
 //@return array
 public function store(Request $request){
 $re['er'] ='No valid request';
 if(session()->has('admin_logg') && $request->has(['title', 'description', 'content'])){
 $vals =['title'=>$request->title, 'description'=>$request->description, 'content'=>$request->content];
 $id = DB::table($this->table)->insertGetId($vals);

 if($id >0) $re =['re'=>'Data saved, - <a href="/crud/'.$id.'" target="_blank">See the page</a>'];
 else $re['er'] ='Unable to insert data in table: '. $this->table;
 }
 return $re;
 }

 //Display the specified page
 //@param int $id
 //@return view
 public function show($id){
 $page = DB::table($this->table)->where('id', $id)->get();

 //keep data for variables in view
 $page =[
 'title'=>$page[0]->title,
 'description'=>$page[0]->description,
 'content'=>$page[0]->content
 ];
 return view('crud.page', $page);
 }

 //Not needed with Ajax
 //@param int $id
 //@return void
 public function edit($id){
 //
 }

 //Update the specified resource in storage.
 //@param Request $request
 //@param int $id
 //@return array
 public function update(Request $request, $id){
 $re['er'] ='No valid request';
 if($request->has(['id', 'title', 'description', 'content', 'dtreg'])){
 $vals =['title'=>$request->title, 'description'=>$request->description, 'content'=>$request->content, 'dtreg'=>$request->dtreg];
 $nr = DB::table($this->table)->where('id', $request->id)->update($vals);

 if($nr >=0) $re =['re'=>$nr];
 else $re['er'] ='Unable to update data in table: '. $this->table;
 }
 return $re;
 }

 //Remove the specified page data
 //@param int $id
 //@return array
 public function destroy($id){
 $nr = DB::table($this->table)->where('id', $id)->delete();
 if($nr >0) return ['re'=>$nr.' row deleted'];
 else return ['er'=>'Unable to delete data in table: '. $this->table];
 }
}
In acest controller editati proprietatile: $admin_name, $admin_pass, $table cu valorile pe care vreti sa le folositi.

2. Creati un director numit "crud" in directorul resources/views/. In directorul "crud/" vom crea patru fisiere template pentru aceasta aplicatie: index.blade.php, form_logg.blade.php, body.blade.php, page.blade.php.
- Copiati si salvati urmatoarele coduri in fisierele specificate.

a) resources/views/crud/index.blade.php - pagina principala.
<!doctype html>
<html lang="{{app()->getLocale()}}">
<head>
<meta charset="utf-8">
<title>{{$title}}</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style>
body {background:#f7f8fe;margin:1px 1%;padding:0;position:relative;text-align:center;font-family:'Calibri',sans-serif;}
.bg_b{background:#e0e0f0}
.bg_g{background:#99ee99}
.cl_r{color:#ee0000}
h4:empty, div:empty{display:none;}

/* Form to authentication admin */
#admin_logg {
position:relative;
width:13em;
margin:8% auto 2em auto;
background:#fefefe;
padding:1em;
border:2px solid #bbb;
font-size:1.2em;
font-weight:700;
}
#admin_logg label {
display:block;
margin:.2em 1px;
text-align:left;
}
#admin_logg #name, #admin_logg #pass {
width:10.7em;
background:#ff1;
padding:.1em;
font-style:oblique;
}
#admin_logg #name:focus, #admin_logg #pass:focus {
background:#d1e0fb;
}
#admin_logg #name {
margin-left:2.2em;
}
#admin_logg #submit {
margin:1em auto .5em auto;
}
/* End */

h1{
font-size:22px;
margin:3px auto 8px auto;
}

#loggout{
margin:0;
font-size:18px;
position:absolute;
right:8px;
top:0;
}

#add_page{
color:#0000da;
cursor:pointer;
text-decoration:underline;
}

/*form for insert */
#f_insert{
background:#e0e0f0;
border-radius:8px;
display:none;
font-weight:700;
font-size:18px;
line-height:130%;
margin:8px auto;
padding:2px;
position:relative;
width:98%;
max-width:1100px;
}
#f_insert input[name=title], #f_insert input[name=description]{
width:88%;
max-width:400px;
}
#f_insert input[name=title]{
margin-left:48px;
}
#f_insert input[type=submit]{
display:block;
font-size:18px;
font-weight:700;
margin:2px auto;
}
#f_insert textarea{
display:block;
height:200px;
margin:5px auto;
width:98%;
}
#f_insert #f_close{
background:#efef00;
border-radius:5px;
color:#ee0000;
cursor:pointer;
padding:0 2px 2px 2px;
margin:0;
position:absolute;
right:-8px;
top:-8px;
}
/* End */

/*Table pages data*/
#pages{
background:#fbfbfe;
margin:2px auto;
position: relative;
width:99.8%;
}
#pages button{
display:block;
margin:8px auto;
}
#pages .update{
display:none;
}
#pages td{
padding:2px;
position: relative;
}
#pages .pg_title input, #pages .pg_description input{
width:calc(100% - 4px);
max-width:260px;
min-width:70px;
}
#pages .td_content{
max-height:145px;
overflow:hidden;
width:40%;
max-width:250px;
min-width:100px;
}
#pages div.pg_content{
width:100%;
height:100%;
max-height:148px;
overflow:hidden;
}
#pages div.pg_content textarea{
width:calc(100% - 4px);
height:140px;
}
#pages button{
font-weight:700;
}
/* End */

/*pagination links*/
.pagination{
background-color:#b0d0f0;
border:1px solid #eeeffe;
border-radius:8px;
list-style-type:none;
margin:10px 10%;
padding:3px 14px;
}
.pagination li{
display:inline;
font-size:18px;
font-weight:700;
}
.pagination a {
background-color:#f7f8fe;
border-radius:7px;
color:#0001da;
font-size:19px;
margin:1px 4px;
padding:1px 7px;
text-decoration:none;
}
.pagination a:hover {
background-color:#efef00;
text-decoration:underline;
}
/* End */
</style>
</head>
<body>
<h1>{{$title}}</h1>

<h4 id='p_resp' class='cl_r'>
@if(session('resp'))
 {{session('resp')}}
@endif
</h4>

@if(Session::has('admin_logg'))
 @include('crud.body')
@else
 @include('crud.form_logg')
@endif
</body>
</html>

b) resources/views/crud/form_logg.blade.php - pentru autentificare Admin.
<form action='/crud/adminlogg' method='post' id='admin_logg'>
{{ csrf_field() }}
 <label for='name'>Name: <input type='text' name='name' id='name' /></label>
 <label for='pass'>Password: <input type='password' name='pass' id='pass' /></label>
 <input type='submit' id='submit' value='Send' />
</form>

c) resources/views/crud/body.blade.php - contine formularul pentru creare pagina noua, tabelul cu datele paginilor, link-uri de paginare si codul JavaScript /Ajax.
<a href="/crud/adminloggout" id='loggout' title='Log-Out'>Log-Out</a>
<h3 id='add_page'>Create New Page</h3>

<form method="post" action="/crud" id='f_insert'>
{{ csrf_field() }}

Title: <input type='text' name='title' required /><br>
Description: <input type='text' name='description' /><br>
Content:
<textarea name='content'>Content</textarea>
<input type='submit' name='f_sbmt' value='Store'/>
<h3 id='f_close'>[X]</h3>
</form>

@isset($pages)
@if(count($pages)>0)
 <table id='pages' border='1' cellspacing='0'>
 <tr><th>ID</th><th>Title</th><th>Description</th><th>Content</th><th>Reg. Date</th><th>Action</th></tr>
 @foreach($pages as $page)
 <tr><td class='pg_id'>{{$page->id}}</td><td class='pg_title'><a href="{{route('crud.show', ['id'=>$page->id])}}" target='_blank'>$page-&gt;title</a></td><td class='pg_description'>$page-&gt;description</td><td class='td_content'><div class='pg_content'>$page-&gt;content</div></td><td class='dtreg'>{{$page->dtreg}}</td><td colspan='2'><button class='edit'>Edit</button><button class='update'>Update</button><button class='delete'>Delete</button></td></tr>
 @endforeach
 </table>
 {{$pages->links()}}
 @else
 <h4>No page data in database</h4>
@endif
@endisset

<script>
//the csrf_token generated by Laravel, to be sent with Ajax to server
var csrf_token ='{{csrf_token()}}';

//#p_resp elemet, for response from controller
var p_resp = document.getElementById('p_resp');
if(p_resp) window.setTimeout(function(){ p_resp.innerHTML='';}, 5000);

// Ajax, receives the url of file to access, data to send, request method, and a callback function (called when the response is received)
function ajaxSend(url, data, callback){
 var req = (window.XMLHttpRequest) ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP'); // XMLHttpRequest object

 //put data from "data" into a string to be send to "php"
 var str_data ='_token='+csrf_token; // to pass the csrf_token
 for(var k in data){
 k = k.toString(); //convert numeric key to string

 //build the string with data to be sent
 if(data[k]) str_data +='&'+ k +'='+ data[k].toString().replace(/\?/g, '?').replace(/=/g, '=').replace(/&/g, '&').replace(/[ ]+/g, ' ').replace(/[\+]/g, '+');
 }
// alert(str_data); //for debug, to see the string that is sent

 //send data to php
 req.open('POST', url, true);
 req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
 req.send(str_data);

 //check the state request, if completed, pass the response to callback function
 req.onreadystatechange = function(){
 if(req.readyState == 4){
// alert(req.responseText); // debug
 callback(req.responseText);
 }
 }
}

 /*Code for Insert */
var add_page = document.getElementById('add_page');
var f_insert = document.getElementById('f_insert');
var f_close = document.getElementById('f_close');

//shows the form, reset input values
add_page.addEventListener('click', function(){
 f_insert.style.display ='block';
 f_insert['title'].value ='';
 f_insert['description'].value ='';
 f_insert['content'].value ='Content';
 f_insert['f_sbmt'].removeAttribute('disabled'); //make sure isn't disabled
});

//hides the form
f_close.addEventListener('click', function(){
 f_insert.style.display ='none';
});

//when submit the form
f_insert.addEventListener('submit', function(e){
 e.preventDefault();

 //get page data, send it to ajax
 var data ={
 title: f_insert['title'].value,
 description: f_insert['description'].value,
 content: f_insert['content'].value,
 };
 ajaxSend(e.target.action, data, function(resp){
 var res = JSON.parse(resp);
 if(res){
 if(res.re){
 p_resp.innerHTML = res.re;
 e.target.style.display ='none';
 }
 else if(res.er) alert(res.er);
 }
 else alert(resp);
 });
 f_insert['f_sbmt'].setAttribute('disabled', 'disabled'); //to not click twice

 return false;
});
 /*end*/

 /*Code for Edit/Update/Delete */

//register click on .edit buttons
var btns_edit = document.querySelectorAll('#pages td .edit');
for(var i=0; i<btns_edit.length; i++){
 btns_edit[i].removeAttribute('disabled'); //make sure isn't disabled
 btns_edit[i].addEventListener('click', function(e){
 e.target.setAttribute('disabled', 'disabled');
 var row = e.target.parentNode.parentNode; //parent /tr row
 row.className ='bg_b';

 //to can resize textarea with content
 row.querySelector('.td_content').style.maxWidth ='none';
 row.querySelector('.pg_content').style.maxHeight ='none';

 //get elemets in button's row
 var elms ={
 title: row.querySelector('.pg_title a'),
 description: row.querySelector('.pg_description'),
 content: row.querySelector('.pg_content'),
 dtreg: row.querySelector('.dtreg'),
 };

 //puts elms content in inputs
 elms.title.parentNode.innerHTML ='<input type="text" value="'+ elms.title.innerHTML.replace(/"/g, '&quot;') +'"/>';
 elms.description.innerHTML ='<input type="text" value="'+ elms.description.innerHTML.replace(/"/g, '&quot;') +'"/>';
 elms.content.innerHTML ='<textarea>'+ elms.content.innerHTML.replace(/\</g, '&lt;').replace(/\>/g, '&gt;') +'</textarea>';
 elms.dtreg.innerHTML ='<input type="date" value="'+ elms.dtreg.innerHTML +'"/>';

 //after a few sec. shows .update, hides this button
 window.setTimeout(function(){
 row.querySelector('.update').style.display ='block';
 e.target.style.display ='none';
 }, 3000);
 });
}

//register click on .update buttons
var btns_upd = document.querySelectorAll('#pages td .update');
for(var i=0; i<btns_upd.length; i++){
 btns_upd[i].removeAttribute('disabled'); //make sure isn't disabled
 btns_upd[i].addEventListener('click', function(e){
 e.target.setAttribute('disabled', 'disabled');
 var row = e.target.parentNode.parentNode; //parent /tr row

 //get page data, send it to ajax
 var data ={
 id: row.querySelector('.pg_id').innerHTML*1,
 title: row.querySelector('.pg_title input').value,
 description: row.querySelector('.pg_description input').value,
 content: row.querySelector('.pg_content textarea').value,
 dtreg: row.querySelector('.dtreg input').value,
 _method:'PUT'
 };
 ajaxSend('/crud/'+data.id, data, function(resp){
 var res = JSON.parse(resp);
 e.target.removeAttribute('disabled');
 if(res){
 if(res.re >=0){
 resp = res.re +' row updated';

 //reset buttons, swows data without inputs
 if(res.re >0){
 row.className ='bg_g';

 //restore these css
 row.querySelector('.td_content').style.maxWidth ='250px';
 row.querySelector('.pg_content').style.maxHeight ='148px';

 row.querySelector('.edit').removeAttribute('disabled');
 e.target.style.display ='none';
 row.querySelector('.edit').style.display ='block';
 row.querySelector('.pg_title').innerHTML ='<a href="/crud/'+ data.id +'" target="_blank">'+ data.title.replace(/\</g, '&lt;').replace(/\>/g, '&gt;') +'</a>';
 row.querySelector('.pg_description').innerHTML = data.description.replace(/\</g, '&lt;').replace(/\>/g, '&gt;');
 row.querySelector('.pg_content').innerHTML = data.content.replace(/\</g, '&lt;').replace(/\>/g, '&gt;');
 row.querySelector('.dtreg').innerHTML = data.dtreg;
 }
 }
 else if(res.er) resp = res.er;
 }
 alert(resp);
 });
 });
}

//register click on .delete buttons
var btns_del = document.querySelectorAll('#pages td .delete');
for(var i=0; i<btns_del.length; i++){
 btns_del[i].removeAttribute('disabled'); //make sure isn't disabled
 btns_del[i].addEventListener('click', function(e){
 //if delete confirmed, pass $id to ajax
 if(window.confirm('Page data will be definetivelly deleted.')){
 e.target.setAttribute('disabled', 'disabled');

 ajaxSend('/crud/'+(e.target.parentNode.parentNode.querySelector('.pg_id').innerHTML*1), {_method:'DELETE'}, function(resp){
 var res = JSON.parse(resp);
 e.target.removeAttribute('disabled');
 if(res){
 if(res.re){
 e.target.parentNode.parentNode.outerHTML ='';
 resp = res.re;
 }
 else if(res.er) resp = res.er;
 }
 alert(resp);
 });
 }
 });
}
</script>

d) resources/views/crud/page.blade.php - va afisa datele paginii cand un URI de forma: 'crud/{id}' este accesat.
<!doctype html>
<html lang="{{app()->getLocale()}}">
<head>
<meta charset="utf-8">
<title>{{$title}}</title>
</head>
<body>
<h1>{{$title}}</h1>
<strong>Description</strong>: {{$description}}
<h3>Content:</h3>
{!!$content !!}
</body>
</html>

3. Setare Route; adaugati urmatorul cod in fisierul routes/web.php:
//calls the method to create the table in mysql
Route::get('/crud/createtable','CrudAjax@createTable');

//authentication admin in ajax-crud application
Route::post('/crud/adminlogg', 'CrudAjax@adminLogg');

//to log-out admin in ajax-crud application
Route::get('/crud/adminloggout', 'CrudAjax@adminLoggOut');

//to get pages data
Route::post('/crud/pages', 'CrudAjax@getPages');

//uses CrudAjax as a resource
Route::resource('/crud', 'CrudAjax');

Folosire aplicatie CRUD

Acum, puteti folosi aceasta aplicatie simpla Ajax-CRUD pentru a stoca, edita si sterge datele paginilor in mysql.

1. Accesati urmatoarea adresa URL si autentificativa cu datele $admin_name si $admin_pass.
//localhost:8000/crud
2. Va apare mesaj sa creati tabelul in baza de date.
- Dupa ce tabelul este creat, puteti adauga pagini cu date pentru: Titlu, Descriere, Continut, si Data-Inregistrare in baza de date.
Daca aveti intrebari in legatura cu aceasta Aplicatie CRUD Laravel, intrebati pe: MarPlo Forum

• Ca sa testati acest script, clic pe: Demo: Laravel Ajax MySQL CRUD.

• Pentru a descarca fisierele cu codurile prezentate aici, apasati pe: Download: Laravel Ajax MySQL CRUD.

Un Test simplu in fiecare zi

HTML
CSS
JavaScript
PHP-MySQL
Engleza
Spaniola
Care tag HTML5 defineste un text marcat, evidentiat?
<mark> <embed> <span>
<p>Cursuri graruite: <mark>MarPlo.net</mark> , jocuri, anime.</p>
Ce pseudo-clasa CSS defineste un stil la element cand mouse-ul e deasupra lui?
:focus :hover :active
a:hover {
  font-weight: bold;
  color: #00da01;
}
Clic pe functia ce returneaza un sir cu un numar rotunjit la x decimale.
toPrecision(x) toFixed(x) floor(x)
var num = 12.34567;
num = num.toFixed(2);
alert(num);       // 12.35
Indicati functia PHP care adauga continutul unui fisier intr-un array.
[) file() readfile()
$arr = file("a_file.txt", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
var_export($arr);
Clic pe raspunsul potrivit la intrebarea: "What time is it?"
On the 7th of July 1996 It is a quarter to 5. Nice weather.
What time is it? It is a quarter to 5.
- Cat este ora? E 5 fara un sfert.
Indicati raspunsul potrivit la intrebarea: "¿Qué hora es?"
Hace buen tiempo. En el 7 de julio de 1996 Son las tres menos cuarto.
¿Qué hora es? Son las tres menos cuarto.
- Cat este ora? E 3 fara un sfert.
Laravel Ajax MySQL CRUD cu Paginare

Last accessed pages

  1. Scriere scripturi PHP elementare (1576)
  2. Conditional IF in Limba Engleza - Fraze Conditionale (20736)
  3. Curs PHP MySQL, Tutoriale si Scripturi PHP (6659)
  4. Espanol Chistes - Glume, Bancuri (877)
  5. Sintaxa JavaScript (2435)

Popular pages this month

  1. Gramatica limbii engleze - Prezentare Generala (2144)
  2. Prezentul simplu si continuu - Present Tense Simple and Continuous (1480)
  3. Cursuri si Tutoriale: Spaniola, Engleza, HTML, CSS, Php-Mysql, JavaScript, Ajax (1072)
  4. Trecutul simplu si continuu - Past Tense Simple and Continuous (1025)
  5. Prezent perfect si Prezent perfect continuu - Present perfect and Continuous (981)