Single selection checkbox - c#

I want to only allow a single checkbox to be selected inside my foreach loop, right now I can select multiple.I have a click event but this will not uncheck the other checkboxes when I make a checkbox selection. What's wrong here? Thanks
<div class="consulting-editors" data-bind="foreach: ConsultingEditors">
<input type="checkbox" name="Promote" data-bind="checked: Promote, click: $parent.promoterSelectedOnclick" /> Display as main editor
</div>
ConsultingEditors: KnockoutObservableArray<NavigatorAuthorApi> = ko.observableArray();
promoterSelectedOnclick = (selectedEditor: NavigatorAuthorApi) => {
if (this.ConsultingEditors().some(e => e.Promote)) {
this.ConsultingEditors().filter(e => e.AuthorRef != selectedEditor.AuthorRef).forEach((e) => {
e.Promote = false;
});
}
return this.ConsultingEditors();
}
export type NavigatorAuthorApi =
{
SortOrder: number,
FirmRef: number,
FirmName: string,
AuthorRef: number,
AuthorName: string,
DisplayString: string,
EditorImage: ByteString[],
Promote: boolean
}

Promote should be an observable if you want property change to reflect on the DOM.
class viewModel {
ConsultingEditors = ko.observableArray([
{ Promote: ko.observable(false), AuthorRef: 1},
{ Promote: ko.observable(false), AuthorRef: 2 },
{ Promote: ko.observable(false), AuthorRef: 3 }
]);
promoterSelectedOnclick = (selectedEditor) => {
this.ConsultingEditors().filter(e => e.AuthorRef != selectedEditor.AuthorRef).forEach((e) => {
e.Promote(false);
});
return true;
}
}
ko.applyBindings(new viewModel())
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div class="consulting-editors" data-bind="foreach: ConsultingEditors">
<input type="checkbox" name="Promote" data-bind="checked: Promote, click: $parent.promoterSelectedOnclick" /> Display
</div>

Two things,
You need your click function to return true otherwise the click binding will conflict with the checked binding.
Promote is being used as a boolean, but it needs to be an Observable for the UI to react to any changes to its value. Everything that the UI needs to react to has to be a knockout observable.
function viewModel(){
var self=this;
self.ConsultingEditors = ko.observableArray([
new NavigatorAuthorApi(false, 1),
new NavigatorAuthorApi(false, 2),
new NavigatorAuthorApi(false, 3)
]);
self.promoterSelectedOnclick = function(selectedEditor){
if (self.ConsultingEditors().some(e => e.Promote())) {
var others = self.ConsultingEditors().filter(e => e.AuthorRef != selectedEditor.AuthorRef);
others.forEach((e) => {
e.Promote(false);
});
}
return true;
}
}
function NavigatorAuthorApi(promote, authorRef)
{
var self = this;
self.SortOrder = null;
self.FirmRef = null;
self.FirmName = null;
self.AuthorRef = authorRef;
self.AuthorName = null;
self.DisplayString = null;
self.EditorImage = null;
self.Promote = ko.observable(promote);
}
ko.applyBindings(new viewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div class="consulting-editors" data-bind="foreach: ConsultingEditors">
<input type="checkbox" name="Promote" data-bind="checked: Promote, click: $parent.promoterSelectedOnclick" /> Display as main editor
</div>

Related

DropDownListFor onchange but for same value

I'm trying to trigger an onchange event, even if the value they select is the same as before. I have tried onselect, but it does not trigger at all. And onchange does not trigger if value is the same. Is there any other patterns I could use to make this possible?
#Html.DropDownListFor(m => m.SelectedMarkdownDate, Model.ValidDatesSelectList, new{onchange = "LoadGridData(this);" })
Ended up using JQuery:
var go = false;
$('#SelectedMarkdownDate').on('click',function() {//on click
if (go) {//if go
var date = $('#SelectedMarkdownDate option:selected').text();
LoadGridData(date);
go = false;//switch off
} else { go = true; }//if !go, switch on
}).on('blur', function () { go = false; });
It looks like you answered your question, however I already made a fiddle so here it is.
you can use the onClick event with blur to tell whether or not the dropdown is open, when you select the same item it gives you an alert just to demonstrate that it recognizes the event.
https://jsfiddle.net/Anon_E_Mustard/yoxs0gk8/
<script>
var dropboxOpen = false,
oldItem = null;
counter = 0;
function onClick(e) {
if (dropboxOpen) {
if (oldItem && oldItem === e.target.value) {
alert("same selected")
}
oldItem = e.target.value;
dropboxOpen = false;
}else{
dropboxOpen = true;
}
}
function onBlur(e){
dropboxOpen = false;
}
</script>
<select onclick="onClick(event)" onblur="onBlur(event)">
<option value="volvo">volvo</option>
<option value="saab">saab</option>
<option value="opel">opel</option>
<option value="audi">audi</option>
</select>

How to create a disabled textbox in MVC razor view

I want to create text area which will be disabled or invisible at starting.
There's a dropdown list, on selection of last option i.e other, it should enable or make the text area visible and take the value and pass to controller on submission.
Use
#Html.TextArea("Name", null, new { disabled="disabled" })
For You:
<div>
#Html.TextArea("Name", null, new { disabled="true" })
#Html.DropDownList("switch", new List<SelectListItem>() {
new SelectListItem(){Text="Enable", Value="Enable"},
new SelectListItem(){Text="Disable", Value="Disable", Selected=true},
})
</div>
<script>
$(function ($) {
var dropDown = $("#switch");
var txtName = $("#Name");
dropDown.change(function () {
if (dropDown.val() === "Disable")
{
txtName.attr("disabled", true);
}
else {
txtName.removeAttr("disabled");
}
})
})(jQuery)
</script>
You should hide the text area, not only disable it. What you can do is add the html :
#Html.TextArea("Text", null, new { #class="hiddenOptionArea", disabled="disabled" })
and apply the class:
hiddenOptionArea {
display:none
}
Also you better use #Html.EditorFor and make yourself a template for your model, so that you can reuse your html wherever you need it - you can find the link here: http://rachelappel.com/razor/partial-views-in-asp-net-mvc-3-w-the-razor-view-engine/
You should try this for creating disabled textArea
#Html.TextAreaFor(m => m.property, new { id = "txtId", disabled = "disabled" })

