I have a form view, "addMachine.blade.php", which is currently a pop-up modal form accessed through the navigation bar. I also setup Typeahead autocomplete in the form.
These are the routes for the addMachine view and autocompleteUser
Route::get('/machine/add', 'Machine\AddMachineController@index')->name('addMachine');
Route::get('/machine/add/operator_autocomplete', [
'as'=>'autocompleteUser',
'uses'=>'Machine\AddMachineController@autocompleteUser']);
Typeahead autocomplete works when I access my website by going to http://localhost/machine/add.
However, when I try to access the form through the navigation bar and have it open as a pop-up modal (which is what I want it to do), I get the following error from Chrome's console: TypeError: $(...).typeahead is not a function
. I have tried moving the typeahead and jquery links to my app.blade.php but I still get the same error.
This is the code for my form view, "addMachine.blade.php".
-- removed code, see edit below for new addMachine.blade.php code --
This is the function from my AddMachineController which handles the autocomplete
/**
* Handle a autocomplete user request.
*
* @return \Illuminate\Http\Response
*/
public function autocompleteUser(Request $request)
{
$data = User::where("name", "LIKE", "%{$request->input('query')}%")
->orWhere("id", "LIKE", "%{$request->input('query')}%")
->orderBy('name')
->take(5)
->get();
return response()->json($data);
}
This is my app.blade.php
-- removes code, see edit below for new app.blade.php code --
And finally, this is my navigationBar.blade.php
<nav class="navbar navbar-inverse">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false"
aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/home">SEI</a>
</div>
@if (!Auth::guest())
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
</ul>
<ul class="nav navbar-nav navbar-right">
<-- Some more links -->
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">
Machine <span class="caret"></span>
</a>
<ul class="dropdown-menu" role="menu">
@if (Auth::user()->isMQE())
<li><a href="{{ route('addMachine') }}" data-toggle="modal" data-target="#addMachinePopupModal">Add New Machine</a></li>
@endif
</ul>
</li>
<-- Some more links -->
</ul>
</div>
<div id="addMachinePopupModal" class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
</div>
</div>
</div>
@endif
</div>
</nav>
Any help is appreciated. Also, I am not sure if this is the best way to have a popup modal form be displayed by a navigation bar. If anyone has a better solution for anything I am doing, please feel free to share. I am new to web development and love to learn :)
Note: Using Laravel 5.4 and Php7
EDIT: I can see my code for the addMachine view when I use the "Inspect" tool in Chrome. However, when I use "View Page Source" it isn't there.
I am guessing now that that is the reason behind the typeahead error and I am not displaying pop-up modal forms from my navigation bar in a smart way. Any suggestions?
EDIT2: It does seem like the pop-up modal is the problem. I changed my app.blade.php to the following code
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- CSRF Token -->
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>{{ config('app.name', 'SEI-MQE') }}</title>
<!-- Styles -->
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>
<body>
<div id="app">
@include('include.navigationBar')
@include('include.flashMessage')
@yield('content')
</div>
<!-- Scripts -->
<script src="{{ asset('js/app.js') }}"></script>
@yield('scripts')
</body>
</html>
Then I changed my addMachine.blade.php to this
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading text-center">Add New Machine</div>
<div class="panel-body">
<form class="form-horizontal" method="POST" action="{{ route('addMachine') }}">
{{ csrf_field() }}
<div class="form-group{{ $errors->has('name') ? ' has-error' : '' }}">
<label for="name" class="col-md-4 control-label">Name</label>
<div class="col-md-6">
<input id="name" type="text" class="form-control" name="name" value="{{ old('name') }}" required autofocus>
@if ($errors->has('name'))
<span class="help-block">
<strong>{{ $errors->first('name') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-group{{ $errors->has('part_id') ? ' has-error' : '' }}">
<label for="part_id" class="col-md-4 control-label">Part Id#</label>
<div class="col-md-6">
<input class="typeahead form-control" autocomplete="off" type="text" id="part_id" name="part_id" value="{{ old('part_id') }}">
@if ($errors->has('part_id'))
<span class="help-block">
<strong>{{ $errors->first('part_id') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-group">
<label for="department_id" class="col-md-4 control-label">Department</label>
<div class="col-md-6">
<p style="margin-top: 7px;">
<select name="department_id" id="department_id" type="department_id">
<?php
foreach ($departments as $department) {
echo "<option value=".$department['id'].">".$department['name']."</option>";
}
?>
</select>
</div>
</div>
<div class="form-group">
<label for="type_id" class="col-md-4 control-label">Machine Type</label>
<div class="col-md-6">
<p style="margin-top: 7px;">
<select name="type_id" id="type_id" type="type_id">
<?php
foreach ($types as $type) {
echo "<option value=".$type['id'].">".$type['name']."</option>";
}
?>
</select>
</div>
</div>
<div class="form-group">
<label for="production_status_id" class="col-md-4 control-label">Production Status</label>
<div class="col-md-6">
<p style="margin-top: 7px;">
<select name="production_status_id" id="production_status_id" type="production_status_id">
<?php
foreach ($productionStatuses as $productionStatus) {
echo "<option value=".$productionStatus['id'].">".$productionStatus['name']."</option>";
}
?>
</select>
</div>
</div>
<div class="form-group">
<div class="col-md-6 col-md-offset-4">
<button type="submit" class="btn btn-primary">
Add Machine
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
@section('scripts')
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-3-typeahead/4.0.2/bootstrap3-typeahead.min.js"></script>
<script type="text/javascript">
var autocompletePartPath = "{{ route('autocompletePart') }}";
$('#part_id').typeahead( {
source: function (query, process) {
return $.get(autocompletePartPath, { query: query }, function (data) {
return process(data);
});
},
displayText: function (item) {
return `${item.id} - ${item.name} ${item.revision}`;
},
afterSelect: function (item) {
$('#part_id').val(item.id);
},
fitToElement: true
});
</script>
@endsection
I changed my navigation bar html to open the addMachine view normally rather than by pop-up modal and the typeahead works now.
Can anyone explain to me how I can make my addMachine view a pop-up modal form that opens from the navigation bar AND has typeahead working?
Finally figured it out. Solution for my problem was just to move the jquery and typeahead source scripts from addMachine.blade.php into app.blade.php like so:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- CSRF Token -->
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>{{ config('app.name', 'SEI-MQE') }}</title>
<!-- Styles -->
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>
<body>
<div id="app">
@include('include.navigationBar')
@include('include.flashMessage')
@yield('content')
</div>
<!-- Scripts -->
<script src="{{ asset('js/app.js') }}"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-3-typeahead/4.0.2/bootstrap3-typeahead.min.js"></script>
</body>
</html>
Solution is simple so I feel dumb, but for anyone who wants an example of having the navigation bar to open a pop-up modal form with typeahead autocomplete, read my solution in the question.