Adeel Raza Azeemi
Adeel Raza Azeemi

Reputation: 823

Autocomplete from remote datasource doesn't give any suggestions

Autocomplete suggestion are narrowed based on the form. Thing is I am able to send filter(s) to the server; which also gives the correct output but it does not end up as suggestions (autocomplete) in the textarea.

<!doctype html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Combined</title>
        <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
        <style>
            .ui-autocomplete-category {
                font-weight: bold;
                padding: .2em .4em;
                margin: .8em 0 .2em;
                line-height: 1.5;
            }

            .ui-autocomplete {
                max-height: 100px;
                overflow-y: auto;
                /* prevent horizontal scrollbar */
                overflow-x: auto;
            }

            .ui-autocomplete-loading {
                background: white url("../img/ui-anim.gif") right center no-repeat;
            }
        </style>
        <script src="https://code.jquery.com/jquery-1.12.4.js"></script>
        <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
        <script>
            $(function () {
                $.widget("custom.catcomplete", $.ui.autocomplete, {
                    _create: function () {
                        this._super();
                        this.widget().menu("option", "items", "> :not(.ui-autocomplete-category)");
                    },
                    _renderMenu: function (ul, items) {
                        var that = this,
                                currentCategory = "";
                        $.each(items, function (index, item) {
                            var li;
                            if (item.event != currentCategory) {
                                ul.append("<li class='ui-autocomplete-category'>" + item.event + "</li>");
                                currentCategory = item.event;
                            }
                            /* li = that._renderItemData(ul, item);
                             if (item.event) {
                             li.attr("aria-label", item.event + " : " + item.label);
                             } */
                            $("<li></li>")
                                    .data("ui-autocomplete-item", item)
                                    .append('<a href="javascript:;"><input type="checkbox"/>' + item.label + '</a>')
                                    .appendTo(ul);
                        });
                    }
                });

                $("#trade").catcomplete({
                    delay: 0,
                    source: function (request, response) {
                        $.ajax({
                            type: "POST",
                            url: "tmp3.php",
                            data: {
                                trade: request.term,
                                trainingID: $('form[name=searchTraining] input[name=trainingID]').val(),
                                totalParticipants: $('form[name=searchTraining] input[name=totalParticipants]').val(),
                                male: $('form[name=searchTraining] input[name=male]').val(),
                                female: $('form[name=searchTraining] input[name=female]').val(),
                                district: $('form[name=searchTraining] input[name=district]').val(),
                                project: $('form[name=searchTraining] input[name=project]').val(),
                                fromDate: $('form[name=searchTraining] input[name=fromDate]').val(),
                                toDate: $('form[name=searchTraining] input[name=toDate]').val(),
                                rPerson: $('form[name=searchTraining] input[name=rPerson]').val()
                            },
                            success: response,
                            dataType: 'json',
                            minLength: 1
                        });
                    }
                });

            });
        </script>
    </head>
    <body>

        <form name="searchTraining">
            <div class="ui-widget">
                <label for="search">Search: </label>
                <textarea class="tradeF" name='trade' id='trade' placeholder="Trade" autocomplete="on" pattern="[a-zA-Z ]+" size="21" ></textarea>
            </div>

            <input pattern="[0-9]+" placeholder="Training ID" name="trainingID" size="1" class="idF" type="text" title="TrainingID">
            <input autocomplete="on" pattern="[0-9]+" placeholder="Total" name="totalParticipants" size="3" type="text" class="totalF">
            <input autocomplete="on" pattern="[0-9]+" placeholder="Male" name="male" size="3" type="text" class="maleF">
            <input autocomplete="on" pattern="[0-9]+" placeholder="Female" name="female" size="3" type="text" class="femaleF">
            <input autocomplete="on" pattern="[a-zA-Z ]+" placeholder="District" name="district" size="3" type="text">
            <input autocomplete="on" pattern="[a-zA-Z ]+" placeholder="Project" name="project" size="3" type="text" value="kfw">
            From<input name="fromDate" size="3" type="text"><br />To<input name="toDate" size="3" type="text">
            <input autocomplete="on" pattern="[a-zA-Z ]+" placeholder="Venue" name="venue" size="3" type="text">
            <input autocomplete="on" pattern="[a-zA-Z ]+" placeholder="Resource Person" name="rPerson" size="3" type="text">
            <input type="hidden" name="defaulter" value="true" />
            <input type="hidden" name="questItem" value="" />
        </form>
    </body>
</html>

FYI: Server response is

[{event:'Commercial',label:'Adda Work'},
{event:'Commercial',label:'Alternative Dispute Resolution'},
{event:'Commercial',label:'Auto Electrician'},
{event:'Commercial',label:'Beautician'},
{event:'Staff',label:'Youth Activits Training'}]

