I try to make following parts run, but always failed. The objective is: if a target in combobox is selected, the mediaId's combobox should be filled with respective values. At this moment I just emulate the values of mediaId combobox. Can anyone show me how to combine them correctly? Thx in advance.
The view Medium.cshtml:
<script src="#Url.Content("~/Scripts/PartialLoad.js")" type="text/javascript"></script>
<div class="editor-label">
#Html.LabelFor(model => model.Files[i].TargetId)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.Files[i].PTargetId, (ViewData["targets"] as SelectList).MakeSelection(Model.Files[i].PTargetId))
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Files[i].MediaId)
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.Files[i].MediaId, (ViewData["mediaIds"] as SelectList).MakeSelection(1))
</div>
The javascript partialload.js
$(document).ready(function () {
$("#targets").change(function () { GetMValues("#targets", "#mediaIds"); });
});
function ClearDrop(objSource) {
$(objSource).empty();
}
function GetMValues(objSource, objDest) {
var url = '/GetMValues/';
$.getJSON(url, { id: $(objSource).val() },
function (data) {
ClearDrop(objDest); $.each(data, function (index, optionData) {
$(objDest).append("<option value='" + optionData.Value + "'>" + optionData.Text + "</option>");
});
});
}
The homecontroller.cs
public ActionResult GetMValues(String id)
{
int myId = 0;
int.TryParse(id, out myId);
var mediumIds = new List<long>();
int max = myId + 3;
// just to emulate the data in the list
for ( long l = 1 ; l < max ; l++ ){
mediumIds.Add(l);
}
var select = new SelectList(mediumIds, "PTargetId", "TargetId");
return Json(select, JsonRequestBehavior.AllowGet); //allow get needed to allow get calls
}
Here you are using an id selector for the dropdownlist: $("#targets") but your dropdown doesn't seem to have such id. Maybe you want to assign it an id or a class:
#Html.DropDownListFor(
model => model.Files[i].PTargetId,
(ViewData["targets"] as SelectList).MakeSelection(Model.Files[i].PTargetId),
new { id = "targets" }
)
But because this seems to be repeated and you cannot have multiple elements with the same id a class selector is probably more appropriate:
#Html.DropDownListFor(
model => model.Files[i].PTargetId,
(ViewData["targets"] as SelectList).MakeSelection(Model.Files[i].PTargetId),
new { #class = "targets" }
)
and then:
$(document).ready(function () {
$(".targets").change(function () {
...
});
});
Same remark obviously for #mediaIds.
Related
Hope all of you fine and doing well.
I am using multi select bootstrap drop down jquery. I am using asp.net core to populdate Listbox, its working fine for selection,select all etc.
But i want that when i select element from Dropdown A then this element must be removed from dropdown B and if i unselect element from dropdown A then it must added/show in dropdownB. And vice virsa as well, if element selected in dropdown B then this element removed from dropdownA, also if select all from dropdownA then all elements removed from dropdownB and vice virsa as well.
Hope you understand guys.
For example: If A,B,C,D values in dropdownlistA and if i select A then it must be disable or hide from dropdownB,if i select all then must remove all from dropdownB, and also vice virsa for dropdownB as well,
Note: DropdownA and DropdownB both have same number of values/elements,same text ,same value,
View
#section AddToHead{
<link rel="stylesheet" href="~/css1/bootstrap-3.1.1.min.css" type="text/css" />
<link rel="stylesheet" href="~/css1/bootstrap-multiselect.css" type="text/css" />
<script type="text/javascript" src="https://code.jquery.com/jquery-1.8.2.js"></script>
<script type="text/javascript" src="~/js1/bootstrap-2.3.2.min.js"></script>
<script type="text/javascript" src="~/js1/bootstrap-multiselect.js"></script>
}
<form class="column" asp-controller="group" asp-action="createresult" style="height:100%;" method="post">
<span class="column" style="height:50px;">
#Html.ListBoxFor(x => x.AvailablePlayers, Model.AvailablePlayers, new { id = "PlayersTeamA", onChange = "getSelectedOptions(this)", multiple = "multiple" })
#Html.ValidationMessageFor(model => model.TeamOnePlayers)
</span>
<span class="column">
#Html.ListBoxFor(x => x.AvailablePlayers, Model.AvailablePlayers, new { id = "PlayersTeamB", onChange = "getSelectedOptions(this)", multiple = "multiple" })
#Html.ValidationMessageFor(model => model.TeamTwoPlayers)
</span>
</form>
</div>
#section Scripts {
<script type="text/javascript">
$(function () {
$('#PlayersTeamA').multiselect({
includeSelectAllOption: true
});
$('#PlayersTeamB').multiselect({
includeSelectAllOption: true
});
});
function getSelectedOptions(sel) {
var idddl = sel.id;
var opts = [],
opt;
var len = sel.options.length;
for (var i = 0; i < len; i++) {
opt = sel.options[i];
if (opt.selected) {
opts.push(opt);
var idul = sel.id;
alert(idul);
var ul = document.getElementById(idul);
ul.removeChild(ul.childNodes[1]);
}
}
return opts;
}
Here is a working demo like below:
#model Players
<form class="column" asp-controller="group" asp-action="createresult" style="height:100%;" method="post">
<div id="A">
<span class="column" style="height:50px;">
#Html.ListBoxFor(x => x.AvailablePlayers, Model.AvailablePlayers, new { id = "PlayersTeamA", multiple = "multiple" })
</span>
</div>
<div id="B">
<span class="column">
#Html.ListBoxFor(x => x.AvailablePlayers, Model.AvailablePlayers, new { id = "PlayersTeamB", multiple = "multiple" })
</span>
</div>
</form>
#section Scripts {
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-multiselect/0.9.15/js/bootstrap-multiselect.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-multiselect/0.9.15/css/bootstrap-multiselect.css"/>
<script>
$(function () {
$('#PlayersTeamA').multiselect({
includeSelectAllOption: true
});
$('#PlayersTeamB').multiselect({
includeSelectAllOption: true
});
});
var data = [];
$('#B option').each(function (index, item) {
data.push({ label: this.label, value: this.value });
});
$("#PlayersTeamA").change(function () {
var selectedText = $('#PlayersTeamA').val();
var newData = data;
selectedText.forEach(function (element, index, array) {
newData = newData.filter(function (el) { return el.value != element; });
});
$("#PlayersTeamB").multiselect('dataprovider', newData);
});
</script>
}
My testing model:
public class Players
{
public SelectList AvailablePlayers { get; set; }
}
public class AvailablePlayer
{
public int Id { get; set; }
public string Name { get; set; }
}
My testing controller:
[HttpGet]
public async Task<IActionResult> Index()
{
var player = new List<AvailablePlayer>()
{
new AvailablePlayer(){ Id=1,Name="aa"},
new AvailablePlayer(){ Id=2,Name="bb"},
new AvailablePlayer(){ Id=3,Name="cc"}
};
var model = new Players()
{
AvailablePlayers = new SelectList(player, "Id", "Name")
};
return View(model);
}
Result:
It appears you are using bootstrap's multiselect. In the documentation, we can see that you can configure data as follows (after executing .multiselect on particular input, as you do in your sample):
var data = [
{label: "Messi", value: "Messi"},
{label: "Ronaldo", value: "Ronaldo"}
];
$("#PlayersTeamA").multiselect('dataprovider', data);
Now, attach to 'onchange' event of #PlayersTeamA and update the available data for #PlayersTeamB, for example like this:
$("#PlayersTeamA").change(function () {
var selectedText = $(this).find("option:selected").text();
var newData = data.filter(function(el) { return el.value == selectedText; });
$("#PlayersTeamB").multiselect('dataprovider', newData);
});
You have to attach to onchange of #PlayersTeamB as well, I believe (so that it works in both directions).
I have a javascript function I use to do an Ajax call to my controller function. The javascript is generic enough I can use it for multiple controls. I have two areas that use the script. One works, one doesn't. I believe it's the footprint of the MVC controller that is being called.
The javascript looks like this:
$(Document).on("click",".delete-link",function (event) {
var deleteLink = $(this);
deleteLink.hide();
var confirmButton = deleteLink.siblings(".delete-confirm");
confirmButton.show();
var cancelDelete = function () {
removeEvents();
showDeleteLink();
};
var deleteItem = function () {
removeEvents();
confirmButton.hide();
var url = '/' + confirmButton.attr('data-delete-controller') + '/' + confirmButton.attr('data-delete-action') + '/' + confirmButton.attr('data-delete-id');
$.post(
url,
AddAntiForgeryToken({ id: confirmButton.attr('data-delete-id') }))
.done(function () {
var parentRow = deleteLink.closest(".removable-row");//"tr:first, li:first");
parentRow.fadeOut('fast', function () {
parentRow.remove();
});
}).fail(function (data) {
alert("error");
});
return false;
};
var removeEvents = function () {
confirmButton.off("click", deleteItem);
$(document).on("click", cancelDelete);
$(document).off("keypress", onKeyPress);
};
var showDeleteLink = function () {
confirmButton.hide();
deleteLink.show();
};
var onKeyPress = function (e) {
//Cancel if escape key pressed
if (e.which == 27) {
cancelDelete();
}
};
confirmButton.on("click", deleteItem);
$(document).on("click", cancelDelete);
$(document).on("keypress", onKeyPress);
return false;
});
AddAntiForgeryToken = function (data) {
data.__RequestVerificationToken = $('input[name=__RequestVerificationToken]').val();
return data;
};
So the MVC view and controller action that work are defined like this:
<div class="row">
#Html.HiddenFor(model => model.CustomFieldOptionId)
#Html.HiddenFor(model => model.CustomFieldId)
#Html.HiddenFor(model => model.SortOrder, new { #class = "SortOrder" })
#Html.HiddenFor(model => model.IsActive)
#Html.ValidationMessageFor(model => model.OptionLabel, "", new { #class = "text-danger" })
<div class="col-md-2">
#Html.LabelFor(model => model.OptionLabel, htmlAttributes: new { #class = "control-label" })
</div>
<div class="col-md-7">
#Html.EditorFor(model => model.OptionLabel, new { htmlAttributes = new { #class = "form-control" } })
</div>
<div class="col-md-3">
<input type="button" value="Delete" class="btn delete-link" />
<div class="btn btn-primary delete-confirm" style="display: none"
data-delete-id="#Model.CustomFieldOptionId"
data-delete-controller="customforms"
data-delete-action="_OptionEditorRowDelete">Confirm Delete</div>
</div>
</div>
Controller:
[HttpPost, ActionName("_OptionEditorRowDelete")]
[ValidateAntiForgeryToken]
public ActionResult _OptionEditorRowDelete(int id)
{
var custFieldOption = db.CustomFieldOptions.Find(id);
if (custFieldOption == null) return null;
custFieldOption.IsActive = false;
db.Entry(custFieldOption).State = EntityState.Modified;
db.SaveChanges();
return null;
}
The one that is not working is defined like this:
#foreach (var item in Model) {
<tr>
<td>
#Html.HiddenFor(modelItem => item.ProfileId)
#Html.DisplayFor(modelItem => item.ProfileIdentifierValue)
</td>
<td>
#Html.DisplayFor(modelItem => item.IsPrimary)
</td>
<td>
#Html.ActionLink("Edit", "profileemailsedit", new { id = item.ProfileIdentifierId }) |
#Html.ActionLink("Delete", "_ProfileEmailsDelete", new { id = item.ProfileIdentifierId }, new { #class = "delete-link" })
<a class="delete-link" href="#Url.Action("_ProfileEmailsDelete", new { id = item.ProfileIdentifierId })">Delete</a>
<input type="button" value="Delete" class="btn delete-link" />
<div class="btn btn-primary delete-confirm" style="display: none"
data-delete-id="#item.ProfileIdentifierId"
data-delete-controller="profiles"
data-delete-action="_ProfileEmailsDelete">Confirm Delete</div>
</td>
</tr>
}
Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult _ProfileEmailsDelete(int id)
{
var profIdentifier = db.ProfileIdentifier.Find(id);
if (profIdentifier == null) return null;
profIdentifier.IsActive = false;
db.Entry(profIdentifier).State = EntityState.Modified;
db.SaveChanges();
return null;
}
As you can see the controllers are very similar. However, the _ProfileEmailsDelete get's this javascript error:
POST http://localhost:63595/profiles/_ProfileEmailsDelete/168 500 (Internal Server Error)
Part of the server 500 error is:
[HttpAntiForgeryException]: The required anti-forgery form field
"__RequestVerificationToken" is not present. at
System.Web.Helpers.AntiXsrf.TokenValidator.ValidateTokens(HttpContextBase
httpContext, IIdentity identity, AntiForgeryToken sessionToken,
AntiForgeryToken fieldToken) at
System.Web.Helpers.AntiXsrf.AntiForgeryWorker.Validate(HttpContextBase
httpContext) at System.Web.Helpers.AntiForgery.Validate()
I'm not sure why the AntiForgery works with one and not the other.
The 500 error is your ajax response from the server, not your javascript. The actual problem is not jumping out at me, but most often when I have seen this type of behavior it ends up being something in the view rendering that causes it. For example trying to reference the values of a collection that is null in the view would act this way. Using the traffic analyzer features of the browser developer tools can sometimes help shed light on the real problem.
The first example was in a partial view. The parent view had this:
#Html.AntiForgeryToken()
I added that to the View for the second example, and then the javascript could properly get the token to pass back with the $.post command.
#{
ViewBag.Title = " Grid with Multicolumn headers";
}
#using Kendo.Mvc.UI
#using SampleUIApp.Areas.GridSample.Models
#model SampleUIApp.Areas.GridSample.Models.GridSampleModel
#{
ViewBag.Title = "Grid Sample - InLine Edit";
Layout = "~/Views/Shared/_PageLayout.cshtml";
}
#section pageBody {
<div style="float:right;margin-right:10px;margin-top:10px;margin-bottom:10px">
#(Html.Kendo().Button()
.Name("Hide_toolbar")
.Events(e => e.Click("Hidetoolbar"))
.Content("Hide Toolbar"))
#(Html.Kendo().Button()
.Name("Show_toolbar")
.Events(e => e.Click("Showtoolbar"))
.Content("Show Toolbar"))
</div>
<br />
<br />
#using (Html.BeginForm("InLineIndex", "GridSample", FormMethod.Post, new { #id = "InLineIndexMain" }))
{
<div id="DetailPanel" class="containerDiv100">
#(Html.Kendo().Grid<GridSampleModel>()
.Name("KendoGrid1") // Grid Name can be used in Javascript, if required.
//Columns defination of the fields.
.Columns(columns =>
{
columns.Template(m => m.SampleId).Title("<input id='checkAll', type='checkbox', class='check-box' />");
columns.Group(group=>group
.Title("Personal Information")
.Columns(info => {
info.Bound(m => m.SampleName).Title("Sample Name").Width(200).Filterable(true).HtmlAttributes(new { #style = "font-size:x-small" });
info.Bound(m => m.Age).Title("Age").Width(100).Filterable(false).Format("{0:d}").HtmlAttributes(new { #style = "text-align:right" });
info.Bound(m => m.Height).Title("Height").Width(150).Locked().Filterable(false).Format("{0:N2}").HtmlAttributes(new { #style = "font-size:x-small" });
info.Bound(m => m.City).Title("City (Auto Complete)").Width(350).Lockable(false).Filterable(true).ClientTemplate("#=City.CityName#");
})
);
//columns.Bound(m => m.Age).Title("Age").Width(100).Filterable(false).Format("{0:d}").HtmlAttributes(new { #style = "text-align:right" });
//columns.Bound(m => m.Height).Title("Height").Width(150).Locked().Filterable(false).Format("{0:N2}").HtmlAttributes(new { #style = "font-size:x-small" });
//columns.Bound(m => m.City).Title("City (Auto Complete)").Width(350).Lockable(false).Filterable(true).ClientTemplate("#=City.CityName#");
columns.Bound(m => m.Category).Title("Category (Drop Down List)").Width(400).Filterable(true).ClientTemplate("#=Category.CategoryName#");
columns.Bound(m => m.EmployeeList).Title("Employee (Multi Select)").Width(300).Filterable(true).ClientTemplate("#= renderSelectedEmployees(data.EmployeeList)#")
.EditorTemplateName("ClientEmployee");
columns.Bound(m => m.EntityStatus).Title("Status (CheckBox)").Width(200);
columns.Bound(m => m.CreditCard).Title("Credit Card No (Masked TextBox)").Width(250).HtmlAttributes(new { #Style = "font-size:x-small" });
columns.Bound(m => m.StartDate).Title("Start Date ").Width(150).Filterable(false).Format("{0:dd/MM/yyyy}").HtmlAttributes(new { #style = "font-size:x-small" });
columns.Bound(m => m.EndDate).Title("End Date").Width(150).Filterable(false).Format("{0:dd/MM/yyyy}").HtmlAttributes(new { #style = "font-size:x-small" });
columns.Bound(m => m.Qty).Title("Quantity").Width(100).ClientTemplate("#=Qty#").HtmlAttributes(new { #Style = "text-align:right" });
columns.Bound(m => m.Rate).Title("Rate").Width(100).ClientTemplate("#=Rate#").Format("{0:N2}").HtmlAttributes(new { #Style = "text-align:right" });
columns.Bound(m => m.LineValue).Title("Value").Width(100).Format("{0:n2}").HtmlAttributes(new { #Style = "text-align:right;" });
columns.Command(commands =>
{
commands.Edit().Text(" ");
commands.Destroy().Text(" ");
commands.Custom("Hide").Click("Hide").HtmlAttributes(new { #style = "min-width : 0;font-size:x-small;" });
}).Title("Commands").Width(200).HtmlAttributes(new { #style = "font-size:x-small" });
})
.ToolBar(toolbar =>
{
toolbar.Custom().Text("Add New Sample").Name("add").HtmlAttributes(new { #class = "Toolbar_right" }).HtmlAttributes(new { #style = "font-size:x-small" }).Url("~/GridSample/GridSample02/Create");
toolbar.Create().HtmlAttributes(new { #class = "Toolbar_right" }).HtmlAttributes(new { #class = "hide-button" });
})
.Editable(editable => editable.Enabled(#Model.EditEnable).Mode(GridEditMode.InLine)) // will make grid editable with all cells
// Here "Enabled(#Model.EditEnable)" will allow user to edit the grid control or not depending on Model's EditEnable value i.e. True / False
.Pageable() // Display grid data in multiple pages depending on PageSize parameter
.Scrollable(config => config.Enabled(true)) // Make grid Scrollable
.Filterable(config => config.Mode(GridFilterMode.Menu)) // Allow to set filters on different columns of the grid
.Sortable() // Allow user to sort the data in grid
.ColumnMenu() // Display menu with different actions on
// Display grid row in different colour it will be helpful to identify which grid row is selected.
.Selectable(selectable => selectable
.Mode(GridSelectionMode.Multiple)
.Type(GridSelectionType.Row))
.Navigatable()
.Resizable(config => { config.Columns(true); })
.Reorderable(config => { config.Columns(true); })
.Events(events => events.Save("OnCellDataModified").Edit("OnCellChange")) // Grid events to call javascripts on different actions.
.DataSource(source => source
.Ajax()
.Batch(false)
.PageSize(5)
.ServerOperation(false)
.Model(model =>
{
model.Id(m => m.SampleId);
model.Field(m => m.Category).DefaultValue(
ViewData["defaultCategory"] as CategoryViewModel);
model.Field(m => m.City).DefaultValue(
ViewData["defaultCity"] as CityViewModel);
//Given below code will not allow user
//to change (either manual / calculated) the given cell value
//But it will also do not change updated value in model
//model.Field(m => m.LineValue).Editable(false);
})
// Actions called from controller
.Read(read => read.Action("Fetch", "GridSample", new { area = "GridSample" }))
.Create(create => create.Action("InLine_Insert", "GridSample", new { area = "GridSample" }))
.Update(update => update.Action("InLine_Update", "GridSample", new { area = "GridSample" }))
.Destroy(delete => delete.Action("Delete", "GridSample", new { area = "GridSample" }))
)
)
</div>
<script type="text/javascript">
// Code added for Keyboard Navigation Support
$(document.body).keydown(function (e) {
if (e.altKey && e.keyCode == 87) {
$("#grid").data("kendoGrid").table.focus();
}
});
function OnSelectEmply(e) {
// This sample javascript function called from Employee MultiSelect Partial View
}
function CalculateTotValue(data) {
return data.Qty * data.Rate;
}
function OnCellChange(e) {
//alert("Cell Change");
//Disable the edit mode depending on the model value of EntityStatus field i.e. True / False
$("#LineValue").prop("disabled", e.model.EntityStatus);
//Set Default values while adding new row in Grid
if (e.model.isNew() && !e.model.dirty) {
e.container
.find("input[name=SampleName]") // get the input element for the field
.val("Sample Name - 4") // set the value
.change(); // trigger change in order to notify the model binding
}
}
function OnCellDataModified(e) {
//alert("Cell Data Modified");
if (e.values && e.values.LineValue) {
//alert("Calculate # LineValue");
var qty = e.values.Qty || e.model.Qty;
var rate = e.values.Rate || e.model.Rate;
e.model.set("LineValue", rate * qty);
e.values.set("LineValue", rate * qty);
$("#KendoGrid1").data("kendoGrid").refresh();
}
else {
if (e.values && (e.values.Qty || e.values.Rate)) {
//alert("Calculate # Qty, Rate");
var qty = e.values.Qty || e.model.Qty;
var rate = e.values.Rate || e.model.Rate;
e.model.set("LineValue", rate * qty);
e.values.set("LineValue", rate * qty);
$("#KendoGrid1").data("kendoGrid").refresh();
}
}
}
function renderSelectedEmployees(List) {
//alert(List.length);
if (List != undefined && List[0] != undefined) {
var text;
$.each(List, function (index) {
if (text == undefined)
text = List[index].EmployeeName;
else
text = text + ", " + List[index].EmployeeName;
})
//alert($("#LineValue").width);
if (text.length > 30) {
text = text.substring(0, 5) + " .... (" + List.length.toString().trim() + ")"
}
return text;
}
else
return "";
}
function Hide(e)
{
var grid = $("#KendoGrid1").data("kendoGrid");
////e.preventDefault();
//var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
//var row = $(this).closest("tr");
//var rowIdx = $("tr", grid.tbody).index(row);
//grid.tbody.find("tr:first").hide();
grid.tbody.closest("tr").Hide();
//grid.tbody.closest("tr").hide();
//var item = this.dataSource.get(); //Get by ID or any other preferred method
//this.tbody.find("tr[data-uid='" + item.uid + "']").hide();
}
function Hidetoolbar() {
$(".k-grid-add").hide();
}
function Showtoolbar() {
$(".k-grid-add").show();
}
$("#kendoGrid1").on("click", ".hide-button", function () {
alert("reached");
$(this).parent().parent().hide();
});
</script>
}
}
As you can see there is custom command button know as hide in my grid.. i wish to hide the row when that button is clicked..
how do i get hat done?
i have tried a line as grid.tbody.find("tr:first").hide();
but this works only for the first line. wha should i do for the other rows?
Your selector will find only the first tr, so only the first line.
You need to change your selecor to:
grid.tbody.closest("tr").hide();
This code is very ugly:
commands.Custom("Hide").Click("Hide").HtmlAttributes(new { #style = "min-width : 0;font-size:x-small;" });
It is mixing server-side code with css and javascript. Forget about the click event and do not give it style attribute. You should give it a class attribute. Let's name its class hide-button.
Define a rule for your hide-button elements in CSS, like this:
.hide-button {
min-width: 0;
font-size: x-small;
}
Make sure that this CSS rule is loaded in your page.
Then, your Javascript should be defined. Since you have not given us the HTML the code generated, I will assume your HTML contains a grid, which contains a tbody, which contains tr elements, which contain td elements. One of the td elements will contain your hide-button in each row. So, you should define this behavior:
$("body").on("click", ".hide-button", function() {
$(this).parent().parent().hide();
});
Note, that since you did not give me enough information, I have used assumptions in my answer. As a result, if any of my assumptions was wrong, the answer will not work for you. If you have any more problems, then make sure that you give me all the information.
So, I want to change my checkbox, that has checked and unchecked state to radio buttons that say, Yes (checked) or No (unchecked).
Here's what I did for the checkbox:
In my view:
#Html.CheckBoxUi("PerpendicularCheckbox",#H.GetString("IsPerpendicular"), null, new { style = "margin-right:10px", #class = "type-style-paragraph" })
js:
$('input:checkbox[name=PerpendicularCheckbox]').on({
"change": function () {
if (getUpdate()) {
var $this = $(this);
if (($this).is(':checked'))
$("ul li button").click();
}
}
});
if (!Perpendicular) {
$("#PerpendicularCheckbox").prop("checked", false);
}
else {
$("#PerpendicularCheckbox").prop("checked", true);
}
I was wondering what would I need to change it to radio buttons, yes and no options, using html extension in asp.net mvc?
EDIT:
My loosy attempt at radio buttons:
#Html.RadioButtonForUi("PerpendicularCheckbox",#H.GetString("IsPerpendicular"), null, new { style = "margin-right:10px", #class = "type-style-paragraph" })
$('input:radio[name=PerpendicularCheckbox]').on({
"change": function () {
if (getUpdate()) {
var $this = $(this);
if (($this).is(':checked'))
$("ul li button").click();
}
}
});
RadioButtonForUi :
public static MvcHtmlString RadioButtonForUi<TModel, TProperty>(
this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression,
string name,
bool IsEnable,
bool IsChecked,
object onchange = null,
string className = "",
bool isRequreid = true
) {etc.....}
Here is a tested sample:
<div class="form-group">
#Html.LabelFor(model => model.SaleOfPropertyPurchase, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<div class="checkbox">
#Html.RadioButtonFor(model => model.SaleOfPropertyPurchase, true, new { id = "SaleOfPropertyPurchase-true" }) Yes
#Html.RadioButtonFor(model => model.SaleOfPropertyPurchase, false, new { id = "SaleOfPropertyPurchase-false" }) No
#Html.ValidationMessageFor(model => model.SaleOfPropertyPurchase, "", new { #class = "text-danger" })
</div>
</div>
</div>
Here is some sample jquery that reacts to the radio button click, and also sets up initial display on the form:
#Scripts.Render("~/bundles/jquery")
<script type="text/javascript">
$(function () {
$('#CurrentPropertyOwner-true').on('change', function () {
$('#CurrentProperty').show();
});
});
$(function () {
$('#CurrentPropertyOwner-false').on('change', function () {
$('#CurrentProperty').hide();
});
});
$(document).ready(function () {
var ischecked = $('#CurrentPropertyOwner-true').is(':checked')
if (ischecked == true) {
$('#CurrentProperty').show();
}
var ischecked = $('#CurrentPropertyOwner-false').is(':checked')
if (ischecked == true) {
$('#CurrentProperty').hide();
}
});
</script>
You need to render two radio buttons for the property, one with the value of "True" and the other with the value of "False" so the selected value can be bound to a boolean value
You custom html helper would need to be
namespace YourAssembly.Html
{
public static class MyHelpers
{
public static MvcHtmlString BooleanButtonsFor<TModel>(this HtmlHelper<TModel> helper, Expression<Func<TModel, bool>> expression)
{
ModelMetadata metaData = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);
string name = ExpressionHelper.GetExpressionText(expression);
StringBuilder html = new StringBuilder();
// Yes button
string id = string.Format("{0}-yes", name);
html.Append(helper.RadioButtonFor(expression, "True", new { id = id }));
html.Append(helper.Label(id, "Yes"));
// No button
id = string.Format("{0}-no", name);
html.Append(helper.RadioButtonFor(expression, "False", new { id = id }));
html.Append(helper.Label(id, "No"));
// enclode in a div for easier styling with css
TagBuilder div = new TagBuilder("div");
div.AddCssClass("radiobuttongroup");
div.InnerHtml = html.ToString();
return MvcHtmlString.Create(div.ToString());
}
}
}
then add a reference to the <namespaces> section of web.config
<add namespace="YourAssembly.Html "/>
and use it in the view
#Html.BooleanButtonsFor(m => m.YourBoolProperty)
I'm having two dropdown lists in my MVC(Razor) view: Country and State.
I'm able to fill both the dropdown's independent of each other.Now i want to fill second dropdown(State) based on the change event of Country's dropdown.
For this I have used JsonResult method in Controller and for this method i'm passing countryID on the Change event of Country from my view inorder to fill my second dropdown state.
Problem Statement: The JsonResult method is getting triggered from my view but the CountryId value is not getting passed from view to controller in-order to fill state.
What i'm doing wrong here?
View:
Javascript:
<script type="text/JavaScript">
function CountryChange() {
var url = '#Url.Content("~/MasterConfigGeneral/GetState")';
var ddlsource = "#CountryID";
var ddltarget = "#StateID";
if ($(ddlsource).val() != "") {
$.ajaxSetup({ cache: false });
$.getJSON(url, { countryID: $(ddlsource).val() }, function (data) {
$(ddltarget).empty();
$("#StateID").append("<option value=''>Select State</option>");
$.each(data, function (index, optionData) {
$("#StateID").append("<option value='" + optionData.Value + "'>" + optionData.Text + "</option>");
});
});
}
else {
$("#StateID").empty();
$("#StateID").append("<option value=''>Select State</option>");
}
}
</script>
Dropdown's in my View:
<div class="cssclass">
#Html.DropDownListFor(model => model.companyModel.CountryID, new SelectList(Model.ddlCountryStateCity.ddlCountry, "Value", "Text"), "Select Country", new { onchange="CountryChange()" })
#Html.ValidationMessageFor(model => model.companyModel.CountryID)
</div>
<div class="cssclass">
#Html.LabelFor(model => model.companyModel.StateID)
</div>
<div class="editor-field">
#Html.DropDownList("stateid",Model.ddlCountryStateCity.ddlState,"Select State")
#Html.ValidationMessageFor(model => model.companyModel.StateID)
</div>
Controller:
Country Dropdown:
#region Country
public DropdownListCountryStateCity FillDropDownListCountry()
{
objDropDownCountryStateCity.ddlCountry = (from s in dbEntity.Countries
select new SelectListItem()
{
Text = s.Name,
Value = s.CountryID
}).ToList<SelectListItem>();
return objDropDownCountryStateCity;
}
#endregion
State Dropdown:
#region State
public JsonResult GetState(string countryID)
{
JsonResult jsResult = new JsonResult();
objDropDownCountryStateCity.ddlState = (from csc in dbEntity.CountryStateCities
join c in dbEntity.Countries on csc.CountryID equals c.CountryID
join s in dbEntity.States on csc.StateID equals s.StateID
where csc.CountryID == countryID
select new SelectListItem()
{
Text = s.Name,
Value = s.StateID
}).ToList<SelectListItem>();
jsResult.Data = objDropDownCountryStateCity.ddlState;
jsResult.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
return jsResult;
}
#endregion
Your problem lies on how the DropDownListFor helper generates the element.
In your code, it's generating names and ids something like this:
<select id="companyModel_CountryID" name="companyModel.CountryID">
...
</select>
In your javascript the ddlSouce is "#CountryID". Since there's no element with that id, jQuery pass null as data to $.getJSON. That's why the controller method receives nothing.
You have two options:
Change ddlSource javascript to the proper id (you'll have to see on the source code) OR
Change the last DropDownListFor helper from
new { onchange="CountryChange()" }
to
new { id = "CountryID", onchange="CountryChange()" }
IMHO, the last option is the best choice.