Handling dynamically generated html elements using jquery mvc5 - javascript

Im developing a mvc5 application. In a view, using jquery i generate html elements(dropdownlists and textboxes) dynamically.
View briefly
#using (#Html.BeginForm("Save", "Item"))
{
#Html.DropDownListFor(a => a.MainGrpId, new SelectList(ViewBag.mnGrpList, "MainGroupId", "MainGroupName"), " Select a MainGroup", new { Class = "form- control", title = "", style = "width:175px;height:30px; margin-top:6px;" })
#Html.DropDownListFor(a => a.SubGrpId, new SelectList(ViewBag.sbGrpList, "SubGroupId", "SubGroupName"), " Select a SubGroup", new { Class = "form-control", title = "", style = "width:175px;height:30px; margin-top:6px;" })
<div id="ss" class="col-md-6">
</div>
#Html.TextBoxFor(a=>a.ItemName, new { Class = "form-control", placeholder = " Item Name", TextMode = "MultiLine2", onkeyup = "return validateChar(this)", style = "width:175px;height:25px;" })
<input type="submit" value="Save" class="btn btn-success" />
}
Jquery
var ss = $('#ss');
$('#SubGrpId').change(function () {
$('#ss').empty();
$.ajax({
url: '#Url.Action("FillItem", "Item")', // dont hard code your url's
type: "GET",
dataType: "JSON",
data: { MnId: $('#MainGrpId').val(), SbId: $(this).val() }, // pass the selected value
success: function (y) {
$.each(y, function (l, u) {
// add the label
var label = u.Name;
var name = 'Field' + l;
var label = $('<label></label>').text(label).attr('for', name);
ss.append(label);
if (u.Options.length==0) {
// There is only one item and its for generating a textbox
var input = $('<input>').attr({ type: 'text', id: name, name: name });
ss.append(input);
} else {
// Its a select
var select = $('<select></select>').attr({ id: name, name: name });
// add each option
$.each(u.Options, function (i, option) {
select.append($('<option></option>').val(option.Value).text(option.Text));
})
ss.append(select);
}
});
},
error: function () {
alert("something wrong");
}
});
});
ItemViewModel
public class ItemViewModel
{
public string ItemName { get; set; }
public int MainGrpId { get; set; }
public int SubGrpId { get; set; }
public string Field0 { get; set; }
public string Field1 { get; set; }
public string Field2 { get; set; }
public string Field3 { get; set; }
public string Field4 { get; set; }
public string Field5 { get; set; }
}
Altogether number of dynamically generated ddls+textboxes are equal or less than 6. What i want to do is when user selects an item from a ddl or enters a value to a texbox, the value in that particular element(string) should be shown in 'ItemName' textbox. User can go on adding like that. Each added value(string) should be shown separated by a space in 'ItemName' textbox.
Futher every ddl and textbox(only dynamically generated ones-Field0, Field1, Field2, Field3, Field4, Field5, ) should get enabled one by one(one after another) allowing user to select(ddls)/enter(textboxes). But im struggling to develop the correct jquery function for this whole scenario. Pls help me with this. Thanks!

Related

How do you append a select with a asp-item tag helper

