Laravel, can't set old value to bootstrap datetimepicker, when validate - laravel

I'm using Laravel 8.5 (current version)
Therefore I'm new to laravel, I'm trying to learn with simple examples.
I have some blade view, with code part bellow:
<div class="form-group">
<input type="hidden" id="hdnLocale" value="ru">
<input type="hidden" name="hdndefDate" id="hdndefDate" value="2021-01-17">
#if (old('hdndefDate'))
<input type="hidden" name="hdndefDate" value="{{ old('hdndefDate') }}">
#endif
<label for="picker">Birthday</label>
<div class="input-group">
<div class="input-group-prepend">
<button type="button" class="input-group-text" id="toggle">
<i class="fa fa-calendar-alt"></i>
</button>
</div>
<input type="text" id="picker" name="picker" value="{{old('picker')}}" class="form-control" readonly>
</div>
</div>
As you see I'm using two hidden inputs, with a variable value from the controller, that must be set from javaScript (In a simple I use exact value).
Here is my script:
<script>
var locale = $('#hdnLocale').val()
jQuery.datetimepicker.setLocale(locale)
jQuery.datetimepicker.setDateFormatter('moment')
var yourDate = $('#hdndefDate').val();
$('#picker').val(yourDate);
$('#picker').datetimepicker({
timepicker: false,
datepicker: true,
format: 'YYYY-MM-DD',
defaultDate: yourDate,
weeks: false,
hours12: false,
step: 15,
yearStart: 2015,
yearEnd: 2022,
dayOfWeekStart: 1
});
$('#toggle').on('click', function () {
$('#picker').datetimepicker('toggle');
})
</script>
I have some other inputs also, that I've validating via the controller,
when I change the value of datepicker, post form and validation fails, other fields set with old values, except datepicker.
Where I have messed something? I wanna set the old value to datepicker, when validation fails.
As I discovered later, the old value is set and immediately refreshed with default value '2021-01-17'

Seems like you're getting two inputs with name hdndefDate when old values from this input exists.
And in your JS you're getting the value from the input #hdndefDate, that holds the default value.
Change your #if to something like this:
#if (old('hdndefDate'))
<input type="hidden" name="hdndefDate" id="hdndefDate" value="{{ old('hdndefDate') }}">
#else
<input type="hidden" name="hdndefDate" id="hdndefDate" value="2021-01-17">
#endif
Or even better:
<input type="hidden" name="hdndefDate" id="hdndefDate" value="{{ old('hdndefDate') ?? 2021-01-17}}">

Related

How to display stored value of datetimepicker to blade in Laravel

Do you know guys how display the date value from database to datetimepicker field?
the example value from database is 2022-10-31
<div class="input-group date" id="allDay" data-target-input="nearest">
<input type="text" id="all-value" name="all_day"
class="form-control datetimepicker-input" data-target="#allDay"
value="" />
<div class="input-group-append" data-target="#allDay" data-toggle="datetimepicker">
<div class="input-group-text"><i class="fa fa-calendar"></i></div>
</div>
</div>
js
$('#allDay,#startLongDay,#endLongDay').datetimepicker({
format: 'L',
minDate: new Date()
});
If you're using the jQuery DateTime Picker, You can retrieve the value from the database and then pass it to the view through your controller. After that, you can set it as the value attribute.
Example:
<input type="text" id="all-value" name="all_day"
class="form-control datetimepicker-input" data-target="#allDay"
value="{{$date}}" />
Or else you can do it in JS Way:
Setting with viewDate option
<script>
var d = "{{$date}}"
$('#allDay,#startLongDay,#endLongDay').datetimepicker('viewDate', d);
</script>
Setting with date option
<script>
var d = "{{$date}}"
$('#allDay,#startLongDay,#endLongDay').datetimepicker('date', d);
</script>
Please note that in all of the above steps you need to format the date correctly.

How do i set focus on an invalid input field

I have an input; it's a string type of input. When I put an invalid input on it, I want it to focus on that invalid input field because the input is wrong, and I have to do a correct input on that invalid input field. How do I do it??
<form action="{{url('/store')}}" method="POST">
#csrf
<div class="form-group">
<label>NIK</label>
<input type="text" id="kredit_nik" name="kredit_nik" class="form-control" autocomplete="off"
value="{{old('kredit_nik')}}" placeholder="Contoh : 3152021502002002">
</div>
#if ($errors->first('kredit_nik'))
<div class="alert alert-danger">{{$errors->first('kredit_nik')}}</div>
#endif
<br>
<div class="form-group">
<label>Nama Lengkap</label>
<input type="text" id="kredit_name" name="kredit_name" class="form-control" autocomplete="off"
value="{{old('kredit_name')}}" placeholder="Contoh : Nathanael Budiman">
</div>
#error ('kredit_name')
<div class="alert alert-danger">{{ $message }}</div>
#enderror
<br>
</form>
You can use Laravel's provided #error blade directive to check if the validation error exists for an input/attribute and combine it with Bootstrap's error class as:
#error('input-name') is-invalid #enderror
Example:
<input type="text" required class="form-control #error('input-name') is-invalid #enderror" name="input-name" id="input-name" value="{{ old('input-name') }}">
Now, to scroll to the error field you can use jquery to scroll to the first error field:
Add this before the closing </body> tag:
<script src="https://cdn.jsdelivr.net/npm/jquery#3.6.0/dist/jquery.min.js"></script>
<script>
$(document).ready(function() {
var errors = $('.is-invalid')
if (errors.length) {
$(document).scrollTop(errors.offset().top)
}
});
</script>
Scrolling code is partially taken from: https://github.com/1000hz/bootstrap-validator/issues/52#issuecomment-71472662 (original credit)