I donot know where i am doing wrong But i had narrow it down to the $("#trade").catcomplete code block.

Answering to the twisty comment. We don't needs a div wrapper for li. the following code will prove it. It basically the same except it doesn't uses remote data source.

<!doctype html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>jQuery UI Autocomplete - Categories</title>
        <link rel="stylesheet" href="../../res/jquery/jquery-ui/jquery-ui-1.12.1/jquery-ui.css">
        <style>
            .ui-autocomplete-category {
                font-weight: bold;
                padding: .2em .4em;
                margin: .8em 0 .2em;
                line-height: 1.5;
            }

            .ui-autocomplete {
                max-height: 600px;
                overflow-y: auto;
                /* prevent horizontal scrollbar */
                overflow-x: auto;
            }

            .ui-autocomplete-loading {
                background: white url("../img/ui-anim.gif") right center no-repeat;
            }
        </style>
        <script src="../../res/jquery/jquery1.x/jquery-1.12.4.js"></script>
        <script src="../../res/jquery/jquery-ui/jquery-ui-1.12.1/jquery-ui.js"></script>
        <script>
            $(function () {
                $.widget("custom.catcomplete", $.ui.autocomplete, {
                    _create: function () {
                        this._super();
                        this.widget().menu("option", "items", "> :not(.ui-autocomplete-category)");
                    },
                    _renderMenu: function (ul, items) {
                        var that = this,
                                currentCategory = "";
                        $.each(items, function (index, item) {
                            var li;
                            if (item.event != currentCategory) {
                                ul.append("<li class='ui-autocomplete-category'>" + item.event + "</li>");
                                currentCategory = item.event;
                            }
                            $("<li></li>")
                                    .data("ui-autocomplete-item", item)
                                    .append('<a href="javascript:;"><input type="checkbox"/>' + item.label + '</a>')
                                    .appendTo(ul);
                        });
                    }
                });

                var data = [{event: 'Community', label: 'Agriculture Ex Worker (AEW)'},
                    {event: 'Community', label: 'BMT Trainings for CRPs'},
                    {event: 'Community', label: 'Carpentry'},
                    {event: 'Community', label: 'Fruits & Forest Nursery (Production & Marketting)'},
                    {event: 'Community', label: 'Heavy Machinery Excavator'},
                    {event: 'Community', label: 'Masonry'},
                    {event: 'Community', label: 'Mobile Repairing'},
                    {event: 'Community', label: 'Motor Cycle Repairing'},
                    {event: 'Community', label: 'Operation & Maintenance'},
                    {event: 'Community', label: 'Solar Panel Installation'},
                    {event: 'Community', label: 'Tailoring & Embroidery'},
                    {event: 'Staff', label: 'Engineers Training'},
                    {event: 'Staff', label: 'Engineers Training (Solar Panal)'},
                    {event: 'Staff', label: 'FATA Engineers Meeting'},
                    {event: 'Staff', label: 'FATA Projects Review Meeting'},
                    {event: 'Staff', label: 'Staff Orientation'}];

                $("#trade").catcomplete({
                 delay: 0,
                 source: data
                 });

            });
        </script>
    </head>
    <body>

        <form name="searchTraining">
            <div class="ui-widget">
                <label for="search">Search: </label>
                <textarea class="tradeF" name='trade' id='trade' placeholder="Trade" autocomplete="on" pattern="[a-zA-Z ]+" size="21" ></textarea>
            </div>

            <input pattern="[0-9]+" placeholder="Training ID" name="trainingID" size="1" class="idF" type="text" title="TrainingID">
            <input autocomplete="on" pattern="[0-9]+" placeholder="Total" name="totalParticipants" size="3" type="text" class="totalF">
            <input autocomplete="on" pattern="[0-9]+" placeholder="Male" name="male" size="3" type="text" class="maleF">
            <input autocomplete="on" pattern="[0-9]+" placeholder="Female" name="female" size="3" type="text" class="femaleF">
            <input autocomplete="on" pattern="[a-zA-Z ]+" placeholder="District" name="district" size="3" type="text">
            <input autocomplete="on" pattern="[a-zA-Z ]+" placeholder="Project" name="project" size="3" type="text" value="kfw">
            From<input name="fromDate" size="3" type="text"><br />To<input name="toDate" size="3" type="text">
            <input autocomplete="on" pattern="[a-zA-Z ]+" placeholder="Venue" name="venue" size="3" type="text">
            <input autocomplete="on" pattern="[a-zA-Z ]+" placeholder="Resource Person" name="rPerson" size="3" type="text">
            <input type="hidden" name="defaulter" value="true" />
            <input type="hidden" name="questItem" value="" />
        </form>
    </body>
