suhaib-kotb/nova-ajax-text
A Laravel Nova field by Suhaib Kotb that upgrades plain text inputs into AJAX-powered fields, fetching and saving values asynchronously without full page reloads. Handy for inline editing and dynamic, responsive forms inside Nova resources.
This is an unproven package (0 stars, 0 dependents), so treat the first ten minutes as a code review, not an install.
composer require suhaib-kotb/nova-ajax-text first; if that fails, add a VCS repository entry pointing at the GitHub URL and require dev-master. Pin the commit in composer.json — dev-master with no tags means your build is not reproducible.src/ before you register anything. A Nova field is small by design: you are looking for one class extending Laravel\Nova\Fields\Field (or Text), a composer.json declaring a nova service provider, and a dist/js/field.js (compiled) or resources/js/ (source) plus webpack.mix.js. If there is no dist/, you must build the assets yourself — confirm Node and laravel-nova are available.dist/js/field.js, search for nova-api, axios, or a route string. That tells you instantly what the field actually does — whether it PATCHes the resource field directly, calls a custom route the package registers, or just does client-side suggestion fetching. This single grep answers 90% of the questions you will have later.fields() method, load the detail page, and watch the network tab on blur. Do not wire it into a production resource until you can see the request and its response.The natural first use case for a field like this is inline editing on the detail page — a short text column (internal note, SKU, slug, ticket reference) that the user can change without entering the full edit form and clicking Update. If the field does not behave that way, you have likely misread its purpose and should stop here.
Standard field usage. The field follows Nova conventions, so it slots into fields() like any other:
use SuhaibKotb\NovaAjaxText\AjaxText;
public function fields(NovaRequest $request)
{
return [
ID::make()->sortable(),
Text::make('Name')->rules('required', 'max:255'),
AjaxText::make('Internal Reference')
->rules('max:64')
->help('Saves on blur.'),
];
}
Scope it to detail and update only. If the field writes on blur, it has no meaningful index behaviour and will confuse users on the Index view. Guard it with ->hideFromIndex() and ->hideWhenCreating() unless the package's README explicitly supports create-time use.
Pair with authorization, not just validation. Because the save path bypasses the normal Update request, Nova's authorize() on the resource may not run. Add ->canSee(fn ($request) => $request->user()->can('update', $this->resource)) and ->readonly(fn () => ...) for locked records, so the field cannot become a privilege-escalation hole on a resource with a policy.
Compose with the rest of the field API. Chaining ->rules(), ->nullable(), ->placeholder(), ->default(), and ->fillUsing() generally works because these are inherited from the base Field. Anything custom to this package will be in its own class — read the public methods there before assuming a chain method exists.
Model events and auditing. If you rely on saving/saved observers, LogsActivity, or Nova's action events, verify the AJAX path goes through $model->save(). If it uses a raw query builder update for speed, observers silently do not fire — a real problem for audit trails. Test this explicitly.
Multi-tenant and scoping. For any resource behind a global scope, confirm the endpoint resolves the model through Nova's nova-api resource route (which honours scopes and policies) rather than by raw id lookup.
field.js built against the wrong laravel-nova dev dependency will throw a blank field or a console error about an unknown component. Match the package's package.json against your Nova major version before debugging anything else.php artisan nova:publish (and check vendor/suhaib-kotb/nova-ajax-text/dist exists). After any fork or patch, bump the asset version — Nova caches aggressively.rules() on a Nova field are not a real guarantee here; replicate every constraint in the endpoint or in a FormRequest-equivalent guard, otherwise users can bypass max:255 and hit a MySQL truncation error.->readonly() field still renders; if the endpoint does not re-check authorization, a determined user can curl it. Treat the field as UI sugar over a normal API endpoint and secure the endpoint.fillUsing. For anything else — debounce timing, error display, optimistic UI — expect to fork the resources/js component. Fork early rather than patching vendor/, since composer update will wipe your changes.How can I help you explore Laravel packages today?