Retrieving values for Selectize.js - javascript

I am using Selectize.js to create a tagging like experience, for adding users to jobs, using the current users of the system.
In my view
Following the documentation, I have a select box with the multiple attribute which I populate with the users on the system. I have also declared that this input is an array by adding square braces.
<select name="job_administrator[]" multiple id="selectize" class="form-control{{ $errors->has('job_administrator') ? ' is-invalid' : '' }}">
<option value="">Select a user </option>
#foreach($users as $user)
<option value="{{ $user->id }}">{{ $user->full_name }} - {{ $user->access_level }}</option>
#endforeach
</select>
Then, I initialize the plugin
$('#selectize').selectize({
placeholder: 'Select user',
plugins: ['remove_button'],
delimiter: ',',
persist: false,
})
In my Controller
/**
* Handle adding job administrators to jobs
*
* #param Array $data
* #return void
*/
public function addAdministrators(Array $data, int $id)
{
$vacancy = JobPost::where('id', $id)->first();
if(!empty($data['job_administrator'])){
$jobAdmins = $data['job_administrator'];
// Grab the IDs for the tags in the array
$admins = Admin::whereIn('id', $jobAdmins)->get()->pluck('id');
$vacancy->administrators()->sync($admins);
} else {
// If there were no tags, remove them from this model instance
$vacancy->administrators()->sync(array());
}
}
My question is: on the editing screen is it possible to prefill the selected items when using Selectize?

Yes you can, just add the selected attribute to the option. You can do something like this.
<option value="{{ $user->id }}" {{$selected->contains($user->id) ? 'selected' : ''}}>{{ $user->full_name }} - {{ $user->access_level }}</option>
The $selected is then a collection of ids.

Related

`wire:model` not letting selected value to be selected

A select element with a pre-selected value does not render correctly, if I do not add wire:model to the element, it works well and shows the selected value in the select element.
But I need to add wire:model to save user-updated data
<div class="m-widget4">
#foreach ($this->result as $data)
<div>{{$data->id}}</div>
<select wire:model="list_session_picker.{{ $data->id }}" wire:key="{{ $data->id }}">
<option value="" disabled hidden>Select Session</option>
#foreach ($sessionData as $session)
<option value="{{ $session->id }}">{{ $data->user_session_id == $session->id ? 'selected' : '' }} {{ $session->session }}</option>
#endforeach
</select>
#endforeach
</div>
Componenet.php
public $result = [], $list_session_picker = [];
public $search_picker;
public function render()
{
$data['sessionData'] = Session::all('id', 'session');
$data['sectionData'] = Section::all('id', 'section');
return view('livewire.promote', $data);
}
public function search()
{
$search = ScCompany::query();
if (!empty($this->search_picker)) {
$search->where('session_id', $this->search_picker);
return
$this->result = $search
->whereNull('date_of_enter')
->with(['session:id,session', 'section:id,name'])
->get();
}
}
It works if I remove wire:model, so how could I show the selected value while using wire:model or is there any other way ?
Note** here i set wire:model="list_session_picker.{{ $data->id }}" so the list comes from for each loop can't update each other (on changing the option of one select will not uodate another select element in the list) .
I found this and this solutions, but how to apply them in my case, not much clear to me
You should set the selected element in the livewire component and not in the view. The view will reflect the state of the component thanks to the wire model.
At present you have conflicting views of which element should be selected and they will always be at odds with each other.
Just wire model. If you have an existing item selected, then set it state at the component.

How to get data only if the data is not filled in front-end using livewire and alpinejs?

For using less resources I want to fetch data from the server (using livewire) only for the first time and the other times to use the already fetched data in alpinejs.
So if there is a change in my <select>, the fillStates will be triggered:
<select wire:model="selectedCountry" name="selectedCountry" id="selectedCountry" wire:change="fillStates">
<option value="">Select Country</option>
#foreach($this->countries as $country)
<option value="{{ $country->id }}">{{ $country->name }}</option>
#endforeach
</select>
The fillStates method will return the data:
public function fillStates()
{
$states = State::where('country_id', $this->selectedCountry)->get();
if(count($states)) {
$this->states[$this->selectedCountry] = $states;
return $this->states[$this->selectedCountry];
}
return [];
}
And my question is here. How can I prevent it requesting more than one time when the $this->states[$country] has already value and can be accessed with alpinejs?
For example I select United States in my <select>. For the first time it needs to fetch the data which is its states. I change it to Canada. This time it needs to fetch the data which is its states. But if I select the United States again, it shouldn't request as it has already fetched and is available in alpinejs. How can I achieve it?
I think you have to manually validate using alpinejs.
<div x-data="{
selectedCountry: null,
countries: {},
}"
x-init="$watch('selectedCountry', () => {
if(! (selectedCountry in countries)) {
#this.call('fillStates');
countries[selectedCountry] = #this.get('states');
}
})"
>
<select x-model="selectedCountry" name="selectedCountry" id="selectedCountry" >
<option value="">Select Country</option>
#foreach($this->countries as $country)
<option value="{{ $country->id }}">{{ $country->name }}</option>
#endforeach
</select>
</div>

