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

Filament Jalali Laravel Package

ariaieboy/filament-jalali

Bring Jalali (Persian) calendar support to Filament forms and tables. This plugin provides Jalali date, datetime, and time pickers, plus formatted table columns, so Laravel/PHP admin panels can handle Persian dates without custom conversion code. Easy to install and configure for Persian-language ap...

View on GitHub
Deep Wiki
Context7

Getting Started

Upgrade context first. The 3.1.0 release is a small, quiet release — dependency bump, README improvements, and one bug fix — but the fix it carries is the one that matters most to you: PR #44, titled "مشکل در نمایش تقویم بعد از آپدیت" ("calendar display problem after the update"), issue #43. That is a direct confirmation that 3.0.0 shipped a calendar rendering regression, which is exactly the class of symptom you'd otherwise spend a day debugging as a config or asset problem.

Practical consequences:

  1. Do not install ^3.0.0 and land on 3.0.x. Require ^3.1 explicitly. If you already upgraded to 3.0.x, 3.1.0 is your fix — upgrade before investigating anything else.
  2. 3.0.0's changelog is still effectively empty. The major bump was undocumented. 3.1.0 does not retroactively document it. Still open the 2.2.0...3.0.0 compare link and read composer.json on the 3.1.0 tag before writing code.
  3. The README is now worth reading (PR #42, first-time contributor). Previously it lagged badly; it's been improved. Treat it as the primary doc for 3.1.0 specifically — but still verify class names against vendor source, since examples can lag the tag.

Answer these three questions before coding:

  1. Which Filament major does 3.1.0 require (filament/filament: ^3.0 vs ^4.0)?
  2. Did the component/service-provider namespace move in 3.0 (and therefore apply to 3.1)?
  3. Was the config file schema changed (keys renamed/removed)?

Install / upgrade

composer require ariaieboy/filament-jalali:^3.1
php artisan vendor:publish --tag="filament-jalali-config" --force
php artisan filament:upgrade   # or: php artisan filament:assets
php artisan optimize:clear

Re-publishing with --force matters on a major bump: the compiled JS/CSS in public/ and the published config are the two artefacts that silently survive an upgrade and cause "nothing changed" symptoms. On 3.1.0 the same applies — if you jumped 3.0 → 3.1 and the calendar is still broken, stale assets are the first suspect, then confirm you actually resolved 3.1.

Where to look first

  • config/filament-jalali.php — locale, timezone, display format, asset/CDN options. Still the highest-confusion file, though the improved README now covers more of it.
  • The improved README on the 3.1.0 tag — read it and cross-check against src/Components/ for actual class names.
  • The vendor source src/Components/ — grep -r "class Jalali" vendor/ariaieboy/filament-jalali/src. Trust this over any doc when they disagree.
  • Your panel provider, if 3.0 introduced a plugin registration object.

First use case

Replace a single Gregorian field rather than the whole app. In a Resource form:

use Ariaieboy\FilamentJalali\Components\JalaliDatePicker;

JalaliDatePicker::make('published_at')
    ->label('تاریخ انتشار')
    ->required(),

The model column stays a normal date / datetime in the database. The picker renders and accepts Jalali input but transmits a Gregorian value — so the rest of your app, your validation rules, your API, and your Carbon casts are untouched. Prove that end-to-end on one field (create, edit, re-open) before touching anything else.

Implementation Patterns

Per-field swap, not global swap. The lowest-risk migration is field-by-field. Keep the built-in DatePicker/DateTimePicker for non-Persian-facing fields and opt in explicitly. A small helper keeps the intent readable:

function jdate(string $name): JalaliDatePicker
{
    return JalaliDatePicker::make($name)->timezone(config('app.timezone'));
}

Store Gregorian, present Jalali. Never change the database column type or the $casts. The correct boundary is:

  • Write path: picker → Gregorian string → $casts = ['published_at' => 'date'] → Carbon.
  • Read path in Filament: the Jalali column/entry component formats for display.
  • Read path outside Filament (emails, PDFs, API): format at the edge with whatever Jalali library you already use, e.g. Verta::instance($model->published_at)->format('%Y/%m/%d') or Morilog\Jalali\Jalalian::fromCarbon(...). Do not leak Persian strings into JSON payloads consumed by other clients.

Tables, filters, infolists. Use the package's column/entry counterparts for display, but leave ->sortable() and ->searchable() pointed at the underlying Gregorian column — the database sorts and searches Gregorian, and that is correct. Any custom ->formatStateUsing() you had on the old column must be removed, or you'll double-format.

Validation stays Gregorian. Rules like after_or_equal:today, date, and before_or_equal operate on the transmitted value. Do not write date_format:Y/m/d — a Jalali-format rule will reject the Gregorian state the component actually submits. If you need Jalali-specific business rules (e.g. "not on a Persian public holiday"), convert the incoming Gregorian value in a Rule:: closure and compare there.

Reusable partials for large forms. If a resource has many date fields, extract the field definitions into a private function dateFields(): array and merge() them into both form() and the filter schema. This is the cheapest way to keep a mixed Gregorian/Jalali form consistent and to survive the next patch bump in one place.

Testing. Livewire/Filament form tests should set Gregorian values, not Jalali strings:

livewire(CreatePost::class)
    ->fillForm(['published_at' => '2025-03-21'])
    ->call('create')
    ->assertHasNoFormErrors();

Add one dedicated test asserting the round-trip (create → edit → form state unchanged). That single test catches almost every upgrade regression, including silent timezone shifts — and would have caught the 3.0.0 calendar rendering bug at the state level, if not the visual one.

Add a rendering smoke check. Because 3.0.0 shipped a visual calendar defect that only #44 fixed, a state-level test isn't sufficient. Include one assertion or manual check that the picker actually opens and renders a Jalali month grid — cheap insurance for the next release.

Rollout. Ship behind a feature flag or a per-panel config key so you can revert to the stock picker without a redeploy if a minor release misbehaves in production. The 3.0.0 → 3.1.0 sequence is proof that this package can ship a user-visible regression in a minor-adjacent upgrade path.

Gotchas and Tips

3.0.0 is a version to skip. If your composer.json resolves to 3.0.x, you are on a build with a known calendar display bug. Bump to ^3.1 before writing any workaround. Symptom to recognise: the picker opens but the calendar grid is empty, misaligned, or renders wrong/blank months — that's the #43/#44 regression, not your config.

The empty major changelog is still the main risk. 3.1.0 does not document what broke in 3.0.0 either. Assume nothing: diff the src/ tree and composer.json between 2.2.0 and 3.1.0, and check repo issues for reports against both tags. If your panel is on Filament v3 and 3.0+ requires v4, this is not an upgrade — it's a Filament migration, and it should be scheduled as one.

README is better but still not gospel. PR #42 substantially improved the docs in this release. Use them — but in the week after any release, examples can lag the tag. Grep the vendor source when the README and reality disagree, especially for class names and config keys.

Stale published assets. After any upgrade, the most common symptom is "the picker still renders Gregorian / the styling is broken." Cause is almost always old compiled assets or view cache: run php artisan filament:upgrade, php artisan vendor:publish --tag=filament-jalali-config --force, then php artisan optimize:clear and hard-refresh. Confirm the asset URL actually changed in the page source — and confirm composer show ariaieboy/filament-jalali reports 3.1.x before blaming the package.

Timezone off-by-one. Two independent clocks are in play: app.timezone (usually UTC) and the picker's configured timezone (usually Asia/Tehran). Mismatch produces dates that flip by a day for records created near midnight. Set the package config and app.timezone deliberately, and assert the round-trip test above with a timestamp at 23:30 local.

Daylight saving assumptions. Iran dropped DST in 2022, but stale Jalali libraries and hardcoded offsets still assume it. If you compute Jalali dates anywhere in PHP, make sure it's the same library/version the picker uses; mixing two Jalali implementations is how you get dates that disagree by an hour in Farvardin.

Month-end edge cases. Converting 31 Shahrivar / 30–31 Esfand against Gregorian month ends is where hand-rolled conversion code fails. Never addDays() in Jalali space — convert to Carbon, manipulate, convert back.

State dehydration. If a date field is conditionally hidden, confirm it's still ->dehydrated() when hidden or you'll null the column on update. This bites hardest on forms where the Jalali picker replaced a field that previously always rendered.

RTL and panel locale. The picker's dir and the surrounding form layout are separate concerns. Force ->extraAttributes(['dir' => 'rtl']) (or set the panel to fa) rather than relying on global CSS, and check the picker inside a Grid/Section — popover positioning in RTL containers is a frequent visual regression across releases, and is in the same family of failure as the 3.0.0 calendar bug.

Extension points to prefer over forking. Filament\Forms\Components\DatePicker::configureUsing() for cross-cutting tweaks (timezone, display format), the published config for global defaults, and ->view() / a custom Blade view for presentation changes. Vendor-patching the picker's JS is the one thing that will make the next release unmaintainable — and note that the calendar rendering bug came from the package's own front-end, so patches there are the most likely to conflict.

Pin and watch. "ariaieboy/filament-jalali": "^3.1" plus a Renovate/Dependabot rule that surfaces patch releases for review rather than auto-merging: this release fixed a visible defect in a patch-level bump, which cuts both ways — you want to receive it quickly, but you also don't want a 3.2.x rendering change auto-deployed to a production panel.

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.
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core