I have a functionality where I append a select html when a button is clicked using jQuery. I already have a select which uses a asp-item tag helper to fill it with my corresponding model. The platform I'm using is asp-net core 2.2 and I'm using a razor page for my page.
My question is how do I edit my jQuery so that when I clicked the button, the asp-item is already loaded into the select?
Here is my jQuery code:
$("#AddButton").click(function () {
tc = tc + 1;
$("#totalContacts").val(tc)
$(".addselection").append('<div> <select class="form-control" name="[' + (tc) + '].DriverID" asp-for="TripDrivers.DriverID" asp-items="Model.DriverList" > <option value = ""> Select a driver </option></select></div>')
});
and this is my OnGet to load the items
public IActionResult OnGet()
{
DriverList = _context.Drivers.Select(a =>
new SelectListItem
{
Value = a.ID.ToString(),
Text = a.FullName
}).ToList();
}
This is my first ever question, so please bear with me if there are any grammatical errors or missing information. I'll add them if necessary.
EDIT: Here is the design I'm trying to do.
Once the plus button is clicked. It should add a row of dropdownlist each with the option being loaded from the list on the OnGet method.
ANOTHER EDIT: As per user #itminus instructions, I've created a one sample page and a partial view to apply the code given below.
Here is what my FirstPage.cshtml looks like
#page
#model MasigasigTrackingSystem.Pages.TestingPages.FirstPageModel
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>FirstPage</title>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<script>
$("#AddButton").click(function () {
tc = tc + 1;
$("#totalContacts").val(tc)
$.ajax('?handler=DropdownList', {
method: "GET",
data: { tc: tc },
success: function (d) { $(".addselection").append(d); }
});
});
</script>
</head>
<body>
<button id="AddButton" class="btn" type="button">+</button>
#*<select asp-for="Mode" asp-items="Model.DropdownListViewModel.Drivers" class="form-control">
<option value="">Select a driver</option>
</select>*#
<div class="addselection">
<partial name="_SecondPage.cshtml" />
</div>
</body>
</html>
My FirstPageModel
namespace MasigasigTrackingSystem.Pages.TestingPages
{
public class FirstPageModel : PageModel
{
private readonly MasigasigTrackingSystem.Data.ApplicationDBContext _context;
public FirstPageModel(MasigasigTrackingSystem.Data.ApplicationDBContext context)
{
_context = context;
}
[BindProperty]
public Drivers Drivers { get; set; }
public List<SelectListItem> DriverList { get; set; }
[BindProperty]
public DropdownListViewModel DropdownListViewModel { get; set; }
public void OnGet()
{
DriverList = _context.Drivers.Select(a =>
new SelectListItem
{
Value = a.ID.ToString(),
Text = a.FullName
}).ToList();
DropdownListViewModel = new DropdownListViewModel();
DropdownListViewModel.Drivers = DriverList;
}
public IActionResult OnGetDropdownListAsync(int tc)
{
var list = _context.Drivers.Select(a => new SelectListItem
{
Value = a.ID.ToString(),
Text = a.FullName,
}).ToList(); // or filter by Where( ... tc...).ToList()
return Partial("/Pages/TestingPages/_SecondPage.cshtml", new DropdownListViewModel
{
Drivers = list,
ID = tc,
});
}
}
}
My partial _SecondPage
#using MasigasigTrackingSystem.Models
#model DropdownListViewModel
<div>
<select class="form-control dropdown" name="[#Model.ID].DriverID" asp-items="#Model.Drivers">
<option> Select a driver </option>
</select>
</div>
My DropdownlistViewModel
namespace MasigasigTrackingSystem.Models
{
public class DropdownListViewModel
{
public int ID { get; set; }
public IList<SelectListItem> Drivers { get; set; }
}
}
Here's a demo that gets the partial view dynamically from server.
Create a Handler OnGetDropdownListAsync(int tc) in your PageModel:
public class YourPageModel : PageModel
{
... other handler methods, e.g. OnGet() render the Index
public IActionResult OnGetDropdownListAsync(int tc)
{
var list = _context.Drivers.Select(a =>new SelectListItem{
Value = a.ID.ToString(),
Text = a.FullName,
}).ToList(); // or filter by Where( ... tc...).ToList()
return Partial( "/Pages/Shared/Selection.cshtml" , new DropdownListViewModel{
Drivers = list,
Index = tc,
});
}
}
Here the DropdownListViewModel is a plain ViewModel that holds the data:
public class DropdownListViewModel{
public IList<SelectListItem> Drivers{get;set;}
public int Index {get;set;}
}
Move your original html snippet within jQuery into a new partial view file: /Pages/Shared/Selection.cshtml
#using App.Pages
#model DropdownListViewModel
<div>
<select class="form-control dropdown" name="[#Model.Index].DriverID" asp-items="#Model.Drivers">
<option> Select a driver </option>
</select>
</div>
Finally, change your JavaScript to send an ajax request and update the UI in following way:
$("#AddButton").click(function () {
tc = tc + 1;
$("#totalContacts").val(tc)
$.ajax('?handler=DropdownList',{
method:"GET",
data:{ tc: tc },
success:function(d){ $(".addselection").append(d); }
});
});
[Edit]
You are passing currect ViewData to <partial> implicitly, which leads to this type error. You need change it to :
<partial name="/Pages/TestingPages/_SecondPage.cshtml" model="#Model.DropdownListViewModel" />
You're referencing an slim jQuery that doesn't have a ajax. Please change the script to <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>.
You're binding an event for #AddButton before this element has been created. You need wrap the js into a $(document).ready(function(){ .... }. You can also create a manually script after the #AddButton element. Or put the <script> into #section Scripts{} if you're using a default Layout which will make the script take effect after the page has been loaded.
Also you didn't initialize a tc variable.
In short, you need fix the bugs as below:
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script>
$(document).ready(function(){
var tc = 0;
$("#AddButton").click(function () {
tc = tc + 1;
$("#totalContacts").val(tc)
$.ajax('?handler=DropdownList', {
method: "GET",
data: { tc: tc },
success: function (d) { $(".addselection").append(d); }
});
});
});
</script>
...
<div class="addselection">
<partial name="/Pages/TestingPages/_SecondPage.cshtml" model="#Model.DropdownListViewModel" />
</div