</html>

the above code works i.e. autocomplete suggestion do show up. but it is basically useless for me because the source of the autocomplete is static where as mine requirement is it to be generated dynamically.

As far as the what javascript code will pop up is later issue (which code is not included above).

Thanks for the comments anyway.

Upvotes: 0

Views: 361

Answers (2)

Adeel Raza Azeemi
Adeel Raza Azeemi

Reputation: 823

The problem was as I suspected minor and cryptic coding of JavaScript. When I created the Json array in php I used quote instead of double quote. i.e.

"{'event':'Community','label':'Agriculture'}" 

instead i should had used

'{"event":"Community","label":"Agriculture"}' 

when i reverse quote with double quote it worked like a charm. btw: @twisty thanks for helping me along the way.

Upvotes: 0

Twisty
Twisty

Reputation: 30899

Some suggestions. As you have not provided any sample data, it's difficult to test or provide an example answer.

$(function() {
  $.widget("custom.catcomplete", $.ui.autocomplete, {
    _create: function() {
      this._super();
      this.widget().menu("option", "items", "> :not(.ui-autocomplete-category)");
    },
    _renderMenu: function(ul, items) {
      var that = this,
        currentCategory = "";
      $.each(items, function(index, item) {
        var li;
        if (item.event != currentCategory) {
          ul.append("<li class='ui-autocomplete-category'>" + item.event + "</li>");
          currentCategory = item.event;
        }
        li = $("<li></li>")
          .data("ui-autocomplete-item", item)
          .append('<div><a href="javascript:;"><input type="checkbox"/>' + item.label + '</a></div>')
          .appendTo(ul);
      });
    }
  });

  $("#trade").catcomplete({
    delay: 0,
    source: function(request, response) {
      var myForm = $("form[name='searchTraining']");
      $.ajax({
        type: "POST",
        url: "tmp3.php",
        data: {
          trade: request.term,
          trainingID: $('[name=trainingID]', myForm).val(),
          totalParticipants: $('[name=totalParticipants]', myForm).val(),
          male: $('[name=male]', myForm).val(),
          female: $('[name=female]', myForm).val(),
          district: $('[name=district]', myForm).val(),
          project: $('[name=project]', myForm).val(),
          fromDate: $('[name=fromDate]', myForm).val(),
          toDate: $('[name=toDate]', myForm).val(),
          rPerson: $('[name=rPerson]', myForm).val()
        },
        success: response,
        dataType: 'json',
        minLength: 1
      });
    }
  });
});
.ui-autocomplete-category {
  font-weight: bold;
  padding: .2em .4em;
  margin: .8em 0 .2em;
  line-height: 1.5;
}

.ui-autocomplete {
  max-height: 100px;
  overflow-y: auto;
  /* prevent horizontal scrollbar */
  overflow-x: auto;
}

.ui-autocomplete-loading {
  background: white url("../img/ui-anim.gif") right center no-repeat;
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<form name="searchTraining">
  <div class="ui-widget">
    <label for="search">Search: </label>
    <textarea class="tradeF" name='trade' id='trade' placeholder="Trade" autocomplete="on" pattern="[a-zA-Z ]+" size="21"></textarea>
  </div>
  <input pattern="[0-9]+" placeholder="Training ID" name="trainingID" size="1" class="idF" type="text" title="TrainingID">
  <input autocomplete="on" pattern="[0-9]+" placeholder="Total" name="totalParticipants" size="3" type="text" class="totalF">
  <input autocomplete="on" pattern="[0-9]+" placeholder="Male" name="male" size="3" type="text" class="maleF">
  <input autocomplete="on" pattern="[0-9]+" placeholder="Female" name="female" size="3" type="text" class="femaleF">
  <input autocomplete="on" pattern="[a-zA-Z ]+" placeholder="District" name="district" size="3" type="text">
  <input autocomplete="on" pattern="[a-zA-Z ]+" placeholder="Project" name="project" size="3" type="text" value="kfw"> From
  <input name="fromDate" size="3" type="text"><br />To<input name="toDate" size="3" type="text">
  <input autocomplete="on" pattern="[a-zA-Z ]+" placeholder="Venue" name="venue" size="3" type="text">
  <input autocomplete="on" pattern="[a-zA-Z ]+" placeholder="Resource Person" name="rPerson" size="3" type="text">
  <input type="hidden" name="defaulter" value="true" />
  <input type="hidden" name="questItem" value="" />
</form>

Upvotes: 0

Related Questions