667 lines
35 KiB
HTML
667 lines
35 KiB
HTML
{% extends 'base.html' %}
|
|
{% load static %}
|
|
|
|
{% block title %}{% if metric %}Edit Metric Definition{% else %}Create Metric Definition{% endif %} - Hospital Management{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="content">
|
|
<div class="container-fluid">
|
|
<!-- Page Header -->
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<div class="page-header">
|
|
<div class="page-title">
|
|
<h4>{% if metric %}Edit Metric Definition{% else %}Create New Metric Definition{% endif %}</h4>
|
|
<h6>{% if metric %}Update metric configuration{% else %}Define a new analytics metric{% endif %}</h6>
|
|
</div>
|
|
<div class="page-btn">
|
|
<a href="{% url 'analytics:metric_definition_list' %}" class="btn btn-secondary">
|
|
<i class="fas fa-arrow-left me-1"></i>Back to Metrics
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<form method="post" id="metricForm">
|
|
{% csrf_token %}
|
|
<div class="row">
|
|
<!-- Main Form -->
|
|
<div class="col-lg-8">
|
|
<!-- Basic Information -->
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="card-title">
|
|
<i class="fas fa-info-circle me-2"></i>Basic Information
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="row">
|
|
<div class="col-md-8">
|
|
<div class="form-group">
|
|
<label for="name" class="form-label">Metric Name <span class="text-danger">*</span></label>
|
|
<input type="text" class="form-control" id="name" name="name"
|
|
value="{{ metric.name|default:'' }}"
|
|
placeholder="Enter metric name" required>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="form-group">
|
|
<label for="status" class="form-label">Status</label>
|
|
<select class="form-select" id="status" name="status">
|
|
<option value="draft" {% if metric.status == 'draft' or not metric %}selected{% endif %}>Draft</option>
|
|
<option value="active" {% if metric.status == 'active' %}selected{% endif %}>Active</option>
|
|
<option value="inactive" {% if metric.status == 'inactive' %}selected{% endif %}>Inactive</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="description" class="form-label">Description</label>
|
|
<textarea class="form-control" id="description" name="description" rows="3"
|
|
placeholder="Describe what this metric measures and its purpose">{{ metric.description|default:'' }}</textarea>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-4">
|
|
<div class="form-group">
|
|
<label for="category" class="form-label">Category <span class="text-danger">*</span></label>
|
|
<select class="form-select" id="category" name="category" required>
|
|
<option value="">Select category</option>
|
|
<option value="clinical" {% if metric.category == 'clinical' %}selected{% endif %}>Clinical</option>
|
|
<option value="financial" {% if metric.category == 'financial' %}selected{% endif %}>Financial</option>
|
|
<option value="operational" {% if metric.category == 'operational' %}selected{% endif %}>Operational</option>
|
|
<option value="quality" {% if metric.category == 'quality' %}selected{% endif %}>Quality</option>
|
|
<option value="patient_satisfaction" {% if metric.category == 'patient_satisfaction' %}selected{% endif %}>Patient Satisfaction</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="form-group">
|
|
<label for="metric_type" class="form-label">Metric Type <span class="text-danger">*</span></label>
|
|
<select class="form-select" id="metric_type" name="metric_type" required onchange="updateFormulaHelp()">
|
|
<option value="">Select type</option>
|
|
<option value="count" {% if metric.metric_type == 'count' %}selected{% endif %}>Count</option>
|
|
<option value="percentage" {% if metric.metric_type == 'percentage' %}selected{% endif %}>Percentage</option>
|
|
<option value="average" {% if metric.metric_type == 'average' %}selected{% endif %}>Average</option>
|
|
<option value="sum" {% if metric.metric_type == 'sum' %}selected{% endif %}>Sum</option>
|
|
<option value="ratio" {% if metric.metric_type == 'ratio' %}selected{% endif %}>Ratio</option>
|
|
<option value="custom" {% if metric.metric_type == 'custom' %}selected{% endif %}>Custom</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="form-group">
|
|
<label for="unit" class="form-label">Unit</label>
|
|
<input type="text" class="form-control" id="unit" name="unit"
|
|
value="{{ metric.unit|default:'' }}"
|
|
placeholder="e.g., %, $, days, patients">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<label for="data_source" class="form-label">Data Source</label>
|
|
<select class="form-select" id="data_source" name="data_source">
|
|
<option value="">Select data source</option>
|
|
{% for source in data_sources %}
|
|
<option value="{{ source.id }}" {% if metric.data_source_id == source.id %}selected{% endif %}>
|
|
{{ source.name }}
|
|
</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<label for="calculation_frequency" class="form-label">Calculation Frequency</label>
|
|
<select class="form-select" id="calculation_frequency" name="calculation_frequency">
|
|
<option value="manual" {% if metric.calculation_frequency == 'manual' %}selected{% endif %}>Manual</option>
|
|
<option value="hourly" {% if metric.calculation_frequency == 'hourly' %}selected{% endif %}>Hourly</option>
|
|
<option value="daily" {% if metric.calculation_frequency == 'daily' %}selected{% endif %}>Daily</option>
|
|
<option value="weekly" {% if metric.calculation_frequency == 'weekly' %}selected{% endif %}>Weekly</option>
|
|
<option value="monthly" {% if metric.calculation_frequency == 'monthly' %}selected{% endif %}>Monthly</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Formula Configuration -->
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="card-title">
|
|
<i class="fas fa-code me-2"></i>Formula Configuration
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="form-group">
|
|
<label for="formula" class="form-label">Calculation Formula</label>
|
|
<textarea class="form-control" id="formula" name="formula" rows="4"
|
|
placeholder="Enter the calculation formula">{{ metric.formula|default:'' }}</textarea>
|
|
<div class="form-text">
|
|
<div id="formulaHelp">
|
|
Use mathematical expressions and field references. Example: (field1 + field2) / field3 * 100
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="sql_query" class="form-label">SQL Query (Optional)</label>
|
|
<textarea class="form-control" id="sql_query" name="sql_query" rows="6"
|
|
placeholder="SELECT ... FROM ... WHERE ...">{{ metric.sql_query|default:'' }}</textarea>
|
|
<div class="form-text">
|
|
Advanced: Custom SQL query for complex calculations. Leave empty to use formula above.
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="validate_formula" name="validate_formula" checked>
|
|
<label class="form-check-label" for="validate_formula">
|
|
Validate formula syntax
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Parameters -->
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="card-title">
|
|
<i class="fas fa-sliders-h me-2"></i>Parameters
|
|
</h5>
|
|
<div class="card-tools">
|
|
<button type="button" class="btn btn-outline-primary btn-sm" onclick="addParameter()">
|
|
<i class="fas fa-plus me-1"></i>Add Parameter
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="card-body">
|
|
<div id="parametersContainer">
|
|
{% if metric.parameters %}
|
|
{% for param in metric.parameters %}
|
|
<div class="parameter-row">
|
|
<div class="row">
|
|
<div class="col-md-3">
|
|
<div class="form-group">
|
|
<label class="form-label">Parameter Name</label>
|
|
<input type="text" class="form-control" name="param_name[]"
|
|
value="{{ param.name }}" placeholder="parameter_name">
|
|
</div>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<div class="form-group">
|
|
<label class="form-label">Type</label>
|
|
<select class="form-select" name="param_type[]">
|
|
<option value="string" {% if param.type == 'string' %}selected{% endif %}>String</option>
|
|
<option value="number" {% if param.type == 'number' %}selected{% endif %}>Number</option>
|
|
<option value="date" {% if param.type == 'date' %}selected{% endif %}>Date</option>
|
|
<option value="boolean" {% if param.type == 'boolean' %}selected{% endif %}>Boolean</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<div class="form-group">
|
|
<label class="form-label">Default Value</label>
|
|
<input type="text" class="form-control" name="param_default[]"
|
|
value="{{ param.default_value }}" placeholder="default">
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="form-group">
|
|
<label class="form-label">Description</label>
|
|
<input type="text" class="form-control" name="param_description[]"
|
|
value="{{ param.description }}" placeholder="Parameter description">
|
|
</div>
|
|
</div>
|
|
<div class="col-md-1">
|
|
<div class="form-group">
|
|
<label class="form-label"> </label>
|
|
<button type="button" class="btn btn-outline-danger btn-sm d-block" onclick="removeParameter(this)">
|
|
<i class="fas fa-trash"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
{% endif %}
|
|
</div>
|
|
|
|
{% if not metric.parameters %}
|
|
<div class="text-center py-3" id="noParametersMessage">
|
|
<i class="fas fa-sliders-h fa-2x text-muted mb-2"></i>
|
|
<p class="text-muted mb-0">No parameters defined. Click "Add Parameter" to create configurable parameters for this metric.</p>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Display Configuration -->
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="card-title">
|
|
<i class="fas fa-palette me-2"></i>Display Configuration
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="row">
|
|
<div class="col-md-4">
|
|
<div class="form-group">
|
|
<label for="format" class="form-label">Number Format</label>
|
|
<select class="form-select" id="format" name="format">
|
|
<option value="default" {% if metric.format == 'default' %}selected{% endif %}>Default</option>
|
|
<option value="integer" {% if metric.format == 'integer' %}selected{% endif %}>Integer (1,234)</option>
|
|
<option value="decimal" {% if metric.format == 'decimal' %}selected{% endif %}>Decimal (1,234.56)</option>
|
|
<option value="percentage" {% if metric.format == 'percentage' %}selected{% endif %}>Percentage (12.34%)</option>
|
|
<option value="currency" {% if metric.format == 'currency' %}selected{% endif %}>Currency ($1,234.56)</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="form-group">
|
|
<label for="decimal_places" class="form-label">Decimal Places</label>
|
|
<input type="number" class="form-control" id="decimal_places" name="decimal_places"
|
|
value="{{ metric.decimal_places|default:'2' }}" min="0" max="10">
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="form-group">
|
|
<label for="color" class="form-label">Display Color</label>
|
|
<input type="color" class="form-control form-control-color" id="color" name="color"
|
|
value="{{ metric.color|default:'#007bff' }}">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<label for="target_value" class="form-label">Target Value (Optional)</label>
|
|
<input type="number" class="form-control" id="target_value" name="target_value"
|
|
value="{{ metric.target_value|default:'' }}" step="0.01"
|
|
placeholder="Target or goal value">
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<label for="threshold_type" class="form-label">Threshold Type</label>
|
|
<select class="form-select" id="threshold_type" name="threshold_type">
|
|
<option value="none" {% if metric.threshold_type == 'none' %}selected{% endif %}>None</option>
|
|
<option value="higher_better" {% if metric.threshold_type == 'higher_better' %}selected{% endif %}>Higher is Better</option>
|
|
<option value="lower_better" {% if metric.threshold_type == 'lower_better' %}selected{% endif %}>Lower is Better</option>
|
|
<option value="target_range" {% if metric.threshold_type == 'target_range' %}selected{% endif %}>Target Range</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Tags and Metadata -->
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="card-title">
|
|
<i class="fas fa-tags me-2"></i>Tags & Metadata
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="form-group">
|
|
<label for="tags" class="form-label">Tags</label>
|
|
<input type="text" class="form-control" id="tags" name="tags"
|
|
value="{{ metric.tags_string|default:'' }}"
|
|
placeholder="Enter tags separated by commas">
|
|
<div class="form-text">
|
|
Use tags to organize and categorize metrics. Separate multiple tags with commas.
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<label for="version" class="form-label">Version</label>
|
|
<input type="text" class="form-control" id="version" name="version"
|
|
value="{{ metric.version|default:'1.0' }}"
|
|
placeholder="1.0">
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<label for="owner" class="form-label">Owner</label>
|
|
<input type="text" class="form-control" id="owner" name="owner"
|
|
value="{{ metric.owner|default:'' }}"
|
|
placeholder="Metric owner or responsible person">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Sidebar -->
|
|
<div class="col-lg-4">
|
|
<!-- Formula Validation -->
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="card-title">
|
|
<i class="fas fa-check-circle me-2"></i>Formula Validation
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="text-center">
|
|
<button type="button" class="btn btn-outline-primary" onclick="validateFormula()">
|
|
<i class="fas fa-check me-1"></i>Validate Formula
|
|
</button>
|
|
<div id="validationResult" class="mt-3" style="display: none;">
|
|
<!-- Validation result will be shown here -->
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Test Calculation -->
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="card-title">
|
|
<i class="fas fa-calculator me-2"></i>Test Calculation
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="text-center">
|
|
<button type="button" class="btn btn-outline-success" onclick="testCalculation()">
|
|
<i class="fas fa-play me-1"></i>Test Calculate
|
|
</button>
|
|
<div id="testResult" class="mt-3" style="display: none;">
|
|
<!-- Test result will be shown here -->
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Form Actions -->
|
|
<div class="card">
|
|
<div class="card-body">
|
|
<div class="d-grid gap-2">
|
|
<button type="submit" class="btn btn-primary">
|
|
<i class="fas fa-save me-1"></i>
|
|
{% if metric %}Update Metric{% else %}Create Metric{% endif %}
|
|
</button>
|
|
{% if metric %}
|
|
<button type="button" class="btn btn-outline-secondary" onclick="calculateAfterSave()">
|
|
<i class="fas fa-calculator me-1"></i>Save & Calculate
|
|
</button>
|
|
{% endif %}
|
|
<a href="{% url 'analytics:metric_definition_list' %}" class="btn btn-outline-danger">
|
|
<i class="fas fa-times me-1"></i>Cancel
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Help -->
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="card-title">
|
|
<i class="fas fa-question-circle me-2"></i>Help
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="help-content">
|
|
<h6>Metric Types:</h6>
|
|
<ul class="list-unstyled">
|
|
<li><strong>Count:</strong> Simple counting metrics</li>
|
|
<li><strong>Percentage:</strong> Ratio expressed as percentage</li>
|
|
<li><strong>Average:</strong> Mean value calculation</li>
|
|
<li><strong>Sum:</strong> Total aggregation</li>
|
|
<li><strong>Ratio:</strong> Division of two values</li>
|
|
<li><strong>Custom:</strong> Complex custom formulas</li>
|
|
</ul>
|
|
|
|
<h6 class="mt-3">Formula Examples:</h6>
|
|
<ul class="list-unstyled small">
|
|
<li><code>COUNT(*)</code> - Count records</li>
|
|
<li><code>(A / B) * 100</code> - Percentage</li>
|
|
<li><code>SUM(field)</code> - Total sum</li>
|
|
<li><code>AVG(field)</code> - Average value</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
function updateFormulaHelp() {
|
|
const metricType = document.getElementById('metric_type').value;
|
|
const helpDiv = document.getElementById('formulaHelp');
|
|
|
|
const examples = {
|
|
'count': 'Example: COUNT(*) WHERE condition',
|
|
'percentage': 'Example: (numerator / denominator) * 100',
|
|
'average': 'Example: AVG(field_name)',
|
|
'sum': 'Example: SUM(field_name)',
|
|
'ratio': 'Example: field1 / field2',
|
|
'custom': 'Example: CASE WHEN condition THEN value1 ELSE value2 END'
|
|
};
|
|
|
|
helpDiv.textContent = examples[metricType] || 'Use mathematical expressions and field references.';
|
|
}
|
|
|
|
function addParameter() {
|
|
const container = document.getElementById('parametersContainer');
|
|
const noMessage = document.getElementById('noParametersMessage');
|
|
|
|
if (noMessage) {
|
|
noMessage.style.display = 'none';
|
|
}
|
|
|
|
const parameterRow = document.createElement('div');
|
|
parameterRow.className = 'parameter-row';
|
|
parameterRow.innerHTML = `
|
|
<div class="row">
|
|
<div class="col-md-3">
|
|
<div class="form-group">
|
|
<label class="form-label">Parameter Name</label>
|
|
<input type="text" class="form-control" name="param_name[]" placeholder="parameter_name">
|
|
</div>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<div class="form-group">
|
|
<label class="form-label">Type</label>
|
|
<select class="form-select" name="param_type[]">
|
|
<option value="string">String</option>
|
|
<option value="number">Number</option>
|
|
<option value="date">Date</option>
|
|
<option value="boolean">Boolean</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<div class="form-group">
|
|
<label class="form-label">Default Value</label>
|
|
<input type="text" class="form-control" name="param_default[]" placeholder="default">
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="form-group">
|
|
<label class="form-label">Description</label>
|
|
<input type="text" class="form-control" name="param_description[]" placeholder="Parameter description">
|
|
</div>
|
|
</div>
|
|
<div class="col-md-1">
|
|
<div class="form-group">
|
|
<label class="form-label"> </label>
|
|
<button type="button" class="btn btn-outline-danger btn-sm d-block" onclick="removeParameter(this)">
|
|
<i class="fas fa-trash"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`;
|
|
|
|
container.appendChild(parameterRow);
|
|
}
|
|
|
|
function removeParameter(button) {
|
|
const parameterRow = button.closest('.parameter-row');
|
|
parameterRow.remove();
|
|
|
|
const container = document.getElementById('parametersContainer');
|
|
const noMessage = document.getElementById('noParametersMessage');
|
|
|
|
if (container.children.length === 0 && noMessage) {
|
|
noMessage.style.display = 'block';
|
|
}
|
|
}
|
|
|
|
function validateFormula() {
|
|
const formula = document.getElementById('formula').value;
|
|
const resultDiv = document.getElementById('validationResult');
|
|
|
|
if (!formula.trim()) {
|
|
resultDiv.innerHTML = `
|
|
<div class="alert alert-warning">
|
|
<i class="fas fa-exclamation-triangle me-2"></i>
|
|
Please enter a formula to validate.
|
|
</div>
|
|
`;
|
|
resultDiv.style.display = 'block';
|
|
return;
|
|
}
|
|
|
|
// Simulate validation
|
|
setTimeout(() => {
|
|
resultDiv.innerHTML = `
|
|
<div class="alert alert-success">
|
|
<i class="fas fa-check-circle me-2"></i>
|
|
Formula syntax is valid!
|
|
</div>
|
|
`;
|
|
resultDiv.style.display = 'block';
|
|
}, 1000);
|
|
}
|
|
|
|
function testCalculation() {
|
|
const formula = document.getElementById('formula').value;
|
|
const resultDiv = document.getElementById('testResult');
|
|
|
|
if (!formula.trim()) {
|
|
resultDiv.innerHTML = `
|
|
<div class="alert alert-warning">
|
|
<i class="fas fa-exclamation-triangle me-2"></i>
|
|
Please enter a formula to test.
|
|
</div>
|
|
`;
|
|
resultDiv.style.display = 'block';
|
|
return;
|
|
}
|
|
|
|
// Simulate test calculation
|
|
setTimeout(() => {
|
|
resultDiv.innerHTML = `
|
|
<div class="alert alert-success">
|
|
<i class="fas fa-calculator me-2"></i>
|
|
Test result: <strong>42.5</strong>
|
|
<br><small class="text-muted">Calculation completed in 0.15s</small>
|
|
</div>
|
|
`;
|
|
resultDiv.style.display = 'block';
|
|
}, 1500);
|
|
}
|
|
|
|
function calculateAfterSave() {
|
|
document.getElementById('calculate_after_save').value = 'true';
|
|
}
|
|
|
|
// Form validation
|
|
document.getElementById('metricForm').addEventListener('submit', function(e) {
|
|
const name = document.getElementById('name').value.trim();
|
|
const category = document.getElementById('category').value;
|
|
const metricType = document.getElementById('metric_type').value;
|
|
|
|
if (!name || !category || !metricType) {
|
|
e.preventDefault();
|
|
alert('Please fill in all required fields');
|
|
return;
|
|
}
|
|
|
|
// Show loading state
|
|
const submitBtn = document.querySelector('button[type="submit"]');
|
|
const originalText = submitBtn.innerHTML;
|
|
submitBtn.innerHTML = '<i class="fas fa-spinner fa-spin me-1"></i>Saving...';
|
|
submitBtn.disabled = true;
|
|
|
|
// Re-enable after delay (in real app, handled by form submission)
|
|
setTimeout(() => {
|
|
submitBtn.innerHTML = originalText;
|
|
submitBtn.disabled = false;
|
|
}, 2000);
|
|
});
|
|
|
|
// Initialize
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
updateFormulaHelp();
|
|
});
|
|
</script>
|
|
|
|
<style>
|
|
.parameter-row {
|
|
margin-bottom: 20px;
|
|
padding: 15px;
|
|
border: 1px solid #e9ecef;
|
|
border-radius: 8px;
|
|
background: #f8f9fa;
|
|
}
|
|
|
|
.help-content h6 {
|
|
color: #2c3e50;
|
|
font-weight: 600;
|
|
margin-bottom: 10px;
|
|
}
|
|
|
|
.help-content ul li {
|
|
margin-bottom: 5px;
|
|
font-size: 0.875rem;
|
|
}
|
|
|
|
.help-content ul li strong {
|
|
color: #2c3e50;
|
|
}
|
|
|
|
.help-content code {
|
|
background: #e9ecef;
|
|
padding: 2px 4px;
|
|
border-radius: 3px;
|
|
font-size: 0.8rem;
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.page-btn {
|
|
margin-top: 15px;
|
|
}
|
|
|
|
.help-content {
|
|
font-size: 0.875rem;
|
|
}
|
|
|
|
.parameter-row .row {
|
|
flex-direction: column;
|
|
}
|
|
|
|
.parameter-row .col-md-1 {
|
|
margin-top: 10px;
|
|
}
|
|
}
|
|
</style>
|
|
{% endblock %}
|
|
|