JQuery client side continues even if invalid mvc 4

Script
$(document).ready(function () {
"use strict";
$.validator.unobtrusive.parse($("#form"));
$("#submit").on("click", function () {
var form = $("#form");
form.validate();
if (form.valid()) {
}
return false;
});
});
HTML
<span>Please enter the amount of orders you wish you process:</span>
<br>
#Html.TextBoxFor(m => m.OrderModel.AmountOfOrders, new {id = "AmountOfOrders"})
#Html.ValidationMessageFor(m=> m.OrderModel.AmountOfOrders)
<input type="submit" value ="Submit" id="submit" />
I seem to have a problem with the script. The DataAnnotations for C# are showing up on the View but even if required fields are empty it will still continue to the other page.
if your button is not given
type="button"
, it will default to
type="submit"
Considering that you are using a form, the form will get submitted by the button click as your javascript is executing.
Try this.
$("#submit").on("click", function (event) {
var form = $("#form");
form.validate();
if (form.valid()) {
}
else
{
event.preventDefault();
return false;
}
});
Always use the submit event for forms, not the click event. That way it will work with key-presses:
$("#submit").on("submit", function () {
var form = $("#form");
form.validate();
if (form.valid()) {
// Proceed with submit!
}
else {
// Stop submit!
return false;
}
});

How can I include hidden DIVs using CSS without them take up space?

