Yet another jQuery autocomplete thread - javascript

I am trying to figure out what's wrong with my code (Laravel5 project).
So far I have:
master.blade.php
<!-- jQuery Version 1.11.0 and jQuery UI-->
<link rel="stylesheet" href="http://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="{{asset("patho/to/jquery/jquery-1.11.0.js")}}"></script>
<script src="http://code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
the master view is preloaded in any view, it serves as a header and footer wrapper. Note that I obfuscated the local path to jQuery script, it's real and it's loaded and it works.
Included in one of my CRUD views:
create.blade.php
{!! Form::select('league_id',[], Request::old('league_id'), array('class' => 'form-control', 'id' => 'league_name')) !!}
<script src="{{ asset('js/tips.js') }}">
And in my tips.js file:
$(document).ready(function() {
var dataSource = ['test1', 'test2'];
$('#league_name').autocomplete(
{
source: dataSource
}
);
});
I also tried with:
var dataSource = [{value: 'test1', name: 'test1'}]
Yet it still does not work at all, no console errors displayed either.
Any clues?
Edit: following michaelbahr's suggestion:
the autocomplete widget doesn't execute at all, the resulting select dropdown I get is just an empty one. No items, no search box from the widget. A plain, empty select:
<select class="form-control ui-autocomplete-input" id="league_name" name="league_id" autocomplete="off"></select>

It won't work that way. Autocomplete needs an input (text) field to work. If you wanna have a select, you can do something like this.
But, if you already have an array, you don't need autocomplete, you can simply use jQuery like so:
$(document).ready(function() {
var dataSource = ['test1', 'test2'];
var league = $('#league_name');
$.each(dataSource, function(index, value){
league.append("<option>" + value + "</option>");
})
});

Related

How add new values in drop-down list using plugin "selectory" jquery

