New to jquery but I am working on a responsive calendar. Now I have a start date and an end date field. If the end date is populated, the reoccurrence check box shows as it removes it from the not-visible class.
How can I add a check on the start date also? I want the check box to show when both of the start and end fields are filled not just one.
$("#end_date").on("input", function (){
if($('#end_date').length >= 1) {
$("#reoccurrence").removeClass('not-visible');
} else {
$("#reoccurrence").addClass('not-visible');
}
});
.not-visible {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="col">
<div class="md-form md-form-container-fix">
<input type="text" id="start_date" class="form-control date-picker" name="start_date" required />
<label for="start_date">Start Date</label>
</div>
</div>
<div class="col">
<div class="md-form md-form-container-fix">
<input type="text" id="end_date" class="form-control date-picker" name="end_date" required />
<label for="end_date">End Date</label>
</div>
</div>
<div class="form-check not-visible" id="reoccurrence" name="reoccurrence">
<input class="form-check-input" type="checkbox" id="is_reoccurring" name="is_reoccurring" value="1" />
<label class="form-check-label" for="is_reoccurring"> Reoccurrence? </label>
</div>
In this context, using length will tell you whether that input exists in the DOM (0 = doesn't exist, 1 = exists), but it won't evaluate the values of the inputs.
length
The number of elements in the jQuery object.
The number of elements currently matched.
Instead, I recommend using val() to verify that the values of both inputs are not empty strings.
In the demonstration below, I define each input and the "reoccurrence" element as variables. I use add() to combine the two inputs and bind the event handler to both. Alternatively, you could simply select both inputs: $("#start_date,#end_date"); see multiple selector.
Upon input, I define a boolean "oneEmpty" variable based on the values of both inputs. Then, I use toggleClass() to "add or remove one or more classes ... depending on ... the value of the state argument."
When either input is empty, the "oneEmpty" state is true and the "not-visible" class is toggled on. When both inputs are filled, the state is false and the class is toggled off.
var $start_date = $('#start_date');
var $end_date = $('#end_date');
var $reoccurrence = $("#reoccurrence");
$start_date.add($end_date).on("input", function() {
let oneEmpty = $start_date.val() == '' || $end_date.val() == '';
$reoccurrence.toggleClass('not-visible', oneEmpty);
});
.not-visible {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="col">
<div class="md-form md-form-container-fix">
<input type="text" id="start_date" class="form-control date-picker" name="start_date" required />
<label for="start_date">Start Date</label>
</div>
</div>
<div class="col">
<div class="md-form md-form-container-fix">
<input type="text" id="end_date" class="form-control date-picker" name="end_date" required />
<label for="end_date">End Date</label>
</div>
</div>
<div class="form-check not-visible" id="reoccurrence" name="reoccurrence">
<input class="form-check-input" type="checkbox" id="is_reoccurring" name="is_reoccurring" value="1" />
<label class="form-check-label" for="is_reoccurring"> Reoccurrence? </label>
</div>
Related
I'm trying to disable a radio button if the other one is selected.
Next to the radio input is a text input in which if they choose the option, they would write the age depending on the selection of the radio (months or years).
Ideally, the text input would be disabled too. I have this code right now but it's not working:
<div class="md-form mb-3">
<i class="fas fa-paw prefix grey-text"></i><label data-error="wrong" data-success="right" style="padding-left: 5px">Age: </label>
<br />
<input type="radio" id="age_in_years" name="age_in_years" value="years">
<label for="age_in_years">Años:</label><input id="age_in_years"type="number" name="age_in_years" ng-model="age_in_years" class="form-control" style="margin-left: 5px;width: 70px;"/>
<input type="radio" id="age_in_months" name="age_in_months" value="months">
<label for="age_in_months">Months:</label><input id="age_in_months" type="number" name="age_in_months" value="age_in_months" ng-model="age_in_months" class="form-control" style="margin-left: 5px;width:70px;"/>
</div>
<script>
function selection() {
let x = document.getElementById("age_in_years");
let y = document.getElementById("age_in_months");
if (x.checked()) {
document.getElementById("age_in_months").disabled = true;
}
else if (y.checked()) {
document.getElementById("age_in_years").disabled = true;
}
}
</script>
I would refactor the HTML slightly and generate the radio buttons with the same name so that only 1 can ever be checked at a time. With that in place some simple javascript to determine the other inputs can be used to disable the number input.
label elements should not be used for arbitrary HTML - they are to be associated with input elements ( either using for=ID syntax or by wrapping the input element itself ) - hence some alterations to the markup.
document.addEventListener('change',e=>{
if( e.target.name=='age_unit' ){
let parent=e.target.parentNode;
let self=parent.querySelector(`input[type='number'][name='age[${e.target.value}]']`);
let other=parent.querySelector(`input[type='number']:not( [name='age[${e.target.value}]'] )`);
self.disabled=false;
other.disabled=true;
self.required=true;
other.required=false;
self.focus();
}
})
[type='number']{
width:70px;
}
<div class="md-form mb-3">
<i class="fas fa-paw prefix grey-text"></i>
<h2>Age:</h2>
<input type="radio" name="age_unit" value="years" />
<label>Años:
<input type="number" name="age[years]" ng-model="age_in_years" class="form-control" disabled />
</label>
<input type="radio" name="age_unit" value="months" />
<label>Months:
<input type="number" name="age[months]" ng-model="age_in_months" class="form-control" disabled />
</label>
</div>
A radio type is grouped by the name, so using the same name would already give the behavior you want, without needing any JavaScript.
<div class="md-form mb-3">
<i class="fas fa-paw prefix grey-text"></i>
<label data-error="wrong" data-success="right" style="padding-left: 5px">Age: </label>
<br>
<input type="radio" id="age_in_years" name="age" value="years">
<label for="age_in_years">Años:</label><input id="age_in_years"type="number" name="age_in_years" ng-model="age_in_years" class="form-control" style="margin-left: 5px;width: 70px;"/>
<input type="radio" id="age_in_months" name="age" value="months">
<label for="age_in_months">Months:</label>
<input id="age_in_months" type="number" name="age_in_months" value="age_in_months" ng-model="age_in_months" class="form-control" style="margin-left: 5px;width:70px;"/>
</div>
This would make sure that if one of radio elements is clicked or, once another one is clicked, the previous would be unchecked.
Because you have a value there, there's no reason to use different names, because the value already hints what kind of data has been submitted or is required.
I have this code
$(function() {
if(document.getElementById('price') !== null && document.getElementById('dp') !== null){
var price = document.getElementById('price').value;
var deposite = document.getElementById('dp').value;
document.getElementById('remained').value = parseInt(price)-parseInt(deposite);
}
});
and this fields in my form
<div class="col-md-3">
<label for="price">Price *</label>
<input type="number" class="form-control" id="price" name="price">
</div>
<div class="col-md-3">
<label for="dp">DP *</label>
<input type="number" class="form-control" id="dp" name="dp">
</div>
<div class="col-md-3">
<label for="remained">Remained *</label>
<input type="number" class="form-control" id="remained" name="remained">
</div>
The logic is simple:
get price
get DP
print minus results in remained input
but somehow it doesn't print anything in remained input.
Any idea what I did wrong?
Your code is executing on page load and the value of the inputs are empty.
You should execute your code on some event like the following way:
$(function() {
$('#dp, #price').on('input', function(){
if(document.getElementById('price') !== null && document.getElementById('dp') !== null){
var price = document.getElementById('price').value;
var deposite = document.getElementById('dp').value;
document.getElementById('remained').value = parseInt(price)-parseInt(deposite);
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="col-md-3">
<label for="price">Price *</label>
<input type="number" class="form-control" id="price" name="price">
</div>
<div class="col-md-3">
<label for="dp">DP *</label>
<input type="number" class="form-control" id="dp" name="dp">
</div>
<div class="col-md-3">
<label for="remained">Remained *</label>
<input type="number" class="form-control" id="remained" name="remained">
</div>
I think you should put the calculation to ready function
because it is asynchronous
$( document ).ready(function() {
console.log( "ready!" );
// calculation
});
Or better use angular ... Instead of jQuery
the calculation is right but it doen one time on page ready event
add manual button to tell javascrip when to calculate the value
alos add event listener to automatically call on change
<div class="col-md-3">
<label for="price">Price *</label>
<input type="number" class="form-control" id="price" name="price">
</div>
<div class="col-md-3">
<label for="dp">DP *</label>
<input type="number" class="form-control" id="dp" name="dp">
</div>
<div class="col-md-3">
<label for="remained">Remained *</label>
<input type="number" class="form-control" id="remained" name="remained">
</div>
<button type="button"
onclick="cal()">
cal
</button>
$(function() {
document.getElementById("price").addEventListener("change",cal);
document.getElementById("dp").addEventListener("change",cal);
});
function cal(){
if(document.getElementById('price') !== null && document.getElementById('dp') !== null){
var price = document.getElementById('price').value;
var deposite = document.getElementById('dp').value;
document.getElementById('remained').value = parseInt(price)-parseInt(deposite);
}
}
The js code runs on the initial loading of webpage. The js code must be called by an onclick or an onkeyup
I have 2 inputs where I enter value and concat it into new one
Here is code from HTML
<div class="form-group">
<label>{{l("FirstName")}}</label>
<input #firstNameInput="ngModel" class="form-control" type="text" name="name" (ngModelChange)="onNameChange()" [(ngModel)]="landlord.firstName" required maxlength="32">
<validation-messages [formCtrl]="firstNameInput"></validation-messages>
</div>
<div class="form-group">
<label>{{l("LastName")}}</label>
<input #lastNameInput="ngModel" class="form-control" type="text" name="name" (ngModelChange)="onNameChange()" [(ngModel)]="landlord.lastName" required maxlength="32">
<validation-messages [formCtrl]="lastNameInput"></validation-messages>
</div>
And concat value I show in this field
<div class="form-group">
<label>{{l("OrganizationName")}}</label>
<input #organizationName="ngModel" class="form-control" type="text" name="organizationName" [(ngModel)]="landlord.organizationName" required maxlength="500">
<validation-messages [formCtrl]="organizationName"></validation-messages>
</div>
Here is code from ts file
onNameChange() {
this.landlord.organizationName = `${
this.landlord.firstName ? this.landlord.firstName : ''
} ${this.landlord.lastName ? this.landlord.lastName : ''}`;
}
My problem, that last character is deleted from firstName or lastName
How I can fux this stuff?
Your ngModelChange event is firing before the model is actually updated, so with the current value at the time the event is fired, prior to the change. Likely to do with the ordering of (ngModelChange) and [(ngModel)] in your template.
Change your event to fire on (input) and it will get the most recent value.
<div class="form-group">
<label>{{l("FirstName")}}</label>
<input #firstNameInput="ngModel" class="form-control" type="text" name="name" (input)="onNameChange($event)" [(ngModel)]="landlord.firstName" required maxlength="32">
</div>
OR
Change the order of your attributes in your template:
<div class="form-group">
<label>{{l("FirstName")}}</label>
<input #firstNameInput="ngModel" class="form-control" type="text" name="name" [(ngModel)]="landlord.firstName" (ngModelChange)="onNameChange()" required maxlength="32">
</div>
Stackblitz: https://stackblitz.com/edit/angular-p7ecgh
Ok, I've been having a really weird problem using a checkbox which collapses a hidden div using bootstrap.
if I have data-toggle="collapse" in the checkbox input attribute section, the Div Collapses but requires that every single one of the inputs inside it be filled out.
If data-toggle="collapse" is not there, the hidden div doesn't collapse, and if the checkbox is checked it requires the inputs to be entered and if it's left unchecked I can submit the form without the inputs being entered. (desired action, but the div doesn't hide or show when the checkbox is checked)
How do I hide/show the div when the checkbox is unchecked/checked AND only require the inputs if the box is checked?
I'm using this as the HTML:
<div class="col-md-1">
<input type="checkbox" onclick="ChangeShip()" href="#moreabout" data-toggle="collapse" aria-expanded="false" aria-controls="moreabout" class="form-control" id="chShipAdd" name="chShipAdd" value="no">
</div>
<label for="chShipAdd" class="col-md-3 control-label">Shipping Information?</label>
<div id="shipadddiv" style="visibility: hidden;">
<div class="collapse" id="moreabout" >
<div class="form-group">
<div class="col-md-12">
<br>
<input id="sStreet" name="sStreet" type="text" placeholder="Street Name (required)" class="form-control shipClass" required>
</div>
</div>
<div class="form-group">
<div class="col-md-4">
<input id="sCity" name="sCity" type="text" placeholder="City (required)" required class="form-control shipClass">
</div>
<div class="col-md-4">
<input id="sState" name="sState" type="text" placeholder="State (required)" required class="form-control shipClass">
</div>
<div class="hidden-lg hidden-md"> </div>
<div class="col-md-4">
<input id="sZipcode" name="sZipcode" type="text" placeholder="Zip (required)" required class="form-control shipClass">
</div>
</div>
</div>
</div>
and the javascript:
function ChangeShip() {
if (!(document.getElementById('chShipAdd').checked)) {
document.getElementById('shipadddiv').style.visibility="hidden";
$(".shipClass").prop("disabled",true);
}
else {
document.getElementById('shipadddiv').style.visibility="visible";
$(".shipClass").prop("disabled",false);
}
}
Any solution that WORKS will be acceptable. I've bashed my brain all day trying to do this simple action. I've tried .prop .attribute .setAttribute .removeAttribute, and much much more.
Any Advice?
You can use jquery to solve this quickly. You can wrap your inputs for change ship and give it and id. And let jquery do the rest.
var form = $('#myForm'),
checkbox = $('#changeShip'),
chShipBlock = $('#changeShipInputs');
chShipBlock.hide();
checkbox.on('click', function() {
if($(this).is(':checked')) {
chShipBlock.show();
chShipBlock.find('input').attr('required', true);
} else {
chShipBlock.hide();
chShipBlock.find('input').attr('required', false);
}
});
See this jsfiddle for your problem. This should help you.
your click event will toggle the display and the disabled, but when the form is loaded you will have hidden content that is not disabled.
simply call the function on document.ready
function ChangeShip() {
var show = $('#chShipAdd').prop('checked');
$('#shipadddiv').toggle(show);
$("#shipadddiv .shipClass").prop("disabled", !show);
}
$(ChangeShip); // call on document.ready
or simply add the disabled attribute to those elements so that the initial form state is valid
If the [required] attribute is still triggered on a [disabled] element you could juggle the attribute value
function ChangeShip() {
var show = $('#chShipAdd').prop('checked');
$('#shipadddiv').toggle(show);
$("#shipadddiv .shipClass").each(function(){
if (!('_required' in this))
this._required = this.required;
this.disabled = !show;
this.required = (show) ? this._required : false;
});
}
Try to do this :
HTML :
<div class="col-md-1">
<input type="checkbox" onclick="ChangeShip()" href="#moreabout" data-toggle="collapse" aria-expanded="false" aria-controls="moreabout" class="form-control" id="chShipAdd" name="chShipAdd" value="no">
</div>
<label for="chShipAdd" class="col-md-3 control-label">Shipping Information?</label>
<div id="shipadddiv" style="visibility: hidden;">
<div class="collapse" id="moreabout" >
<div class="form-group">
<div class="col-md-12">
<br>
<input id="sStreet" name="sStreet" type="text" placeholder="Street Name (required)" class="form-control shipClass" required>
</div>
</div>
<div class="form-group">
<div class="col-md-4">
<input id="sCity" name="sCity" type="text" placeholder="City (required)" required class="form-control shipClass">
</div>
<div class="col-md-4">
<input id="sState" name="sState" type="text" placeholder="State (required)" required class="form-control shipClass">
</div>
<div class="hidden-lg hidden-md"> </div>
<div class="col-md-4">
<input id="sZipcode" name="sZipcode" type="text" placeholder="Zip (required)" required class="form-control shipClass">
</div>
</div>
</div>
</div>
JQUERY :
$('#chShipAdd').change(function() {
if ($('#chShipAdd').prop('checked')) {
$('#shipadddiv').show();
} else {
$('#shipadddiv').hide();
}
});
How in angular when a checkbox is uncheck, the form data will be reset.
<div class="form-group">
<input type="text" verify-store ng-model="user.merchant_store_name" class="form-control" name="merchant.store_name" placeholder="Store Name" ng-model-options="{ updateOn: 'blur' }" required>
<div ng-if="signupForm.$pending.usernameExists">verifying....</div>
<div ng-if="signupForm.$error.usernameExists[0].$viewValue">
<label class="control-label" style="color:red">A store with that name already exists. Please select another name.</label>
</div>
<div class="form-group">
<input type="text" class="form-control" ng-model="user.merchant_mobile_phone" placeholder="Phone" >
</div>
</div>
<div class="checkbox clip-check check-primary">
<input type="checkbox" id="agree" ng-model="signupForm.agree" value="agree" ng-required="!signupForm.agree">
<label for="agree">I agree</label>
</div>
<div class="checkbox clip-check check-primary" ng-show="signupForm.agree">
<input type="checkbox" id="merchant" ng-model="signupForm.merchant" value="merchant" >
<label for="merchant">Sign up as merchant</label>
</div>
Is there a way this can be done within the view template rather than passing it to controller. Or should I write a directive for this?
Thanks!!
You don't have to write a single line in your controller to achieve your task with the following two DOM settings.
<input type="text" ng-model="myText">
<input type='checkbox' ng-model='chkMonitor' ng-click='!chkMonitor && (myText = "")' >
Explanation:
Your inputs are bound to the scope through scope variables. Now you place your code in ng-click of the check box to execute the clearing code. This has to be done only when the check box is unchecked. So, first check for this in a boolean expression before executing your clearing code :
ng-click='!chkMonitor && (myText = "")'
Your myText = "" will never execute as long as the chkMonitor is false.