views:

223

answers:

3

Hello,

Inside a jquery dialog I would like to use the jquery autocomplete feature of jqueryUI.

I have then prepared an action in my Controller (I am using ASP.NET MVC2) that is as follow

public ActionResult GetForos(string startsWith, int pageSize)
{
    // get records from underlying store
    int totalCount = 0;
    string whereClause = "Foro Like '" + startsWith + "%'";
    List<Foro> allForos = _svc.GetPaged(whereClause, "Foro", 0, pageSize, out totalCount);

    //transform records in form of Json data
    List<ForoModelWS> foros = new List<ForoModelWS>();
    foreach ( Foro f in allForos)
        foros.Add( new ForoModelWS() { id= Convert.ToString(f.ForoId), 
            text= f.Foro + ", Sezione: " + f.Sezione + ", " + f.AuthorityIdSource.Name });

    return Json(foros);
}

The class ForoModelWS is a simple class used only to hold the data that shall be transferred in json. Here it is

public class ForoModelWS
{
    public string id;
    public string text;
}

On the client side I have the following jquery code:

<input id="theForo" />

<script type="text/javascript">
    $(document).ready(function() {

        $("#theForo").autocomplete({
            source: function(request, response) {
                $.ajax({
                    type: "post",
                    url: "/Foro/GetForos",
                    dataType: "json",
                    data: {
                        startsWith: request.term,
                        pageSize: 15
                    },
                    success: function(data) {
                        response($.map(data, function(item) {
                            return {
                                label: item.text,
                                value: item.text
                            }
                        }))
                    }
                })
            },
            minLength: 2,
            select: function(event, ui) {
            },
            open: function() {
                $(this).removeClass("ui-corner-all").addClass("ui-corner-top");
            },
            close: function() {
                $(this).removeClass("ui-corner-top").addClass("ui-corner-all");
            }
        });

    });
</script>

But the sliding window with the suggeestions does not appear. If I put an alert inside the response function I can see the correct data.

Do I miss something?

Thanks for helping

1st EDIT: Moreover, How to change the code to use the "id" property of the selected element in the returned list?

2nd EDIT: I have checked more with Chrome developer tool and I have seen that when autocomplete starts some error appear. the following:

Uncaught TypeError: Cannot call method 'zIndex' of undefined  @ _assets/js/jquery-ui-1.8.4.custom.min.js:317
Uncaught TypeError: Cannot read property 'element' of undefined @ _assets/js/jquery-ui-1.8.4.custom.min.js:321
Uncaught TypeError: Cannot read property 'element' of undefined @ _assets/js/jquery-ui-1.8.4.custom.min.js:320

It seems that the autocomplete plugin does not find an element when it tries to set the z-Index of the sliding suggestion 1 level up its container. The first error appear when the jquery UI Dialog opens. The input for the autocomplete is inside a jquery tab that is inside a jquery Dialog

3rd EDIT: I am adding the HTML markup to be complete

<td width="40%">
   <%= Html.LabelFor(model => model.ForoID)%>
   <br />
   <%= Html.HiddenFor(model => model.ForoID) %>
   <input id="theForo" />
   <%= Html.ValidationMessageFor(model => model.ForoID, "*")%>
</td>
+1  A: 

Just like I answered here, take a loot at my working example of jQuery UI's autocomplete. Pay attention to the source part. Hope it helps:

    var cache = {};
    $("#textbox").autocomplete({
      source: function(request, response) {
       if (request.term in cache) {
        response($.map(cache[request.term].d, function(item) {
         return { value: item.value, id: item.id }
        }))
        return;
       }
       $.ajax({
        url: "/Services/AutoCompleteService.asmx/GetEmployees",  /* I use a web service */
        data: "{ 'term': '" + request.term + "' }",
        dataType: "json",
        type: "POST",
        contentType: "application/json; charset=utf-8",
        dataFilter: function(data) { return data; },
        success: function(data) {
         cache[request.term] = data;
         response($.map(data.d, function(item) {
          return {
           value: item.value,
           id: item.id
          }
         }))
        },
        error: HandleAjaxError  // custom method
       });
      },
      minLength: 3,
      select: function(event, ui) {
       if (ui.item) {
        formatAutoComplete(ui.item);   // custom method
       }
      }
     });

