In jquery 3.4.1 app I have checkbox defined
<div class="form-row mb-3 mt-3">
<label for="step_2_invoice_on_next_period_cbx" class="col-12 col-sm-6 col-form-label">Invoice on next period</label>
<div class="col-12 col-sm-6">
<input type="checkbox" value="1" style="width: 50px;padding-left: 10px; margin-top: 7px;"
id="step_2_invoice_on_next_period_cbx"
checked>
</div>
</div>
and I got valid true if checkbox input is selected. But I got undefined if checkbox input not is selected
and I need to set additive condition :
var step_2_invoice_on_next_period_cbx= $("#step_2_invoice_on_next_period_cbx:checked").val()
if(typeof step_2_invoice_on_next_period_cbx=='undefined') step_2_invoice_on_next_period_cbx= false
Looks like it works ok, but if there is a better way to got valid true/false condition without additive
checking line ?
Thanks!
Solution
This is the way you should go about doing this this way will listen for when the checkbox is checked (true or false) how it does this is by listening for the checkbox to be clicked when it is clicked it will run everything inside of stepTwoInvoiceOnNextPeriodCbx.click() what we are doing inside of the stepTwoInvoiceOnNextPeriodCbx.click() event is checking if the property checked is true or false (stepTwoInvoiceOnNextPeriodCbx.prop("checked")) if this is true in my code example we are going to change the text of the element with an id of #text to "Is checked" when true and "is not checked" when false.
JavaScript
let stepTwoInvoiceOnNextPeriodCbx = $(
"#step_2_invoice_on_next_period_cbx"
);
let text = $("#text"); // This is just here to show output of the example
// Listen for checkbox to be click
stepTwoInvoiceOnNextPeriodCbx.click(() => {
// If the checked property
if (stepTwoInvoiceOnNextPeriodCbx.prop("checked")) {
// Is true set text to "Is checked"
text.text("Is checked");
} else {
// Is false set text to "Is not checked"
text.text("Is not checked");
}
});
HTML
<div id="app">
<div class="form-row mb-3 mt-3">
<label
for="step_2_invoice_on_next_period_cbx"
class="col-12 col-sm-6 col-form-label"
>Invoice on next period</label
>
<div class="col-12 col-sm-6">
<input
type="checkbox"
value="1"
style="width: 50px; padding-left: 10px; margin-top: 7px;"
id="step_2_invoice_on_next_period_cbx"
checked
/>
</div>
<span id="text"></span>
</div>
</div>
Here is an example I made so you can see how it works https://codesandbox.io/s/compassionate-blackwell-d9hex?file=/src/index.js
What your code is doing
You are checking to see if the data type of the value property is "undefined", "undefined" and undefined are two different things since you are checking the type of the data what you are telling the computer to do is check if the type of the value property is equal to (==) a string (text data type) with the value of undefined ("undefined") this comparison is not checking the data types you would have to use the identical operator (===) this checks the value and data type are the same. the val() method get the value property of the HTML element this in your case will always be undefined because it is never set.
The way you have coded this also means that it will only run once the page has loaded since you are not listening for a event (like click() in my example) the click() event means anytime the #step_2_invoice_on_next_period_cbx element is clicked run the function inside of the click() event.
Other things to keep in mind
In JavaScript, it is good practice to use camelcase for naming varibles and functions, not undersorces (snakecase) languages like PHP use snakecase (this_is_snake_case) while in JavaScript we use camelcase (thisIsCamelCase) but we tend use pascalcase (ThisIsPascalCase) for class names.
It looks like you want prop: https://api.jquery.com/prop/
Not sure what you're trying to accomplish based on the code, so here is some examples:
This code will take a checkbox that is checked and uncheck it for instance:
$(document).ready(function() {
var step_2_invoice_on_next_period_cbx= $("#step_2_invoice_on_next_period_cbx:checked");
if (step_2_invoice_on_next_period_cbx.prop("checked")) {
step_2_invoice_on_next_period_cbx.prop("checked", false);
}
})
This code will take a checkbox that is not checked and do something
$(document).ready(function() {
var step_2_invoice_on_next_period_cbx= $("#step_2_invoice_on_next_period_cbx:checked");
if (!step_2_invoice_on_next_period_cbx.prop("checked")) {
//do something
}
})
JavaScript
var isChecked = document.querySelector("#step_2_invoice_on_next_period_cbx").checked;
jQuery
var isChecked = $("#step_2_invoice_on_next_period_cbx").prop("checked");
$("#step_2_invoice_on_next_period_cbx:checked") gets you a HTML element with
id="step_2_invoice_on_next_period_cbx"
state "checked"
For an unchecked element the second condition is false and will return undefined for you.
Related
I have a frustrating issue since last week. I am using a bootstrap checkbox inside a modal that I want to prefill with either true or false depending on the user selection for that boolean field. Even though I can get the value correctly, I can not get the tick on the checkbox working.
modal.html
<div class="input-group">
<label class="form-check-label" for="active">
Active
<span>
<input class="form-check-input" name="activeCheckbox" type="checkbox" id="active" onclick="handleCheckboxClick()">
</span>
</label>
</div>
handleCheckboxClick.js
$('.form-check-input').change(function () {
var check = $(this).prop('checked');
if(check === true) {
$('#active').prop('checked', true);
} else {
$('#active').prop('checked', false);
}
});
jQuery that prefills the modal
$('#modal-edit-config').on('shown.bs.modal', function() {
$('#classname').focus();
var selectedId = confId;
$.ajax({
url: 'getConfig',
data: {configId: selectedId},
success: function(data){
var config = data;
if(config != null) {
$('#id').val(config.id);
$('#className').val(config.className);
console.log(config.active);
config.active ? $('#active').attr('checked', true).change() : $('#active').attr('checked', false).change();
}
},
error: function(result) {
alert("Error getting the audit configId");
}
});
});
I tried both with prop() and attr() but, it doesn't work.
The js function works perfectly fine but when the modal pops up the prefilled value of the checkbox even though it is correct, it is not corresponding to the tick or untick in the UI.
Checkboxes change their visual "checked" status based on the existence of the attribute name itself, not its setting -- according to dev.mozilla.org: checked, Boolean; if present, the checkbox is toggled on by default
<p>Checkbox checked="true"</p>
<input type="checkbox" checked="true">
<p>Checkbox checked="false"</p>
<input type="checkbox" checked="false">
<p>Checkbox (no checked attr)</p>
<input type="checkbox">
You should update your checkbox generation JS to leave out the attribute itself: $('#active').attr('checked', false) will show a checked checkbox.
For regular checkboxes
You should use the proper HTML semantics with .form-check wrapper as described in Forms > Checkboxes & Radios:
<div class="form-check">
<input class="form-check-input" type="checkbox" id="gridCheck">
<label class="form-check-label" for="gridCheck">
Check me out
</label>
</div>
As such, our <input>'s and <label>'s are sibling elements as opposed to an <input> within a <label>. This is slightly more verbose as you must specify id and for attributes to relate the <input> and <label>.
For custom checkboxes
To point you in the right direction you should read the section Custom forms > checkboxes.
Please note a label and input pairing wrapped in a div comes with a specific order.
The input goes first and is not wrapped by the label.
The reason is simple once you realize an input is an HTML element and they do not support "pseudo elements" :before and :after. These "pseudo class selectors" are required to introduce custom design on checkboxes/radios and so on.
Trivial and simplified CSS selector:
input[type="checkbox"]:checked ~ label:before { content: '✓' }
Otherwise there's no direct solution to reverse this selector like label input[type="checkbox"]:checked.
With that said, HTML is capable of handling your states by itself. No need for the handleCheckboxClick.js. You can then use .prop() to select by default in the ajax handler.
If you need to change the order visualy, you can introduce something like .custom-checkbox-reverse.
.custom-checkbox-reverse .custom-control-label::before,
.custom-checkbox-reverse .custom-control-label::after {
left: auto;
right: -1.5rem;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.css" rel="stylesheet"/>
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="customCheck1">
<label class="custom-control-label" for="customCheck1">Label after the checkbox</label>
</div>
<div class="custom-control custom-checkbox custom-checkbox-reverse">
<input type="checkbox" class="custom-control-input" id="customCheck2">
<label class="custom-control-label" for="customCheck2">Label before the checkbox</label>
</div>
FIDDLE to play around and enhance the padding for example as well.
A revision on the JavaScript part:
// what to expect here?
// should be sufficient to check if it has an id
// perhaps something else we can check? like config.status? Only you know at this point
// in fact it should always return the object or enter the error function
var checkboxState = false; // default
if(config && config.hasOwnProperty('id')) {
$('#id').val(config.id);
$('#className').val(config.className);
console.log(config.active); // expecting a boolean value
checkboxState = !!config.active; // double bang operator to make sure it's a boolean value
}
$('#active').prop('checked', checkboxState);
Trying to implement a checkbox where I can dynamically set the value (and have it appear in the box).
HTML
<mat-checkbox *ngIf="isReply()" class="col-2" formControlName="checkbox" [checked]="false" >CheckBox off</mat-checkbox>
<mat-checkbox *ngIf="!isReply()" class="col-2" formControlName="checkbox" >CheckBox</mat-checkbox>
materials.module.ts
addCheckbox() {
this.checkboxForm = this.fb.group({
'CheckBox':true,
main.module.ts
isReply(): boolean {
return: true;
}
There is a radio button that toggles isReply() off and on.
When I toggle isReply() on, I can see the CheckBox label change from "CheckBox" to "CheckBox off" but the checkbox status (visibly) does not change.
I can apply other logic which responds to the checkbox being off, even though the checkbox is still visibly checked (true). This changes the value of the checkbox to false, even though the checkbox is still visibly checked (true).
When I click on the checkbox (clear the visible box) the value toggles and the response is as expected, the value of checkbox is now true, even though the box is not checked.
I have made the following changes which STILL do not work
adjust this to:
<div class="row" *ngIf="isReply()">
<mat-checkbox class="col-2" formControlName="checkBox" >CheckBox</mat-checkbox>
</div>
<div class="row" *ngIf="!isReply()">
<mat-checkbox class="col-2" [checked]='true'
formControlName="checkBox" >CheckBox</mat-checkbox>
</div>
In the ts:
addCheckbox() {
this.checkboxForm = this.fb.group({
'checkBox':false,
I have two radio buttons (standard & reply).
The html for the radio buttons:
<form [formGroup]="materials.SignatureType">
<mat-radio-group formControlName="sigtype" >Signature Type:
<label><input type="radio" value="standard" formControlName="sigtype">
<span> Standard</span>
</label>
<label><input type="radio" value="reply" (click)="setBoxes()" formControlName="sigtype" >
<span> Reply</span>
</label>
</mat-radio-group>
The code for setBoxes():
if (this.isReply) {
this.materials.checkboxForm.value.checkBox = false;
}
else {
this.materials.checkboxForm.value.checkBox = true;
}
The click on "reply" radio button changes the value for the checkBox but does not change the state of the button.
I can not get the button state to change OTHER THAN to click on the checkbox.
Using Angular 7.2.3 [(ngModel)] is deprecated.
try:
In your component.html
<div class="container-fluid p-5 mt-2 mb-2" >
<mat-checkbox class="col-2" [checked]="var1" >CheckBox off</mat-checkbox>
<mat-checkbox class="col-2" [checked]="var2" >CheckBox</mat-checkbox>
</div>
In your component.ts file
var1 = false;
var2 = true
You just need binding checked property then you can change the value of var1 and var2 in your logic.
I was having this issue with my project.
I had my checkboxes wired up with the [checked]=... but I had missions getting it to work as expected. Which was to show non selected items as opacity: 40%; and have the box ticked next to the selected item.
eg. sometimes there would be a checked box and no selected items, or multiple checked boxes, or a selected item and no checked box... Very strange.
My conclusion; it's being set programatically and being over ridden by the click action.
TLDR;
My solution; change the click action configuration in the module providers by specifying:
MAT_CHECKBOX_CLICK_ACTION, useValue: 'noop'
this will leave any click actions in your hands for developer implementation.
Check the docs for more deets -> https://v6.material.angular.io/components/checkbox/overview
I have a list of Users to select for a team. Imagine that i select a User, he can either be active or inactive in his team. Now, if i don't select him at all, i should not be able to either activate or deactivate him.
This is made by a checkbox and a slider, like this:
When I click the checkbox, i need to disable the toggle. I have tried doing this by:
$("#2048").prop('disabled', true);
or
document.querySelector('[name="' + '#2048' + '"]').disabled = true;
Does not work either (And yes, i know that IDs should not be numbers, but it's because every toggle is inside a *ngFor. Still, i can use them as numbers, as jQuery can select them anyway)
Either way, i strongly believe that the only way to do something like this is to data-bind the 'disabled' attribute as some back-end variable that returns either a 'true' or 'false' value.
Something like:
<mat-slide-toggle
[id]='data.id'
class="status"
[disabled]='disableVariable'
>Active
</mat-slide-toggle>
and then:
disableVariable = someFunction(); //that returns true or false
This works, but the variable is 'too generic', i mean, every single slider will become disabled. Another problem is that this is not 'real-time', so i cant disable and enable multiple times.
Basically, it does not do the job.
What should i be doing here? If i had a way to select those tags using their unique ID's, that would fix the problem, but neither jQuery or Javascript's Query selector can disable or enable this tag.
EDIT:
A litle more of my code:
<div id="table" *ngFor="let data of User; let i = index">
<div [id]='data.id' *ngIf='data.user== 0' class="item">
<label class="container" style="width: 90%">
<input
type="checkbox"
*ngIf='data.status== 0'
id={{i}}
class="checkbox"
color=primary
checked>
<span class="checkmark"></span>
<div *ngIf='data.status== 0'>{{data.name}}
<mat-slide-toggle
[id]='data.id'
(change)=toggle(data.id)
*ngIf='data.status== 0'
color=primary
class="status"
>Active
</mat-slide-toggle>
</div>
</label>
</div>
</div>
When i add the ([ngModel)], my checkboxes stop working, and yes, i'm importing the FormsModule
You can use two-way binding to update the status of the checkbox as follows:
Add [(ngModel)] and disabled property to the input field
// Declare variable in component
CheckboxVar:boolean;
// In Html write below code
<input type="checkbox" [(ngModel)]="CheckboxVar" [disabled]="!CheckboxVar">
// Disabled checkbox when checkboxvar = false;
<input type="checkbox" [disabled]="!CheckboxVar">
Update CheckboxVar variable as per your need in your component.
Example with mat-slide-toggle
TS Code:
checked = false;
disabled = false;
HTML Code:
<input type="checkbox" [(ngModel)]="checked">
<mat-slide-toggle [disabled]="checked">
Slide me!
</mat-slide-toggle>
Now in the above example, if you checked the checkbox checked variable will be updated and if checked equals true then your toggle will be disabled.
If I understand the requirement correctly:
HTML Code:
<div *ngFor="let obj of list">
<mat-checkbox [(ngModel)]="obj.inTeam">In Team</mat-checkbox>
<br><br>
<mat-slide-toggle [(ngModel)]="obj.inTeam">Active</mat-slide-toggle>
</div>
TS Code:
list = [
{ id : 1,inTeam: false, isActive: false },
{ id : 3,inTeam: false, isActive: false },
{ id : 3,inTeam: false, isActive: false },
{ id : 4,inTeam: false, isActive: false }
]
StackBlitz
So every 'special-input' div contains an input field. I am trying regulate when each information can be entered into each input field.
Initially, I would like the first input field from the top to be enabled, while the rest of the input fields below it be disabled.
OnChange of input field 1, I would like for the next input field below it to be enabled, while the rest disabled. OnChange of input field 2, I would like for input field 3 to become enabled, while the rest remain disabled, etc...
I know I can use JQuery's attr() to enable input fields when needed, but I am unsure how to apply the logic to accomplish this as JQuery is quite new to me.
<div class="special-input"><input type="text" /></div>
<div class="special-input"><input type="text" /></div>
<div class="special-input"><input type="text" /></div>
<div class="special-input"><input type="text" /></div>
<div class="special-input"><input type="text" /></div>
<div class="special-input"><input type="text" /></div>
<div class="special-input"><input type="text" /></div>
<div class="special-input"><input type="text" /></div>
<div class="special-input"><input type="text" /></div>
......
......
......
<div class="special-input"><input type="text" /></div>
// Cache the inputs, this is a good way to improve performance of your
// jQuery code when re-using selectors.
var $inputs = $('.special-input :input');
// Disable all except the first input
$inputs.not(':first').attr('disabled', 'disabled');
$inputs.each(function(i) {
// For each input, bind a change event to enable the next input,
// if the user presses enter, the next textbox will receive focus. if the user
// presses tab, the following input won't receive focus, so you'll have to add
// code if you want this to work.
$(this).on('change', function() {
// Get the index of the current input element we're looking at,
// We need to re-wrap the $input[i] element as it is now a normal
// DOM element.
var $nextInput = $($inputs[i + 1]);
$nextInput.removeAttr('disabled').focus();
});
});
Edit: You can see a working example at http://jsfiddle.net/dFZEq/11/
Edit 2:
To enable the next line's set of elements after a certain condition is met, use this:
var $specialInputs = $('.special-input');
// don't disable the first line's input elements.
$specialInputs.not(':first').find(':input').attr('disabled', 'disabled');
$specialInputs.on('change', function() {
var $this = $(this);
if ($this.find(':input').filter(function() {
// you can change this filter to match any condition you
// like, for now we'll just make sure all inputs have a non-empty value
return $(this).val() == '';
}).length == 0) {
var $nextInputSet = $($specialInputs[$this.index() + 1]).find(':input');
// enable the next set of elements
$nextInputSet.removeAttr('disabled');
// focus your element here, requires more work
$nextInputSet.first().focus();
}
});
Example at http://jsfiddle.net/tFG5W/
I've not tested the following code, but should look something like this :
$(".special-input").bind("change",function(event){
$(this).attr("disabled","disabled");
$(this).next().removeAttr("disabled").focus();
});
I am trying to toggle the value of a checkbox using the following code:
<div class="control-group">
<label class="control-label checkbox" for="IsViewAsWebpage">
{{#if this.IsViewAsWebpage}}
<input type="hidden" id="IsViewAsWebpage" name="IsViewAsWebpage" value="true"/>
<input type="checkbox" class="enable-checkbox" checked />
{{else}}
<input type="hidden" id="IsViewAsWebpage" name="IsViewAsWebpage" value="false"/>
<input type="checkbox" class="enable-checkbox" />
{{/if}}
<span>View as Webpage</span>
</label>
</div>
'click .enable-checkbox': function (e) {
if (e.currentTarget.parentElement.htmlFor == "IsViewAsWebpage") {
this.$('#IsViewAsWebpage').is(':checked');
}
}
I know I am misssing something in the click function. I would basically want to toggle the checkbox value when the user clicks on it. Can someone point me to the right directions pls. Thank you.
When your checkbox gets clicked, it's going to toggle. That's the way checkboxes work.
If you want the hidden input to change value when the checkbox is toggled, I think what you want is this:
$(".enable-checkbox").change(function (e) {
if($(this).parent().attr("for") == "IsViewAsWebpage") {
var checked = $(this).is(":checked"); // Returns true/false.
$('#IsViewAsWebpage').attr("value", checked); // Sets true/false.
}
});
If you want to use handlebars.js to switch content when you click an check box, you will need to replace your content by calling handlebars each time you make a modification to your checkbox
$(".enable-checkbox").change(function (e) {
if($(this).parent().attr("for") == "IsViewAsWebpage") {
var checked = $(this).is(":checked");
IsViewAsWebpage = checked;
$("#yourcontainer").html(Handlebars.compile(yourtemplatesource));
}
}
then your IsViewAsWebpage variable should be global and your mustache condition should only be :
{{#if IsViewAsWebpage}}
But this is complicated for nothing... just use Aesthete solution, it will save you a lot of time.