PageSourceSearch

https://albanyjcc.org/cms3t/res/js/mw.forms.js

js albanyjcc.org collected 2026-09-29 10:05:15 UTC 36,534 bytes, 1,409 lines download raw bytes

1//ToDo: Redo everything!!!
2
3// Simple cache to do not monitor same values
4var upload_procesing_cache = {};
5
6/** //** ----= setFormsSubmit	 =----------------------------------------------\**//** \
7*
8* 	Sets forms to have submit control. Applies to forms with set onsubmit attribute.
9*
10* 	@param	MIXED element	- jQuery selector to search forms within
11*				  (set to speed up search).
12*
13* 	@return	bool		- Always FALSE.
14*
15\**//** ------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/
16function setFormsSubmit ( element ) {
17
18	if ( element && !(element instanceof jQuery) )
19		element = jQuery(element);
20
21	// Searching for forms, only with onsubmit attribute
22	var forms = ( element )? jQuery(element).find('FORM[onsubmit]') : jQuery('FORM[onsubmit]');
23
24	// Processing each form for submit control
25	forms.each( function() {
26
27		var form	= jQuery(this);
28		var form_id	= form.attr('id');
29
30		// Checking if form has no submit already
31		// ToDo: More complex check
32		if ( form.find('[type=submit]').length ) return;
33
34		// If still here - form have no submit, but have onsubmit attribute
35		// So adding hidden submit control
36		// Adding on top, to do not mess with winContents and layout
37		form.prepend('<input type="submit" style="display: none;" />');
38
39		if ( !form_id ) return;
40
41		// If element is window with footer buttons related to form (by id) - set them to submit form too.
42		element.find('.winFooter A[rel=' + form_id + ']')
43			.addClass('hi')
44			.unbind('click')
45			.click( function () {
46
47				jQuery('#' + form_id).submit();
48
49				return false;
50			} ); //FUNC onClick
51
52	}); //FUNC each form
53
54	return false;
55} //FUNC setFormsSubmit
56
57/** //** ----= mwUpdateSelector	=--------------------------------------------------------------------------------------\**//** \
58*
59*	Updates selector options with items given. Optionally marks certain items as selected.
60*
61\**//** ---------------------------------------------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/
62function mwUpdateSelector (input, options, selected) {
63
64	input = _jq(input);
65
66	// Removing all styles from selector
67	var sel = unstyleInput(input);
68
69	// Cleanning old options
70	sel.find('OPTION').remove();
71
72	// Adding given options
73	// Supporting maps if one is given
74	if ( isClass(options, 'Map') ) {
75
76
77	/**/	// Using method to iterate, to stay compatible with older JS parsers
78		options.forEach( function ( $val, $key ) {
79			jQuery('<option value="' + $key + '">' + $val + '</option>').appendTo(sel);
80		}); //forEach
81
82	/*/
83		for ( var i of options )
84			jQuery('<option value="' + i[0] + '">' + i[1] + '</option>').appendTo(sel);
85	/**/
86	} //IF map given
87
88	else {
89
90		for ( var i in options )
91			jQuery('<option value="' + i + '">' + options[i] + '</option>').appendTo(sel);
92
93	} //IF regular data object
94
95	// Setting selected values if given some
96	if ( selected )
97		setValue_Select(sel.get(0), selected);
98
99	// Restyling input back
100	styleDialog( sel.parent() );
101
102	// Triggering update
103	sel.trigger('update');
104
105	return false;
106} //FUNC mwUpdateSelector
107
108/** //** ----= filterSelect	 =----------------------------------------------\**//** \
109*
110* 	Filters styled selector with values.
111*
112* 	@param	MIXED	select	- Valid jQuery element selector.
113* 				  Sould point to .mwinput.List control.
114*
115* 	@param	string	filter	- Comma separated filters.
116* 	@return	bool		- Always FALSE.
117*
118\**//** ------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/
119function filterSelect ( select, filter ) {
120
121	if ( !filter ) {
122//		jQuery(select).find('.Item').fadeIn(200);
123		jQuery(select).find('.item').show();
124		return false;
125	} //IF empty filter
126
127	// Trimming filters, and composing regex
128	var filter	= strToArray(filter, ',');
129	var reg		= new RegExp('(' + filter.join('|') + ')', 'i');
130
131	jQuery(select + ' .item').each( function () {
132		var el		= jQuery(this);
133
134		var title	= el.find('div').first().html();
135
136		if ( reg.test(title) )
137			el.show();
138		else
139			el.hide();
140
141	}); //jQuery each
142
143	return false;
144} //FUNC filterSelect
145
146/** //** ----= selectAddItem	 =----------------------------------------------\**//** \
147*
148* 	Adds items to target styled selector.
149*
150* 	@param	MIXED	select	- Valid jQuery element selector.
151* 	@param	string	values	- Comma separated values.
152* 	@return	bool		- Always FALSE.
153*
154\**//** ------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/
155function selectAddItem ( select, values, checked ) {
156
157	if ( !values ) return false;
158
159	var select	= _jq(select);
160
161	checked = ( checked )? ' selected="selected"' : '';
162
163	// If input given as value, it should be cleaned after all
164	var relate = false;
165	if ( values instanceof jQuery ) {
166		relate = values;
167		values = relate.val();
168	} //IF parent element given
169
170	if ( isStr(values) ) {
171		var tmp	= strToArray(values, ',');
172
173		// Reindexing to have meaningfull keys to use as values
174		// Normally associated arrays or objects should be passed
175		values = {};
176
177		for ( var i in tmp )
178			values[tmp[i]] = tmp[i];
179
180	} //IF string given
181
182	// Before have to save selected inputs, cuz unstyle will reset all to beginning
183	var checks	= [];
184	select.find('input:checked').each( function () {
185		checks.push( jQuery(this).val() );
186	}); //FUNC each.callback
187
188	// Destyling select for easy add new inputs
189	select = unstyleInput(select);
190
191	// Resetting options to to new setting
192	select.find('option').each( function () {
193
194		var el = jQuery(this);
195		if ( checks.indexOf( el.val() ) != -1 )
196			el.attr('selected', 'selected');
197		else
198			el.removeAttr('selected');
199
200	}); //FUNC each.callback
201
202	for ( var i in values ) {
203		select.prepend('<option value="' + i + '"' + checked + '>' + values[i] + '</option>');
204	} //FOR each value
205
206	// Styling input back again
207	styleDialog(select.parent());
208
209	return false;
210} //FUNC selectAddItem
211
212/** //** ----= inputClassString	 =----------------------------------------------\**//** \
213*
214* 	Takes source element, and type classes. Prepares full class and style attributes.
215*
216* 	@param	object	el		- Source input jQuery object.
217* 	@param	string	typeClass	- Additional classes to add.
218* 	@return	string			- Attributes to add to element.
219		bool			- FALSE if no modification necessary.
220*
221\**//** ------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/
222function inputClassString(el, typeClass) {
223
224	// If already styled - nothing to do again
225	if ( el.hasClass('mw') ) return false;
226
227	// Saving source to allow fast unstyle
228	el.data('source', getOuterHTML( el.get(0) ));
229
230	// Getting existing attributes
231	var cls		= el.attr('class');
232
233	// Getting other transferrable attributes
234	var $attr	= {'class' : ''};
235	var $aList	= ['style', 'size', 'data-prefix', 'data-suffix'];
236	for ( var $i in $aList )
237		$attr[ $aList[$i] ] = el.attr($aList[$i]);
238
239	var styles	= el.attr('style');
240
241	// Composing classes
242	var ctmp	= ['mwInput', typeClass, cls];
243
244	var name	= el.attr('name');
245	if ( name ) {
246		name	= name.replace(/[\[\]]/g, '');
247		ctmp.push('name-'+name);
248	} //IF name
249
250	// Storing class as attribute
251	$attr['class'] = ctmp.join(' ').trim();
252
253	// Processing results
254	var $res = '';
255	for ( var $i in $attr )
256		if ( !isEmpty($attr[$i]) )
257			$res += ' '+$i+'="'+$attr[$i]+'"';
258
259	// Cleaning source attributes
260	el[0].className = '';
261
262	for ( var $i in $aList )
263		el.removeAttr($aList[$i]);
264
265	// Adding styled marker
266	el.addClass('mw');
267
268	return $res;
269} //FUNC inputClassString
270
271/** //** ----= styleDialog	 =----------------------------------------------\**//** \
272*
273* 	Applies style to all inputs childs to specified element.
274*
275* 	@param	MIXED	el	- Valid jQuery element selector.
276* 	@return	bool		- Always FALSE.
277*
278\**//** ------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/
279function styleDialog ( dialog ) {
280
281	dialog = _jq(dialog);
282
283// ---- TEXT ----
284
285	dialog.find('INPUT[type=text], INPUT[type=search], INPUT[type=password], INPUT[type=email], INPUT[type=date], INPUT[type=number], INPUT[type=tel], INPUT[type=url]').not('[data-input="table"]').each( function () {
286
287		var el		= jQuery(this);
288
289		// Cleaning errors state on load
290		//el.closest('.mwInput').removeClass('Error');
291
292		// Checking if some of subcontrol classes are set and reading sub class
293		var subs = false;
294		var $sClass = ['plus', 'go', 'ok'];
295		for ( var $i in $sClass )
296			if ( el.is('.'+$sClass[$i]) )
297				subs = $sClass[$i];
298
299		// Compatabilty with renamed sub
300		if ( subs == 'go' )
301			subs = 'ok';
302
303		var tclass	= 'text';
304		if ( subs ) tclass += ' wSub';
305
306		var attr	= inputClassString(el, tclass);
307		if ( !attr ) return;
308
309		var wrap = jQuery('<div ' + attr + '></div>');
310		el.wrapAll(wrap);
311
312		// Researching wrap
313		wrap = el.closest('.mwInput');
314
315		// Adding some common subcontrols if set
316		if ( subs ) {
317
318			var sub		= jQuery('<div class="subcontrol button hi icon light '+ subs+'"></div>').insertBefore(el);
319			var click	= el.attr('onclick');
320
321			if ( click )
322				sub.attr('onclick', click);
323
324			el.removeAttr('onclick');
325		} //IF is Plus
326
327		// Initiating date picker
328		Date.format = 'yyyy-mm-dd';
329		if ( wrap.is('.date') ) {
330			el.datePicker({
331				clickInput	: true,
332				createButton	: false,
333				verticalOffset	: 26,
334				startDate	: '2000-01-01'
335			});
336		} //IF date input
337
338		// Search input is special
339		// Then adding icon and subcontrol
340		// This allows better compatability than regular search, and finer styles control
341		// Skipping manually added icons
342		if ( wrap.is('.search:not(.icon)') ) {
343
344			// Adding search icon on left (it's already search, so just adding icon class)
345			wrap.addClass('icon left');
346
347			// Padding right is exactly same as left
348			wrap.css( 'padding-right', wrap.css('padding-left') );
349
350			// Adding clear subcontrol
351			var $sub = jQuery('<div class="subcontrol icon right declined" style="display:none"></div>
351').appendTo(wrap);
352
353			// Adding change event on input
354			el.on('keyup.mwInput.search', function () {
355
356				if ( this.value )
357					$sub.show();
358				else
359					$sub.hide();
360
361			}); //On change
362
363			// Adding clear action
364			$sub.on('click.mwInput.search.clear', function () {
365
366				el.val('');
367				$sub.hide();
368
369				el.trigger('keyup');
370
371			}); //on click
372
373
374		} //IF search found
375
376		// Ensuring input size for prefix/suffix
377		if ( wrap.is('[data-prefix], [data-suffix]') ) {
378
379		} //IF pfx
380
381		// Text inputs should select on forcus
382		el.focus( function () { this.select() } );
383
384
385		/*/
386		// Adding required check
387		if ( wrap.hasClass('required') ) {
388
389			el.keyup( function () {
390				var e = jQuery(this);
391				if ( e.val().trim() )
392					e.closest('.mwInput').removeClass('Error');
393				else
394					e.closest('.mwInput').addClass('Error');
395			});
396
397		} //IF required
398		/**/
399
400	}); //jQuery each text input
401
402// ---- TEXTAREA ----
403
404	dialog.find('TEXTAREA').not('.mw, .tinyMCE, .mwTinyMCE, .richEdit').each( function () {
405		var $el = jQuery(this);
406
407		$el.addClass('multiline');
408
409		var $attr = inputClassString($el, 'textarea');
410		if ( !$attr ) return;
411
412		$el.wrapAll('<div ' + $attr + '></div>');
413
414		// Researching wrapper
415		var $wrap	= $el.parent();
416
417		// 100% size inputs are marked with class instead
418		// and triggers default size for fallbacks
419		if ( $wrap.attr('size') == '100%' )
420			$wrap.addClass('fullHeight').removeAttr('size');
421
422		// Adding default height
423		if ( !$wrap.attr('size') )
424			$wrap.attr('size', '3');
425
426	}); //jQuery each textarea input
427
428	dialog.find('TEXTAREA.richEdit').not('.mw').each( function () {
429
430		// Doing nothing if no tinyMCE defined on page
431		// No fallbacks, as developer should see that smth went wrong
432		if ( typeof(tinyMCE) == 'undefined' )
433			return;
434
435		var el = jQuery(this);
436
437		el.addClass('multiline');
438
439		// Marking element as initiated
440		el.addClass('mw');
441
442		// 100% size inputs are marked with class instead
443		// and triggers default size for fallbacks
444		if ( el.attr('size') == '100%' )
445			el.addClass('fullHeight').removeAttr('size');
446
447		// Adding default height
448		if ( !el.attr('size') )
449			el.attr('size', '5');
450
451		// Giving it small delay, to let freshly loaded windows to cool a bit.
452		setTimeout( function () {
453			mwTinyMCE().init(el);
454		}, 10);
455
456	}); //jQuery each textarea input
457
458// ---- BUTTONS ----
459
460//	dialog.find('BUTTON, INPUT[type=button], INPUT[type=submit]').each( function () {
461	dialog.find('INPUT[type=button], INPUT[type=submit]').each( function () {
462
463		var el = jQuery(this);
464
465		// Quickly skipping tinyMCE buttons
466		// Bit dirty, but tiny is supported natively
467		// ToDo: init styles from original input instead (would come naturally once proper mwForms are implemented)
468		if ( el.parent().is('.mce-btn') )
469			return;
470
471		var attr = inputClassString(el, 'button');
472		if ( !attr ) return;
473
474		el.wrapAll('<div ' + attr + '></div>');
475
476		// Sumulating active for parent
477		el
478			.bind('mousedown', function () {
479				jQuery(this).parent().addClass('active');
480			}) //FUNC onMouseDown
481			.bind('mouseup', function () {
482				jQuery(this).parent().removeClass('active');
483			}) //FUNC onMouseUp
484		; //jQuery element
485	}); //jQuery each textarea input
486
487	dialog.find('INPUT[type=image]').each( function () {
488		var el = jQuery(this);
489
490		var attr = inputClassString(el, 'button image');
491		if ( !attr ) return;
492
493		el.wrapAll('<div ' + attr + '></div>');
494
495		// Sumulating active for parent
496		el
497			.bind('mousedown', function () {
498				jQuery(this).parent().addClass('active');
499			}) //FUNC onMouseDown
500			.bind('mouseup', function () {
501				jQuery(this).parent().removeClass('active');
502			}) //FUNC onMouseUp
503		; //jQuery element
504	}); //jQuery each textarea input
505
506// ---- SELECT ----
507
508	dialog.find('SELECT').not('.checkList, .radioList, .browseButton, .selectEx').each( function () {
509		var el = jQuery(this);
510
511		if ( el.is('SELECT[multiple], SELECT[size]') ) {
512
513			el.addClass('multiline');
514
515			var attr = inputClassString(el, 'multiple');
516			if ( !attr ) return;
517
518			el.wrapAll('<div ' + attr + '></div>');
519
520			// Researching wrapper
521			var $wrap	= el.parent();
522
523			// 100% size inputs are marked with class instead
524			// and triggers default size for fallbacks
525			if ( $wrap.attr('size') == '100%' )
526				$wrap.addClass('fullHeight').removeAttr('size');
527
528			// Adding default height
529			if ( !$wrap.attr('size') )
530				$wrap.attr('size', '3');
531
532		} //IF multiselect
533		else {
534
535			var nowidth = el.hasClass('nowidth');
536
537			var attr = inputClassString(el, 'select');
538			if ( !attr ) return;
539
540		// ---- Calculating selector min width ----
541
542			var width = '';
543
544			if ( !nowidth ) {
545				var tmp = el.clone();
546				tmp.appendTo('BODY');
547				width = tmp.width() + 30;
548				tmp.remove();
549
550				width = ' style="min-width : ' + width + 'px"';
551			} //IF need width
552
553			el.wrapAll('<div ' + attr + '></div>');
554			el.addClass('hidden');
555
556			var val = el.find('OPTION:selected').text();
557
558			el.before('<div class="subcontrol icon gray dropdown"></div>');
559			el.before('<div class="value"' + width + '>
559' + val + '</div>');
560
561			el.on('change update', function () {
562				el.prev('.value').html( el.find('OPTION:selected').text() );
563			}); //jQuery onChange
564
565		} //IF regular select
566
567	}); //jQuery each select input
568
569/**/
570// ---- CHECKLIST and RADIOLIST ----
571
572//	dialog.find('SELECT.checkList, SELECT.radioList').not('.old').each( function () {
573	dialog.find('SELECT.checkList.new, SELECT.radioList.new').each( function () {
574
575		var $input	= jQuery(this);
576
577	// ---- Defaults -----
578
579		// Checklist forces multiselect
580		if ( $input.is('.checkList') )
581			$input.attr('multiple', 'multiple');
582
583		// Adding default height
584		if ( !$input.attr('size') ) {
585
586			if ( $input.is('[multiple], .checkList, .radioList') )
587				$input.attr('size', '5');
588			else
589				$input.attr('size', '1');
590
591			// For mobiles - size is always 1
592			if ( $input.is('.noMobile') && isTouchScreen() )
593				$input.attr('size', '1');
594
595		} //IF autodeciding on size
596
597		// Preparing attributes
598		var $attr	= inputClassString($input, '');
599		if ( !$attr ) return;
600
601	// ---- Creating container element ----
602
603		$input.wrapAll('<div ' + $attr + '></div>');
604
605		// Researching wrapper, for later use
606		var $wrap	= $input.parent();
607
608		// Flagging input type: inline/multiline
609		if ( $wrap.attr('size') != '1' )
610			$wrap.addClass('multiline');
611
612		// 100% size inputs are marked with class instead
613		// and triggers default size for fallbacks
614		if ( $wrap.attr('size') == '100%' )
615			$wrap.addClass('fullHeight').removeAttr('size');
616
617	// ---- Model ----
618
619		// Initiating selector model
620		var $select = $input.mwSelectInput();
621
622	}); //jQuery each morweb selector input
623
624	dialog.find('SELECT.checkList, SELECT.radioList').not('.new').each( function () {
625//	dialog.find('SELECT.checkList.old, SELECT.radioList.old').each( function () {
626
627		var sel = jQuery(this);
628
629		sel.addClass('multiline');
630
631		if ( sel.is('.checkList') )
632			sel.attr('multiple', 'multiple');
633
634		var attr = inputClassString(sel, 'list');
635		if ( !attr ) return;
636
637	// ---- Creating container and subcontainer elements ----
638
639		var el		= jQuery('<div ' + attr + '><div class="list"></div></div>');
640		var items	= el.find('.list');
641
642		// 100% size inputs are marked with class instead
643		// and triggers default size for fallbacks
644		if ( el.attr('size') == '100%' )
645			el.addClass('fullHeight').removeAttr('size');
646
647		// Adding default height
648		if ( !el.attr('size') )
649			el.attr('size', '5');
650
651	// ---- Saving source ----
652
653		// Selector itself will be replaced, so we need to save source in separate hidden element which will not affect nothing
654
655		var source_data	= sel.data('source');
656
657		var source	= jQuery('<input type="hidden" class="mw">');
658		source.data('source', source_data);
659		source.appendTo(el);
660
661	// ---- Transferring hint ----
662
663		var hint	= sel.attr('hint');
664		if ( hint )
665			items.attr('hint', hint);
666
667	// ---- Composing common attributes ----
668
669		var radio	= el.hasClass('radioList');
670		var name	= sel.attr('name');
671
672		// Checkboxes should be arrays
673		// Not doing for selects that alrady had this
674		if ( !radio && name && !name.endsWith('[]') )
675			name += '[]';
676
677		// Input type
678		var type = ( radio )? 'radio' : 'checkbox';
679
680	// ---- Processing sub controls ----
681
682		sel.find('OPTION').each( function () {
683
684			var op		= jQuery(this);
685			var title	= op.html();
686
687		// ---- Parsing title for special things ----
688
689			// Column
690			var col		= '';
691			var d		= title.indexOf('|');
692			if ( d >= 0 ) {
693				col = title.substr(d + 1);
694				title = title.substr(0, d) + '<div class="col">' + col + '</div>';
695			} //IF divider come
696
697			var $icon	= op.attr('data-icon');
698			if ( $icon )
699				$icon = '<div class="icon" style="background-image: url(' + $icon + ');"></div>';
700
701
702			// Value/checked
703			var val		= op.val();
704			var checked	= op.attr('selected');
705
706			title		= $icon + '<div class="title">' + title + '</div>';
707
708			var titem	= jQuery(title);
709
710			var input	= jQuery('<input type="' + type + '" class="meta" name="' + name + '" value="' + val + '" />');
711			if ( checked ) input.attr('checked', 'checked');
712
713			// Setting up actions
714			var actions	= ['onclick', 'onchange', 'ondblclick'];
715			for ( var i in actions )
716				input.attr(actions[i], sel.attr(actions[i]) );
717
718			input.change( function () {
719
720				var check = this.checked;
721
722				var el = jQuery(this);
723
724				if ( check ) {
725					el.parent().addClass('selected icon hi left');
726				} else { //IF checked
727					el.parent().removeClass('selected icon hi left')
728				} //IF not checked
729
730				if ( this.type == 'radio') {
731					if ( this.checked ) {
732						jQuery(this)
733							.parents('.mwInput.list')				// Searching parent container
734							.find('INPUT[type="radio"][name="' + this.name + '"]')	// 
734Searching all items
735							.not(this)						// Excluding self
736							.each( function () {					// Triggering change on each
737								jQuery(this).change();
738							}); //each radio
739					} //IF got cheked state
740				} //IF radio
741
742			}); //jQuery onChange
743
744			var $itemClass	= 'item';
745			var $itemStyle	= '';
746
747			if ( checked ) $itemClass+=' selected icon hi left';
748/*/
749			var $src	= op.attr('data-icon');
750			if ( $src ) {
751				$itemClass += ' icon';
752				$itemStyle = 'background-image: url(' + $src + ');';
753			} //IF class
754/**/
755
756			$itemClass = $itemClass ? ' class="' + $itemClass + '"' : '';
757			$itemStyle = $itemStyle ? ' style="' + $itemStyle + '"' : '';
758
759			var item	= jQuery('<div' + $itemClass + $itemStyle + '></div>');
760			item.append(titem).append(input);
761
762			item.appendTo(items);
763		}); //jQuery each option
764
765		sel.replaceWith(el);
766	}); //jQuery each multiselect input
767
768	// ---- CHECKBOX and RADIO ----
769
770	dialog.find('INPUT[type="checkbox"], INPUT[type="radio"]').not('.meta').each( function () {
771
772		var el		= jQuery(this);
773
774		// Checking if custom titles are set
775		var custom	= el.attr('cap');
776
777		var attr = inputClassString(el, 'checkbox' + ((custom)? ' custom' : ''));
778		if ( !attr ) return;
779
780// ---- Processing custom titles ----
781
782		// Webkit browsers require smth to have inside to propertly align, so setting nbsp as default
783		var on		= '&nbsp;';
784		var off		= '&nbsp;';
785
786		if ( custom ) {
787
788		//	el.removeAttr('cap');
789
790			custom = custom.split('|');
791
792			var on	= custom[0];
793			var off	= (custom[1])? custom[1] : custom[0];
794
795		} //IF title set
796
797	// ---- Wrapping layout structure ----
798
799		el.wrapAll('<div ' + attr + '></div>');
800		el.addClass('hidden');
801
802		el.before('<div class="icon hi left">_</div>');
803
804	// ---- Applying change function ----
805
806		el.change( function () {
807
808			var check = this.checked;
809
810			if ( check ) {
811				el.parent().addClass('checked');
812				el.prev().html(on).addClass('selected');
813				el.addClass('checked');
814			} else { //IF checked
815				el.parent().removeClass('checked')
816				el.prev().html(off).removeClass('selected');
817				el.removeClass('checked');
818			} //IF not checked
819
820		}); //jQuery onChange
821
822		// Initiating first time
823		el.change();
824
825	// ---- Radio buttins refresh fix ----
826
827		if ( this.type == 'radio' ) {
828
829			el.change( function () {
830
831				var radio = jQuery(this);
832
833				if ( this.checked ) {
834
835					// Searching neighbours via closest parent form. Fastest way. Usually there is form around.
836					radio.closest('FORM')
837						.find('INPUT[type="radio"][name="' + this.name + '"].checked')
838							.not(this).change();
839
840				} //IF got cheked state
841
842			}); //jQuery onChange
843
844		} //IF radio button
845
846	}); //jQuery each checbox and radio input
847
848// ---- FILES ----
849
850	dialog.find('INPUT[type=file]').each( function () {
851
852		var el = jQuery(this);
853
854		var attr = inputClassString(el, 'file');
855		if ( !attr ) return;
856
857		// Detecting SN if set, and applying it as uBar
858		var fid = el.attr('sn') || '';
859
860		if ( fid )
861			fid = ' uBar_' + fid;
862
863		// Preparing structure and layout
864		el.wrapAll('<div ' + attr + '></div>');
865
866		// Reading input wrapper
867		var $jWrap	= el.closest('.mwInput');
868
869		// Saving some properties
870		var $size	= el.attr('size') || $jWrap.attr('size') || 6;
871		var $preview	= el.attr('preview') || '';
872
873		// Preparing preview element, it goes first
874		var $jPreview	= jQuery('<div class="filePreview"></div>');
875		el.before($jPreview);
876
877		// Adding additional face wrapper for layout control
878		var $jFace	= jQuery('<div class="fileFace divider"></div>');
879
880 		// Adding title progress control inside face
881		var $jProgress	= jQuery('<div class="subcontrol hi fill progressFill' + fid + '"></div>').appendTo($jFace);
882		var $jTitle	= jQuery('<div class="fileName"></div>').appendTo($jFace);
883		var $jNum	= jQuery('<div class="num progressNum' + fid + '">&nbsp;</div>').appendTo($jFace);
884
885		// Attaching face
886		el.before($jFace);
887
888		// Preparing controls
889		// Upload/browse is unconditional, goes right after the face
890		var $jUpload	= jQuery('<div class="subcontrol button icon upload"></div>').insertAfter($jFace);
891
892		// Preparing download button, but not attaching it yet (this will be decided in updateFace() )
893		var $jDownload	= jQuery('<div class="subcontrol button icon download hi"></div>');
894
895		// Delete button present only if specified
896		// Always inserted last
897	//	var $jDelete	= jQuery('<div class="subcontrol button icon delete red"></div>');
898	//	$jDelete.insertBefore(el);
899
900		// Testing varying subcontrols count
901	//	el.before('<div class="subcontrol button icon ok"></div>');
902	//	el.before('<div class="subcontrol button icon delete"></div>');
903	//	el.before('<div class="subcontrol button icon download"></div>');
904	//	el.before('<div class="subcontrol button icon search"></div>');
905
906		// Autoconfiguring path for morweb editors
907		// This is supported only for inputs added through form editor, which are part of files section
908		// They should have gallery attribute, input should be part of window (this will indicate presence of morweb)
909		// ToDo: This validation should be done outside by forms editor/custom inputs
910
911		// Custom paths are still supported normally
912		var $fPath	= el.attr('data-path');
913		var $fGallery	= el.attr('gallery');
914		var $fPrivate	= el.attr('private') || 0;
915		var $fStorage	= $fPrivate ? 'download' : 'files';
916
917		// Path for gallery files are known
918		// Checking if running inside window
919		if ( !$fPath && $fGallery && el.closest('.mwWindow').length  ) {
920
921			// Default path is in gallery
922			var $fPath	= '/'+$fStorage+'/galleries/';
923
924			// Setting path as attribute
925			el.attr('data-path', $fPath);
926
927		} //If no path set
928
929		// Using dedicated face update function
930		function mwFileInputUpdateFace ($el) {
931
932			// Need jQuery
933			$el	= _jq($el);
934
935			// Checking if file/path set.
936			// Both are required for preview and download
937			var $file	= $el.attr('data-file');
938			var $fileVal	= fileName($el.get(0).value);
939			var $path	= $el.attr('data-path');
940
941
942			// Detecting value is present, and using as visual title
943			var $title = $fileVal || $el.attr('data-file') || $el.attr('value') || $el.attr('src') || $el.attr('img') || $el.attr('cap')  || 'Select File...';
944
945			// Setting title
946			$jTitle.html($title);
947
948			// Preparing preview url right away
949			var $previewUrl	= '';
950
951			// File and path should be just present to create download button
952			if ( $file && $path ) {
953
954				// Attaching download button
955				$jDownload.insertAfter($jUpload);
956
957				// Preparing preview with direct path
958				// Replacing /files with resizer: /getimage
959				// This way - images available for resizer will be run through resizer,
960				// and very custom images will stay as they are
961
962				// Previews are available only for images currently
963				if ( isFileImage($file) ) {
964
965					var $previewUrl	= $path.replace('/'+$fStorage+'/', '/getimage/');
966					$previewUrl += $file+'?resize='+Math.ceil( $jWrap.width() || 600 )+'x0';
967
968				} //IF image file
969
970			} //IF file defined
971
972			else {
973
974				// Detaching download
975				$jDownload.detach();
976
977				// Resetting preview
978				$previewUrl	= '';
979
980			} //IF no file
981
982			// ToDo: split input (hidden text with input name and name_file for file input)
983			// ToDo: delete button support. Automated for split inputs, ondelete="" event enables delete button
984
985			// For preview - need to do additional checks
986			// It's visibe when forced or when both file and path are present
987			// Previe is visible in auto mode when either URL is set, or file source is set
988			if ( !$fPrivate && (($preview == 'on') || ($preview && ($previewUrl || $fileVal))) ) {
989
990				// Filling in preview BG
991				// Using as is, even if it happen to be empty (when preview box is forced)
992				$jPreview.css({'background-image' : "url('"+$previewUrl+"')"}).show();
993
994				// Setting input height
995				$jWrap.attr('size', $size);
996
997			} //IF file defined
998
999			else {
1000
1001				// Clearing preview
1002				$jPreview.css({'background-image' : "url('')"}).hide();
1003
1004				$jWrap.attr('size', '');
1005
1006			} //IF no file
1007
1008		} //FUNC mwFileInputUpdateFace
1009
1010		// Adding download click
1011		$jDownload.click( function () {
1012
1013			// Support for "view file" requires both data path and value
1014			// Supporting download only for values set through fromArray() calls.
1015			// If file was browsed - can't download anyway
1016			var $file	= el.attr('data-file');
1017			var $path	= el.attr('data-path');
1018
1019			if ( !$file || !$path )
1020				return;
1021
1022			// If gallery specified - using it to view file
1023			if ( !isEmpty($fGallery) ) {
1024
1025				// Compiling path to gallery view in backend
1026				$path		= '/site/files/'+$fGallery+'/';
1027
1028			} //IF actual gallery specified
1029
1030			// Using virtual form to safely click into new tab
1031			submitUrl($path+$file, {}, true);
1032
1033		});
1033 //FUNC $jDownload.click
1034
1035		// Adding preview click
1036		$jPreview.click( function () {
1037
1038			// Just triggering download
1039			$jDownload.click();
1040
1041		}); //$jPreview.click
1042
1043		// Adding update on change
1044		el.change( function () {
1045
1046			// Preparing face
1047			mwFileInputUpdateFace(this);
1048
1049			// Preloading image if defined/selected
1050			if ( $preview && this.value )
1051				mwBackgroundPreview($jPreview, this);
1052
1053		}); //el.change
1054
1055		// Running initial update
1056		mwFileInputUpdateFace(el);
1057
1058	}); //jQuery each select input
1059
1060// ---- BROWSER ----
1061
1062	dialog.find('SELECT.selectEx').each( function () {
1063
1064		var $el = jQuery(this);
1065
1066		$el.addClass('multiline');
1067
1068		var $attr = inputClassString($el, '');
1069		if ( !$attr ) return;
1070
1071	// ---- Creating container element ----
1072
1073		$el.wrapAll('<div ' + $attr + '></div>');
1074
1075		// Researching wrapper, for later use
1076		var $wrap	= $el.parent();
1077
1078		// 100% size inputs are marked with class instead
1079		// and triggers default size for fallbacks
1080		if ( $wrap.attr('size') == '100%' )
1081			$wrap.addClass('fullHeight').removeAttr('size');
1082
1083		// Adding default height
1084		if ( !$wrap.attr('size') )
1085			$wrap.attr('size', '6');
1086
1087	// ---- Options ----
1088
1089		var $o	= {
1090			inline : $wrap.is('.inline')
1091		}; //$o
1092
1093		if ( $el.data('title') )
1094			$o.title = $el.data('title');
1095
1096		// Initiating selector
1097		// Checking inline mode by resulitng wrapper class
1098		var $sx = mwSelectEx($el, $o);
1099
1100		$el.data('selectEx', $sx);
1101
1102	}); //jQuery.each select
1103
1104// ---- TABLE ----
1105
1106	dialog.find('input[data-input="table"]').each( function () {
1107
1108		var $el		= jQuery(this);
1109		var $name	= $el.attr('name');
1110
1111		var $attr	= inputClassString($el, 'table');
1112
1113		if ( !$attr )
1114			return;
1115
1116
1117		$el.wrapAll('<div ' + $attr + '></div>');
1118
1119		// Researching wrapper
1120		var $wrap	= $el.closest('div');
1121
1122		// Reading columns
1123		var $cols	= strToArray($el.data('columns'));
1124
1125		// Generating table, replacing old one
1126		function tGen ($data) {
1127
1128			var $table	= $wrap.find('table').remove();
1129
1130			// Will try to recognize some values format
1131			var $cClass	= {};
1132
1133			// Rendering rows and headers in separate vars
1134			// Cols are rendered first, to collect data format info
1135			// Which then will allow to format headers
1136			// in the end all will be put together as table
1137			var $headHtml	= '';
1138			var $rowsHtml	= '';
1139
1140			// Rendering rows
1141			for (var $r in $data ) {
1142				var $row = $data[$r];
1143
1144				$rowsHtml += '<tr>';
1145				for (var $i in $cols ) {
1146
1147					var $col = $cols[$i];
1148					var $val = $row[$col];
1149
1150					if ( isNumeric($val) )
1151						$cClass[$col] = 'num';
1152
1153					// Checking if some classes are present
1154					var $class	= $cClass[$col] || '';
1155					if ( !isEmpty($class) )
1156						$class = ' class="'+$class+'"';
1157
1158					$rowsHtml += '<td'+$class+'>'+$val+'</td>';
1159				} //FOR each column
1160				$rowsHtml += '</tr>';
1161
1162			} //FOR each data row
1163
1164			// Rendering headers
1165			$headHtml += '<tr>';
1166			for (var $i in $cols ) {
1167
1168				var $col	= $cols[$i];
1169
1170				// Checking if some classes are present
1171				var $class	= $cClass[$col] || '';
1172				if ( !isEmpty($class) )
1173					$class = ' class="'+$class+'"';
1174
1175				$headHtml += '<th'+$class+'>'+ucfirst($cols[$i])+'</th>';
1176			} //FOR each column
1177			$headHtml += '</tr>';
1178
1179			var $html = '<table>'+$headHtml+$rowsHtml+'</table>';
1180
1181			return jQuery($html).appendTo($wrap);
1182
1183		} //FUNC tGen
1184
1185		tGen({});
1186
1187		// Hiding source input
1188		$el.hide();
1189
1190		// Updating table on input change
1191		$el.change( function () {
1192
1193			var $input	= jQuery(this);
1194			var $data	= JSON.parse($input.val() || '{}');
1195
1196			tGen($data);
1197
1198		}); //FUNC input.change
1199
1200	}); //jQuery each table input
1201
1202// ---- COMMON ----
1203
1204	// Tracking hovers/focus via java and classes to have extra styling options.
1205	// Unfortunately have to exclude few inputs
1206
1207	dialog.find('.mwInput').each( function () {
1208
1209		var $el = jQuery(this);
1210
1211		// Hover
1212		$el
1213			.off('mouseenter.mwInput')
1214			.on('mouseenter.mwInput', function () {
1215				$el.addClass('hover');
1216
1217				if ( $el.parent().is('.combo') )
1218					$el.parent().addClass('hover');
1219
1220			}) //FUNC hoverin
1221
1222			.off('mouseleave.mwInput')
1223			.on('mouseleave.mwInput', function () {
1224				$el.removeClass('hover');
1225
1226				if ( $el.parent().is('.combo') )
1227					$el.parent().removeClass('hover');
1228
1229			}) //FUNC hoverout
1230		; //$el
1231
1232		$el.not('.selectEx')
1233			.off('focusin.mwInput')
1234			.on('focusin.mwInput', function () {
1235				$el.addClass('focus');
1236
1237				if ( $el.parent().is('.combo') )
1238					$el.parent().addClass('focus');
1239			}) //FUNC hoverout
1240
1241			.off('focusout.mwInput')
1242			.on('focusout.mwInput', function () {
1243				$el.removeClass('focus');
1244
1245				if ( $el.parent().is('.combo') )
1246					$el.parent().removeClass('focus');
1247			}) //FUNC hoverout
1248		; //$el
1249
1250	}); //jQuery.each input
1251
1252	return false;
1253} //FUNC styleDialog
1254
1255/** //** ----= unstyleInput	 =----------------------------------------------\**//** \
1256*
1257* 	Removes styles from input given.
1258*
1259* 	@param	jQuery	input	- Valid jQuery input element selector.
1260* 	@return	jQuery		- New input element.
1261*
1262\**//** ------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/
1263function unstyleInput ( input ) {
1264
1265	// All styled inputs have .mw class.
1266	// Source is stored under jQuery's .data().
1267	input = _jq(input);
1268
1269	// Making sure that we are pointing to input itself
1270/*/
1271	if ( !input.is('.mw') )
1272		input = input.find('.mw');
1273
1274	var source	= input.data('source');
1275/*/
1276	var source	= input.find('.mw').data('source');
1277/**/
1278
1279	if ( source ) {
1280		source = jQuery(source);
1281		input.replaceWith(source);
1282		return source;
1283	} //IF source was stored
1284
1285	return input;
1286} //FUNC unstyleInput
1287
1288/** //** ----= unstyleDialog	 =----------------------------------------------\**//** \
1289*
1290* 	Removes styles from inputs in given element.
1291*
1292* 	@param	MIXED	el	- Valid jQuery element selector.
1293* 	@return	bool		- Always FALSE.
1294*
1295\**//** ------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/
1296function unstyleDialog ( dialog ) {
1297
1298	// All styled inputs have .mw class.
1299	// Source is stored under jQuery's .data().
1300	dialog.find('.mw').each( function () {
1301
1302		var el		= jQuery(this);
1303
1304		var source	= el.data('source');
1305
1306		if ( source )
1307			el.closest('.mwInput', dialog).replaceWith(source);
1308
1309	}); //jQuery each .mw
1310
1311	return false;
1312} //FUNC unstyleDialog
1313
1314function setValidations (dialog, validations) {
1315
1316	if ( !dialog )
1317		return;
1318
1319	dialog.find('INPUT, SELECT, TEXTAREA')
1320		.each( function () {
1321
1322			// Shortcuts to input and it's parent (morweb forms)
1323			var input	= jQuery(this);
1324			var parent	= input.closest('.mwInput');
1325			if ( !parent.length )
1326				parent = input;
1327
1328			// Input should have name to be validatable
1329			var name	= input.attr('name');
1330			if ( !name ) return;
1331
1332			// Shortcut to messages array to simplify code
1333			var msgs	= validations[name];
1334
1335			// Might be complex input name, so checking for that
1336			if ( isUndefined(msgs) ) {
1337
1338				// Splitting name to parts
1339				// Safe to do event if it's not complext - will end up with same name
1340				var $tmp	= name.split(/\[|\]/);
1341
1342				// Clearing empties
1343			//	$tmp		= $tmp.filter(n => n);
1344				$tmp		= $tmp.filter(Boolean);
1345
1346				// Finally - using last element
1347				name		= $tmp.slice(-1)[0];
1348				msgs		= validations[name];
1349
1350			} //IF nothing found
1351
1352			// TinyMCE support
1353			// Marking tinyEditor instead of input itself
1354			if ( input.is('.mwTinyMCE') ) {
1355
1356				// If it's tinyMCE input - there should be sibling mceEditor input
1357				input	= input.siblings('.mceEditor');
1358				parent	= input;
1359
1360				// If none - smth went wrong
1361				if ( !input.length )
1362					return;
1363		 	} //IF tinyMCE input
1364
1365			// Removing errors attribute if no messages
1366			if ( !msgs ) {
1367
1368				input.removeAttr('error');
1369
1370				// Class for parent
1371				parent.removeClass('error');
1372
1373				return;
1374			} //IF no messages
1375
1376			// Compiling messages, very simple br can be stored inside attribute
1377			var msg = implode('<br />', msgs);
1378
1379			// Setting error
1380			input.attr('error', msg);
1381
1382			// Class for parent
1383			parent.addClass('error');
1384
1385		}); //jQuery.each.callback
1386
1387	return;
1388} //FUNC setValidations
1389
1390/** //** ----= 	fillViews	 =----------------------------------------------\**//** \
1391*
1392* 	Fills fileds views within specified element.
1393*
1394*	@param	jQuery	el	- Context element.
1395*	@param	object	obj	- Data object to pull views from.
1396*
1397* 	@return	bool		- Always FALSE.
1398*
1399\**//** ------------------------------------= by Mr.V!T @ Morad Media Inc. =----/** //**/
1400function fillViews (el, obj) {
1401
1402	el = _jq(el);
1403
1404	for ( var i in obj ) {
1405		el.find('.view-' + i).html(obj[i]);
1406	} //FOR each field
1407
1408	return false;
1409} //FUNC fillViews

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.