Dynamic dropdown in laravel 5.8 - laravel

here's what i want to happened
- First dropdown (Parent)
- Second dropdown (Child)
- The options on the second dropdown will depend on the selected value of the first dropdown.
I am using laravel 5.8.

In Your view
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select class="form-control{{ $errors->has('state') ? ' is-invalid' : '' }}" onchange="dropdown(this.value);" name="state" id="state">
<option>--select state--</option>
<option value="Kerala">Kerala</option>
<option value="Karnataka">Karnataka</option>
<option value="Tamil Nadu">Tamil Nadu</option>
</select>
<select class="form-control{{ $errors->has('district') ? ' is-invalid' : '' }}" name="district" id="district">
<option>Please choose state from above dropdown</option>
</select>
<script >
function dropdown(msg){
var state=msg;
$.ajax({
url: 'getdistrict/'+state,
type: 'get',
dataType: 'json',
success: function(response){
$("#district").empty();
var len = 0;
if(response['data'] != null){
len = response['data'].length;
}
if(len > 0){
// Read data and create <option >
for(var i=0; i<len; i++){
var id = response['data'][i].id;
var name = response['data'][i].name;
var option = "<option value='"+name+"'>"+name+"</option>";
$("#district").append(option);
}
}
}
});
}
In your controller
public function district($id)
{
$userData['data'] = DB::table('alldistricts')
->where('state', $id)
->orderBy('name', 'asc')
->get();
echo json_encode($userData);
exit;
}
In your web.php
Route::get('/getdistrict/{id}','RegistrationController#district')->name('getdistrict');

To achieve this you must know front end script like Vue js or at least native javascript. I'll show how to achieve this using vue js and axios package and native js and ajax.
Vue js and axios:
Documentation:
1)https://vuejs.org (for vue js)
2)https://www.npmjs.com/package/axios (for axios package)
include this line in you header.
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>
Note: I used Vue js cdn for development mode. Make sure to change to production mode on live. Check the documentation for further.
Then add this in the form:
<form method='post' action="http://example.com/location" id="developers">
<select name="developer_type" v-on:change="getLanguages" v-model="developerType">
<option disabled> Select Developer Type </option>
<option value="front"> Front-End Developer </option>
<option value="back"> Back-End Developer </option>
<option value="full"> Full Stack Developer </option>
</select>
<select name="Coding_language">
<option disabled v-if="developerType!=null"> Select Developer Type First </option>
<option disabled v-else="developerType!=null"> Select Coding Language </option>
<option v-for="lang in codingLaguanges" value="lang"> #{{lang}} </option>
</select>
</form>
Note: use #{{}} if only you use Laravel blade as your template engine Otherwise use only {{}}
Then add this on footer script
let developerForm = new Vue({
el:'#developers',
data:{
developerType:null,
codingLanguages:null
},
methods:{
getLanguages: function () {
axios
.post('/developers/getLanguages',{
type: developerForm.developerType
})
.then(response => (
developerForm.codingLanguages = response.data.languages
));
}
}
});
Note:I have used v-on:change and v-model in select instead of using watcher ands-model because this concept will be easier if you are new to vue js, Otherwise use Watcher itself. Check Vue js Documentation. However Both will work in this case.
In .post give you correct url to get result.
then define your route
Route::post('/developers/getLanguages', ['as'=>'dev.getLang','uses'=>'web\DevController#getLanguages']);
Note this is laravel part. you ca see Documentation in https://laravel.com
then in your DevController add this method
public function getLanguages(Request $request){
//do something to fetch result from db. Let us consider user has selected backend as developer type and there is array named Languages and it contains elements named php, python and java. i.e. $languages = ['php','python','java'].
return response()->Json(['languages'=>$languages],200);
}
Note: This will be your method for Controller to know detailed about controller check laravel documentation mentioned in previous note. Here you can retrieve the variable value from db also. but I used only sample values. In return I used array in json because you can n number of variables in that array(For example you can use statusCode to identify your error in future and much more.). Then make sure the name of the key in json array and name of the object in axios while retrieving is same. And I used status code as 200 because the browser take response of the request is successful. if you use 400 browser take response of the request is error.
This is the easiest method you can achieve.
You can also use jquery ajax and jquery or native javascript and javascript ajax to achieve this. But it has some complexity and limitation.
If you need code for native js or jQuery comment it and I will post it

Related

Laravel 8 multi value select filtering