How to check checkbox array values exist from database PHP Laravel?

I want to check either the countries exist in countries and the checkbox will be displayed. The values is directly from the database. I can't set the value at the input since it is array/multiple values. So, I want to check every array so that it will be a checkbox.
Controller :
public function edit($id)
{
$region = Region::find($id);
$countries = Country::all();
$country_region = DB::table('regions')
->select('countries.id', 'countries.name')
->join('country_region', 'regions.id', '=', 'country_region.region_id')
->join('countries', 'country_region.country_id', '=', 'countries.id')
->where('regions.id', '=', $id)
->get();
$items = array(
'region' => $region,
'countries' => $countries,
'country_region' => $country_region,
);
return view('admin.region.edit')->with($items);
}
blade
<div class="form-group">
<label>Choose Country</label>
<select id="test" type="checkbox" name="country_id[]">
#foreach ($countries as $item)
<option value="{{$item->id}}" selected #if (in_array($item->id, array_keys($country_region))) checked="checked"
#endif>{{$item->name}}
</option>
#endforeach
</select>
</div>
As you can see, I put php statement inside the blade to check either $country_region is exist in the countries or not. I got errors that related to the array such below :
array_keys() expects parameter 1 to be array, object given
Database :
Country Region Table :
Region Table :
Country Table :
Use pluck instead of select in the query.
$country_region = DB::table('regions')
->join('country_region', 'regions.id', '=', 'country_region.region_id')
->join('countries', 'country_region.country_id', '=', 'countries.id')
->where('regions.id', '=', $id)
->get()
->pluck('countries.name', 'countries.id');
I don't think you need array function there like in_array since you are already looping each country, simple if should work, also please show the content of tables you are trying to compare.
<div class="form-group">
<label>Choose Country</label>
<select id="test" type="checkbox" name="country_id[]">
#foreach ($countries as $item)
<option value="{{$item->id}}" selected #if ($item->id == $country_region.country.id) checked="checked"
#endif>{{$item->name}}
</option>
#endforeach
</select>
</div>
$country_region is not an array in your controller. It's an Eloquent collection. To change it to array you simply use toArray() on it.
In your controller, replace this:
$items = array(
'region' => $region,
'countries' => $countries,
'country_region' => $country_region,
);
with this:
$items = array(
'region' => $region,
'countries' => $countries,
'country_region' => $country_region->toArray(),
);
Use pluck to get all country's id in an array
$country_region = DB::table('regions')
->join('country_region', 'regions.id', '=', 'country_region.region_id')
->join('countries', 'country_region.country_id', '=', 'countries.id')
->where('regions.id', '=', $id)
->pluck('country_region.id')
->toArray();
Then don't use array_keys() anymore. Modify your HTML like this
<option value="{{$item->id}}" selected #if (in_array($item->id, $country_region)) checked="checked"
#endif>{{$item->name}}
</option>
make sure that $country_region is an array

I'm looking for help to display a part on my database according to my previous choices in the select buttons [duplicate]

