Skip to content
This repository has been archived by the owner on Sep 16, 2024. It is now read-only.
/ laravel-inplace Public archive

inline edit with laravel blade components

License

Notifications You must be signed in to change notification settings

mwkcoding/laravel-inplace

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Laravel Inplace

Latest Version on Packagist Total Downloads

Because forms are boaring.

This package provide set of blade components to make editing content exciting & blazing fast.

Installation

composer require devsrv/laravel-inplace

Setup (required)

include @include('inplace::styles') and @include('inplace::scripts') on every page where you'll be using the inplace component

its best to add those directives in your main layout blade file and extend that blade layout

...
    @include('inplace::styles')
</head>
<body>
    ...

    @include('inplace::scripts')
</body>
</html>

Publishing Frontend Assets (required)

php artisan vendor:publish --provider="devsrv\inplace\InplaceServiceProvider" --tag=public
๐Ÿ’ก NOTE :

when updating the package make sure to use the --force flag to keep the assets up-to-date i.e.

php artisan vendor:publish --provider="devsrv\inplace\InplaceServiceProvider" --tag=public --force

Publish config (optional)

php artisan vendor:publish --provider="devsrv\inplace\InplaceServiceProvider" --tag=config

โœ”๏ธ icons :

svg content for edit save and cancel button icon

โœ”๏ธ middleware :

add as many middlewares you with in the middleware array e.g.: ['auth', 'admin']

Guide

Inline Editable All Examples here

Example 1 | simplest usage

<x-inplace-text
  model="App\Models\User:name,1"		// (REQUIRED) format: App\ModelNamespace\Model:id
  :model="\App\Models\User::find(1)" 	// Alternatively you can pass model instance
  column="name"							// (OPTIONAL) name of the table column to update
  validation="required|min:10"			// (OPTIONAL) pass validation rules
>
  {{ \App\Models\User::find(1)->name }}
</x-inplace-text>

Example 2 | Slotted Markup

<x-inplace-text
	:model="$user"
    ...
>
   <x-slot name="before"><div class="myclass anotherclass"><h2></x-slot>	// custom markup prepend
   <x-slot name="after"></h2></div></x-slot>								// custom markup append

    {{ $user->email }}
</x-inplace-text>

Example - 3 | Pass Custom Class to save content check here

the custom save class must be a invokable object (class with __invoke method) which receives $model, $column, $value and it should return an array with key success (bool) and message (string)

Example Custom Save class : refer to this CustomSave full example

Example - 4 | Render content as custom component

<x-inplace-text
  model="..."
  render-as="CustomInlineRender"		// pass your own blade component which takes care of how content gets rendered
>
  ...
</x-inplace-text>

make sure to pass {{ $attributes }} to the html elenent that is wrapping the target content e.g.: <h1 class="your-class" {{ $attributes }}></h1>

refer to this example component

Example - 5 | Complex Validation Rules

@php
$rules = ['required', \Illuminate\Validation\Rule::in(['11', '12']), 'min:2'];
@endphp

<x-inplace-text
model="App\Models\User:1"
column="name"
:validation="$rules"                   // complex validation can be passed`
>
  {{ \App\Models\User::find(1)->name }}
</x-inplace-text>

refer this example

๐Ÿ“Œ Note:

if using direct inplace blade component to pass all the configs, authorization will be enforced always. to override/customize this behaviour consider using field maker configurator.

๐Ÿ‘พADVANCED

instead passing config via attributes you can use the advanced field configurator file where you have access to fluent config setter methods, also this approach lets you reuse same config for multiple edits and more fine grained options to configure

php artisan inplace:config {all | text | relation}

this command will create App\Http\Inplace\Text.php and App\Http\Inplace\Relation.php or just one of them depending on your input

in the config method of the class add multiple configs as array

for inline field: using devsrv\inplace\InlineText class and

for relation field: using devsrv\inplace\RelationManager class

then you can simply use the component as:

<x-inplace-text
	id="USERNAME"							// the should match id of field config
	:model="\App\Models\User::find(1)"		// however model still needs to be passed via attribute (always required)
>

refer to this file for example

Field configurator supports some extra methods like: authorizeUsing( closure ), bypassAuthorize(), middleware(['foo', 'bar']) etc.

detailed documentation comming soon . . .

โ˜„๏ธ Rate Limiting:

there are two ways to rate limit inplace requests

  1. Generic Rate Limiter: define rate limiter and put the rate limiter middleware name in either config file to apply globally or attach in the field config in ->middleware() method. example

by doing this when a field's request gets blocked by 429, any field which is configured with that same rate limiter middleware will also be blocked

  1. Field Level Rate Limiter: define rate limiter using devsrv\inplace\RateLimiter and attach it in field config

field level rate limiter blocks only same type fields.

Example 1 - if you are saving the name for user with id 1 and the field gets rate limited then this has no effect on any other field which is configured with the same field level rate limiter middleware.

Example 2 - if you are updating badges relation of user with id 2 and the request gets rate limited then this has no effect on any other relation or even non relation field which is configured with the same field level rate limiter middleware

Defining Field Level Rate Limiter: example

App\Providers\RouteServiceProvider.php

use devsrv\inplace\RateLimiter as InplaceFieldRateLimiter;

protected function configureRateLimiting()
{
	InplaceFieldRateLimiter::for('author_badges')->perMinute(1);  // support perMinutes | perHour | perDay
}

Supported available limiter methods

Method Description
perMinute check api
perMinutes check api
perHour check api
perDay check api

๐ŸŽ Bonus:

1. authorize manually:

when passing custom class to save data you may choose to authorize the action from within your class using

  1. Gate::authorize('update', $model); OR
  2. Gate::authorize('edit-settings'); OR
  3. $this->authorize('update', $model);

donn't forget to use the Illuminate\Foundation\Auth\Access\AuthorizesRequests trait.

referer this example

2. if you use the popular SPATIE PERMISSION package:

you may choose to use authorizeSpatieRoleOrPermission method that comes with the package as a support when you use the devsrv\inplace\Traits\SpatieAuthorize trait.

use devsrv\inplace\Traits\SpatieAuthorize;

class CustomSave
{
    use SpatieAuthorize;

    public function __invoke($model, $column, $value)
    {
    	$this->authorizeSpatieRoleOrPermission(['admin', 'some permission']);

        // save data here

        return [
            'success' => 0,
            'message' => 'not allowed'
        ];
    }
}

refer this example

2. ๐Ÿ”ฅ Listen events

  1. inplace-editable-progress custom window browser event diaptched after ajax start & ajax finished. refer to example for NProgress Implementation
  2. inplace-editable-finish custom window browser event diaptched after content is either saved | failed by server. refer to example for a sample notifier system

Changelog

Please see CHANGELOG for more information on what has changed recently.

License

The MIT License (MIT). Please see License File for more information.

๐Ÿ‘‹๐Ÿผ Say Hi!

Leave a โญ if you find this package useful ๐Ÿ‘๐Ÿผ, don't forget to let me know in Twitter