0

I'm returning JSON from my controller to my view in order to populate a jquery autocomplete textbox in MVC. The problem is, some of my data contains commas, and therefore is split by the autocomplete helper.

Heres my code.

Controller:

    public ActionResult GetData()
    {
        var data = repository.GetData();

        return Json(data);
    }

View (script):

    $.post("../MyController/GetData",

        function(data) {
        var evalData = eval(data) + ""; //formats the text

        $("#Data").autocomplete(evalData.split(","),
        {
            max: 500,
            matchContains: true
        });
    });

As you can see, I am using the jquery .split helper to split the returned Json. Should I be using regex or should I go with a completely different approach?

Josh Lee
  • 171,072
  • 38
  • 269
  • 275
Darcy
  • 5,228
  • 12
  • 53
  • 79
  • 1
    if evalData looks like "bla bla ", "bla bla bla" ... you can split by '", "' instead of ',' – vittore Apr 01 '10 at 18:55
  • How many items are you returning with GetData? With it not accepting any parameters it will send all the data and jquery is left to do the filtering. – AdmSteck Apr 01 '10 at 23:59

2 Answers2

1

I assume you're using the Autocomplete built into jQuery UI 1.8. If you are, you have a couple of different options.

  1. Based on one of the samples that's available in documentation, you can just give it a string specifying the URL of your service and not have to worry about parsing the return yourself. So something along the lines of:

    $("#Data").autocomplete({
        source: "../MyController/GetData"
    });
    

    Your action will most likely need to respond to get requests as well as post though and your data may need to be in the form of [{ label: "something", value: "1" }, ... ] Which you could do by shaping your data using a Linq query before sending it out.

    var data = from d in repository.GetData()
               select new
               {
                   label = d.[whatever you want the label to be]
                   value = d.[whatever you want the value to be]
               };
    return Json(data);
    
  2. You can combine your current implementation with parts of the example above to and get something like this:

    $.post("../MyController/GetData",
        function(data) {
            $("#Data").autocomplete({
                source: JSON.parse(data),
                max: 500,
                matchContains: true
            });
        });
    

    This assumes that data is in the form of [{ label: "something", value: "1" }, ... ] (see 1 for how to shape it using Linq). The JSON parser will take care of commas in quotes problem for you.

  3. You can also specify a method to call when you want to retrieve data.

    $("#Data").autocomplete({
        source: function(request, response) {
            $.ajax({
                url: "../MyController/GetData",
                dataType: "json",
                success: function(data) {
                    response( data );
                }
            })
        }
    });
    

    (see above about how to shape data using Linq)

A couple of comments about your current implementation.

  • You should considering using the UrlHelper instead of hard-codeing the URL in case you ever change your routes.

  • Instead of eval you should use the JSON2.js library to parse the return value from your action. It is generally a little bit more secure and yields better performance in newer browsers that support native JSON parsing.

Community
  • 1
  • 1
Roman
  • 19,581
  • 6
  • 68
  • 84
  • Thanks a bunch romanArmy. I didn't get the 'source: JSON.parse(data)' paramater to work. Instead, I replaced the eval.split(',') with it and it works great. – Darcy Apr 05 '10 at 13:58
  • @Darcy: to get JSON.parse to work you need to include JSON2.js file on your page. That's where the parse method comes from. Also, once you call **eval** you no longer have to call split, the data from your action will come back as as JSON array, so passing it as an argument to **eval** will give you back an array (the split should either be a no-op or cause an error). – Roman Apr 05 '10 at 14:43
0

Alright, after much going back and forth and several edits here is my final answer. :)

    $.post("../MyController/GetData", function(data) {
        $("#Data").autocomplete({
            source: data
        })
    });

Also, I believe the split function is plain javascript and not jquery.

AdmSteck
  • 1,753
  • 15
  • 25