If you're not doing so by now, get Firebug. It's an invaluable tool for web development. You can set a breakpoint on this JavaScript and see what happens.

Rafael Belliard
@Rafael: please have a look to my edit
Lorenzo
@Rafael: I had a deep looking to your sample and it seems to me almost identical. I dont need to pass "data.d" to the map function. Anyway as I wrote on my question if I write "alert(item.text)" as the first istruction inside the map function I can see the correct data showing up.
Lorenzo
@Lorenzo: try parsing the "source" as shown in my example. The previous person I helped (and myself) had problems unless we parsed it with $.map.
Rafael Belliard
@Rafael: What do you mean by parsing with map? For me, it seems that I am using the map function exactly as your sample. Could you please explain more? thank you
Lorenzo
@Lorenzo: you're right, yours is pretty identical to mine. Could you please try two things: adding the dataFilter and contentType properties to your $.ajax from my code. It's the only differences I can spot (besides your data: {} not being sent json parsed, like "{ 'term': '" + request.term + "' }").
Rafael Belliard
@Rafael: I dont think that the problem is related to sending or receiving data. The problem is encountered inside the _create function of the Autocomplete plugin. In particular when it creates the UL that will contains the items in the istruction ".zIndex( this.element.zIndex() + 1 )".
Lorenzo
A: 

Hello. I'm having the same problem. Could anyone help me? Heres my code:

     autoCompleteComponent : function () {          
         $( "#share-with" ).autocomplete({
             minLength: 0,
             source : function(request, response) {
             if ( request.term in AnalysisExplorerUIControler.userCache ) {
                 response( AnalysisExplorerUIControler.userCache[ request.term ] );
                 return;
            }else{              
                 AnalysisExplorerListProxy.getUsers(request.term, AnalysisExplorerUIControler.userCache, response);
                }   
            }, 

            focus: function(event, ui) {
                $('#share-with').val(ui.item[0]);
                return false;
            },

            select: function(event, ui) {
                $('#share-with').val(ui.item[1]);
                return false;
            }
        })
        .data( "autocomplete" )._renderItem = function( ul, item ) {
            return $( "<li></li>" )
            .data( "item.autocomplete", item )                  
            .append( "<a>"+ "<div>"+item[0]+"</div>" + "<div>"+item[1]+"</div>" + "</a>")               
            .appendTo( ul );
        };
    }

The code is correct... because if I put the default autocomplete code, occurs the same problem.

Rafael
+1  A: 

I have found the problem.

In my case I was using also another plugin, this one.

That plugin was included at the end of my scripts and caused the error described in the question. I have removed the plugin and everything work very fine.

Before removing it I have tried also to isolate the problem putting in a static html both the scripts. I experienced that even the simplest usage of the autocomplete features, like this

<script type="text/javascript">
$(document).ready(function() {

    var availableTags = ["ActionScript", "AppleScript", "Asp", "BASIC", "C", "C++", "Clojure",
    "COBOL", "ColdFusion", "Erlang", "Fortran", "Groovy", "Haskell", "Java", "JavaScript",
    "Lisp", "Perl", "PHP", "Python", "Ruby", "Scala", "Scheme"];

    $("#theForo").autocomplete({
        source: availableTags
    });
});
</script>

would cause the error I got.

My choice has been to remove the menu plugin even because that code is'nt supported anymore.

Thanks!

Lorenzo
The fg.menu and autocomplete both add .menu() to jQuery. I renamed the fg.menu to $.fn.fgmenu and they cooperate now.
Corey Downie
can you share your code please? or at least give more info on the changes to do... :) thanks!
Lorenzo
Anyway, that menu does not permit me to attach jquery events at runtime to the <a> element (the menuitem). really nice but really bad!
Lorenzo
It's a quick change in the fg.menu.js. Change the line that reads " $.fn.menu = function(options) { " to " $.fn.fgmenu = function(options) { ". And then to use the menu you call $().fgmenu().
Corey Downie