I'm developing an MVC webpage, where I'm intending to do Create and Edit operations via a pop-up. So, the idea is I click on the 'Create' button, a modal-popup appears with all the model fields empty and allows user to input. In the same way, when user double clicks on any row, the row would open up for edit via the same pop-up, this time with the details filled from that row.
So, for reusage, I have decided to develop a single partial view(that would be the pop-up) and accept 'Model' as input.
My problem is, no matter what I do, I'm not able to make the partial view come up as pop-up. (Note: my main parent Index view would accpet input as List
Here is my code:
MY Index view:
#model List<TrackBuildConfig.DAL.Models.BuildModel>
#{
Layout = null;
}
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/MyScript.js" type="text/javascript"></script>
<script src="~/Scripts/bootstrap.min.js"></script>
<link href="~/Content/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
<div class="jumbotron">
<h1>Track Coverity and Nightly builds</h1>
<h4>on your own!</h4>
</div>
<div class="container-fluid">
<div class="row btn-group">
#Html.ActionLink("Create a new record", "SaveData", "Home", new { configID = 0 }, new { #class = "btn btn-primary modal-link", id = "btnCreate"})
</div>
<div class="modal fade" aria-labelledby="ModalLabel" id="modal-container" role="dialog" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content" style="width: 500px !important; margin:10px !important">
</div>
</div>
</div>
</div>
</body>
</html>
Script:
$(function () {
$('body').on('click', '.modal-link', function (e) {
e.preventDefault();
$('#btnCreate').attr('data-toggle', 'modal');
$('#btnCreate').attr('data-target', '#modal-container');
$('#modal-container').modal('show');
return true;
});
}
});
Partial view _PartialModal.csHtml
#model TrackBuildConfig.DAL.Models.BuildModel
#{
Layout = null;
}
<html>
<head>
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/MyScript.js"></script>
<script src="~/Scripts/bootstrap.min.js"></script>
<link href="~/Content/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
<div class="">
<div class="modal-header">
<button type="button" class="close" aria-hidden="true" data-dismiss="modal">×</button>
<h4>Configure Coverity and Nightly builds</h4>
</div>
<div class="modal-body" style="height: 400px;">
#using (Html.BeginForm("SaveData", "Home", FormMethod.Post))
{
<div class="row">
<div class="form-group row">
<div class="col-sm-4">
#Html.Label("Stream name", new { #class = "control-label" })
</div>
<div class="col-sm-6">
#Html.DropDownList("BuildLocations", (IEnumerable<SelectListItem>)ViewBag.BuildLocations, new { #class = "col-sm-6 form-control", id = "ddlBuildLocation" })
</div>
</div>
<div class="form-group row">
<div class="col-sm-4">
#Html.Label("Build Location", new { #class = "control-label" })
</div>
<div class="col-sm-6">
#Html.DropDownList("Streams", (IEnumerable<SelectListItem>)ViewBag.Streams, new { #class = "col-sm-6 form-control", id = "ddlStreams" })
</div>
</div>
<div class="form-group row">
<div class="col-sm-4">
<div class="checkbox">
<label>
#Html.CheckBoxFor(m => m.IsCoverity)
Enable Coverity
</label>
</div>
</div>
<div class="col-sm-8">
<div class="checkbox">
<label>
#Html.CheckBoxFor(m => m.IsNightly)
Enable Nightly build
</label>
</div>
</div>
<label style="color: red; font-weight: 300;" id="warningEnableBuild"></label>
</div>
<div class="form-group row">
#Html.Label("Email for Coverity", new { #class = "col-sm-4 control-label" })
<div class="col-sm-8" style="width: 100%">
#Html.TextAreaFor(m => m.EmailCoverity, new { #class = "form-control clsEmailCoverity", #placeholder = "Enter some value", #onkeyup = "return true;", #rows = "5", id = "txtEmailCoverity" })
#*<textarea id="txtEmailCoverity" class="form-control clsEmailCoverity" runat="server" rows="5" placeholder="Enter email IDs for Coverity builds" onkeyup="SetEmailForNightly()"></textarea>*#
<span class="help-block">Please add only comma separated addresses!</span>
<label style="color: red; font-weight: 300;" id="warningLabelCoverity"></label>
</div>
</div>
<div class="form-group row">
#Html.Label("Email for Nightly", new { #class = "col-sm-4 control-label" })
<div class="col-sm-8" style="width: 100%">
#Html.TextAreaFor(m => m.EmailNightly, new { #class = "form-control clsEmailNightly", #placeholder = "Enter some value", #onkeyup = "return true;", #rows = "5", id = "txtEmailNightly" })
#*<textarea id="txtEmailCoverity" class="form-control clsEmailCoverity" runat="server" rows="5" placeholder="Enter email IDs for Coverity builds" onkeyup="SetEmailForNightly()"></textarea>*#
<span class="help-block">Please add only comma separated addresses!</span>
<label style="color: red; font-weight: 300;" id="warningLabelNightly"></label>
</div>
</div>
<div class="modal-footer">
<button id="btnSave" class="btn btn-success" type="submit" role="button">Save changes</button>
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
</div>
</div>
}
</div>
</div>
</body>
</html>
Controller methods:
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
GetData getdata = new GetData();
return View(getdata.GetDataFromTable());
}
[HttpPost]
public ActionResult SaveData()
{
return View("Index");
}
//[HttpGet]
public ActionResult SaveData(int configID)
{
BuildModel model = new BuildModel();
PopulateBuildLocations();
PopulateStreams();
//Create
if (configID != 0)
{
GetData getdata = new GetData();
model = getdata.GetDataFromTable().Where(co => co.ConfigID == configID).FirstOrDefault();
}
else
{
model.BuildLocation = "";
model.EmailCoverity = "";
model.EmailNightly = "";
model.IsCoverity = false;
model.IsNightly = false;
}
return PartialView("_PartialModal", model);
}
public void PopulateBuildLocations()
{
string reportTypes = ConfigurationManager.AppSettings["ddlStreams"].ToString();
ViewBag.BuildLocations = reportTypes.Split('|')
.Select((text, value) => new SelectListItem { Text = text, Value = value.ToString() });
}
public void PopulateStreams()
{
List<string> lstStreams = new List<string>();
for (int i = 0; i < 6; i++)
{
lstStreams.Add("Stream " + i);
}
ViewBag.Streams = lstStreams.Select((text, value) => new SelectListItem { Text = text, Value = value.ToString() });
}
}
This is the link I used as reference. Reference
Please put my code in your visual studio and see that it works.
Controller/View Model/Classes:
public class BuildModel
{
public string theBuildModel { get; set; }
public int ConfigID { get; set; }
public string BuildLocation { get; set; }
public string EmailCoverity { get; set; }
public string EmailNightly { get; set; }
public bool IsCoverity { get; set; }
public bool IsNightly { get; set; }
}
public class GetData
{
public IList<BuildModel> GetDataFromTable()
{
IList<BuildModel> list = new List<BuildModel>();
var buildModel1 = new BuildModel { theBuildModel = "one" };
var buildModel2 = new BuildModel { theBuildModel = "two" };
var buildModel3 = new BuildModel { theBuildModel = "three" };
list.Add(buildModel1);
list.Add(buildModel2);
list.Add(buildModel3);
return list;
}
}
public class HomeController : Controller
{
[HttpPost]
public ViewResult SaveData(BuildModel buildModel)
{
GetData getdata = new GetData();
var model = getdata.GetDataFromTable();
return View("IndexStackOverflow", model);
}
[HttpGet]
public PartialViewResult SaveData(int configID)
{
BuildModel model = new BuildModel();
PopulateBuildLocations();
PopulateStreams();
//Create
if (configID != 0)
{
GetData getdata = new GetData();
model = getdata.GetDataFromTable().Where(co => co.ConfigID == configID).FirstOrDefault();
}
else
{
model.BuildLocation = "";
model.EmailCoverity = "";
model.EmailNightly = "";
model.IsCoverity = false;
model.IsNightly = false;
}
return PartialView("_PartialModal", model);
}
public void PopulateBuildLocations()
{
string reportTypes = ConfigurationManager.AppSettings["ddlStreams"].ToString();
ViewBag.BuildLocations = reportTypes.Split('|')
.Select((text, value) => new SelectListItem { Text = text, Value = value.ToString() });
}
public void PopulateStreams()
{
List<string> lstStreams = new List<string>();
for (int i = 0; i < 6; i++)
{
lstStreams.Add("Stream " + i);
}
ViewBag.Streams = lstStreams.Select((text, value) => new SelectListItem { Text = text, Value = value.ToString() });
}
public ActionResult IndexStackOverflow()
{
GetData getdata = new GetData();
return View(getdata.GetDataFromTable());
}
web.config:
<appSettings>
<add key="ddlStreams" value="text1|value1"/>
</appSettings>
View:
#model List<Testy20161006.Controllers.BuildModel>
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>IndexStackOverflow</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
#*YOU MUST PUT THE NEXT LINE FOLLOWING IN YOUR CODE-NUGET IF YOU NEED TO GET THE SCRIPT*#
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
</head>
<body>
<div class="jumbotron">
<h1>This is part of the Main Page</h1>
<h1>Partial View rendered in result</h1>
<h1>Track Coverity and Nightly builds</h1>
<h4>on your own!</h4>
</div>
<div class="container-fluid">
<div class="row btn-group">
#*#Html.ActionLink("Create a new record", "SaveData", "Home", new { configID = 0 },
new { #class = "btn btn-primary modal-link", id = "btnCreate" })*#
#using (Ajax.BeginForm("SaveData", "Home", new { configID = 0 },
new AjaxOptions
{
UpdateTargetId = "result",
InsertionMode = InsertionMode.Replace,
OnFailure = "error",
HttpMethod = "Get"
}))
{
<input id="btnCreate" type="submit" value="Create a new record" class="btn btn-primary modal-link" />
}
<div id="result"></div>
</div>
</div>
</body>
</html>
Partial View in shared folder:
#model Testy20161006.Controllers.BuildModel
<script type="text/javascript">
$(function () {
$('#myModal').modal('show');
})
</script>
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"
aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="myModalLabel">Configure Coverity and Nightly builds</h4>
</div>
<div class="modal-body">
<div class="modal-body" style="height: 400px;">
#using (Html.BeginForm("SaveData", "Home", FormMethod.Post))
{
<div class="row">
<div class="form-group row">
<div class="col-sm-4">
#Html.Label("Stream name", new { #class = "control-label" })
</div>
<div class="col-sm-6">
#Html.DropDownList("BuildLocations", (IEnumerable<SelectListItem>)ViewBag.BuildLocations, new { #class = "col-sm-6 form-control", id = "ddlBuildLocation" })
</div>
</div>
<div class="form-group row">
<div class="col-sm-4">
#Html.Label("Build Location", new { #class = "control-label" })
</div>
<div class="col-sm-6">
#Html.DropDownList("Streams", (IEnumerable<SelectListItem>)ViewBag.Streams, new { #class = "col-sm-6 form-control", id = "ddlStreams" })
</div>
</div>
<div class="form-group row">
<div class="col-sm-4">
<div class="checkbox">
<label>
#Html.CheckBoxFor(m => m.IsCoverity)
Enable Coverity
</label>
</div>
</div>
<div class="col-sm-8">
<div class="checkbox">
<label>
#Html.CheckBoxFor(m => m.IsNightly)
Enable Nightly build
</label>
</div>
</div>
<label style="color: red; font-weight: 300;" id="warningEnableBuild"></label>
</div>
<div class="form-group row">
#Html.Label("Email for Coverity", new { #class = "col-sm-4 control-label" })
<div class="col-sm-8" style="width: 100%">
#Html.TextAreaFor(m => m.EmailCoverity, new { #class = "form-control clsEmailCoverity", #placeholder = "Enter some value", #onkeyup = "return true;", #rows = "5", id = "txtEmailCoverity" })
#*<textarea id="txtEmailCoverity" class="form-control clsEmailCoverity" runat="server" rows="5" placeholder="Enter email IDs for Coverity builds" onkeyup="SetEmailForNightly()"></textarea>*#
<span class="help-block">Please add only comma separated addresses!</span>
<label style="color: red; font-weight: 300;" id="warningLabelCoverity"></label>
</div>
</div>
<div class="form-group row">
#Html.Label("Email for Nightly", new { #class = "col-sm-4 control-label" })
<div class="col-sm-8" style="width: 100%">
#Html.TextAreaFor(m => m.EmailNightly, new { #class = "form-control clsEmailNightly", #placeholder = "Enter some value", #onkeyup = "return true;", #rows = "5", id = "txtEmailNightly" })
#*<textarea id="txtEmailCoverity" class="form-control clsEmailCoverity" runat="server" rows="5" placeholder="Enter email IDs for Coverity builds" onkeyup="SetEmailForNightly()"></textarea>*#
<span class="help-block">Please add only comma separated addresses!</span>
<label style="color: red; font-weight: 300;" id="warningLabelNightly"></label>
</div>
</div>
<div class="modal-footer">
<button id="btnSave" class="btn btn-success" type="submit" role="button">Save changes</button>
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
</div>
</div>
}
</div>
</div>
</div>
</div>
</div>
Related
I have a button which add individualSearch partial view and individualSearch partial view also have a add button which adds individualSearcharacteristic partial view in it.
I want to bind BMRTestData model with individualSearch partial so that i can get the characteristic partial view data. So i store that data in IndividualSearch's list public List<Characteristic> Characteristics { get; set; } = new List<Characteristic>();
Please guide me to do same as i am new to .net .
Coding
//TestData(Main View)
#using ABC.Core.Models.DTOs
#model ABC.Core.Models.Api.BMRTestData
#using (Html.BeginForm())
{
<div class="card mb-3">
<h5 class="card-header">Response</h5>
<div class="card-body">
<div class="card-block">
<div class="form-group">
#Html.LabelFor(m => m.CompanyName, "Company Name", new { #class = "form-control-label" })
#Html.TextBoxFor(m => m.CompanyName, null, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.CompanyName)
</div>
<div id="searchindividuals" class="mb-3">
#if (Model?.IndividualSearches != null)
{
for (var i = 0; i < Model?.IndividualSearches.Count; i++)
{
<div class="form-group">
#{ Html.RenderPartial("IndividualSearchPartial", Model.IndividualSearches[i], new ViewDataDictionary()); }
</div>
}
}
</div>
<div class="mb-3">
<button id="add-search-individual" type="button" class="btn btn-success">Add Search Individual</button>
</div>
<button id="add-company-characteristic" type="button" class="btn btn-success">Add Characteristic</button>
</div>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
}
#section Scripts
{
function add(element){
var action = ' #Url.Action("NewIndividualSearchCharacteristic", "Blended")';
$.post(action)
.done(function (partialView) {
$(element.previousElementSibling).append(partialView);
});
}
</script>
}
//IndividualSearchPartial
#using (Html.BeginCollectionItem("IndividualSearches"))
{
<div id="individual-details" class="card">
<div class="form-horizontal">
<div class="card-block">
<div class="form-group">
#Html.LabelFor(m => m.SearchPostcode, "Search Post Code", new { #class = "form-control-label" })
#Html.TextBoxFor(m => m.SearchPostcode, null, new { #class = "form-control" })
</div>
</div>
</div>
<div class="card-block">
<div id="Characteristics" class="mb-3">
#if (Model?.Characteristics != null)
{
for (var i = 0; i < Model?.Characteristics.Count; i++)
{
<div class="form-group">
#{ Html.RenderPartial("IndividualSearchCharacterisiticPartial", Model.Characteristics[i], new ViewDataDictionary()); }
#* #Html.EditorFor(m => m.Characteristics);*#
</div>
}
}
</div>
<button id="add-characteristics" onclick="add(this)" type="button" class="btn btn-success">Add Characteristics</button>
</div>
</div>
}
// IndividualSearchCharacterisiticPartial
#model ABC.Core.Models.DTOs.Characteristic
#using (Html.BeginCollectionItem("Characteristics"))
{
<div id="characteristic-details" class="card">
<div class="form-horizontal">
<div class="card-block">
<div class="container">
<div class="row">
<div class="col-*-*">
#Html.LabelFor(m => m.Name, "Name", new { #class = "form-control-label" })
</div>
<div class="col">
#Html.TextBoxFor(m => m.Name, null, new { #class = "form-control" })
</div>
<div class="col-*-*">
#Html.LabelFor(m => m.Value, "Value", new { #class = "form-control-label" })
</div>
<div class="col">
#Html.TextBoxFor(m => m.Value, null, new { #class = "form-control" })
</div>
<div class="col-*-*">
<a id="characteristic-remove" href="#" onclick="removeCharacteristic(this)" class="btn btn-danger pull-right">Remove</a>
</div>
</div>
</div>
</div>
</div>
</div>
}
//IndividualSearch Class
namespace ABC.Core.Models.DTOs.Individual
{
public class IndividualSearch
{
public List<Characteristic> Characteristics { get; set; } = new List<Characteristic>();
}
}
namespace ABC.Core.Models.Api
{
public class BMRTestData : BMRRequest
{
public List<IndividualSearch> IndividualSearches { get; set; } = new List<IndividualSearch>();
}
}
Update
You can add onclick event in Add Search Individual button:
<button id="add-search-individual" type="button" class="btn btn-success" onclick="addSearch(this)">Add Search Individual</button>
Add an action in controller to return IndividualSearchPartial partial view:
[HttpPost]
public ActionResult IndividualSearchCharacteristic()
{
IndividualSearch individualSearch = new IndividualSearch() { };
return PartialView("IndividualSearchPartial", individualSearch);
}
Here is all the js in main view:
#section Scripts
{
<script>
function add(element){
var action = ' #Url.Action("NewIndividualSearchCharacteristic", "Default")';
$.post(action)
.done(function (partialView) {
$(element).parents('#individual-details').find("#Characteristics").append('<div class="form-group">' + partialView + '</div>');
ResetName();
});
}
function addSearch(element){
var action = ' #Url.Action("IndividualSearchCharacteristic", "Default")';
$.post(action)
.done(function (partialView) {
$(element).parents('.mb-3').find('#searchindividuals').append('<div class="form-group search">' + partialView + '</div>');
ResetName();
});
}
function ResetName() {
var index = 0;
$(".search").each(function () {
var nameIndex = 0; var valueIndex = 0;
$(this).find(":input[type='hidden']").each(function () {
$(this).removeAttr("name");
});
$(this).find(":input[type='text']").each(function () {
if ($(this).attr("name").indexOf("Characteristics") > -1 && $(this).attr("name").indexOf("Name") > -1) {
$(this).attr("name", "IndividualSearches[" + index + "].Characteristics[" + nameIndex + "].Name");
nameIndex++;
return;
}
if ($(this).attr("name").indexOf("Characteristics") > -1 && $(this).attr("name").indexOf("Value") > -1) {
$(this).attr("name", "IndividualSearches[" + index + "].Characteristics[" + valueIndex + "].Value");
valueIndex++;
return ;
}
if ($(this).attr("name").indexOf("IndividualSearches") > -1) {
$(this).attr("name", "IndividualSearches[" + index + "].SearchPostcode");
return;
}
});
index++;
})
}
</script>
}
After submit, it will enter into following action to receive BMRTestData data:
[HttpPost]
public IActionResult TestData(BMRTestData bMRTest)
{
return View();
}
Here is the test result:
My Register.cshtml page contains both Patient and Doctor registration. I have written a script to check if the user is Patient then displays only information relevant to patient and vice-versa.
If click on register patient then patient information only should insert into the database and the vice-versa for doctor registration.
Currently, If I register patient then it should not take specialization data into database because it is doctor's specific information.
Another problem is that, If I change the specialization or city value from drop down then it throws error:
The ViewData item that has the key 'Specialization' is of type
'System.String' but must be of type 'IEnumerable'.
Exception Details: System.InvalidOperationException: The ViewData item
that has the key 'Specialization' is of type 'System.String' but must
be of type 'IEnumerable'.
Source Error: #Html.DropDownListFor(x
=> Model.Specialization, Model.Specializations, htmlAttributes: new { #class = "form-control form-control-sm" })
Register.cshtml
model Aayumitra.Models.RegisterViewModel
<!-- Register Form -->
<div id="accounts-form">
<div class="account-nav">
<div class="row">
<div class="col-md-12 text-center">
<ul class="d-flex align-items-center justify-content-center">
<li>#Html.ActionLink("Login", "Login", "Account", null, new { #class = "mr-4" })</li>
<li>#Html.ActionLink("Register", "Register", "Account", null, new { #class = "active" })</li>
</ul>
</div>
</div>
</div>
<script>
function getUrlVars() {
var vars = {};
var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function (m, key, value) {
vars[key] = value;
});
return vars;
}
var text = getUrlVars()["profile"];
let profile;
if (text) {
if (text == 'doctor') {
profile = 'doctor';
}
if (text == 'patient') {
profile = 'patient';
}
} else {
profile = 'patient';
}
$(document).ready(function () {
if (profile === "doctor") {
$(".doctor").show();
}
else {
$(".doctor").hide();
}
});
</script>
<div class="container">
<div class="row py-5 border-top">
<div class="col-md-6">
<div class="form-img text-right">
<img src="~/Content/images/accounts.png" class="img-fluid" alt="Accounts Image">
</div>
</div>
<div class="col-md-5">
<div class="card">
<div id="form-card-header" class="card-header d-flex justify-content-between bg-white">
<h6>Join Aayumitra </h6>
<span class="float-right">Are you a Doctor? <span>#Html.ActionLink("register here", "register", "Account", new { profile = "doctor" }, null)</span>
</div>
<script>
var formCardHeader = document.getElementById('form-card-header');
if(profile == 'patient'){
formCardHeader.innerHTML = `
<h6>Join Aayumitra </h6>
<span class="float-right">Are you a Doctor? <span>#Html.ActionLink("register here", "register", "Account", new { profile="doctor"}, null)</</span>
`
}
if (profile == 'doctor'){
formCardHeader.innerHTML = `
<h6 id="join-doctors">Join 1000+ doctors</h6>
<span id="not-doctor" class=""text-primary>#Html.ActionLink("Not a doctor?", "register", "Account", new { profile="patient"}, null)</span>
`
}
</script>
#using (Html.BeginForm("Register", "Account", FormMethod.Post, new { #class = "form-horizontal", role = "form" }))
{
<div class="card-body">
<form action="register.chtml?profile=doctor">
<div class="form-group">
<label for="FullName">First Name</label>
#Html.TextBoxFor(m => m.FirstName, new { #class = "form-control form-control-sm", placeholder = "First Name" })
</div>
<div class="form-group">
<label for="FullName">Last Name</label>
#Html.TextBoxFor(m => m.LastName, new { #class = "form-control form-control-sm", placeholder = "First Name" })
</div>
<div class="form-group">
<label for="email">Email</label>
#Html.TextBoxFor(m => m.Email, new { #class = "form-control form-control-sm", placeholder = "Email ID" })
</div>
<div class="form-group doctor">
<label for="number">Specialization</label>
#Html.DropDownListFor(x => Model.Specialization, Model.Specializations, htmlAttributes: new { #class = "form-control form-control-sm", placeholder = "Specialization" })
</div>
<div class="form-group">
<label for="number">City</label>
#Html.DropDownListFor(x => Model.City, Model.Cities, htmlAttributes: new { #class = "form-control form-control-sm", placeholder = "City" })
</div>
<div class="form-group">
<label for="number">Mobile Number</label>
<div class="col-md-8">
<div class="form-group">
#Html.TextBoxFor(m => m.MobileNumber, new { #class = "form-control form-control-sm", placeholder = "Mobile Number" })
</div>
</div>
</div>
<div class="form-group">
<label for="password">Create Password</label>
#Html.PasswordFor(m => m.Password, new { #class = "form-control form-control-sm", placeholder = "Password" })
</div>
<div class="form-group">
<input type="submit" value="Send" class="btn btn-primary btn-block">
</div>
</form>
</div>
}
</div>
</div>
</div>
</div>
</div>
<!-- Register Form End -->
Controller
// GET: /Account/Register
[AllowAnonymous]
public ActionResult Register()
{
var model = new RegisterViewModel();
List<SelectListItem> SpecialitiesList = GetSpecialities();
List<SelectListItem> CitiesList = GetCities();
model.Specializations = SpecialitiesList;
model.Cities = GetCities();
return View(model);
}
//
// POST: /Account/Register
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
var user = new ApplicationUser { UserName = model.Email, Email = model.Email,FirstName=model.FirstName,LastName=model.LastName,City=model.City, IsDoctor = model.IsDoctor, NMC_Number = model.NMC_Number, Specialization = model.Specialization};
var result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
return RedirectToAction("Index", "Home");
}
AddErrors(result);
}
return View(model);
}
I think the best way to solve it write two register action(doctor,Patient)that doctor and Patient have own view
I have problem uploading videos in ASP.NET MVC. I m using HttpPostedfile base class to upload videos and I have a model for my videos to add extra field. I'm getting this error and don't know how to fix it.
The error I am getting is;
System.Data.SqlClient.SqlException: Procedure or function 'sAddNewVideoFile' expects parameter '#CourseName', which was not supplied.
Here is my code
Model
namespace eLearning.Models
{
public class FileModel
{
public int ID { get; set; }
public string Name { get; set; }
public Nullable<int> FileSize { get; set; }
public string FilePath { get; set; }
public int CourseID { get; set; }
public string CourseName { get; set; }
}
}
Controller
public ActionResult UploadVideos()
{
return View();
}
[HttpPost]
public ActionResult UploadVideos(HttpPostedFileBase fileupload)
{
if (fileupload != null)
{
var file = new FileModel();
string fileName = Path.GetFileName(fileupload.FileName);
int fileSize = fileupload.ContentLength;
int Size = fileSize / 1000;
fileupload.SaveAs(Server.MapPath("~/VideoFileUpload/" + fileName));
int CourseId = file.CourseID;
string CourseName = file.CourseName;
string CS = ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;
using (SqlConnection con = new SqlConnection(CS))
{
SqlCommand cmd = new SqlCommand("sAddNewVideoFile", con);
cmd.CommandType = CommandType.StoredProcedure;
con.Open();
cmd.Parameters.AddWithValue("#Name", fileName);
cmd.Parameters.AddWithValue("#FileSize", Size);
cmd.Parameters.AddWithValue("#FilePath", "~/VideoFileUpload/" + fileName);
cmd.Parameters.AddWithValue("#CourseID", CourseId);
cmd.Parameters.AddWithValue("#CourseName", CourseName);
cmd.ExecuteNonQuery();
}
}
return View();
}
Stored procedure:
CREATE procedure [dbo].[sAddNewVideoFile]
(#Name NVARCHAR(50),
#FileSize INT,
#FilePath NVARCHAR(100),
#CourseID INT,
#CourseName NVARCHAR(50)
)
AS
BEGIN
INSERT INTO Files (Name, FileSize, FilePath, CourseID, CourseName)
VALUES (#Name, #FileSize, #FilePath, #CourseID, #CourseName)
END
View
#model eLearning.Models.FileModel
#{
ViewBag.Title = "UploadVideos";
}
<h2>UploadVideo</h2>
<!DOCTYPE html>
<html>
<body>
<div class="container py-4">
<div class="card">
<div class="card-header bg-danger text-white">
<h6 class="text-uppercase">video List</h6>
</div>
<div class="card-body">
<div class="row">
<button style="margin-left: 27px; margin-bottom:10px;" type="button" class="btn btn-danger rounded-0" data-toggle="modal" data-target="#UploadVideo">
<i class="fa fa-plus-circle"></i> Add New
</button>
<div class="modal fade" id="UploadVideo">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Upload New video File</h4>
<button type="button" class="close" data-dismiss="modal">×</button>
</div>
<div class="modal-body">
#using (Html.BeginForm("UploadVideos", "File", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div class="form-group">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.CourseID, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.CourseID, new { htmlAttributes = new { #class = "form-control" } })
</div>
#Html.LabelFor(model => model.CourseName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.CourseName, new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>>
<label>Choose File:</label>
<div class="input-group">
<div class="custom-file">
<input type="file" id="fileupload" name="fileupload" class="custom-file-input" />
<label class="custom-file-label"></label>
</div>
<div class="input-group-append">
<input type="submit" id="btnUpload" class="btn btn-secondary" value="Upload" />
</div>
</div>
</div>
}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
The error can point out that the CourseName is null, try change it to:
cmd.Parameters.AddWithValue("#CourseName", CourseName ?? "");
if null is not allowed you have to check your model binder or model validation.
mabey about CourseName value if CourseName is null change it to string.Empty!
Form having dropdown country list when i click on submit button country ID value is passed to the controller..when i click on F10 keybord button country bind method is called .so again return to starting point so that again country value is Null Below i attached the screen shot:
<div class="page-content">
<div class="container-fluid">
<header class="section-header">
<div class="tbl">
<div class="tbl-row">
<div class="tbl-cell">
<h2>Company Registration Form</h2>
</div>
</div>
</div>
</header>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<section class="tabs-section">
<div class="tabs-section-nav tabs-section-nav-icons">
<div class="tbl">
<ul class="nav" role="tablist">
<li class="nav-item">
<a class="nav-link active" href="#tabs-1-tab-1" role="tab" data-toggle="tab">
<span class="nav-link-in">
<i class="font-icon font-icon-cogwheel"></i>
Company Registration Form
</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#tabs-1-tab-2" role="tab" data-toggle="tab">
<span class="nav-link-in">
<span class="glyphicon glyphicon-music"></span>
Company Social Network
</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#tabs-1-tab-3" role="tab" data-toggle="tab">
<span class="nav-link-in">
<i class="fa fa-product-hunt"></i>
Company Reference
</span>
</a>
</li>
</ul>
</div>
</div><!--.tabs-section-nav-->
<div class="tab-content">
<div role="tabpanel" class="tab-pane fade in active show" id="tabs-1-tab-1">
<br />
<br />
<section>
<div>
<div class="row">
<div class="col-lg-4">
<fieldset class="form-group">
#Html.LabelFor(model => Model.company.CompanyName, new { #class = "form-label semibold control-label" })
#Html.TextBoxFor(model => model.company.CompanyName, new { #class = "form-control", #id = "txtCompanyName", placeholder = "Enter the Company Name" })
#Html.ValidationMessageFor(model => model.company.CompanyName)
</fieldset>
</div>
<div class="col-lg-4">
<fieldset class="form-group">
#Html.LabelFor(model => model.company.ShortName, new { #class = "form-label semibold" })
#Html.TextBoxFor(model => model.company.ShortName, new { #class = "form-control", #id = "txtShortName", placeholder = "Enter the Short Name" })
#Html.ValidationMessageFor(model => model.company.ShortName)
</fieldset>
</div>
<div class="col-lg-4">
<fieldset class="form-group">
#Html.LabelFor(model => model.company.Division, new { #class = "form-label semibold" })
#Html.TextBoxFor(model => model.company.Division, new { #class = "form-control", #id = "txtDivision", placeholder = "Enter the Division" })
#Html.ValidationMessageFor(model => model.company.Division)
</fieldset>
</div>
</div><!--.row-->
<br />
<div class="row">
<div class="col-lg-4">
<fieldset class="form-group">
#Html.LabelFor(model => model.company.Email, new { #class = "form-label semibold" })
#Html.TextBoxFor(model => model.company.Email, new { #class = "form-control", #id = "txtEmail", placeholder = "Enter your Email" })
#Html.ValidationMessageFor(model => model.company.Email)
</fieldset>
</div>
<div class="col-lg-4">
<fieldset class="form-group">
#Html.LabelFor(model => model.company.Address1, new { #class = "form-label semibold" })
#Html.TextBoxFor(model => model.company.Address1, new { #class = "form-control", #id = "txtAddress1", placeholder = "Enter your Address Line 1" })
#Html.ValidationMessageFor(model => model.company.Address1)
</fieldset>
</div>
<div class="col-lg-4">
<fieldset class="form-group">
#Html.LabelFor(model => model.company.Address2, new { #class = "form-label semibold" })
#Html.TextBoxFor(model => model.company.Address2, new { #class = "form-control", #id = "txtAddress2", placeholder = "Enter your Address Line 2" })
</fieldset>
</div>
</div><!--.row-->
<br />
<div class="row">
<div class="col-lg-4">
<fieldset class="form-group">
#Html.LabelFor(model => model.company.Country, new { #class = "form-label semibold" })
#Html.DropDownList("Country", null, "--- Select Country ---", new { #class = "select2-arrow" })
</fieldset>
</div>
<div class="col-lg-4">
<fieldset class="form-group">
#Html.LabelFor(model => model.company.State, new { #class = "form-label semibold" })
<select id="state" class="select2-arrow"></select>
</fieldset>
</div>
<div class="col-lg-4">
<fieldset class="form-group">
#Html.LabelFor(model => model.company.City, new { #class = "form-label semibold" })
<select id="city" class="select2-arrow"></select><br />
</fieldset>
</div>
</div><!--.row-->
<br />
<div class="row">
<div class="col-lg-4">
<fieldset class="form-group">
#Html.LabelFor(model => model.company.Pincode, new { #class = "form-label semibold" })
#Html.TextBoxFor(model => model.company.Pincode, new { #class = "form-control", #id = "txtPincode", placeholder = "Enter your Pincode" })
#Html.ValidationMessageFor(model => model.company.Pincode)
</fieldset>
</div>
<div class="col-lg-4">
<fieldset class="form-group">
#Html.LabelFor(model => model.company.CountryCode, new { #class = "form-label semibold" })
#*#Html.DropDownList("CountryCode", null, "---Select CountryCode---", new { #class = "select2-arrow" })*#
</fieldset>
</div>
<div class="col-lg-4">
<fieldset class="form-group">
#Html.LabelFor(model => model.company.MobileNo, new { #class = "form-label semibold" })
#Html.TextBoxFor(model => model.company.MobileNo, new { #class = "form-control", #id = "txtMobileNo", placeholder = "Enter your Mobile Number" })
#Html.ValidationMessageFor(model => model.company.MobileNo)
</fieldset>
</div>
</div><!--.row-->
<br />
<div class="row">
<div class="col-lg-4">
<fieldset class="form-group">
#Html.LabelFor(model => model.company.PhoneNo, new { #class = "form-label semibold" })
#Html.TextBoxFor(model => model.company.PhoneNo, new { #class = "form-control", #id = "txtPhoneNo", placeholder = "Enter your PhoneNo" })
</fieldset>
</div>
<div class="col-lg-4">
<fieldset class="form-group">
#Html.LabelFor(model => model.company.PanNo, new { #class = "form-label semibold" })
#Html.TextBoxFor(model => model.company.PanNo, new { #class = "form-control", #id = "txtPanNo", placeholder = "Enter Company PanNo" })
</fieldset>
</div>
<div class="col-lg-4">
<fieldset class="form-group">
#Html.LabelFor(model => model.company.TinNo, new { #class = "form-label semibold" })
#Html.TextBoxFor(model => model.company.TinNo, new { #class = "form-control", #id = "txtTinNo", placeholder = "Enter Company TinNo" })
</fieldset>
</div>
</div><!--.row-->
<br />
<div class="row">
<div class="col-lg-4">
<fieldset class="form-group">
#Html.LabelFor(model => model.company.GSTno, new { #class = "form-label semibold" })
#Html.TextBoxFor(model => model.company.GSTno, new { #class = "form-control", #id = "txtGSTno", placeholder = "Enter Company GSTno" })
</fieldset>
</div>
<div class="col-lg-4">
<fieldset class="form-group">
#Html.LabelFor(model => model.company.IECCode, new { #class = "form-label semibold" })
#Html.TextBoxFor(model => model.company.IECCode, new { #class = "form-control", #id = "txtIECCode", placeholder = "Enter Company IECCode" })
</fieldset>
</div>
</div><!--.row-->
<br />
<div class="row">
<div class="col-lg-4">
<fieldset class="form-group">
<label class="form-label semibold">Upload Company Logo</label>
<input type="file" name="file" id="txtUploadImage" style="cursor:pointer;" />
</fieldset>
</div>
<div class="col-lg-4">
<fieldset class="form-group">
<label class="form-label semibold">Perview Image</label>
<img id="image_upload_preview" src="http://placehold.it/100x100" alt="your image" />
<a id="remove" onclick="javascript:ClearFileUploadControl();" style="display: none; cursor: pointer;">Remove</a>
</fieldset>
</div>
</div>
<br />
<input type="submit" name="Submit" id="SaveCompany" value="Save" class="btn btn-rounded btn-inline btn-success" />
</div>
</section>
</div><!--.tab-pane-->
<div role="tabpanel" class="tab-pane fade" id="tabs-1-tab-2">
<br />
<section>
<div>
<div class="row">
<div class="col-lg-4">
<fieldset class="form-group">
#Html.LabelFor(model => model.CompanySocial.FaceBookID, new { #class = "form-label semibold" })
#Html.TextBoxFor(model => model.CompanySocial.FaceBookID, new { #class = "form-control", #id = "txtFaceBookID", placeholder = "Enter the Facebook Link" })
</fieldset>
</div>
<div class="col-lg-4">
<fieldset class="form-group">
#Html.LabelFor(model => model.CompanySocial.TwitterID, new { #class = "form-label semibold" })
#Html.TextBoxFor(model => model.CompanySocial.TwitterID, new { #class = "form-control", #id = "txtTwitterID", placeholder = "Enter the Twitter Link" })
</fieldset>
</div>
<div class="col-lg-4">
<fieldset class="form-group">
#Html.LabelFor(model => model.CompanySocial.linkedinID, new { #class = "form-label semibold" })
#Html.TextBoxFor(model => model.CompanySocial.linkedinID, new { #class = "form-control", #id = "txtlinkedinID", placeholder = "Enter the Linkedin Link" })
</fieldset>
</div>
</div><!--.row-->
</div>
</section>
<input type="submit" name="Submit" value="Previous" class="btn btn-rounded btn-inline btn-primary prev-step " />
<input type="submit" name="Submit" id="saveSocial" value="Next" class="btn btn-rounded btn-inline btn-success" />
</div><!--.tab-pane-->
<div role="tabpanel" class="tab-pane fade" id="tabs-1-tab-3">
Tab 3
<br />
<br />
<input type="submit" name="Submit" value="Previous" class="btn btn-rounded btn-inline btn-primary prev-step" />
<input type="submit" name="Submit" value="Finish" class="btn btn-rounded btn-inline btn-success" />
</div><!--.tab-pane-->
</div><!--.tab-content-->
</section><!--.tabs-section-->
}
</div>
</div>
Scripts:
<script>
function GetInfo() {
var Company = {
CompanyName: $("#txtCompanyName").val(), ShortName: $("#txtShortName").val(), Division: $("#txtDivision").val(), Email: $("#txtEmail").val(), Address1: $("#txtAddress1").val(), Address2: $("#txtAddress2").val(), Country: $("#Country").val(), State: $("#state").val(), City: $("#city").val(),
Pincode: $("#txtPincode").val(), MobileNo: $("#txtMobileNo").val(), PhoneNo: $("#txtPhoneNo").val(), PanNo: $("#txtPanNo").val(), TinNo: $("#txtTinNo").val(), GSTno: $("#txtGSTno").val(), IECCode: $("#txtIECCode").val()
};
var mainModel = {};
mainModel.Company = Company;
$.ajax({
type: "POST",
url: "/Company/AddCompany",
data: JSON.stringify(mainModel),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: OnSuccess,
failure: function (response) {
alert(response.d);
}
});
}
function OnSuccess(response) {
alert(response.d);
}
$(document).ready(function () {
$("#saveSocial").click(function (e) {
e.preventDefault();
GetInfo1();
});
$("#SaveCompany").click(function (e) {
//e.preventDefault();
GetInfo();
});
});
function GetInfo1() {
var Social = { FaceBookID: $("#txtFaceBookID").val(), TwitterID: $("#txtTwitterID").val(), linkedinID: $("#txtlinkedinID").val() };
var mainModel = {};
mainModel.CompanySocial = Social;
$.ajax({
type: "POST",
url: "/Company/AddSocial",
data: JSON.stringify(mainModel),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: OnSuccess,
failure: function (response) {
alert(response.d);
}
});
}
</script>
<script>
$(document).ready(function () {
$("#Country").change(function () {
var id = $(this).val();
$("#state").empty();
$.get("State_Bind", { CountryID: id }, function (data) {
var v = "<option>--- Select State ---</option>";
$.each(data, function (i, v1) {
v += "<option value=" + v1.Value + ">" + v1.Text + "</option>";
});
$("#state").html(v);
});
});
$("#state").change(function () {
var id = $(this).val();
$("#city").empty();
$.get("City_Bind", { StateID: id }, function (data) {
var v = "<option>--- Select City---</option>";
$.each(data, function (i, v1) {
v += "<option value=" + v1.Value + ">" + v1.Text + "</option>";
});
$("#city").html(v);
});
});
});
</script>
Class value:
public int Country { get; set; }
public int State { get; set; }
public int City { get; set; }
Screen shot:
ActionResult:
[HttpPost]
public ActionResult AddCompany(MainModel mainModel)
{
try
{
Country_Bind();
if (ModelState.IsValid)
{
dp obj = new dp();
if (obj.AddNewCompany(mainModel))
{
ViewBag.Message = "Company added successfully";
}
}
return View();
}
catch
{
return View();
}
}
Country code:
public void Country_Bind()
{
DataSet ds = dblayer.Get_Country();
List<SelectListItem> coutrylist = new List<SelectListItem>();
foreach (DataRow dr in ds.Tables[0].Rows)
{
coutrylist.Add(new SelectListItem { Text = dr["CountryName"].ToString(), Value = dr["CountryID"].ToString() });
}
ViewBag.Country = coutrylist;
}
You are currently calling the Country_Bind() method as the first statement inside your httppost action method. You actually need to do that when you want to rerender the dropdown list when re rendering the same view.
If you are not doing an ajax post,You should follow the PRG pattern. On successful save of the data, you should redirect to the GET action method which render the view. If the Modelstate validation fails, that is when you return the same view (so that you can show the validation message to user) and you need to repopulate the dropdown data before that.
When you do a Redirect, ViewData does not work to transfer messages.Use TempData instead.
[HttpPost]
public ActionResult AddCompany(MainModel mainModel)
{
try
{
if (ModelState.IsValid)
{
dp obj = new dp();
if (obj.AddNewCompany(mainModel))
{
TempData.Message = "Company added successfully";
return RedirectToAction("CompanyList");
}
}
// We need to repopulate the data needed for rendering dropdown
Country_Bind();
return View(mainModel);
}
catch(Exception ex)
{
// to do : Make sure to log the error
return View("Error");
}
}
In your case, when you do an ajax post returning a redirect result does not makes sense. You may return the url to the next page if needed as part of a json response and use that in your ajax calls success/done event handler and do appropriate things (redirect to the new page/show a message to user)
[HttpPost]
public ActionResult AddCompany(MainModel mainModel)
{
try
{
if (ModelState.IsValid)
{
dp obj = new dp();
if (obj.AddNewCompany(mainModel))
{
return Json(new { Message="Company added successfully"});
}
}
return Json(new { Message="Validation errors!"});
}
catch(Exception ex)
{
// must log the exception
return Json(new { Message="Error "});
}
}
Make sure to update your success/done event handler of your ajax call to read the response (the json and do something like showing message to user/hiding or showing the next tab)
I also noticed an issue with your ajaxifying code. Since you are making an ajax form submission, you should prevent the default form submit behavior by calling the event.preventDefault method.
$("#SaveCompany").click(function (e) {
e.preventDefault();
GetInfo();
});
I would also recommend to use a flat-lean view model specific for the view. So your properties will not be nested level and when you use the helper methods (TextBoxFor etx), It will generate the correct input field names and you do not need to manually build the Js object you want to send. You may simply use the jquery serialize() method on your form object and send that as the data for the ajax call.
I´m writing a project to manage a pool of users of asp.net identity 2.0, and i want to create a user and add roles to the user in the same view, so when i post the model just simple create the user and add the roles in the same action.
I don't know how to generate the roles list for the user, for example i have a dropdownlist for with the roles and id´s and my view is something like this
<div class="form-horizontal">
<div class="col-md-6">
<div class="panel panel-info">
<div class="panel-heading">Datos personales</div>
<div class="panel-body">
<div class="form-group">
<div class="col-md-4">
#Html.DisplayNameFor(m => m.User.Nombre)
</div>
<div class="col-md-8">
#Html.TextBoxFor(m => m.User.Nombre, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
<div class="col-md-4">
#Html.DisplayNameFor(m => m.User.Apellido)
</div>
<div class="col-md-8">
#Html.TextBoxFor(m => m.User.Apellido, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
<div class="col-md-4">
#Html.DisplayNameFor(m => m.User.DependenciaId)
</div>
<div class="col-md-8">
#Html.DropDownListFor(m => m.User.DependenciaId, new SelectList(ViewBag.ListaDependencia, "Id", "Descripcion"), "Ninguno", new { #class = "form-control" })
</div>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="panel panel-info">
<div class="panel-heading">Datos usuario</div>
<div class="panel-body">
<div class="form-group">
<div class="col-md-4">
#Html.DisplayNameFor(m => m.User.UserName)
</div>
<div class="col-md-8">
#Html.TextBoxFor(m => m.User.UserName, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
<div class="col-md-4">
#Html.DisplayNameFor(m => m.User.NetUser)
</div>
<div class="col-md-8">
#Html.TextBoxFor(m => m.User.NetUser, new { #class = "form-control" })
</div>
</div>
</div>
</div>
</div>
<div class="panel panel-info">
<div class="panel-heading">Datos usuario</div>
<div class="panel-body">
<div class="form-group">
<div class="col-md-4">
#Html.DisplayNameFor(m => m.User.Roles)
</div>
<div class="col-md-8">
#Html.DropDownListFor(m => m.User.Roles, new SelectList(ViewBag.RolesList, "Id", "Name"), "Ninguno", new { #class = "form-control" })
</div>
</div>
<table>
Here must present the roles to add to the user
</table>
</div>
</div>
I found a way
first a helper for offline collections, that a i found on internet
public static class HtmlPrefixScopeExtensions
{
private const string idsToReuseKey = "__htmlPrefixScopeExtensions_IdsToReuse_";
public static IDisposable BeginCollectionItem(this HtmlHelper html, string collectionName)
{
if (html.ViewData["ContainerPrefix"] != null)
{
collectionName = string.Concat(html.ViewData["ContainerPrefix"], ".", collectionName);
}
var idsToReuse = GetIdsToReuse(html.ViewContext.HttpContext, collectionName);
var itemIndex = idsToReuse.Count > 0 ? idsToReuse.Dequeue() : Guid.NewGuid().ToString();
var htmlFieldPrefix = string.Format("{0}[{1}]", collectionName, itemIndex);
html.ViewData["ContainerPrefix"] = htmlFieldPrefix;
// autocomplete="off" is needed to work around a very annoying Chrome behaviour whereby it reuses old values after the user clicks "Back", which causes the xyz.index and xyz[...] values to get out of sync.
html.ViewContext.Writer.WriteLine("<input type=\"hidden\" name=\"{0}.index\" autocomplete=\"off\" value=\"{1}\" />", collectionName, html.Encode(itemIndex));
return BeginHtmlFieldPrefixScope(html, htmlFieldPrefix);
}
public static IDisposable BeginHtmlFieldPrefixScope(this HtmlHelper html, string htmlFieldPrefix)
{
return new HtmlFieldPrefixScope(html.ViewData.TemplateInfo, htmlFieldPrefix);
}
private static Queue<string> GetIdsToReuse(HttpContextBase httpContext, string collectionName)
{
// We need to use the same sequence of IDs following a server-side validation failure,
// otherwise the framework won't render the validation error messages next to each item.
var key = idsToReuseKey + collectionName;
var queue = (Queue<string>)httpContext.Items[key];
if (queue == null)
{
httpContext.Items[key] = queue = new Queue<string>();
var previouslyUsedIds = httpContext.Request[collectionName + ".index"];
if (!string.IsNullOrEmpty(previouslyUsedIds))
foreach (var previouslyUsedId in previouslyUsedIds.Split(','))
queue.Enqueue(previouslyUsedId);
}
return queue;
}
private class HtmlFieldPrefixScope : IDisposable
{
private readonly TemplateInfo templateInfo;
private readonly string previousHtmlFieldPrefix;
public HtmlFieldPrefixScope(TemplateInfo templateInfo, string htmlFieldPrefix)
{
this.templateInfo = templateInfo;
previousHtmlFieldPrefix = templateInfo.HtmlFieldPrefix;
templateInfo.HtmlFieldPrefix = htmlFieldPrefix;
}
public void Dispose()
{
templateInfo.HtmlFieldPrefix = previousHtmlFieldPrefix;
}
}
then using an editor template
<tr>
#using (Html.BeginCollectionItem("ListaObraSocialPrepagasSeleccionadas"))
{
<td>
<input type="radio" name="RolesUserTableRadio" />
#Html.HiddenFor(model => model.Id, new { #readonly = "readonly" })
</td>
<td>
#Html.HiddenFor(model => model.Id, new { #readonly = "readonly" })
#Html.DisplayTextFor(model => model.Name)
</td>
}
a partial view to manage the list
<script type="text/javascript">
$(document).ready(function () {
$("#btnAddRoles").click(function () {
var rolId = $("#ddRoles").val();
if (rolId == null || rolId == '') {
alert("Debe seleccionar un rol.");
return;
}
var foundRol = $("#RolesUserTable").find("input[value='" + rolId + "']");
if (foundRol.size() > 0) {
alert("Ya se ha agregado el rol.");
return;
}
$.ajax({
url: '#Url.Action("AddRoles", "Users")',
data: {
rolId: rolId
},
type: 'GET',
contentType: 'application/x-www-form-urlencoded',
success: function (data) {
if (data.Valid) {
$("#RolesUserTable").append(data.html);
} else {
alert('El rol seleccionado no existe');
}
},
error: function (jqXHR, exception) {
alert('Error durante la llamada al servidor.' + jqXHR.responseText);
},
complete: function () {
}
});
});
$("#btnDeleteRoles").click(function () {
var myRadio = $('input[name=RolesUserTableRadio]');
var radio = myRadio.filter(':checked');
if (radio.size() == 0) {
alert("Debe seleccionar un rol.");
return;
}
if (!confirm("¿Confirma que desea eliminar el rol seleccionado?")) {
return;
}
$(radio).closest('tr').remove();
});
});
</script>
<div style="width: 100%; overflow-x: auto;">
<table id="RolesUserTable" class="table table-striped">
<thead>
<tr>
<th></th>
<th>Rol</th>
</tr>
</thead>
#Html.EditorFor(m => m.Roles)
</table>
</div>
and finnaly the dropdown and the table
<div class="form-group">
<label for="ddRoles" class="col-sm-2 control-label">Roles</label>
<div class="col-sm-3">
#Html.DropDownList("ddRoles", new SelectList(ViewBag.Roleslist, "Id", "Name", null), "Seleccione un rol", new { #class = "selectpicker", data_live_search = "true" })
</div>
<div class="btn-group">
<button id="btnAddRoles" type="button" class="btn btn-default"><span class="glyphicon glyphicon-plus"></span></button>
<button id="btnDeleteRoles" type="button" class="btn btn-default"><span class="glyphicon glyphicon-minus"></span> </button>
</div>
</div>
<div>
#Html.Partial("_Roles")
</div>