Change PUT request to POST request to include image update

I wrote a post edit method which at first consisted only of text. I did the update using a PUT request.
Now I want to include images to my posts, so I added it, and it works for my POST request of creating a post but doesn't work for my update post, when I want to change image, since PUT request doesn't support file uploads.
So now I'm stuck trying to change my update method from PUT request that only updates text to a POST request that updates both the text and an image if supplied.
This is the code I wrote so far:
public function update(Request $request, Post $post)
{
//store updated image
if($request->hasFile('image') && $request->file('image')->isValid()){
if($post->hasMedia('posts')) {
$post->media()->delete();
}
$post->addMediaFromRequest('image')->toMediaCollection('post', 's3');
}
$post->update(request()->validate([
'body' => 'required'
]));
return redirect($post->path());
}
I think that the $post->update doesn't work for the POST request. I just want to update a text if an update was given.
Using Laravel 6.
EDIT: My form layout structure (simplified)
<form action="action="/posts/{post}" method="POST">
#method('PUT')
#csrf
<div class="form-group row">
<input id="body" type="text" class="form-control" name="body" value="{{ old('body', $post->body) }}">
<input id="image" type="file" class="form-control" name="image">
<button type="submit" class="btn btn-primary">Update Post</button>
</form>
My routes:
Route::get('/posts/{post}/edit', 'PostsController#edit')->name('posts.edit');
Route::put('/posts/{post}', 'PostsController#update');
I tried your code and it worked fine with me , only added #csrf in form tag.
<form action="/posts/{post}" method="POST" enctype="multipart/form-data">
#csrf
#method('PUT')
<div class="form-group row">
<input id="body" type="text" class="form-control" name="body" value="{{ old('body', $post->body) }}">
<input id="image" type="file" class="form-control" name="image">
<button type="submit" class="btn btn-primary">Update Post</button>
</form>

How to get checkbox value in a Laravel controller?

I have a checkbox in my form and I want to save its value into the database. When I check it, its value will be 1 and when I uncheck it then it's value will be 0. However, in the controller, I am getting NULL all the time. But why? Is it possible to solve without jQuery?
Blade/View
<form action="{{ route('admin.categories.store') }}" method="POST" enctype="multipart/form-data">
#csrf
<div class="form-group>
<label>
<input type="checkbox" name="category_is_menu"
value="{{ old('category_is_menu', isset($category) ? 'checked' : '') }}"/>
</label>
</div>
<input class="btn btn-success" type="submit" value="Submit">
</form>
Controller
public function store(Request $request)
{
$category = new Category();
$category->category_is_menu = $request->category_is_menu;
return $category;
}
Unfortunately, it's giving me NULL for category_is_menu.
Add a hidden input with the negative value just before the checkbox input (with the same value in the name attribute)
<div class="form-group">
<input type="hidden" name="category_is_menu" value="0"/>
<input type="checkbox" name="category_is_menu" value="1" {{ old('category_is_menu', isset($category) ? 'checked' : '') }}/>
</div>
The value in the checkbox input needs to be always 1.
A checkbox input in not sent in the request when it's unchecked, in that case the hidden input will be sent with the value 0.
When the Checkox is checked, it will overwrite the value to 1.
Either use the hidden input trick as mentioned in the other answers or just check if the input was passed at all. If it was passed at all it was checked, if its not there it was not checked:
$category->category_is_menu = $request->has('category_is_menu');
If it was checked you get true, 1, if it wasn't checked you get false, 0.

Thymeleaf = how to th:each adding value in tag input

so I want to make input income/outcome increase according to the income/outcome data that has been obtained from the controller
I have tried using th:each as follows to add income/outcome from each transaction
this is my form
<form class="form-horizontal" th:action="#{/report/create}" method="post">
<div th:each="transactions : ${transaction}">
<input type="hidden" name="income" th:value="${report.income + transactions.income}">
<input type="hidden" name="outcome" th:value="${report.outcome + transaction.outcome}">
</div>
<div class="form-group">
<label class="col-sm-2 control-label"></label>
<div class="col-sm-10">
<button type="submit" class="btn btn-primary">Save</button>
</div>
</div>
</form>
with that I only got the first income/outcome from the loop
Not sure how you implemented the backend, but your spelling for transactions isn't correct. Other than that, it should work as I've done something similar myself in the past. Typically you would have
#GetMapping("/my-page")
public String showAll(Model model) {
//....
model.addAttribute("report", report);
// however you define (a list) of transactions
model.addAttribute("transactions", transactions);
return "my-page";
}
then in your html
<div th:each="transaction : ${transactions}">
<input type="hidden" name="income" th:value="${report.income + transaction.income}">
<input type="hidden" name="outcome" th:value="${report.outcome + transaction.outcome}">

Resources