PageSourceSearch

https://member.ushcc.com/js/formUtils.js

js ushcc.com collected 2026-10-02 04:17:25 UTC 14,039 bytes, 341 lines download raw bytes

1'use strict'
2
3/**
4 * 
5 * Dependencies:  Validator object (validator.js) for doing basic validtion
6 */
7const formUtils = function(){
8
9    const getContainer = function(options){
10        let container;
11
12        if (options.container){
13            container = options.container;
14        }
15        else if (options.containerSelector) {
16            container = $(options.containerSelector);
17        }
18        else
19            container = $("body");
20
21        return container;
22    }
23
24
25    //#region objectfiller
26        
27    const objectFiller = {};
28
29    /**
30     *  Fills-out an objec from html fields
31     * @param {*} options 
32     * containerSelector:  string defining the container.
33     * container:          jquery element, usually a div.  Either containereSelector or container need to be fed 
34     * skipSelector:       elements fulfilling this criteria won't be included on the object
35     * dataIdAttribute:    alternative identifier for fields, this is used on dynamic generated forms in which ids wouldn't be unique
36     * specialControlList : array of elements [{ name, is, get}]  that contain functions to fill-out object values out of controls like kendo.
37     *                      name:   Name of control, this is for developer reference only.
38     *                      is:     Function that returns true if an html control is processed as a special control.
39     *                      get:    Function used to get value fom control.
40     * @returns javascript object contianing fields
41     */
42    objectFiller.htmlToObject = function(options){        
43        const objectToFill = {};        
44        let selector = "input{notSelector}, select{notSelector}, textarea{notSelector}";
45        let notSelector = ""; 
46        const container = getContainer(options);
47        
48
49        if (options.skipSelector){            
50            notSelector += (notSelector === "" ? "" : ", ")  + ":not(" + options.skipSelector + ")";
51        }
52        selector = selector.replace(/{notSelector}/g, notSelector);
53
54        container.find(selector).each(function(i,e) {
55            const input = $(e);
56            const type = input.prop("type");
57            let id;
58            const name = input.attr("name");
59            let isInputChecked;
60            
61            if (options.dataIdAttribute){
62                id = input.data(options.dataIdAttribute);            
63            }
64            else{
65                id = input.attr("id");            
66            }
67
68            //begin: test and get value out of special control list (this is the list of controls that is injected)
69            let valueOptions = {};
70            if (options.specialControlList && options.specialControlList.length > 0){
71                valueOptions =  testAndGetValueFromSpecialElementList(input, options.specialControlList);
72                if (valueOptions.foundInSpecialElementList)
73                    objectToFill[id] = validator.stripHTMLTags(valueOptions.value);
74            }
75            if (valueOptions.foundInSpecialElementList)
76                return;
77            //end
78
79            if (type==="file" || type==="button"  || type==="submit" ||  type==="color"  
80                ||  type==="image"  ||  type==="reset" || type==="search" 
81                || ((!id  || id === "") && type !== "radio") ){
82                return;
83            }
84
85            //uses boolean 'checked' attribute to get selected radio and stores whatever value is stored on the control
86            if(type === "radio" ) {
87                
88                if (input.is (":checked")){
89                    if (options.dataIdAttribute){
90                        objectToFill[id] = input.val();    
91                    }
92                    else{
93                        objectToFill[name] = input.val();    
94                    }
95                }
96                
97            }
98
99            //uses boolean 'checked' attribute as values for checkboxes
100            else if(type === "checkbox") {
101               isInputChecked = input.is(":checked");
102                objectToFill[id] = isInputChecked ? "y" : "n";
103            }
104                                    
105            else { //all other elements for which 'val' applies, select and all input type={inputtype} 
106
107                //for numeric inputs, set value to 'null' if value is empty
108                const isNumber = input.prop("type") === "number";
109
110                if (isNumber && input.val() === ""){
111                    objectToFill[id] = "null";
112                }
113                else
114                    //objectToFill[id] = input.val();
115                    objectToFill[id] = validator.stripHTMLTags(input.val());
116            }
117        });
118
119        return objectToFill;
120    }
121    
122
123 
124
125    /**
126     * Fills-out html elements from a javascript object
127     * @param {*} options 
128     * containerSelector:  string defining the container, optional
129     * container:          jquery element, usually a div, optional, 
130     * data:               Data to fill-out
131     * dataIdAttribute:    alternative identifier for fields, this is used on dynamic generated forms in which ids wouldn't be unique    
132     * specialControlList : array of elements [{ name, is, get}
132]  that contain functions to fill-out object values out of controls like kendo.
133     *                      name:   Name of control, this is for developer reference only.
134     *                      is:     Function that returns true if an html control is processed as a special control.
135     *                      set:    Function used to get value fom control.      
136     * @returns     
137     */
138    objectFiller.objectToHtml = function(options){
139
140        const container = getContainer(options);
141        
142        for (const prop in options.data) {
143    
144            let elementName = "";
145            let elementById;
146            let elementByName; 
147            let alreadyProcessedBySpecialElement = false;
148
149            //begin: test and get value out of special control list (this is the list of controls that is injected)
150            let valueOptions = {};
151            let scElement;
152            if (options.specialControlList && options.specialControlList.length > 0){
153                if (options.dataIdAttribute)
154                    scElement = container.find("["+ options.dataIdAttribute + "=" + prop + "]");    
155                else
156                    scElement = container.find("#" + prop);
157                valueOptions =  testAndSetValueFromSpecialElementList($(scElement), options.data[prop], options.specialControlList);
158                if (valueOptions.foundInSpecialElementList) 
159                    alreadyProcessedBySpecialElement = true;
160            }
161            //end
162
163
164            if (options.dataIdAttribute){
165                elementById = container.find("input["+ options.dataIdAttribute + "=" + prop + "], textarea["+ options.dataIdAttribute + "=" + prop + "], select["+ options.dataIdAttribute + "=" + prop + "]");    
166                elementByName = [];
167            }
168            else{
169                elementByName = container.find("input[name='" + prop + "'], textarea[name='" + prop + "'], select[name='" + prop + "']");
170                elementById = container.find("#" + prop);
171            }
172            
173            if (Object.prototype.hasOwnProperty.call(options.data, prop) && (elementById.length || elementByName.length) && !alreadyProcessedBySpecialElement) {
174                
175                const input = $(elementById);                
176                if (!input.length){
177                    input = $($(elementByName)[0]);//assuming radiobutton
178                    elementName = input.prop("name");
179                }                    
180                if (!input)
181                    return; //html element counterpart does not exist
182    
183                const type = input.prop("type");
184    
185                if(type === "radio" ) {
186                    if (options.data[prop]){
187                        if (options.dataIdAttribute ){
188                            container.find("input["+ options.dataIdAttribute + "=" + prop + "][value=" + options.data[prop] + "]").prop('checked', true);
189                        }
190                        else{
191                            $("input[name=" + elementName + "][value=" + options.data[prop] + "]").prop('checked', true);
192                        }    
193                    }
194                }
195    
196                else if(type === "checkbox") {
197                    if(options.data[prop] ==="y")
198                        input.prop("checked", true);
199                }
200
201                else { //all other elements for which 'val' applies, select and all input type={inputtype} 
202                    input.val(validator.stripHTMLTags(options.data[prop]));
203                }    
204    
205            }
206        }
207    }
208    
209    function testAndGetValueFromSpecialElementList(element, specialControlList){
210        let returnOptions = { value: null, foundInSpecialElementList:false};
211        specialControlList.forEach(function(specialControl){
212            if (specialControl.isSpecialElement(element)){
213                returnOptions.value = specialControl.get(element);
214                returnOptions.foundInSpecialElementList = true;
215            }
216        });
217        return returnOptions;
218    }
219
220    function testAndSetValueFromSpecialElementList(element, value,  specialControlList){
221        let returnOptions = { foundInSpecialElementList:false};
222        specialControlList.forEach(function(specialControl){
223            if (specialControl.isSpecialElement(element)){
224                specialControl.set(element, value);
225                returnOptions.foundInSpecialElementList = true;
226            }
227        });
228        return returnOptions;
229    }
230
231    //#endregion
232
233
234
235    //#region validation
236
237    /**
238     *     main validation function, it includes validations for lists and real file components.
239     * @param {*} options 
240     *          containerSelector:  String defining the form container.  
241     *          container:          Jquery element, usually a div.  Eitehr container or containerSelector parameter needs to be supplied
242     *          dataIdAttribute:    Optional alternative id for dynamically generated forms having no unique ids
243     *          showFeedback:       Shows feedback . .error css class is used to highlight controls that do not pass validation     
244     * @returns true or false     
245     */
246    const validate = function(options){
247
248        options.feedBack = options.showFeedback;
249
250        const okBasicValidation = validator.basicValidate(options);
251        const okValidationList = validateLists(options);  
252        const okValidationRFFileViewer = validateRFVFileViewers(options);  
253
254        const okValidation = okBasicValidation && okValidationList && okValidationRFFileViewer;
255            
256        return okValidation;
257    }
258
259    /**
260     *     validates required checkbox and radio lists 
261     *      by looking for elements having the 'listRequired' class assigned
262     * @param {*} options 
263     *  containerSelector:  string definig the container, optional
264     *  container:          jquery element, usually a div, optional, 
265     *  dataIdAttribute:    optional alternative id for dynamically generated forms having no unique ids
266     * @returns  true or false
267     */
268    function validateLists(options){
269        let isValid = true;
270        const container = getContainer(options);
271
272        container.find("div[data-list-required=true]:visible").each(function (i, e) {
273            const container = $(e);
274            const validationGroup = container.data("validationGroup");;
275            const numElementsSelected = container.find("input[data-validation-group='" + validationGroup + "']:checked").length;
276
277            if (numElementsSelected === 0){
278                if (options.feedBack)
279                    container.addClass("invalid").attr("title", "Please select at least one option")
280                isValid = false;
281            }
282            else{
283                container.removeClass("invalid").attr("title", null);
284            }
285        });
286
287        return isValid;
288    }
289
290    /**
291     * look for any RF components (Divs having 'fileViewer' class)
292     * @param {*} options 
293     * @returns 
294     */
295    function validateRFVFileViewers(options){
296        let isValid = true;
297        const container = getContainer(options);
298
299        container.find("div.fileViewer.required:visible").each(function (i, e) {
300            const container = $(e);
301            const numFiles = container.find(".rf-row").length;                
302
303            if (numFiles === 0){
304                if (options.feedBack)
305                    container.addClass("invalid").attr("title", "File is required")
306                isValid = false;
307            }
308            else{
309                container.removeClass("invalid").attr("title", null);
310            }
311        });
312
313        return isValid;
314    }
315
316    //#endregion
317
318
319    function cleanValidationErrorMarkers(options){
320        $(options.containerSelector + " .invalid").removeClass("invalid").attr("title");
321        // $(options.containerSelector + " input").removeClass("invalid").attr("title");
322        // $(options.containerSelector + " textarea").removeClass("invalid").attr("title");
323        // $(options.containerSelector + " select").removeClass("invalid").attr("title");
324    }
325
326
327    $(document).ready(function(){
328        //clears invalid visual clue on elements whenever a user modifies them
329        $(document).on("change", "select,input,textarea", function(){ 
330            $(this).removeClass("invalid").attr("title", null);
331        });
332    
333    });
334
335    return {
336        objectFiller,
337        validate,
338        cleanValidationErrorMarkers
339    }
340
341}();

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.