Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

autocomplete How to avoid duplicate selection

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);
like image 696
Mili Avatar asked Dec 07 '25 10:12

Mili


1 Answers

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.

like image 65
Saeed.Gh Avatar answered Dec 09 '25 23:12

Saeed.Gh



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!