Selecting the matching label to input on submit - autocomplete - javascript

I am creating an autocomplete on one of my search inputs and have pretty much most of it working fine except one final part which is getting the system to recognise if the input matches a label if the label has not been clicked.
For example if 'London' is typed into the input box but the user does not click on the label for 'London' then the values of the label are not sent and it does not achieve the results that their are for london as the values are sent as null.
So what i want to achieve is that if london is typed into the input box but the label is not clicked then when the submit button is clicked the matching label for london is sent. This has to be for a direct match only so if "london" matches "london". How do i go about doing this?
here is my code so far :
html:
<div class="search-homepage-input">
{!! Form::open(['route' => 'search.index', 'method' => 'GET']) !!}
<div class="col-md-9 col-l">
{!! Form::text('sl', null, array('class' => 'form-control shop-input', 'maxlength' =>'50', 'placeholder' => 'Search by city. Eg. London, New York, Paris...', 'id' => 'sl')) !!}
</div>
{!! Form::hidden('country', null, array('id' => 'country')) !!}
{!! Form::hidden('city', null, array('id' => 'city')) !!}
<div class="col-md-3 col-r">
{!! Form::submit('Find Shops', array('class' => 'btn btn-homepage-search')) !!}
</div>
{!! Form::close() !!}
</div>
PHP laravel:
public function autoComplete(Request $request){
$query = $request->term;
$res = City::where('name', 'LIKE', "%$query%")->orderBy('name')->paginate(5);
foreach($res as $cities ){
$usersArray[] = array(
"label" => $cities->name,
"value" => $cities->id,
"country" => $cities->countries->id,
"countryname" => $cities->countries->country
);
}
return response()->json($usersArray);
}
JS:
$('#sl').autocomplete({
source: countries,
select: function(event, ui) {
event.preventDefault();
if (ui.item.label === "No results found") {
$("#sl").val("");
return false;
}
$("#country").val(ui.item.country); // save selected id to hidden input
$("#city").val(ui.item.value); // save selected id to hidden input
$('#sl').val(ui.item.label + ', ' + ui.item.countryname)
},
focus: function(event, ui) {
event.preventDefault();
$('#sl').val(ui.item.label);
},
response: function(event, ui) {
if (!ui.content.length) {
var noResult = {
value: "",
label: 'No results found'
};
ui.content.push(noResult);
}
}
});
$("#sl").autocomplete("widget").menu("option", "items", "> li:not('.no-select')");
$("#sl").autocomplete("instance")._renderItem = function(ul, item) {
var li = $("<li>");
if (item.country == undefined) {
li.addClass("no-select").append(item.label);
} else {
li.append("<div><strong>" + item.label + "</strong>, " + item.countryname + "</div>");
}
return li.appendTo(ul);
}

Related

Select2 Disable other Select2 based on option

