1

I have a working code where I can dynamically add input fields which can be used for auto-completion using AJAX. Though working, there are limitations. After adding more fields, placement of the autofill is incorrect, as demonstrated in this image: enter image description here

The results are not showing under the current input field but rather under the last one. Lastly, once the user adds too many input fields and starts removing them, the autocomplete feature stops working altogether.

HTML Code:

<div class="item form-group">
    <label class="control-label col-md-3 col-sm-3 col-xs-12">Case Category <button style="margin-top: 5px;" id = "add_field" class="add_field btn btn-primary btn-xs">+</button></label>
    <div class="col-md-6 col-sm-6 col-xs-12">   
        <input id="search_keyword_idd" class="search_keywordd form-control col-md-5 col-xs-12" name="category[]" required="required" type="text">
        <input type="hidden" name="catID[]" id="catID"/>
        <div id="resultd"></div>
    </div>
</div>
<div class = "t"></div>

Javascript/jQuery Pt. 1: (on the first input field)

        <script type="text/javascript">
        $(function(){
        $(".search_keywordd").keyup(function() 
        { 
            var search_keyword_value = $(this).val();
            var dataString = 'search_keyword='+ search_keyword_value;
            if(search_keyword_value!='')
            {
                $.ajax({
                    type: "POST",
                    url: "../resources/ajax-search/case_category.php",
                    data: dataString,
                    cache: false,
                    success: function(html)
                        {
                            $("#resultd").html(html).show();
                        }
                });
            }
            return false;    
        });

            jQuery("#resultd").on("click", ".show", function(e){
                var showName = $('.returnName',this).text();
                var showId = $('.returnID',this).text();
                $('#search_keyword_idd').val(showName);
                $('#catID').val(showId);
            });

            jQuery(document).on("click", function(e) { 
                var $clicked = $(e.target);
                if (! $clicked.hasClass("search_keywordd")){
                jQuery("#resultd").hide(); 
                }
            });



            $('#search_keyword_idd').click(function(){
                jQuery("#resultd").show();
            });
        });
    </script>

Javascript/jQuery Pt. 2: (on the input fields that the user want to add)

$(document).ready(function() {
            var max_fields      = 10; //maximum input boxes allowed
            var wrapper3         = $(".t"); //Fields wrapper
            var add_button3      = $("#add_field"); //Add button ID

            var z = 1; //initlal text box count
            $(add_button3).click(function(e){ //on add input button click
                e.preventDefault();

                    if(z < max_fields){ //max input box allowed
                        z++; //text box increment
                        $(wrapper3).append('<div class="item form-group"><label class="control-label col-md-3 col-sm-3 col-xs-12"></label><div class="col-md-6 col-sm-6 col-xs-12"><input id="search_keyword_idd'+z+'" class="search_keywordd'+z+' form-control col-md-5 col-xs-12" name="category['+z+']" required="required" type="text"><input type="hidden" name="catID['+z+']" id="catID'+z+'"/><div id="resultd'+z+'"></div><button class="remove btn btn-dark">Remove</button></div></div>'); //add input box
                        $("#resultd"+z+"").css({"margin-top": "40px", "position": "absolute", "display": "none", "border-top": "0px", "overflow": "visible", "border": "1px #F0F0F0 solid", "float": "left", "padding": "0"});
                        //$(".show"+z+"").css("cursor:", "default", "margin:", "0", "display:", "none", "background:", "#F7F7F7", "width:", "548px", "border-bottom:", "#F0F0F0 1px solid", "position:", "relative", "z-index:", "10");
                    }

                    $(".search_keywordd"+z+"").keyup(function() { 

                        var search_keyword_value = $(this).val();
                        var dataString = 'search_keyword='+ search_keyword_value;
                        if(search_keyword_value!='') {
                            $.ajax({
                                type: "POST",
                                url: "../resources/ajax-search/case_category.php",
                                data: dataString,
                                cache: false,
                                success: function(html)
                                    {
                                        $("#resultd"+z+"").html(html).show();
                                    }
                            });
                        }
                        return false;
                    });

                    jQuery("#resultd"+z+"").on("click", ".show", function(e){
                        var showName = $('.returnName',this).text();
                        var showId = $('.returnID',this).text();
                        $('#search_keyword_idd'+z+'').val(showName);
                        $('#catID'+z+'').val(showId);
                    });


                    jQuery(document).on("click", function(e) { 
                        var $clicked = $(e.target);
                        if (! $clicked.hasClass("search_keyword"+z+"")){
                        jQuery("#resultd"+z+"").hide(); 
                        }
                    });

                    $('#search_keyword_idd'+z+'').click(function(){
                        jQuery("#resultd"+z+"").show();
                    });

                    $(wrapper3).on("click",".remove", function(e){ //user click on remove text
                        e.preventDefault(); $(this).parent('div').parent('div').remove(); y--;
                    });
                });
     });

