1

I have 2 cascade dropdowns in an editortemplates view. When I open the view for the first time and the editortemplate is loaded the data in the dropdowns load with no problems. However when clicking in a button that will repeat this editortemplate several times in my view the dropdowns data don't load. I have used routemapping for the cascade dropdowns and the button is calling a jquery. What can be wrong here?

First time the page is loaded

After clicking in Add Row button, there is still data in the original row but the second row is empty

This is the code for the dropdowns:

For the editortemplates view:

<script type="text/jscript">
$(function () {
    $.getJSON("/Budget/Categories/List/", function (data) {
        var items = "<option value='0'>Select a Category</option>";
        $.each(data, function (i, category) {
            items += "<option value='" + category.Value + "'>" + category.Text + "</option>";
        });
        $("#Category").html(items);
    });

    $("#Category").change(function () {
        $.getJSON("/Budget/SubCategories/List/" + $("#Category > option:selected").attr("value"), function (data) {

            var items = "<option value='0'>Select a SubCategory</option>"; ;
            $.each(data, function (i, subcat) {
                items += "<option value='" + subcat.Value + "'>" + subcat.Text + "</option>";
            });
            $("#SubCategory").html(items);
        })
    });
});
</script>

<label for="Category">Categories</label>
<select id="Category"  name="Category" style = "width:150px"></select>

<label for="SubCategory">SubCategories</label>
<select id="SubCategory"  name="SubCategory"  style = "width:150px"></select>

For the controller:

[Authorize]
[HttpGet]
public ActionResult GetCategories()
{
    IQueryable categories = _db.categories;
    if (HttpContext.Request.IsAjaxRequest())
    {
        return Json(new SelectList(categories, "idCategory", "CategoryName"), JsonRequestBehavior.AllowGet);
    }
    return View(categories);
}

[Authorize]
[HttpGet]
public ActionResult GetSubCategories(int idCategory)
{
    IQueryable subcategories = _db.subcategories.Where(c => c.idCategory == idCategory);
    if (HttpContext.Request.IsAjaxRequest())
    {
        return Json(new SelectList(subcategories, "idsubCategory", "SubCategoryName"), JsonRequestBehavior.AllowGet);
    }
    return View(subcategories);
}

For the routeconfig:

routes.MapRoute("GetCat", "Budget/Categories/List/",
    new { controller = "Budget", action = "GetCategories" });

routes.MapRoute("GetSubCat", "Budget/SubCategories/List/{idCategory}",
    new { controller = "Budget", action = "GetSubCategories", idCategory = "" });

And this is the code for the button:

For the view:

<script type="text/jscript">
jQuery(document).ready(function ($) {
    $('#add-bdetail').on('click', function () {
        jQuery.get('/Budget/AddBudgetDetail').done(function (html) {
            $('#bdetail-list').append(html);
        });
    });
});
 </script>

 <div> <input type="button" id="add-bdetail" value="Add row" /></div>

For the controller:

[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
public ActionResult AddBudgetDetail()
{
    return View(new List<budgetdetail>() {  new budgetdetail() });
}
Cœur
  • 37,241
  • 25
  • 195
  • 267
mdiaz
  • 27
  • 1
  • 10
  • Do not use ajax to load your first dropdownlist - use the `DropDownListFor() method and pass the `IEnumerable` to the view (in a view model or `ViewBag` property. And remove your scripts from the `EditorTemplate` - it means your duplicating them! Scripts should only ever be in the view (or layout) –  Mar 14 '16 at 08:08
  • But that's the least of your problems - you generating invalid html (duplicate `id` atributes) and you script will only ever run for the first element with `id="Category"`. Then you adding the first option with a valid value so you will never get `ModelState` errors and will probably throw an exception when saving. And your implemetation could not bind to a collection since your indexers are not consecutive. –  Mar 14 '16 at 08:17
  • Thank you for your response. That helps me a lot. Could you give some an example on how to use the DropDownListFor() method. I have found some info online but I am bit confused. Also is there a way to make the id's dynamic? For example Category1, Category2 and make the java script use them? If not is there a different way I could do create my budgetlist using a grid? If so could you give me an example or point me in the right direction? Thank you. – mdiaz Mar 15 '16 at 05:06
  • Refer the code in this [DotNetFiddle](https://dotnetfiddle.net/1bPZym) for an example of how to generate cascading dropdownlists. In particular note the code in the controller `ConfigureViewModel()` method for what is need to generate you dropdownlists that allow you to display the view initially and if if you need to return the view. –  Mar 15 '16 at 05:13
  • Based on the code you have shown, you are a long way off being able to implement dynamically adding items, so get the cascading dropdownlists working correctly for the initial items. Then you can look at the answers [here](http://stackoverflow.com/questions/29161481/post-a-form-array-without-successful/29161796#29161796) and [here](http://stackoverflow.com/questions/28019793/submit-same-partial-view-called-multiple-times-data-to-controller/28081308#28081308) for how to implement dynamically adding and removing items –  Mar 15 '16 at 05:16
  • And id's have nothing to do with it. In fact you need to make sure that you remove the `id` attributes (using `new { id = "" }` in your helpers) . What is important is the `name` attribute of your controls (having the correct indexer for binding to a collection) –  Mar 15 '16 at 05:18
  • Thank you, you have been really helpful. I will give this information a try. Do you mind if i reach out to you when I get stuck again? It may happens sooner than later :) – mdiaz Mar 15 '16 at 05:22
  • Just ask a new question :) –  Mar 15 '16 at 05:25
  • I made the modifications you suggested, however my javascript don't seem to me working. I have posted a new question could you please take a look. Thank you – mdiaz Mar 15 '16 at 18:50
  • That question is now closed (and your subsequent one will probably be closed shortly). You need to learn to use your browser tools to debug your scripts, and until you do so, I highly recommend you get someone else to write your code. –  Mar 16 '16 at 00:25
  • Thank you for taking a look Stephen. I have actually figured out how to debug scripts in browser using firebug. I fixed the script and now i have cascade dropdowns. I will start working on the next step. I am quite experienced in programming I am just new to mvc and have little knowledge of javascrip, so it is taking me a little but to figure out things but I have learned a lot in one week. – mdiaz Mar 16 '16 at 04:23

0 Answers0