0

Im trying to change a "name" textbox color to (blue if it is male, and pink if it is female) after changing a "gender" dropdown in a partial view.

Index View:

@{
    ViewData["Title"] = "Home Page";
    var gender = ViewBag.Gender; //breakpoint
}
 @if (gender == "Male") 
{
    <div id="name">
        <label asp-for="Name">Name</label>
        <input id="nametextbox" type="text" asp-for="Name" style="background-color: lightblue" />
    </div>
}
else if (gender == "Female")
{
    <div id="name">
        <label asp-for="Name">Name</label>
        <input id="nametextbox" type="text" asp-for="Name" style="background-color: lightpink" />
    </div>
}
else
{
    <div id="name">
        <label asp-for="Name">Name</label>
        <input id="nametextbox" type="text" asp-for="Name" style="background-color: white" />
    </div>
}
<div id="gender">
    <partial name="_GenderDropdown" model="Model" />
</div>

Partial View:

<label>Gender</label>
<select id="genderstring">
    <option value="">Select Gender</option>
    <option value="Male">Male</option>
    <option value="Female">Female</option>
</select>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
    $(document).ready(function () {
        //ajax for posting gender to controller

        $('#genderstring').on('change', function () {
            $.ajax({
                url: '@Url.Action("Index", "Home")',
                type: 'GET',
                data: { gender: $("#genderstring").val() },
                success: function () {
                
                },
                error: function () {
                
                }
            });
        });

    });

</script>

Controller:

public IActionResult Index(string gender)
    {

        if(gender == null)
        {
            return View(new User { Name = "", Gender = "" });
        }
        else
        {
            ViewBag.Gender = gender;
            return View("Index"); //breakpoint
        }
    }

With this 2 breakpoints i can see that the data is passing but after I change the gender it gets to the view with the gender in the viewbag but the rest of the page doesen't run.

Rena
  • 30,832
  • 6
  • 37
  • 72
DanielCaps
  • 51
  • 1
  • 8
  • Why do you want to use an ajax request to update the textbox colour? This is a job for Javascript – haldo Mar 11 '21 at 18:47
  • When you say "the rest of the page doesen't run" do you mean the javascript on the partial view is not executed? Have you tried to move the code out of the document ready event handler? – Jasen Mar 11 '21 at 18:59
  • This was a challenge im just trying to solve it. When i say the rest of the page doesn't run i mean when the view is returned with the gender the page doesn't render the form. it basically doesen´t reload with the changed color. – DanielCaps Mar 11 '21 at 19:26
  • Well, you don't anything in the `success` handler. – Jasen Mar 11 '21 at 19:30
  • This is a bit old but still valid https://stackoverflow.com/a/11947606/2030565 – Jasen Mar 11 '21 at 19:40
  • Are you using the same action `Index` for both main view and partial view? How do you expect that to work? You would need to refresh the whole page for it to pick up your `if` statement in the view. A simpler solution is to have a single textbox in the view and use javascript to change the colour, you could even send an ajax request if you want and update the colour inside the `success` function but in that case you should use a different action on the controller and that action would return the partial view – haldo Mar 11 '21 at 19:53

1 Answers1

1

When you use ajax,it would not reload your page after backend code finishing by default.More detailed explanation and solution you could check as follow:

The first way

You could use .html() method to render the backend result to html after ajax success:

1.View(Be sure add a div to contain the whole html):

<div id="result">    //add the div......
    @if (gender == "Male")
    {
        <div id="name">
            <label asp-for="Name">Name</label>
            <input id="nametextbox" type="text" asp-for="Name" style="background-color: lightblue" />
        </div>
    }
    else if (gender == "Female")
    {
        <div id="name">
            <label asp-for="Name">Name</label>
            <input id="nametextbox" type="text" asp-for="Name" style="background-color: lightpink" />
        </div>
    }
    else
    {
        <div id="name">
            <label asp-for="Name">Name</label>
            <input id="nametextbox" type="text" asp-for="Name" style="background-color: white" />
        </div>
    }
    <div id="gender">
        <partial name="_GenderDropdown" model="Model" />
    </div>
</div>

2.Js in partial view:

<script>
    $(document).ready(function () {    
        $('#genderstring').on('change', function () {
            $.ajax({
                url: '@Url.Action("Index", "Home")',
                type: 'GET',
                data: { gender: $("#genderstring").val() },
                success: function (res) {
                    $("#result").html(res);   //add this...
                },
                error: function () {

                }
            });
        });

    });

</script>

3.Controller:

You need return PartialView instead of returning View,because if you return view it will generate the layout(e.g the nav bar) again(you could have a try by yourself).

[HttpGet]
public IActionResult Index(string gender)
{

    if (gender == null)
    {
        return View(new User { Name = "", Gender = "" });
    }
    else
    {
        ViewBag.Gender = gender;
        return PartialView("Index"); //change here...
    }
}

Result:

enter image description here


The second way

You could avoid using ajax,just use window.location.href to reload the page(The view and controller are the same as yours,do not change like the first way):

<script>
    $(document).ready(function () {    
        $('#genderstring').on('change', function () {
            window.location.href = "/Home/Index?gender=" + $("#genderstring").val();               
        });

    });  
</script>

Result:

enter image description here

Note:

If you want to maintain the select list selected item,you may choose the first way,and modify your js like below:

<script>
    $(document).ready(function () {
        //ajax for posting gender to controller

        $('#genderstring').on('change', function () {
            var selected_item = $("#genderstring").val(); //add this ....

            $.ajax({
                url: '@Url.Action("Index", "Home")',
                type: 'GET',
                data: { gender: selected_item },
                success: function (res) {
                    $("#result").html(res);  
                    $("#genderstring").val(selected_item);   //add this....
                },
                error: function () {
                }
            });
        });

    });

</script>

Result:

enter image description here

Rena
  • 30,832
  • 6
  • 37
  • 72