PHP:

<?php
include('config.php'); //working just fine
if($_POST)
{
    if($_POST['search_keyword']) // returns an error from answer 1
    {
        $similar = mysql_real_escape_string($_POST['search_keyword']);

        $result=mysqli_query($conn, "SELECT * FROM casecategory WHERE (caseCategoryName like '" . $_POST["search_keyword"] . "%')");

        if (mysqli_num_rows($result) > 0) {
            while($row=mysqli_fetch_array($result))
            {

                ?>          
                <div class="show" align="left">
                    <span class="returnName"><?php echo $row["caseCategoryName"] ?></span>
                    <span class="returnID" style="display:none"><?php echo $row['idCaseCategory'];?></span> 
                </div>

            <?php
            }
        }

        else {
            ?>
                <div class="show" align="left">
                    <span class="returnMessage">No matching records found.</span>
                </div>
            <?php
        }

    }



    mysqli_close($conn);
}
?>

I am at a loss as to which part(s) are not working and how to fix it so that:

  1. The auto-complete box displays under the current onfocus input
  2. When max-amount of inputs are added and then removed, that the auto-complete feature still works
5
  • You need to use unique id values. You are probably running into issues there. Commented Mar 5, 2016 at 15:08
  • Hi. What do you mean unique id values? In the php part? Commented Mar 5, 2016 at 15:10
  • Hmm actually you I thought I saw you had some same id values but after closer inspection I think you have unique Ids, provided they are working. Commented Mar 5, 2016 at 15:12
  • Yes it's working but not efficient tho. :/ Commented Mar 5, 2016 at 15:17
  • Doesn't your Ajax return the block using is line $("#resultd").html(html).show();? If so that is why it stays where it does. I populates the same container. Commented Mar 5, 2016 at 20:57

1 Answer 1

2

See if this is what you are looking for. The HTML appears to be correct when looking at the console, but I don't have your css, so it's hard to say. The changes:

1) I have removed all the id values in favor of using just classes. That way you don't have to worry about id values...what works for a static block of html, will work for a dynamic block so note all the changes in the html

2) I have consolidated all js to just what I have pasted below

3) There is only one instance of ajax

4) All clicks are relegated to one if/else/else if condition:

<div class="item form-group">
    <label class="control-label col-md-3 col-sm-3 col-xs-12">Case Category <button style="margin-top: 5px;" class="add_field btn btn-primary btn-xs">+</button></label>
    <div class="col-md-6 col-sm-6 col-xs-12 search_wrap">   
        <input class="search_keyword form-control col-md-5 col-xs-12" name="category[]" required="required" type="text">
        <input type="text" name="catID[]" />
        <div class="resultd"></div>
    </div>
</div>
<div class = "t"></div>

Javascript

<script type="text/javascript">
// I have created an ajax instance incase you want to use ajax else where
// You just make a new instance instead of copy/pasting same scripts
var AjaxEngine  =   function()
    {
        $       =   arguments[0];
        var url =   '../resources/ajax-search/case_category.php';
        // Allows you to use a different destination for the call
        this.useUrl =   function()
            {
                if(arguments.length === 1) {
                    url =   arguments[0];
                }

                return this;
            };

        this.ajax   =   function(data,userFunc)
            {
                $.ajax({
                    type: "POST",
                    url: url,
                    // Send data object instead of string
                    data: data,
                    cache: false,
                    // Not hardcoding a response will allow
                    // for flexibility
                    success: function(response) {
                        userFunc(response);
                    }
                });
            }
    }
