Laravel Nova - How to determine the view (index, detail, form) you are in for a resource's computed field?
Asked Answered
P

6

6

I would like to return a different result for a computed field when viewing the index view than when viewing the detail view of a resource.

Basically something like viewIs() below:

Text::make('Preview', function () {
    if($this->viewIs('index'){
        return \small_preview($this->image);
    }
    return \large_preview($this->image);
 })->asHtml(),
Plyler answered 10/12, 2018 at 10:17 Comment(0)
L
9

You can check the class of the request:

Text::make('Preview', function () use ($request) {
    if ($request instanceof \Laravel\Nova\Http\Requests\ResourceDetailRequest) {
        return \large_preview($this->image);
    }

    return \small_preview($this->image);
});

Otherwise, you can create your own viewIs function:

// app/Nova/Resource.php

/**
 * Check the current view.
 *
 * @param  string  $view
 * @param  \Laravel\Nova\Http\Requests\NovaRequest  $request
 * @retrun bool
 */
public function viewIs($view, $request)
{
    $class = '\Laravel\Nova\Http\Requests\\Resource'.ucfirst($view).'Request';

    return $request instanceof $class;
}

Then you can do it like this:

Text::make('Preview', function () use ($request) {
    if ($this->viewIs('detail', $request) {
        return \large_preview($this->image);
    }

    return \small_preview($this->image);
});
Lawgiver answered 10/12, 2018 at 16:2 Comment(1)
This technique appears to no longer be reliable in v4Taimi
D
5

Unfortunately, @Chin's answer did not work for me as for Edit view the request class is just a basic Laravel\Nova\Http\Request class.

My workaround to check if this is an index view is as follows:

/**
 * Check if the current view is an index view.
 *
 * @param  \Laravel\Nova\Http\Requests\NovaRequest $request
 * @return bool
 */
public function isIndex($request)
{
    return $request->resourceId === null;
}
Dactylography answered 19/1, 2019 at 23:11 Comment(0)
B
2

The NovaRequest class will soon be able to help, as the isResourceIndexRequest and isResourceDetailRequest are already in master.

As the Nova repo is private I will keep you posted, when it will be usable.

In the meantime I am falling back to helper methods on the Nova Resource class (app/Nova/Resource.php):

namespace App\Nova;

use Laravel\Nova\Http\Requests\ResourceDetailRequest;
use Laravel\Nova\Http\Requests\ResourceIndexRequest;
use Laravel\Nova\Resource as NovaResource;
use Laravel\Nova\Http\Requests\NovaRequest;

abstract class Resource extends NovaResource
{
    // [...]

    /**
     * Determine if this request is a resource index request.
     *
     * @return bool
     */
    public function isResourceIndexRequest($request)
    {
        return $request instanceof ResourceIndexRequest;
    }

    /**
     * Determine if this request is a resource detail request.
     *
     * @return bool
     */
    public function isResourceDetailRequest($request)
    {
        return $request instanceof ResourceDetailRequest;
    }
}

Usage:

public function fields(Request $request)
{
    $fields = [
        // [...]
    ];

    if ($this->isResourceDetailRequest($request)) {
        if ($this->isResourceDetailRequest($request)) {
            $fields = array_merge($fields, [
                // [...]
            ]);
        }
    }

    return $fields;
}
Berchtesgaden answered 12/3, 2020 at 9:53 Comment(0)
S
1

I added this little helper class

namespace App\Helpers;

class CurrentResourceAction {
    public static function isIndex($request)
    {
        return $request instanceof \Laravel\Nova\Http\Requests\ResourceIndexRequest;
    }
    public static function isDetail($request)
    {
        return $request instanceof \Laravel\Nova\Http\Requests\ResourceDetailRequest;
    }
    public static function isCreate($request)
    {
        return $request instanceof \Laravel\Nova\Http\Requests\NovaRequest &&
            $request->editMode === 'create';
    }
    public static function isUpdate($request)
    {
        return $request instanceof \Laravel\Nova\Http\Requests\NovaRequest &&
            $request->editMode === 'update';
    }
}

you can call it anywhere you need to

Smegma answered 27/6, 2020 at 16:30 Comment(1)
How do I instantiate $request in Nova Resource class?Liner
L
1

A bit late but hey! You can check against the NovaRequest properties editing and editMode ('create', 'update', 'attach' etc.)

// Determine if you are creating a model. 
$request->editMode == 'create';

Or as they say, "Read the source Luke" and see how they determine it. See the Laravel\Nova\Http\Requests\NovaRequest, it contains similar checks.

namespace Laravel\Nova\Http\Requests;

class NovaRequest extends FormRequest
{
    /**
     * Determine if this request is via a many to many relationship.
     *
     * @return bool
     */
    public function viaManyToMany();

    /**
     * Determine if this request is an attach or create request.
     *
     * @return bool
     */
    public function isCreateOrAttachRequest();

    /**
     * Determine if this request is an update or update-attached request.
     *
     * @return bool
     */
    public function isUpdateOrUpdateAttachedRequest();

    /**
     * Determine if this request is a resource index request.
     *
     * @return bool
     */
    public function isResourceIndexRequest();

    /**
     * Determine if this request is a resource detail request.
     *
     * @return bool
     */
    public function isResourceDetailRequest();

    /**
     * Determine if this request is an action request.
     *
     * @return bool
     */
    public function isActionRequest();
}

Would've been nice if you can type hint the NovaRequest instead of the regular one in the Nova resource fields() method but it is not allowed due to the parent resource being extended.

Lowestoft answered 13/3, 2021 at 23:16 Comment(1)
In the latest Laravel Nova release - v4, the NovaRequest is type hinted in the fields() and other methods so you can directly use these methods now.Lowestoft
H
0

You can create two separate fields for index & details page.

// ----- For Index page
Text::make('Preview', function () {
    return \small_preview($this->image);
})
->onlyOnIndex()
->asHtml(),

// ----- For Detail page
Text::make('Preview', function () {
    return \large_preview($this->image);
})
->onlyOnDetail()
->asHtml(),
Hypogeum answered 10/12, 2018 at 10:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.