Laravel 5.2 - Autocomplete Suggest - javascript

i'm creating a input autocomplete suggest from list of my database, but i have some problem, my input show the suggest like the picture:
Problem: My controller show 10 items like i want, but the termns doesn't work well, because as you can see if i write my municipality "Milan" it doesn't suggest correctly, actually my controller is showing the first 10 item of my table.
MY CONTROLLER:
public function getData(Request $request) {
$termn = $request->input('municipality');
// controllo
$data = Municipality::where('name', 'LIKE', '%'.$termn.'%')->take(10)
->get();
$results = array();
foreach($data as $v){
$results[]=['id' => $v->id, 'value' => $v->name];
}
//return $results;
return response()->json($results);
}
ROUTES
Route::get('getdata', 'PostController#getData');
JS
$('#searchname').autocomplete({
minLength: 1,
autoFocus: true,
source: $('#route-url').val(),
select: function(e, ui){
console.log(ui.item.id);// it work and show me id of item selected
},
});
VIEW FORM
<!-- Select Basic -->
<div class="form-group">
<label class="col-md-3 control-label" for="seller-Location">Municipality</label>
<div class="col-md-8">
<input
type="text"
name="municipality"
placeholder="comune"
class="form-control input-md"
id="searchname">
<input type="hidden" id="route-url" value="{{ url('getdata') }}">
</div>
</div>

If dd is empty, it's because there is no data for this key :)
Use var_dump($request->all()); or dd($request->all());
You will have the lsit of all parameters available.
I can see on your javascript's code source: $('#route-url').val(),.
So, I guess you will have values like this:
If result of dd is:
'source' => '...' Then, you will have to use $request->input('source')
0 => '...' Then, source is an array. Maybe try with source: {municipality: $('#route-url').val()} ?
If data is empty, then, you have another issue. Read the documentation/examples of the autocomplete library

Related

How to manage dependent dropdown list in php when create and update method is managed in same page

I have written the code to display the dependent dropdown list in php, when I create the record it is working. What changes I need to do while updating the record as I want the create and update method in same page.
Here's the code for reference,
<div class="form-group row m-b-15">
<label class="col-md-4 col-sm-4 col-form-label" for="fin_is_fin_req">
Is Finance Required? * :
</label>
<div class="col-md-4 col-sm-4">
<select name="fin_is_fin_req" id="is_finance" class="form-control" autofocus>
<option value="">-Select Finance-</option>
<?php
$fin_req=array('Yes','No');
foreach ($fin_req as $list) {
if ($allotment->fin_is_fin_req==$list):?>
<option selected value="<?=$list?>">
<?php else:?>
</option>
<option value="<?=$list?>">
<?php endif;?>
<?=$list?></option>
<?php } ?
</select>
</div>
</div>
<div class="form-group row m-b-15 ">
<label class="col-md-4 col-sm-4 col-form-label" for="fin_stage">
Finance Stage * :
</label>
<div class="col-md-4 col-sm-4">
<select name="fin_stage" id="stages" class="form-control">
</select>
</div>
</div>
$(document).ready(function () {
$('#is_finance').on('change', function () {
var finance_value = $("#is_finance").val();
$.ajax({
url: 'ajax/loadstages.php',
method: 'post',
data: 'finance_value=' + finance_value
}).done(function (stages) {
stages = JSON.parse(stages);
stages.forEach(function (stage) {
$('#stages').append('<option value=' + stage.id + '>' + stage.stage_name + '</option>')
})
})
});
});
loadstages.php
if (isset($_POST['finance_value'])) {
if ($_POST['finance_value'] == "Yes") {
$stages = FinStage::select('*', 'state=1');
//select(rows,where)
} else {
$stages = FinStage::select('*', 'state=0');
}
}
echo
json_encode($stages);
//screenshot during insert
//screenshot during update
If I understand you, you are saying that when you open the page, you want that page to show that second select, if the first dropdown has a value saved to it already? If that is the case, you can load it initially with PHP initially or you can adjust your JS to load the first dropdown at page ready:
<script>
// I might consider making this an object for reuse
class FormController
{
fetch(data, page, success)
{
$.ajax({
// Presumably all your ajax files are in this directory
url: `ajax/${page}.php`,
method: 'post',
data: data
}).done(r => {
// If your ajax pages send headers for Content-Type: application/json,
// you can skip the JSON parse if you want to
success(JSON.parse(r));
});
}
}
// If you extend the main form, you can use the ajax
class Finance extends FormController
{
getStages()
{
// Fetch the value from dropdown
const finance_value = $("#is_finance").val();
// Fetch the value of the first dropdown
super.fetch({ finance_value }, 'loadstages', r => {
// Do your append loop from the return
r.forEach(stage => {
$('#stages').append(`<option value=${stage.id}>${stage.stage_name}</option>`);
});
});
}
}
// Document ready
$(() => {
// Create the financial form
var FinForm = new Finance();
// Fetch the select value on page load
FinForm.getStates();
// On change, fetch the value again
$('#is_finance').on('change', () => {
FinForm.getStates();
});
});
</script>
Your PHP probably should be more like:
<?php
# Consider using this header
// header('Content-Type: application/json');
# Set a default, makes sure the json doesn't throw a warning if the condition
# is not set for whatever reason
$stage = [];
if (isset($_POST['finance_value'])) {
$finAffirm = ($_POST['finance_value'] == "Yes");
# You can just do this in one line so there is no duplication
$stages = FinStage::select('*', 'state='.(($finAffirm)? '1' : '0'));
# Fetch only on the affirmative
if ($finAffirm) {
//select(rows,where)
}
}
# It's safer just to exit here
die(json_encode($stages));

