2

So i'm building a simple mvc4 application, I have created all base models for the creation of the DB, from these classes I could naturally create basic controllers with their matching views.

Now my problem: I have the basic create actionresult + view and in this view I wanted that the user would be able to select some values from a dropdownlist which would make creation of new objects simpler.

I tried to achieve this with a second form in my view (the first one is the basic create form) now if I want to use these dropdowns (they filter each other(so first the user must specify a continent, then the dropdown of the countries only shows countries from that continent and after he specifies a country the region dropdown gets updated :) )) the submit of the basic view is always automatically called.

so making the dropdowns update themselves isn't the problem :s it's that the form for the create automatically validates when the dropdowns are updated

this is the controller where the dropdowns filter each other

//
// GET: /FederationCenter/Create
public ActionResult Create(string searchRegion, string searchCountry, string searchContinent)
{
  var countries = from c in db.Countries select c;
  if (!String.IsNullOrEmpty(searchContinent))
  {
    Continent searchContinentEnumValue = (Continent)Enum.Parse(typeof(Continent), searchContinent);
    countries = from c in db.Countries where ((int)c.Continent).Equals((int)searchContinentEnumValue) select c;
  }

  var regions = from r in db.Regions where r.Country.Name.Equals(searchCountry) select r;

  ViewBag.searchContinent = new SelectList(Enum.GetNames(typeof(SchoolCup.Domain.Continent)));
  ViewBag.searchCountry = new SelectList(countries, "Name", "Name");
  ViewBag.searchRegion = new SelectList(regions, "Name", "Name");
  return View();
}

//
// POST: /FederationCenter/Create

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(NSSF nssf, string searchRegion, string searchCountry, string searchContinent)
{
  var countries = from c in db.Countries select c;
  if (!String.IsNullOrEmpty(searchContinent))
  {
    Continent searchContinentEnumValue = (Continent)Enum.Parse(typeof(Continent), searchContinent);
    countries = from c in db.Countries where ((int)c.Continent).Equals((int)searchContinentEnumValue) select c;
  }

  var regions = from r in db.Regions where r.Country.Name.Equals(searchCountry) select r;

  ViewBag.searchContinent = new SelectList(Enum.GetNames(typeof(SchoolCup.Domain.Continent)));
  ViewBag.searchCountry = new SelectList(countries, "Name", "Name");
  ViewBag.searchRegion = new SelectList(regions, "Name", "Name");
  if (ModelState.IsValid)
  {
    var naam = Request["searchRegion"];
    Region creatie = (from c in db.Regions where c.Name.Equals(naam) select c).SingleOrDefault();
    nssf.ISFId = 1;
    nssf.RegionId = creatie.RegionId;
    db.NSSFs.Add(nssf);
    db.SaveChanges();
    return RedirectToAction("Index");
  }
  return View(nssf);
}

and this is my view

@model SchoolCup.Domain.POCO.NSSF

@{
ViewBag.Title = "Create";
}

<h2>Create NSSF</h2>
     <div>
        @using (Html.BeginForm(null, null, FormMethod.Post, new { name = "form" }))
        {
         @Html.AntiForgeryToken()

        @Html.DropDownList("searchContinent", null, "-- All continents --", new { onchange = "sendForm()" }) 
        @Html.DropDownList("searchCountry", null, "-- All countries --", new { onchange = "sendForm()" })
        @Html.DropDownList("searchRegion", null, "-- All regions --", new { onchange = "sendForm()" })
            <>
            <input type="submit" name= value="Search" />    
        }
    </div>   
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)

<fieldset>
    <legend>NSSF</legend>

    <div class="editor-label">
        @Html.LabelFor(model => model.Name)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.Name)
        @Html.ValidationMessageFor(model => model.Name)
    </div>

some more inputs

   </fieldset>
    <p>
        <input type="submit" value="Create" />
        @Html.ActionLink("Back to List", "Index", null, new { @class = "button" })

    </p>
}

@section Scripts {
<script type="text/javascript">
    function sendForm() {
        document.form.submit()
    }
    </script>
}

I've been looking for at least a day and I don't know how to solve this