I'm trying to build Laravel project that will have a multi-select dropdown with list of categories. Selecting category should reload the page and apply filter.
"scopeFilter" in my model is actually doing filtering, but here i just need to find a way to properly form URL. The problem is that this code i have:
<form id="cats-form" action="#" method="GET">
<select multiple class="chosen-select" name="test[]">
#foreach($categories->get() as $cat) //this loop goes through existing categories in the system
#php
//if category is part of URL, pre-select it in the select:
$arr = request()->all();
$selected = '';
if(array_key_exists('test', $arr)) {
$testArr = $arr['test'];
$selected = in_array($cat->id, explode(',', $testArr)) ? 'selected' : '';
}
#endphp
<option {{ $selected }} value="{{ $cat->id }}">{{ $cat->name }}</option>
#endforeach
</select>
</form>
<script>
$(".chosen-select").chosen({ })
$('.chosen-select').on('change', function(evt, params) {
$('#cats-form').submit();
});
</script>
Is actually giving me this URL:
http://localhost:11089/?test%5B%5D=19&test%5B%5D=5
While i actually need this:
http://localhost:11089/?test=19,5
I guess it's a trivial problem to solve for someone with better knowledge of Laravel, can you tell me pls what i'm doing wrong here?
This is rather how the language or framework or library reads an URL query string. Assuming that your prefered way of URL string is a valid format (as I usually see the format ?arr[]=val1&arr[]=val2 and never see the second format that you preferred), both query string formats should be acceptable to PHP.
As Yarin stated that the best way PHP reads an array is the first method, you don't have to worry too much because the decoded URL query string is exactly in the first format.

Laravel VUE JS dynamic drop down menu