I need some help. How can I add new values in code to the list if I use a plugin from jquery. I wrote this code, but the list is empty, although the values are passed to the view. This is probably due to the fact that I am referring to the id of the div tag, but the plugin did not work differently. Help please
<html>
<main>
<form action="#">
<div class="form-group col-xs-12 col-sm-4" id="example-2"> </div>
</form>
</main>
<script>
$('#example-2').selectivity({
items: ['Amsterdam', 'Antwerp'],
multiple: true,
placeholder: 'Type to search a city'
});
function addOption() {
var ul = document.getElementById("#example-2");
for (var item in #ViewBag.List)
{
var value = item;
}
var newOption = new Option(value, value);
ul.options[ul.options.length] = newOption;
}
</script>
</html>
result of code from answer 1
The documentation of the selectivity library covers how to add new options to the dropdown.
The main issue you have is that the output from #ViewBag.List won't be in a format that JS can understand. I would suggest formatting it as JSON before outputting it to the page, then the JS can access this as a standard object, though which you can loop.
// initialisation
$('#example-2').selectivity({
items: ['Amsterdam', 'Antwerp'],
multiple: true,
placeholder: 'Type to search a city'
});
// add options, somewhere else in your codebase...
const $list = $('#example-2')
const options = #Html.Raw(Json.Encode(ViewBag.List));
options.forEach((option, i) => {
$list.selectivity('add', { id: i, text: option })
});
Note that for this to work the JS code which reads from the ViewBag needs to be placed somewhere the C# code will be executed, ie. in a .cshtml file, not in a .js file.

Checkbox to enable or disable a list box

I have a checkbox on my ASP.NET MVC page that I create like:
<div>
#Html.CheckBoxFor(m => m.allUsers, new { Name = "allUsersCheck" })
#Html.LabelFor(m => m.allUsers)
</div>
I also have a listbox that I create with:
#Html.ListBoxFor(x => x.selectedUsers, Model.ListofUsers, new { style = "width:200px", size = 10, Id = "lbUsers" })
I have this following script (which I wrote to disable the listbox when my checkbox is checked. I can't understand why it doesn’t work. Can someone point out what's wrong in my code please?
This script is in the same .cshtml page and not in the .js file:
<script >
$(function () {
$('#allUsersCheck').click(function () {
$('#lbUsers').prop("disabled", $(this).prop('checked'));
});
});
</script>
Because you are using the Id selector of '#allUsersCheck'. The checkbox does not have an Id attribute unlike your list box(?).
#Html.CheckBoxFor(m => m.allUsers, new { Name = "allUsersCheck" })
Try the following with an Id attribute:
#Html.CheckBoxFor(m => m.allUsers, new { Name = "allUsersCheck", Id = "allUsersCheck" })
Ok. Took me a while to figure out the entire list of things I need to do.
Here's all I did to finally get it working.
Firstly, I needed this jquery library being used.
<script type="text/javascript" src="http://code.jquery.com/jquery-1.8.2.js"></script>
Then I had to create a function under the above jquery inclusion
<script type="text/javascript">
$(function () {
$("#allUsersCheck").change(function () {
$("#lbUsers").find("option").prop("selected", this.checked)
});
});
</script>
In the above you'll see allUsersCheck is the checkbox element's id and lbUsers is the id for the ListBoxFor element.
The next thing is, in my .cshtml I needed to use/create the listboxfor / checkbox elements. This is how I did it
<b>Users </b><br />
#Html.ListBoxFor(x => x.selectedUsers, Model.ListofUsers, new { style = "width:200px", size = 10, id = "lbUsers" })
<br />
<div>
#Html.CheckBoxFor(m => m.allUsers, new { id = "allUsersCheck" })
#Html.LabelFor(m => m.allUsers)
</div>
I also used a bool flag as part of my model. allUsers is the flag. The bool flag was needed for something else in the controller code and not for UI reasons.
I am not sure if this is the best method. But this is the method I could get it working.
Thanks to the guys who helped me in this process get this working. Obviously not without them.

How can I add Automatic intellisense to a Textbox using Jquery

I want to add automatic Intellisense (Auto Complete--Filtering Search Result) to a textbox, corresponding to the words that I'm typing in that textbox and the Intellisense is fetched from a database table. How can I achieve this? Can anyone help?
Here is my jQuery code:
$(document).ready(function() {
$('#city').autocomplete({
source:'send.php'
});
});
send.php file given below:
$link=mysqli_connect("localhost","hari","123","hari");
$searchTerm = $_GET['query']; //get search term
$query = $db->query("SELECT fname FROM user WHERE fname LIKE
'%".$searchTerm."%' ORDER BY fname ASC"); //get matched data from user table
while ($row = $query->fetch_assoc()) {
$data[] = $row['fname'];
}
echo json_encode($data);//return json data
Corresponding HTML Code is given below:
<div class="content col-sm-12">
<form>
<h1>Hello!!!</h1>
<input type="text" id="city" name="city" size="20" class="city"
placeholder="Please Enter City or ZIP code"><br><br>
</form>
</div>
You have to include the following scripts in your html page
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
And add the following css in head of your html
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
The mistake you made is the parameter passing with the name term and trying to read with the name query in your php file. In your send.php file change the line
$searchTerm = $_GET['query'];
into
$searchTerm = $_GET['term'];
Try this:
$(document).ready(function() {
$('#city').autocomplete({
source: function( request, response ) {
$.ajax( {
url: "send.php",
dataType: "jsonp",
data: {
query: request.term
},
success: function( data ) {
response( data );
}
} );
},
});
});
I have a recommendation for you, use angular 1 for this, you can simply write that code without additional UI libraries and with much much better performance and issue-free solution.
Add the following parent div to your input element:
Change your input to this:
<input type="text" id="city" name="city" size="20" class="city" ng-model="query" ng-change="fetch()" placeholder="Please Enter City or ZIP code">
Add the following code right under your <input>:
<ul>
<li ng-repeat="text in suggestions">{{ text }}</li>
</ul>
As a basic set up, you need this in your <head> section:
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
Finally you will create a new file like in assets directory like "suggestions.js" in your assets directory or somewhere and add this file right before you your </body> tag like this in your template:
<script src="assets/suggestions.js"></script>
The file will have the following lines:
var app = angular.module('myApp', []);
app.controller('suggestionsCtrl', function($scope, $http) {
$scope.suggestions = [];
$scope.query = '';
$scope.fetch = function() {
$http({method: 'POST', url: 'send.php', params: { query: $scope.query } }).
then(function(response) {
$scope.status = response.status;
$scope.suggestions = response.data;
}, function(response) {
/* SOMETHING WENT WRONG WTIH THE CALL DO SOMETHING HERE */
});
};
});
There is very simple set-up/tutorial for Angular 1 here:
https://www.w3schools.com/angular/default.asp
This is not a direct answer but believe me a more efficient answer. Angular 1 and the newer versions save a lot of time and brings performance.
And btw, autocomplete() is not a native jQuery function. Also I do not mention that you need jQuery also for Angular, but I assume it's already added in your template.

JQuery and Autocomplete Using a List (Python/Flask)

This has probably been asked before, but after searching for awhile I'm still a bit confused. I'm trying to make a flask app but I'm not too familiar with JQuery itself, but I would like to create an autocomplete widget in my html. However, instead of querying a database I'd like to just use a static list and a regex to get results. I used this as reference.
What I did was:
#app.route('/autocomplete', methods=['GET'])
def autocomplete():
search = request.args.get('q')
#query = db_session.query(Movie.title).filter(Movie.title.like('%' + str(search) + '%'))
#results = [mv[0] for mv in query.all()]
results = ['Beer', 'Wine', 'Soda', 'Juice', 'Water']
return jsonify(matching_results=results)
while keeping the rest of the code:
<head>
<link href="//code.jquery.com/ui/1.10.2/themes/smoothness/jquery-ui.css" rel="Stylesheet"></link>
<script src="//code.jquery.com/jquery-2.2.0.min.js"></script>
<script src="//code.jquery.com/ui/1.10.2/jquery-ui.js" ></script>
<script type="text/javascript">
$(function() {
$("#autocomplete").autocomplete({
source:function(request, response) {
$.getJSON("{{url_for('autocomplete')}}",{
q: request.term, // in flask, "q" will be the argument to look for using request.args
}, function(data) {
response(data.matching_results); // matching_results from jsonify
});
},
minLength: 2,
select: function(event, ui) {
console.log(ui.item.value); // not in your question, but might help later
}
});
})
</script>
</head>
<body>
<div>
<input name="autocomplete" type="text" id="autocomplete" class="form-control input-lg"/>
</div>
</body>
I haven't implemented a regex but I assumed if I typed anything with at least 2 characters I would get a dropdown of the list I wrote above. However, I get nothing. Any ideas on how I can get this autocomplete to work?

Using initSelection in select2 3.5.2 for custom filtering

I have a text field which uses select2. Here is the initialization:
$("#foo").select2({
createSearchChoice:function(term, data) {
if ($(data).filter(function() {
return this.text.localeCompare(term)===0;
}).length===0)
{return {id:term, text:term};}
},
initSelection : function (element, callback) {
var data = {id: element.val(), text: element.val()};
callback(data);
},
tags:[],
tokenSeparators: [","],
data: [...data goes here...]
});
In this field, the user is supposed to put in a number, or select items from a list. If an item that the user puts in doesn't appear on the list, it ought be created as a simple tag (id and text identical). This works.
What doesn't work is when I set the value programmatically:
myvar.find('.placeholder lorem-ipsum').val(number).trigger("change");
The way it works now, is that when I set it to any value, it takes it without complaint, making a new simple tag. However, if I were to remove the initSelection parameter completely, it would ignore unknown values, and use known values as taken from the list (where tags are complex - id and text are different).
How do I make it so that if the value I set to the field is found on the list, it will use the item, and otherwise make a simple tag? The way it works now (simple tags only) is sort-of acceptable, but I'd prefer it worked ideally.
EDIT:
I've made examples for how it works with and without the initSelection parameter.
http://jppk.byethost12.com/with.html
http://jppk.byethost12.com/without.html
In short, I want it to work like with.html when I push "Add New Item" and I want it to work like without.html when I push "Add Existing Item".
Here is my best interpretation of what you want.
JSFiddle
The trick is to append the element to the select field.
var array = ['foo', 'bar', 'baz']
$.each(array, function(key, value) {
appendSelect(value);
});
$("#foo").select2();
$('#submit').click(function() {
var val = $('#name').val();
$('#name').val('');
array.push(val);
appendSelect(val);
});
function appendSelect(value) {
$('#foo').append($("<option></option>").text(value));
}
<link href="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0-rc.1/css/select2.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0-rc.1/js/select2.min.js"></script>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" rel="stylesheet">
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
<div class='container'>
<select id='foo' multiple="multiple" class='form-control'></select>
<label>Input</label>
<input id='name' />
<button id='submit'>submit</button>
</div>
Much, much later, I found a solution that works right:
initSelection : function (element, callback) {
var eArr = element.val().split(",");
var data = [];
for (var i=0;i<eArr.length;i++) {
for (var j=0;j<preExistingData.length;j++) {
if (preExistingData[j]["id"] === eArr[i]) {
data.push(preExistingData[j]);
continue;
}
}
data.push({id: eArr[i], text: eArr[i]});
}
callback(data);
},
This not only checks if the value is among the pre-existing values (in which case it uses that item), but also if the value is a comma-separated list of values (in which case it properly encapsulates them as JS objects).

Categories