with regards Alexander

  • Your question is not clear but it is almost clear. ;) I think if you expand this sentence with more information: `now if I want to use these dropdowns (they filter each other) the submit of the basic view is always automatically called.` then your question will become clear to everyone. – David Tansey May 02 '13 at 21:14
  • so first the user must specify a continent, then the dropdown of the countries only shows countries from that continent and after he specifies a country the region dropdown gets updated :) sry for the big post :s – Alexander Van Loock May 02 '13 at 21:30
  • Perhaps this post will help you: http://stackoverflow.com/questions/5497524/easiest-way-to-create-a-cascade-dropdown-in-asp-net-mvc-3-with-c-sharp. The answer uses AJAX to fetch new options as a JSON response then replace the select items. – Jasen May 02 '13 at 21:55
  • 1
    making the dropdowns update themselves isn't the problem :s it's that the form for the create automatically validates when the dropdowns are updated – Alexander Van Loock May 02 '13 at 22:08
  • @AlexanderVanLoock Please add that to your question. It will help others understand your problem. – Jasen May 02 '13 at 22:23

1 Answers1

2

How about either (1) using JQuery and loading the drop-down with a Partial view returned by your controller or (2) you could have an AJAX call that would return your values as a JSON object mapped from your entity and you can render them in the drop-down. This way your form won't be submitted every time you update a drop-down.

The first solution might look something like this:

JQUERY

<script>
$("#searchContinent").change(function() { 
    $("#searchCountry").load("/YourController/GetCountries", { 'continentId': $(this).val() },
                                        function (response, status, xhr) {
                                            if (status == "error") {
                                                alert("An error occurred while loading the results.");
                                            }
                                        });
});
</script>

@Html.DropDownList("searchContinent", null, "-- All continents --" }) 
<div id="searchCountry">
    <!--the newly created drop-down will be placed here-->
</div>

(EDIT)

For Javascript you might try something like this:

YOUR CURRENT VIEW

@Html.DropDownList("searchContinent", null, "-- All continents --", new { onchange = "getCountries(this)" }) 
<div id="searchCountry">
<!--the newly created drop-down will be placed here-->
</div>

<script> 
function getCountries(input){
    var selectedValue = input.options[input.selectedIndex].value;
    var xhReq = new XMLHttpRequest();
    xhReq.open("GET", "YourController/GetCountries?continentId="+selectedValue, false);
    xhReq.send(null);
    var serverResponse = xhReq.responseText;
    document.getElementById("searchCountry").innerHTML=serverResponse ;
}
</script>

DISCLAIMER: This I have never tried so if it's wrong don't hesitate to let me know and correct it if necessary

(END EDIT)


CONTROLLER

public ActionResult GetCountries(string continentId)
    {
        /*Get your countries with your continentId and return a Partial View with a list of 
          countries as your model*/


        return PartialView(countryList);
    }

GetCountries VIEW

@model IEnumerable<SchoolCup.Domain.Country>

@Html.DropDownListFor( 0, Model)
sunshineDev
  • 323
  • 3
  • 10
  • I'm not familiar with jQuery :s so I don't realy know how to implement this solution – Alexander Van Loock May 02 '13 at 22:47
  • Jquery is a javascript library. It's really easy. What you have to do is include the JQUERY libraries and add the bit of code I provided to your view in a – sunshineDev May 02 '13 at 22:56
  • if that wouldn't be to much trouble you would really help me out :D – Alexander Van Loock May 02 '13 at 23:01
  • I think I got a little ahead of myself there :) I haven't developed AJAX calls in pure Javascript but I'll try and find out how unless someone else helps us out here. However I must emphasize that it is truly truly easy to do with [JQUERY](http://jquery.com/download/) and you don't have to add much more to your project, trust me. If you decide to use it, don't hesitate to ask me if you get stuck on something. – sunshineDev May 02 '13 at 23:11
  • I'll try and give it a shot ;) – Alexander Van Loock May 02 '13 at 23:13
  • I've edited the response with some Javascript. Not sure it will work but give it a try and see. – sunshineDev May 02 '13 at 23:30
  • thanks a lot for the help :) i'm going to sleep now because it's 2.30 am :p it didn't get it to work yet but I'll keep you posted tomorrow , tx again – Alexander Van Loock May 03 '13 at 00:18
  • One thing that might give you trouble is the YourController/GetCountries URL. You might have to prepend a "/" or "../" depending on where your script is defined. One way of knowing if your controller call is actually working is calling the URL directly from your browser. – sunshineDev May 03 '13 at 14:40
  • i fixed it with JQuery and partial views wich fill the dropdowns :) – Alexander Van Loock May 04 '13 at 14:01