Why doesn't this work?
Here is my select tag:
<select class="form-control" v-model="provider">
<option value="0">Select Provider</option>
<option v-for="provider in providers" :value="provider.provider_id">{{provider.name}}</option>
</select>
Code which loads the data:
loadProviders(){
axios.get('api/provider').then(({data}) => (this.providers = data.data));
data is then stored in:
data(){
return{
providers : {}
}
}
I've checked the developer networks tab of Chrome and it does return the data from the database.
However the value(provider.name) doesnt show up in the dropdown options menu.
This issue has already been solved: the model for Provider had an error all along.
The issue is, that you are destructuring the API response, but don't take into account that when assigning to data.
axios.get('api/provider').then((data) => (this.providers = data.data));
and
axios.get('api/provider').then(({data}) => (this.providers = data));
both work.
Update your select box
<select v-model="provider">
<option v-for="(value,key) in provider"
:value="value.provider_id">
{{value.name}}
</option>
</select>
Make sure you received proper data from your API.
assign data to provider variable. it will appeare in select box

Display Object list from server in a Select option in Vue

I receive a list of Grades that are in the right format ( $key => $value) in a $grades variable
How can I fill a select option input with Vue using this variable.
I guess I must bind the vue variable with : but I'm just beginning with vue and I can find so very little basic examples,
<select v-model="grades" class="form-control">
<option v-for="gradeValue in gradeValues" :gradeValues="{{ $grades /* Laravel Variable */ }}">#{{ gradeValue }}</option>
</select>
EDIT: I could make an ajax call from Vue, this should not be so complicated, but as the page load, my Laravel controller passes variables to my View, so, this is for me a cleaner aproach, in this case there is no need for ajax.
I think this has been over complicated for you, your code in this question looks close. Is your Vue component in the same file as your blade? Then it's just:
html
<select v-model="selectedGrade" class="form-control">
<option v-for="(grade, val) in grades" :value="val">#{{ grade }}</option>
</select>
js:
new Vue({
...
data:function(){
return {
grades:{{ $grades }},
selectedGrade:2 //some default value
}
}
...
});
If your component is in a separate file you still don't need a separate component for each select dropdown, you just need to pass all the required info into one component. Without a better understanding of your app, I'd guess it could be something like this:
<person-data :grades="{{ $grades }}" :categories="{{ $categories }}" :ages="{{ $ages }}"></person-data>
then the vue component:
var PersonData = Vue.extend({
props:['grades','categories','ages']
});
You have two choices:
You can create the option elements using blade's foreach method:
#foreach ($grades as $grade)
<option ...>{{ $grade }}</option>
#endforeach
Or you can create a dedicated component for your grades with your template and pass in the $grades variable. For example:
<grades :grades="{{ $grades }}"></grades>

How to add if statements to Ajax

I do mostly PHP programming, but am stuck on an Ajax problem since I do not know Javascript or Ajax very well at all. I have a combo select menu right now and I would like to hide the third select menu (direction) if the first choice is = 'train'. I read that some browsers do not support the hide function, so the next best option is to keep the third select menu disabled when the second option is chosen assuming the first is train. If it is bus, then the third select menu should still show. Here is my javascript right now and as I'm sure you can imagine it doesn't work.
$(document).ready(function(){
if ($("select#agency").attr('value') == 'cta-train') {
$("select#direction").attr("disabled","disabled");
}
$("select#route").attr("disabled","disabled");
$("select#agency").change(function(){
$("select#route").attr("disabled","disabled");
$("select#route").html("<option>wait...</option>");
var id = $("select#agency option:selected").attr('value');
$.post("select_route.php", {id:id}, function(data){
$("select#route").removeAttr("disabled");
$("select#route").html(data);
});
});
});
$(document).ready(function(){
if ($("select#agency").attr('value') == 'cta-train') {
$("select#direction").attr("disabled","disabled");
}
else {
$("select#direction").attr("disabled","disabled");
$("select#route").change(function(){
$("select#direction").attr("disabled","disabled");
$("select#direction").html("<option>wait...</option>");
var id = $("select#route option:selected").attr('value');
$.post("select_direction.php", {id:id}, function(data){
$("select#direction").removeAttr("disabled");
$("select#direction").html(data);
});
});
}
});
Any help would be greatly appreciated!
Seems like you dont want ajax, you want to use javascript to hide a select if another select has a certain element in it. Then use your ajax to file the select as needed. Here is an example of that http://jsfiddle.net/2FQwQ/
<select id='direction'>
<option value='train'>train</option>
<option value='car'>car</option>
<option value='pogo stick'>pogo stick</option>
<select>
<select id='agency'>
<option value='1'>1</option>
<option value='2'>2</option>
<option value='3'>3</option>
<select>
<select id='route'>
<option value='1'>1</option>
<option value='2'>2</option>
<option value='3'>3</option>
<select>
Script
//SEts your html up to hide the secelt if train
function amITrain() {
if ($('#direction').val() === "train"){
$('#route').hide();
$('#route').attr('disabled');
}else{
$('#route').show();
$('#route').removeAttr('disabled');
}
}
$('#direction').change(amITrain);
//When you get the ajax back, you would fill the select like this, then call the function
$('#direction').html("<option value='train'>train</option><option value='car'>car</option> <option value='pogo stick'>pogo stick</option>");
amITrain();

Submit form on select change via AJAX

Let's say I have this form :
<form action="Change-status.php" method="post">
<select class="changeStatus" name="changeStatus">
<option value="0">Starting</option>
<option value="1">Ongoing</option>
<option value="2">Over</option>
</select>
<input class="projectId" type="hidden" name="projectId" value="<?php echo $data['id'];?>"/>
</form>
I am currently using this script to submit the form, but it implies refreshing :
$('select').change(function ()
{
$(this).closest('form').submit();
});
What I want to do is to send the form on select change without refreshing the page. I know I have to use AJAX to do so but I couldn't exactly figure out how to implement it.
Could you orient me on how to do this?
Thanks for your help.
EDIT :
After taking comments into consideration, I ended up with the following code :
Html :
<form action="" method="post">
<select class="changeStatus" name="changeStatus">
<option value="0">Starting</option>
<option value="1">Ongoing</option>
<option value="2">Over</option>
</select>
<input class="projectId" type="hidden" name="projectId" value="<?php echo $data['id'];?>"/>
</form>
JS :
$(document).ready(function() {
$('select.changeStatus').change(function(){
$.ajax({
type: 'POST',
url: 'Change-status.php',
data: {selectFieldValue: $('select.changeStatus').val(), projectId: $('input[name$="projectId"]').val()},
dataType: 'html'
});
});
});
PHP :
<?php
include('../Include/Connect.php');
$changeStatus=$_POST['selectFieldValue'];
$id=$_POST['projectId'];
$sql='UPDATE project SET progress="'.$changeStatus.'" WHERE id="'.$id.'"';
mysql_query($sql) or die("Erreur: ".mysql_error());
?>
Getting cross browser onchange events and AJAX requests working isn't trivial. I'm recommend you use a javascript framework of some kind, which abstracts away all of the cross browser issues so you don't have to worry about them.
Try a js framework
Jquery is just one such framework which has methods such as .change() which attaches a handler to the change event for elements like <select> and .get() which performs a GET request.
Here's a little bit of code to get you started:-
// The $ is the shorthand for a jquery function, you can then use jquery
// selectors which are essentially the same as css selectors, so here
// we select your select field and then bind a function to
// it's change event handler
$('select.changeStatus').change(function(){
// You can access the value of your select field using the .val() method
alert('Select field value has changed to' + $('select.changeStatus').val());
// You can perform an ajax request using the .ajax() method
$.ajax({
type: 'GET',
url: 'changeStatus.php', // This is the url that will be requested
// This is an object of values that will be passed as GET variables and
// available inside changeStatus.php as $_GET['selectFieldValue'] etc...
data: {selectFieldValue: $('select.changeStatus').val()},
// This is what to do once a successful request has been completed - if
// you want to do nothing then simply don't include it. But I suggest you
// add something so that your use knows the db has been updated
success: function(html){ Do something with the response },
dataType: 'html'
});
});
Some references that will be better than my explanations
Please note for this code to work you will need to include the jquery library on you page with a <script> tag.
See here for a quick start guide on using jquery
And here for a beginners tutorial on how to use jquery's ajax() method

Resources