I have two select2 options
I want to implement something like, if user click daily they can use the Select2 option of Days, But if they select Monthly then the another Select2 button will be disable. Can u check why my code isn't working.
{{ Form::select('type', $type, null, ['class' => 'form-control select2', 'onchange' => 'myFunction()', 'id' => 'recurring_type', 'required' => 'true', }}
{{ Form::select('days', $days, null, ['class' => 'form-control select2', 'id' => 'days', 'required' => 'true', }}
And this is the javascript
function myFunction() {
if($(this).val() === 'Daily') {
$('#days').select2('disable');
} else {
$('#days').select2('disable');
}
}
My blind guess is that $(this).val() is not equal to "Daily". You definatelly should recheck what you get with console.log($(this).val()) in beginning of myFunction

stopping the no results label being added to input and if input matches a label

I have created an autocomplete input, it works well but i want to expand it and make it better. But this is a struggle with my limited jquery ui knowledge and despite some trial and error i cannot seem to work out two problems.
The first problem i would like to address is making the noresult label not selectable meaning that it can't be added to the input on focus or on select or at all.
I want to make it so that if what the user has entered into the input box matched the label value but they did not select it for some reason then when they press the submit button on my form the label that is a match is selected and therefore inputted.
Here is what i have so far:
html:
<div class="search-homepage-input">
{!! Form::open(['route' => 'search.index', 'method' => 'GET']) !!}
<div class="col-md-9 col-l">
{!! Form::text('sl', null, array('class' => 'form-control shop-input', 'maxlength' =>'50', 'placeholder' => 'Search by city. Eg. London, New York, Paris...', 'id' => 'sl')) !!}
</div>
{!! Form::hidden('country', null, array('id' => 'country')) !!}
{!! Form::hidden('city', null, array('id' => 'city')) !!}
<div class="col-md-3 col-r">
{!! Form::submit('Find Shops', array('class' => 'btn btn-homepage-search')) !!}
</div>
{!! Form::close() !!}
</div>
PHP laravel:
public function autoComplete(Request $request){
$query = $request->term;
$res = City::where('name', 'LIKE', "%$query%")->orderBy('name')->paginate(5);
foreach($res as $cities ){
$usersArray[] = array(
"label" => $cities->name,
"value" => $cities->id,
"country" => $cities->countries->id,
"countryname" => $cities->countries->country
);
}
return response()->json($usersArray);
}
JS:
$('#sl').autocomplete({
source: '/autocomplete',
select: function(event, ui) {
event.preventDefault();
$("#country").val(ui.item.country); // save selected id to hidden input
$("#city").val(ui.item.value); // save selected id to hidden input
$('#sl').val(ui.item.label +', '+ ui.item.countryname)
},
focus: function(event, ui){
event.preventDefault();
$('#sl').val(ui.item.label+', '+ui.item.countryname);
},
response: function(event, ui) {
if (!ui.content.length) {
var noResult = { value:"",label:'No results found', countryname:"" };
ui.content.push(noResult);
}
}
}).autocomplete( "instance" )._renderItem = function( ul, item ) {
var li = $("<li>");
if (item.country == undefined) {
li.append("<div>" + item.label +"</div>");
} else {
li.append("<div><strong>" + item.label + "</strong>, " + item.countryname + "</div>");
}
return li.appendTo(ul);
};
An example of how to disable a selection item is found here: http://jqueryui.com/autocomplete/#categories
This example is a bit complex, since we're accessing the menu widget inside the autocomplete widget. For your code, a similar method can be used:
$("#sl").autocomplete("widget").menu("option", "items", "> li:not('.no-select')");
widget()
Returns a jQuery object containing the menu element. Although the menu items are constantly created and destroyed, the menu element itself is created during initialization and is constantly reused.
This addresses point #1.
To address point #2, you need to consider the logic of assuming a selection if the user has not made a selection. For example, if the user typed in l and got 10 results, or even just 2 results... which do you select for the user? Also, if the user has navigated away from the field, autoselect would close it's menu and destroy the results.
In my opinion, it would be better to examine the hidden fields, if they are empty, prevent the form from being submitted and force the user to select an option, make it a required field.
$(function() {
var countries = [{
country: 1,
countryname: "UK",
label: "London",
value: 1
}, {
country: 1,
countryname: "UK",
label: "Manchester",
value: 2
}];
$('#sl').autocomplete({
source: countries,
select: function(event, ui) {
event.preventDefault();
if (ui.item.label === "No results found") {
$("#sl").val("");
return false;
}
$("#country").val(ui.item.country); // save selected id to hidden input
$("#city").val(ui.item.value); // save selected id to hidden input
$('#sl').val(ui.item.label + ', ' + ui.item.countryname)
},
focus: function(event, ui) {
event.preventDefault();
$('#sl').val(ui.item.label);
},
response: function(event, ui) {
if (!ui.content.length) {
var noResult = {
value: "",
label: 'No results found'
};
ui.content.push(noResult);
}
}
});
$("#sl").autocomplete("widget").menu("option", "items", "> li:not('.no-select')");
$("#sl").autocomplete("instance")._renderItem = function(ul, item) {
var li = $("<li>");
if (item.country == undefined) {
li.addClass("no-select").append(item.label);
} else {
li.append("<div><strong>" + item.label + "</strong>, " + item.countryname + "</div>");
}
return li.appendTo(ul);
}
$("form").submit(function(e) {
e.preventDefault();
console.log($(this).serialize());
if ($("#country").val() == "" || $("#city").val() == "") {
$("#sl").focus();
return false;
}
return true;
});
});
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div class="search-homepage-input">
<form>
<div class="col-md-9">
<input type="text" name="sl" class="form-control shop-input" max-length="50" placeholder="Eg. England, London, Manchester" id="sl" /> <span style="color: red; font-size: 65%;">* Required</span>
<input type="text" name="country" id="country" style="display: none;" />
<input type="text" name="city" id="city" style="display: none;" />
</div>
<div class="col-md-3">
<button type="submit" class="btn btn-homepage">Find Teams</button>
</div>
</form>
</div>
Hope that helps.

Returning no result matches in autocomplete

How do i return a no results label in my autocomplete when there is no matches to the data, currently it just shows nothing..
here is my current code:
HTML:
{!! Form::open(['route' => 'search.index', 'method' => 'GET']) !!}
<div class="col-md-9">
{!! Form::text('searchlocation', null, array('class' => 'form-control', 'maxlength' =>'55', 'placeholder' => 'Eg. England, London or Sports', 'id' => 'sl')) !!}
</div>
{!! Form::hidden('country', null, array('id' => 'country')) !!}
{!! Form::hidden('city', null, array('id' => 'city')) !!}
<div class="col-md-3">
{!! Form::submit('Find Sights', array('class' => 'btn btn-homepage-search')) !!}
</div>
{!! Form::close() !!}
JS:
$('#sl').autocomplete({
source: '/autocomplete',
select: function(event, ui) {
event.preventDefault();
$("#country").val(ui.item.country);
$("#city").val(ui.item.value);
$('#sl').val(ui.item.label);
},
focus: function(event, ui){
event.preventDefault();
$('#sl').val(ui.item.label);
},
})
You can set this in php as :
if(count($usersArray) < 1){
$usersArray[] = array(
"label" => "No Result",
"value" => "-1",
"country" => "-1"
);
}
you can use client side check to show no records found. please take a look below.
$(function() {
$("#SearchUser").autocomplete({
source: function(request, response) {
$.ajax({
url: "http://api.stackexchange.com/2.1/users",
data: {
site: 'stackoverflow',
inname: request.term
},
dataType: 'jsonp'
}).done(function(data) {
if (data.items) {
response($.map(data.items, function(item) {
console.log(item);
return item.display_name + " " + item.location;
}));
}
});
},
minLength: 1,
response: function(event, ui) {
if (!ui.content.length) {
var message = { value:"",label:"No records found" };
ui.content.push(message);
}
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.9.0/jquery-ui.js"></script>
<link href="http://code.jquery.com/ui/1.9.0/themes/base/jquery-ui.css" rel="stylesheet"/>
<label for="SearchUser">StackOverflow user:</label>
<input id="SearchUser" type="text" />
.

Html::dropDownList depending Yii2

I have a problem to connect two select. I would like the choice of a select filters the search of the second select statement.Both select take data from their tableDB but are not influenced each other. Can someone help me?
my first select customers take data from db table customers:
<?=
Html::dropDownList('userlist', [],
ArrayHelper::map(Customers::find()->where('id',['company_id' =>
'name'])->orderBy('name')->all(), 'id', 'name'),
['prompt' => 'Select a User ...',
'class' => 'form-control',
'style' => 'width: 100%;']);
?>
my second select offers take data from db table offers:
<?=
Html::dropDownList('offerslist', [],
ArrayHelper::map(Offers::find()->where('customer_id',['company_id'
=> 'offers_n'])->orderBy('customer_id')->all(),
'id','offers_n','customer_id'),
['prompt' => 'Select a Offert ...',
'onchange' => 'change_user_list(this.value)',
'class' => 'form-control',
'style' => 'width: 100%;']);
?>
This is my function js:
function change_user_list(company_id)
{
$.ajax({
url: "<?= \yii\helpers\Url::to(['offers/userlist'])?>",
type: 'get',
data: {
company_id: company_id
},
success: function (data) {
document.getElementsByName('userlist')[0].innerHTML = data;
}
});
}
this is my actionFucntion in the controller:
public function actionUserlist($company_id)
{
if (Yii::$app->request->isAjax) {
$userlist = ArrayHelper::map(Customers::find()-
>where(['company_id' => $company_id])->orderBy('name')->all(),
'id', 'name');
$string = "<option value>Select a Users</option>";
foreach($userlist as $id => $name) {
$string .= "<option value=".$id.">".$name."</option>";
}
return $string;
}
}

Show form fields conditionally based on user input

In my Laravel app, I have a select form field that lists a set of countries:
<select id="js-countrySiteSelect">
<option>Select Your Country</option>
<option>United States</option>
<option>Australia</option>
<option>Germany</option>
<option>Switzerland</option>
<option>United Kingdom</option>
</select>
Beneath that, I also have a series of select form fields. Each select shows a series of locations within that country.
{!! Form::select('site_id', $australia, null, ['class' => 'js-siteSelect select-australia', null => 'Select a user...']) !!}
{!! Form::select('site_id', $germany, null, ['class' => 'js-siteSelect select-germany']) !!}
{!! Form::select('site_id', $switzerland, null, ['class' => 'js-siteSelect select-switzerland']) !!}
{!! Form::select('site_id', $us, null, ['class' => 'js-siteSelect select-us']) !!}
{!! Form::select('site_id', $uk, null, ['class' => 'js-siteSelect select-uk']) !!}
Based on which country the user selects, I want to show or hide the corresponding form fields:
$('#js-countrySiteSelect').change(function(e) {
e.preventDefault();
$('.js-siteSelectLabel').addClass('js-show');
if ( $(this).val() == 'United States' ) {
$('.js-siteSelect').removeClass('js-show');
$('.select-us').addClass('js-show');
} else if ( $(this).val() == 'Australia' ) {
$('.js-siteSelect').removeClass('js-show');
$('.select-australia').addClass('js-show');
} else if ( $(this).val() == 'Germany' ) {
$('.js-siteSelect').removeClass('js-show');
$('.select-germany').addClass('js-show');
} else if ( $(this).val() == 'Switzerland' ) {
$('.js-siteSelect').removeClass('js-show');
$('.select-switzerland').addClass('js-show');
} else if ( $(this).val() == 'United Kingdom' ) {
$('.js-siteSelect').removeClass('js-show');
$('.select-uk').addClass('js-show');
}
});
However, since each location dropdown is still loaded into the DOM, the form always submits the first option of the last select—in this example, the UK dropdown.
How can I refactor this so that only the visible select element submits data?
this is because you just hide the not used selects, if you mark them as disabled, then the elements wont be send to the server.
Try in place to set
$select.hide()
use
$select.prop('disabled', true)

Categories