I'm using Select2 in my webapplication. I load my Select2 boxes with Ajax. When validation fails, all the inputs are filled as before except the Select2 box. How can I restore the old value after the form validation fails? My bet was using Request::old('x')
, but this inserts the value (in my case an user ID) instead of the selected text. So for example the text John
would become 27
in the selectbox. How can I get the text back?
<select id="customer" name="customer" class="searchselect searchselectstyle">
</select>
The js:
token = '{{csrf_token()}}';
$(".searchselect").select2({
ajax: {
dataType: "json",
type: "POST",
data: function (params) {
return {
term: params.term,
'_token': token,
'data' : function(){
var result = [];
var i = 1;
$('.searchselect').each(function(){
result[i] = $(this).val();
i++;
});
return result;
}
};
},
url: function() {
var type = $(this).attr('id');
return '/get' + type;
},
cache: false,
processResults: function (data) {
return {
results: data
};
}
}
});
Edit
The only (dirty) solution I found so far is the following:
<select id="customer" name="customer" class="searchselect searchselectstyle">
@if(Request::old('customer') != NULL)
<option value="{{Request::old('customer')}}">{{$customers->where('id', intval(Request::old('customer')))->first()->name}}</option>
@endif
</select>
$customers
is a list of all customers, so this means that for each Select2 box I need to query a big list of items in order to make it work. This will be pretty inefficient if we're talking about thousands of rows per Select2 box.
I guess there must be a better solution. Who can help me?
Normally to programmatically set the value of a select2, you would expect to use the .val()
method followed by a .trigger('change')
call as per their documentation (and other queries like this on SO). However, select2 themselves have something in their documentation about preselecting options for remotely sourced data.
Essentially their suggestion boils down to (after initalizing your AJAX-driven <select>
):
<select>
from a promise function (.then()
) after the AJAX call is finished
change
eventselect2:select
event (and pass along the whole data
object)Assuming you're already flashing the old data to the session, Laravel provides handy access to the previously requested input in a variety of ways, notably these three:
Request
class e.g. Request::old('customer')
as in the OPold()
helper e.g. old('customer')
, which returns null
if no old input for the given field exists, and can have a default as a second parameterold()
method on the Request
instance from the controller e.g. $request->old('customer')
The global helper method is more commonly suggested for use inside Blade templates as in some of the other answers here, and is useful when you don't need to manipulate the value and can just plug it straight back in, which you would with things like text inputs.
The last method probably provides you with the answer you're looking for - instead of querying the entire collection from inside of the view, you're able to either manipulate the collection from the controller (similar to the OP, but should be nicer since it's not parsing it in the view) or make another query from the controller based on the old ID and fetch the data you want without having to trawl the collection (less overhead):
$old_customer = Customer::find($request->old('customer'));
Either way, you'd have the specific data available at your fingertips (as a view variable) before the blade template processes anything.
However you choose to inject the data, it would still follow the pattern suggested by select2:
The only difference being you don't need to fetch the data from another API endpoint (unless you want/need to for other programmatic reasons).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With