I'm new to JQuery and jQuery UI.
I'm using autocomplete with remote json in a table with dynamically rows.
The problem is: everything works, but for some reasons, the input code isn't filled.
The curious thing is that if I hardcode #code0 or #code1 in select area, it works.
But it seem #code+i isn't recognized in select. Another strange thing is $("#product"+i) works.
Can someone help a JS beginner?
$(document).ready(function(){
var i=0;
$("#add_row").click(function(){
$('#addr'+i).html("<td>"+ (i+1) +"<\/td><td><input id='product"+i+"' name='product"+i+"' type='text' placeholder='Digita il codice o il nome del prodotto' class='form-control input-md' /> <\/td><td><input id='code"+i+"' name='code"+i+"' type='text' placeholder='Codice' class='form-control' readonly='readonly'><\/td>");
$('#tab_logic').append('<tr id="addr'+(i+1)+'"><\/tr>');
$("#product"+i).autocomplete({
source: function( request, response ) {
$.ajax({
url: "productsearch.php",
dataType: "json",
data: {term: request.term},
success: function(data) {
response($.map(data, function(item) {
return {
label: item.text,
id: item.id,
code: item.id
};
}));
}
});
},
minLength: 2,
select: function(event, ui) {
var codice="$code"+i;
$('#codice').val(ui.item.id);
}
});
i++;
});
$("#delete_row").click(function(){
if(i>1){
$("#addr"+(i-1)).html('');
i--;
}
});
$("#product"+i).autocomplete({
source: function( request, response ) {
$.ajax({
url: "productsearch.php",
dataType: "json",
data: {term: request.term},
success: function(data) {
response($.map(data, function(item) {
return {
label: item.text,
id: item.id,
code: item.id
};
}));
}
});
},
minLength: 2,
select: function(event, ui) {
$("#code"+i).val(ui.item.id);
}
});
i++;
});
});
<tbody>
<tr id='addr0'>
<td>1</td>
<td><input id="product0" type="text" name='product0' placeholder='Digita il codice o il nome del prodotto' class="form-control"></td>
<td><input id="code0" type="text" name='code0' placeholder='Codice' class="form-control" readonly="readonly"></td>
</tr>
<tr id='addr1'>
</tr>
One thing for sure is that in your select event handler on the first autocomplete, you have a bug:
select: function(event, ui) {
var codice="$code"+i;
$('#codice').val(ui.item.id);
}
You create a variable for the jquery selector and then don't use it. You can't update your input value whose id is "code"+i with this function. Instead, it needs to be:
select: function(event, ui) {
var codice="#code"+i;
$(codice).val(ui.item.id);
}
Fix that and see if your problem goes away.
I've solved by adding a new var count=0; at the top.
Now I use:
$("[id^=code]:eq( " + count + " ) ").val(ui.item.id);
the problem is the variable i
Thank you everyone for the help
select: function(event, ui) {
$("[id^=code]:eq( " + count + " ) ").val(ui.item.id);
}
});
i++;
count++;
});
Related
This is my coding
$("#txtBox").autocomplete({
source: function (request, response) {
$.ajax({
type: "POST",
url: '#Url.Action("Get", "Ctrl")',
dataType: 'json',
data: "{ 'mode': 'associate','prefix': '" + request.term + "' }",
contentType: "application/json;charset=utf-8",
success: function (data) {
var transformed = $.map(data, function (item) {
return {
label: item.Name,
value: item.Id
};
});
response(transformed);
},
error: function() {
alert('error');
},
});
},
minLength: 3,
select: function (event, ui) {
console.log('ui.item.label', ui.item.label);
$('#txtBox').val(ui.item.label);
},
focus: function (event, ui) {
console.log('ui.item.label - focus', ui.item.label);
$('#txtBox').val(ui.item.label);
}
});
});
I am getting Name and Id from c# controller as Json. I want to the auto complete textbox to display Name and while sending it back to backend while saving, I wanted to send the Id of the Name. But now when I type the name and select the name from the list of suggestions. The Id gets displayed in the text box instead of name.Where am i making the mistake. Can some one guide me on this.
I would suggest you to keep two <input /> one type=text and other type=hidden. You can initialize autocomplete on the type=text, and set the value in type=hidden and in server you can access the value of type hidden.
e.g.
<input type="text" id="txtBox" name="label" />
<input type="hidden" id="valBox" name="value" />
$("#txtBox").autocomplete({
source: function (request, response) {
$.ajax({
type: "POST",
url: '#Url.Action("Get", "Ctrl")',
dataType: 'json',
data: "{ 'mode': 'associate','prefix': '" + request.term + "' }",
contentType: "application/json;charset=utf-8",
success: function (data) {
var transformed = $.map(data, function (item) {
return {
label: item.Name,
value: item.Id
};
});
response(transformed);
},
error: function() {
alert('error');
},
});
},
minLength: 3,
select: function (event, ui) {
console.log('ui.item.label', ui.item.label);
$('#txtBox').val(ui.item.label);
$('#valBox').val(ui.item.value);
},
focus: function (event, ui) {
console.log('ui.item.label - focus', ui.item.label);
$('#txtBox').val(ui.item.label);
}
});
});
In your controller, you can access both values Request["label"], Request["value"]
I am using JQuery autocomplete. In which i want to avoid duplicate selection of pre-selected and pre-located (pre fetched) list.
The following script works with currently selected list. But how can I do it with pre-located list which are fetched with document onload.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
JS
$(document).on('focus','.search',function(){
let type = $(this).data('type');
$(this).autocomplete({
source: function( request, response ) {
$.ajax({
url : 'autocomplete.php',
dataType: "json",
method: 'post',
data: {
name_startsWith: request.term,
type: type
},
success: function( data ) {
let selected = [],
uniques = [],
choices = [];
$('tr .search[id^="name_"]').each(function(){
let value = this.value.trim().toLowerCase();
if (value && selected.indexOf(value) < 0) {
selected.push(value);
}
});
data.forEach(item => {
let value = item.name.trim().toLowerCase();
if (uniques.indexOf(value) < 0 && selected.indexOf(value) < 0) {
choices.push({
label: item.name,
value: item.name,
data: item,
type: 'name'
});
uniques.push(value);
}
});
response(choices);
}
});
},
autoFocus: true,
minLength: 1,
select: function( event, ui ) {
// Strips the 'team_' part, leaving just the number.
let id_num = $(this).attr('id').substring(5);
$(this).val(ui.item.value);
$('#id_' + id_num).val(ui.item.data.id).change();
$('#marks_' + id_num).val(ui.item.data.marks);
$(this).attr('data-type', ui.item.type);
return false;
},
appendTo: $(this).parent()
});
});
HTML
<table class="table table-bordered table-hover" id="pat_tests">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Marks</th>
</tr>
</thead>
<tbody>
<tr>
<td> <input type="number" id="id_1"> </td>
<td><input type="text" id="name_1" class="search" data-type="type"></td>
<td><input type="number" id="marks_1" ></td>
</tr>
<tr>
<td> <input type="number" id="id_2"> </td>
<td><input type="text" id="name_2" class="search" data-type="type"></td>
<td><input type="number" id="marks_2" ></td>
</tr>
<tr>
<td> <input type="number" id="id_3"> </td>
<td><input type="text" id="name_3" class="search" data-type="type"></td>
<td><input type="number" id="marks_3" ></td>
</tr>
</tbody>
</table>
<h2>Pre Selected List of Students</h2>
<p class="selected">Mario</p>
<p class="selected">Nico"</p>
<p class="selected">Mento</p>
PHP
if(!empty($_POST['type'])){
$type = $_POST['type'];
$name = $_POST['name_startsWith'];
$query = $db->prepare("SELECT id, name, marks FROM class where (name LIKE '".$name."%') ");
$query->execute();
$data = array();
$i = 0;
while ($row = $query->fetch(PDO:: FETCH_ASSOC)) {
$data[$i]['id'] = $row['id'];
$data[$i]['name'] = $row['name'];
$data[$i]['marks'] = $row['marks'];
++$i;
}
echo json_encode($data);
I recommend to use an array in Js, you can put preselected in it. and then use it to verify if not selected already push in it then you can add to your dom.
so in js you would have something like
var selected = [<?= !empty($selected) ? '"'.implode('","', $selected).'"' : '' ?>];
above code in firs line of script make an array of empty or already selected if selected is not empty
then you can use it to check if an item is selected or not. also it's better to use $selected = array_map('strtolower', $selected); before in php (according to your code)
EDIT
<script type="text/javascript">
//in case you have php array of already selected items. remove it if $selected is not provided in php.
//var selected = [<?= !empty($selected) ? '"'.implode('","', $selected).'"' : '' ?>];
var selected = [];
$(".selected").each(function(index, value){
selected.push($(this).text().trim().toLowerCase());
});
$(document).on('focus', '.search', function (e) {
let type = $(this).data('type');
$(this).autocomplete({
source: function (request, response) {
$.ajax({
url: 'your url',
dataType: "json",
method: 'post',
data: {
name_startsWith: request.term,
type: type
},
success: function (data) {
let uniques = [],
choices = [];
data.forEach(function (item) {
let value = item.name.trim().toLowerCase();
if (uniques.indexOf(value) < 0 && selected.indexOf(value) < 0) {
choices.push({
label: item.name,
value: item.name,
data: item,
type: 'name'
});
uniques.push(value);
}
});
response(choices);
}
});
},
autoFocus: true,
minLength: 1,
select: function (event, ui) {
// Strips the 'team_' part, leaving just the number.
let id_num = $(this).attr('id').substring(5);
$(this).val(ui.item.value);
$('#id_' + id_num).val(ui.item.data.id).change();
$('#marks_' + id_num).val(ui.item.data.marks);
$(this).attr('data-type', ui.item.type);
selected.push(ui.item.value.trim().toLowerCase());
return false;
},
appendTo: $(this).parent()
});
});
</script>
dont wory if you load js as an external file. just make sure define
<script>
var selected = [<?= !empty($selected) ? '"'.implode('","', $selected).'"' : '' ?>];
</script>
before it.
Updated answer:
Because you changed your HTML a solution could be based on:
if ($('.selected:contains(' + value + ')').length == 0) {
The updated snippet:
$(document).on('focus', '.search', function (e) {
let type = $(this).data('type');
$(this).autocomplete({
source: function (request, response) {
$.ajax({
url: 'https://api.github.com/repositories?since=364',
dataType: "json",
method: 'get',
data: {
name_startsWith: request.term,
type: type
},
success: function (data) {
data = data.map((a) => ({name: a.name || ''})).filter((e) => e.name.indexOf('_') == -1);
let selected = [],
uniques = [],
choices = [];
$('tr .search[id^="name_"]').each(function () {
let value = this.value.trim().toLowerCase();
if (value && selected.indexOf(value) < 0) {
selected.push(value);
}
});
data.forEach(function (item) {
let value = item.name.trim().toLowerCase();
if (uniques.indexOf(value) < 0 && selected.indexOf(value) < 0) {
if ($('.selected:contains(' + value + ')').length == 0) {
choices.push({
label: item.name,
value: item.name,
data: item,
type: 'name'
});
uniques.push(value);
}
}
});
response(choices);
}
});
},
autoFocus: true,
minLength: 1,
select: function (event, ui) {
// Strips the 'team_' part, leaving just the number.
let id_num = $(this).attr('id').substring(5);
$(this).val(ui.item.value);
$('#id_' + id_num).val(ui.item.data.id).change();
$('#marks_' + id_num).val(ui.item.data.marks);
$(this).attr('data-type', ui.item.type);
return false;
},
appendTo: $(this).parent()
});
});
<link href="https://code.jquery.com/ui/1.12.0/themes/smoothness/jquery-ui.css" rel="stylesheet"/>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.0/jquery-ui.js"></script>
<table class="table table-bordered table-hover" id="pat_tests">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Marks</th>
</tr>
</thead>
<tbody>
<tr>
<td> <input type="number" id="id_1"> </td>
<td><input type="text" id="name_1" class="search" data-type="type"></td>
<td><input type="number" id="marks_1" ></td>
</tr>
<tr>
<td> <input type="number" id="id_2"> </td>
<td><input type="text" id="name_2" class="search" data-type="type"></td>
<td><input type="number" id="marks_2" ></td>
</tr>
<tr>
<td> <input type="number" id="id_3"> </td>
<td><input type="text" id="name_3" class="search" data-type="type"></td>
<td><input type="number" id="marks_3" ></td>
</tr>
</tbody>
</table>
<h2>Pre Selected List of Students</h2>
<p class="selected">invisible</p>
<p class="selected">tinder</p>
<p class="selected">ike</p>
Try to select tinder, just for a test.
Old answer:
First issue: you initialize the autocomplete on every focus event! Please, avoid to initialize it more times.
If I understood correctly, you want to remove from the autocomplete list elements having a value already contained in one of the Pre Selected List of Students.
If so, you can add, before the choices.push({ a test:
if ($('.selected:text[value="' + item.name + '"]').length == 0) {
Full code:
$(document).on('focus', '.search', function (e) {
let type = $(this).data('type');
$(this).autocomplete({
source: function (request, response) {
$.ajax({
url: 'your url',
dataType: "json",
method: 'post',
data: {
name_startsWith: request.term,
type: type
},
success: function (data) {
let selected = [],
uniques = [],
choices = [];
$('tr .search[id^="name_"]').each(function () {
let value = this.value.trim().toLowerCase();
if (value && selected.indexOf(value) < 0) {
selected.push(value);
}
});
data.forEach(function (item) {
let value = item.name.trim().toLowerCase();
if (uniques.indexOf(value) < 0 && selected.indexOf(value) < 0) {
if ($('.selected:text[value="' + item.name + '"]').length == 0) {
choices.push({
label: item.name,
value: item.name,
data: item,
type: 'name'
});
uniques.push(value);
}
}
});
response(choices);
}
});
},
autoFocus: true,
minLength: 1,
select: function (event, ui) {
// Strips the 'team_' part, leaving just the number.
let id_num = $(this).attr('id').substring(5);
$(this).val(ui.item.value);
$('#id_' + id_num).val(ui.item.data.id).change();
$('#marks_' + id_num).val(ui.item.data.marks);
$(this).attr('data-type', ui.item.type);
return false;
},
appendTo: $(this).parent()
});
});
I want to accomplish to implement a message when user search a query that it is not in the list to show No Search Found. I tried using
$('#searchTextField').html(" NO SEARCH FOUND");
but it is not working. Does anyone know how to solve this with my code below? Thanks for the help.
Here is my code:
$(function () {
var myData = [];
myData.push("NO SEARCH FOUND");
$.get("http://localhost:8080/myApp/JobSearchItem.xhtml", function (data) {
$("#searchTextField").autocomplete({
minLength: 2,
source: myData,
}).val('NO SEARCH FOUND').data('autocomplete')._trigger('select');
$.each(data, function (k, v) {
myData.push({
id: v.id,
label: v.label,
value: v.id
});
});
});
});
html
<form id="searchForm" >
<input type="text" name="searchValue" id="searchTextField" class="form-control"
placeholder="search"/>
<button type="submit" class="btn btn-primary" >Search</button>
</form>
Hi I think you are looking for if no match found it should be shown in dropdown. so you need to update your code something like this.
$(function() {
$("#userInput").autocomplete({
source: function(request, response) {
$.ajax({
url: "http://api.stackexchange.com/2.1/users", // update with your url
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; // return your value which is coming from ajax response
}));
}
});
},
minLength: 1,
response: function(event, ui) {
if (!ui.content.length) {
var message = { value:"",label:"No results found" };
ui.content.push(message);
}
}
});
});
<label for="userInput">Search StackOverflow user:</label>
<input id="userInput" type="text" />
Please check with working fiddle
I'm having an issue using jQuery autocomplete with dynamically created inputs (again created with jQuery). I can't get autocomplete to bind to the new inputs.
Autocomplete
$("#description").autocomplete({
source: function(request, response) {
$.ajax({
url: "../../works_search",
dataType: "json",
type: "post",
data: {
maxRows: 15,
term: request.term
},
success: function(data) {
response($.map(data.works, function(item) {
return {
label: item.description,
value: item.description
}
}))
}
})
},
minLength: 2,
});
New table row with inputs
var i = 1;
var $table = $("#works");
var $tableBody = $("tbody",$table);
$('a#add').click(function() {
var newtr = $('<tr class="jobs"><td><input type="text" name="item[' + i + '][quantity]" /></td><td><input type="text" id="description" name="item[' + i + '][works_description]" /></td></tr>');
$tableBody.append(newtr);
i++;
});
I'm aware that the problem is due to the content being created after the page has been loaded but I can't figure out how to get around it. I've read several related questions and come across the jQuery live method but I'm still in a jam!
Any advice?
First you'll want to store the options for .autocomplete() like :
var autocomp_opt={
source: function(request, response) {
$.ajax({
url: "../../works_search",
dataType: "json",
type: "post",
data: {
maxRows: 15,
term: request.term
},
success: function(data) {
response($.map(data.works, function(item) {
return {
label: item.description,
value: item.description
}
}))
}
})
},
minLength: 2,
};
It's more neat to use the class attribute for marking the input, like:
<input type="text" class="description" name="item[' + i + '][works_description]" />
Last, when you create a new table row apply the .autocomplete() with the options already stored in autocomp_opt:
$('a#add').click(function() {
var newtr = $('<tr class="jobs"><td><input type="text" name="item[' + i + '][quantity]" /></td><td><input type="text" class="description" name="item[' + i + '][works_description]" /></td></tr>');
$('.description', newtr).autocomplete(autocomp_opt);
$tableBody.append(newtr);
i++;
});
I found that I needed to put teh autocomplete after the append so:
$tableBody.append(newtr);
$('.description', newtr).autocomplete(autocomp_opt);
using this plugin
https://github.com/aehlke/tag-it
its very cool by the way.
problem:
<input type="hidden" name="tags" id="mySingleField" value="Apple, Orange" disabled="true">
Tags:<br>
<ul id="mytags"></ul>
<script type="text/javascript">
$(document).ready(function () {
$("#mytags").tagit({
singleField: true,
singleFieldNode: $('#mySingleField'),
allowSpaces: true,
minLength: 2,
removeConfirmation: true,
tagSource: function (request, response) {
//console.log("1");
$.ajax({
url: "../City/GetList",
data: { term: request.term },
dataType: "json",
success: function (data) {
response($.map(data, function (item) {
return {
label: item.label + " (" + item.id + ")",
value: item.value
}
}));
}
});
}
});
});
</script>
When tag it selects the values it adds values to the hidden field in CSV format in value attr. i want it to do ID instead anyone know how to ?
A couple of things here. You can set the delimeter instead of a CSV to anything by setting the parameter as such say to an underscore:
$("#mytags").tagit({
...
singleFieldDelimiter: '_',
...
Then you can modify the tag-it.js file on line 197 to say use the ID attribute.
Change:
var tags = node.val().split(this.options.singleFieldDelimiter);
To be
var tags = node.attr("id").split(this.options.singleFieldDelimiter);
So let's say that you modified the hidden field to be:
<input type="hidden" name="tags" class="mySingleField" id="Apple_Orange_Banana" value="Apple_Orange" disabled="true">
You would modify the javascript as such to get the desired output:
$(document).ready(function () {
$("#mytags").tagit({
singleField: true,
singleFieldNode: $('.mySingleField'),
singleFieldDelimiter: '_',
allowSpaces: true,
minLength: 2,
removeConfirmation: true,
tagSource: function (request, response) {
//console.log("1");
$.ajax({
url: "../City/GetList",
data: { term: request.term },
dataType: "json",
success: function (data) {
response($.map(data, function (item) {
return {
label: item.label + " (" + item.id + ")",
value: item.value
}
}));
}
});
}
});
});
Change the tag-it.js file
Comment from line 264
// that.createTag(that._cleanedInput());
// The autocomplete doesn't close automatically when TAB is pressed.
// So let's ensure that it closes.
// that.tagInput.autocomplete('close');
around line 285
var autocompleteOptions = {
select: function(event, ui) {
that.createTag(ui.item);
Create a new function
assignedTagsData: function(){
// Only to be used when singleField option is not seleted
var tags = [];
this.tagList.children('.tagit-choice').each(function() {
tags.push($(this).data('tag_item_data') );
});
return tags;
}
that.createTag(ui.item);
Create tag
var tag = $('<li></li>')
.data('tag_item_data',item) //add this line
.addClass('tagit-choice ui-widget-content ui-state-default ui-corner-all')
.addClass(additionalClass)
.append(label);