Why does select2 return null? - asp.net-mvc

I have a class "MetaKeyword" and an a class "Article", which has a List MetaKeywords atributes. These metakeywords are stored in db and users select them for their articles via select2 in html. But this article atribute returns null, even though rawValue in ModelState has values.
Here's my controller code:
[HttpGet]
public IActionResult Create(Guid Id)
{
var article = new Article();
var Page = _dataManager.Pages.GetPageById(Id);
var Blog = _dataManager.Blogs.GetBlogById(Id);
ViewBag.KeywordId = new SelectList(_dataManager.MetaKeywords.GetMetaKeywords(), "Id", "Name");
if ((Page == null) && (Blog == null))
return NotFound();
else
return View(article);
}
[HttpPost]
public IActionResult Create(Article article, IFormFile titleImageFile)
I didn't list HtppPost action here as it may not help in solving the issue
And that's my html part resposible for MetaKeywords:
<div>
<label asp-for="MetaKeywords" class="control-label">Keywords</label>
<select asp-for="MetaKeywords" id="metakeyword" name="metakeywords" style="width:250px" multiple asp-items=#ViewBag.KeywordId>
<option value=""> -- Select MetaKeywords --</option>
</select>
</div>
Also a script:
<script type="text/javascript">
jQuery.noConflict()(function ($) {
$(document).ready(function() {
$('#metakeyword').select2({
allowClear: true
});
});
});
</script>

Related

ASP.NET MVC Select Drop Down list, set the default value and retrieve the selected value

The answer I am sure is simple. I have a <select> with a list of values. For edit mode, I want the drop down to show the current value and have the selected when the view renders. And also when the form is submitted take a possible new selected value and pass it back to the controller. Any help would be greatly appreciated.
From the view:
<td style="padding:15px">
<label asp-for="OrganizationTypeId" class="form-control-label" style="font-weight:bold">Organization</label>
<select asp-for="OrganizationTypeId" class="form-control" style="width:450px" asp-items="#(new SelectList(Model.orgTypes, "Id", "OrganizationName"))">
<option value="" disabled hidden selected>Select Organization....</option>
</select>
</td>
Code in the controller:
dr = _electedOfficials.getDeputyReg(jurisdictionId, Id);
dr.orgTypes = _electedOfficials.GetOrganizationTypes(jurisdictionId);
return View(dr);
OrgTypes class
public int Id { get; set; }
public string OrganizationName { get; set; }
One of the solutions is preparing list of the SelectListItem and return the selected item Id to the controller:
public ActionResult Index()
{
// ...
dr.orgTypes = _electedOfficials.GetOrganizationTypes(jurisdictionId);
var model = dr.orgTypes.Select(d => new SelectListItem() { Selected = (d.Id == /* id of default selection*/), Text = d.OrganizationName, Value = d.Id.ToString() }).ToList();
return View(model);
}
[HttpPost]
public ActionResult Index(int? seletedId)
{
if (ModelState.IsValid && seletedId.HasValue)
{
// Processing the selected value...
}
return RedirectToAction("Index");
}
In the view:
#model IEnumerable<SelectListItem>
<script type="text/javascript">
$(document).ready(function () {
var e = document.getElementById("OrgTypesList");
$("#SeletedId").val(e.options[e.selectedIndex].value);
});
function changefunc(val) {
$("#SeletedId").val($("#OrgTypesList").val());
}
</script>
#using (Html.BeginForm("Index", "Home"))
{
#* To pass `SeletedId` to controller *#
<input id="SeletedId" name="SeletedId" type="hidden" />
<label asp-for="OrganizationTypeId" class="form-control-label" style="font-weight:bold">Organization</label>
#Html.DropDownList("OrgTypesList", Model, "Select Organization...", new { #class = "form-control", #onchange = "changefunc(this.value)" })
<button type="submit" class="btn btn-primary">Save</button>
}

How to get selected value of DropDownList in Post method MVC