How to dynamic dropdown list in laravel 5.3?

My html is like this :
<div class="form-group has-feedback{{ $errors->has('kdkotama') ? ' has-error' : '' }}">
<select class="form-control" name="kdkotama" id="kdkotama">
<option value="">---- Pilih Kotama----</option>
#foreach($tkotam as $tkotam)
<option value="{{$tkotam->kdkotama}}">{{$tkotam->nmkotama}}</option>
#endforeach
</select>
#if ($errors->has('kdkotama'))
<span class="help-block">
<strong>{{ $errors->first('kdkotama') }}</strong>
</span>
#endif
</div>
<div class="form-group has-feedback{{ $errors->has('kdsatker') ? ' has-error' : '' }}">
<select class="form-control" name="kdsatker">
<option value="">---- Pilih Satker ----</option>
</select>
#if ($errors->has('kdsatker'))
<span class="help-block">
<strong>{{ $errors->first('kdsatker') }}</strong>
</span>
#endif
</div>
My javascript is like this :
<script>
$(document).ready(function() {
$("#kdkotama").change(function() {
console.log($("#kdkotama").val());
$.getJSON("../dropdowns/satkers/" + $("#kdkotama").val(), function(data) {
var $satkers = $("#kdkotama");
$satkers.empty();
$.each(data, function(index, value) {
$satkers.append('<option value="' + index +'">' + value + '</option>');
});
$("#kdkotama").trigger("change"); /* trigger next drop down list not in the example */
});
});
});
</script>
My routes/web is like this :
Route::get('dropdowns/satkers/{id}', 'DropDownController#getSatkers');
My controller is like this :
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\TSatkr
class DropDownController extends Controller
{
public function getSatker($id)
{
$satkers = TSatkr::where('kdkotama', '=', $id)->get();
$options = array();
foreach ($satkers as $satker) {
$options += array($satker->kdsatkr => $satker->nmsatkr);
}
return Response::json($options);
}
}
I added this: console.log ($ ("# kdkotama"). val ()); in javascript. when I select kotama, the results of console.log that appear. but in the console, it did not succeed in calling controller. whereas the code, it looks like it is correct
is there anyone who can help me?
I faced so many problem to generate dynamic drop-down but now I do like this which is more powerful and useful to set dynamic drop-down value.
Lets generate DOM using method which can help us to generate dynamic DOM with one truth or source..
//Controller/HelperController.php
class HelperController
{
public static function ajaxDynamicDropDown($changeDropdown, $replaceDropdown, $url, $empty = []) {
$html = '<script type="text/javascript">';
$html.='jQuery(document).ready(function($) {';
$html.='jQuery("select[name=\'' . $change_dropdown . '\']").change(function(e){';
$html.='jQuery.ajax({';
$html.='type: "'.$action_type.'",';
$html.='url: "' . $url . '",';
$html.='dataType:"json",';
$html.='data: jQuery(this).parents("form").find("input,select").not("[type=hidden][name^=_]").serialize(),';
$html.='success:function(data){';
$html.=' jQuery("select[name=\'' . $replace_dropdown . '\']").find("option:not(:first)").remove();';
if (!empty($empty)) {
foreach ($empty as $key => $emt) {
$html.=' jQuery("select[name=\'' . $emt . '\']").find("option:not(:first)").remove();';
}
}
$html.=' jQuery.each(data, function(key,value){';
$html.=' jQuery("select[name=\'' . $replace_dropdown . '\']").append(\'<option value="\'+key+\'">\'+value+\'</option>\');';
$html.='});';
$html.='}';
$html.='});';
$html.='});';
$html.='});';
$html.='</script>';
return $html;
}
}
Benefit of it is I don't have to write change event for each dropdown. Also no need trigger.
// Blade File:
{!! Form::select('country_id',['1'=>'Test 1','2'=>'Test 2'],null,[]) !!} // First Dropdown with value
{!! Form::select('state_id',[],null,[]) !!} // Second Dropdown will set based on first one.
<script type="text/javascript">
{!! HelperController::ajaxDynamicDropDown('country_id','state_id',URL::to('ajax/states'),['state_id','city_id']) !!}
</script>
Now I am going to use implicit route controller. Using that I get controller methods based on the HTTP request type and name.
Mean in ajax if I used POST method request then in my controller my method name will be like postState() or if GET request then same getState(). For more please click here
//routes.php
Route::controller('ajax', 'AjaxController');
Here is code sample of AjaxController
// AjaxController.php
class AjaxController
{
public function postState()
{
// of course here I get Input by using request()->get('input_name')
return ['1'=>'test'];
}
}
Also you can set old value when validation going false with old() in AjaxController.
You can also use it for multiple dependencies like state if came from country now it can be possible you need to get city from state same method you can use for it..

