I have a page that has multiple inputs for pickadate and pickatime. How can I consilidate the jquery to where I have one call for pickadate and one call for pickatime?
Here is the markup.
<div class="container">
<div class="row">
<div class="col-xs-3">
<div class="form-group">
<label><span class="required">*</span> Display Start Date</label>
<input type="text" class="form-control select-date display-start-date" required>
<i id="trigger1" class="calendar-icon"></i>
</div>
</div>
<div class="col-xs-3">
<div class="form-group">
<label><span class="required">*</span> Display Start Time</label>
<input type="text" class="form-control select-time display-start-time" required>
<i id="trigger2" class="fa fa-clock-o fa-2x"></i>
</div>
</div>
<div class="col=xs-6"></div>
</div>
<div class="row">
<div class="col-xs-3">
<div class="form-group">
<label><span class="required">*</span> Display End Date</label>
<input type="text" class="form-control select-date display-end-date" required>
<i id="trigger3" class="calendar-icon"></i>
</div>
</div>
<div class="col-xs-3">
<div class="form-group">
<label><span class="required">*</span> Display End Time</label>
<input type="text" class="form-control select-time display-end-time" required>
<i id="trigger4" class="fa fa-clock-o fa-2x"></i>
</div>
</div>
<div class="col-xs-6"></div>
</div>
<div class="row">
<div class="col-xs-3">
<div class="form-group">
<label><span class="required">NEW!</span> Start Date</label>
<input type="text" class="form-control select-date new-start-date">
<i id="trigger5" class="calendar-icon"></i>
</div>
</div>
<div class="col-xs-3">
<div class="form-group">
<label><span class="required">NEW!</span> Start Time</label>
<input type="text" class="form-control select-time new-start-time" required>
<i id="trigger6" class="fa fa-clock-o fa-2x"></i>
</div>
</div>
<div class="col-xs-6"></div>
</div>
<div class="row">
<div class="col-xs-3">
<div class="form-group">
<label><span class="required">NEW!</span> End Date</label>
<input type="text" class="form-control select-date new-end-date">
<i id="trigger7" class="calendar-icon"></i>
</div>
</div>
<div class="col-xs-3">
<div class="form-group">
<label><span class="required">NEW!</span> End Time</label>
<input type="text" class="form-control select-time new-end-time" required>
<i id="trigger8" class="fa fa-clock-o fa-2x"></i>
</div>
</div>
<div class="col-xs-6"></div>
</div>
</div>
And here is the jquery.
// Initialize datepicker.
// Add Video - Display Start Date
var $input1 = $('.display-start-date').pickadate({
format: 'mm/dd/yyyy',
editable: true
});
var picker1 = $input1.data('pickadate');
$('#trigger1').click( function( e ) {
e.stopPropagation();
e.preventDefault();
picker1.open();
});
// Add Video - Display Start Time
var $input2 = $('.display-start-time').pickatime({
interval: 15,
editable: true
});
var picker2 = $input2.data('pickatime');
$('#trigger2').click( function( e ) {
e.stopPropagation();
e.preventDefault();
picker2.open();
});
// Add Video - Display End Date
var $input3 = $('.display-end-date').pickadate({
format: 'mm/dd/yyyy',
editable: true
});
var picker3 = $input3.data('pickadate');
$('#trigger3').click( function( e ) {
e.stopPropagation();
e.preventDefault();
picker3.open();
});
// Add Video - Display End Time
var $input4 = $('.display-end-time').pickatime({
interval: 15,
editable: true
});
var picker4 = $input4.data('pickatime');
$('#trigger4').click( function( e ) {
e.stopPropagation();
e.preventDefault();
picker4.open();
});
// Add Video - New! Start Date
var $input5 = $('.new-start-date').pickadate({
format: 'mm/dd/yyyy',
editable: true
});
var picker5 = $input5.data('pickadate');
$('#trigger5').click( function( e ) {
e.stopPropagation();
e.preventDefault();
picker5.open();
});
// Add Video - NEW! Start Time
var $input6 = $('.new-start-time').pickatime({
interval: 15,
editable: true
});
var picker6 = $input6.data('pickatime');
$('#trigger6').click( function( e ) {
e.stopPropagation();
e.preventDefault();
picker6.open();
});
// Add Video - New! End Date
var $input7 = $('.new-end-date').pickadate({
format: 'mm/dd/yyyy',
editable: true
});
var picker7 = $input7.data('pickadate');
$('#trigger7').click( function( e ) {
e.stopPropagation();
e.preventDefault();
picker7.open();
});
// Add Video - NEW! End Time
var $input8 = $('.new-end-time').pickatime({
interval: 15,
editable: true
});
var picker8 = $input8.data('pickatime');
$('#trigger8').click( function( e ) {
e.stopPropagation();
e.preventDefault();
picker8.open();
});
Thanks in advance!
Here's something that is a little cleaner. It deals with the date pickers and the time pickers separately.
$('.select-date').pickadate({
format: 'mm/dd/yyyy',
editable: true
});
$('.calendar-icon').each( function() {
// find the date picker element in this form-group
$picker = $(this).closest('.form-group').find('.select-date');
$picker.on('click', function(ev) {
ev.stopPropagation();
ev.preventDefault();
picker = $picker.data('pickadate')
picker.open();
});
$('.select-time').pickatime({
interval: 15,
editable: true
});
$('.fa-clock-o').each( function() {
// find the date picker element in this form-group
$picker = $(this).closest('.form-group').find('.select-time');
$picker.on('click', function(ev) {
ev.stopPropagation();
ev.preventDefault();
picker = $picker.data('pickatime')
picker.open();
});
And if you gave all your icon triggers a class (like date-trigger and time-trigger, then you could change:
$('.calendar-icon').each( function() {
to
$('.date-trigger').each( function() {
and the same for the timepickers. This makes the selector less dependent on the particular icon you are using.
And this should set things up for the whole page.
Related
I am trying to allow a user to add an option from a select class after pressing submit. As of now, it is adding the whole list. How do I go about allowing the user to select the specific option that they have chosen?
<div class="col alert alert-dark">
<h1 class="text-center">To Do App</h1>
</div>
<form class="form text-center col-8 ml-auto mr-auto alert alert-primary" id="newTaskForm">
<label for="toDo" class="toDo">What Color Do You Want To Add?</label>
<div class="row">
<select class="form-control col-8 mr-2" id="colorToAdd">
<option>Red</option>
<option>Yellow</option>
<option>Orange</option>
<option>Green</option>
<option>Blue</option>
</select>
<button type="submit" class="btn btn-success col-2" id="taskSubmit">Submit</button>
</div>
</form>
<hr class="col-8 ml-auto mr-auto mb-3">
<section class="text-center col-8 ml-auto mr-auto alert alert-dark" id="toDoList">
<h2>Tasks</h2>
<div id="colors">
</div>
window.addEventListener("load", () => {
const form = document.querySelector("#newTaskForm");
const input = document.querySelector("#colorToAdd");
const list_el = document.querySelector("#colors");
form.addEventListener("submit", (e) => {
e.preventDefault();
const colorElement = document.createElement("div");
colorElement.classList.add("newColor");
colorElement.type = "text";
colorElement.innerHTML = input.innerHTML;
list_el.appendChild(colorElement);
});
});
I currently have a disabled input box. I use the box to display the sum of two range sliders, where I update the value of the box via JavaScript.
I currently require that the value of the box equals 100 before allowing the form to be submitted. Is there a work-around where I can still disable the box, where it will still adopt the same Bootstrap style formatting (change color from red to green, etc) as a non-disabled box with the 'require' option?
Following a suggestion here, I've updated the code snippet below to almost be what I want. The only thing that I'd like to change, is to make 'rSum', the box that displays the sum, disabled (while still keeping all the validation formatting features). Ideally, I want this sum to adopt the validation feedback rather than the sliders, or other mutable input objects.
function checkSum() {
let currSum = parseInt(document.getElementById('rSum').value);
if (currSum != 100) {
document.getElementById('rSum').setCustomValidity('Must sum to 100%');
return false
} else {
document.getElementById('rSum').setCustomValidity('');
return true
}
}
function updateBoxes() {
const s1 = document.getElementById('range1');
const s2 = document.getElementById('range2');
let currSum = parseInt(s1.value) + parseInt(s2.value);
document.getElementById('rangeValue1').value = (s1.value)+"%";
document.getElementById('rangeValue2').value = (s2.value)+"%";
document.getElementById('rSum').value = (currSum)+"%";
}
// This last function is the original bootstrap validation example, modified to call 'checkSum()' instead
(function () {
'use strict'
// Fetch all the forms we want to apply custom Bootstrap validation styles to
var forms = document.querySelectorAll('.custom-validation')
// Loop over them and prevent submission
Array.prototype.slice.call(forms)
.forEach(function (form) {
form.addEventListener('submit', function (event) {
if (!checkSum()) {
event.preventDefault()
event.stopPropagation()
}
form.classList.add('was-validated')
}, false)
})
})()
<!-- CSS only -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous">
<!-- JavaScript Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.2.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-OERcA2EqjJCMA+/3y+gxIOqMEjwtxJY7qPCqsdltbNJuaOe923+mo//f6V8Qbsw3" crossorigin="anonymous"></script>
<form class="custom-validation" novalidate>
<div class="mb-3 row">
<div class="form-group col-md-1">
<input class="form-control" type="text" id="rangeValue1" disabled>
</div>
<div class="form-group col-md-4 col-form-label">
<input type="range" class="form-range" min="0" max="100" step="5" id="range1" value="0" onchange="updateBoxes()" >
</div>
</div>
<div class="mb-3 row">
<div class="form-group col-md-1">
<input class="form-control" type="text" id="rangeValue2" disabled>
</div>
<div class="form-group col-md-4 col-form-label">
<input type="range" class="form-range" min="0" max="100" step="5" id="range2" value="0" onchange="updateBoxes()" >
</div>
</div>
<div class="mb-3 row">
<div class="form-group">
<input type="text" class="form-control text-center" id="rSum" placeholder="100%" required>
<div class="valid-feedback">
Looks good!
</div>
<div class="invalid-feedback">
Probabilities must add up to 100%
</div>
</div>
</div>
<div class="mb-3 row">
<div class="col-sm-6 offset-md-1">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</div>
</form>
A couple of ways to do this. Here I use an example form with some inputs that can be used in the slider validation (one is a range slider but could be a simple number input also).
I set an event handler for those elements, associate them using data attributes and then; very verbosely and a bit ugly for clarity, use them in a function.
function checkSum(event) {
const fearRequird = this.fearNeed;
const myFear = event.target;
const associated = document.querySelector(myFear.dataset.related);
const result = this.sumEl;
const thisValue = parseInt(myFear.value);
const associatedValue = parseInt(associated.value);
let currSum = thisValue + associatedValue;
result.value = currSum;
let isValidSlider = currSum >= fearRequird;
result.classList.toggle("is-valid", isValidSlider);
result.classList.toggle("is-invalid", !isValidSlider);
let t = isValidSlider ? '' : `You Fear ${thisValue} and ${associatedValue} total ${currSum}. You need total ${fearRequird} fear`;
result.setCustomValidity(t);
result.closest('.form-group').querySelector('.invalid-feedback').textContent = t;
return isValidSlider;
}
(function() {
'use strict'
// Fetch all the forms we want to apply custom Bootstrap validation styles to
let forms = document.querySelectorAll('.needs-validation');
// Loop over them and prevent submission
Array.prototype.slice.call(forms)
.forEach(function(form) {
form.addEventListener('submit', function(event) {
if (!form.checkValidity()) {
event.preventDefault();
event.stopPropagation();
}
form.classList.add('was-validated');
}, false)
});
const fearNeed = 100;
const myFears = document.querySelectorAll('.fear-factor');
const needs = {
fearNeed: fearNeed,
sumEl: document.querySelector('#rSum')
};
myFears.forEach((fearElement) => {
fearElement.addEventListener('change', checkSum.bind(needs), false);
});
})();
<!-- CSS only -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous">
<!-- JavaScript Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.2.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-OERcA2EqjJCMA+/3y+gxIOqMEjwtxJY7qPCqsdltbNJuaOe923+mo//f6V8Qbsw3" crossorigin="anonymous"></script>
<form class="row g-3 needs-validation mx-1 my-2" novalidate>
<div class="form-group">
<input type="text" class="form-control text-center" id="rSum" placeholder="100%" required>
<div class="valid-feedback">
Looks good!
</div>
<div class="invalid-feedback">
Fears must add up to 100%
</div>
</div>
<div class="col-md-4">
<label for="validationCustomUsername" class="form-label">Fish Name</label>
<div class="input-group has-validation">
<span class="input-group-text" id="inputGroupPrepend">Fish</span>
<input type="text" class="form-control" id="validationCustomFishname" aria-describedby="inputGroupPrepend" required>
<div class="invalid-feedback">
Must catch a fish.
</div>
<div class="valid-feedback">
Looks like an good catch!
</div>
</div>
</div>
<div class="col-md-3">
<label for="validationCustomFearMet" class="form-label">Scary cats fear</label>
<div class="input-group has-validation">
<input type="number" class="form-control fear-factor" min="0" max="100" step="1" value="13" id="validationCustomFearMet" data-related="#customRange3" required />
<span class="input-group-text" id="inputGroupPrepend">%</span>
<div class="invalid-feedback">
Please provide scary cats fear as a percent 0-100.
</div>
<div class="invalid-feedback">
Please provide scary cats fear as a percent 0-100.
</div>
</div>
</div>
<div class="mx-1">
<label for="customRange3" class="form-label">Fear range</label>
<input type="range" class="form-range fear-factor" min="0" max="100" step="1" value="0" data-related="#validationCustomFearMet" id="customRange3">
</div>
<div class="col-12">
<button class="btn btn-primary" type="submit">Submit form</button>
</div>
</form>
friends, I want to turn the datepicker on and off in both input and icon clicks in this code structure, but I couldn't succeed, can you help?
<div class="container">
<div class="col-sm-6" style="height:130px;">
<div class="form-group">
<div class='input-group datetimepicker'>
<input type='text' class="form-control" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar">
</span>
</span>
</div>
</div>
</div>
<script type="text/javascript">
$(function () {
$('.datetimepicker').datetimepicker({
viewMode: 'years'
});
});
</script>
</div>
I want to fire my function Automatically when i complete my typing in ng-model.
I applied 2 different technique but nothing work
1. Approch
<div class="col-sm-6">
<input type="text" class="form-control" ng-model="testing" placeholder="Name" maxlength="50" /></div>
<span ng-if="testing.length != null " ng-show="Add()"></span>
Approach
<div class="col-sm-6">
<input type="text" class="form-control" ng-model="testing" placeholder="Name" maxlength="50" /></div>
<span ng-show="testing && Add()"></span>
Both fire my function with single character. I want to fire Add() function when my typing is completed. I do not want to use button.
Try following 2 sample codes.
I hope following sample code could help you solve the problem you were facing
var app = angular.module('app', []);
app.controller('myCtrl', function($scope) {
$scope.testing = "";
$scope.Add = function() {
console.log("Hope this Helps!!")
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.5/angular.min.js"></script>
<div ng-app="app" ng-controller="myCtrl">
<div class="col-sm-6">
<input type="text" class="form-control" ng-model="testing" placeholder="Name" maxlength="50" />
</div>
<span ng-if="testing.length >=1 " ng-show="Add()"></span>
<div>
or you could do like this
var app = angular.module('app', []);
app.controller('myCtrl', function($scope) {
$scope.testing = ""; //model scope variable initialization
$scope.testFun=function(a){ //function to check whether length of variable is greater than 0
if (a>=1) return true;
else return false;
}
$scope.Add = function() { //function to be exucuted when ng-if gets true value
console.log("Hope this Helps!!")
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.5/angular.min.js"></script>
<div ng-app="app" ng-controller="myCtrl">
<div class="col-sm-6">
<input type="text" class="form-control" ng-model="testing" placeholder="Name" maxlength="50" />
</div>
<span ng-if="testFun(testing.length)" ng-show="Add()"></span>
<div>
I click Buy radio button, images upload field will be removed, but when i click submit, the page refresh. It works normally when I don't affect DOM
Please, explain me what happened ?
Here is my code
onSubmitPost() {
this.progress = true;
const fileList: FileList = this.event.target.files;
if (fileList.length > 0) {
const fileListLength = fileList.length;
const formData: FormData = new FormData();
formData.append('title', this.title);
formData.append('telephone', this.telephone);
formData.append('description', this.description);
formData.append('city', this.city);
if (this.isSell === true) {
for (let x = 0; x < fileListLength; x++) {
formData.append('thumbnail', fileList[x]);
}
}
const headers = new Headers();
headers.append('Accept', 'application/json');
headers.append('Authorization', 'clientId 7702919f7e72965');
this.http
.post('http://localhost:3000/api/post', formData, {
headers: headers
})
.map(res => res.json())
.subscribe(
data => {
this.Notificationervice.success('Success');
this.progress = false;
},
error => this.Notificationervice.error('Something wrong')
);
}
}
}
HTML Code
<div id="new-post" class="modal" materialize="modal">
<div class="modal-content">
<div class="row">
<form class="col s12" (submit)="onSubmitPost()" enctype="multipart/form-data">
<div class="row">
<div class="input-field col s12">
<i class="material-icons prefix">web</i>
<input id="icon_prefix" type="text" class="validate" name="title" [(ngModel)]="title">
<label for="icon_prefix">Title</label>
</div>
</div>
<div class="row">
<div class="input-field col s12">
<i class="material-icons prefix">phone</i>
<input id="icon_telephone" type="tel" class="validate" name="telephone" [(ngModel)]="telephone">
<label for="icon_telephone">Telephone</label>
</div>
</div>
<div class="row">
<div class="input-field col s12">
<i class="material-icons prefix">mode_edit</i>
<textarea id="icon_prefix2" class="materialize-textarea" [(ngModel)]="description" name="description"></textarea>
<label for="icon_prefix2">Description</label>
</div>
</div>
<div class="row">
<div class="input-field col s12">
<i class="material-icons prefix">location_on</i>
<input type="text" id="autocomplete-input" class="autocomplete" materialize="autocomplete" [materializeParams]="[{'data': {'houston': null, 'Cali': null}}]"
[(ngModel)]="city" name="city">
<label for="autocomplete-input">City</label>
</div>
</div>
<div class="row">
<div class="col s6">
<p>
<input name="isSell" type="radio" id="buy" (change)="isSell = !isSell" [checked]="!isSell" />
<label for="buy">Buy</label>
</p>
</div>
<div class="col s6">
<p>
<input name="isSell" type="radio" id="sell" (change)="isSell = !isSell" [checked]="isSell" />
<label for="sell">Sell</label>
</p>
</div>
</div>
<div class="file-field input-field" *ngIf="isSell">
<div class="btn">
<span>Images</span>
<input type="file" multiple accept='image/*' name="post" (change)="onChange($event)">
</div>
<div class="file-path-wrapper">
<input class="file-path validate" type="text" placeholder="Upload one or more files">
</div>
</div>
<div class="modal-footer">
<input type="submit" class="modal-action modal-close waves-effect waves-green btn-flat" value="Submit">
</div>
</form>
</div>
</div>
</div>