I'm searching for a good way to bind a List<string> to a form in MVC3. Right now I have 2 options:
Use a ListBox with a textbox, add/delete button in jquery and do a select all items before posting my form
Use a <li> that will contains a <input type="hidden" /> with the value also with a add/delete button in jquery
I'm sure there is easyer way to do this but I did not found anything here so I'm asking for help. My concern is to add different bussiness units (string) to a company while editing the company other properties (name, address..).
Thanks!
Using a ListBox seems like a good way to achieve that. Then you could have a textbox and an add button next to it that will append a new element to the listbox and a delete button that will remove the selected items from the ListBox all using client side jquery. And when the form is submitted, since you have used a ListBox (<select> with multiple="multiple") it will automatically bind to a property on your view model of type List<string> and you will be able to fetch the selected values.
Here's my code for the first option, if anyone find a better solution, let me know!
Html/Razor :
<div class="row">
<div class="span12">
<div class="control-group">
<label for="AddBusinessUnit" class="control-label">#Strings.BusinessUnit</label>
<div class="controls">
<div class="input-append">
<input type="text" class="span2" size="16" id="AddBusinessUnit" />
<button class="btn" type="button" id="add-business-unit">#Strings.Add</button>
</div>
</div>
</div>
<div class="control-group">
<div class="controls">
#Html.ListBoxFor(model => model.BusinessUnits, SelectLists.BusinessUnits(Model.BusinessUnits, false), new { Multiple = "multiple" })<br/>
#Strings.DeleteSelectedElement
</div>
</div>
</div>
</div>
<div class="form-actions">
<input type="submit" class="btn btn-primary" value="#Strings.Save" />
#Strings.Cancel
</div>
Js :
<script type="text/javascript">
$(document).ready(function () {
$('#add-business-unit').click(function (e) {
var bu = $('#AddBusinessUnit').val();
if (bu != '') {
$('#BusinessUnits').append($('<option></option>').val(bu).html(bu));
$('#AddBusinessUnit').val('');
}
e.preventDefault();
});
$('#delete-business-unit').click(function (e) {
$('#BusinessUnits :selected').remove();
e.preventDefault();
});
$('input[type="submit"]').click(function () {
$('#BusinessUnits option').attr('selected', 'selected');
});
});
The SelectList :
public static class SelectLists
{
public static IList<SelectListItem> BusinessUnits(IList<string> bussinessUnits, bool addEmpty, string selected = "")
{
var list = new List<SelectListItem>();
if(addEmpty) list.Add(new SelectListItem());
list.AddRange(bussinessUnits.Select(businessUnit => new SelectListItem {Selected = selected == businessUnit, Text = businessUnit, Value = businessUnit}));
return list;
}
}
It will bind to my property public virtual IList<string> BusinessUnits { get; set; } in my model.
Hope it can helps!
Related
I am working on a project in C# with .NetCore Razor Pages and I have this page where a user makes an appointment by completing some fields.
I have this field that is a calendar and the user can select a date from it. Based on that date I want to populate a drop down with a list of hours that are available for an appointment.
I tried to use Handlers like OnPost() but that requires a submit button, but I only have the calendar input.
This is the code I use in my Razor Page for the calendar
<div class="form-group col-md-4">
<label asp-for="StartDate"></label>
<input asp-for="StartDate" class="form-control" />
<span class="text-danger" asp-validation-for="StartDate"></span>
</div>
In my model page I should have something like
public IActionResult OnPostStartDate()
{
\\code that brings from the database the available hours
}
Is there any other function that I can use so when the user chooses a date from the calendar the dropdown will be populated with the available hours?
EDIT
In my Razor Page
#section Scripts {
<script>
$("#StartDate").on("change", function () {
var time = $(this).val();
$("#select").empty();
$("#select").append("<option value=''>select </option>");
$.getJSON(`?handler=Time&time=${time}`, (data) => {
$.each(data, function (i, item) {
$("#select").append("<option value='" + "'>" + item.hour + "</option>");
});
});
});
</script>
}
<form class="form-style" method="post" id="createBTForm">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="StartDate" class="control-label"></label>
<input asp-for="StartDate" class="form-control" />
<span asp-validation-for="StartDate" class="text-danger"></span>
</div>
<select id="select" asp-for="Time" class="form-control"></select>
<div class="form-group button-position col-md4">
<input type="submit" id="placeRequest" name="placeRequest" value="Place Request" class="btn btn-primary" />
</div>
</form>
In my model Page
[Required(ErrorMessage = "Field cannot be empty!")]
[BindProperty]
[DataType(DataType.Date)]
[Display(Name = "Start Date:")]
public DateTime StartDate { get; set; }
//this is null after selecting an option from the dropdown
[BindProperty]
public string Time { get;set; }
//this is the method that should work when I press the Place Request submit button
public async Task<IActionResult> OnPost()
{
if (!ModelState.IsValid)
{
return Page();
}
//here I send the data to the database
return Redirect(Url.Page(indexPage));
}
//this is the method that puts the values on the dropdown (this works)
public async Task<IActionResult> OnGetTime(DateTime time)
{
//Here I set my model based on database data
var finalHours = leaveFromLocations.Where(f => !unavailable.Contains(f));
foreach (var h in finalHours)
{
model.Add(new Hours
{
Hour = h
});
}
return new JsonResult(model);
}
The problem is that after I send the json model to the dropdown and the values appear in the dropdown I can't take the option that is selected (in debug after choosing an option the Time property appears null)
You can write an onchange function and then use ajax to send data to backend.Below is a simple demo.
<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Time.StartDate" class="control-label"></label>
<input asp-for="Time.StartDate" class="form-control" />
<span asp-validation-for="Time.StartDate" class="text-danger"></span>
</div>
<select id="select" asp-for="Time.Hour" class="form-control"></select>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
#section Scripts {
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
<script>
$("#Time_StartDate").on("change", function () {
var time = $(this).val();
$("#select").empty();
$("#select").append("<option value=''>select </option>");
$.getJSON(`?handler=Time&time=${time}`, (data) => {
$.each(data, function (i, item) {
//"id" and "hours" is in your JsonResult(model),and remember The first letter of the attribute must be lowercase
$("#select").append("<option value='" + item.id + "'>" + item.hours + "</option>");
});
});
});
</script>
}
Backend:
public IActionResult OnGetTime(DateTime time)
{
//this is a fake data,you can query your data here.
var model = new List<Hour>
{
new Hour
{
Id=1,
Hours=1
},
new Hour
{
Id=2,
Hours=2
},
};
return new JsonResult(model);
}
Test result:
I am using Twitter Bootstrap in an ASP.NET MVC application. In one page I want to show a Grid or List view when a user click on the relevant icon. To do that, I'm using radio buttons and it does show based on user selection.
But the problem is that it always focuses on the Grid icon, even if it fires list mode.
Here's My Code:
<div class="row" >
<div class="col-xs-4 col-sm-4">
<form class="pull-left">
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-primary active" title="Show as a Grid" >
<i class="fa fa-table"></i>
#Html.RadioButtonFor(model => Model.Context.ViewMode, "grid",
new { name = "viewmode", #class = "",
onchange = "setLocation('?viewmode=grid');" })
Grid
</label>
<label class="btn btn-primary" title="Show as a List" >
<i class="fa fa-list"></i>
#Html.RadioButtonFor(model => Model.PagingFilteringContext.ViewMode, "list",
new { name = "viewmode", #class = "",
onchange = "setLocation('?viewmode=list');" })
List
</label>
</div>
</form>
</div>
</div>
<div class="show-content">
#if (Model.Context.ViewMode == "grid")
{
<label>Grid content here...</label>
}
else
{
<label>List content here...</label>
}
</div>
// set visibility between icons
$(document).ready(function () {
$("#Context_ViewMode").on('click', function () {
ToggleRadioButtons("#Context_ViewMode", $(this));
});
});
function ToggleRadioButtons(groupName, current) {
var chk = $(groupName + " .fa-table");
$(chk).removeClass('fa-table').addClass('fa-list');
$(current).find(">:first-child").removeClass('fa-list');
$(current).find(">:first-child").addClass('fa-table');
}
But it didn't set focus on List icon when clicked. Any ideas?
Edit:
I managed to get event firing work, but it doesn’t stay as selected if ‘List’ selected, change back to ‘Grid’ highlighted(active) after loading correct ‘List’ result from the server.
Summary of changes:
Added new class ‘fawsm-radiobutton’ for both labels
Added new class ‘nonactive’ for label list
Changed the JavaScript to add remove 'active' and 'notactive'
Here’s My Code changes:
<label class="fawsm-radiobutton btn btn-primary active" title="Show as a Grid" >
<i class="fa fa-table"></i>
#Html.RadioButtonFor(model => Model.Context.ViewMode, "grid",
new { name = "viewmode", #class = "",
onchange = "setLocation('?viewmode=grid');" })
Grid
</label>
<label class="fawsm-radiobutton btn btn-primary notactive" title="Show as a List" >
<i class="fa fa-list"></i>
#Html.RadioButtonFor(model => Model.PagingFilteringContext.ViewMode, "list",
new { name = "viewmode", #class = "",
onchange = "setLocation('?viewmode=list');" })
List
</label>
$(document).ready(function () {
$("#Context_ViewMode>.fawsm-radiobutton").on('change', function () {
ToggleRadioButtons("#Context_ViewMode", $(this));
});
});
function ToggleRadioButtons(groupName, current) {
var chk = $(groupName + " .fawsm-radiobutton.active");
$(chk).removeClass('active’).addClass('notactive');
$(current).find(">:first-child").removeClass('notactive');
$(current).find(">:first-child").addClass('active');
}
When I use developer tool(F12) on the browser it shows the removal and addition of ‘active’ and ‘notactive’ classes to lable. But after loading List items from the server it revert back to original ‘Grid’ icon in active mode.
So I guess that when the browser renders
#if (Model.Context.ViewMode == "grid")
{}
else{}
section I need to notify client to do the above changes to the label classes. I do not know how to do it. Do I need to use something like AJAX?
You should use the .focus() method.
hi am developing mvc project using c#
currently am working on employee system model
I have designed view below like this
#Html.CheckBoxFor("value", new {data_divToDisable="SSLCSection",#class="SelectSection" })
<div id="SSLCSection" class="DisableDiv">
<table>
//Conntent goes here
</table>
</div>
#Html.CheckBoxFor("value", new {data_divToDisable="PUCSection",#class="SelectSection" })
<div id="PUCSection" class="DisableDiv">
<table>
//Conntent goes here
</table>
</div>
#Html.CheckBoxFor("value", new {data_divToDisable="GraduationSection",#class="SelectSection" })
<div id="GraduationSection" class="DisableDiv">
<table>
//Conntent goes here
</table>
</div>
#Html.CheckBoxFor("value", new {data_divToDisable="PostGraduationSection",#class="SelectSection" })
<div id="PostGraduationSection" class="DisableDiv">
<table>
//Conntent goes here
</table>
</div>
here I need to disable sections when loading view based on checkbox value
like if checkbox is checked no need to disable that section otherwise it would be disable
I have written jquery like this
$(document).ready(function () {
$(".SelectSection").attr('checked', false,function(){
var id = $(this).find(".DisableDiv");
alert(id);
$(this).find(".DisableDiv").find('input, textarea, select,table').each(function () {
$(this).prop('disabled', true);
});
});
this is not doing anything for us
please help and your help would be greately appreciated
Please Note I have using data-Attribute to simplify the jquery and while each time loading the page it has to disable the sections based on checkbox value (hint:it has to disable if checkbox value is false )
You could try the follow, excuse the pseudo code.
HTML
<input class="SelectSection" type="checkbox" >hello1</input>
<div id="SSLCSection" class="DisableDiv" >
<input type="input">Test</input>
<textarea>Test1</textarea>
</div>
<br>
<input class="SelectSection" type="checkbox">hello2</input>
<div id="PUCSection" class="DisableDiv" >
<input type="input">Test2</input>
<textarea>Test12</textarea>
</div>
<br>
<input class="SelectSection" type="checkbox" checked>hello3</input>
<div id="PostGraduationSection" class="DisableDiv" >
<input type="input">Test3</input>
<textarea>Test3</textarea>
</div>
jQuery
$(document).ready(function () {
$(".SelectSection[type='checkbox']").each(function (i, o) {
if ($(o).is(":checked")) {
$(o).next('div').find('input,textarea').each(function (i, o) {
$(o).prop('disabled', true);
});
}
});
})
The above assumes that your next element after the relevant checkbox is the div in question which holds the elements that need to be disabled.
I have a view partial in a strongly typed controller. Is it possible to render the would-be contents of that view partial on mouseclick?
Example:
Active View
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
<div id="modalView"></div>
<script>
$(document).ready(function () {
$('.open-popup-link').magnificPopup({
key: 'my-popup',
type: 'inline',
inline: {
// Define markup. Class names should match key names.
markup: '<div class="white-popup"><div class="mfp-close"></div>awesome</div>'
}
},
{
callbacks: {
open: function(){
}
}
});
$('.open-popup-link').on('mfpOpen', function(e /*, params */) {
var linkText = // how to I grab this? (e.g. 1, 2, 3, or 4)
$.ajax({
// call view partial withlinktext as parameter
//on success
// var inlineContent = viewPartialContent
// On error
// var inlineCOntent = 'Uh oh, something went wrong'
});
});
});
</script>
View Partial
#model *******.Models.Reservation
<div class="container">
<div class="section-heading">
<h2 class="red">Confirm Your Reservation</h2><br />
</div>
<div class="section-content">
<div class="row">
<h3 class="black text-center">Are you sure you want to reserve space <span class="dark-red">#Model.SpaceNumber</span></h3>
<h4 class="black text-center">for <span class="dark-red">#Model.Game.Description</span> on <span class="dark-red">#Model.Game.Date.ToShortDateString()</span>?</h4>
</div>
<div class="row">
<div class="hero-buttons text-center">
No
<form action="/api/Reservations" method="post" id="confirmationForm">
#Html.Hidden("eRaiderUserName", #Model.eRaiderUserName)
#Html.Hidden("SpaceNumber", #Model.SpaceNumber)
<input type="submit" value="Yes" class="btn btn-red btn-lg white">
</form>
</div>
</div>
</div>
</div>
Method for viewpartial in controller
public ActionResult Confirm(int spaceNumber)
{
var reservation = new Reservation { SpaceNumber=spaceNumber, UserName=AppSettings.CurrentUserName, Game=db.Games.FirstOrDefault(g => g.ID == AppSettings.CurrentGameID) };
return View(reservation);
}
Does this make sense, and can I make it work?
You need to do two things:
change your Confirm method, so that it returns PartialView(reservation) instead of View(reservation)
You need to use AJAX, for example jQuery ajax, to get the HTML, and render it in your page
$.ajax({url = 'the url for your Confirm action',
type = 'GET',
dataType='html',
data = params}).done(function(html) {
// use the jQuery and the html to inject it wherever you need in your page
});
NOTE: params is a jQuery object which contains the data you need to pass like spaceNumber in this case, i.e.
var params = { spaceNumber: 'spaceNumberValue' }
I have created a search function on my website that allows the user to select what table they wnat to search for. The select list is within a dropdown rendered within a dropdown menu using bootstrap. The issue I'm facing is that when the form is run the value of the selected item from the dropdown menu that is passed into the controller is "" instead of the value that was selected in the dropdown menu.
Any help would be grateful.
** search function**
<div class="col-lg-6">
#{using (Html.BeginForm("Results", "Searchv2", FormMethod.Get))
{
<div class="input-group">
<div class="input-group-btn">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">Action <span class="caret"></span></button>
<ul class="dropdown-menu">
#foreach (var searchType in new[] { "User", "Restaurant", "Cuisine" })
{
<li>#searchType</li>
}
</ul>
<input type="hidden" name="SearchBy" />
</div>
<input type="text" class="form-control" placeholder="Search" name="SearchString" id="SearchString">
</div>
}}
</div>
jquery that finds the value
<script>
$(".dropdown-menu").click(function () {
$("input[name='SearchBy']").val($(this).html());
});
</script>
you have to write click event on anchor tag, as you have anchor tag inside <li> like this:
<ul class="dropdown-menu">
<li>
<a>SearchText</a>
</li>
</ul>
$(".dropdown-menu li a").click(function () {
$("input[name='SearchBy']").val($(this).html());
});
I believe you want to set the SearchBy value by getting the value of the selected item:
<script>
$(".dropdown-menu").click(function () {
$("input[name='SearchBy']").val($(this).val());
});
</script>
if you want to get the value of text in between the <a></a> tags, try use .text() instead of html()
First you are selecting the ul not the a inside its li and second you should use jquery text function:
<script>
$('.dropdown-menu li a').click(function (e) {
e.preventDefault();
$('input[name="SearchBy"]').val($(this).text());
});
</script>