I'm a beginner in asp.net MVC. I have made a List property in the model which I'm updating in the Get Method. I'm binding that to the drop-down list in view using ViewBag. I'm trying to get the selected value of the dropdown list in the post method.
Below is the approach.
//UserRole Model
public UserRole()
{
UsersNotInRole = new List<string>();
}
public string Id { get; set; }
public List<string> UsersNotInRole { get; set; }
}
Updating list in UsersInRole [HttpGet] Action method:
[HttpGet]
public async Task<IActionResult> UsersInRole(string roleId, string roleName)
{
//Finds the role associated with the specified roleId if any.
var role = await roleManager.FindByIdAsync(roleId);
//initialize the model properties
var model = new UserRole
{
Id = role.Id
};
//add the users not in the role to the UsersNotInRole property in model
foreach (var user in userManager.Users)
{
if (!await userManager.IsInRoleAsync(user, role.Name))
{
model.UsersNotInRole.Add(user.UserName);
}
}
//Binding list to the drop-down list in view using ViewBag
ViewData["UsersNotInRole"] = new SelectList(model.UsersNotInRole);
return View(model);
}
AddUserToRole POST method:
[HttpPost]
public async Task<IActionResult> AddUserToRole(string roleId, string userName) //userName?? selected from UserNotInRole list
{
var user = await userManager.FindByNameAsync(userName);
if (user == null)
{
TempData["message"] = $"User selected cannot be found";
return RedirectToAction("UsersInRole", new { roleId = role.Id.ToString(), roleName = role.Name.ToString() });
}
// Add user to role
IdentityResult addResult = await userManager.AddToRoleAsync(user, userName);
return RedirectToAction("UsersInRole");
}
//View
#model UserRole
#{
ViewData["Title"] = $"Users In Role";
}
<h1>#ViewData["Title"]</h1>
<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group row">
<label class="control-label">Users not in role: </label>
<select asp-for="UsersNotInRole" class="form-control" asp-
items="ViewBag.UsersNotInRole"></select>
<button type="submit" asp-action="AddUserToRole" asp-route-roleId="#Model.Id" class="btn
btn-primary"> Add to Role</button>
</div>
</form>
Instead of select tag in you can use:
#Html.DropDownListFor(m => m.Id, ViewData["UsersNotInRole"] as SelectList)
Give your form tag an action and controller address, then put an input with submit type (or button), then pass your model as an input to the post action.
when user clicks the submit input (or button), model with users data gets back to the post action, the id of the dropdown gets back as well as other properties of the model.
<form method="post" action="/controller/action">
<button type="submit" class="btn btn-primary"> Add to Role</button>
</form>
and to show your dropdown, you can use #Html.DropDown() in your view. if you dont know how to work with that, use below link.
https://www.tutorialsteacher.com/mvc/htmlhelper-dropdownlist-dropdownlistfor
and your action post should be this:
[HttpPost]
public async Task<IActionResult> AddUserToRole(UserRole model)
{
return RedirectToAction("UsersInRole");
}

MVC 5 Layout page

I have an MVC site, and I use the same "_layout page" for all the view.
In _layout page, I have a select control.
What I want is to read the selected value of the control from the other pages.
Can you help me understand how to do?
Edit:
_Layout.cshtml
<div class="col-sm-4 col-xs-6">
<label class="col-sm-2 control-label" for="slt_Aziende">Azienda:</label>
<select id="mySharedSelectControl">
<option value="1">value 1</option>
<option value="2">value 2</option>
</select>
</div>
Index.cshtlm (using _Layout.cshtml)
#model IEnumerable<MySite.Models.MyModel>
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
MyModelController
public class MyModelController : Controller
{
public ActionResult Index()
{
//get value from mySharedSelectControl from Layout page
var selectedValueFromLayoutPage;
//do something
return View();
}
}
Based on what #Mairaj said is right i.e you can't directly read values of controls in your controller.
What you can do is create a JavaScript function like this:
$(document).ready(function () {
$("#mySharedSelectControl").change(function () {
var dropdownValue = $(this).val();
$.ajax({
url: "#Url.Action("PutValueinSession", "MyModel")", //Action method on which you want to send this dropdown value
data: { id: dropdownValue },
success: function (e) {
window.location = window.location;
}
});
});
});
You can create a method in which you can put this value in session and used across your whole page like below:
public JsonResult PutValueinSession(int id)
{
Session["DropdownControlValue"] = id;
return Json(new { Result = "" }, JsonRequestBehavior.AllowGet);
}
Now you can access this value on any page:
public ActionResult Index()
{
//get value from mySharedSelectControl from Layout page
var selectedValueFromLayoutPage=Session["DropdownControlValue"];
//do something
return View();
}
You can't directly read value of controls in Controller, you need to send the value of dropdown to the controller and than process what you want.
Or you can directly read value of dropdown from JavaScript in other views and do your processing.

How can send List<> Model From View To Controller using Ajax Jquery in Mvc3 asp.net?

