Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Star Rating Bundle Laravel Package

nurikabe/star-rating-bundle

A Symfony bundle for adding reusable star-rating fields to forms and views, making it easy to collect and display user Ratings with lightweight, configurable integration and Twig-friendly rendering.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a Symfony 2-era bundle (last tagged release April 2015). Laravel does not use Symfony bundles, so you will not composer require this into a Laravel app and get anything useful — the bundle service provider registers a Symfony FormType and TwigExtension, both of which assume the Symfony Form component and Twig bundle conventions.

Treat it as a reference implementation for wiring FyneWorks' star-rating jQuery widget into a form, not as a dependency.

Minimal steps to get value out of it:

  1. Clone the repo and read the two meaningful classes: the StarRatingType form type and the Twig extension. That is the entire integration surface.
  2. Note the two moving parts they expose: a form field that renders a container element, and a Twig function/filter that emits the widget markup with a value bound in. This is the pattern you will reproduce.
  3. Pull the underlying JS widget (FyneWorks' star rating / jquery-bar-rating-style plugin) as a static asset or via npm and load it after jQuery.
  4. In Laravel, replace the form type with a Blade component and the Twig extension with a component class + view.

First use case to target: a single integer rating (1–5) on a reviews table, rendered as clickable stars on a review form, persisted as an integer, and displayed read-only on the review list.

The smallest viable port:

{{-- resources/views/components/star-rating.blade.php --}}
@props(['name', 'value' => 0, 'max' => 5, 'readonly' => false])
<div class="star-rating"
     data-max="{{ $max }}"
     data-readonly="{{ $readonly ? 'true' : 'false' }}">
    <input type="hidden" name="{{ $name }}" id="{{ $name }}" value="{{ old($name, $value) }}">
</div>

Then initialize the widget against #{name} — the plugin reads/writes the hidden input.

Implementation Patterns

Blade component as the FormType replacement. The Symfony form type's only job is rendering a container plus a bound value. Your Blade component does the same: accepts name, value, max, and readonly, emits a hidden input and a container the JS plugin attaches to. Pass old($name, $value) so validation failures preserve state.

Livewire / reactive forms. The widget is a jQuery plugin that mutates a hidden input directly, which does not fire Livewire's model events. Bind with wire:model on the hidden input and wrap the widget container in wire:ignore so Livewire does not re-render and wipe the plugin's DOM. After any Livewire update, re-run the plugin init in a Livewire.hook('message.processed', ...) or dispatch a browser event:

<div wire:ignore>
    <x-star-rating name="rating" :value="$rating" />
</div>
document.addEventListener('livewire:load', () => {
    Livewire.hook('message.processed', () => { initStars(); });
});

Validation. The plugin writes to a hidden field, so validate exactly that field name in a FormRequest:

'rating' => ['required', 'integer', 'between:1,' . $max],

Never trust the client for the max — keep max in a config value and validate against it.

Read-only display. The extension supports a display mode in the original bundle. Mirror this as a separate prop (readonly) that renders static SVG/glyph stars on the index/show views instead of instantiating the plugin — cheaper and server-renderable.

Eloquent model + cast. Cast the column so views stay tidy:

protected $casts = ['rating' => 'integer'];

Reusable partial for lists. Iterate reviews and render the read-only component per row; do not instantiate the interactive plugin inside a loop unless you truly need per-row editing.

Integration tip — Vite. The 2015 bundle assumed script tags in a Twig base template. In a modern Laravel app, import the widget's JS and CSS in resources/js/app.js and resources/css/app.css, ensure jQuery is available globally before the plugin loads, and only call initStars() after DOMContentLoaded.

Gotchas and Tips

  • This bundle predates Symfony 3/4 and will not load as a bundle in any modern Symfony, let alone Laravel. Do not attempt composer require nurikabe/star-rating-bundle expecting working code. The value is entirely in reading its form type and Twig extension and porting ~50 lines.
  • jQuery dependency. FyneWorks' widget is a jQuery plugin. Adding jQuery to a Vite/ESM app is friction. Decide up front: either isolate the widget behind a single import that also pulls jQuery in, or skip the widget and build a tiny vanilla star component — the UX is trivial to reimplement.
  • Hidden input naming. The most common bug is a mismatch between the plugin's target input id and the name validation reads. Keep one source of truth (name) and derive the id from it.
  • Livewire re-renders destroy widget state. wire:ignore is mandatory; forgetting it produces "stars reset after save" bugs that look like validation failures.
  • Old Symfony API quirks. Expect getName() returning the bundle alias, Resources/views template paths, and a Twig extension registered via services.yml — all of which map to a Blade component + composer-autoloaded class in Laravel, not a service provider tagged call.
  • No maintained release since 2015 and zero dependents. Treat any bug you hit as yours to fix. Pin nothing; vendor the ~40 lines you need.
  • Debugging checklist: (1) Is jQuery loaded before the plugin? (2) Does the container exist at init time? (3) Does the hidden input have the exact name your FormRequest validates? (4) After a Livewire update, did you re-init? (5) With Vite, is the CSS actually imported, or are the stars rendering as unstyled text?
  • Extension point worth keeping: the Twig extension exposes max and value formatting. Preserve that configuration surface in your component (max prop, :value prop) so you can reuse the same component for 5-star and 10-point scales without duplicating markup.
  • If you are on Inertia/Vue or React, ignore this package entirely. There are maintained Vue/React star-rating components; porting a jQuery widget across the boundary is strictly negative value.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk