lordisp

Member Since 3 Months Ago

Experience Points
1,410
Total
Experience

3,590 experience to go until the next level!

In case you were wondering, you earn Laracasts experience when you:

  • Complete a lesson — 100pts
  • Create a forum thread — 50pts
  • Reply to a thread — 10pts
  • Leave a reply that is liked — 50pts
  • Receive a "Best Reply" award — 500pts
Lessons Completed
13
Lessons
Completed
Best Reply Awards
0
Best Reply
Awards
  • start your engines Created with Sketch.

    Start Your Engines

    Earned once you have completed your first Laracasts lesson.

  • first-thousand Created with Sketch.

    First Thousand

    Earned once you have earned your first 1000 experience points.

  • 1-year Created with Sketch.

    One Year Member

    Earned when you have been with Laracasts for 1 year.

  • 2-years Created with Sketch.

    Two Year Member

    Earned when you have been with Laracasts for 2 years.

  • 3-years Created with Sketch.

    Three Year Member

    Earned when you have been with Laracasts for 3 years.

  • 4-years Created with Sketch.

    Four Year Member

    Earned when you have been with Laracasts for 4 years.

  • 5-years Created with Sketch.

    Five Year Member

    Earned when you have been with Laracasts for 5 years.

  • school-in-session Created with Sketch.

    School In Session

    Earned when at least one Laracasts series has been fully completed.

  • welcome-newcomer Created with Sketch.

    Welcome To The Community

    Earned after your first post on the Laracasts forum.

  • full-time-student Created with Sketch.

    Full Time Learner

    Earned once 100 Laracasts lessons have been completed.

  • pay-it-forward Created with Sketch.

    Pay It Forward

    Earned once you receive your first "Best Reply" award on the Laracasts forum.

  • subscriber Created with Sketch.

    Subscriber

    Earned if you are a paying Laracasts subscriber.

  • lifer Created with Sketch.

    Lifer

    Earned if you have a lifetime subscription to Laracasts.

  • evangelist Created with Sketch.

    Laracasts Evangelist

    Earned if you share a link to Laracasts on social media. Please email [email protected] with your username and post URL to be awarded this badge.

  • chatty-cathy Created with Sketch.

    Chatty Cathy

    Earned once you have achieved 500 forum replies.

  • lara-veteran Created with Sketch.

    Laracasts Veteran

    Earned once your experience points passes 100,000.

  • 10k-strong Created with Sketch.

    Ten Thousand Strong

    Earned once your experience points hits 10,000.

  • lara-master Created with Sketch.

    Laracasts Master

    Earned once 1000 Laracasts lessons have been completed.

  • laracasts-tutor Created with Sketch.

    Laracasts Tutor

    Earned once your "Best Reply" award count is 100 or more.

  • laracasts-sensei Created with Sketch.

    Laracasts Sensei

    Earned once your experience points passes 1 million.

  • top-50 Created with Sketch.

    Top 50

    Earned once your experience points ranks in the top 50 of all Laracasts users.

  • Community Pillar

    Earned once your experience points ranks in the top 10 of all Laracasts users.

Level 1
1,410 XP
Apr
19
2 weeks ago
Activity icon

Started a new Conversation This Is A Component You May Like To Use For Inline Editing

I grab some code from a nice blog post which is actually a edit in place component with Livewire & Alpine.js. The only thing which made me scatty, is wasn't reusable for multiple columns in a table or fields in different forms with different models.

I've refactored the entire component to make this happen. So check it out!

Place it wherever you want in your project. For e.g.:

<x-table.cell class="font-bold">
                                <livewire:components.edit-field :model="'\App\Models\User'" :entity="$user" :field="'name'" :key="'users'.$user->id"/>
                            </x-table.cell>

EditField.php:

<?php

namespace App\Http\Livewire\Components;

use Illuminate\Support\Str;
use Livewire\Component;

class EditField extends Component
{
    public $origName;
    public $entityId;
    public $shortId;
    public $newName; // dirty operation name state
    public $isName; // determines whether to display it in bold text
    public string $field; // this is can be column. It comes from the blade-view foreach($fields as $field)
    public string $model; // Eloquent model with full name-space

