PageSourceSearch

https://myportal.smartstartinc.com/js/ViewModels/OnlineInstall/Onl…U1Thp2ACbC2SanUq5tn9ycz0NAe3FjJ8Z015M5iTMr4

js smartstartinc.com collected 2026-10-01 12:35:42 UTC 12,702 bytes, 333 lines download raw bytes

1function OnlineInstallVehicleVm() {
2    var self = this;
3
4    self.States = [];
5    self.Mode = ko.observable('plate');
6    self.PlateState = ko.observable('');
7    self.PlateNumber = ko.observable('');
8    self.Vin = ko.observable('');
9
10    self.PlateNumber.subscribe(function (val) {
11        if (val) {
12            var cleaned = val.replace(/[^a-zA-Z0-9]/g, '').toUpperCase();
13            if (cleaned !== val) self.PlateNumber(cleaned);
14        }
15    });
16
17    self.Vin.subscribe(function (val) {
18        if (val) {
19            var cleaned = val.replace(/[^a-zA-Z0-9]/g, '').toUpperCase();
20            if (cleaned !== val) self.Vin(cleaned);
21        }
22    });
23
24    self.Year = ko.observable('');
25    self.Make = ko.observable('');
26    self.VehicleModel = ko.observable('');
27    self.Color = ko.observable('');
28
29    self.YearOptions = ko.observableArray([]);
30    self.MakeOptions = ko.observableArray([]);
31    self.ModelOptions = ko.observableArray([]);
32    self.ColorOptions = ko.observableArray([]);
33
34    self.LookupPerformed = ko.observable(false);
35    self.LookupErrorTitle = ko.observable('');
36    self.LookupErrorMessage = ko.observable('');
37
38    self.LookupErrorTitle.subscribe(function (v) {
39        if (v) window.scrollTo({ top: 0, behavior: 'smooth' });
40    });
41
42    self._suppressCascade = false;
43    self._loadingLookup = false;
44
45    self.IsManualMode = ko.computed(function () {
46        return self.Mode() === 'manual';
47    });
48
49    self.ShowVehicleFields = ko.computed(function () {
50        if (self.Mode() === 'manual') return true;
51        return self.LookupPerformed();
52    });
53
54    self.CanLookupPlate = ko.computed(function () {
55        return self.PlateState() !== '' && self.PlateNumber() !== '';
56    });
57
58    self.CanLookupVin = ko.computed(function () {
59        return self.Vin() !== '' && self.Vin().length > 0;
60    });
61
62    self.CanSubmit = ko.computed(function () {
63        return self.ShowVehicleFields();
64    });
65
66    self.ShowVehicleFields.subscribe(function (visible) {
67        if (visible) {
68            var $form = $('#vehicleForm');
69            $form.removeData("validator").removeData("unobtrusiveValidation");
70            $.validator.unobtrusive.parse($form);
71        }
72    });
73
74    // Cascade: Year changed → load Makes
75    self.Year.subscribe(function (year) {
76        if (self._suppressCascade) return;
77        self.MakeOptions([]);
78        self.ModelOptions([]);
79        self.Make('');
80        self.VehicleModel('');
81        if (year) {
82            self.LoadMakes(year);
83        }
84    });
85
86    // Cascade: Make changed → load Models
87    self.Make.subscribe(function (makeName) {
88        if (self._suppressCascade) return;
89        self.ModelOptions([]);
90        self.VehicleModel('');
91        if (makeName && self.Year()) {
92            var selected = self.MakeOptions().find(function (m) { return m.name === makeName; });
93            if (selected) {
94                self.LoadModels(self.Year(), selected.id);
95            }
96        }
97    });
98
99    self.SetMode = function (mode) {
100        self.Mode(mode);
101        self.LookupErrorTitle('');
102        self.LookupErrorMessage('');
103        self.LookupPerformed(false);
104        self.Year('');
105        self.Make('');
106        self.VehicleModel('');
107        self.Color('');
108        self.YearOptions([]);
109        self.MakeOptions([]);
110        self.ModelOptions([]);
111        if (mode === 'manual') {
112            self.LoadYears();
113            self.LogVehicleManualEntry();
114        }
115    };
116
117    self.LogVehicleManualEntry = function () {
118        if (typeof logEvent !== 'function' || typeof analyticsEvent === 'undefined') return;
119
120        const analyticsContext = window.onlineInstallAnalyticsContext || {};
121        logEvent(analyticsEvent.enro_vehicle_manual_entry, {
122            enrollment_id: analyticsContext.enrollment_id || ''
123        });
124    };
125
126    self.LoadYears = function (callback) {
127        ajaxHelper({
128            url: window.location.origin + '/OnlineInstall/GetVehicleYears',
129            type: 'GET',
130            dataType: 'json',
131            spinner: !self._loadingLookup,
132            spinnerSelector: '.vehicle-form',
133            success: function (result) {
134                self.YearOptions(result.sort(function (a, b) { return b - a; }).map(function (y) { return y.toString(); }));
135                if (callback) callback();
136            }
137        });
138    };
139
140    self.LoadMakes = function (year, callback) {
141        ajaxHelper({
142            url: window.location.origin + '/OnlineInstall/GetVehicleMakes',
143            type: 'GET',
144            dataType: 'json',
145            data: { year: year },
146            spinner: !self._loadingLookup,
147            spinnerSelector: '.vehicle-form',
148            success: function (result) {
149                self.MakeOptions(result);
150                if (callback) callback();
151            }
152        });
153    };
154
155    self.LoadColors = function (callback) {
156        ajaxHelper({
157            url: window.location.origin + '/OnlineInstall/GetVehicleC
157olors',
158            type: 'GET',
159            dataType: 'json',
160            success: function (result) {
161                self.ColorOptions(result);
162                if (callback) callback();
163            }
164        });
165    };
166
167    self.LoadModels = function (year, makeId, callback) {
168        ajaxHelper({
169            url: window.location.origin + '/OnlineInstall/GetVehicleModels',
170            type: 'GET',
171            dataType: 'json',
172            data: { year: year, makeId: makeId },
173            spinner: !self._loadingLookup,
174            spinnerSelector: '.vehicle-form',
175            success: function (result) {
176                self.ModelOptions(result);
177                if (callback) callback();
178            }
179        });
180    };
181
182    self.LookupVehicle = function () {
183        if (self.Mode() === 'plate' && !self.CanLookupPlate()) return;
184        if (self.Mode() === 'vin' && !self.CanLookupVin()) return;
185
186        self.LookupErrorTitle('');
187        self.LookupErrorMessage('');
188        self.LookupPerformed(false);
189        self.LogVehicleLookupAttempt();
190
191        var data = {};
192        if (self.Mode() === 'plate') {
193            data.plateNumber = self.PlateNumber();
194            data.plateState = self.PlateState();
195        } else {
196            data.vin = self.Vin();
197        }
198
199        AddSpinner('.vehicle-form');
200
201        ajaxHelper({
202            url: window.location.origin + '/OnlineInstall/VehicleLookup',
203            type: 'GET',
204            dataType: 'json',
205            contentType: 'application/json',
206            data: data,
207            success: function (result) {
208                if (result.success) {
209                    if (result.vin) self.Vin(result.vin);
210                    self._suppressCascade = true;
211                    self._loadingLookup = true;
212                    self.LoadYears(function () {
213                        self.Year(result.year.toString());
214                        self.LoadMakes(result.year.toString(), function () {
215                            self._suppressCascade = true;
216                            var selectedMake = self.MakeOptions().find(function (m) { return m.name.toUpperCase() === result.make.toUpperCase(); });
217                            if (selectedMake) {
218                                self.Make(selectedMake.name);
219                                self.LoadModels(result.year.toString(), selectedMake.id, function () {
220                                    self._suppressCascade = true;
221                                    var selectedModel = self.ModelOptions().find(function (m) { return m.name.toUpperCase() === result.model.toUpperCase(); });
222                                    if (selectedModel) self.VehicleModel(selectedModel.name);
223                                    self._suppressCascade = false;
224                                    self._loadingLookup = false;
225                                    self.LookupPerformed(true);
226                                    RemoveSpinner('.vehicle-form');
227                                });
228                            } else {
229                                self._suppressCascade = false;
230                                self._loadingLookup = false;
231                                self.LookupPerformed(true);
232                                RemoveSpinner('.vehicle-form');
233                            }
234                        });
235                    });
236                } else {
237                    self.LookupErrorTitle(result.errorTitle);
238                    self.LookupErrorMessage(result.errorMessage);
239                    self.LookupPerformed(false);
240                    self.LogVehicleLookupFailed(result.failureReason || 'not_found');
241                    RemoveSpinner('.vehicle-form');
242                }
243            },
244            error: function () {
245                self.LookupErrorTitle(localizationHelper.error.genericError);
246                self.LookupErrorMessage('');
247                self.LookupPerformed(false);
248                self.LogVehicleLookupFailed('service_error');
249                RemoveSpinner('.vehicle-form');
250            }
251        });
252    };
253
254    self.LogVehicleLookupFailed = function (failureReason) {        
255        if (self.Mode() !== 'plate' && self.Mode() !== 'vin') return;        
256        logEvent(analyticsEvent.enro_vehicle_lookup_failed, {
257            lookup_method: self.Mode(),
258            reason: failureReason,
259            enrollment_id: window.onlineInstallAnalyticsContext.enrollment_id
260        });
261    };
262
263    self.LogVehicleLookupAttempt = function () {
264        if (typeof logEvent !== 'function' || typeof analyticsEvent === 'undefined') return;
265        if (self.Mode() !== 'plate' && self.Mode() !== 'vin') return;
266
267        const analyticsContext = window.onlineInstallAnalyticsContext || {};
268        logEvent(analyticsEvent.enro_vehicle_lookup_attempt, {
269            lookup_method: self.Mode(),
270            enrollment_id: analyticsContext.enrollment_id || ''
271        });
272    };
273
274    self.Init = function (mode, plateState, plateNumber, vin, year, make, model, color, errorTitle, errorMessage) {
275        var stateItems = self.States.map(function (s) {
276            return { text: s.text, value: s.value };
277        });
278        self.States = stateItems;
279
280        self._suppressCascade = true;
281
282        if (mode) self.Mode(mode);
283        if (plateState) self.PlateState(plateState);
284        if (plateNumber) self.PlateNumber(plateNumber);
285        if (vin) self.Vin(vin);
286
287        self.LoadColors(function () { self.Color(color) });
288
289        if (mode === 'manual') {
290            self.LoadYears(function () {
291                if (year) self.Year(year);
292                if (year && make) {
293                    self.LoadMakes(year, function () {
294                        self._suppressCascade = true;
295                        self.Make(make);
296                        if (year && make) {
297                            var selected = self.MakeOptions().find(function (m) { return m.name === make; });
298                            if (selected) {
299                                self.LoadModels(year, selected.id, function () {
300                                    self._suppressCascade = true;
301                                    if (model) self.VehicleModel(model);
302                                    if (color) self.Color(color);
303                                    self._suppressCascade = false;
304                                });
305                            } else {
306                                self._suppressCascade = false;
307                            }
308                        } else {
309                            self._suppressCascade = false;
310                        }
311                    });
312                } else {
313                    self._suppressCascade = false;
314                }
315            });
316        } else if (year && make && model) {
317            self.YearOptions([year]);
318            self.MakeOptions([{ id: '', name: make }]);
319            self.ModelOptions([{ id: '', name: model }]);
320            self.Year(year);
321            self.Make(make);
322            self.VehicleModel(model);
323            if (color) self.Color(color);
324            self.LookupPerformed(true);
325            self._suppressCascade = false;
326        } else {
327            self._suppressCascade = false;
328        }
329
330        if (errorTitle) self.LookupErrorTitle(errorTitle);
331        if (errorMessage) self.LookupErrorMessage(errorMessage);
332    };    
333}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.