More opinionated changes for PR #11

* Fixed validation pattern for IP addresses in jQuery Validation. It was
  missing escape characters for the periods so "192.168." was showing as
  a fully valid address.
* Changed the validation error display to be Bootstrap tooltips instead
  of additional elements that shift the contents of the page.
* Added custom tooltip style for validation errors.
* Updated jQuery Validation dependencies.
This commit is contained in:
Caesar Kabalan 2024-06-24 14:53:48 -07:00
parent b30c1719ef
commit c53af91e48
No known key found for this signature in database
GPG key ID: DDFEF5FF6CFAB608
6 changed files with 72 additions and 23 deletions

View file

@ -1,4 +1,4 @@
/*!
.custom-tooltip{--bs-tooltip-bg: var(--bs-danger) !important;--bs-tooltip-color: var(--bs-white) !important;--bs-tooltip-opacity: 1 !important}/*!
* Bootstrap v5.3.2 (https://getbootstrap.com/)
* Copyright 2011-2023 The Bootstrap Authors
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)

File diff suppressed because one or more lines are too long

5
dist/css/main.css vendored
View file

@ -255,8 +255,3 @@
white-space: nowrap;
padding-top: 0.25rem;
}
.active-mode {
color: #4091C9;
font-weight: bold;
}

38
dist/index.html vendored
View file

@ -39,7 +39,19 @@
<form id="input_form" class="row g-2 mb-3">
<div class="font-monospace col-lg-2 col-md-3 col-4">
<div><label for="network" class="form-label mb-0 ms-1">Network Address</label></div>
<div><input name="network" id="network" type="text" class="form-control" value="10.0.0.0" aria-label="Network Address" pattern="^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)" required></div>
<div><input data-bs-toggle="tooltip"
data-bs-placement="top"
data-bs-custom-class="custom-tooltip"
data-bs-title="Error"
data-bs-trigger="manual"
name="network"
id="network"
type="text"
class="form-control"
value="10.0.0.0"
aria-label="Network Address"
pattern="^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)"
required></div>
</div>
<div class="font-monospace col-auto">
<div style="height:2rem"></div>
@ -47,7 +59,19 @@
</div>
<div class="font-monospace col-lg-2 col-md-3 col-4">
<div><label for="netsize" class="form-label mb-0 ms-1">Network Size</label></div>
<div><input name="netsize" id="netsize" type="text" class="form-control w-10" value="16" aria-label="Network Size" pattern="^([0-9]|[12][0-9]|3[0-2])$" required></div>
<div><input data-bs-toggle="tooltip"
data-bs-placement="top"
data-bs-custom-class="custom-tooltip"
data-bs-title="Error"
data-bs-trigger="manual"
name="netsize"
id="netsize"
type="text"
class="form-control w-10"
value="16"
aria-label="Network Size"
pattern="^([0-9]|[12][0-9]|3[0-2])$"
required></div>
</div>
<div class="col-lg-2 col-md-3 col-3 font-">
<div style="height:1.5rem"></div>
@ -198,11 +222,11 @@
<script src="https://code.jquery.com/jquery-3.7.0.min.js"
integrity="sha256-2Pmvv0kuTBOenSvLm6bvfBSSHrUJ+3A7x6P5Ebd07/g="
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery-validation@1.19.5/dist/jquery.validate.min.js"
integrity="sha384-aEDtD4n2FLrMdE9psop0SHdNyy/W9cBjH22rSRp+3wPHd62Y32uijc0H2eLmgaSn"
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery-validation@1.19.5/dist/additional-methods.min.js"
integrity="sha384-kxI94MBt6egf2HqINJ9x8sPSfqxudviPxgttYjlTFaPREJb/gmAOgTr/GYie5ung"
<script src="https://cdn.jsdelivr.net/npm/jquery-validation@1.20.1/dist/jquery.validate.min.js"
integrity="sha256-0xVRcEF27BnewkTwGDpseENfeitZEOsQAVSlDc7PgG0="
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery-validation@1.20.1/dist/additional-methods.min.js"
integrity="sha384-Wxa7enUK34eRCZgjQIh81NeuzGHX2YaEkcLPCBIvASsdqlXBtAvVUiM7Tb56UvtC"
crossorigin="anonymous"></script>
<script src="js/lz-string.min.js"></script>
<script src="js/main.js"></script>

42
dist/js/main.js vendored
View file

@ -494,10 +494,10 @@ function switchMode(operatingMode) {
switch (operatingMode) {
case 'AWS':
var validate_error_message = "(AWS) Smallest size is /" + minSubnetSizes[operatingMode]
var validate_error_message = "AWS Mode - Smallest size is /" + minSubnetSizes[operatingMode]
break;
case 'AZURE':
var validate_error_message = "(Azure) Smallest size is /" + minSubnetSizes[operatingMode]
var validate_error_message = "Azure Mode - Smallest size is /" + minSubnetSizes[operatingMode]
break;
default:
var validate_error_message = "Smallest size is /" + minSubnetSizes[operatingMode]
@ -566,16 +566,16 @@ function validateSubnetSizes(subnetMap, minSubnetSize) {
function set_usable_ips_title(operatingMode) {
switch (operatingMode) {
case 'AWS':
$('#useableHeader').html('Usable IPs (<a href="https://docs.aws.amazon.com/vpc/latest/userguide/subnet-sizing.html#subnet-sizing-ipv4" target="_blank" style="color:#000; border-bottom: 1px dotted #000; text-decoration: dotted" data-toggle="tooltip" data-placement="top" data-bs-html="true" title="AWS reserves 5 addresses in each subnet for platform use.<br/>Click to navigate to the AWS documentation.">AWS</a>)')
$('#useableHeader').html('Usable IPs (<a href="https://docs.aws.amazon.com/vpc/latest/userguide/subnet-sizing.html#subnet-sizing-ipv4" target="_blank" style="color:#000; border-bottom: 1px dotted #000; text-decoration: dotted" data-bs-toggle="tooltip" data-bs-placement="top" data-bs-html="true" title="AWS reserves 5 addresses in each subnet for platform use.<br/>Click to navigate to the AWS documentation.">AWS</a>)')
break;
case 'AZURE':
$('#useableHeader').html('Usable IPs (<a href="https://learn.microsoft.com/en-us/azure/virtual-network/virtual-networks-faq#are-there-any-restrictions-on-using-ip-addresses-within-these-subnets" target="_blank" style="color:#000; border-bottom: 1px dotted #000; text-decoration: dotted" data-toggle="tooltip" data-placement="top" data-bs-html="true" title="Azure reserves 5 addresses in each subnet for platform use.<br/>Click to navigate to the Azure documentation.">Azure</a>)')
$('#useableHeader').html('Usable IPs (<a href="https://learn.microsoft.com/en-us/azure/virtual-network/virtual-networks-faq#are-there-any-restrictions-on-using-ip-addresses-within-these-subnets" target="_blank" style="color:#000; border-bottom: 1px dotted #000; text-decoration: dotted" data-bs-toggle="tooltip" data-bs-placement="top" data-bs-html="true" title="Azure reserves 5 addresses in each subnet for platform use.<br/>Click to navigate to the Azure documentation.">Azure</a>)')
break;
default:
$('#useableHeader').html('Usable IPs')
break;
}
$('[data-toggle="tooltip"]').tooltip()
$('[data-bs-toggle="tooltip"]').tooltip()
}
function show_warning_modal(message) {
@ -588,10 +588,13 @@ $( document ).ready(function() {
// Initialize the jQuery Validation on the form
var validator = $('#input_form').validate({
onfocusout: function (element) {
$(element).valid();
},
rules: {
network: {
required: true,
pattern: "^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)"
pattern: "^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)"
},
netsize: {
required: true,
@ -601,16 +604,37 @@ $( document ).ready(function() {
messages: {
network: {
required: "Please enter a network",
pattern: "Must be a valid IP Address"
pattern: "Must be a valid IPv4 Address"
},
netsize: {
required: "Please enter a network size",
pattern: "Smallest size is 32"
pattern: "Smallest size is /32"
}
},
errorPlacement: function(error, element) {
error.insertAfter(element);
console.log(error);
console.log(element);
if (error[0].innerHTML !== '') {
console.log('Error Placement - Text')
if (!element.data('errorIsVisible')) {
bootstrap.Tooltip.getInstance(element).setContent({'.tooltip-inner': error[0].innerHTML})
element.tooltip('show');
element.data('errorIsVisible', true)
}
} else {
console.log('Error Placement - Empty')
console.log(element);
if (element.data('errorIsVisible')) {
element.tooltip('hide');
element.data('errorIsVisible', false)
}
}
console.log(element);
},
// This success function appears to be required as errorPlacement() does not fire without the success function
// being defined.
success: function(label, element) { },
// When the form is valid, add the 'was-validated' class
submitHandler: function(form) {
form.classList.add('was-validated');

View file

@ -18,4 +18,10 @@ $new-container-max-widths: (
$container-max-widths: map-merge($container-max-widths, $new-container-max-widths);
.custom-tooltip {
--bs-tooltip-bg: var(--bs-danger) !important;
--bs-tooltip-color: var(--bs-white) !important;
--bs-tooltip-opacity: 1 !important;
}
@import "../node_modules/bootstrap/scss/bootstrap";