Dependent list without the same value

I'm trying to make one list dependent on the other using javascript, but the value of the second is the value of the first list plus its own id, separeated by "*". I've been trying to split the value and get only the first part, but it returns nothing. What's wrong with the code?
listaversao = _context.Versao.Select(v => new SelectListItem
{
Value = v.idLinguagem.ToString() + "*" + v.idVersao.ToString(),
Text = v.nmVersao //this one depends on listaling, but it has two ids separated by the *;
});
listaling = _context.Linguagem.Select(l => new SelectListItem
{
Value = l.idLinguagem.ToString(),
Text = l.nmLinguagem
});
Javascript:
var $linguagem = $('#lingua'),
$versao = $('#versao'),
$options = $versao.find('option');
$linguagem.change(function () {
$('#versao option')
.hide() // hide all
.filter(versao => versao.val().split("*")[0] == $linguagem.val()) // splits the val and filter options with required value
.show(); // and show them
});
And that's how I'm setting the binding:
public IEnumerable<SelectListItem> listaversao { get; set; }
public IEnumerable<SelectListItem> listaling { get; set; }
[BindProperty(SupportsGet =true)]
public string[] selecaover { get; set; }
And the html:
<label asp-for="Scripts.idLinguagem" class="control-label"></label>
<br />
<select onchange="mudar()" id="lingua" asp-for="linguagem" asp-items="Model.listaling"></select>
<select id="versa" size="10" onclick="mostrarv()" multiple="multiple" asp-for="selecaover" asp-items="Model.listaversao"></select>
Thanks for helping.

How to assign default value to Radio Button List in ASP.NET MVC?

How to fetch .Net MVC Model value in the JavaScript?
I am populating the Radio Button Control from the list stored in the database.
item.MyColumn has the list of Radio button options such as Yes, No, NA etc.
In the jQuery, I need to fetch the value of Yes (or) No (or) NA and based on that value, I have to do some validation.
<div class="col-sm-8 checkbox-inline text-left">
#foreach (var item in Model.YesNoNAList)
{
#Html.RadioButtonFor(model => model.ReceivingMedication, item.ID, new { #id = "ReceivingMedication" + item.MyColumn }) #: #item.MyColumn
}
<span asp-validation-for="ReceivingMedication" class="text-danger"></span>
</div>
Having this syntax in the JavaScript, gives me the column : id . And not the value associated with the Id.
var selValue = $('input[name=ReceivingMedication]:checked').val();
Normally, you do not need to manipulate the control's ID. If you want to assign default value, you assign it to ReceivingMedication.
<div class="col-sm-8 checkbox-inline text-left">
#foreach (var item in Model.YesNoNAList)
{
<p>#Html.RadioButtonFor(model => model.ReceivingMedication, item.Value) #item.Text</p>
}
<span asp-validation-for="ReceivingMedication" class="text-danger"></span>
</div>
<script>
var selValue = $('input[name=ReceivingMedication]:checked').val();
console.log(selValue);
</script>
Model
public class Model
{
public List<SelectListItem> YesNoNAList { get; set; }
public string ReceivingMedication { get; set; }
public string ID { get; set; }
}
Controller
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new Model
{
YesNoNAList = new List<SelectListItem>
{
new SelectListItem {Text = "Yes", Value = "1"},
new SelectListItem {Text = "No", Value = "0"},
new SelectListItem {Text = "N/A", Value = ""}
},
ReceivingMedication = "0" // Default value
};
return View(model);
}
}

I have a requirement which I need to display price based on drop down selection