This question already has an answer here:
I'm looking for help to display a part of my database according to my previous choices in a select button
(1 answer)
Closed 3 years ago.
i study the web developpement and i'm actually stuck with a problem.
I have two select buttons in which my database is displayed, the concern being that I would like the second select button to display only the results based on the first one. A bit like if the first button select would have inside "Numbers" and "Letters" and the second in consequences would have inside "1" "2" "3" if in the first select button we choose "Numbers" and "a" "b" "c" if we choose "Letters". I currently only have the full display of my entire database in the second and it does not do the sorting.
I tried a lot of thing but not realy working this is why i come here to have some help or tips.
I'm currently working with symfony 3.4 and on ubuntu.
Here is the code for my first select button:
<select id="sel1" class="formDevis" >
<option> Cliquez pour choisir </option>
{% for categorie in categories %}
<option>{{ categorie.nomCategories }}
</option>
{% endfor %}
</select>
Then this is the code for the second select button:
<select id="prod1" class="formDevis">
<option> Cliquez pour choisir </option>
<option>Non spécifié</option>
{% for produit in produits %}
<option>{{ produit.nomProduits }}
</option>
{% endfor %}
</select>
And finaly here is the code i use in my controller:
/**
* Lists all devis entities.
*
* #Route("/", name="admin_devis_index")
* #Method("GET")
*/
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$devis = $em->getRepository('DevisBundle:Devis')->findAll();
$produits = $em->getRepository('DevisBundle:Produits')->findAll();
$categories = $em->getRepository('DevisBundle:Categories')->findAll();
return $this->render('categories/devis.html.twig', array(
'produits' => $produits,
'devis' => $devis,
'categories' => $categories
));
}
I tried to have on the second button select the display of my database according to the first button select but I managed to have the complete display.
One way to handle this is to use AJAX in your twig view like this :
//event on change of the first select
$('#firstSelect').change(function(){
// Url to the controller where you do some action and return the second
//list depend of select on the first select
var url = "{{path('route_to_a_controller_that_handle_your_request')}}";
// With this Jquery selector you get the select value on the first select
var data ={"id" : $('#select option:selected').val()};
$.ajax({
url : url,
dataType: 'json',
data : data,
success: function(response) {
// Empty the second select
// For each element in response, do something like :
// $('#SecondSelect').append('<option value="1">One</option>');
}
});
And the controller to return the response (that's what you get in the 'success' of the AJAX). This is the controller your route refer in the ajax method.
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse;
public function myMethodAction(Request $request)
{
if($request->isXmlHttpRequest())
{
$id_list1 = $request->get('id');
$em = $this->getDoctrine()->getManager();
$data = $em->getRepository('MyBundle:List2')->findByType($id_list1);
return new JsonResponse($data);
}
return new Response("Error");
}
I hope it will help, I realise this very quickly.

open route .show when onchange a dropdown

In my view tests.index is it possible to open my route tests.show by clicking in a select dropdown where datas comes from database ?
My controller :
public function index(Request $request)
{
$tests = DB::table('test')->distinct()->get();
return view('tests.index')->with('tests', $tests);
}
public function show($id)
{
$test = Test::findOrFail($id);
return view('tests.show', compact('test'));
}
My view index :
<select id="apports" type="dropdown-toggle" class="form-control" name="apports" onchange="{{ route("tests.show", $test->id) }}">
<option value="choisir" selected disabled>Choisir</option>
#foreach($tests as $test)
<option class="apports" value="{{$test->id}}">{{$test->apports}}</option>
#endforeach
When I put my route here : onchange I get the error "Undefined variable: test"
when I add a button below the select like that :
<a class="btn btn-small btn-success" href="{{ route("tests.show", $test->id) }}">Show</a>
I get always the last id of the table...
I would prefer not have a button, just when I change value in the select, return tests.show... Is someone could help me please ?
The $test variable is not set in the index view, only the $tests collection is available because you load the view with that:
return view('tests.index')->with('tests', $tests);
You need to use some JavaScript to achieve what you are looking for.
In the index template:
<select id="apports" type="dropdown-toggle" class="form-control" name="apports" onchange="goToTestPage(this.value)">
Then in your JavaScript file:
function goToTestPage(id) {
window.location.href = "link to your show route/"+id;
}
If the test id is changed dynamically by the user, you can't set it on PHP because PHP is executed before the user actually does the selection, so you have to rely on JavaScript
All you need is a javascript snippet to read the select option change and redirect you.
<select id="apports" type="dropdown-toggle" class="form-control" name="apports">
<option value="choisir" selected disabled>Choisir</option>
#foreach($tests as $test)
<option class="apports" value="{{ route("tests.show", $test->id) }}">{{ $test->apports }}</option>
#endforeach
</select>
<script>
$('select').on('change', function (e) {
var link = $("option:selected", this).val();
if (link) {
location.href = link;
}
});
</script>

Categories