Cascade DropDownList - c#

I have a cascade DropDownList, but in the second dropdown when I post data to controller the valeu property in the object that my action receives is null, and I dont know why.
My controller.
[HttpPost]
public JsonResult ListaEstados(String id)
{
var estados = Util.getEstados(id);
return Json(estados);
}
[HttpPost]
public ActionResult AddCidade(Cidade c)
{
c.Cadastrar(c);
return RedirectToAction("AddCidade");
}
My View
#model Projeto_P1.Models.Cidade
#{
ViewBag.Title = "Cadastro de Cidades";
}
#using (Html.BeginForm("AddCidade", "Geral", FormMethod.Post))
{
<div class="container">
<fieldset>
<div>
#Html.Label("Cidade")
#Html.EditorFor(model => model.Nome)
</div>
<div>
#Html.Label("País")
#Html.DropDownList("Pais", (SelectList)ViewData["paises"], "Selecione", new { id = "PaisID"})
</div>
<div>
#Html.Label("Estado")
#Html.DropDownListFor(model => model.Estado, Enumerable.Empty<SelectListItem>(), "Selecione")
</div>
<br />
<input type="submit" value="Cadastrar" />
</fieldset>
</div>
}
<script type="text/javascript">
$(document).ready(function () {
$("#PaisID").change(function () {
$.ajax({
url: "ListaEstados",
type: 'POST',
data: { ID: $(this).val() },
datatype: 'json',
success: function (data) {
var elements = "";
$.each(data, function () {
elements = elements + '<option values="' + this.ID + '">' + this.Nome + '</option>'
})
$('#Estado').empty().attr('disabled', false).append(elements);
}
});
});
});
</script>

Ive solved my problem, there is a S in ajax code, I have´t seen it: elements = elements + '<option values="' + this.ID...
I took it and it worked.

Related

Pass Id parameter into ajax function

