Files
shopdb/deviceaccesspoint.asp
cproudlock 1b7946900c Remove category grouping from machine type dropdowns
Simplified machine type dropdowns to flat list without category
grouping. This removes dependency on the 'category' column in
machinetypes table which may not exist on all environments.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 16:24:07 -05:00

573 lines
25 KiB
Plaintext

<!DOCTYPE html>
<html lang="en">
<head>
<!--#include file="./includes/header.asp"-->
<!--#include file="./includes/sql.asp"-->
<!--#include file="./includes/validation.asp"-->
</head>
<%
theme = Request.Cookies("theme")
IF theme = "" THEN
theme="bg-theme1"
END IF
Dim accesspointid, isNewRecord
accesspointid = Request.QueryString("id")
If accesspointid = "" Or accesspointid = "0" Then
isNewRecord = True
accesspointid = 0
Else
isNewRecord = False
End If
' If editing, fetch existing data
Dim rs, accesspointname, modelid, serialnumber, ipaddress, fqdn, description, maptop, mapleft, isactive
Dim vendorname, modelnumber, logicmonitorurl
If Not isNewRecord Then
Dim strSQL
strSQL = "SELECT mac.machineid, mac.alias AS apname, mac.modelnumberid AS modelid, " & _
"mac.serialnumber, mac.fqdn, mac.logicmonitorurl, mac.machinenotes AS description, mac.maptop, mac.mapleft, mac.isactive, " & _
"m.modelnumber, v.vendor, c.address AS ipaddress " & _
"FROM machines mac " & _
"LEFT JOIN models m ON mac.modelnumberid = m.modelnumberid " & _
"LEFT JOIN vendors v ON m.vendorid = v.vendorid " & _
"LEFT JOIN communications c ON mac.machineid = c.machineid AND c.isprimary = 1 AND c.comstypeid = 1 " & _
"WHERE mac.machineid = " & accesspointid & " AND mac.machinetypeid = 16"
Set rs = objConn.Execute(strSQL)
If rs.EOF Then
Response.Write("Access Point not found")
Response.End
End If
If Not IsNull(rs("apname")) Then accesspointname = rs("apname") Else accesspointname = ""
If Not IsNull(rs("modelid")) Then modelid = rs("modelid") Else modelid = ""
If Not IsNull(rs("serialnumber")) Then serialnumber = rs("serialnumber") Else serialnumber = ""
If Not IsNull(rs("ipaddress")) Then
ipaddress = rs("ipaddress")
Else
ipaddress = ""
End If
If Not IsNull(rs("fqdn")) Then fqdn = rs("fqdn") & "" Else fqdn = ""
If Not IsNull(rs("logicmonitorurl")) Then logicmonitorurl = rs("logicmonitorurl") & "" Else logicmonitorurl = ""
description = rs("description") & ""
If Not IsNull(rs("maptop")) Then maptop = rs("maptop") Else maptop = ""
If Not IsNull(rs("mapleft")) Then mapleft = rs("mapleft") Else mapleft = ""
If Not IsNull(rs("isactive")) Then isactive = rs("isactive") Else isactive = 1
If Not IsNull(rs("vendor")) Then vendorname = rs("vendor") Else vendorname = ""
If Not IsNull(rs("modelnumber")) Then modelnumber = rs("modelnumber") Else modelnumber = ""
rs.Close
Set rs = Nothing
Else
' New record defaults
accesspointname = ""
modelid = ""
serialnumber = ""
ipaddress = ""
fqdn = ""
logicmonitorurl = ""
description = ""
maptop = ""
mapleft = ""
isactive = 1 ' Active by default for new records
vendorname = ""
modelnumber = ""
End If
%>
<body class="bg-theme <%Response.Write(theme)%>">
<!-- start loader -->
<div id="pageloader-overlay" class="visible incoming"><div class="loader-wrapper-outer"><div class="loader-wrapper-inner" ><div class="loader"></div></div></div></div>
<!-- end loader -->
<!-- Start wrapper-->
<div id="wrapper">
<!--#include file="./includes/leftsidebar.asp"-->
<!--Start topbar header-->
<!--#include file="./includes/topbarheader.asp"-->
<!--End topbar header-->
<div class="clearfix"></div>
<div class="content-wrapper">
<div class="container-fluid">
<!-- Breadcrumb -->
<div class="row mt-3">
<div class="col-lg-12">
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="networkdevices.asp">Network Devices</a></li>
<li class="breadcrumb-item"><a href="networkdevices.asp?filter=Access Point">Access Pointes</a></li>
<li class="breadcrumb-item active"><%If isNewRecord Then Response.Write("Add Access Point") Else Response.Write("Edit Access Point")%></li>
</ol>
</nav>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<div class="card">
<div class="card-body">
<h5 class="card-title">
<i class="zmdi zmdi-wifi"></i>
<%If isNewRecord Then Response.Write("Add Access Point") Else Response.Write("Edit Access Point: " & Server.HTMLEncode(accesspointname))%>
</h5>
<hr>
<form method="post" action="savenetworkdevice.asp">
<input type="hidden" name="type" value="accesspoint">
<input type="hidden" name="id" value="<%=accesspointid%>">
<div class="form-group row">
<label class="col-sm-3 col-form-label">Access Point Name <span class="text-danger">*</span></label>
<div class="col-sm-9">
<input type="text" name="apname" class="form-control"
value="<%=Server.HTMLEncode(accesspointname)%>"
required maxlength="100"
placeholder="e.g., DB-Access Point-01, App-Access Point-Primary">
<small class="form-text text-muted">
Short name to identify this accesspoint
</small>
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">Model</label>
<div class="col-sm-9">
<div class="input-group">
<select name="modelid" id="modelid" class="form-control">
<option value="">-- Select Model --</option>
<%
Dim strSQL2, rsModels, currentModelId
' Show Access Point models (machinetypeid = 16) plus currently assigned model
If IsNumeric(modelid) Then currentModelId = CLng(modelid) Else currentModelId = 0
strSQL2 = "SELECT m.modelnumberid, m.modelnumber, v.vendor " & _
"FROM models m " & _
"INNER JOIN vendors v ON m.vendorid = v.vendorid " & _
"WHERE m.isactive = 1 AND (m.machinetypeid = 16 OR m.modelnumberid = " & currentModelId & ") " & _
"ORDER BY v.vendor, m.modelnumber"
Set rsModels = objConn.Execute(strSQL2)
Do While Not rsModels.EOF
Dim selected
selected = ""
If Not IsNull(modelid) And modelid <> "" Then
If CStr(rsModels("modelnumberid")) = CStr(modelid) Then
selected = "selected"
End If
End If
%>
<option value="<%=rsModels("modelnumberid")%>" <%=selected%>>
<%=Server.HTMLEncode(rsModels("vendor") & " - " & rsModels("modelnumber"))%>
</option>
<%
rsModels.MoveNext
Loop
rsModels.Close
Set rsModels = Nothing
%>
<option value="new">+ Add New Model</option>
</select>
<div class="input-group-append">
<button type="button" class="btn btn-info" id="addModelBtn">
<i class="zmdi zmdi-plus"></i> New
</button>
</div>
</div>
<small class="form-text text-muted">
Select a model or click "New" to add one
</small>
</div>
</div>
<!-- Hidden section for adding new model -->
<div id="newModelSection" class="form-group row" style="display:none;">
<div class="col-sm-9 offset-sm-3">
<div style="padding:15px; background:rgba(255,255,255,0.03); border:1px solid rgba(255,255,255,0.1); border-radius:5px;">
<h6 class="mb-3"><i class="zmdi zmdi-plus-circle"></i> New Model</h6>
<div class="form-group">
<label for="newmodelnumber">Model Number <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="newmodelnumber" name="newmodelnumber"
maxlength="255" placeholder="e.g., UniFi AP-AC-Pro">
</div>
<div class="form-group">
<label for="newvendorid">Vendor <span class="text-danger">*</span></label>
<div class="input-group">
<select class="form-control" id="newvendorid" name="newvendorid">
<option value="">-- Select Vendor --</option>
<%
Dim rsVendors
strSQL2 = "SELECT vendorid, vendor FROM vendors WHERE isactive = 1 ORDER BY vendor ASC"
Set rsVendors = objConn.Execute(strSQL2)
While Not rsVendors.EOF
Response.Write("<option value='" & rsVendors("vendorid") & "'>" & Server.HTMLEncode(rsVendors("vendor")) & "</option>")
rsVendors.MoveNext
Wend
rsVendors.Close
Set rsVendors = Nothing
%>
<option value="new">+ Add New Vendor</option>
</select>
<div class="input-group-append">
<button type="button" class="btn btn-info" id="addVendorBtn">
<i class="zmdi zmdi-plus"></i> New
</button>
</div>
</div>
</div>
<!-- Hidden section for adding new vendor -->
<div id="newVendorSection" style="display:none; padding:15px; background:rgba(255,255,255,0.05); border:1px solid rgba(255,255,255,0.15); border-radius:5px; margin-bottom:15px;">
<h6 class="mb-3"><i class="zmdi zmdi-plus-circle"></i> New Vendor</h6>
<div class="form-group">
<label for="newvendorname">Vendor Name <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="newvendorname" name="newvendorname"
maxlength="50" placeholder="e.g., Ubiquiti, Cisco, Aruba">
</div>
<button type="button" class="btn btn-sm btn-secondary" id="cancelNewVendor">
<i class="zmdi zmdi-close"></i> Cancel
</button>
</div>
<div class="form-group">
<label for="newmodelmachinetypeid">Machine Type <span class="text-danger">*</span></label>
<div class="input-group">
<select class="form-control" id="newmodelmachinetypeid" name="newmodelmachinetypeid">
<option value="">-- Select Machine Type --</option>
<%
Dim rsMachineTypes
strSQL3 = "SELECT machinetypeid, machinetype FROM machinetypes WHERE isactive = 1 ORDER BY machinetype ASC"
Set rsMachineTypes = objConn.Execute(strSQL3)
While Not rsMachineTypes.EOF
Response.Write("<option value='" & rsMachineTypes("machinetypeid") & "'>" & Server.HTMLEncode(rsMachineTypes("machinetype")) & "</option>")
rsMachineTypes.MoveNext
Wend
rsMachineTypes.Close
Set rsMachineTypes = Nothing
%>
<option value="new">+ Add New Type</option>
</select>
<div class="input-group-append">
<button type="button" class="btn btn-info" id="addMachineTypeBtn">
<i class="zmdi zmdi-plus"></i> New
</button>
</div>
</div>
</div>
<!-- Hidden section for adding new machine type -->
<div id="newMachineTypeSection" style="display:none; padding:15px; background:rgba(255,255,255,0.05); border:1px solid rgba(255,255,255,0.15); border-radius:5px; margin-bottom:15px;">
<h6 class="mb-3"><i class="zmdi zmdi-plus-circle"></i> New Machine Type</h6>
<div class="form-group">
<label for="newmachinetypename">Type Name <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="newmachinetypename" name="newmachinetypename"
maxlength="50" placeholder="e.g., Firewall, Router, UPS">
</div>
<button type="button" class="btn btn-sm btn-secondary" id="cancelNewMachineType">
<i class="zmdi zmdi-close"></i> Cancel
</button>
</div>
<div class="form-group">
<label for="newmodelnotes">Model Notes</label>
<textarea class="form-control" id="newmodelnotes" name="newmodelnotes"
rows="2" maxlength="255"
placeholder="Additional notes about this model..."></textarea>
</div>
<div class="form-group">
<label for="newmodeldocpath">Documentation Path</label>
<input type="text" class="form-control" id="newmodeldocpath" name="newmodeldocpath"
maxlength="255" placeholder="\\server\docs\model.pdf or http://...">
</div>
<button type="button" class="btn btn-sm btn-secondary" id="cancelNewModel">
<i class="zmdi zmdi-close"></i> Cancel
</button>
</div>
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">Serial Number</label>
<div class="col-sm-9">
<input type="text" name="serialnumber" class="form-control"
value="<%=Server.HTMLEncode(serialnumber)%>"
maxlength="100" placeholder="e.g., SN123456789">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">IP Address</label>
<div class="col-sm-9">
<input type="text" name="ipaddress" class="form-control"
value="<%=Server.HTMLEncode(ipaddress)%>"
maxlength="45" pattern="^[0-9\.:]*$"
placeholder="e.g., 192.168.1.100 or 2001:db8::1">
<small class="form-text text-muted">
IPv4 or IPv6 address
</small>
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">FQDN</label>
<div class="col-sm-9">
<input type="text" name="fqdn" class="form-control"
value="<%=Server.HTMLEncode(fqdn)%>"
maxlength="255"
placeholder="e.g., ap-01.network.company.com">
<small class="form-text text-muted">
Fully Qualified Domain Name (optional)
</small>
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">Logic Monitor URL</label>
<div class="col-sm-9">
<input type="url" name="logicmonitorurl" class="form-control"
value="<%=Server.HTMLEncode(logicmonitorurl)%>"
maxlength="512"
placeholder="e.g., https://company.logicmonitor.com/santaba/uiv3/...">
<small class="form-text text-muted">
Link to this device in Logic Monitor (optional)
</small>
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">Description</label>
<div class="col-sm-9">
<textarea name="description" class="form-control" rows="3"
maxlength="255" placeholder="Detailed notes about this accesspoint..."><%=Server.HTMLEncode(description)%></textarea>
<small class="form-text text-muted">
Optional: Purpose, rack location, or other notes
</small>
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label"></label>
<div class="col-sm-9">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="isactive" name="isactive" value="1"
<%If isactive = True Or isactive = 1 Then Response.Write("checked")%>>
<label class="custom-control-label" for="isactive">Active</label>
</div>
<small class="form-text text-muted">
Inactive devices are hidden from most lists and the network map
</small>
</div>
</div>
<!-- Hidden coordinate fields - populated by map selector -->
<input type="hidden" id="maptop" name="maptop" value="<%=maptop%>">
<input type="hidden" id="mapleft" name="mapleft" value="<%=mapleft%>">
<div class="form-group row">
<label class="col-sm-3 col-form-label">Map Position (Optional)</label>
<div class="col-sm-9">
<button type="button" class="btn btn-secondary" id="selectLocationBtn">
<i class="zmdi zmdi-pin"></i> Select Location on Map
</button>
<div id="coordinateDisplay" style="margin-top:10px; color:#aaa; font-size:13px;">
<%If maptop <> "" And mapleft <> "" Then
Response.Write("Current position: X=" & mapleft & ", Y=" & maptop)
Else
Response.Write("No position set - click button to select")
End If%>
</div>
<small class="form-text text-muted">
Click to select this accesspoint's position on the network map
</small>
</div>
</div>
<hr>
<div class="form-group row">
<div class="col-sm-9 offset-sm-3">
<button type="submit" class="btn btn-success">
<i class="zmdi zmdi-save"></i>
<%If isNewRecord Then Response.Write("Add Access Point") Else Response.Write("Save Changes")%>
</button>
<a href="networkdevices.asp?filter=Access Point" class="btn btn-secondary">
<i class="zmdi zmdi-close"></i> Cancel
</a>
<%If Not isNewRecord Then%>
<button type="button" class="btn btn-danger float-right" onclick="confirmDelete()">
<i class="zmdi zmdi-delete"></i> Delete
</button>
<%End If%>
</div>
</div>
</form>
</div>
</div>
</div>
</div><!--End Row-->
</div><!-- End container-fluid-->
</div><!--End content-wrapper-->
<!--Start Back To Top Button-->
<a href="javaScript:void();" class="back-to-top"><i class="fa fa-angle-double-up"></i> </a>
<!--End Back To Top Button-->
<!--Start footer-->
<footer class="footer">
</footer>
<!--End footer-->
</div><!--End wrapper-->
<!-- Bootstrap core JavaScript-->
<script src="assets/js/jquery.min.js"></script>
<script src="assets/js/popper.min.js"></script>
<script src="assets/js/bootstrap.min.js"></script>
<!-- sidebar-menu js -->
<script src="assets/js/sidebar-menu.js"></script>
<!-- Custom scripts -->
<script src="assets/js/app-script.js"></script>
<script>
function confirmDelete() {
if (confirm('Are you sure you want to delete this accesspoint? This action cannot be undone.')) {
var form = document.createElement('form');
form.method = 'POST';
form.action = 'savenetworkdevice.asp';
var typeInput = document.createElement('input');
typeInput.type = 'hidden';
typeInput.name = 'type';
typeInput.value = 'accesspoint';
form.appendChild(typeInput);
var idInput = document.createElement('input');
idInput.type = 'hidden';
idInput.name = 'id';
idInput.value = '<%=accesspointid%>';
form.appendChild(idInput);
var deleteInput = document.createElement('input');
deleteInput.type = 'hidden';
deleteInput.name = 'delete';
deleteInput.value = '1';
form.appendChild(deleteInput);
document.body.appendChild(form);
form.submit();
}
}
// Model/Vendor nested add functionality
$(document).ready(function() {
// Show/hide new model section
$('#addModelBtn, #modelid').on('change click', function() {
if ($('#modelid').val() === 'new' || $(this).attr('id') === 'addModelBtn') {
$('#modelid').val('new');
$('#newModelSection').slideDown();
$('#newmodelnumber').prop('required', true);
$('#newvendorid').prop('required', true);
}
});
$('#cancelNewModel').on('click', function() {
$('#newModelSection').slideUp();
$('#newVendorSection').slideUp();
$('#modelid').val('');
$('#newmodelnumber').val('').prop('required', false);
$('#newvendorid').val('').prop('required', false);
$('#newmodelnotes').val('');
$('#newmodeldocpath').val('');
$('#newvendorname').val('').prop('required', false);
});
// Show/hide new vendor section
$('#addVendorBtn, #newvendorid').on('change click', function() {
if ($('#newvendorid').val() === 'new' || $(this).attr('id') === 'addVendorBtn') {
$('#newvendorid').val('new');
$('#newVendorSection').slideDown();
$('#newvendorname').prop('required', true);
}
});
$('#cancelNewVendor').on('click', function() {
$('#newVendorSection').slideUp();
$('#newvendorid').val('');
$('#newvendorname').val('').prop('required', false);
});
// Show/hide new machine type section
$('#addMachineTypeBtn, #newmodelmachinetypeid').on('change click', function() {
if ($('#newmodelmachinetypeid').val() === 'new' || $(this).attr('id') === 'addMachineTypeBtn') {
$('#newmodelmachinetypeid').val('new');
$('#newMachineTypeSection').slideDown();
$('#newmachinetypename').prop('required', true);
}
});
$('#cancelNewMachineType').on('click', function() {
$('#newMachineTypeSection').slideUp();
$('#newmodelmachinetypeid').val('');
$('#newmachinetypename').val('').prop('required', false);
});
// Form validation
$('form').on('submit', function(e) {
// If adding new model, make sure fields are filled
if ($('#modelid').val() === 'new') {
if ($('#newmodelnumber').val().trim() === '') {
e.preventDefault();
alert('Please enter a model number or select an existing model');
$('#newmodelnumber').focus();
return false;
}
if ($('#newvendorid').val() === '' || $('#newvendorid').val() === 'new') {
// If vendor is 'new', check vendor name
if ($('#newvendorid').val() === 'new') {
if ($('#newvendorname').val().trim() === '') {
e.preventDefault();
alert('Please enter a vendor name or select an existing vendor');
$('#newvendorname').focus();
return false;
}
} else {
e.preventDefault();
alert('Please select a vendor or add a new one');
$('#newvendorid').focus();
return false;
}
}
// If machine type is 'new', check machine type name
if ($('#newmodelmachinetypeid').val() === 'new') {
if ($('#newmachinetypename').val().trim() === '') {
e.preventDefault();
alert('Please enter a machine type name or select an existing type');
$('#newmachinetypename').focus();
return false;
}
}
}
});
});
</script>
<!--#include file="./includes/map_picker.asp"-->
</body>
</html>
<%
objConn.Close
%>