PageSourceSearch

https://www.ivecocr.cz/resource/fea/js/files.fea.jquery.js?_dc=126

js ivecocr.cz collected 2026-10-02 05:58:38 UTC 18,065 bytes, 654 lines download raw bytes

1(function($){
2	/**
3	 * Komponenta pro editaci vetsiho mnozstvi souboru
4	 *
5	 * Jako hodnota se zadava id adresare z VFS.
6	 *
7	 * Komponenta je obdoba filemanageru z ExtJS. Jen s modernejsim navrhem
8	 *
9	 * Events:
10	 * * fea.fileEdit - vola se pred editaci souboru, pokud se vrati false, nevyvola se vychozi okno a vse ma v rukach
11	 *                  zpracovatel udalosti. Vysledne metainformace zavola pres callback funkci, ktera je jako druhy parametr.
12	 *                  do return je mozne vratit formular v podobe html, musi obshaovat formular tj '<form>...</form>'.
13	 */
14	$.fea.registerType('multiFile',{
15		extends: 'bssimpleTemplate',
16		fileMetadataValue: null,
17		maxSize: null,
18		minSize: null,
19		denyButtons: [],
20		async: null,
21		_getCtConfig: function(){
22			var ctCfg = this._callParent('bssimple','_getCtConfig',arguments);
23			$.extend(ctCfg,{
24				editor: {
25					selector: '.fea-field-files input[type=hidden]'
26				},
27				fileList: {
28					selector: '.fea-field-files .file-list'
29				},
30				toolbar:{
31					selector: '.fea-field-files .toolbar'
32				},
33				button_add:{
34					selector: '.fea-field-files .toolbar .add'
35				},
36				button_replace:{
37					selector: '.fea-field-files .toolbar .replace'
38				}
39			});
40
41			return ctCfg;
42		},
43		init: function(){
44			var  me = this;
45			me._callParent('bssimple','init',arguments);
46
47			me.maxSize = me._getProp('max-size');
48			me.minSize = me._getProp('min-size');
49			me.async = this.fea.helpers.toBool(me._getProp('async', true));
50			me.baseUrl = me._getProp('base-url');
51			me.rootDir = me._getProp('root-dir');
52			me.imageSize = me._getProp('image-size', '');
53
54			me.sort = me._getProp('sort');
55			me.sortDirection = me._getProp('sort-direction');
56
57			var dropZone =  me._getCt('fileList');
58
59			me.buttons = $.extend({},{
60				remove: {'enabled': false, 'titleT': 'label_fea_file_remove', 'autoDeselect': true, 'selectable': '*', 'icon': 'fa fa-minus', handler: me._removeFile},
61				edit: {'enabled': false, 'titleT': 'label_fea_file_edit', 'selectable': '1', 'icon': 'fa fa-edit', handler: me._editFile},
62				download: {'enabled': false, 'titleT': 'label_fea_file_download', 'selectable': '*', 'icon': 'fa fa-download', handler: me._downloadFile},
63				refresh: {'enabled': true, 'titleT': 'label_fea_file_refresh', 'icon': 'fa fa-refresh', handler: me._refreshFiles}
64			}, me._getButtons(), me.extendButtons || {});
65
66			me._renderButtons(me.buttons);
67
68			dropZone.bind('dragover', function (e){
69				dropZone.addClass('in');
70				e.stopPropagation();
71			});
72			dropZone.bind('dragleave drop', function (e){
73				dropZone.removeClass('in');
74				e.stopPropagation();
75			});
76
77			var addOptions = {
78				replaceFileInput: false,
79				dropZone: dropZone,
80				autoUpload: false
81			};
82
83			if ( me.maxSize ) {
84				addOptions.maxFileSize = me.maxSize;
85			}
86
87			if ( me.minSize ) {
88				addOptions.minFileSize = me.minSize;
89			}
90
91			if ( me.async && me.baseUrl) {
92				addOptions.url = me.baseUrl + 'create' ;
93				addOptions.autoUpload = true;
94				addOptions.paramName = 'Filedata',
95				addOptions.dataType = 'json',
96				addOptions.formData =  {
97					root: me.rootDir, // root name VFS
98					dir: me.getValue() // dir_id VFS
99				};
100			}
101
102			me.selectHandler = me._getCt('fileList').on('click', '.editor-file', function(e){
103				var el = $(this)
104					;
105				if ( e.target.tagName !== 'INPUT' ) {
106					e.stopPropagation();
107					el.find("input[type='checkbox'].file-select").trigger('click');
108				}
109			});
110
111			me.selectChangeHandler = me._getCt('fileList').on('change', "input[type='checkbox'].file-select", function(e){
112				var select = me._selectedFiles();
113				me._updateToolbar(select.length);
114
115				var input = $(this),
116					parent = input.closest('.editor-file');
117
118				if ( parent && parent.length > 0 ) {
119					if ( input.prop('checked') ) {
120						parent.addClass('file-selected');
121					} else {
122						parent.removeClass('file-selected');
123					}
124				}
125			});
126
127			me.buttonClickHandler = me._getCt('toolbar').on('click', '.btn:not(.disabled):not(.nohandler)', function(e){
128					var button = $(this),
129						name = button.data('name');
130
131				if ( me.buttons.hasOwnProperty(name) ) {
132						var defButton = me.buttons[name];
133						if ( typeof defButton.handler === 'function' ) {
134							var files = me._selectedFiles();
135							defButton.handler.call(defButton.scope || me, files, me);
136						}
137					}
138
139					if ( button.data('autoDeselect') ) {
140						me._unselectAll();
141					}
142			});
143
144			var fileAdd = me._getCt('button_add').fileupload(addOptions);
145
146			fileAdd.on('fileuploaddone', $.proxy(me._uploadDone, me));
147			fileAdd.on('fileuploadstart', $.proxy(me._showLoadMask, me));
148			fileAdd.on('fileuploadstop', $.proxy(me._hideLoadMask, me));
149
150			var replaceOptions = {
151				replaceFileInput: true,
152				dropZone: null, //TODO lze navazat na konkretni soubor pres selector by to nemel byt problem
153				autoUpload: false
154			};
155
156			//replace
157			if ( me.async && me.baseUrl) {
158				replaceOptions.url = me.baseUrl + 'replace' ;
159				replaceOptions.autoUpload = true;
160				replaceOptions.paramName = 'file',
161				replaceOptions.dataType = 'json',
162
163				replaceOptions.formData =  {
164					root: me.rootDir, // root name VFS
165					dir: me.getValue() // dir_id VFS
166				};
167			}
168			var fileReplace = me._getCt('button_replace').fileupload(replaceOptions);
169
170			fileReplace.on('fileuploaddone', $.proxy(me._uploadDone, me));
171			fileReplace.on('fileuploadstart', $.proxy(me._showLoadMask, me));
172
173			fileReplace.on('fileuploadsubmit', function(e, data){
174				var files = me._selectedFiles();
175				if ( files.length > 0 ) {
176					var file = files[0],
177						fileInfo = me._getFileInfo(file),
178						i, len
179						;
180
181					data.formData = {
182						root: me.rootDir, // root name VFS
183						dir: me.getValue(), // dir_id VFS
184						id: fileInfo.id
185					};
186					var checkbox = me._getCt('button_replace').siblings('ul.dropdown-menu').find("input[type='checkbox'].file-select:checked"); //TODO hezci selector
187
188					for ( i = 0, len = checkbox.length; i < len; ++i) {
189						var elm = $(checkbox[i]);
190						var param = elm.data('param');
191						if ( param ) {
192							data.formData[param] = 1;
193						}
194					}
195				}
196				else {
197					return false;
198				}
199			});
200			fileReplace.on('fileuploadstop', $.proxy(me._hideLoadMask, me));
201
202			me._getCt('button_add').fileupload('disable');
203			me._getCt('button_replace').fileupload('disable');
204		},
205		_activate: function() {
206			var me = this;
207			me._callParent('bssimple','_activate',arguments);
208			//me._refreshEditorFiles(me.getValue());
209			me._getCt('button_add').fileupload('enable');
210			me._getCt('button_replace').fileupload('enable');
211		},
212		_deactivate: function() {
213			var me = this;
214			me._callParent('bssimple','_deactivate',arguments);
215			me._getCt('button_add').fileupload('disable');
216			me._getCt('button_replace').fileupload('disable');
217		},
218		_getButtons: function(){
219			return {};
220		},
221		_showLoadMask: function() {
222			// TODO zabranit vicenasobnemu zobrazeni
223			this.fea.helpers.componentLoading(this, true);
224		},
225		_hideLoadMask: function() {
226			this.fea.helpers.componentLoading(this, false);
227		},
228		_uploadDone: function(e, data) {
229
230			if ( data.result && !data.result.success  ) {
231				this.addErrors(data.result.message);
232			} else {
233				this.clearErrors();
234			}
235
236			this._refreshFiles();
237		},
238		_refreshFiles: function() {
239			this._refreshEditorFiles(this.getValue());
240			this._unselectAll();
241		},
242		reset: function() {
243			this._callParent('bssimple','reset',arguments);
244
245			///this._clearContainers();
246		},
247		_unselectAll: function(){
248			this._getCt('fileList').find("input[type='checkbox'].file-select:checked").prop('checked', false).trigger("change");
249			this._updateToolbar(0);
250		},
251		_renderButtons: function(buttons)
252		{
253			var	me = this,
254				toolbar = me._getCt('toolbar'),
255				buttonName,
256				key,
257				filter = ['class', 'icon', 'title', 'titleT', 'tooltip', 'enabled', 'handler', 'scope']
258				;
259
260			for ( buttonName in buttons){
261
262				if ( -1 !== $.inArray(buttonName, me.denyButtons) ) {
263					continue;
264				}
265
266				var button = buttons[buttonName],
267					attrs = {'data-name': buttonName, 'data-toggle': 'tooltip' }
268					;
269
270				var btnElm = $('<span></span>').addClass('btn btn-default');
271
272				if ( button.class) {
273					btnElm.addClass(button.class);
274				}
275
276				if (  button.icon )	{
277					btnElm.append($('<i class="'+button.icon+'"></i>'));
278				}
279
280				if (  button.titleT )	{
281					button.title = T(button.titleT) ;
282				}
283
284				if (  button.title ) {
285					btnElm.append($('<span class="label">'+button.title+'</span>'));
286				}
287
288				if (  typeof button.enabled !== 'undefiened' && !button.enabled ) {
289					btnElm.addClass('disabled');
290				}
291
292				attrs['title'] = button.tooltip || button.title;
293
294				for ( key in button )
295				{
296					if ( button.hasOwnProperty(key) && $.inArray(key, filter) === -1 ) {
297						attrs['data-'+key] = button[key];
298					}
299				}
300
301				btnElm.attr(attrs);
302
303				toolbar.append(btnElm);
304			}
305
306		},
307		_selectedFiles: function(){
308			var me = this,
309				inputs = me._getCt('fileList').find('.editor-file'),
310				len = inputs.length,
311				selected = [],
312				i, input
313				;
314
315			if ( len === 1 ) {
316				selected.push($(inputs[0]));
317			} else {
318				for ( i = 0; i < len; ++i ) {
319					input = $(inputs[i]);
320					if ( input.find("input[type='checkbox'].file-select:checked" ).length ) {
321						selected.push(input);
322					}
323				}
324			}
325
326			return selected;
327		},
328		_updateToolbar: function(count){
329			var me = this,
330				items = me._getCt('toolbar').find('[data-selectable]'),
331				len = items.length,
332				i, item, selectable
333				;
334			for ( i = 0 ; i < len; ++i) {
335				item = $(items[i]);
336				selectable = item.data('selectable');
337				if ( (selectable === '*' && count > 0) || (selectable === count ) ) {
338					item.removeClass('disabled');
339				}
340				else {
341					item.addClass('disabled');
342				}
343			}
344		},
345		_removeFile: function(select){
346			var me = this,
347				i, len = select.length
348				;
349
350			if ( true === confirm( T('text_fea_files_remove_question') ) ) {
351
352				for (i = 0; i < len; ++i ) {
353					(function(){ //obalka kvuli kontextu
354						var file = select[i];
355
356						file.toggleClass('fea-file-remove');
357
358						if ( me.async ) {
359							me._showLoadMask();
360							$.ajax(me.baseUrl+'delete', {
361								method: 'POST',
362								data: {
363									root: me.rootDir, // root name VFS
364									dir: me.getValue(), // dir_id VFS
365									data: JSON.stringify(me._getFileInfo(file))
366								}
367							}).done(function( data ) {
368								if ( data && data.success ) {
369									file.remove();
370								} else {
371									if (data.message) {
372										me.addErrors(data.message);
373									}
374								}
375							}).fail(function(){
376								me.addErrors(T('error_fea_files_remove'));
377							}).always(function(){
378								me._hideLoadMask();
379							});
380						} else {
381							//TODO: sync rezim - asi vygenerovat ID do hidden elementu ve formatu JSON pole
382						}
383					})();
384				}
385
386			}
387		},
388		_download: function(url) {
389			$('<iframe src="'+url+'" style="display: none"></iframe>')
390				.load(function() {
391					var that = this;
392					setTimeout(function() {
393						$(that).remove();
394					}, 100);
395				})
396				.appendTo($('body'));
397		},
398		_downloadFile: function(selections){
399			var me = this,
400				i, len = selections.length
401				;
402
403			for (i = 0; i < len; ++i ) {
404				var fileInfo = me._getFileInfo(selections[i])
405					;
406				if ( fileInfo && fileInfo.url ) {
407					me._download(fileInfo.url);
408				}
409			}
410		},
411		_openDialog: function(options) {
412			options = options || {};
413
414			var me = this,
415				winHtml = '<div class="modal fade" tabindex="-1" role="dialog">' +
416				'<div class="modal-dialog">' +
417					'<div class="modal-content">' +
418					'<div class="modal-header"><button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>' +
419					'<h4 class="modal-title">'+(options.title || '') +'</h4>' +
420				'</div>' +
421				'<div class="modal-body">'+ (options.html || '') + '</div>' +
422				'<div class="modal-footer">' +
423					'<button type="button" class="btn btn-default" data-dismiss="modal">'+T('label_fea_files_win_close')+'</button>' +
424					'<button type="button" class="btn btn-primary">'+T('label_fea_files_win_submit')+'</button>' +
425				'</div>' +
426			'</div>';
427
428			var win = $(winHtml).appendTo($('body')).on('click', 'div.modal-footer > button.btn-primary', function(){
429				var content = win.find('.modal-body').children();
430				var state = false;
431
432				if ( typeof options.callback === 'function') {
433					state = options.callback.call(options.scope || me, content, win);
434				}
435				if ( options.autoClose || state ) {
436
437					win.on('hidden.bs.modal', function(){
438						win.remove();
439					});
440
441					win.modal('hide');
442				}
443			});
444
445			win.modal();
446
447		},
448		_editFile: function(select) {
449			var me = this;
450			if ( select.length > 0 ) {
451				var fileInfo = me._getFileInfo(select[0]),
452					storeFunction = function(newMetadata, callbackSucces, scope) { //TODO predelat na promise
453						me._storeMetadata(select[0], newMetadata, {callback: callbackSucces, scope: scope});
454					}
455					;
456
457				var res = me.$elem.triggerHandler('fea.fileEdit', [fileInfo, storeFunction]);
458				if ( res !== false ) {
459					me._openDialog({
460						title: fileInfo.name,
461						html:  ( typeof res === 'string' ? res : me._baseForm(fileInfo)),
462						callback: function(content, callbackSucces, scope){
463							var newMetadata = me.fea.helpers.unlinearizeData(content.serializeArray())
464								;
465							storeFunction(newMetadata);
466						},
467						autoClose: true
468					});
469				}
470			}
471		},
472		_baseForm: function(fileInfo) {
473			var formHtml = '<form  class="form-horizontal">' +
474					'<div class="form-group"><label class="col-sm-4 control-label">'+T('label_fea_file_name')+':</label><div class="col-sm-8"><input class="form-control" name="name" value="'+(fileInfo.name || '')+'"></div></div>'+
475					'<div class="form-group"><label class="col-sm-4 control-label">'+T('label_fea_file_title')+':</label><div class="col-sm-8"><input class="form-control" name="title" value="'+(fileInfo.title || '')+'"></div></div>'+
476				'</form>';
477
478			return formHtml;
479		},
480		_storeMetadata: function(fileElm, newMetadata, options) {
481			options = options || {};
482
483			var me = this,
484				fileInfo = me._getFileInfo(fileElm),
485				metadata =	$.extend({}, fileInfo, newMetadata);
486				;
487			if ( me.async ) {
488				me._showLoadMask();
489				$.ajax(me.baseUrl+'update', {
490					method: 'POST',
491					dataType: 'json',
492					data: {
493						root: me.rootDir, // root name VFS
494						dir: me.getValue(), // dir_id VFS
495						data: JSON.stringify(metadata)
496					}
497				}).done(function( data ) {
498					if ( data && data.success ) {
499						me._setFileInfo(fileElm, data.data);
500
501						if ( typeof options.callback === 'function' ) {
502							options.callback.call(options.scope || me, data.data);
503						}
504					}
505					else if ( data.message ) {
506						me.addErrors(data.message);
507					} else {
508						me.addErrors(T('error_fea_files_edit'));
509					}
510				}).fail(function(){
511					me.addErrors(T('error_fea_files_edit'));
512				}).always(function(){
513					me._hideLoadMask();
514				});
515			} else {
516				//TODO: sync rezim - asi vygenerova hidden elementy ve formatu JSON pole
517			}
518
519		},
520		_setFileInfo: function(select, data) {
521			var me = this;
522
523			select.data('file-info', data);
524				//.attr('data-file-info', JSON.stringify(data));
525
526			//select.children('.file-preview').html(me._renderFile(data, me.editType));
527			me._localRefresh();
528
529			return null;
530		},
531		_getFileInfo: function(select) {
532			return select.data('file-info');
533		},
534		loadData: function(id, callback){
535			var me = this,
536				baseUrl = me.baseUrl
537				;
538
539			if ( id && baseUrl ) {
540
541				var params = {
542					root: me._getProp('root-dir'),
543					dir: id
544				};
545
546				if ( me.sort ) {
547					params.sort = [{'property':  me.sort , 'direction':  me.sortDirection || "ASC"}];
548				}
549
550				$.ajax(baseUrl+'read', {
551					data: params
552				}).success(function(result){
553					if ( result && result.success ) {
554						var imageInfo = result.data;
555
556						if ( $.isArray(imageInfo) && typeof callback === 'function' ) {
557							callback.call(me, imageInfo);
558						}
559					}
560				});
561			}
562		},
563		_normalizeData: function(data) {
564			var me = this,
565				imageSize = me.imageSize,
566				i, len,
567				fileInfo,
568				varReplace
569				;
570
571			if ( imageSize.length > 0 ) {
572				imageSize = '/'+imageSize;
573			}
574
575			for ( i = 0, len = data.length; i < len; ++i) {
576				fileInfo = data[i];
577				varReplace = $.extend({'imageSize': imageSize}, fileInfo);
578
579				var imageUrl;
580
581				if ( 'image' === fileInfo.type ) {
582					imageUrl = me.fea.helpers.varsReplace(fileInfo.path_template, varReplace);
583
584					if ( fileInfo.hasOwnProperty('checksum') && !!fileInfo.checksum ) {
585						imageUrl += '?v=' + fileInfo.checksum;
586					}
587				}
588				else {
589					imageUrl = me._getProp('default-thumb');
590				}
591
592				fileInfo.imageUrl = imageUrl;
593				fileInfo.adminAttr = me.fea.helpers.attrsToString({'class': "editor-file", 'data-file-info': JSON.stringify(fileInfo)});
594			}
595
596			return data;
597		},
598		_localRefresh: function(){
599			var me = this,
600				fileList = me._getCt('fileList'),
601				files = fileList.find('.editor-file'),
602				len, i,
603				filesInfo = [],
604				foo;
605
606			for ( i = 0, len = files.length; i < len; i++ ) {
607				foo = me._getFileInfo($(files[i]));
608				if ( foo ) {
609					filesInfo.push(foo);
610				}
611			}
612
613			if (filesInfo.length > 0 ) {
614				filesInfo = me._normalizeData(filesInfo);
615
616				me._renderEditorFiles(filesInfo);
617
618				me._unselectAll();
619			}
620		},
621		_refreshEditorFiles: function(value) {
622			var me = this;
623
624			me.loadData(value, function(imagesInfo){
625				me._renderEditorFiles(me._normalizeData(imagesInfo));
626			});
627		},
628		_renderEditorFiles: function(imagesInfo){
629			var me = this,
630				fileList = me._getCt('fileList'),
631				data = {
632					'files': imagesInfo,
633					'isAdmin': true
634				};
635
636			fileList.empty();
637			fileList.append(me._renderTpl('adminTpl', data));
638		},
639		displayTrafo: function(value) {
640			var me = this;
641
642			me.loadData(value, function(imagesInfo){
643				var data = {
644					'files':  me._normalizeData(imagesInfo),
645					'isAdmin': false
646				};
647
648				me._getCt('presentation').html(me._renderTpl('tpl', data));
649			});
650
651			return '';
652		}
653	});
654})(jQuery);

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.