validating data in database in angularjs

I am using angularjs in my project. In a process/module, the form will not be submitted if a certain data input is already exist in the database. For example, this process: registering /Signing up. If the user inputted a username that's already been used by someone, the form will not be submitted. And it will be checked in a controller where the list of usernames has been loaded prior to user entering the data by comparing (in a for loop). My question is, is this a good way of checking the data or do I have to use $http?
Edit:
<div class="col-xs-6 col-sm-6 col-md-6">
<div class="form-group"><label class="control-label">Username</label>
<input type="text" ng-model="reg.username" usernameAvailable
name="username" class="form-control input-md"
placeholder="Username" required />
<div ng-if="regForm.$pending.usernameExists">checking....</div>
<div ng-if="regForm.$error.usernameExists">username exists
already
</div>
</div>
</div>
mainApp.directive('usernameAvailable', function($timeout, $q, $http) {
return {
restrict: 'AE',
require: 'ngModel',
link: function(scope, elm, attr, model) {
model.$asyncValidators.usernameExists = function() {
//here you should access the backend, to check if username exists
//and return a promise
// var defer = $q.defer();
// $timeout(function(){
// model.$setValidity('usernameExists', true);
// defer.resolve;
// }, 1000);
// return defer.promise;
console.log(model);
return $http.get(BASE_URL+'Register/validate?u='+username).
then(function(res){+$timeout(function(){
model.$setValidity('usernameExists', !!res.data);
}, 1000);
});
};
}
}
});
Php controller:
public function validate(){
$this->load->model('account_model');
$data =$this->account_model->exist($this->input->get('u'));
echo json_encode($data);
}
You should take the data to the server. And there, should fire a query in db to check if this data already exists. If it does then show error message on UI and do not save other wise save it with success message.
Fire query (sample) Something like :
SELECT * FROM users WHERE username='myName'
If records are more than 0, then what you have is a repeated value.
Do not fetch all the records on UI and then loop through them.
Think of :
What if there are 1 Million or more records?
Security ? (You are getting all the user names to client)
And other such things.
Hope it guides you.

Populating dropdownlist using knockout observable array

