views:

2366

answers:

1

I have some data which I am formatting like this:

 // ... imagine populating a SqlDataReader with some results ...
 var results = new StringBuilder();
 while (reader.Read())
 {
     results.AppendFormat("{0}, {1}\n", reader["name"], reader["emailAddress"]);
 }
 return results.ToString();

My controller action is pretty simple:

 public ActionResult Find(string q)
 {
     var users = Customer.Search(q);
     return Content(users);
 }

And my javascript in the view looks like this:

 $(document).ready(function() {
     $("input#user").autocomplete('<%= Url.Action("Find", "Customer") %>', {
         minChars: 2,
         width: 500,
         matchContains: true,
         autoFill: false,
         formatItem: function(row, i, max) {
             return i + "/" + max + ": (" + row[0] + ") " + row[1];
         },

         formatMatch: function(row, i, max) {
             return row[0];
         },

         formatResult: function(row) {
             return row[1];
         }
      });
    });

Question A

I am using the Autocomplete from here. At this point I am having an issue where I cannot get the two fields to read as separate values. For example, if a rows name field is "John" and its email field "[email protected]" I would expect those to show up in row[0] and row[1] respectively. However, they currently I get "John, [email protected]" in row[0] and row[1] is undefined.

What do I need to change (either in the javascript or the method where I'm building the string) to get row[0] and row[1] to show the proper data?

Question B

I would prefer to have the data in the rows named. By this I mean:

 formatItem: function(row, i, max) {
     return i + "/" + max + ": (" + row.name + ") " + row.email;

I struggled for a while to format my data so this would happen but I was never successful. How would I format my data so that the AutoComplete would understand this?

+2  A: 

If you create a list of results of a class with Name and Email properties, then return it as JSON, then I think it will work the way you want it to.

Intermediate class

public class AutocompleteResult
{
    public string Name { get; set; }
    public string Email { get; set; }
}

Search code:

var results = new List<AutocompleteResult>();
while (reader.Read())
{
    results.Add( new AutocompleteResult
                     {
                         Name = reader["name"],
                         Email = reader["email"]
                     });
}
return results;

Action:

public ActionResult Find(string q)
{
    var users = Customer.Search(q);
    return Json(users);
}

View:

I think... the key difference is the parse method and the dataType, you might have to adjust the parse method, et. al. to get the formatting right. You might be able to get rid of formatResult/formatMatch, but I'm not sure. I don't use these and as I recall what I'm doing in parse sets the values properly. I'm trying to keep your basic code, but as I said I don't use all the methods that you do and haven't explored them in depth.

$(document).ready(function() {
    $("input#user").autocomplete('<%= Url.Action("Find", "Customer") %>', {
        dataType: 'json',
        minChars: 2,
        width: 500,
        matchContains: true,
        autoFill: false,
        parse: function(data) {
           var array = new Array();
           for (var i = 0; i < data.length; ++i) {
              var datum = data[i];
              array[array.length] = {
                          data: datum,
                          value: datum.Name,
                          result: dataum.Email
              };
           }
        }
        formatItem: function(data, i, max) {
            return i + "/" + max + ": (" + data.Name + ") " + data.Email;
        },
        formatMatch: function(data, i, max) {
            return data.Name;
        },
        formatResult: function(data) {
            return data.Email;
        }
     });
});
tvanfosson
this was one of the many things I tried but was unable to get functioning. could you possibly update your answer to show how the javascript would work in this case?
Sailing Judo
to demonstrate my issue, when I do what you have above and execute my page, -all- the results are in -one- row.
Sailing Judo
Updated with javascript -- including the parse method...
tvanfosson
thanks! the parse helped a lot. still not quite done, but you've got me over my chief hurdles.
Sailing Judo