wad-lab 1.0.4 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/templates/html-css-js/index.html +224 -27
- package/templates/html-css-js/script.js +358 -25
- package/templates/html-css-js/style.css +452 -11
package/package.json
CHANGED
|
@@ -1,42 +1,239 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
|
-
<html>
|
|
2
|
+
<html lang="en">
|
|
3
3
|
<head>
|
|
4
|
-
<
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>WAD Unit 1 & 2 Complete Reference</title>
|
|
5
7
|
<link rel="stylesheet" href="style.css">
|
|
8
|
+
<script src="script.js" defer></script>
|
|
6
9
|
</head>
|
|
7
10
|
<body>
|
|
8
|
-
<
|
|
11
|
+
<header class="app-header">
|
|
12
|
+
<h1>Student Registration & DOM Reference</h1>
|
|
13
|
+
<nav class="nav-bar">
|
|
14
|
+
<a href="#form-section">Registration Form</a>
|
|
15
|
+
<a href="#table-section">Records Table</a>
|
|
16
|
+
<a href="#dom-section">DOM Utilities</a>
|
|
17
|
+
<a href="#object-section">Object Operations</a>
|
|
18
|
+
</nav>
|
|
19
|
+
</header>
|
|
9
20
|
|
|
10
|
-
<
|
|
11
|
-
<label>Name:</label><br>
|
|
12
|
-
<input type="text" id="name" required><br><br>
|
|
21
|
+
<div class="fixed-badge animated-badge">Lab Ready</div>
|
|
13
22
|
|
|
14
|
-
|
|
15
|
-
<
|
|
23
|
+
<main class="container">
|
|
24
|
+
<section id="form-section" class="card">
|
|
25
|
+
<h2>Student Registration Form</h2>
|
|
26
|
+
<form id="registrationForm" onsubmit="handleFormSubmit(event)">
|
|
27
|
+
<fieldset>
|
|
28
|
+
<legend>Personal & Academic Details</legend>
|
|
16
29
|
|
|
17
|
-
|
|
18
|
-
|
|
30
|
+
<div class="form-grid">
|
|
31
|
+
<div class="form-group">
|
|
32
|
+
<label for="rollNo">Roll Number:</label>
|
|
33
|
+
<input type="text" id="rollNo" name="rollNo" placeholder="e.g. 21CS001" required autofocus>
|
|
34
|
+
</div>
|
|
19
35
|
|
|
20
|
-
|
|
21
|
-
|
|
36
|
+
<div class="form-group">
|
|
37
|
+
<label for="fullName">Full Name:</label>
|
|
38
|
+
<input type="text" id="fullName" name="fullName" placeholder="Enter full name" required>
|
|
39
|
+
</div>
|
|
22
40
|
|
|
23
|
-
|
|
41
|
+
<div class="form-group">
|
|
42
|
+
<label for="password">Password:</label>
|
|
43
|
+
<input type="password" id="password" name="password" placeholder="Min 6 characters" minlength="6" required>
|
|
44
|
+
</div>
|
|
24
45
|
|
|
25
|
-
|
|
46
|
+
<div class="form-group">
|
|
47
|
+
<label for="email">Email Address:</label>
|
|
48
|
+
<input type="email" id="email" name="email" placeholder="student@example.com" required>
|
|
49
|
+
</div>
|
|
26
50
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
<th>Name</th>
|
|
32
|
-
<th>Description</th>
|
|
33
|
-
<th>Price</th>
|
|
34
|
-
<th>Action</th>
|
|
35
|
-
</tr>
|
|
36
|
-
</thead>
|
|
37
|
-
<tbody id="tableBody"></tbody>
|
|
38
|
-
</table>
|
|
51
|
+
<div class="form-group">
|
|
52
|
+
<label for="phone">Phone Number:</label>
|
|
53
|
+
<input type="tel" id="phone" name="phone" placeholder="10-digit number" pattern="[0-9]{10}" required>
|
|
54
|
+
</div>
|
|
39
55
|
|
|
40
|
-
|
|
56
|
+
<div class="form-group">
|
|
57
|
+
<label for="age">Age:</label>
|
|
58
|
+
<input type="number" id="age" name="age" min="1" max="100" value="20" required>
|
|
59
|
+
</div>
|
|
60
|
+
|
|
61
|
+
<div class="form-group">
|
|
62
|
+
<label for="dob">Date of Birth:</label>
|
|
63
|
+
<input type="date" id="dob" name="dob" required>
|
|
64
|
+
</div>
|
|
65
|
+
|
|
66
|
+
<div class="form-group">
|
|
67
|
+
<label for="regTime">Registration Time:</label>
|
|
68
|
+
<input type="time" id="regTime" name="regTime">
|
|
69
|
+
</div>
|
|
70
|
+
|
|
71
|
+
<div class="form-group">
|
|
72
|
+
<label for="gradMonth">Graduation Month:</label>
|
|
73
|
+
<input type="month" id="gradMonth" name="gradMonth">
|
|
74
|
+
</div>
|
|
75
|
+
|
|
76
|
+
<div class="form-group">
|
|
77
|
+
<label for="themeColor">Favorite Color:</label>
|
|
78
|
+
<input type="color" id="themeColor" name="themeColor" value="#3498db">
|
|
79
|
+
</div>
|
|
80
|
+
|
|
81
|
+
<div class="form-group full-width">
|
|
82
|
+
<label for="skillRating">Proficiency Rating: <span id="ratingDisplay">75</span>%</label>
|
|
83
|
+
<input type="range" id="skillRating" name="skillRating" min="0" max="100" value="75" oninput="updateRangeDisplay(this.value)">
|
|
84
|
+
</div>
|
|
85
|
+
|
|
86
|
+
<div class="form-group">
|
|
87
|
+
<label>Gender:</label>
|
|
88
|
+
<div class="radio-group">
|
|
89
|
+
<label><input type="radio" name="gender" value="Male" checked> Male</label>
|
|
90
|
+
<label><input type="radio" name="gender" value="Female"> Female</label>
|
|
91
|
+
<label><input type="radio" name="gender" value="Other"> Other</label>
|
|
92
|
+
</div>
|
|
93
|
+
</div>
|
|
94
|
+
|
|
95
|
+
<div class="form-group">
|
|
96
|
+
<label>Technical Skills:</label>
|
|
97
|
+
<div class="checkbox-group">
|
|
98
|
+
<label><input type="checkbox" name="skills" value="HTML" checked> HTML</label>
|
|
99
|
+
<label><input type="checkbox" name="skills" value="CSS" checked> CSS</label>
|
|
100
|
+
<label><input type="checkbox" name="skills" value="JavaScript" checked> JavaScript</label>
|
|
101
|
+
<label><input type="checkbox" name="skills" value="Java"> Java</label>
|
|
102
|
+
</div>
|
|
103
|
+
</div>
|
|
104
|
+
|
|
105
|
+
<div class="form-group">
|
|
106
|
+
<label for="department">Department:</label>
|
|
107
|
+
<select id="department" name="department" required>
|
|
108
|
+
<option value="">Select Department</option>
|
|
109
|
+
<option value="CSE" selected>Computer Science & Engineering</option>
|
|
110
|
+
<option value="IT">Information Technology</option>
|
|
111
|
+
<option value="ECE">Electronics & Communication</option>
|
|
112
|
+
<option value="MECH">Mechanical Engineering</option>
|
|
113
|
+
</select>
|
|
114
|
+
</div>
|
|
115
|
+
|
|
116
|
+
<div class="form-group">
|
|
117
|
+
<label for="courseTrack">Specialization (Datalist):</label>
|
|
118
|
+
<input list="courses" id="courseTrack" name="courseTrack" placeholder="Choose or type track">
|
|
119
|
+
<datalist id="courses">
|
|
120
|
+
<option value="Web Technologies">
|
|
121
|
+
<option value="Cloud Computing">
|
|
122
|
+
<option value="Artificial Intelligence">
|
|
123
|
+
<option value="Data Analytics">
|
|
124
|
+
</datalist>
|
|
125
|
+
</div>
|
|
126
|
+
|
|
127
|
+
<div class="form-group full-width">
|
|
128
|
+
<label for="address">Address:</label>
|
|
129
|
+
<textarea id="address" name="address" rows="3" placeholder="Street, City, State, Pincode"></textarea>
|
|
130
|
+
</div>
|
|
131
|
+
|
|
132
|
+
<div class="form-group full-width">
|
|
133
|
+
<label for="resume">Upload Document / Resume:</label>
|
|
134
|
+
<input type="file" id="resume" name="resume">
|
|
135
|
+
</div>
|
|
136
|
+
</div>
|
|
137
|
+
|
|
138
|
+
<div class="button-group">
|
|
139
|
+
<button type="submit" class="btn btn-primary" id="submitBtn">Submit Registration</button>
|
|
140
|
+
<button type="reset" class="btn btn-secondary" id="resetBtn">Reset Form</button>
|
|
141
|
+
</div>
|
|
142
|
+
</fieldset>
|
|
143
|
+
</form>
|
|
144
|
+
|
|
145
|
+
<div id="formAlert" class="alert-box"></div>
|
|
146
|
+
</section>
|
|
147
|
+
|
|
148
|
+
<section id="table-section" class="card">
|
|
149
|
+
<h2>Registered Students Table</h2>
|
|
150
|
+
<div class="table-container">
|
|
151
|
+
<table id="recordsTable">
|
|
152
|
+
<caption>Student Enrollment Records</caption>
|
|
153
|
+
<thead>
|
|
154
|
+
<tr>
|
|
155
|
+
<th>Roll No</th>
|
|
156
|
+
<th>Name</th>
|
|
157
|
+
<th>Email</th>
|
|
158
|
+
<th>Department</th>
|
|
159
|
+
<th>Gender</th>
|
|
160
|
+
<th>Skills</th>
|
|
161
|
+
<th>Rating</th>
|
|
162
|
+
<th>Actions</th>
|
|
163
|
+
</tr>
|
|
164
|
+
</thead>
|
|
165
|
+
<tbody id="recordsBody"></tbody>
|
|
166
|
+
<tfoot>
|
|
167
|
+
<tr>
|
|
168
|
+
<td colspan="7">Total Registered Records</td>
|
|
169
|
+
<td id="totalRecordCount">0</td>
|
|
170
|
+
</tr>
|
|
171
|
+
</tfoot>
|
|
172
|
+
</table>
|
|
173
|
+
</div>
|
|
174
|
+
</section>
|
|
175
|
+
|
|
176
|
+
<section id="dom-section" class="card">
|
|
177
|
+
<h2>Interactive DOM Manipulation Lab</h2>
|
|
178
|
+
|
|
179
|
+
<div class="dom-grid">
|
|
180
|
+
<div class="dom-box">
|
|
181
|
+
<h3>Mouseover & Mouseout Event</h3>
|
|
182
|
+
<img id="bulbImg" src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100' viewBox='0 0 24 24' fill='%237f8c8d'><path d='M12 2C8.13 2 5 5.13 5 9c0 2.38 1.19 4.47 3 5.74V17c0 .55.45 1 1 1h6c.55 0 1-.45 1-1v-2.26c1.81-1.27 3-3.36 3-5.74 0-3.87-3.13-7-7-7zm-3 18h6v1c0 .55-.45 1-1 1h-4c-.55 0-1-.45-1-1v-1z'/></svg>" alt="Light Bulb" onmouseover="turnBulbOn()" onmouseout="turnBulbOff()">
|
|
183
|
+
<p id="bulbStatus">Hover over the bulb to turn it ON</p>
|
|
184
|
+
</div>
|
|
185
|
+
|
|
186
|
+
<div class="dom-box">
|
|
187
|
+
<h3>Countdown Timer (Interval)</h3>
|
|
188
|
+
<div id="timerDisplay" class="counter-display">10</div>
|
|
189
|
+
<div class="btn-cluster">
|
|
190
|
+
<button type="button" class="btn btn-sm" onclick="startTimer()">Start</button>
|
|
191
|
+
<button type="button" class="btn btn-sm" onclick="resetTimer()">Reset</button>
|
|
192
|
+
</div>
|
|
193
|
+
</div>
|
|
194
|
+
|
|
195
|
+
<div class="dom-box">
|
|
196
|
+
<h3>Dynamic List & Swapping</h3>
|
|
197
|
+
<button type="button" class="btn btn-sm" onclick="addListItem()">Add Node</button>
|
|
198
|
+
<ol id="orderList">
|
|
199
|
+
<li onclick="swapWithNext(this)">Item Alpha (Click to Swap)</li>
|
|
200
|
+
<li onclick="swapWithNext(this)">Item Beta (Click to Swap)</li>
|
|
201
|
+
<li onclick="swapWithNext(this)">Item Gamma (Click to Swap)</li>
|
|
202
|
+
</ol>
|
|
203
|
+
</div>
|
|
204
|
+
|
|
205
|
+
<div class="dom-box">
|
|
206
|
+
<h3>Collapse & Expand Element</h3>
|
|
207
|
+
<button type="button" class="btn btn-sm" onclick="toggleCollapse('collapsibleContent', this)">Click to Collapse</button>
|
|
208
|
+
<div id="collapsibleContent" class="collapse-panel">
|
|
209
|
+
<p>This panel can be toggled using JavaScript DOM style display manipulation.</p>
|
|
210
|
+
</div>
|
|
211
|
+
</div>
|
|
212
|
+
|
|
213
|
+
<div class="dom-box">
|
|
214
|
+
<h3>Dynamic Array Menu</h3>
|
|
215
|
+
<ul id="dynamicMenuList" class="styled-list"></ul>
|
|
216
|
+
</div>
|
|
217
|
+
|
|
218
|
+
<div class="dom-box">
|
|
219
|
+
<h3>Mouse Trail Effect</h3>
|
|
220
|
+
<button type="button" class="btn btn-sm" onclick="toggleMouseTrail(this)">Enable Mouse Trail</button>
|
|
221
|
+
<p id="trailStatus">Trail is currently disabled.</p>
|
|
222
|
+
</div>
|
|
223
|
+
</div>
|
|
224
|
+
</section>
|
|
225
|
+
|
|
226
|
+
<section id="object-section" class="card">
|
|
227
|
+
<h2>JavaScript Object Operations Lab</h2>
|
|
228
|
+
<div class="btn-cluster">
|
|
229
|
+
<button type="button" class="btn btn-primary" onclick="runStudentObjectDemo()">Execute Student Object Methods</button>
|
|
230
|
+
</div>
|
|
231
|
+
<pre id="objectOutput" class="console-box">Click "Execute Student Object Methods" to view object transformations, keys, values, iterations, and JSON conversions...</pre>
|
|
232
|
+
</section>
|
|
233
|
+
</main>
|
|
234
|
+
|
|
235
|
+
<footer class="app-footer">
|
|
236
|
+
<p>WAD Web Technologies Reference Kit</p>
|
|
237
|
+
</footer>
|
|
41
238
|
</body>
|
|
42
239
|
</html>
|
|
@@ -1,38 +1,371 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
let timerInterval = null;
|
|
2
|
+
let currentTimerVal = 10;
|
|
3
|
+
let mouseTrailActive = false;
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
document.addEventListener("DOMContentLoaded", function () {
|
|
6
|
+
initDynamicMenu();
|
|
7
|
+
updateRecordCount();
|
|
8
|
+
});
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
function handleFormSubmit(event) {
|
|
11
|
+
event.preventDefault();
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
const rollNo = document.getElementById("rollNo").value.trim();
|
|
14
|
+
const fullName = document.getElementById("fullName").value.trim();
|
|
15
|
+
const password = document.getElementById("password").value;
|
|
16
|
+
const email = document.getElementById("email").value.trim();
|
|
17
|
+
const phone = document.getElementById("phone").value.trim();
|
|
18
|
+
const age = parseInt(document.getElementById("age").value, 10);
|
|
19
|
+
const dob = document.getElementById("dob").value;
|
|
20
|
+
const regTime = document.getElementById("regTime").value;
|
|
21
|
+
const gradMonth = document.getElementById("gradMonth").value;
|
|
22
|
+
const themeColor = document.getElementById("themeColor").value;
|
|
23
|
+
const skillRating = document.getElementById("skillRating").value;
|
|
24
|
+
const department = document.getElementById("department").value;
|
|
25
|
+
const courseTrack = document.getElementById("courseTrack").value.trim();
|
|
26
|
+
const address = document.getElementById("address").value.trim();
|
|
27
|
+
|
|
28
|
+
const selectedGender = document.querySelector('input[name="gender"]:checked');
|
|
29
|
+
const gender = selectedGender ? selectedGender.value : "";
|
|
30
|
+
|
|
31
|
+
const selectedSkills = Array.from(document.querySelectorAll('input[name="skills"]:checked')).map(function (cb) {
|
|
32
|
+
return cb.value;
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
const alertBox = document.getElementById("formAlert");
|
|
36
|
+
alertBox.className = "alert-box";
|
|
37
|
+
alertBox.textContent = "";
|
|
38
|
+
|
|
39
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
40
|
+
const phoneRegex = /^[0-9]{10}$/;
|
|
41
|
+
|
|
42
|
+
if (rollNo.length < 3) {
|
|
43
|
+
showFormAlert("Roll Number must have at least 3 characters.", "error");
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (fullName.length < 2) {
|
|
48
|
+
showFormAlert("Full Name must have at least 2 characters.", "error");
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (password.length < 6) {
|
|
53
|
+
showFormAlert("Password must have at least 6 characters.", "error");
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (!emailRegex.test(email)) {
|
|
58
|
+
showFormAlert("Please enter a valid email address.", "error");
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (!phoneRegex.test(phone)) {
|
|
63
|
+
showFormAlert("Phone number must contain exactly 10 digits.", "error");
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (isNaN(age) || age < 1 || age > 100) {
|
|
68
|
+
showFormAlert("Age must be between 1 and 100.", "error");
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (!department) {
|
|
73
|
+
showFormAlert("Please select a department.", "error");
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const tbody = document.getElementById("recordsBody");
|
|
78
|
+
const tr = document.createElement("tr");
|
|
79
|
+
|
|
80
|
+
tr.innerHTML = "<td>" + escapeHtml(rollNo) + "</td>" +
|
|
81
|
+
"<td>" + escapeHtml(fullName) + "</td>" +
|
|
82
|
+
"<td>" + escapeHtml(email) + "</td>" +
|
|
83
|
+
"<td>" + escapeHtml(department) + "</td>" +
|
|
84
|
+
"<td>" + escapeHtml(gender) + "</td>" +
|
|
85
|
+
"<td>" + escapeHtml(selectedSkills.join(", ") || "None") + "</td>" +
|
|
86
|
+
"<td>" + escapeHtml(skillRating) + "%</td>" +
|
|
87
|
+
"<td>" +
|
|
88
|
+
"<button type='button' class='btn btn-danger' onclick='deleteRecord(this)'>Delete</button> " +
|
|
89
|
+
"<button type='button' class='btn btn-sm' onclick='moveRecordUp(this)'>Up</button>" +
|
|
90
|
+
"</td>";
|
|
91
|
+
|
|
92
|
+
tbody.appendChild(tr);
|
|
93
|
+
updateRecordCount();
|
|
94
|
+
|
|
95
|
+
showFormAlert("Student registered successfully!", "success");
|
|
96
|
+
document.getElementById("registrationForm").reset();
|
|
97
|
+
document.getElementById("ratingDisplay").textContent = "70";
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function showFormAlert(message, type) {
|
|
101
|
+
const alertBox = document.getElementById("formAlert");
|
|
102
|
+
alertBox.textContent = message;
|
|
103
|
+
alertBox.className = "alert-box " + type;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function deleteRecord(button) {
|
|
107
|
+
const row = button.closest("tr");
|
|
108
|
+
if (row) {
|
|
109
|
+
row.remove();
|
|
110
|
+
updateRecordCount();
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function moveRecordUp(button) {
|
|
115
|
+
const row = button.closest("tr");
|
|
116
|
+
if (row && row.previousElementSibling) {
|
|
117
|
+
row.parentNode.insertBefore(row, row.previousElementSibling);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function updateRecordCount() {
|
|
122
|
+
const count = document.querySelectorAll("#recordsBody tr").length;
|
|
123
|
+
const counterEl = document.getElementById("totalRecordCount");
|
|
124
|
+
if (counterEl) {
|
|
125
|
+
counterEl.textContent = count;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function updateRangeDisplay(val) {
|
|
130
|
+
const display = document.getElementById("ratingDisplay");
|
|
131
|
+
if (display) {
|
|
132
|
+
display.textContent = val;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function turnBulbOn() {
|
|
137
|
+
const img = document.getElementById("bulbImg");
|
|
138
|
+
const status = document.getElementById("bulbStatus");
|
|
139
|
+
img.src = "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100' viewBox='0 0 24 24' fill='%23f1c40f'><path d='M12 2C8.13 2 5 5.13 5 9c0 2.38 1.19 4.47 3 5.74V17c0 .55.45 1 1 1h6c.55 0 1-.45 1-1v-2.26c1.81-1.27 3-3.36 3-5.74 0-3.87-3.13-7-7-7zm-3 18h6v1c0 .55-.45 1-1 1h-4c-.55 0-1-.45-1-1v-1z'/></svg>";
|
|
140
|
+
status.textContent = "Bulb status: ON";
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function turnBulbOff() {
|
|
144
|
+
const img = document.getElementById("bulbImg");
|
|
145
|
+
const status = document.getElementById("bulbStatus");
|
|
146
|
+
img.src = "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100' viewBox='0 0 24 24' fill='%237f8c8d'><path d='M12 2C8.13 2 5 5.13 5 9c0 2.38 1.19 4.47 3 5.74V17c0 .55.45 1 1 1h6c.55 0 1-.45 1-1v-2.26c1.81-1.27 3-3.36 3-5.74 0-3.87-3.13-7-7-7zm-3 18h6v1c0 .55-.45 1-1 1h-4c-.55 0-1-.45-1-1v-1z'/></svg>";
|
|
147
|
+
status.textContent = "Hover over the bulb to turn it ON";
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function startTimer() {
|
|
151
|
+
if (timerInterval) {
|
|
152
|
+
clearInterval(timerInterval);
|
|
153
|
+
}
|
|
154
|
+
const display = document.getElementById("timerDisplay");
|
|
155
|
+
timerInterval = setInterval(function () {
|
|
156
|
+
display.textContent = currentTimerVal;
|
|
157
|
+
currentTimerVal--;
|
|
158
|
+
if (currentTimerVal < 0) {
|
|
159
|
+
clearInterval(timerInterval);
|
|
160
|
+
timerInterval = null;
|
|
161
|
+
display.textContent = "Time Up!";
|
|
162
|
+
}
|
|
163
|
+
}, 1000);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function resetTimer() {
|
|
167
|
+
if (timerInterval) {
|
|
168
|
+
clearInterval(timerInterval);
|
|
169
|
+
timerInterval = null;
|
|
170
|
+
}
|
|
171
|
+
currentTimerVal = 10;
|
|
172
|
+
document.getElementById("timerDisplay").textContent = "10";
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function addListItem() {
|
|
176
|
+
const list = document.getElementById("orderList");
|
|
177
|
+
const count = list.children.length + 1;
|
|
178
|
+
const li = document.createElement("li");
|
|
179
|
+
const textNode = document.createTextNode("Dynamic Item " + count + " (Click to Swap)");
|
|
180
|
+
li.appendChild(textNode);
|
|
181
|
+
li.onclick = function () {
|
|
182
|
+
swapWithNext(this);
|
|
183
|
+
};
|
|
184
|
+
list.appendChild(li);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function swapWithNext(elt) {
|
|
188
|
+
const nextItem = elt.nextElementSibling;
|
|
189
|
+
if (nextItem) {
|
|
190
|
+
elt.parentNode.insertBefore(nextItem, elt);
|
|
191
|
+
} else if (elt.previousElementSibling) {
|
|
192
|
+
elt.parentNode.insertBefore(elt, elt.parentNode.firstElementChild);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function toggleCollapse(panelId, btn) {
|
|
197
|
+
const panel = document.getElementById(panelId);
|
|
198
|
+
if (panel.style.display === "none") {
|
|
199
|
+
panel.style.display = "block";
|
|
200
|
+
btn.textContent = "Click to Collapse";
|
|
201
|
+
} else {
|
|
202
|
+
panel.style.display = "none";
|
|
203
|
+
btn.textContent = "Click to Expand";
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function initDynamicMenu() {
|
|
208
|
+
const menuItems = ["Home", "About Us", "Department", "Academics", "Contact"];
|
|
209
|
+
const ul = document.getElementById("dynamicMenuList");
|
|
210
|
+
if (!ul) return;
|
|
211
|
+
ul.innerHTML = "";
|
|
212
|
+
|
|
213
|
+
menuItems.forEach(function (item) {
|
|
214
|
+
const li = document.createElement("li");
|
|
215
|
+
li.textContent = item;
|
|
216
|
+
li.addEventListener("click", function (event) {
|
|
217
|
+
alert("Clicked Menu Item: " + this.textContent + "\nEvent Type: " + event.type + "\nTarget Node: " + event.target.nodeName);
|
|
218
|
+
});
|
|
219
|
+
ul.appendChild(li);
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
function toggleMouseTrail(btn) {
|
|
224
|
+
mouseTrailActive = !mouseTrailActive;
|
|
225
|
+
const status = document.getElementById("trailStatus");
|
|
226
|
+
if (mouseTrailActive) {
|
|
227
|
+
window.addEventListener("mousemove", handleMouseTrail);
|
|
228
|
+
btn.textContent = "Disable Mouse Trail";
|
|
229
|
+
status.textContent = "Move your mouse around the window to see the trail effect.";
|
|
230
|
+
} else {
|
|
231
|
+
window.removeEventListener("mousemove", handleMouseTrail);
|
|
232
|
+
btn.textContent = "Enable Mouse Trail";
|
|
233
|
+
status.textContent = "Trail is currently disabled.";
|
|
14
234
|
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
function handleMouseTrail(e) {
|
|
238
|
+
const particle = document.createElement("div");
|
|
239
|
+
particle.className = "mouse-trail-particle";
|
|
240
|
+
particle.style.left = e.pageX + "px";
|
|
241
|
+
particle.style.top = e.pageY + "px";
|
|
242
|
+
document.body.appendChild(particle);
|
|
243
|
+
|
|
244
|
+
setTimeout(function () {
|
|
245
|
+
if (particle.parentNode) {
|
|
246
|
+
particle.parentNode.removeChild(particle);
|
|
247
|
+
}
|
|
248
|
+
}, 800);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
function runStudentObjectDemo() {
|
|
252
|
+
const student = {
|
|
253
|
+
rollNo: "21CS101",
|
|
254
|
+
name: "Alex Johnson",
|
|
255
|
+
department: "Computer Science",
|
|
256
|
+
year: 3,
|
|
257
|
+
address: {
|
|
258
|
+
street: "123 Tech Boulevard",
|
|
259
|
+
city: "Metropolis",
|
|
260
|
+
state: "California",
|
|
261
|
+
pincode: "90210"
|
|
262
|
+
},
|
|
263
|
+
marks: [88, 92, 79, 95, 85],
|
|
264
|
+
skills: ["HTML", "CSS", "JavaScript"],
|
|
265
|
+
attendancePercentage: 92.5,
|
|
266
|
+
|
|
267
|
+
displayDetails: function () {
|
|
268
|
+
return "Roll No: " + this.rollNo +
|
|
269
|
+
"\nName: " + this.name +
|
|
270
|
+
"\nDepartment: " + this.department +
|
|
271
|
+
"\nYear: " + this.year +
|
|
272
|
+
"\nCity: " + this.address.city +
|
|
273
|
+
"\nAttendance: " + this.attendancePercentage + "%";
|
|
274
|
+
},
|
|
275
|
+
|
|
276
|
+
calculateTotalAndAverage: function () {
|
|
277
|
+
let total = 0;
|
|
278
|
+
for (let i = 0; i < this.marks.length; i++) {
|
|
279
|
+
total += this.marks[i];
|
|
280
|
+
}
|
|
281
|
+
const avg = total / this.marks.length;
|
|
282
|
+
return { total: total, average: avg };
|
|
283
|
+
},
|
|
284
|
+
|
|
285
|
+
determineGrade: function (avg) {
|
|
286
|
+
if (avg >= 90) return "A";
|
|
287
|
+
if (avg >= 80) return "B";
|
|
288
|
+
if (avg >= 70) return "C";
|
|
289
|
+
if (avg >= 60) return "D";
|
|
290
|
+
return "F";
|
|
291
|
+
},
|
|
15
292
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
293
|
+
addSkill: function (newSkill) {
|
|
294
|
+
this.skills.push(newSkill);
|
|
295
|
+
},
|
|
296
|
+
|
|
297
|
+
updateAddress: function (street, city, state, pincode) {
|
|
298
|
+
this.address.street = street;
|
|
299
|
+
this.address.city = city;
|
|
300
|
+
this.address.state = state;
|
|
301
|
+
this.address.pincode = pincode;
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
let log = "=== INITIAL STUDENT DETAILS ===\n";
|
|
306
|
+
log += student.displayDetails() + "\n\n";
|
|
307
|
+
|
|
308
|
+
const stats = student.calculateTotalAndAverage();
|
|
309
|
+
const grade = student.determineGrade(stats.average);
|
|
310
|
+
log += "=== ACADEMIC PERFORMANCE ===\n";
|
|
311
|
+
log += "Total Marks: " + stats.total + " / 500\n";
|
|
312
|
+
log += "Average Marks: " + stats.average.toFixed(2) + "\n";
|
|
313
|
+
log += "Grade: " + grade + "\n\n";
|
|
314
|
+
|
|
315
|
+
student.addSkill("MongoDB");
|
|
316
|
+
student.updateAddress("456 Innovation Parkway", "Silicon Valley", "California", "94016");
|
|
317
|
+
log += "=== UPDATED SKILLS & ADDRESS ===\n";
|
|
318
|
+
log += "Skills: " + student.skills.join(", ") + "\n";
|
|
319
|
+
log += "New Address: " + student.address.street + ", " + student.address.city + "\n\n";
|
|
320
|
+
|
|
321
|
+
student.email = "alex.johnson@techuniv.edu";
|
|
322
|
+
log += "=== DYNAMIC PROPERTY ADDITION ===\n";
|
|
323
|
+
log += "Added student.email: " + student.email + "\n\n";
|
|
324
|
+
|
|
325
|
+
delete student.year;
|
|
326
|
+
log += "=== DYNAMIC PROPERTY DELETION ===\n";
|
|
327
|
+
log += "Deleted student.year: " + ("year" in student ? "Still exists" : "Successfully deleted") + "\n\n";
|
|
328
|
+
|
|
329
|
+
log += "=== CHECK PROPERTY EXISTENCE ===\n";
|
|
330
|
+
log += "'email' in student: " + ("email" in student) + "\n";
|
|
331
|
+
log += "'year' in student: " + ("year" in student) + "\n";
|
|
332
|
+
log += "hasOwnProperty('department'): " + student.hasOwnProperty("department") + "\n\n";
|
|
333
|
+
|
|
334
|
+
log += "=== FOR...IN LOOP (ALL KEYS & VALUES) ===\n";
|
|
335
|
+
for (let key in student) {
|
|
336
|
+
if (typeof student[key] !== "function") {
|
|
337
|
+
log += key + " : " + (typeof student[key] === "object" ? JSON.stringify(student[key]) : student[key]) + "\n";
|
|
338
|
+
}
|
|
20
339
|
}
|
|
340
|
+
log += "\n";
|
|
341
|
+
|
|
342
|
+
log += "=== OBJECT.KEYS() ===\n";
|
|
343
|
+
log += JSON.stringify(Object.keys(student)) + "\n\n";
|
|
21
344
|
|
|
22
|
-
|
|
23
|
-
const
|
|
345
|
+
log += "=== OBJECT.VALUES() (NON-FUNCTIONS) ===\n";
|
|
346
|
+
const values = Object.values(student).filter(function (val) {
|
|
347
|
+
return typeof val !== "function";
|
|
348
|
+
});
|
|
349
|
+
log += JSON.stringify(values) + "\n\n";
|
|
24
350
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
"<td><button onclick='deleteRow(this)'>Delete</button></td>";
|
|
351
|
+
const jsonString = JSON.stringify(student, null, 2);
|
|
352
|
+
log += "=== CONVERT OBJECT TO JSON STRING (JSON.stringify) ===\n";
|
|
353
|
+
log += jsonString + "\n\n";
|
|
29
354
|
|
|
30
|
-
|
|
355
|
+
const parsedObj = JSON.parse(jsonString);
|
|
356
|
+
log += "=== CONVERT JSON BACK TO JAVASCRIPT OBJECT (JSON.parse) ===\n";
|
|
357
|
+
log += "Parsed Object Name: " + parsedObj.name + "\n";
|
|
358
|
+
log += "Parsed Object Email: " + parsedObj.email + "\n";
|
|
31
359
|
|
|
32
|
-
document.getElementById("
|
|
33
|
-
return true;
|
|
360
|
+
document.getElementById("objectOutput").textContent = log;
|
|
34
361
|
}
|
|
35
362
|
|
|
36
|
-
function
|
|
37
|
-
|
|
363
|
+
function escapeHtml(str) {
|
|
364
|
+
if (typeof str !== "string") return str;
|
|
365
|
+
return str
|
|
366
|
+
.replace(/&/g, "&")
|
|
367
|
+
.replace(/</g, "<")
|
|
368
|
+
.replace(/>/g, ">")
|
|
369
|
+
.replace(/"/g, """)
|
|
370
|
+
.replace(/'/g, "'");
|
|
38
371
|
}
|
|
@@ -1,22 +1,463 @@
|
|
|
1
|
+
* {
|
|
2
|
+
box-sizing: border-box;
|
|
3
|
+
margin: 0;
|
|
4
|
+
padding: 0;
|
|
5
|
+
}
|
|
6
|
+
|
|
1
7
|
body {
|
|
2
|
-
font-family: sans-serif;
|
|
3
|
-
|
|
8
|
+
font-family: Arial, Helvetica, sans-serif;
|
|
9
|
+
background-color: #f4f6f9;
|
|
10
|
+
color: #333333;
|
|
11
|
+
line-height: 1.6;
|
|
4
12
|
}
|
|
5
13
|
|
|
6
|
-
|
|
7
|
-
|
|
14
|
+
.app-header {
|
|
15
|
+
background-color: #2c3e50;
|
|
16
|
+
color: #ffffff;
|
|
17
|
+
padding: 20px;
|
|
18
|
+
text-align: center;
|
|
8
19
|
}
|
|
9
20
|
|
|
10
|
-
|
|
11
|
-
|
|
21
|
+
.app-header h1 {
|
|
22
|
+
margin-bottom: 10px;
|
|
23
|
+
font-size: 24px;
|
|
12
24
|
}
|
|
13
25
|
|
|
14
|
-
|
|
15
|
-
|
|
26
|
+
.nav-bar {
|
|
27
|
+
display: flex;
|
|
28
|
+
justify-content: center;
|
|
29
|
+
gap: 15px;
|
|
30
|
+
flex-wrap: wrap;
|
|
16
31
|
}
|
|
17
32
|
|
|
18
|
-
|
|
19
|
-
|
|
33
|
+
.nav-bar a {
|
|
34
|
+
color: #ecf0f1;
|
|
35
|
+
text-decoration: none;
|
|
36
|
+
font-weight: bold;
|
|
37
|
+
padding: 6px 12px;
|
|
38
|
+
border-radius: 4px;
|
|
39
|
+
transition: background-color 0.3s ease, transform 0.2s ease;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.nav-bar a:hover {
|
|
43
|
+
background-color: #34495e;
|
|
44
|
+
transform: translateY(-2px);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.container {
|
|
48
|
+
max-width: 1000px;
|
|
49
|
+
margin: 25px auto;
|
|
50
|
+
padding: 0 15px;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.card {
|
|
54
|
+
background-color: #ffffff;
|
|
55
|
+
border-radius: 8px;
|
|
56
|
+
padding: 25px;
|
|
57
|
+
margin-bottom: 25px;
|
|
58
|
+
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.08);
|
|
59
|
+
position: relative;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.card h2 {
|
|
63
|
+
color: #2c3e50;
|
|
64
|
+
border-bottom: 2px solid #3498db;
|
|
65
|
+
padding-bottom: 8px;
|
|
66
|
+
margin-bottom: 20px;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
fieldset {
|
|
70
|
+
border: 1px solid #bdc3c7;
|
|
71
|
+
border-radius: 6px;
|
|
72
|
+
padding: 20px;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
legend {
|
|
76
|
+
padding: 0 10px;
|
|
77
|
+
font-weight: bold;
|
|
78
|
+
color: #2c3e50;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.form-grid {
|
|
82
|
+
display: grid;
|
|
83
|
+
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
|
84
|
+
gap: 15px;
|
|
85
|
+
margin-top: 10px;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.form-group {
|
|
89
|
+
display: flex;
|
|
90
|
+
flex-direction: column;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.form-group.full-width {
|
|
94
|
+
grid-column: 1 / -1;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
label {
|
|
98
|
+
font-size: 14px;
|
|
99
|
+
font-weight: bold;
|
|
100
|
+
margin-bottom: 5px;
|
|
101
|
+
color: #34495e;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
input[type="text"],
|
|
105
|
+
input[type="password"],
|
|
106
|
+
input[type="email"],
|
|
107
|
+
input[type="tel"],
|
|
108
|
+
input[type="number"],
|
|
109
|
+
input[type="date"],
|
|
110
|
+
input[type="time"],
|
|
111
|
+
input[type="month"],
|
|
112
|
+
input[type="color"],
|
|
113
|
+
input[type="file"],
|
|
114
|
+
select,
|
|
115
|
+
textarea {
|
|
116
|
+
width: 100%;
|
|
117
|
+
padding: 10px;
|
|
118
|
+
border: 1px solid #ccc;
|
|
119
|
+
border-radius: 4px;
|
|
120
|
+
font-size: 14px;
|
|
121
|
+
transition: border-color 0.3s ease, box-shadow 0.3s ease;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
input::placeholder,
|
|
125
|
+
textarea::placeholder {
|
|
126
|
+
color: #95a5a6;
|
|
127
|
+
font-style: italic;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
input:focus,
|
|
131
|
+
select:focus,
|
|
132
|
+
textarea:focus {
|
|
133
|
+
outline: none;
|
|
134
|
+
border-color: #3498db;
|
|
135
|
+
box-shadow: 0 0 5px rgba(52, 152, 219, 0.5);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
input:invalid:not(:placeholder-shown):not(:focus) {
|
|
139
|
+
border-color: #e74c3c;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
input:valid:not(:placeholder-shown):not([type="color"]):not([type="range"]) {
|
|
143
|
+
border-color: #2ecc71;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.radio-group,
|
|
147
|
+
.checkbox-group {
|
|
148
|
+
display: flex;
|
|
149
|
+
gap: 15px;
|
|
150
|
+
align-items: center;
|
|
151
|
+
flex-wrap: wrap;
|
|
152
|
+
padding-top: 5px;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
.radio-group label,
|
|
156
|
+
.checkbox-group label {
|
|
157
|
+
font-weight: normal;
|
|
158
|
+
cursor: pointer;
|
|
159
|
+
display: inline-flex;
|
|
160
|
+
align-items: center;
|
|
161
|
+
gap: 5px;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
input[type="range"] {
|
|
165
|
+
width: 100%;
|
|
166
|
+
cursor: pointer;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
.button-group {
|
|
170
|
+
display: flex;
|
|
171
|
+
gap: 10px;
|
|
172
|
+
margin-top: 20px;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
.btn {
|
|
176
|
+
padding: 10px 20px;
|
|
177
|
+
border: none;
|
|
178
|
+
border-radius: 4px;
|
|
179
|
+
font-size: 14px;
|
|
180
|
+
font-weight: bold;
|
|
181
|
+
cursor: pointer;
|
|
182
|
+
transition: background-color 0.3s ease, transform 0.1s ease;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
.btn:active {
|
|
186
|
+
transform: scale(0.98);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
.btn-primary {
|
|
190
|
+
background-color: #3498db;
|
|
191
|
+
color: #ffffff;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
.btn-primary:hover {
|
|
195
|
+
background-color: #2980b9;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
.btn-secondary {
|
|
199
|
+
background-color: #95a5a6;
|
|
200
|
+
color: #ffffff;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
.btn-secondary:hover {
|
|
204
|
+
background-color: #7f8c8d;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
.btn-danger {
|
|
208
|
+
background-color: #e74c3c;
|
|
209
|
+
color: #ffffff;
|
|
210
|
+
padding: 5px 10px;
|
|
211
|
+
font-size: 12px;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
.btn-danger:hover {
|
|
215
|
+
background-color: #c0392b;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.btn-sm {
|
|
219
|
+
padding: 6px 12px;
|
|
220
|
+
background-color: #34495e;
|
|
221
|
+
color: #ffffff;
|
|
222
|
+
font-size: 12px;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
.btn-sm:hover {
|
|
226
|
+
background-color: #2c3e50;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
.alert-box {
|
|
230
|
+
margin-top: 15px;
|
|
231
|
+
padding: 12px;
|
|
232
|
+
border-radius: 4px;
|
|
233
|
+
display: none;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
.alert-box.success {
|
|
237
|
+
display: block;
|
|
238
|
+
background-color: #d4edda;
|
|
239
|
+
color: #155724;
|
|
240
|
+
border: 1px solid #c3e6cb;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
.alert-box.error {
|
|
244
|
+
display: block;
|
|
245
|
+
background-color: #f8d7da;
|
|
246
|
+
color: #721c24;
|
|
247
|
+
border: 1px solid #f5c6cb;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
.table-container {
|
|
251
|
+
overflow-x: auto;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
table {
|
|
255
|
+
width: 100%;
|
|
20
256
|
border-collapse: collapse;
|
|
21
|
-
|
|
257
|
+
margin-top: 10px;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
caption {
|
|
261
|
+
font-weight: bold;
|
|
262
|
+
margin-bottom: 8px;
|
|
263
|
+
text-align: left;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
table, th, td {
|
|
267
|
+
border: 1px solid #dddddd;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
th, td {
|
|
271
|
+
padding: 10px;
|
|
272
|
+
text-align: left;
|
|
273
|
+
font-size: 14px;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
th {
|
|
277
|
+
background-color: #2c3e50;
|
|
278
|
+
color: #ffffff;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
tbody tr:nth-child(even) {
|
|
282
|
+
background-color: #f9f9f9;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
tbody tr:hover {
|
|
286
|
+
background-color: #f1f1f1;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
tfoot {
|
|
290
|
+
font-weight: bold;
|
|
291
|
+
background-color: #ecf0f1;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
.dom-grid {
|
|
295
|
+
display: grid;
|
|
296
|
+
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
|
297
|
+
gap: 20px;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
.dom-box {
|
|
301
|
+
border: 1px solid #e0e0e0;
|
|
302
|
+
border-radius: 6px;
|
|
303
|
+
padding: 15px;
|
|
304
|
+
background-color: #fafafa;
|
|
305
|
+
display: flex;
|
|
306
|
+
flex-direction: column;
|
|
307
|
+
align-items: center;
|
|
308
|
+
text-align: center;
|
|
309
|
+
gap: 10px;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
.dom-box h3 {
|
|
313
|
+
font-size: 16px;
|
|
314
|
+
color: #2c3e50;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
.dom-box img {
|
|
318
|
+
cursor: pointer;
|
|
319
|
+
transition: transform 0.3s ease;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
.dom-box img:hover {
|
|
323
|
+
transform: scale(1.1);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
.counter-display {
|
|
327
|
+
font-size: 36px;
|
|
328
|
+
font-weight: bold;
|
|
329
|
+
color: #e74c3c;
|
|
330
|
+
min-height: 50px;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
.btn-cluster {
|
|
334
|
+
display: flex;
|
|
335
|
+
gap: 8px;
|
|
336
|
+
flex-wrap: wrap;
|
|
337
|
+
justify-content: center;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
ol#orderList {
|
|
341
|
+
text-align: left;
|
|
342
|
+
width: 100%;
|
|
343
|
+
padding-left: 20px;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
ol#orderList li {
|
|
347
|
+
padding: 6px;
|
|
348
|
+
cursor: pointer;
|
|
349
|
+
user-select: none;
|
|
350
|
+
border-radius: 4px;
|
|
351
|
+
transition: background-color 0.2s ease;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
ol#orderList li:hover {
|
|
355
|
+
background-color: #e8f4fd;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
.collapse-panel {
|
|
359
|
+
display: block;
|
|
360
|
+
width: 100%;
|
|
361
|
+
padding: 10px;
|
|
362
|
+
background-color: #eaf2f8;
|
|
363
|
+
border: 1px dashed #3498db;
|
|
364
|
+
border-radius: 4px;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
.styled-list {
|
|
368
|
+
list-style-type: none;
|
|
369
|
+
width: 100%;
|
|
370
|
+
text-align: left;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
.styled-list li {
|
|
374
|
+
padding: 8px;
|
|
375
|
+
border-bottom: 1px solid #eee;
|
|
376
|
+
cursor: pointer;
|
|
377
|
+
position: relative;
|
|
378
|
+
transition: transform 0.2s ease, color 0.2s ease;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
.styled-list li::before {
|
|
382
|
+
content: "➔ ";
|
|
383
|
+
color: #3498db;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
.styled-list li:hover {
|
|
387
|
+
color: #2980b9;
|
|
388
|
+
transform: translateX(5px);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
.console-box {
|
|
392
|
+
background-color: #2c3e50;
|
|
393
|
+
color: #2ecc71;
|
|
394
|
+
padding: 15px;
|
|
395
|
+
border-radius: 6px;
|
|
396
|
+
font-family: 'Courier New', Courier, monospace;
|
|
397
|
+
font-size: 13px;
|
|
398
|
+
white-space: pre-wrap;
|
|
399
|
+
max-height: 350px;
|
|
400
|
+
overflow-y: auto;
|
|
401
|
+
margin-top: 15px;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
.fixed-badge {
|
|
405
|
+
position: fixed;
|
|
406
|
+
bottom: 20px;
|
|
407
|
+
right: 20px;
|
|
408
|
+
background-color: #e67e22;
|
|
409
|
+
color: #ffffff;
|
|
410
|
+
padding: 8px 16px;
|
|
411
|
+
border-radius: 20px;
|
|
412
|
+
font-size: 12px;
|
|
413
|
+
font-weight: bold;
|
|
414
|
+
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
|
415
|
+
z-index: 1000;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
.animated-badge {
|
|
419
|
+
animation-name: badgePulse;
|
|
420
|
+
animation-duration: 2s;
|
|
421
|
+
animation-iteration-count: infinite;
|
|
422
|
+
animation-direction: alternate;
|
|
423
|
+
animation-timing-function: ease-in-out;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
@keyframes badgePulse {
|
|
427
|
+
from {
|
|
428
|
+
transform: scale(1);
|
|
429
|
+
}
|
|
430
|
+
to {
|
|
431
|
+
transform: scale(1.08);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
.mouse-trail-particle {
|
|
436
|
+
position: absolute;
|
|
437
|
+
width: 12px;
|
|
438
|
+
height: 12px;
|
|
439
|
+
background-color: #e74c3c;
|
|
440
|
+
border-radius: 50%;
|
|
441
|
+
pointer-events: none;
|
|
442
|
+
transform: translate(-50%, -50%);
|
|
443
|
+
animation: fadeParticle 0.8s forwards;
|
|
444
|
+
z-index: 9999;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
@keyframes fadeParticle {
|
|
448
|
+
0% {
|
|
449
|
+
opacity: 1;
|
|
450
|
+
transform: translate(-50%, -50%) scale(1);
|
|
451
|
+
}
|
|
452
|
+
100% {
|
|
453
|
+
opacity: 0;
|
|
454
|
+
transform: translate(-50%, -50%) scale(2.5);
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
.app-footer {
|
|
459
|
+
text-align: center;
|
|
460
|
+
padding: 15px;
|
|
461
|
+
color: #7f8c8d;
|
|
462
|
+
font-size: 13px;
|
|
22
463
|
}
|