I have a requirement which I need to display price based on drop down selection. and that price comes from same db, when I click one Test from dropdown then respected price of that test should display in textbox.The value is binding in textbox after selecting option from dropdown also it is displaying after taking span but not displaying on textbox, please tell me solution because i want to display it only on textbox .
here is Error Image
Model class
public partial class TwoDDiagnostic
{
public int TwoD_ID { get; set; }
public string TwoDDiagnostic_Name { get; set; }
public string TwoD_Price { get; set; }
public Nullable<System.DateTime> TwoD_Date { get; set; }
public Nullable<int> centr_Id { get; set; }
}
Controller
IEnumerable<SelectListItem> selectList2D = from twod in db.TwoDDiagnostics
where twod.centr_Id == Id
select new SelectListItem()
{
Text = twod.TwoDDiagnostic_Name,
Value = twod.TwoDDiagnostic_Name
};
var lasttwoD = db.TwoDDiagnostics.Where(x => x.centr_Id == Id).OrderByDescending(c => c.TwoD_ID).Take(1).FirstOrDefault();
if (lasttwoD == null)
{
ViewBag.twoDID = new SelectList(selectList2D, "Value", "Text");
model.ViewModel_TwoDDiagnostic = null;
return View(model);
}
string twodname = (from sub in db.TwoDDiagnostics where sub.TwoD_ID == lasttwoD.TwoD_ID select sub.TwoDDiagnostic_Name).First();
ViewBag.twoDID = new SelectList(selectList2D, "Value", "Text", twodname);
View
<div class="form-inline">
<label for="inputEmail1" class=" col-lg-2 col-sm-4 control-label">2D Diagnostic Services</label>
<div class="col-lg-5">
#Html.DropDownListFor(model => model.PTwoDDiagnostic_name, (SelectList)ViewBag.twoDID, "- Select 2D Diagnostics -", new { #class = "form-control ", #id = "twopID", #onchange = "fill()" })
</div>
<div class="col-lg-3">
#*<span class="form-control" id="twoprice"></span>*#
#Html.TextBoxFor(model => model.PTwoDDiagnostic_price, new { #class = "form-control ", #id = "twoprice" , #onchange = "fill()"})
</div>
</div>
here is json method
public JsonResult GetTwoDPrice()
{
AllViewModel model = new AllViewModel();
Session["Two_D"] = model.TwoD_ID;
var id = (int)Session["Two_D"];
if (!string.IsNullOrEmpty(Session["Two_D"].ToString()))
{
//int Id = (int)Session["Two_D"];
var Record = (from patient in db.TwoDDiagnostics
where patient.TwoD_ID == id
select new
{
TwoD_ID = patient.TwoD_ID,
TwoD_Price = patient.TwoD_Price
}).FirstOrDefault();
return Json(Record, JsonRequestBehavior.AllowGet);
}
return Json("", JsonRequestBehavior.AllowGet);
}
here is a script
<script type="text/javascript">
$("#twopID").on('change', function (event) {
$.ajax({
url: "#Url.Action("GetTwoDPrice", "Center")",
type: "Get",
success: function (data) {
debugger;
console.log(data.TwoD_Price);
$('#twoprice').text(data.TwoD_Price);
}
});
});
</script>
You need to use the jquery val() method to set the Value for the TextBox. If you use text() method, it sets the innerText of the input element (in between the <input> and </input> HTML tags) which is applicable only for HTML Elements like span, label, h, div, etc.
$('#twoprice').val(data.TwoD_Price);

Cascading DropDown not return value

I have a two cascading dropdown, when I run the application everything works fine, because the cascade works, but when I get the value of the dropdown only get the value of first dropdown. The second I always get the value of zero.
The ViewModel code:
public class MyViewModel
{
public string SelectedUniversidadId { get; set; }
public string SelectedCiudadId { get; set; }
public IEnumerable<UNIVERSIDAD> Universidades { get; set; }
}
Partial view code:
<script type="text/javascript">
$(function () {
$('#universidad').change(function () {
var selectedUniversidadId = $(this).val();
$.getJSON('#Url.Action("GetCiudadList", "Consultorio", new { Area = "Superusuario", controller = "Consultorio" })', { UniversidadId: selectedUniversidadId }, function (myData) {
var citiesSelect = $('#ciudad');
citiesSelect.empty();
$.each(myData, function (index, itemData) {
citiesSelect.append($('<option/>', {
value: itemData.Value,
text: itemData.Text
}));
});
});
});
});
</script>
#model RolesMVC3.Areas.Superusuario.Models.MyViewModel
<div>
Universidad:
#Html.DropDownListFor(x => x.SelectedUniversidadId, new SelectList(ViewBag.IdUniversidad, "IdUniversidad", "Nombre"), "-- Selecione Universidad --", new { id = "universidad" })
</div>
<div>
Ciudad:
#Html.DropDownListFor(x => x.SelectedCiudadId, Enumerable.Empty<SelectListItem>(), "-- Seleccione Ciudad --", new { id = "ciudad" })
</div>
Controller code:
public ActionResult GetCiudadList(int UniversidadId)
{
decimal idd = (decimal)UniversidadId;
var universidades = (from u in db.UNIVERSIDAD
join s in db.SEDE_UNIVERSIDAD on u.IdUniversidad equals s.IdUniversidad
join c in db.CIUDAD on s.IdCiudadSede equals c.IdCiudad
where u.IdUniversidad == idd
select c).ToList();
var myData = universidades.Select(a => new
{
Text = a.NombreCiudad,
Value = a.IdCiudad.ToString(),
});
return Json(myData, JsonRequestBehavior.AllowGet);
Thanks and blessings
You need a controller action that receives 2 parameters (selected values for the 2 dropdowns). Also, pay attention to the values of the name attributes for the input elements. the name of the parameters need to be the same as the "name" input attribute.

Categories

Resources