views:

178

answers:

2

Hi all,

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?

A: 

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  A: 

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.

R0MANARMY
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
@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).
R0MANARMY