我正在使用JQuery自动完成功能。在这种情况下,我要避免重复选择预选和预定位(预取)列表。
以下脚本适用于当前选择的列表。但是,我该如何使用通过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);
答案 0 :(得分:2)
我建议在Js中使用一个数组,您可以在其中放入预选的数组。然后使用它来验证是否尚未将其推入其中,然后可以将其添加到您的dom中。
因此在js中,您会遇到
var selected = [<?= !empty($selected) ? '"'.implode('","', $selected).'"' : '' ?>];
脚本的第一行代码中的上面的代码使数组为空,或者如果选择的不为空,则已经选择
然后您可以使用它来检查是否选择了一个项目。同样最好在PHP中使用$selected = array_map('strtolower', $selected);
(根据您的代码)
编辑
<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>
如果将js加载为外部文件,请不要担心。只要确保定义
<script>
var selected = [<?= !empty($selected) ? '"'.implode('","', $selected).'"' : '' ?>];
</script>
之前。
答案 1 :(得分:0)
更新的答案: 因为您更改了HTML,所以解决方案可能基于:
if ($('.selected:contains(' + value + ')').length == 0) {
更新的代码段:
$(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>
尝试选择火种,仅用于测试。
旧答案:
第一个问题:您在每个焦点事件上初始化自动完成功能!请避免将其初始化多次。
如果我理解正确,您想从自动完成列表中删除具有预选学生列表之一的值的元素。 如果是这样,您可以在 choices.push({一个测试:
if ($('.selected:text[value="' + item.name + '"]').length == 0) {
完整代码:
$(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()
});
});