Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

SeanKimball's avatar

Return a view from an HTML string

Having a beast of a time getting a dynamic form setup, I am trying to assemble the form from a json config file and use blade/components/template files to create an HTML string variable that I need to use essentially as a blade template to be passed to the view..... (if that makes sense) below is what I have tried, everything does actually work except for the rendering of the @error blocks - they show up on the rendered page....!


namespace App\Livewire;

use App\Models\Forms;
use Livewire\Component;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\View;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\Facades\Storage;
use Illuminate\View\ComponentAttributeBag;

class ShowFormWire extends Component
{

    public $states = [];
    public $message;
    public $markup;


    public function mount()
    {

        $formfields = [
            'firstname',
            'lastname',
        ];
        foreach ($formfields as $field) {
            $this->states[$field] = $field;
        }

    }

    public function updated($property, $value)
    {

        $rules = [
            'states.firstname' => 'required|min:5|numeric',
            'states.lastname' => 'required|min:5|numeric',

        ];
        $messages = [
            'states.firstname.required' => 'Name field is required.',
            'states.firstname.min' => 'Name field must be at least 552243 characters.',
            'states.firstname.numeric' => 'Name field must be a number.',
            'states.lastname.required' => 'lastnameName field is required.',
            'states.lastname.min' => 'lastnameName field must be at least 5435 characters.',
            'states.lastname.numeric' => 'lastnameName field must be a number.',
        ];

        $this->validateOnly($property, $rules);

    }

    public function render()
    {

        $this->markup = $this->processJson();

        // dump($this->markup);

        return view('livewire.showform', [
            'markup' => $this->markup
        ])->layout('layouts.showform');

        // $view =  Blade::compileString($this->markup);

        // $view = View::make('livewire.showform', ['markup' => Blade::compileString($this->markup)]);
        $view = View::make('livewire.showform', ['markup' => $this->markup]);

        // dump($this->markup, $view->layout('layouts.showform'));

        return $view->layout('layouts.showform');

        // return view('livewire.showform')->layout('layouts.showform');
    }

    public function processJson()
    {
        $form = Forms::where('uuid', session('form'))->first();

        $form['definition'] = Storage::disk('private')->get('form-definitions/definition-default.json');

        $definition = json_decode($form->definition, true);

        $components = collect($definition)->map(function ($node) {

            $component = $node['component'];

            $attributes = [];

            $attributes = array_merge($node['meta'] ?? [], $node['data-attribs'] ?? [], $node['arias'] ?? []);

            // $string = View::make('components.'.$component, [
            //     'name' => $node['name'] ?? '',
            //     'slot' => $node['slot'] ?? '',
            //     'disabled' => $node['disabled'] ?? false,
            //     'attributes' => new ComponentAttributeBag($attributes),
            //     'errorBag' => 'default',
            //     ])->render();
            $string = '<input wire:model.live="states.'.$node['name'].'" type="text" class="py-3 px-4 block" /> ##ERROR##';
            $errormarkup = '@error("states.'.$node['name'].'")
                <p class="text-red-500 text-xs italic mt-4">
                    {{ $message }}
                </p>
            @enderror
            ';

            $string = str_replace('##ERROR##', $errormarkup, $string);

            return $string;

        })->implode('');

        return $components;
    }
}

0 likes
2 replies
LaryAI's avatar
Level 58

The issue with the code is that the render() method is returning the view before modifying the HTML string. To fix this, you need to remove the first return statement and modify the HTML string before passing it to the view.

Here's the updated code:

public function render()
{
    $this->markup = $this->processJson();

    $view = View::make('livewire.showform', ['markup' => $this->markup]);

    $view->layout('layouts.showform');

    return $view;
}

Make sure to remove the commented out code as well.

This will ensure that the HTML string is modified before being passed to the view.

SeanKimball's avatar

@LaryAI thanks larry, the first return block in the render method is a typo, one of the many things I have tried, but it is also identical in function to the next return value. so, no that is not the answer.

Please or to participate in this conversation.