5

At first I'm absolutely new on web development. I'm trying to develop a Web application which consists of a single page (I started with an empty project trying to follow the mvc pattern).

To populate my View I pass a ViewModel through my HomeController to my "Home"View.

Now I want to change a few Label-Texts depending on a DropDown selection.

ViewModel:

public IEnumerable<Models.Language> AvailableLanguages;
public Models.Language SelectedLanguage
Public IEnumerable<Models.Text> Content;

Language:

public int ID;
public string LanguageText;

Text:

public Language Language;
public string Description;

HTML: @model ViewModels.MyViewModel

<div>
    @Html.DropDownFor(x => x.AvailableLanguages, 
    new SelectList(Model.AvailableLanguages, 
    "ID", 
    "LanguageText", 
    new {@onchange= ... })) 
</div>

<div>
    @{
        @:@Model.MyViewModel.Content
        .Where(o => o.Language.Equals(Model.SelectedLanguage)
        .First())
        .Description
     }
</div>

I read something about this "@onchange" attribute (Ajax, JQuery) - but to be honest It'd be great if there would be any ASP/MVC/HTML solution to achive my goal - to update my SelectedLanguage Property everytime the selected item of the dropdown gets changed.

Additionaly: Is there a tutorial for webdevelopment (asp, html, ajax, jquery, js) you can recommend?

Thanx!

EDIT

Now I tried to implement the code provided but it seems that nothing happens when changing the selected item...

Script:

<div class="LanguageSelection">
        @{
            @Html.DropDownList("SelectedLanguage", new SelectList(Model.AvailableLanguages, "ID", "Description"))
            <script src="~/Scripts/jquery-1.10.2.min.js" type="text/javascript">
                var url = '@Url.Action("ChangeLanguage", "Home")';
                $('#SelectedLanguage').change() {
                    $.getJSON(url, {
                        ID: $(this).val() 
                    }, function(response){
                        $('#Title').text(response.Title);   
                    });
                };
            </script>
        }
    </div>

JsonResult:

public JsonResult ChangeLanguage(int id) {
        var data = new {
            Title = HVM.Title.Where(o => o.Language.ID.Equals(id)).First(),
        };
        return Json(new { success = true });
    }

The problem should be located somewhere in the script, the ChangeLanguage Method doesn't even get executed.