// I just created a php-like empty function
function empty(val)
    {
        return (val !== null && val !== false && val !== '')? false : true;
    }
// Group everything into one document ready
$(function(){
    // Hide dropdown
    $(this).click(function(e) {
        var target  =   $(e.target);
        if(!target.hasClass('resultd')) {
            $('.resultd').hide();
        }
    });
    // Create ajax engine
    var Remote  =   new AjaxEngine(jQuery);
    // run the keyword search, I would use this here so you can 
    // get all instances of keyup, both dynamic and static instances
    $(this).on('keyup',".search_keyword",function(e){
        var sTerm       =   $(this).val();
        var thisWrap    =   $(this).parents('.form-group').find('.resultd');
        if(!empty(sTerm)) {
            Remote.ajax({ search_word:sTerm },function(response) {
                thisWrap.html(response).show();
            });
        }
    });
    // Create the copy-to function
    function copyTo(thisShow)
        {
            var showName    =   thisShow.find('.returnName').text();
            var showId      =   thisShow.find('.returnID').text();
            var thisWrap    =   thisShow.parents('.search_wrap').find('input[name=category\\[\\]]');
            thisWrap.val(showName);
            thisWrap.next().val(showId);
        };
    // Create the add field function
    function addNewField(obj,max_fields,z)
        {
            if(z < max_fields){
                obj.append('<div class="item form-group"><label class="control-label col-md-3 col-sm-3 col-xs-12"></label><div class="col-md-6 col-sm-6 col-xs-12 search_wrap"><input class="search_keyword search_keywordd form-control col-md-5 col-xs-12" name="category[]" required="required" type="text"><input type="text" name="catID[]" /><div class="resultd"></div><button class="remove btn btn-dark">Remove</button></div></div>'); //add input box
                var lastRes =   obj.find(".resultd");

                lastRes.last().css({"margin-top": "40px", "position": "absolute", "display": "none", "border-top": "0px", "overflow": "visible", "border": "1px #F0F0F0 solid", "float": "left", "padding": "0"});
                z++;
                // return the auto-increment count
                return z;
            }
            // return the max count
            return max_fields;
        }

    var settings    = {
            z: 1,
            max_fields: 10
        }

    $(this).on("click", '.show,.search_keyword,.add_field,.remove', function(e) {
        // Target the click
        var clicked = $(this);
        // Hide by default
        $(".resultd").hide();
        // Run the copyto
        if(clicked.hasClass("show")) {
            copyTo(clicked);
        }
        // Show the search window
        else if(clicked.hasClass("search_keyword")) {
            clicked.parents('.search_wrap').find('.resultd').show();
        }
        // Add fields
        else if(clicked.hasClass("add_field")) {
            settings.z  =   addNewField($(".t"),settings.max_fields,settings.z);
        }
        // remove fields
        else if(clicked.hasClass("remove")) {
            e.preventDefault();
            clicked.parent('div').parent('div').remove();
            settings.z--;
        }
    });
});
</script>
Sign up to request clarification or add additional context in comments.

5 Comments

Hi thank you for this!!! I tried your code and it doesn't seem to return any values from the database. I mean whenever I type something, an error returns: Notice: Undefined index: search_keyword in C:\Users\Admin\Documents\USBWebserver v8.6\root\resources\ajax-search\case_category.php on line 5 I will comment out in the PHP CODE part where the error is coming from.
That's because I changed it to search_word. I shortened it, sorry should have mentioned it
[i am literally screaming right now because... ] YOU SOLVED MY PROBLEM HOLY ADLSKADJDLA HOW THE DAJSDLASJDA YOU SOLVED MY PROBLEM I HAVE BEEN WORRYING ABOUT THIS FOR 6 DAYS. IT'S WORKING AND IT'S NOW EFFICIENT AS HELL!!!! I cannot thank you enough for this. Thank you thank you!!!!!!
No problem, glad I could help. Make sure to mark you mark the question answered. Cheers! Click the check mark.
Yes, I did it!!! Yayyy thank you i really thought no one would answer this question. Anyway, thanks again! Cheers!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.