Why is my categoryName passing instead of my id?

Hi All

I have a form that has a field where the user starts typing and then results show and narrows down until they get the option they want.

This is working fine… it shows the categoryName correctly and has a hidden id.

I want to pass the id when the form is submitted however it is passing the categoryName instead.

The form field is:

<div class="form-floating mb-2">
   <input class="form-control bs-autocomplete" placeholder="Directory Category..." type="text" name="categoryID" id="directoryCategory" data-hidden_field_id="categoryID" data-item_id="id" data-item_label="categoryName" autocomplete="off" autofocus>
   <label for="directoryCategory">Directory Category...</label>
   <div style="padding-left:0.75em; padding-top:0.5em;"><small><strong>NOTE</strong>: start typing to find a category or <a href="#" data-bs-toggle="modal" data-bs-target="#categoryList">click or tap here</a> for a full list.</small></div>
</div>

The Javascript is:

<script>
$(document).ready(function() {
  $.widget("ui.autocomplete", $.ui.autocomplete, {
    _renderMenu: function(ul, items) {
      var that = this;
      ul.attr("class", "nav nav-pills nav-stacked bs-autocomplete-menu");
      $.each(items, function(index, item) {
        that._renderItemData(ul, item);
      });
    },

    _resizeMenu: function() {
      var ul = this.menu.element;
      ul.outerWidth(
        Math.min(
          ul.width("").outerWidth() + 1,
          this.element.outerWidth()
        )
      );
    },
  });

  (function() {
    "use strict";

    var returedInformation = [

{ "id": 7, "categoryName": "Accountant" },{ "id": 4, "categoryName": "Bookkeeper" },{ "id": 1, "categoryName": "Carpenter" },{ "id": 5, "categoryName": "Fashion" },{ "id": 2, "categoryName": "Plumber" },
    ];

    $('.bs-autocomplete').each(function() {
      var _this = $(this),
        _data = _this.data(),
        _hidden_field = $('#' + _data.hidden_field_id);
      _this.after('<div class="bs-autocomplete-feedback form-control-feedback"><div class="loader">Loading...</div></div>')
        .parent('.form-group').addClass('has-feedback');
      var feedback_icon = _this.next('.bs-autocomplete-feedback');
      feedback_icon.hide();
      _this.autocomplete({
        minLength: 1,
        autoFocus: true,
        source: function(request, response) {
          var _regexp = new RegExp(request.term, 'i');
          var data = returedInformation.filter(function(item) {
            return item.categoryName.match(_regexp);
          });
          response(data);
        },
        search: function() {
          feedback_icon.show();
          _hidden_field.val('');
        },
        response: function() {
          feedback_icon.hide();
        },
        focus: function(event, ui) {
          event.preventDefault();
        },
        select: function(event, ui) {
          _this.val(ui.item[_data.item_label]);
          _hidden_field.val(ui.item[_data.item_id]);
          event.preventDefault();
        },
      }).data('ui-autocomplete')._renderItem = function(ul, item) {
        return $("<li>")
          .append('<div style="padding-left:0.75em; padding-top:0.25em; padding-bottom:0.25em;">' + item[_data.item_label] + '</div>')
          .appendTo(ul);
      };
    });
  })();
});

    

</script>

All the other code is there to make this run and, as mentioned, it is running fine it is just passing the categoryName instead of the id.

I think is this something that just needs a small tweak however I have spent all afternoon on it and just can’t get it working.

Any help would be great.

Many Thanks

mrmbarnes

isnt your renderItem function missing the attribute data-value?

https://api.jqueryui.com/autocomplete/#method-_renderItem

(this is really hard to trace without a working example though, i must say. Is the page live somewhere?)

The working example is in a secure area and pulls in includes and uses the database but above is the core part of the code… I just can’t work out what i am missing… any further help would be great.

Well, we’re gonna be very hard pressed to give much advice without seeing it working. If you breakpoint the javascript inside the select function, what value does _data.item_id and ui.item[_data.item_id] have?

I really appreciate your help with this and understand the full code helps… javascript is not my forte and I am at the limit if my skills here… I have remade a test page that functions the same way as the actual page - https://higotec.com/partner/sitepoint.php

An example I have been using is bookkeeper that should have an id of 4.

I have added code so you can see what is submitted once you submit the form but everything else on the page will just take you to the login screen.

Once again thanks for any help with this.

Okay, so here’s what i see.

This makes more sense.

          _this.val(ui.item[_data.item_label]);
          _hidden_field.val(ui.item[_data.item_id]);

this should be

          _this.val(ui.item[_data.item_label]);
          _hidden_field.val(ui.item[_data.value]);

Give that a try.

squints Are you supposed to have a hidden field on the page somewhere? I dont see one with the right ID…

I really appreciate your help with this… more than you understand… I tried that but it is still passing the categoryName and not the id

I don’t think there should be a hidden field? should there? Doesn’t the Javascript pass that? Or do I need a hidden field with an id for the Javascript to use?

So the only form field I can see in your page is this one:

<input class="form-control bs-autocomplete ui-autocomplete-input" placeholder="Directory Category..." type="text" name="categoryID" id="directoryCategory" data-hidden_field_id="categoryID" data-value="id" data-item_label="categoryName" autocomplete="off" autofocus="">

which has a NAME of categoryID, but an ID of directoryCategory.

THAT field’s value gets set by this line:
_this.val(ui.item[_data.item_label]);

There doesnt appear to be a field on the page with id of categoryID.

Humor me. Try changing the HTML this way:

<input class="form-control bs-autocomplete ui-autocomplete-input" placeholder="Directory Category..." type="text" name="categoryID" id="directoryCategory" data-hidden_field_id="categoryID" data-value="id" data-item_label="categoryName" autocomplete="off" autofocus="">

=>

<input class="form-control bs-autocomplete ui-autocomplete-input" placeholder="Directory Category..." type="text" name="categoryName" id="directoryCategory" data-hidden_field_id="categoryID" data-value="id" data-item_label="categoryName" autocomplete="off" autofocus="">
<input type="hidden" id="categoryID" name="categoryID">

(yes, i made tweaks to the first line too, make sure you change it/replace it)

That was the issue… as I said I don’t work with Javascript very often and am not that great at it and it didn’t occur to me to do this.

Once again THANK YOU SOOOOO MUCH for your help with this.

1 Like