-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCode.gs
More file actions
169 lines (134 loc) · 5.03 KB
/
Code.gs
File metadata and controls
169 lines (134 loc) · 5.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
// ============================================================
// CONFIGURATION — edit these values to match your form
// ============================================================
// Partial match for the course selection question title
var COURSE_QUESTION_KEYWORD = "What online course would you like to study?";
// Maximum participants per course
var COURSE_LIMITS = {
"English (basic)": 25,
"English (intermediate)": 30,
"English (advanced)": 10,
"German": 10,
"Photography": 2
};
// All course names (derived from limits)
var ALL_COURSES = Object.keys(COURSE_LIMITS);
// ============================================================
// MAIN: runs every time someone submits the form
// ============================================================
function onFormSubmit(e) {
updateCourseAvailability();
}
// ============================================================
// UPDATE FORM: remove full courses & show "full" message
// ============================================================
function updateCourseAvailability() {
var form = FormApp.getActiveForm();
var counts = countRegistrationsPerCourse(form);
// Find the course question (partial match since the title is bilingual/multiline)
var courseItem = null;
var formItems = form.getItems();
for (var i = 0; i < formItems.length; i++) {
if (formItems[i].getTitle().indexOf(COURSE_QUESTION_KEYWORD) !== -1) {
courseItem = formItems[i];
break;
}
}
if (!courseItem) {
Logger.log("Course question not found. Check COURSE_QUESTION_KEYWORD.");
return;
}
var multipleChoiceItem = courseItem.asMultipleChoiceItem();
// Build available choices and "full" labels
var choices = [];
var fullCourses = [];
for (var j = 0; j < ALL_COURSES.length; j++) {
var course = ALL_COURSES[j];
var count = counts[course] || 0;
var limit = COURSE_LIMITS[course] || 10;
var spotsLeft = limit - count;
if (spotsLeft > 0) {
// Still available
choices.push(
multipleChoiceItem.createChoice(course)
);
} else {
// Full — track it
fullCourses.push(course);
}
}
// Update the help text to show which courses are full
if (fullCourses.length > 0 && fullCourses.length < ALL_COURSES.length) {
multipleChoiceItem.setHelpText(
"\n" +
"⛔ دورههای پر شده (ثبتنام بسته است):\n" +
fullCourses.join("، ")
+ "\n\n\n\n\n"
+ ":دوره های قابل انتخاب"
);
} else if (fullCourses.length === 0) {
multipleChoiceItem.setHelpText("");
}
// If all courses are full, close the form
if (choices.length === 0) {
form.setAcceptingResponses(false);
form.setCustomClosedFormMessage(
"متأسفانه ظرفیت تمام دورهها تکمیل شده است. لطفاً بعداً دوباره بررسی کنید."
);
Logger.log("All courses are full. Form closed.");
return;
}
// Update the multiple choice options to only show available courses
multipleChoiceItem.setChoices(choices);
// Make sure the form is open (in case it was previously closed and spots freed up)
form.setAcceptingResponses(true);
Logger.log(
"Updated: " + choices.length + " available, " + fullCourses.length + " full."
);
}
// ============================================================
// COUNT how many people registered for each course
// ============================================================
function countRegistrationsPerCourse(form) {
var responses = form.getResponses();
var counts = {};
for (var i = 0; i < responses.length; i++) {
var itemResponses = responses[i].getItemResponses();
for (var j = 0; j < itemResponses.length; j++) {
if (itemResponses[j].getItem().getTitle().indexOf(COURSE_QUESTION_KEYWORD) !== -1) {
var answer = itemResponses[j].getResponse();
// Checkbox responses come as an array
var chosen = Array.isArray(answer) ? answer : [answer];
for (var k = 0; k < chosen.length; k++) {
counts[chosen[k]] = (counts[chosen[k]] || 0) + 1;
}
}
}
}
return counts;
}
// ============================================================
// SETUP: run this ONCE to create the form-submit trigger
// ============================================================
function setupTrigger() {
// Remove any existing onFormSubmit triggers to avoid duplicates
var triggers = ScriptApp.getProjectTriggers();
for (var i = 0; i < triggers.length; i++) {
if (triggers[i].getHandlerFunction() === "onFormSubmit") {
ScriptApp.deleteTrigger(triggers[i]);
}
}
// Create the trigger
ScriptApp.newTrigger("onFormSubmit")
.forForm(FormApp.getActiveForm())
.onFormSubmit()
.create();
Logger.log("Trigger created successfully.");
}
// ============================================================
// MANUAL: run this to force-update the form right now
// ============================================================
function manualUpdate() {
updateCourseAvailability();
Logger.log("Manual update complete.");
}