How Can I Send List<int> Roles Model? For example from view To Controller.
Using Ajax Jquery in Mvc3 asp.net not razor.
I'm using this code
var url = '<%:Url.Action("Roles","RolesManager") %>';
$.ajax({
url: url,
type: 'post',
dataType: "json",
traditional: true,
data: $('#EditUserForm').serialize(),
success: function () {
$('#EditUserForm').submit();
},
error: function () {
}
});
but when I debug the controller List<int> Roles = null.
mode in page like
<%: Html.ListBoxFor(m => m.UserRoles, new MultiSelectList(Model.UserRoles, "UserRoleId", "UserRoleName"), new { #id = "UserRoles", #class = "ddlUserRolesCls" })%>
It's a Model Bind List, in this case, you have to send the information using the same name of your parameter in the name attribute of html inputs tag and asp.net model binder will convert it on a collection on the post. Your javascript looks fine. Try something like this:
In the view:
<input type="text" name="roles" value="1" />
<input type="text" name="roles" value="4" />
<input type="text" name="roles" value="2" />
<input type="text" name="roles" value="8" />
in the controller:
public ActionResult Post(List<int> roles)
{
// process
}
Also take a look at this article:
http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx
Change your viewmodel like this. Note that we have a SelectedUserRoles property of type int array.
public class EditUserRole
{
public List<SelectListItem> UserRoles{ get; set; }
public int[] SelectedUserRoles { set; get; }
//Also other relevant properties here
}
And in my Get Action, fill the UserRoles property
public ActionResult EditUser(int id)
{
var vm=new EditUserRole();
vm.UserRoles=GetUserRoles();
}
public List<SelectListItem> GetUserRoles()
{
var roles= new List<SelectListItem>();
// the below is hardcoded. Get it from DB And fill it here
roles.Add(new SelectListItem { Value="1",Text="Admin" });
roles.Add(new SelectListItem { Value = "2", Text = "Editor" });
return roles;
}
and in your view which is strongly typed to EditUserRole,
#Html.ListBoxFor(m => m.SelectedUserRoles,
new MultiSelectList(Model.UserRoles, "Value", "Text"),
new { #id = "UserRoles", #class = "ddlUserRolesCls" })
When you post your form, you will get the selected Roles ID in the SelectedUserRoles property of the posted model.
[HttpPost]
public ActionResult Edit(EditUserRole model)
{
// check model.SelectedUserRoles
// to do : Save and redirect
}

how to insert the selected value from DDL to DB by MVC Razor

hi I have MVC Razor application as e catalog and I used drop down-list to bind data from DB but the DDl bind the same value from DB as if I have three categories " x , Y , Z" the DDL returned similar values " Z ,Z , Z ".As it have the last value "y" . also I tried to insert the selected value "ID" to DB when user selected the item from DDL but I couldn't and it returned false selected value.
public class CategoryController : Controller
{
private AndriodContext db = new AndriodContext();
List<SelectListItem> items = new List<SelectListItem>();
List<string> category = new List<string>();
SelectListItem s = new SelectListItem();
//
// GET: /Category/
public ActionResult Index()
{
var x = db.Categories.Where(y => y.Active == true).ToList();
return View(x);
}
public ActionResult Create()
{
var data = db.Categories.ToList().Distinct();
List<string> x = new List<string>();
foreach (var t in data)
{
s.Text = t.Name;
s.Value = t.Cat_ID.ToString();
items.Add(s);
}
ViewBag.Parent = items;
return View();
}
//
// POST: /Category/Create
[HttpPost]
public ActionResult Create(Category category, IEnumerable<HttpPostedFileBase> files)
{
var data = db.Categories.ToList().Distinct();
List<SelectListItem> items = new List<SelectListItem>();
foreach (var t in data)
{
SelectListItem s = new SelectListItem();
s.Text = t.Name;
s.Value = t.Cat_ID.ToString();
items.Add(s);
if (s.Selected)
{ category.Parent_ID = int.Parse(s.Value); }
}
db.Categories.Add(category);
db.SaveChanges();
return RedirectToAction("Index");
}
}
#using (Html.BeginForm("Create", "Category", FormMethod.Post, new { enctype = "multipart/form-data", #data_ajax = "false" }))
{
#Html.ValidationSummary(true)
<fieldset>
<legend></legend>
<div class="editor-field create-Bt3">
#Html.DropDownList("Parent", new SelectList(ViewBag.Parent, "Value", "Text"), "- Select Parent -")
</div>
<div>
<p class="create-Bt ">
<input type="submit" value="Create" />
</p>
</div>
<br />
<br />
<div>
#Html.ActionLink("Back to List", "Index")
</div>
</fieldset>
}
you need to import jquery 1.7.1.min.js(DOM) in viewpage :
get the jquery DOM from jquery website(http://blog.jquery.com/2011/11/21/jquery-1-7-1-released/).
then in button click (<input type="submit" value="Create" onclick="GetDropDownValue();"/>) :
wrote a javascript function :
<script type="text/javascript" language="javascript">
function GetDropDownValue()
{
$("#hdnParentId").val($("#Parent").val());
}
</script>
The best practice to use a model to bind the dropdownlist instead of ViewBag.
If you don't want to use model the you can do one trick.
you put a hidden field(<input type="hidden" name="hdnParent" id="hdnParentId" />) in view page and calculate selected value of dropdownlis by simple jquery using :
$("#Parent").val();.
make the dropdownlist :
#Html.DropDownList("Parent", new SelectList(ViewBag.Parent, "Value", "Text"), "- Select Parent -",new{ id="Parent" });
After that you get a string parameter in HTTPPOST in controller :
[HttpPost]
public ActionResult Create(string hdnParent) //hdnParent is the name of dropdownlist
{
//now you can get the seleced value from "hdnParent".
//do the stuffs
return View();
}

Resources