I'm trying to follow this tutorial https://laravelcode.com/post/laravel-full-calendar-tutorial-example-using-maddhatter-laravel-fullcalendar. I completed every steps but the calendar still does not appear, only the Laravel header and the "Full Calendar Example" writing but not the calendar itself or if I remove "extends('layout.php')" nothing appears. :( What could be the problem? I hope someone can give a quick answer. Sorry if it's a bad question here.
My code:
config/app.php
'providers' => [
.....
.....
MaddHatter\LaravelFullcalendar\ServiceProvider::class,
],
'aliases' => [
.....
.....
'Calendar' => MaddHatter\LaravelFullcalendar\Facades\Calendar::class,
]
database/migrations/CreateEventsTable
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateEventsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('events', function (Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->date('start_date');
$table->date('end_date');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop("events");
}
}
app/Event.php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Event extends Model
{
protected $fillable = ['title','start_date','end_date'];
}
database/seeds/AddDummyEvents.php
use Illuminate\Database\Seeder;
use App\Event;
class AddDummyEvent extends Seeder
{
public function run()
{
$data = [
['title'=>'Demo Event-1', 'start_date'=>'2017-09-11', 'end_date'=>'2017-09-12'],
['title'=>'Demo Event-2', 'start_date'=>'2017-09-11', 'end_date'=>'2017-09-13'],
['title'=>'Demo Event-3', 'start_date'=>'2017-09-14', 'end_date'=>'2017-09-14'],
['title'=>'Demo Event-3', 'start_date'=>'2017-09-17', 'end_date'=>'2017-09-17'],
];
foreach ($data as $key => $value) {
Event::create($value);
}
}
}
routes/web.php
Route::get('/', function () {
return view('welcome');
});
Auth::routes();
Route::get('/home', 'HomeController#index')->name('home');
Route::get('events', 'EventController#index');
app/Http/Controllers/EventController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Calendar;
use App\Event;
class EventController extends Controller
{
public function index()
{
$events = [];
$data = Event::all();
if($data->count()) {
foreach ($data as $key => $value) {
$events[] = Calendar::event(
$value->title,
true,
new \DateTime($value->start_date),
new \DateTime($value->end_date.' +1 day'),
null,
// Add color and link on event
[
'color' => '#f05050',
'url' => 'pass here url and any route',
]
);
}
}
$calendar = Calendar::addEvents($events);
return view('fullcalendar', compact('calendar'));
}
}
resources/views/fullcalendar.blade.php
#extends('layouts.app')
#section('style')
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/2.2.7/fullcalendar.min.css"/>
#endsection
#section('content')
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">Full Calendar Example</div>
<div class="panel-body">
{!! $calendar->calendar() !!}
</div>
</div>
</div>
</div>
</div>
#endsection
#section('script')
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.9.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/2.2.7/fullcalendar.min.js"></script>
{!! $calendar->script() !!}
#endsection
Unsure why it was left out of the tutorial, but they didn't have you set up a layout blade file. They also forgot to include jquery. If you change fullcalendar.blade.php to the following code it works.
<!DOCTYPE html>
<html lang="en">
<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">
<title>Document</title>
</head>
<link rel="stylesheet" type="text/css"
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet"
ref="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/2.2.7/fullcalendar.min.css"/>
<body>
<div class="container" style="margin-top: 100px">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">Full Calendar Example</div>
<div class="panel-body">
{!! $calendar->calendar() !!}
</div>
</div>
</div>
</div>
</div>
</body>
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.9.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/2.2.7/fullcalendar.min.js"></script>
{!! $calendar->script() !!}
</html>
Look in the EventController in the calender() function
The return view() is trying to return "calender", change it to calendar to match the view name you created in views.
Related
I am trying to send email by html code.
I would like to include image and data on the blade template, but can't render the view.
current code:
MailTemplate.php
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class MailTemplate extends Mailable
{
use Queueable, SerializesModels;
public $subject = null;
public $template;
public $data;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct($subject, $template, $data)
{
//
$this->subject = $subject;
$this->template = $template;
$this->data = $data;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
$this->template = '<div><img src="{{ $message->embed(public_path('/assets/images/logo.png')) }}" ></div>';
return $this->subject( $this->subject)->view('emails.EmailTemplate');
}
}
EmailTemplate.blade.php
<html>
<body>
{!! $template !!}
</body>
</html>
result
current:
<html>
<body>
<div><img src="{{ $message->embed(public_path('/assets/images/logo.png')) }}" ></div>
</body>
</html>
//==============================================
**I want:**
<html>
<body>
<div><img src="embed swiftmailfile~~~~~~" ></div>
</body>
</html>
So, how can I return the view using HTML
so that it can be passed to the variable?
You can try this:
Just pass src to view
public function build()
{
$src = $message->embed(public_path('/assets/images/logo.png'));
return $this->subject( $this->subject)->view('emails.EmailTemplate', ['src' => $src]);
}
And then , render to view
<html>
<body>
<div><img src="{{ $src }}" ></div>
</body>
</html>
You are trying to render blade inside the mailable.
Instead, create the string using concatenation
$this->template = '<div><img src="' . $message->embed(public_path('/assets/images/logo.png')) . '" ></div>';
I need any user to be able to like it every 24 hours
I wrote a function for this
const LIKE_HEART = 'like_heart';
const LIKE_FINGER = 'like_finger';
public static $types = [self::LIKE_HEART, self::LIKE_FINGER];
public function setLikes() {
$likes = Cookie::get($types);
$hours = 24;
if ($likes) {
self::where('id', $article->id)
->where('updated_at', '<', Carbon::now()->subHours($hours))
->increment($types);
}
}
But I have two fields in my database, like_heart and like_finger, these should be two types of likes. How can I rewrite my function into a method so that I can only choose one type of like out of two?
An array of the following type must be serialized in cookies:
$r = [
'1' => [
'like_heart' => '2021-09-28 22:02:01',
'like_finger' => '2021-11-28 11:12:34',
],
'2' => [
'like_finger' => '2021-11-28 11:12:34',
],
];
where 1, 2 is the article ID. Date - the date the like was added by current users
The current date is compared with the date in this cookie for a specific article, and if it is less than 24 hours old or missing, add +1 to the corresponding like in the article and add / change information in the like.
article.blade
<div class="blog-wrapper">
<div class="container">
<div class="article">
<p><b>{!! $article->title !!}</b></p>
<p><b>{!! $article->subtitle !!}</b></p>
<picture>
<source srcset="{{ $article->image_list_mobile }}" media="(max-width: 576px)" alt="{{ $article->image_mobile_alt }}" title="{{ $article->image_mobile_title }}">
<source srcset="{{ $article->image_list }}" alt="{{ $article->image_alt }}" title="{{ $article->image_title }}">
<img srcset="{{ $article->image_list }}" alt="{{ $article->image_alt }}" title="{{ $article->image_title }}">
</picture>
<p><b>{{ date('d F Y', strtotime($article->published_at)) }}</b></p>
<p><b>{{ $article->getTotalViews() }} Views</b></p>
<p><b>{{ $allArticleCommentsCount }} Comments</b></p>
</div>
Like Heart
Like Finger
<div class="comments">
<div class="recommend-title"><p><b>Comments ({{ $allArticleCommentsCount }})</b></p></div>
#foreach($article_comments as $article_comment)
<p><b>{!! $article_comment->name !!}</b></p>
<p><b>{!! $article_comment->text !!}</b></p>
<p><b>{{ date('d F Y', strtotime($article_comment->date)) }}</b></p>
#endforeach
</div>
</div>
</div>
controller
public function index(Request $request, $slug)
{
$article = Article::where('slug', $slug)->first();
if(!$article){
return abort(404);
}
$viewed = Session::get('viewed_article', []);
if (!in_array($article->id, $viewed)) {
$article->increment('views');
Session::push('viewed_article', $article->id);
}
$allArticleCommentsCount = ArticleComment::where('article_id', $article->id)->count();
$article_comments = ArticleComment::where('article_id', $article->id)->get();
return view('article', compact('article', 'article_comments', 'allArticleCommentsCount'));
}
public function postLike() {
if ($like = request('like')) {
$articleId = request('article_id');
if (User::hasLikedToday($articleId, $like)) {
return response()
->json([
'message' => 'You have already liked the Article #'.$articleId.' with '.$like.'.',
]);
}
$cookie = User::setLikeCookie($articleId, $like);
return response()
->json([
'message' => 'Liked the Article #'.$articleId.' with '.$like.'.',
'cookie_json' => $cookie->getValue(),
])
->withCookie($cookie);
}
}
Article model
class User extends Authenticatable
{
// ...
public static function hasLikedToday($articleId, string $type)
{
$articleLikesJson = \Cookie::get('article_likes', '{}');
$articleLikes = json_decode($articleLikesJson, true);
// Check if there are any likes for this article
if (! array_key_exists($articleId, $articleLikes)) {
return false;
}
// Check if there are any likes with the given type
if (! array_key_exists($type, $articleLikes[$articleId])) {
return false;
}
$likeDatetime = Carbon::createFromFormat('Y-m-d H:i:s', $articleLikes[$articleId][$type]);
return ! $likeDatetime->addDay()->lt(now());
}
public static function setLikeCookie($articleId, string $type)
{
// Initialize the cookie default
$articleLikesJson = \Cookie::get('article_likes', '[]');
$articleLikes = json_decode($articleLikesJson, true);
// Update the selected articles type
$articleLikes[$articleId][$type] = today()->format('Y-m-d H:i:s');
$articleLikesJson = json_encode($articleLikes);
return cookie()->forever('article_likes', $articleLikesJson);
}
}
route
Route::get('/article', function () {
$articleLikesJson = \Cookie::get('article_likes', '{}');
return view('article')->with([
'articleLikesJson' => $articleLikesJson,
]);
});
Route::get('article/{id}/like', 'App\Http\Controllers\ArticleController#postLike');
First of all, you should never store any logic in the client side. A great alternative for this kind of feature would be using the Laravel Aquantances package.
https://laravel-news.com/manage-friendships-likes-and-more-with-the-acquaintances-laravel-package
Anyway, since you want to do it with cookies;
We can actually do this a lot easier than thought.
Articles.php
class User extends Authenticatable
{
// ...
public static function hasLikedToday($articleId, string $type)
{
$articleLikesJson = \Cookie::get('article_likes', '{}');
$articleLikes = json_decode($articleLikesJson, true);
// Check if there are any likes for this article
if (! array_key_exists($articleId, $articleLikes)) {
return false;
}
// Check if there are any likes with the given type
if (! array_key_exists($type, $articleLikes[$articleId])) {
return false;
}
$likeDatetime = Carbon::createFromFormat('Y-m-d H:i:s', $articleLikes[$articleId][$type]);
return ! $likeDatetime->addDay()->lt(now());
}
public static function setLikeCookie($articleId, string $type)
{
// Initialize the cookie default
$articleLikesJson = \Cookie::get('article_likes', '[]');
$articleLikes = json_decode($articleLikesJson, true);
// Update the selected articles type
$articleLikes[$articleId][$type] = today()->format('Y-m-d H:i:s');
$articleLikesJson = json_encode($articleLikes);
return cookie()->forever('article_likes', $articleLikesJson);
}
}
The code above will allow us to is a user has liked an article and generate the cookie we want to set.
There are a couple important things you need to care about.
Not forgetting to send the cookie with the response.
Redirecting back to a page so that the cookies take effect.
I've made a very small example:
routes/web.php
Route::get('/test', function () {
$articleLikesJson = \Cookie::get('article_likes', '{}');
if ($like = request('like')) {
$articleId = request('article_id');
if (User::hasLikedToday($articleId, $like)) {
return redirect()->back()
->with([
'success' => 'You have already liked the Article #'.$articleId.' with '.$like.'.',
]);
}
$cookie = User::setLikeCookie($articleId, $like);
return redirect()->back()
->withCookie($cookie)
->with([
'success' => 'Liked the Article #'.$articleId.' with '.$like.'.',
]);
}
return view('test')->with([
'articleLikesJson' => $articleLikesJson,
]);
});
resources/views/test.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#4.6.0/dist/css/bootstrap.min.css" integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l" crossorigin="anonymous">
</head>
<body>
<div class="container">
#if (session('success'))
<div class="alert alert-success" role="alert">
{{ session('success') }}
</div>
#endif
<pre>{{ $articleLikesJson }}</pre>
<div class="row">
#foreach (range(1, 4) as $i)
<div class="col-3">
<div class="card">
<div class="card-header">
Article #{{ $i }}
</div>
<div class="card-body">
<h5 class="card-title">Special title treatment</h5>
<p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
<a href="/test?like=heart&article_id={{ $i }}" class="btn btn-primary">
Like Heart
</a>
<a href="/test?like=finger&article_id={{ $i }}" class="btn btn-primary">
Like Finger
</a>
</div>
<div class="card-footer text-muted">
2 days ago
</div>
</div>
</div>
#endforeach
</div>
</div>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#4.6.0/dist/js/bootstrap.min.js" integrity="sha384-+YQ4JLhjyBLPDQt//I+STsc9iw4uQqACwlvpslubQzn4u2UU2UFM80nGisd026JF" crossorigin="anonymous"></script>
</body>
</html>
Post Update:
1- Remove the range()
2- Update the route of these links (to where you put the logic for liking)
3- Below I've added an example for route Route::post('article/{id}/like', [SomeController::class, 'postLike'])
Like Heart
Like Finger
First i created the Admin model in which i implemented it using Authenticable Admin.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Authenticatable;
class Admin extends Model implements \Illuminate\Contracts\Auth\Authenticatable
{
//
use Authenticatable;
}
then i created the migration :
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateAdminsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('admins', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
$table->rememberToken();
$table->string('email');
$table->string('password');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('admins');
}
}
Replaced the Users model in config/auth.php with Admin Model :
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Admin::class,
],
AdminController.php
<?php
namespace App\Http\Controllers;
use App\Post;
use Illuminate\Http\Request;
use Auth;
class AdminController extends Controller{
public function getIndex()
{
$posts= Post::orderBy('created_at','desc')->take(3)->get();
return view('backend.index')->with(['posts'=>$posts]);
}
public function getLogin(){
return view('backend.login');
}
public function postLogin(Request $request){
$this->validate($request,[
'email'=>'required|email',
'password'=>'required'
]);
dd(Auth::attempt(['email'=>$request['email'],'password'=>$request['password']]));
if(!Auth::attempt(['email'=>$request['email'],'password'=>$request['password']])){
return redirect()->back()->with(['fail'=>'Could Not Log You In']);
}
return redirect()->route('admin.index');
}
public function getLogout(){
Auth::logout();
return redirect()->route('blog.index');
}
}
web.php
Route::get('/admin/login',[
'uses'=>'AdminController#getLogin',
'as'=>'admin.login'
]);
Route::post('/admin/login',[
'uses'=>'AdminController#postLogin',
'as'=>'admin.login'
]);
login.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
<title>Admin Area</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="{{URL::to('css/bootstrap.min.css')}}">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="{{URL::to('js/bootstrap.min.js')}}"></script>
#yield('styles')
</head>
<body>
<div class="container">
<div class="container-fluid">
#include('includes.info-box')
<form method="post" action="{{route('admin.login')}}">
<div class="form-group">
<label for="email">Email: </label>
<input type="email" class="form-control" id="email" name="email"
{{$errors->has('email')?'class=alert alert-danger':'' }}
value="{{Request::old('email')}}">
</div>
<div class="form-group">
<label for="password">Password: </label>
<input type="password" class="form-control" id="password" name="password"
{{$errors->has('password')?'class=alert alert-danger':'' }}
>
</div>
<div class="form-group">
<button type="submit" class="btn btn-default">Login</button>
<input type="hidden" name="_token" value="{{Session::token()}}">
</div>
</form>
</div>
</div>
</body>
</html>
so when i tried to login and dd the Auth Attempt it is returning false i have a user with email test#123.com and password test :
created the user using seeder :
<?php
use Illuminate\Database\Seeder;
class AdminTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
//
$admin = new \App\Admin;
$admin->email='test#123.com';
$admin->password='test#123.com';
$admin->save();
}
}
So for your seeder.
$admin = new \App\Admin;
$admin->email='test#123.com';
$admin->password='test#123.com';
$admin->save();
the password should be hashed using bcrypt.
$admin->password = bcrypt('test#123.com');
but as you've said, you're trying 'test' as the password, so it should be:
$admin->password = bcrypt('test');
that should work.
the reason is, Auth::attempt hashes the entered password using bcrypt.
So if the stored password in your database is not bcrypt-ed, Auth::attempt
will fail to match the two passwords.
For example you put test as the password, plain text, if you try to login to laravel using Auth::attempt using password = 'test', string 'test' will be compared against the bcrpyt version of 'test'.
I'm trying to display flash data but it's not showing properly. It's showing:
{{ Session::get('flash_message') }}
but it should be the message
"Your article has been created"
What's wrong with my code? Thanks!
In my controller I have:
public function store(ArticleRequest $request)
{
Auth::user()->articles()->create($request->all());
\Session::flash('flash_message', 'Your article has been created');
return redirect('articles');
}
My app.blade.php is:
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>App Name - #yield('title')</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="{{ elixir('css/all.css') }}">
<script src= "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script src="js/app.js"></script>
</head>
<body>
<div class="container">
#if(Session::has('flash_message'))
<div class="alert alert-success">{{ Session::get('flash_message') }}</div>
#endif
#yield('content')
</div>
#yield('footer')
</body>
</html>
In my route.php I have the following: Curly braces display content as string not variables.
<?php
Blade::setContentTags('<%', '%>'); // for variables and all things Blade
Blade::setEscapedContentTags('<%%', '%%>'); // for escaped data
Route::get('/', function() {
return 'Home Page';
});
Route::get('blade', function () {
return view('about');
});
Route::get('about', 'HelloWorld#about');
Route::get('foo', ['middleware' => 'manager', function() {
return 'this page may only be viewed by managers';
}]);
Route:resource('articles', 'ArticlesController');
Route::controllers([
'auth' => 'Auth\AuthController',
'password' => 'Auth\PasswordController'
]);
If you have this in your route.php:
Blade::setContentTags('<%', '%>');
then that means you cannot use curly brackets for blade content. Try this instead:
#if(Session::has('flash_message'))
<div class="alert alert-success">
<% Session::get('flash_message') %>
</div>
#endif
or simply remove the setContentTags() call from your route.php.
You can make a multiple messages and with different types.
Follow these steps below:
Create a file: "app/Components/FlashMessages.php"
namespace App\Components;
trait FlashMessages
{
protected static function message($level = 'info', $message = null)
{
if (session()->has('messages')) {
$messages = session()->pull('messages');
}
$messages[] = $message = ['level' => $level, 'message' => $message];
session()->flash('messages', $messages);
return $message;
}
protected static function messages()
{
return self::hasMessages() ? session()->pull('messages') : [];
}
protected static function hasMessages()
{
return session()->has('messages');
}
protected static function success($message)
{
return self::message('success', $message);
}
protected static function info($message)
{
return self::message('info', $message);
}
protected static function warning($message)
{
return self::message('warning', $message);
}
protected static function danger($message)
{
return self::message('danger', $message);
}
}
On your base controller "app/Http/Controllers/Controller.php".
namespace App\Http\Controllers;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesResources;
use App\Components\FlashMessages;
class Controller extends BaseController
{
use AuthorizesRequests, AuthorizesResources, DispatchesJobs, ValidatesRequests;
use FlashMessages;
}
This will make the FlashMessages trait available to all controllers that extending this class.
Create a blade template for our messages: "views/partials/messages.blade.php"
#if (count($messages))
<div class="row">
<div class="col-md-12">
#foreach ($messages as $message)
<div class="alert alert-{{ $message['level'] }}">{!! $message['message'] !!}</div>
#endforeach
</div>
</div>
#endif
On "boot()" method of "app/Providers/AppServiceProvider.php":
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\Components\FlashMessages;
class AppServiceProvider extends ServiceProvider
{
use FlashMessages;
public function boot()
{
view()->composer('partials.messages', function ($view) {
$messages = self::messages();
return $view->with('messages', $messages);
});
}
...
}
This will make the $messages variable available to "views/partials/message.blade.php" template whenever it is called.
On your template, include our messages template - "views/partials/messages.blade.php"
<div class="row">
<p>Page title goes here</p>
</div>
#include ('partials.messages')
<div class="row">
<div class="col-md-12">
Page content goes here
</div>
</div>
You only need to include the messages template wherever you want to display the messages on your page.
On your controller, you can simply do this to push flash messages:
use App\Components\FlashMessages;
class ProductsController {
use FlashMessages;
public function store(Request $request)
{
self::message('info', 'Just a plain message.');
self::message('success', 'Item has been added.');
self::message('warning', 'Service is currently under maintenance.');
self::message('danger', 'An unknown error occured.');
//or
self::info('Just a plain message.');
self::success('Item has been added.');
self::warning('Service is currently under maintenance.');
self::danger('An unknown error occured.');
}
...
Hope it'l help you.
I'm having a problem with an ajax method, it retrieves an html file instead of json and I have no clue why it is happening because it works perfectly in my home route, but when I try to implement it in my create route, the ajax method doesn't work right
route file
Route::get('home', 'HomeController#index');
Route::get('suggestions',[
'as' => 'suggestions_path',
'uses' => 'SuggestionController#index'
]);
Route::get('suggestions/create',[
'as' => 'suggestions_path',
'uses' => 'SuggestionController#create'
]);
Route::get('ajax_scrap_app',[
'as' => 'ajax_scrap_app_path',
'uses' => 'AjaxController#getAppOpenGraph'
]);
HomeController
<?php namespace App\Http\Controllers;
use App\Level;
class HomeController extends Controller {
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('auth');
}
/**
* Show the application dashboard to the user.
*
* #return Response
*/
public function index()
{
$levels = Level::all();
//dd($levels);
return view('home')->with('levels',$levels);
}
}
SuggestionController
<?php namespace App\Http\Controllers;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Http\Requests\SuggestionRequest;
use App\Level;
use App\Scrap;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Suggestion;
class SuggestionController extends Controller {
public function __construct()
{
$this->middleware('auth');
}
/**
* Despliega todas las sugerencias hechas por el usuario
*
* #return Response
*/
public function index()
{
$suggestions = Auth::user()->suggestions()->latest()->get();
return view('suggestions.all')->with('suggestions',$suggestions);
}
/**
* Despliega la forma para crear una sugerencia
*
* #return Response
*/
public function create()
{
$levels = Level::all();
return view('suggestions.create')->with('levels',$levels);
}
/**
* Guarda la nueva sugerencia
* #param SuggestionRequest $request
* #return Response
*/
public function store(SuggestionRequest $request)
{
$suggestion = new Suggestion($request->all());
Auth::user()->suggestions()->save($suggestion);
return redirect('suggestions');
}
/**
* Despliega una sugerencia específica, basados en el id
*
* #param int $id
* #return Response
*/
public function show($id)
{
$openGraph = new Scrap();
$suggestion = Suggestion::find($id);
return view('suggestions.show')->with(['suggestion' => $suggestion, 'openGraph' => $openGraph]);
}
/**
* Despliega la forma para editar una sugerencia específica, basados en el id
*
* #param int $id
* #return Response
*/
public function edit($id)
{
$suggestion = Suggestion::find($id);
return view('suggestions.edit')->with('suggestion',$suggestion);
}
/**
* Actualiza la sugerencia
*
* #param int $id
* #param SuggestionRequest $request
* #return Response
*/
public function update($id, SuggestionRequest $request)
{
$suggestion = Suggestion::find($id);
$suggestion->update($request->all());
return redirect('suggestions');
}
/**
* Remove the specified resource from storage.
*
* #param int $id
* #return Response
*/
public function destroy($id)
{
//
}
}
here is my ajax method so far
$('#app_url').on('focusout',function(e){
var appURL = e.target.value;
console.log("appURL: "+appURL);
/* AJAX */
$.get('ajax_scrap_app?app_url='+appURL, function (data) {
console.log(data);
console.log("THIS IS THE TITLE: "+data[0].title);
console.log("THIS IS THE DESCRIPTION: "+data[0].description);
console.log("THIS IS THE IMAGE: "+data[0].image);
$('#app_title').val(data[0].title);
$('#app_description').val(data[0].description);
$('#app_image').val(data[0].image);
});
});
this is AjaxController
public function getAppOpenGraph(){
$scrap = new Scrap();
$url = Input::get('app_url');
$scrap::setUrl($url);
$title = $scrap::getOpenGraphTitle();
$description = $scrap::getOpenGraphDescription();
$image = $scrap::getOpenGraphImg();
$openGraph = [['title'=>$title,'description'=>$description,'image'=>$image]];
return Response::json($openGraph);
}
OUTPUT from home page (http://localhost/exaproject/public/home)
appURL: https://itunes.apple.com/us/app/crossy-road-endless-arcade/id924373886?mt=8&v0=WWW-NAUS-ITSTOP100-FREEAPPS&l=en&ign-mpt=uo%3D4
[Object]
THIS IS THE TITLE: Crossy Road - Endless Arcade Hopper
THIS IS THE DESCRIPTION: Get Crossy Road - Endless Arcade Hopper on the App Store. See screenshots and ratings, and read customer reviews.
THIS IS THE IMAGE: http://a3.mzstatic.com/us/r30/Purple7/v4/20/7a/c2/207ac26e-66f1-1ee0-1f70-c4733a9015a1/icon320x320.png
OUTPUT form create page (http://localhost/exaproject/public/suggestions/create)
appURL: https://itunes.apple.com/us/app/crossy-road-endless-
arcade/id924373886?mt=8&v0=WWW-NAUS-ITSTOP100-FREEAPPS&l=en&ign-mpt=uo%3D4
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Apprendiendo</title>
<link href="http://localhost/exaproject/public/css/app.css" rel="stylesheet">
<!-- Latest compiled and minified CSS -->
<!--<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">-->
<!-- Fonts -->
<link href='//fonts.googleapis.com/css?family=Roboto:400,300' rel='stylesheet' type='text/css'>
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle Navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Apprendiendo</a>
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li>Home</li>
<li class="dropdown">
Sugerencias <span class="caret"></span>
<ul class="dropdown-menu" role="menu">
<li>Crear Sugerencia</li>
<li>Búscar Sugerencias</li>
<li>Mis Sugerencias</li>
</ul>
</li>
<li>Mi Plan</li>
<li>Mi perfil</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li class="dropdown">
Angel Salazar <span class="caret"></span>
<ul class="dropdown-menu" role="menu">
<li>Logout</li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
<div class="container">
</div>
<!-- Scripts -->
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.1/js/bootstrap.min.js"></script>
<script src="http://localhost/exaproject/public/js/app.js"></script>
</body>
</html>
THIS IS THE TITLE: undefined
THIS IS THE DESCRIPTION: undefined
THIS IS THE IMAGE: undefined
I would appreciate some help !!!
Views by default return a string content like you did:
public function create()
{
$levels = Level::all();
// here you are calling an hmlt/text output
return view('suggestions.create')->with('levels',$levels);
}
That is the main reason why you are receiving html response. There are two options:
Return the rendered view inside of json:
public function create()
{
$levels = Level::all();
// here you are calling an hmlt/text output
$output = view('suggestions.create')->with('levels',$levels)->render();
return response()->json(['html' => $output]);
}
By this way, you can read the response in ajax callable as json like data.html
Avoid returning views. If you want json plain data, then works for that:
public function create()
{
// Do some logic here
// Return json data
return response()->json(['foo' => 'bar']);
}
Finally, looks like you are working with RESTful controllers, that is ok, but resources controllers do not were made to return html data.
I made it work, I don't know exactly why, but those are the changes I made
Route.php
Route::get('suggestions/create/ajax_scrap_app',[
'as' => 'ajax_scrap_app_path',
'uses' => 'AjaxController#getAppOpenGraph'
]);
Ajax method
$('#app_url').on('focusout',function(e){
var appURL = e.target.value;
console.log("appURL: "+appURL);
/* AJAX */
$.get('create/ajax_scrap_app?app_url='+appURL, function (data) {
console.log(data);
console.log("THIS IS THE TITLE: "+data[0].title);
console.log("THIS IS THE DESCRIPTION: "+data[0].description);
console.log("THIS IS THE IMAGE: "+data[0].image);
$('#app_title').val(data[0].title);
$('#app_description').val(data[0].description);
$('#app_image').val(data[0].image);
},'json');
});