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/) * Bootstrap v5.3.2 (https://getbootstrap.com/)
* Copyright 2011-2023 The Bootstrap Authors * Copyright 2011-2023 The Bootstrap Authors
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * 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; white-space: nowrap;
padding-top: 0.25rem; padding-top: 0.25rem;
} }
.active-mode {
color: #4091C9;
font-weight: bold;
}

36
dist/index.html vendored
View file

@ -39,7 +39,19 @@
<form id="input_form" class="row g-2 mb-3"> <form id="input_form" class="row g-2 mb-3">
<div class="font-monospace col-lg-2 col-md-3 col-4"> <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><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>
<div class="font-monospace col-auto"> <div class="font-monospace col-auto">
<div style="height:2rem"></div> <div style="height:2rem"></div>
@ -47,7 +59,19 @@
</div> </div>
<div class="font-monospace col-lg-2 col-md-3 col-4"> <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><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>
<div class="col-lg-2 col-md-3 col-3 font-"> <div class="col-lg-2 col-md-3 col-3 font-">
<div style="height:1.5rem"></div> <div style="height:1.5rem"></div>
@ -198,11 +222,11 @@
<script src="https://code.jquery.com/jquery-3.7.0.min.js" <script src="https://code.jquery.com/jquery-3.7.0.min.js"
integrity="sha256-2Pmvv0kuTBOenSvLm6bvfBSSHrUJ+3A7x6P5Ebd07/g=" integrity="sha256-2Pmvv0kuTBOenSvLm6bvfBSSHrUJ+3A7x6P5Ebd07/g="
crossorigin="anonymous"></script> crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery-validation@1.19.5/dist/jquery.validate.min.js" <script src="https://cdn.jsdelivr.net/npm/jquery-validation@1.20.1/dist/jquery.validate.min.js"
integrity="sha384-aEDtD4n2FLrMdE9psop0SHdNyy/W9cBjH22rSRp+3wPHd62Y32uijc0H2eLmgaSn" integrity="sha256-0xVRcEF27BnewkTwGDpseENfeitZEOsQAVSlDc7PgG0="
crossorigin="anonymous"></script> crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery-validation@1.19.5/dist/additional-methods.min.js" <script src="https://cdn.jsdelivr.net/npm/jquery-validation@1.20.1/dist/additional-methods.min.js"
integrity="sha384-kxI94MBt6egf2HqINJ9x8sPSfqxudviPxgttYjlTFaPREJb/gmAOgTr/GYie5ung" integrity="sha384-Wxa7enUK34eRCZgjQIh81NeuzGHX2YaEkcLPCBIvASsdqlXBtAvVUiM7Tb56UvtC"
crossorigin="anonymous"></script> crossorigin="anonymous"></script>
<script src="js/lz-string.min.js"></script> <script src="js/lz-string.min.js"></script>
<script src="js/main.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) { switch (operatingMode) {
case 'AWS': case 'AWS':
var validate_error_message = "(AWS) Smallest size is /" + minSubnetSizes[operatingMode] var validate_error_message = "AWS Mode - Smallest size is /" + minSubnetSizes[operatingMode]
break; break;
case 'AZURE': case 'AZURE':
var validate_error_message = "(Azure) Smallest size is /" + minSubnetSizes[operatingMode] var validate_error_message = "Azure Mode - Smallest size is /" + minSubnetSizes[operatingMode]
break; break;
default: default:
var validate_error_message = "Smallest size is /" + minSubnetSizes[operatingMode] var validate_error_message = "Smallest size is /" + minSubnetSizes[operatingMode]
@ -566,16 +566,16 @@ function validateSubnetSizes(subnetMap, minSubnetSize) {
function set_usable_ips_title(operatingMode) { function set_usable_ips_title(operatingMode) {
switch (operatingMode) { switch (operatingMode) {
case 'AWS': 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; break;
case 'AZURE': 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; break;
default: default:
$('#useableHeader').html('Usable IPs') $('#useableHeader').html('Usable IPs')
break; break;
} }
$('[data-toggle="tooltip"]').tooltip() $('[data-bs-toggle="tooltip"]').tooltip()
} }
function show_warning_modal(message) { function show_warning_modal(message) {
@ -588,10 +588,13 @@ $( document ).ready(function() {
// Initialize the jQuery Validation on the form // Initialize the jQuery Validation on the form
var validator = $('#input_form').validate({ var validator = $('#input_form').validate({
onfocusout: function (element) {
$(element).valid();
},
rules: { rules: {
network: { network: {
required: true, 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: { netsize: {
required: true, required: true,
@ -601,16 +604,37 @@ $( document ).ready(function() {
messages: { messages: {
network: { network: {
required: "Please enter a network", required: "Please enter a network",
pattern: "Must be a valid IP Address" pattern: "Must be a valid IPv4 Address"
}, },
netsize: { netsize: {
required: "Please enter a network size", required: "Please enter a network size",
pattern: "Smallest size is 32" pattern: "Smallest size is /32"
} }
}, },
errorPlacement: function(error, element) { 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 // When the form is valid, add the 'was-validated' class
submitHandler: function(form) { submitHandler: function(form) {
form.classList.add('was-validated'); 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); $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"; @import "../node_modules/bootstrap/scss/bootstrap";