AJAX function is not passing Id parameter to GET method in my controller.
I have this table.
#foreach (var user in Model)
{
<tr>
<td>#user.FirstName</td>
<td>#user.LastName</td>
<td>#user.Email</td>
<td>#string.Join(" , ", user.Roles.ToList())</td>
<td>
<a class="btn btn-primary" onclick="manageRolePopup('#Url.Action("Manage","Role", new {id=user.UserId },Context.Request.Scheme)')">Manage Roles</a>
<partial name="_RoleManagePopup.cshtml" />
</td>
</tr>
}
On click I want to show in popup user first name and last name so I have this in my Controller
[HttpGet]
public async Task<IActionResult> Manage(string userId)
{
var user = await _userManager.FindByIdAsync(userId);
ViewBag.FirstName = user.FirstName;
ViewBag.LastName = user.LastName;
var model = new ManageRoleViewModel();
List<string> roleNames = new List<string>();
foreach(var role in _roleManager.Roles)
{
model.RoleId = role.Id;
roleNames.Add(role.Name);
}
model.UserId = user.Id;
model.RoleNames = roleNames;
return View(model);
}
AJAX
manageRolePopup = (url) => {
$.ajax({
type: "GET",
url: url,
success: function (res) {
$("#form-modal .modal-body").html(res);
$("#form-modal").modal("show");
}
})
}
View
<form method="post" asp-controller="Role" asp-action="Manage" asp-route-UserId="#Model.UserId">
<div class="row">
<div class="col-3">
<h4>#ViewBag.FirstName #ViewBag.LastName</h4>
<div class="form-group">
<select asp-items="#new SelectList(Model.RoleNames)">
<option selected disabled>---Select New Role---</option>
</select>
</div>
</div>
</div>
</form>
When im passing Id like below, everything is good. User is not null, Id parameter also.
<a asp-controller="Role" asp-action="Manage" asp-route-UserId="user.UserId"></a>
Obviously I want to do UPDATE method but for now I just want to have it displayed.
you have to add userId to your ajax url
manageRolePopup = (userId) => {
var url = #Url.Action("Manage","Role");
$.ajax({
type: "GET",
url: url+"?UserId="+userId,
....
Since you have a list of UserIds you need or add UserId data attribute to you ancore tag, or push it as input parameter
<a class="btn btn-primary" onclick="manageRolePopup(#user.UserId)>Manage Roles</a>
but it is better to use modern javascript syntax
<script type="text/javascript">
$(document).ready(function () {
$(document).on("click", ".userBtn", (function (e) {
e.preventDefault();
e.stopImmediatePropagation();
var userId= this.id;
var url = #Url.Action("Manage","Role");
$.ajax({
type: "GET",
url: url+"?UserId="+userId,
....
}));
});
</script>
and view
<a id="#user.UserId" class="userBtn btn btn-primary"> Manage Roles </a>

Trying to change a textbox after an ajax call from a partial view

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

Jquery Autocomplete blank field

I have this issue with autocomplete, it returns something like this:This
But when you check what returns post method everything is as it should be but in view we get in return just blank field, instead of word "Hardware".
My Code:
Constructuor Method:
[HttpPost]
public JsonResult CreateJS(string prefix)
{
List<CategoryModel> list = new List<CategoryModel>();
list = _context.Categories.ToList();
var CatList = (from N in list
where N.Name.StartsWith(prefix)
select new { value = N.Name,label = N.Name });
return Json(CatList);
View:
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<script>
$(document).ready(function () {
$("#Category").autocomplete({
source: function (request, response) {
$.ajax({
url: "/Incident/CreateJS",
type: "POST",
dataType: "json",
data: { Prefix: request.term },
success: function (data) {
response($.map(data, function (item) {
return { label: item.Name, value: item.Name };
}))
}
})
},
messages: {
noResults: "", results: ""
}
});
})
</script>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="IncidentDescription" class="control-label"></label>
<input asp-for="IncidentDescription" class="form-control" />
<span asp-validation-for="IncidentDescription" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Title" class="control-label"></label>
<input asp-for="Title" class="form-control" />
<span asp-validation-for="Title" class="text-danger"></span>
</div>
<div class="form-group">
<label for="Category">Cat:</label>
<input type"text" name="Category" id="Category"/>
</div>
There is no need to use $.map in the ajax callback functiom. Directly apply the data to the response.
<script>
$(document).ready(function () {
$("#Category").autocomplete({
source: function (request, response) {
$.ajax({
url: "/Incident/CreateJS",
type: "POST",
dataType: "json",
data: { Prefix: request.term },
success: function (data) {
response(data);
}
})
},
});
})
</script>

MVC Ajax prevent redirect to action controller

In my view I have a modal window, it have the next form...
#using (Html.BeginForm("controllerAction", "Controller", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div class="container" id="editRecordForm">
<div class="row">
<div class="col-md-6">
#Html.LabelFor(model => model.Author)
#Html.TextBoxFor(model => model.Author, new { #class = "form-control", #style = "height:auto" })
#Html.ValidationMessageFor(model => model.Author)
</div>
</div>
<br/>
<div class="row">
<div class="col-md-6">
#Html.LabelFor(model => model.Image)
<input type="file" name="file" accept="image/*">
</div>
</div>
<br />
<input type="submit" value="Submit" class="btn btn-primary">
</div>
}
this is the JS that contains the ajax request
<script>
var formdata = new FormData($('form').get(0));
$('form').submit(function () {
if ($(this).valid()) {
$.ajax({
url: this.action,
type: this.method,
cache: false,
data: formdata,
success: function (status, data) {
console.log(data);
}
});
}
return false;
});
</script>
The action controller receives two parameters the model and file
[HttpPost]
public async Task<JsonResult> controllerAction(HttpPostedFileBase file, Model model)
{
var json = new
{
Success = true,
StatusCode = "200",
ErrorDesc = "OK",
ErrorCode = "",
NewId = ""
};
//some process
return Json(json, JsonRequestBehavior.AllowGet);
}
The problem is why when the controller action finish, it redirects to the action controller url
http://controller/action
and it does not stay on the same page?
What Im doing wrong?
You are not preventing the default action of the form.
$('form').submit(function (e) {
e.preventDefault();
if ($(this).valid()) {
$.ajax({
url: this.action,
type: this.method,
cache: false,
data: formdata,
success: function (status, data) {
console.log(data);
}
});
}
return false;
});
The problem was the bad config on the javascript- ajax part
$('form').submit(function () {
var formdata = new FormData($('form').get(0));
if ($(this).valid()) {
$.ajax({
url: this.action,
type: this.method,
cache: false,
processData: false,
contentType: false,
data: formdata,
success: function (status, data) {
console.log(data);
}
});
}
return false;
});
thanks to Stephen for the help.

Submit form with jquery ajax

I'm trying to learn MVC and one the things I want to do is submit a form to an action in my controller and this action will return the submitted data. Sounds simple but I've been trying for hours without any success.
my view:
#using (Html.BeginForm("BlogComment","Blog"))
{
#Html.ValidationSummary(true)
<legend class="AddAComment">Add a comment</legend>
<div class="commentformwrapper">
<div class="editor-text">
<span class="editor-label">User Name:</span>
</div>
<div class="editor-text">
<input type="text" id="username" />
</div>
<div class="editor-text">
<textarea id="comment" rows="6" cols="23"></textarea>
</div>
<div class="editor-field">
<input type="hidden" id="hiddendate" />
</div>
<input type="submit" id="submit" value="Create" />
</div>
}
my controller:
[HttpPost]
public ActionResult CommentForm(Comment comment)
{
Comment ajaxComment = new Comment();
ajaxComment.CommentText = comment.UserName;
ajaxComment.DateCreated = comment.DateCreated;
ajaxComment.PostId = comment.PostId;
ajaxComment.UserName = comment.UserName;
mRep.Add(ajaxComment);
uow.Save();
//Get all the comments for the given post id
return Json(ajaxComment);
}
and my js:
$(document).ready(function () {
$('form').submit(function () {
$.ajax({
url: '#Url.Action("CommentForm")',
type: "POST",
dataType: "json",
contentType: "application/json; charset=utf-8",
data: {
PostId: $('.postid').val(),
UserName: $('#username').val(),
DateCreated: new Date(),
CommentText: $('#comment').val()
},
success: function (result) {
alert("success " + result.UserName);
},
error: function (result) {
alert("Failed");
}
});
return false;
});
});
You don't need to write any client side code to do this, FYI.
To use the ajax methods successfully in MVC, you will need to do the following. Add this key to appsettings in web.config:
<appSettings>
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
As well as include the unobtrusive ajax script:
<script src="/Scripts/jquery.unobtrusive-ajax.min.js" type="text/javascript"></script>
Then create div container around your form and replace Html.BeginForm with Ajax.BeginForm
<div id="ajaxReplace">
#using (Ajax.BeginForm("BlogComment", "Blog", null, new AjaxOptions { UpdateTargetId = "ajaxReplace", OnSuccess = "doFunctionIfYouNeedTo", OnFailure = "ShowPopUpErrorIfYouWant" }))
{
#Html.ValidationSummary(true)
<legend class="AddAComment">Add a comment</legend>
<div class="commentformwrapper">
<div class="editor-text">
<span class="editor-label">User Name:</span>
</div>
<div class="editor-text">
<input type="text" id="username" />
</div>
<div class="editor-text">
<textarea id="comment" rows="6" cols="23"></textarea>
</div>
<div class="editor-field">
<input type="hidden" id="hiddendate" />
</div>
<input type="submit" id="submit" value="Create" />
</div>
}
</div>
Then in your controller you'll return something like this:
return PartialView(ajaxComment);
This will save you maintaining a script to do this manually and will funnel you into using the framework as intended. It will also help you out with data annotation validation and all of the juicy stuff that goes with it,
I hope this helps in some way.
Try this:
The Model
public class Comment
{
public string CommentText { get; set; }
public DateTime? DateCreated { get; set; }
public long PostId { get; set; }
public string UserName { get; set; }
}
The View and js
#model SubmitMvcForWithJQueryAjax.Models.Comment
#using (Html.BeginForm("BlogComment","Blog"))
{
#Html.ValidationSummary(true)
<legend class="AddAComment">Add a comment</legend>
<div class="commentformwrapper">
<div class="editor-text">
<span class="editor-label">User Name:</span>
</div>
<div class="editor-text">
#Html.EditorFor(m => m.UserName)
</div>
<div class="editor-text">
#Html.TextAreaFor(m => m.CommentText, new { rows="6", cols="23"} )
</div>
<div class="editor-field">
#Html.HiddenFor(m => m.DateCreated)
</div>
<div class="editor-field">
#Html.HiddenFor(m => m.PostId)
</div>
<input type="submit" id="submit" value="Create" />
</div>
}
<script type="text/javascript">
$(document).ready(function () {
$('form').submit(function () {
var serializedForm = $(this).serialize();
$.ajax({
url: '#Url.Action("CommentForm")',
type: "POST",
data: serializedForm,
success: function (result) {
alert("success " + result.UserName);
},
error: function (result) {
alert("Failed");
}
});
return false;
});
});
</script>
The Controller
public class CommentController : Controller
{
//
// GET: /Comment/
public ActionResult Index()
{
return View(new Comment());
}
[HttpPost]
public ActionResult CommentForm(Comment comment)
{
Comment ajaxComment = new Comment();
ajaxComment.CommentText = comment.UserName;
ajaxComment.DateCreated = comment.DateCreated ?? DateTime.Now;
ajaxComment.PostId = comment.PostId;
ajaxComment.UserName = comment.UserName;
//mRep.Add(ajaxComment);
//uow.Save();
//Get all the comments for the given post id
return Json(ajaxComment);
}
}
Basically you are passing javascript object literals directly. So, before you pass data to your controller, it must be in JSON format(because you have specified application/json. see your $.ajax call).
SO, you are missing JSON.stringify()
data: JSON.stringify({
PostId: $('.postid').val(),
UserName: $('#username').val(),
DateCreated: new Date(),
CommentText: $('#comment').val()
}),
OR
var someObj = {
PostId: $('.postid').val(),
UserName: $('#username').val(),
DateCreated: new Date(),
CommentText: $('#comment').val()
};
$.ajax({
/// your other code
data: JSON.stringify(someObj),
// your rest of the code
});
Instead of
data: {
PostId: $('.postid').val(),
UserName: $('#username').val(),
DateCreated: new Date(),
CommentText: $('#comment').val()
},
Try
$('form').submit(function () {
var obj = {
PostId: $('.postid').val(),
UserName: $('#username').val(),
DateCreated: new Date(),
CommentText: $('#comment').val()
};
$.ajax({
...,
data: JSON.stringify(obj),
...,
});
return false;
});
You have to convert data to string before sending it to server. and JSON.stringify does that job

Categories

Resources