stanhook's avatar

Using Ajax to Populate Select Options - SOLVED

I am new at this and I could be missing something very basic or have it totally wrong. I have been through some basic tutorials and some things here and Googled around that has gotten me this far.

I have two select boxes in my view (qryStructures_start). The first 'select' I populate via a query in my controller. I have another function in that controller that gets data for my second 'select' to be populated based on whatever is selected in the first box via Ajax.

I know the query works because I am converting an existing form that I built to use Ajax instead.

Route

Route::get( 'ResearchReports/ResearchDatabase/field/qryStructures_start', [\App\Http\Controllers\FieldStructures::class, 'structuresStart'] );

Route for Ajax

Route::get( 'ResearchReports/ResearchDatabase/field/qryStructures_start?site={site}', [\App\Http\Controllers\FieldStructures::class, 'suAjax'] );

Controller

public function suAjax(Request $request)
{
my query...
$ajaxDataSql = "SELECT Blah FROM Blah...."

$ajaxDataSql = DB::getPdo()->prepare($ajaxDataSql);
$ajaxDataSql->setFetchMode(\PDO::FETCH_OBJ);
$ajaxDataSql->execute([]);
$ajaxData = collect($ajaxDataSql->fetchAll());
return response()->json($ajaxData);

In my view, the first box - populates from a different function in the same controller

@if( $selectSite )
<select id="site" name="site[]" size="5" multiple>
	@foreach( $selectSite as $site)
		<option value="{{ $site->Site }}">{{ $site->SiteName }} ({{ $site->Site }})</option>
	@endforeach()
</select>
 @endif

Next box - the Ajax

$('#site').change(function(){
	var site = $(this).val();
if(site){
	$.ajax({
 		type:"GET",
		url:"{{url('/ResearchReports/ResearchDatabase/field/qryStructures_start')}}?site=" + site,
		dataType: "json",
		success:function(sut)
		{
			if(sut.error)
		{	
			console.log(sut);
		}
			console.log(sut);
		if(sut)
		{
			$("#suTyp").empty();
			$("#suTyp").append('<option>Select Study Unit Type</option>');
			$.each(sut,function(key,value){
			$("#suTyp").append('<option value="'+key+'">'+value+'</option>');
			});
		}
	}
});
}
});

The box I want Ajax to populate

<select id="suTyp" name="SUTyp[]" size="7" multiple ></select>

So what works, var site does return the site number when I click on the site, I can see it in the console. After I click and get the site though, nothing happens. Nothing in the console, nothing on the page, nothing.

Thanks for the help!

0 likes
7 replies
jlrdw's avatar

Why use collect instead of just returning the DB results to the view?

Also check the response in your network tab.

1 like
stanhook's avatar

Hi,

Why use collect instead of just returning the DB results to the view?

Because of the way I need to loop and access the data in my view. This is what I found to work for my needs. I am happy to learn a better/different way if that is a better practice.

My Network Tab has

Request URL: http://ccacajax.localhost/ResearchReports/ResearchDatabase/field/qryStructures_start?site=5MT10647
Request Method: GET
Status Code: 200 OK

So it seems to be working (no errors in the console either). I thought it would pass that URL using the Route to my function and then load the next box. But it isn't getting any further. It doesn't pass the data to the suAjax function. I am assuming I just haven't learned enough to get past this point and I haven't been able to figure it out yet.

amitsolanki24_'s avatar

@stanhook try to add console in each loop for debugging.

Try below code


let suType =`<option>Select Study Unit Type</option>`;

$.each(sut,function(key,value){
 console.log(key, value);
  suType += `<option value="${key}">${value}</option>`;
});

$('#suType').html(suType);

stanhook's avatar

@amitsolanki24_

I can try that but I don't think anything is being passed,. I tried testing by doing this:

success: function(sut)
 {
  data = sut.data;
 console.log(data);
}

Since that didn't do anything, I changed my route for that view to use the function in my controller that returns the JSON and I get this when visiting the URL (/ResearchReports/ResearchDatabase/field/qryStructures_start?site=5mt1825):

[{"Site":"5MT1825","ESR_SUcat":"Kivas","ESR_SUcatdesc":"kivas.","SUDescCode":10},{"Site":"5MT1825","ESR_SUcat":"Rooms","ESR_SUcatdesc":"rooms.","SUDescCode":20},{"Site":"5MT1825","ESR_SUcat":"Middens","ESR_SUcatdesc":"refuse deposits.","SUDescCode":30},{"Site":"5MT1825","ESR_SUcat":"Extramural Surfaces","ESR_SUcatdesc":"outdoor surfaces.","SUDescCode":31},{"Site":"5MT1825","ESR_SUcat":"Noncultural Deposits","ESR_SUcatdesc":"noncultural deposits.","SUDescCode":35},{"Site":"5MT1825","ESR_SUcat":"Void","ESR_SUcatdesc":"void","SUDescCode":97}]

So I know data gets returned in my function.

Is there another way to test to see that data getting into:

success: function(sut)
 {
		$("#suTyp").empty();
		$("#suTyp").append('<option>Select Study Unit Type(s)</option>');
		$.each(sut,function(key,value){
				$("#suTyp").append('<option value="'+key+'">'+value+'</option>');
		});
 }

Or maybe something else is wrong?

stanhook's avatar

So changing my route to:

Route::get( 'ResearchReports/ResearchDatabase/field/qryStructures_start/{site}

and now the URL:

/ResearchReports/ResearchDatabase/field/qryStructures_start/5mt1825

I see the json in my view. But when I try to add the trailing '/' to the URL like this in my Ajax:

url:"{{url('/ResearchReports/ResearchDatabase/field/qryStructures_start/')}}" + site,

or

url:"{{url('/ResearchReports/ResearchDatabase/field/qryStructures_start')}}" + '/' + site,

I get this in my Network tab:

/ResearchReports/ResearchDatabase/field/qryStructures_start5MT10719

No slash. I have no idea if I am able to do this then everything will work. But it might.

stanhook's avatar

I wanted to post that I am now getting data back in my console log. This is what I did to get it to work:

I created another view just for the Ajax. It doesn't really exist. I just added it to my route:

Route::get( 'ResearchReports/ResearchDatabase/field/qryStructures_start_ajax', [\App\Http\Controllers\FieldStructures::class, 'suAjax'] );

I now have this in my Ajax:

$.ajax({
 type:"get",
	url:"{{url('/ResearchReports/ResearchDatabase/field/qryStructures_start_ajax')}}",
	data: 'site=' + site,
	dataType: "json",
	success: function(sut)
		{
			console.log(sut);
			$("#suTyp").empty();
			$("#suTyp").append('<option>Select Study Unit Type(s)</option>');
			$.each(sut,function(key,value){
			$("#suTyp").append('<option value="'+key+'">'+value+'</option>');
			});
		}
	});

In the console.log I get:

0: {Site: '5MT1825', ESR_SUcat: 'Kivas', ESR_SUcatdesc: 'kivas.', SUDescCode: 10}
1: {Site: '5MT1825', ESR_SUcat: 'Rooms', ESR_SUcatdesc: 'rooms.', SUDescCode: 20}
2: {Site: '5MT1825', ESR_SUcat: 'Middens', ESR_SUcatdesc: 'refuse deposits.', SUDescCode: 30}
3: {Site: '5MT1825', ESR_SUcat: 'Extramural Surfaces', ESR_SUcatdesc: 'outdoor surfaces.', SUDescCode: 31}
4: {Site: '5MT1825', ESR_SUcat: 'Noncultural Deposits', ESR_SUcatdesc: 'noncultural deposits.', SUDescCode: 35}
5: {Site: '5MT1825', ESR_SUcat: 'Void', ESR_SUcatdesc: 'void', SUDescCode: 97}

This is the data my query returns so I can confirm that it is working. I guess what I don't understand yet is getting this into my Select Box. Right now I have:

<select id="suTyp" name="SUTyp[]" size="7" multiple="">
<option>Select Study Unit Type(s)</option>
<option value="0">[object Object]</option>
<option value="1">[object Object]</option>
<option value="2">[object Object]</option>
<option value="3">[object Object]</option>
<option value="4">[object Object]</option
><option value="5">[object Object]</option>
</select>

Can someone help me get SUDescCode: 35 and ESR_SUcat: 'Kivas' in for value and option?

Thanks!

stanhook's avatar
stanhook
OP
Best Answer
Level 1

SOLVED - I was able to get it to populate the Select box. I am posting what I did here to hopefully help anyone else (provided this is a best practice). I did it by by using this on the page with my form:

(I added a spinner overlay as the next box loads using CSS)

It appends the select box here:

<select id="suTyp" name="SUTyp[]" size="7" multiple ></select>

This posts it to a URL that is in my Route (this is only a URL, not an actual page):

Route::get( 'ResearchReports/ResearchDatabase/field/qryStructures_start_ajax', [\App\Http\Controllers\FieldStructures::class, 'suAjax'] );

My function runs the query and sends it back to my Ajax:

$ajaxDataSql = "SELECT  tlkpSUDesc.ESR_SUcat,  tlkpSUDesc.SUDescCode blah blah.."
$ajaxDataSql = DB::getPdo()->prepare($ajaxDataSql);
$ajaxDataSql->setFetchMode(\PDO::FETCH_OBJ);
$ajaxDataSql->execute([]);
$ajaxData = collect($ajaxDataSql->fetchAll());
return response()->json($ajaxData);

This is the data I get in the console.log that is sent back to my Ajax:

[
    {
        "ESR_SUcat": "Noncultural Deposits",
        "SUDescCode": 35
    },
    {
        "ESR_SUcat": "Void",
        "SUDescCode": 97
    }
]

My box populates. If anyone has a better way or I am doing something I maybe I shouldn't I am happy to learn.

2 likes

Please or to participate in this conversation.