6
  • Have you tried the javascript/jquery solution? Commented Mar 25, 2015 at 13:55
  • It a little unclear exactly what you want to do. You cannot bind a dropdownlist to a complex object (IEnumerable<Models.Language>). If your wanting to identify the selected language on post back, you need a property to bind to (say int SelectedLanguage { get; set; }) and then @Html.DropDownFor(x => x.SelectedLanguage, new SelectList(Model.AvailableLanguages ...). Commented Mar 26, 2015 at 1:11
  • The second part of your view makes no sense. Razor code is parsed on the server before is sent to the view so MyViewModel.Content would only ever be the initial value of the SelectedLanguage. If your wanting to update something in the DOM based on the selected language, then you need to use ajax to call a controller, passing the selected language and returning the new new values you want to display. Note also your models only have fields (no get/set) so nothing will bind when you post back. Commented Mar 26, 2015 at 1:15
  • That's why I said that I'm pretty new on the web development sector. So you mean there is no way to bind a SelectedValue to a List<object> without using advanced technologies such as ajax? If so, could you recommend some tutorials? Commented Mar 26, 2015 at 6:12
  • @Chill-X. You can bind a dropown to a value type (int, string etc), but not to a complex object (a <select> posts back a single value and has no concept of what IEnumerable<Language> is. If you explain what it is you want to do (i.e. what is the purpose of handling the .change event), I can give you an answer. Commented Mar 27, 2015 at 2:10

2 Answers 2

7

From the comments, you want to be able to update labels based on the selected language. In order to do this you will need to use ajax to post the selected language to a controller method that return json and update the DOM. Your view model should be

public SelectList AvailableLanguages { get; set; }
public int SelectedLanguage { get; set; }

and in the controller

public ActionResult YourMethod()
{
  var model = new yourModel();
  model.SelectedLanguage = // set this if you want a default
  var availableLanguages = // get you list of languages
  model.AvailableLanguages = new SelectList(availableLanguages, "ID", "LanguageText")
  return View(model);
}

View

@Html.DropDownListFor(m => m.SelectedLanguage, Model.AvailableLanguages)

<script>
  var url = '@Url.Action("GetLanguageLabels", "yourControllerName")';
  $('#SelectedLanguage').change() {
    $.getJSON(url, { ID: $(this).val() }, function(response) {
      // Note you will need to give your labels an id attribute
      $('#Label1').text(response.Label1);
      $('#Label2').text(response.Label2);
    })
  });
</script>

And the method to get the labels based on the selected language

public JsonResult GetLanguageLabels(int ID)
{
  // Build a object of label values based on the selected language ID
  var data = new
  {
    Label1 = someValue,
    Label2 = anotherValue,
    ....
  };
  return Json(data, JsonRequestBehavior.AllowGet);
}

Side note: Some issues with your current code. (1) Your models have fields only, not properties (no get/set) so nothing would be bound on post back. (2) You cannot bind a html control to a complex object (only an value type, or in the case of <select multiple>, an array of value types).

Sign up to request clarification or add additional context in comments.

7 Comments

Thanks, I'll implement this as soon as possible. Could you explain the code between the <script>-Tags? At the moment I'm writing my code with the Razor-Syntax - Do I have to change something in your code? You see, I'm pretty new on that web development stuff...
OK, You will need to include the jquery.{version}.js file (either using bundling or from the Scripts folder). and you will need to update a few thing to match your requirements (e.g. yourControllerName and the id's of your labels because you did not give enough information). If you have any problems post the code you tried. And you should not mark an answer as accepted until you try it :)
I added some more code - maybe you can help one more time? Thanks in advance!
Your going to need to ask a new question if your having prolems with your new code. There are numerous problems - place the script inside a <script> tag at the bottom of the page. The jquery reference needs to be a separate script tag. Your method is returning return Json(new { success = true }); but it needs to be return Json(data, JsonRequestBehavior.AllowGet). Place breakpoints on the script and the controller method debug you code to understand whats actually happening
Thanks anyway, finally you did it :) Now it works (nearly) as expected. Am I allowed to ask a last question? I want to use my HomeViewModel inside my ChangeLanguage Method - but the reference in there is null although I'm creating an instance in my Index Method (this.ViewModel = new HomeViewModel();)
|
1

You would make sure the elements are in a form and just and the name of the function after the onchange...

@onchange="submitdata();"

Then you would add the script.

function submitdata()
{
  $('form').submit();
}

For a more "MVC" approach you would start with a strongly typed view using a model.

@model My.Path.To.Model

You would also wrap the form data on your razor page with...

using (@Html.BeginForm("myMethod", "Home", FormMethod.Post)){
     //form and inputs here, ect
     <form method="POST" action="" >
         //properties bound to inputs to change your model, or html helpers like display for...
         <input type="Submit" name="Submit" value="Submit"/>
     </form>
}

You would then pass the model as a parameter in the Controller action, this is called on the submit of the form:

[HttpPost]
 public FileStreamResult myMethod(Model model)
 {
     string str = model.imapropertyonthemodel;

 }

If you are new to MVC I would recommend starting with the basics from W3 schools, or if you have pluralsight, there are some great tutorials there.

2 Comments

If I understand your snippet the form (btw. when do I have to use a form?) gets submitted after a button on the form is clicked. What I want to do is to update my complete View after the selection of my Dropdown is changed (if possible without clearing input fields on my page).
Sorry I wasn't more clear. The first few lines answers the question. You would have the javascript function called from the @onchange. So when the dropdown changed the form would be "submitted" which would then give you access to whatever values you wanted from there. You wouldn't have to use a button at all. In addition to having access to all the values, the event is captured in javascript so you can do whatever you want to the view.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.