I have a simple MVC 5 page with a single dropdown list. Based upon the selection made from this dropdown list I enable visibility for one of three divs on the page. The problem I am running into is each div takes space on the page, even if it is not visible. So when I select something from dropdown list that causes the second div to be visible I will see that content shifted down on the page.
Here is the code from the Controller to create the data for the dropdown list.
public ActionResult Index()
{
var searchBy = new List<SearchBy>
{
new SearchBy { Name = "Email Address", Value = "EmailAddress" },
new SearchBy { Name = "Last name, First name", Value = "Name" },
new SearchBy { Name = "Username", Value = "Username" }
};
ViewBag.SearchByOptions = new SelectList(searchBy, "Value", "Name");
return View();
}
Here is my markup for the Index.cshtml
#{
<script type="text/javascript">
$(document).ready(function() {
// Make all three <div>s hidden when the page loads...
document.getElementById("searchByEmail").style.visibility = "hidden";
document.getElementById("searchByName").style.visibility = "hidden";
document.getElementById("searchByUsername").style.visibility = "hidden";
});
function searchBy(selectedItem) {
if (selectedItem == "EmailAddress") {
// Make visible
document.getElementById("searchByEmail").style.visibility = "visible";
// Make in-visible
document.getElementById("searchByName").style.visibility = "hidden";
document.getElementById("searchByUsername").style.visibility = "hidden";
}
if (selectedItem == "Name") {
// Make visible
document.getElementById("searchByName").style.visibility = "visible";
// Make in-visible
document.getElementById("searchByEmail").style.visibility = "hidden";
document.getElementById("searchByUsername").style.visibility = "hidden";
}
if (selectedItem == "Username") {
// Make visible
document.getElementById("searchByUsername").style.visibility = "visible";
// Make in-visible
document.getElementById("searchByEmail").style.visibility = "hidden";
document.getElementById("searchByName").style.visibility = "hidden";
}
};
</script>
}
<h2>Index</h2>
<div>
Search for existing users by: #Html.DropDownList("SelectedItem", (SelectList)ViewBag.SearchByOptions, "-- Select One --", new { onchange = "searchBy($('#SelectedItem').val());" })
</div>
<div id="searchByEmail">
Emails...
</div>
<div id="searchByName">
Names...
</div>
<div id="searchByUsername">
Usernames...
</div>
}
I am not sure what trick is needed to get all of the divs to take the same "real estate" on the page as I will only be showing one of them at a time.
Assuming that you use jQuery, try:
#{
<script type="text/javascript">
$(document).ready(function() {
$("#searchByEmail").hide();
$("#searchByName").hide();
$("#searchByUsername").hide();
});
function searchBy(selectedItem) {
if (selectedItem == "EmailAddress") {
$("#searchByEmail").show();
$("#searchByName").hide();
$("#searchByUsername").hide();
}
if (selectedItem == "Name") {
$("#searchByName").show();
$("#searchByEmail").hide();
$("#searchByUsername").hide();
}
if (selectedItem == "Username") {
$("#searchByUsername").show();
$("#searchByEmail").hide();
$("#searchByName").hide();
}
};
</script>
}
<h2>Index</h2>
<div>
Search for existing users by: #Html.DropDownList("SelectedItem", (SelectList)ViewBag.SearchByOptions, "-- Select One --", new { onchange = "searchBy($('#SelectedItem').val());" })
</div>
Also, check what is the difference between CSS rules:
visibility:hidden
and
display:none
The first just hide the element, but preserve the placeholder the same size as it is visible.
The second removes it from the size and dimension calculations.
.style.display = "block"; /* or none to hide it */

ASP.net getting RadioButtonList value on content page with javascript

I'm having a problem with my JavaScript code having moved it over to a content page in ASP.
It worked perfectly on a stand alone page.
<script type="text/javascript">
function validateQ12(oSrc, args) {
var rbtnList = document.getElementsByName('rbtn12');
var noClicked = false;
for (var i = 0; i < rbtnList.length; i++) {
if (rbtnList[i].checked) {
noClicked = rbtnList[i].value == "No";
break;
}
}
if (noClicked) {
args.IsValid = true;
}
else
args.IsValid = args.Value.trim().length > 0;
}
</script>
I have gone through the html on both pages, on the one that worked had
<input id="rbtn12_1" type="radio" name="rbtn12" value="No" checked="checked" onclick="Q12iNo();">
The new one inside a content page has
<input id="MainContent_rbtn12_1" type="radio" name="ctl00$MainContent$rbtn12" value="No" checked="checked" onclick="Q12iNo();">
Clearly the name change must be causing the problem. How do I reference this new name in my javascript code?
To get the rendered element name use the following:
<%= rbtn12.UniqueID %>
However in your case this may still not work as it looks like you need to loop through each radio button item.
See the following post:
Find out if radio button is checked with JQuery?
Which shows how to determine if a radio button collection has a selected value.
Can you possibly add a className to your control and use getElementByClassName?
<input id="MainContent_rbtn12_1" type="radio" name="ctl00$MainContent$rbtn12" value="No" checked="checked" onclick="Q12iNo();" CssClass="Radio">
<script type="text/javascript">
function validateQ12(oSrc, args) {
var rbtnList = document.getElementsByClassName('Radio');
var noClicked = false;
for (var i = 0; i < rbtnList.length; i++) {
if (rbtnList[i].checked) {
noClicked = rbtnList[i].value == "No";
break;
}
}
if (noClicked) {
args.IsValid = true;
}
else
args.IsValid = args.Value.trim().length > 0;
}
</script>

Categories

Resources