Diese Anleitung erklärt, wie man dhtmlxGantt in eine Laravel Anwendung integriert.
Wenn Sie nach Tutorials zur Integration mit anderen Plattformen suchen, schauen Sie sich folgende an:
Den vollständigen Quellcode für dieses Tutorial finden Sie auf GitHub.
Es gibt auch eine Videoanleitung, die die Erstellung eines Gantt-Diagramms mit PHP Laravel zeigt:
Um zu beginnen, erstellen Sie eine neue Laravel-Anwendung mit Composer:
composer create-project laravel/laravel gantt-laravel-app
Dieser Prozess wird alle notwendigen Dateien herunterladen und einrichten. Nach Abschluss navigieren Sie in das Projektverzeichnis und starten die Anwendung:
cd gantt-laravel-app
php artisan serve
Sie sollten nun die Standard-Laravel-Seite sehen, wenn Sie die Anwendung im Browser öffnen:
Um dhtmlxGantt einzufügen, erstellen Sie eine neue Ansichtsdatei im Verzeichnis resources/views
und benennen Sie sie gantt.blade.php
:
resources/views/gantt.blade.php
<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<script src="https://cdn.dhtmlx.com/gantt/edge/dhtmlxgantt.js"></script>
<link href="https://cdn.dhtmlx.com/gantt/edge/dhtmlxgantt.css" rel="stylesheet">
<style type="text/css"> html, body {
height: 100%;
padding: 0px;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<div id="gantt_here" style='width:100%; height:100%;'></div>
<script type="text/javascript"> gantt.init("gantt_here");
</script>
</body>
Diese Datei richtet ein grundlegendes HTML-Layout ein, inkludiert dhtmlxGantt vom CDN und initialisiert das Gantt-Diagramm. Die Höhe für den Dokumentenkörper und den Gantt-Container ist auf 100% gesetzt, um eine korrekte Anzeige zu gewährleisten.
Um die Gantt-Seite zugänglich zu machen, setzen Sie sie als Standardroute in routes/web.php
:
routes/web.php
<?php
Route::get('/', function () {
return view('gantt');
});
Starten Sie die App neu und vergewissern Sie sich, dass die Gantt-Seite angezeigt wird:
Aktualisieren Sie die Datenbankkonfiguration in der .env
Datei, zum Beispiel:
.env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=gantt-test
DB_USERNAME=root
DB_PASSWORD=
Verwenden Sie Artisan, um Modell- und Migrationsdateien für Aufgaben und Links zu generieren:
php artisan make:model Task --migration
php artisan make:model Link --migration
Definieren Sie das Datenbankschema im Ordner database/migrations
. Das erwartete Schema für Gantt ist hier beschrieben.
database/migrations/_create_tasks_table.php
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateTasksTable extends Migration
{
public function up()
{
Schema::create('tasks', function (Blueprint $table){
$table->increments('id');
$table->string('text');
$table->integer('duration');
$table->float('progress');
$table->dateTime('start_date');
$table->integer('parent');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('tasks');
}
}
database/migrations/_create_links_table.php
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateLinksTable extends Migration
{
public function up()
{
Schema::create('links', function (Blueprint $table) {
$table->increments('id');
$table->string('type');
$table->integer('source');
$table->integer('target');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('links');
}
}
Führen Sie die Migrationen aus:
php artisan migrate
Um Testdaten zu generieren, erstellen Sie Seeder mit Artisan:
php artisan make:seeder TasksTableSeeder
php artisan make:seeder LinksTableSeeder
Fügen Sie Testdaten in TasksTableSeeder
hinzu:
database/seeds/TasksTableSeeder.php
<?php
use Illuminate\Database\Seeder;
class TasksTableSeeder extends Seeder
{
public function run()
{
DB::table('tasks')->insert([
['id'=>1, 'text'=>'Project #1', 'start_date'=>'2017-04-01 00:00:00',
'duration'=>5, 'progress'=>0.8, 'parent'=>0],
['id'=>2, 'text'=>'Task #1', 'start_date'=>'2017-04-06 00:00:00',
'duration'=>4, 'progress'=>0.5, 'parent'=>1],
['id'=>3, 'text'=>'Task #2', 'start_date'=>'2017-04-05 00:00:00',
'duration'=>6, 'progress'=>0.7, 'parent'=>1],
['id'=>4, 'text'=>'Task #3', 'start_date'=>'2017-04-07 00:00:00',
'duration'=>2, 'progress'=>0, 'parent'=>1],
['id'=>5, 'text'=>'Task #1.1', 'start_date'=>'2017-04-05 00:00:00',
'duration'=>5, 'progress'=>0.34, 'parent'=>2],
['id'=>6, 'text'=>'Task #1.2', 'start_date'=>'2017-04-11 00:00:00',
'duration'=>4, 'progress'=>0.5, 'parent'=>2],
['id'=>7, 'text'=>'Task #2.1', 'start_date'=>'2017-04-07 00:00:00',
'duration'=>5, 'progress'=>0.2, 'parent'=>3],
['id'=>8, 'text'=>'Task #2.2', 'start_date'=>'2017-04-06 00:00:00',
'duration'=>4, 'progress'=>0.9, 'parent'=>3]
]);
}
}
Rufen Sie die Seeder in DatabaseSeeder.php
auf:
database/seeds/DatabaseSeeder.php
<?php
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
public function run()
{
$this->call(TasksTableSeeder::class);
$this->call(LinksTableSeeder::class);
}
}
Führen Sie das Seeding der Datenbank durch:
php artisan db:seed
Die generierten Modelle für Aufgaben und Links sind einsatzbereit. Sie können jedoch ein open
Attribut zum Task-Modell hinzufügen, um sicherzustellen, dass der Projektbaum beim Laden erweitert wird:
/app/Task.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Task extends Model
{
protected $appends = ["open"];
public function getOpenAttribute()
{
return true;
}
}
Das Link-Modell bleibt unverändert:
/app/Link.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Link extends Model
{
}
Um Daten in Gantt zu laden, erstellen Sie einen Controller, der Daten im JSON-Format zurückgibt:
app/Http/Controllers/GanttController.php
<?php
namespace App\Http\Controllers;
use App\Task;
use App\Link;
class GanttController extends Controller
{
public function get()
{
$tasks = new Task();
$links = new Link();
return response()->json([
"data" => $tasks->all(),
"links" => $links->all()
]);
}
}
Fügen Sie eine Route für die Aktion in routes/api.php
hinzu:
routes/api.php
<?php
use App\Http\Controllers\GanttController;
Route::get('/data', 'GanttController@get');
Aktualisieren Sie die Ansicht, um Daten zu laden:
resources/views/gantt.blade.php
gantt.config.date_format = "%Y-%m-%d %H:%i:%s";
gantt.init("gantt_here");
gantt.load("/api/data");
Die Methode gantt.load
sendet eine AJAX-Anfrage, um Daten im JSON-Format abzurufen. Das date_format
gibt das erwartete Format für Daten an.
Überprüfen Sie die App erneut und Sie werden sehen, dass Aufgaben im Gantt-Diagramm angezeigt werden:
Nachdem Daten vom Backend gelesen werden können, ist der nächste Schritt, Änderungen zurück in die Datenbank zu speichern. Der Client sendet RESTful-Anfragen (POST/PUT/DELETE) für Aufgaben- und Link-Aktionen. Details zu diesen Anfragen finden Sie hier.
Der nächste Schritt besteht darin, Controller zu erstellen, um diese Aktionen zu behandeln und das Speichern von Daten auf der Client-Seite zu ermöglichen.
Erstellen Sie RESTful Resource Controller für Aufgaben und Links, um Aktionen wie das Hinzufügen, Aktualisieren und Löschen zu verwalten.
Der TaskController
behandelt das Erstellen, Aktualisieren und Löschen von Aufgaben. Hier ist der Code:
app/Http/Controllers/TaskController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Task;
class TaskController extends Controller
{
public function store(Request $request){
$task = new Task();
$task->text = $request->text;
$task->start_date = $request->start_date;
$task->duration = $request->duration;
$task->progress = $request->has("progress") ? $request->progress : 0;
$task->parent = $request->parent;
$task->save();
return response()->json([
"action"=> "inserted",
"tid" => $task->id
]);
}
public function update($id, Request $request){
$task = Task::find($id);
$task->text = $request->text;
$task->start_date = $request->start_date;
$task->duration = $request->duration;
$task->progress = $request->has("progress") ? $request->progress : 0;
$task->parent = $request->parent;
$task->save();
return response()->json([
"action"=> "updated"
]);
}
public function destroy($id){
$task = Task::find($id);
$task->delete();
return response()->json([
"action"=> "deleted"
]);
}
}
Die Route für diese Aktionen wird wie folgt definiert:
routes/api.php
<?php
use Illuminate\Http\Request;
Route::get('/data', 'GanttController@get');
Route::resource('task', 'TaskController');
tid
-Eigenschaft der Antwort zurückgesendet.progress
-Parameter enthält, wird er auf 0 gesetzt.Nun erstellen wir einen ähnlichen Controller für Links.
Der LinkController
verwaltet die Erstellung, Aktualisierung und Löschung von Links. Hier ist der Code:
app/Http/Controllers/LinkController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Link;
class LinkController extends Controller
{
public function store(Request $request){
$link = new Link();
$link->type = $request->type;
$link->source = $request->source;
$link->target = $request->target;
$link->save();
return response()->json([
"action"=> "inserted",
"tid" => $link->id
]);
}
public function update($id, Request $request){
$link = Link::find($id);
$link->type = $request->type;
$link->source = $request->source;
$link->target = $request->target;
$link->save();
return response()->json([
"action"=> "updated"
]);
}
public function destroy($id){
$link = Link::find($id);
$link->delete();
return response()->json([
"action"=> "deleted"
]);
}
}
Die Routen für diesen Controller sind wie folgt:
routes/api.php
<?php
use Illuminate\Http\Request;
Route::get('/data', 'GanttController@get');
Route::resource('task', 'TaskController');
Route::resource('link', 'LinkController');
Um die API auf der Client-Seite funktional zu machen, sind einige Konfigurationen erforderlich:
resources/views/gantt.blade.php
gantt.config.date_format = "%Y-%m-%d %H:%i:%s";
gantt.init("gantt_here");
gantt.load("/api/data");
var dp = new gantt.dataProcessor("/api");dp.init(gantt);dp.setTransactionMode("REST");
Mit dieser Konfiguration ist das Gantt-Diagramm nun vollständig interaktiv, sodass Aufgaben und Links hinzugefügt, aktualisiert und gelöscht werden können.
Für weitere Funktionen, schauen Sie sich unsere Anleitungen an.
Wenn Aufgaben durch Ziehen und Ablegen neu geordnet werden, muss die neue Reihenfolge in der Datenbank gespeichert werden. Der Prozess wird hier detailliert beschrieben.
Um das Neuanordnen in der Benutzeroberfläche zu ermöglichen, aktualisieren Sie die Gantt-Konfiguration in der Index-Ansicht:
resources/views/gantt.blade.php
gantt.config.order_branch = true;gantt.config.order_branch_free = true;
gantt.init("gantt_here");
Um die Aufgabenreihenfolge zu speichern, fügen Sie eine sortorder
-Spalte in das Datenbankschema ein. Hier ist ein Beispielschema:
Schema::create('tasks', function (Blueprint $table){
$table->increments('id');
$table->string('text');
$table->integer('duration');
$table->float('progress');
$table->dateTime('start_date');
$table->integer('parent');
$table->integer('sortorder')->default(0);
$table->timestamps();
});
Alternativ dazu erstellen Sie eine Migration, um die Spalte hinzuzufügen:
php artisan make:migration add_sortorder_to_tasks_table --table=tasks
Migrationsdatei:
database/migrations/_add_sortorder_to_tasks_table.php
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddSortorderToTasksTable extends Migration
{
public function up()
{
Schema::table('tasks', function (Blueprint $table) {
$table->integer('sortorder')->default(0);
});
}
public function down()
{
Schema::table('tasks', function (Blueprint $table) {
$table->dropColumn('sortorder');
});
}
}
Wenden Sie die Migration an:
php artisan migrate
GET /data
Endpunkt sollte Aufgaben geordnet nach sortorder
zurückgeben:app/Http/Controllers/GanttController.php
<?php
namespace App\Http\Controllers;
use App\Task;
use App\Link;
class GanttController extends Controller
{
public function get(){
$tasks = new Task();
$links = new Link();
return response()->json([
"data" => $tasks->orderBy('sortorder')->get(), "links" => $links->all()
]);
}
}
sortorder
Wert haben:app/Http/Controllers/TaskController.php
public function store(Request $request){
$task = new Task();
$task->text = $request->text;
$task->start_date = $request->start_date;
$task->duration = $request->duration;
$task->progress = $request->has("progress") ? $request->progress : 0;
$task->parent = $request->parent;
$task->sortorder = Task::max("sortorder") + 1;
$task->save();
return response()->json([
"action"=> "inserted",
"tid" => $task->id
]);
}
app/Http/Controllers/TaskController.php
public function update($id, Request $request){
$task = Task::find($id);
$task->text = $request->text;
$task->start_date = $request->start_date;
$task->duration = $request->duration;
$task->progress = $request->has("progress") ? $request->progress : 0;
$task->parent = $request->parent;
$task->save();
if($request->has("target")){ $this->updateOrder($id, $request->target); }
return response()->json([
"action"=> "updated"
]);
}
private function updateOrder($taskId, $target){
$nextTask = false;
$targetId = $target;
if(strpos($target, "next:") === 0){
$targetId = substr($target, strlen("next:"));
$nextTask = true;
}
if($targetId == "null")
return;
$targetOrder = Task::find($targetId)->sortorder;
if($nextTask)
$targetOrder++;
Task::where("sortorder", ">=", $targetOrder)->increment("sortorder");
$updatedTask = Task::find($taskId);
$updatedTask->sortorder = $targetOrder;
$updatedTask->save();
}
Sicherheitsmaßnahmen wie die Verhinderung von SQL-Injektionen, XSS und CSRF-Angriffen sind standardmäßig nicht enthalten. Es liegt in der Verantwortung der Entwickler, die Anwendung sicher zu gestalten. Weitere Details finden Sie hier.
Wenn Aufgaben und Links nach Abschluss der Einrichtung nicht gerendert werden, konsultieren Sie den Fehlerbehebungsleitfaden hier.
Das Gantt-Diagramm ist nun voll funktionsfähig. Der komplette Code ist auf GitHub verfügbar. Sie können ihn für Ihre Projekte klonen oder herunterladen. Zusätzliche Anleitungen und Tutorials finden Sie hier.
Zurück nach oben