Laravel Livewire Date Cast and Validation - laravel

I have a form with a modal and one of the fields in the modal form is a date field. It is cast in the Model as:
'date_last_contact' => 'date:m/d/Y'
In the $rules section of the livewire file it is set as:
'editing.date_last_contact' => 'date|nullable',
The issue is if I someone inputs a non-date, non-null value in the field and tries to save, it throws an error because it is not validating…
Carbon\Exceptions\InvalidFormatException
Could not parse ‘adff’: DateTime::__construct(): Failed to parse time string (adff) at position 0 (a): The timezone could not be found in the database
The Save function in the livewire file looks like this:
public function save()
{
$this->validate();
$this->editing->save();
$this->showEditModal = false;
}
What it seems is happening it is trying to CAST it to a date before the validation is happening. How can this be prevented?
Versions:
Laravel: 8.24.0
Livewire: 2.3.8

I'd use date format over date, enforce the structure on the BE, as well as add some front end validation to help hold the user's hand
https://laravel.com/docs/9.x/validation#rule-date-format

Try casting the date field before submiting the form.

Related

Carbon Date Being Saved as String in Database

I am trying to seed some data using Factories. One of the fields I'm trying to seed is a date field -- and I do so with the following code in my factory:
return [
...
'date' => Carbon::now()->subDays(rand(1, 365))->startOfDay()
];
The problem is, this is getting saved in the database as a string -- which means that I CANNOT do the following in my blade templates: {{ $transaction->date->format('M, d Y') }},
When I try that, I get the following error message: Call to a member function format() on string.
Just as a test, I tried in my blade template the same exact code, just switching out created_at for date - and it works as I want. I.e., this works: {{ $transaction->created_at->format('M, d Y') }}.
In case it matters, the created_at field is created using $table->timestamps() in my migration file whereas the date field is created as follows: $table->date('date');.
Any idea what I need to do in order to get this to work?
Thanks.
Laravel provides a method to "cast" certain Model attributes to specific datatypes, including strings, integers, dates, etc. Since Carbon is built in to Laravel, specifying the date type auto-converts Model attributes to a Carbon instance. All you need to do is provide that logic to your model:
class Transaction extends Model {
protected $casts = [
'date' => 'date'
];
...
}
Now, when you retrieve a Transaction model record, the date attribute will automatically be a Carbon instance:
$transaction = Transaction::first();
dd($transaction->date, get_class($transaction->date));
// ^ Carbon\Carbon #1646769789^ {#4514 ... }, `Carbon\Carbon`
Now, you can perform Carbon logic, simply by chaining:
{{ $transaction->date->format('Y-m-d') }}
// `2022-03-08`
More casting types are available, and you can specify multiple attribute casts by simply adding them as key/value pairs to the $casts array. Full documentation is here:
https://laravel.com/docs/9.x/eloquent-mutators#attribute-casting

What type of class of datetime fields in laravel

When I fetch data from database using Laravel, I got some timestamp field like 'created_at', 'updated_at',....
What type of class for these fields, what type of class which return true of expression $created_at instanceof DatetimeClass
Thanks
Recent Laravel uses (Carbon library v2)
for that type of data (Illuminate\Support\Carbon).
As for ... instanceof DatetimeClass part of your question, I am not sure what really you refer to as DatetimeClass class, but I assume that you meant built-in DateTime class. If that's so, you can get DateTime from Carbon object by calling toDateTime(), i.e.:
$dt = $model->created_at->toDateTime();
Alternatively, edit your ... instanceof ... uses to test against Carbon.
Please also have a look at date mutators in Laravel. Laravel will automatically cast a timestamp(created_at, updated_at) or when you need to define custom date fields in the db you can define these in the model: https://laravel.com/docs/7.x/eloquent-mutators#date-mutators
If you do not want to automatically cast you can parse a string representation of a date using $carbonObject = Carbon::parse('2020-02-03');

L5 Unable to store Jquery datepicker value to database

I am using L5 with eloquent. In my model i defined below function for necessary database table field.
public function getBuyingDateAttribute($value)
{
return Carbon::parse($value)->format('d/m/Y');
}
Datepicker
$( "#buying-date" ).datepicker({dateFormat: 'dd-mm-yy'});
I am able to display a current value with this format in my form(usingform model binding) but when i try to store or update the field the value comes null. I am a newbie with Laravel and Eloquent. How can i format and store the data properly ? Anyhelp would be appreciated.
if in your form the date column name is date then use the following in your controller
$date = date('d/m/Y',strtotime($request->date));
//here $request is the object of Request class

Enum unbinds from the model on ajax call

I am reading an enum value from the db then bind it to the model. When i post the form with ajax, somehow the enum is unbound or the model property in null or zero but it display properly on the view. I have posted code below. Im using entityframework and mvc3
//model code constructor
public CarModel(Car car)
{
State=(CarState)car.State;
//car.State comes in as an int
//etc setting other variables
}
//CarState property
public CarState {get;set;}
//model code
#Html.DisplayFor(m=>m.CarState)
//Controller code()
Save(CarModel car)
{
//I have code that saves the changes
}
The minute i get to "car", CarState has no value.
It's not quite clear how you are passing this value to the controller action. You have only shown some #Html.DisplayFor(m=>m.CarState) but obviously this only displays a label in the view. It doesn't send anything back to the server. If you want to send some value back you will have to use an input field inside the form.
For example:
#Html.EditorFor(m => m.CarState)
or use a HiddenFor field if you don't want the user to edit it.
In any case you need to send that value to the server if you expect the model binder to be able to retrieve it. The model binder is not a magician. He cannot invent values. He binds values to your model from the Request.

Validate Custom Sharepoint field if Empty?

I'm using Sharepoint 2010 .. with a custom field in visual studio 2010.
I created a custom field. This particular one is a datetime field ("Termination Date"). I want it to fail validation if it is blank and another field ( "Contract Terminates" is equal to yes ).
So I had previously did this with a calculated field. And that works but it puts the validation error at the top of the edit form, not next to the "Termination Date" field where I want it.. like it would normally be if the field failed validation using GetValidatedString in a custom field.
So because it's in the wrong place, I made a custom field. But because the date is blank, it never hits GetValidatedString method. Am I missing something? is there another way to have it fail validation and be next to the 'Termination Date' field if the 'Termination Date' field is blank?
I'm tried using an event receiver solution also.. the problem there is that it would also put the error message on the top.. not next to the Termination Date field.
Suggestions?
For custom field you could override FieldRenderingControl, write your own FieldControl. If you don't use this custom field in Whereabouts list you could inherited your fieldcontrol from DateTimeField and override Validate method e.g:
public override void Validate()
{
base.Validate();
if (IsValid)
{
if (!(your validation))
{
IsValid = false;
ErrorMessage = “youe message”;
}
}
}

Resources