    public function mount($model, $entity)
    {
        $this->entityId = $entity->id;
        $this->shortId = $entity->short_id;
        $this->origName = $entity->{$this->field};

        $this->init($this->model, $entity); // initialize the component state
    }

    public function save()
    {
        $entity = $this->model::findOrFail($this->entityId);
        $newName = (string)Str::of($this->newName)->trim()->substr(0, 100); // trim whitespace & more than 100 characters
        $newName = $newName === $this->shortId ? null : $newName; // don't save it as operation name it if it's identical to the short_id

        $entity->{$this->field} = $newName ?? null;
        $entity->save();
        $this->init($this->model, $entity); // re-initialize the component state with fresh data after saving
        $this->dispatchBrowserEvent('notify', Str::studly($this->field).' successfully updated!');
    }

    private function init($model, $entity)
    {
        $this->origName = $entity->{$this->field} ?: $this->shortId;
        $this->newName = $this->origName;
        $this->isName = $entity->{$this->field} ?? false;
    }

    public function render()
    {
        return view('livewire.components.edit-field');
    }
}

edit-field

<div
    x-data="
        {
             isEditing: false,
             isName: '{{ $isName }}',
             focus: function() {
                const textInput = this.$refs.textInput;
                textInput.focus();
                textInput.select();
             }
        }
    "
    x-cloak
>
    <div class="p-2" x-show=!isEditing>
        <span
            x-on:click="isEditing = true; $nextTick(() => focus())"
        >{{ $origName }}</span>
    </div>
    <div x-show=isEditing class="flex flex-col">
        <form class="flex" wire:submit.prevent="save">
            <x-input.text shadowless
                          type="text"
                          class="border-0 truncate focus:border-lh-yellow focus:ring focus:ring-lh-yellow focus:ring-opacity-50 h-7 rounded text-sm"
                          placeholder="100 characters max."
                          x-ref="textInput"
                          wire:model.lazy="newName"
                          x-on:keydown.enter="isEditing = false"
                          x-on:keydown.escape="isEditing = false"
            />
            <button type="button" class="pl-2 focus:outline-none" title="Cancel" x-on:click="isEditing = false"><i class="fas fa-undo-alt"></i></button>
            <button
                type="submit"
                class="pl-1 focus:outline-none text-green-700"
                title="Save"
                x-on:click="isEditing = false"
            ><i class="fas fa-check"></i></button>
        </form>
        <small class="text-xs">Enter to save, Esc to cancel</small>
    </div>
</div>

Have fun!!

Apr
17
3 weeks ago
Activity icon

Replied to Dynamic X-data And X-on Variables For Reusable Components

thank you for your help but this does not work. I'll continue playing around with it and post some more debugging details. And btw, you may have overseen the REPLACE_MEfor the session

Apr
16
3 weeks ago
Activity icon

Started a new Conversation Dynamic X-data And X-on Variables For Reusable Components

I like to build a toggle component where I can dynamically change the variables via a property:

<x-toggle :toggle="my_x_toggle" wire:click="doSomething"/>

the property toggle with it's value my_x_toggle shall replace the highlighted REPLACE_ME below

@props(['toggle'])
<div x-data="{ REPLACE_ME: sessionStorage.getItem('REPLACE_ME') }">
    <button x-on:click="{REPLACE_ME = !REPLACE_ME}" type="button" {!! $attributes->merge(['class' => 'flex-shrink-0 group relative rounded-full inline-flex items-center justify-center h-5 w-10 cursor-pointer focus:outline-none  focus:ring-offset-2 focus:ring-white" role="switch" aria-checked="false']) !!}>
        <span class="sr-only">Use setting</span>
        <span aria-hidden="true" class="pointer-events-none absolute bg-white w-full h-full rounded-md"></span>
        <span aria-hidden="true" class="{{(session('REPLACE_ME') === false) ? 'bg-gray-200' : 'bg-lh-yellow'}}  pointer-events-none absolute h-4 w-9 mx-auto rounded-full transition-colors ease-in-out duration-200"></span>
        <span aria-hidden="true" class="{{(session('REPLACE_ME') === false) ? 'translate-x-0' : 'translate-x-5'}} pointer-events-none absolute left-0 inline-block h-5 w-5 border border-gray-200 rounded-full bg-white shadow transform ring-0 transition-transform ease-in-out duration-200"></span>
    </button>
</div>