I am trying to bind 2 drop down lists to knockout observable arrays.The condition is that the first drop down list has to get populated first.The second drop down list is dependent on the first drop down list.Hence I am subscribing to the first drop down list to populate the second drop down list.
To try and achieve this,I have written the following code
HTML is
<div class="form-group">
<label class="col-sm-2 control-label labelfont">Certification:</label>
<div class="col-sm-6">
<select class="form-control" id="certification" name="certification" data-bind="value: certification, options: certificationArray, optionsText: 'Certification', optionsValue: 'CertificationID', optionsCaption: 'Select a Certification'">
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label labelfont">Specialization:</label>
<div class="col-sm-6">
<select class="form-control" id="specialization" name="specialization" data-bind="value: specialization, options: specializationArray,optionsText:'Specialization',optionsValue:'SpecializationId', optionsCaption: 'Select a Specialization'">
</select>
</div>
</div>
The view model is
self.specializationArray = ko.observableArray([]);
self.certificationArray = ko.observableArray([getCertifications()]);
self.certification = ko.observable("");
self.specialization = ko.observable("");
self.certification.subscribe(function () {
self.specializationArray([]);
getSpecializations();
}
});
The functions to get the respective certifications and speciaizations are
var getCertifications = function () {
$.getJSON("/Provider/GetCertifications", function (data) {
return data;
});
});
};
var getSpecializations = function () {
$.getJSON("/Provider/GetSpecializations/", { certificationID: $("#certification").val() }, function (data) {
self.specializationArray(data)
})
}
The JSON response looks like this
and the JSON looks like this
Could someone please guide me in the right direction,I am completely new to knockout and JSON.I am at my wit's end here.So,any help would be greatly appreciated.Thanks in advance.
In KnockOut, the values of the arrays are separate from the options the dropdowns get. You wouldn't change the observableArray, but the value observable itself. Better, though, would be to use a ko.computed field to hold the value of the 2nd dropdown.
I don't really understand why you think your dropdowns must get bound in a certain order, though. I'm not exactly sure how the Certifications and Specializations have to do with each other from your question. You aren't really doing anything in self.certification.subscribe(), like there was any dependency when filling in the Specialization. The JSON you supplied in the Certifications also does not have any related Specialization foreign key. But if your JSON for Certification looked like this:
[{"CertificationID": 1, "Certification": "M.B.B.S.", "SpecializationID": "7"},{"CertificationID": 2, "Certification": "M.D.", "SpecializationID": "3"}, ...]
while the JSON for Specialization looked like this...
[{"SpecializationID": 1, "Specialization": "Cardiology"},
{"SpecializationID": 2, "Specialization": "Dentistry"},
{"SpecializationID": 3, "Specialization": "General Practioner"}, ...
{"SpecializationID": 7, "Specialization": "Surgery"}
]
I believe something like this should work:
self.specialization = ko.computed(function() {
return ko.utils.arrayFirst(getCertifications(), function(certs) {
return certs.ID == self.SpecializationID();
}).SpecializationID;
});
But since I don't see where you have any dependencies, here, why not just fill them in, directly:
self.certificationArray = ko.observableArray(getCertifications());
self.specializationArray = ko.observableArray(getSpecializations());
self.certification = ko.observable(vm.certification);
self.specialization = ko.observable(vm.specialization);
And you set those values using the viewmodel returned from the dataset, which should be ID fields in your database table (CertificationID, SpecializationID).

Angular ng-options behaves odd

I have this typahead with angular strap:
<div class="form-group" ng-class="newGroupForm.placeReference.$invalid ? 'has-error' : ''">
<label for="placeReference" class="col-lg-2 control-label">Group Location</label>
<div class="col-lg-10">
<input type="text" name="placeReference"
ng-model="newGroup.reference"
ng-options="place.reference as place.name
for place in getPlaces($viewValue)"
bs-typeahead min-length="0" required >
</div>
</div>
getPlaces returns array of objects which looks like this:
{
reference: "ccj32213SIJD",
name: "some name",
}
When I am typing I am getting correct results, but when I select the wonted option the value that I see in my input is the reference (instead of the name).
Can any one point out my mistake?
Here is the controller code:
$scope.getPlaces = function(viewValue) {
var input = viewValue || $scope.currentPlace;
return googleService.placesAutocomplete(input).then(
function(places) {
return places;
}
);
};
If ng-options here behaves exactly like <select ng-options> (sorry, I'm not familiar with bs-typeahead directive), then you should change it to:
<input ...
ng-model="selectedPlace"
ng-options="place as place.name for place in getPlaces($viewValue)">
Then you can use get the name elsewhere:
<div>{{selectedPlace.name}}</div>
It's probably best to get the actual place object {name: "..", reference: "..."}, but if you just need the name, then you could do this:
<input ...
ng-model="selectedPlaceName"
ng-options="place.name as place.name for place in getPlaces($viewValue)">

Categories

Resources