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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With