PageSourceSearch

https://iaeglobal.vn/templates/fashion02/assets/js/comment.js

js iaeglobal.vn collected 2026-10-08 19:54:19 UTC 50,685 bytes, 1,429 lines download raw bytes

1'use strict';
2
3var nhComment = {
4	info: {
5		full_name: null,
6		email: null,
7		phone: null,
8		logged: false
9	},
10	config:{
11		max_number_files: 10, // number file upload
12		expires_cookie: 10, // number day cookie expires
13	},	
14	loginModal: null,
15	infoModal: null,
16	infoForm: null,
17	init: function(){
18		var self = this;
19
20		self.loginModal = $('#login-modal');
21		self.infoModal = $('#info-comment-modal');
22		self.infoForm = self.infoModal.find('form#info-comment-form');
23
24		if(self.infoModal.length == 0 || self.infoForm.length == 0 || ($('[nh-rating]').length == 0 && $('[nh-comment]').length == 0)){
25			return false;
26		}
27
28		self.getInfo();		
29		self.event();
30
31		self.comment.init();
32		self.rating.init();
33	},
34	event: function(){
35		var self = this;
36
37		nhMain.validation.phoneVn();
38
39		var validatorInfo = self.infoForm.validate({
40			ignore: ':hidden',
41			rules: {
42				full_name: {
43					required: true,
44					minlength: 6,
45					maxlength: 255
46				},
47				email: {
48					required: true,
49					email: true,
50                    minlength: 10,
51                    maxlength: 255
52				},
53				phone: {
54					required: true,
55					phoneVN: true
56				}
57			},
58			messages: {
59				full_name: {
60                    required: nhMain.getLabel('vui_long_nhap_thong_tin'),
61                    minlength: nhMain.getLabel('thong_tin_nhap_qua_ngan'),
62                    maxlength: nhMain.getLabel('thong_tin_nhap_qua_dai')
63                },
64                email: {
65                	required: nhMain.getLabel('vui_long_nhap_thong_tin'),
66                    email: nhMain.getLabel('email_chua_dung_dinh_dang'),
67                	minlength: nhMain.getLabel('thong_tin_nhap_qua_ngan'),
68                    maxlength: nhMain.getLabel('thong_tin_nhap_qua_dai')
69                },
70                phone: {
71                    required: nhMain.getLabel('vui_long_nhap_thong_tin'),
72                    phoneVN: nhMain.getLabel('so_dien_thoai_chua_chinh_xac')
73                }
74            },
75            errorPlacement: function(error, element) {
76                var group = element.closest('.input-group');
77                if (group.length) {
78                    group.after(error.addClass('invalid-feedback'));
79                }else{                	
80                    element.after(error.addClass('invalid-feedback'));
81                }
82            },
83			invalidHandler: function(event, validator) {
84				validatorInfo.errorList[0].element.focus();
85			},
86		});
87
88		self.infoModal.on('click', '#btn-send-info', function(e) {
89			e.preventDefault();
90
91			if (validatorInfo.form()) {
92				self.setInfo({
93					full_name: self.infoForm.find('input[name="full_name"]').val(),
94					email: self.infoForm.find('input[name="email"]').val(),
95					phone: self.infoForm.find('input[name="phone"]').val(),
96				});
97
98				self.infoModal.modal('hide');
99				
100				if(self.comment.triggerAdd){					
101					self.comment.addComment();
102				}
103
104				if(self.rating.triggerAdd){
105					self.rating.addCommentRating();
106				}
107			}
108		});
109
110		self.infoModal.on('show.bs.modal', function (e) {
111		  	self.infoModal.find('input[name="full_name"]').val(self.info.full_name);
112		  	self.infoModal.find('input[name="email"]').val(self.info.email);
113		  	self.infoModal.find('input[name="phone"]').val(self.info.phone);
114		});
115	},
116	setInfo: function(data = {}){
117		var self = this;	
118
119		var full_name = nhMain.utilities.notEmpty(data.full_name) ? data.full_name : null;
120		var email = nhMain.utilities.notEmpty(data.email) ? data.email : null;
121		var phone = nhMain.utilities.notEmpty(data.phone) ? data.phone : null;
122
123		$.cookie(_INFO_COMMENT, JSON.stringify({
124			full_name: full_name,
125			email: email,
126			phone: phone
127		}), {expires: self.config.expires_cookie});
128
129		self.info.full_name = full_name;
130		self.info.email = email;
131		self.info.phone = phone;
132
133		if(typeof(nhMain.dataInit.member) != _UNDEFINED && !$.isEmptyObject(nhMain.dataInit.member)){
134			self.info.logged = true;			
135		}
136
137		self.comment.showInfo();
138		self.rating.showInfo();
139	},
140	getInfo: function(config = {}){
141		var self = this;
142
143		var loginRequired = typeof(config.login_required) != _UNDEFINED ? config.login_required : 0;		
144		var memberInfo = typeof(nhMain.dataInit.member) != _UNDEFINED && !$.isEmptyObject(nhMain.dataInit.member) ? nhMain.dataInit.member : {};
145
146		if(loginRequired == 0){			
147			var infoCookie = nhMain.utilities.notEmpty($.cookie(_INFO_COMMENT)) ? JSON.parse($.cookie(_INFO_COMMENT)) : {};
148
149			self.info.full_name = typeof(infoCookie.full_name) != _UNDEFINED ? infoCookie.full_name : null;
150			self.info.email = typeof(infoCookie.email) != _UNDEFINED ? infoCookie.email : null;
151			self.info.phone = typeof(infoCookie.phone) != _UNDEFINED ? infoCookie.phone : null;
152		}
153
154		if(loginRequired > 0 || self.info.full_name == null){
155			self.info.full_name = typeof(memberInfo.full_name) != _UNDEFINED ? memberInfo.full_name : null;
156			self.info.email = typeof(memberInfo.email) != _UNDEFINED ? memberInfo.email : null;
157			self.info.phone = typeof(memberInfo.phone) != _UNDEFINED ? memberInfo.phone : null;
158		}
159
160		if(!$.isEmptyObject(memberInfo)){
161			self.info.logged = true;
162		}
163
164		return self.info;		
165	},
166	convertFullNameToSpell: function(fullName = null) {
167		var self = this;
168
169		if(!nhMain.utilities.notEmpty(fullName)) return '';
170
171		var str = fullName.toString().split(' ');
172        var char = '';
173        $.each(str, function(key, value) {
174            char = char + '' + value.charAt(0);
175        });
176
177        return char.toUpperCase().substr(0, 3);
178	},
179	ajaxAddComment: function(data = {}, callback = null){
180		var self = this;
181
182		if (typeof(callback) != 'function') {
183	        callback = function () {};
184	    }
185
186	  	nhMain.showLoading.page();
187		nhMain.callAjax({
188    		async: true,
189			url: '/comment/add',
190			data: {
191				full_name: self.info.full_name,
192				email: self.info.email,
193				phone: self.info.phone,
194				content: typeof(data.content) != _UNDEFINED ? data.content : null,
195				images: typeof(data.images) != _UNDEFINED ? data.images : [],
196				parent_id: typeof(data.parent_id) != _UNDEFINED ? data.parent_id : null,
197				url: window.location.pathname,
198				block_code: typeof(data.block_code) != _UNDEFINED ? data.block_code : null,
199				type_comment: typeof(data.type_comment) != _UNDEFINED ? data.type_comment : null,
200				rating: typeof(data.rating) != _UNDEFINED ? data.rating : null,
201			},
202		}).done(function(response) {
203			callback(response);
204            nhMain.showLoading.remove();
205		});
206	},
207	ajaxLoadComment: function(params = {}, options = {}, callback = null){
208		var self = this;
209
210		if (typeof(callback) != 'function') {
211	        callback = function () {};
212	    }
213
214	    if(typeof(options.show_loading) != _UNDEFINED && Boolean(options.show_loading)){
215	    	nhMain.showLoading.page();
216	    }
217
218	    if(typeof(params.url) == _UNDEFINED){
219	    	params.url = window.location.pathname;
220	    }
221
222		nhMain.callAjax({
223    		async: true,
224			url: '/comment/load',
225			data: params,
226		}).done(function(response) {
227			callback(response);
228			nhMain.showLoading.remove();
229		});
230	},
231	ajaxUploadImage: function(formData = {}, callback = null){
232		var self = this;
233
234		if (typeof(callback) != 'function') {
235	        callback = function () {};
236	    }
237
238	    nhMain.callAjax({
239    		async: true,
240			url: '/comment/upload-image',
241			data: formData,
242			contentType: false,
243			processData: false,
244		}).done(function(response) {
245
246			var code = typeof(response.code) != _UNDEFINED ? response.code : _ERROR;
247        	var message = typeof(response.message) != _UNDEFINED ? response.message : '';
248        	var data = typeof(response.data) != _UNDEFINED ? response.data : {};
249
250        	if (code == _ERROR){
251        		nhMain.showAlert(_ERROR, message);
252        	}
253
254        	if (code == _SUCCESS && !$.isEmptyObject(data)) {
255        		callback(data);
256            }
257		}).fail(function(jqXHR, textStatus, errorThrown){
258	    	nhMain.showLog(errorThrown);
259		});
260	},
261	comment: {
262		config: {},
263		block_code: null,
264		wrapElement: null,
265		listElement: null,
266		contentElement: null,
267		listReplyElement: null,
268		content: null,
269		images: [],
270		scrollHeightDefault: 0,
271		template:{
272			item: '\
273				<li nh-comment-item="" is-parent="true" class="comment-item">\
274					<div class="post-author">\
275						<span class="letter-first"></span>\
276						<span class="name-author"></span>\
277					</div>\
278					<div class="comment-content">\
279						<div class="inner-content"></div>\
280						<div class="comment-action">\
281							<div class="inner-like">\
282								<i class="iconsax isax-like-1"></i>\
283								<span class="number-like"></span> ' +
284								nhMain.getLabel('thich') +
285							'</div>\
286							<div class="inner-reply">\
287								<span class="number-reply"></span> ' +
288								nhMain.getLabel('tra_loi') +
289							'</div>	\
290							<div class="post-date"></div>\
291						</div>\
292					</div>\
293				</li>',
294			itemReply: '\
295				<li nh-comment-item="" class="reply">\
296					<div class="post-author">\
297						<span class="letter-first"></span>\
298						<span class="name-author"></span>\
299					</div>\
300					<div class="comment-content">\
301						<div class="inner-content"></div>\
302						<div class="comment-action">\
303							<div class="inner-like">\
304								<i class="iconsax isax-like-1"></i>\
305								<span class="number-like"></span> ' +
306								nhMain.getLabel('thich') +
307							'</div>\
308							<div class="inner-reply">' +
309								nhMain.getLabel('tra_loi') +
310							'</div>	\
311							<div class="post-date"></div>\
312						</div>\
313					</div>\
314				</li>',
315			wrapReply: '<ul class="list-reply"></ul>',				
316			inputContent: '\
317				<div class="edit-comment">\
318					<textarea nh-input-comment placeholder="'+ nhMain.getLabel('moi_ban_de_lai_binh_luan') +'"></textarea>\
319					<div class="box-comment">\
320						<label>\
321							<i nh-trigger-upload class="iconsax isax-camera"></i>\
322						</label>\
323						<input nh-input-comment-images name="files[]" type="file" class="d-none" accept="image/gif, image/jpeg, image/png" multiple="multiple">\
324					</div>\
325					<ul class="comment-images"></ul>\
326					<span nh-btn-send-comment class="btn rounded-0 btn-dark">' +
327						nhMain.getLabel('gui_binh_luan') +
328					'</span>\
329				</div>',
330			moreItem: '<a nh-comment-more="" class="comment-more" href="javascript:;">'+ nhMain.getLabel('xem_them_thao_luan') +'</a>',
331			wrapListImageSelect: '<ul class="comment-images"></ul>',
332			imageSelect: '\
333				<li nh-item-comment-image class="loading">\
334					<img class="img-comment" src="">\
335					<i class="close-image">x</i>\
336				</li>',
337		},
338		triggerAdd: false,
339		init: function(){
340			var self = this;
341
342			// validate element
343			if($('[nh-comment]').length == 0){
344				return false;
345			}
346
347			self.wrapElement = $('[nh-comment]');
348
349			var configBlock = nhMain.utilities.parseJsonToObject(self.wrapElement.attr('nh-comment'));
350			if($.isEmptyObject(configBlock)){
351				nhMain.showLog(nhMain.getLabel('chuc_nang_binh_luan_thieu_dieu_kien_de_hoat_dong'));
352				return false;
353			}
354			$.extend(self.config, configBlock);			
355
356			var wrapBlock = self.wrapElement.closest('[nh-block]');
357			if(wrapBlock.length > 0 && wrapBlock.attr('nh-block').length > 0){
358				self.block_code = wrapBlock.attr('nh-block');
359			}
360
361			var loginRequired = typeof(self.config.login_required) != _UNDEFINED ? self.config.login_required : 0;
362			if(loginRequired == 1 && nhComment.loginModal.length == 0){
363				nhMain.showLog(nhMain.getLabel('chuc_nang_binh_luan_thieu_dieu_kien_de_hoat_dong'));
364				return false;
365			}
366
367			self.listElement = self.wrapElement.find('[nh-list-comment]');
368			if(self.listElement.length == 0){
369				nhMain.showLog(nhMain.getLabel('chuc_nang_binh_luan_thieu_dieu_kien_de_hoat_dong'));
370				return false;
371			}
372
373			self.showInfo();
374
375			self.contentElement = self.wrapElement.find('[nh-input-comment]');
376			if(self.contentElement.length > 0){
377				self.initInputContent(self.contentElement);
378			}
379
380			self.event();
381			self.loadComment({show_loading: false});
382		},
383		initInputContent: function(input = null	){
384			var self = this;
385			if(typeof(input) == _UNDEFINED || input == null || input.length == 0) return false;
386
387			self.scrollHeightDefault = input[0].scrollHeight;
388			input[0].setAttribute('style', 'height:' + self.scrollHeightDefault + 'px; overflow-y:hidden;');
389			input.on('input', function () {
390		        this.style.height = 'auto';
391		        this.style.height = this.scrollHeight + 'px';
392		    });
393		},
394		event: function(){
395			var self = this;		
396
397			self.wrapElement.on('click', '[nh-btn-send-comment]', function(e){
398				self.contentElement = $(this).closest('.edit-comment').find('[nh-input-comment]');
399				self.addComment();
400			});
401
402			self.wrapElement.on('click', '[nh-comment-change-info]', function(e){
403				if(self.logged){
404					window.location.href = '/member/dashboard';
405				}else{
406					nhComment.infoModal.modal('show');
407				}				
408			});
409
410			self.wrapElement.on('click', '.inner-reply', function(e){
411				var commentItem = $(this).closest('li[nh-comment-item][is-parent]');
412				if(commentItem.length == 0) return false;
413
414				var commentId = commentItem.attr('nh-comment-item');
415				if(!nhMain.utilities.notEmpty(commentId)) return false;
416
417				var numberReply = $(this).find('.number-reply').text();
418
419				var loadReply = false;
420				if(nhMain.utilities.notEmpty(numberReply) && commentItem.find('.list-reply').length == 0) {
421					loadReply = true;
422					commentItem.append(self.template.wrapReply);					
423				}
424
425				if(commentItem.find('.edit-comment').length == 0){
426					commentItem.append(self.template.inputContent);
427
428					self.contentElement = commentItem.find('[nh-input-comment]');
429					self.initInputContent(self.contentElement);
430				}
431
432				self.contentElement = commentItem.find('[nh-input-comment]');
433				self.contentElement.focus();
434
435				if(loadReply){
436					self.loadComment({parent_id: commentId});
437				}
438				
439			});
440
441			self.wrapElement.on('click', '.inner-like', function(e){
442				var commentId = $(this).closest('li[nh-comment-item]').attr('nh-comment-item');
443				var btnLike = $(this);
444				self.likeComment(commentId, function(response){
445					var numberLike = typeof(response.number_like) != _UNDEFINED ? response.number_like : '';
446					btnLike.find('.number-like').text(numberLike);
447	        		btnLike.toggleClass('liked', response.type == 'like' ? true : false);
448				});
449			});
450
451			self.wrapElement.on('click', '[nh-comment-more]', function(e){
452				var commentItem = $(this).closest('li.comment-item');
453
454				var page = $(this).attr('nh-comment-more');
455				if(!page > 0) return;
456
457				var commentId = commentItem.length > 0 ? commentItem.attr('nh-comment-item') : null;
458				self.loadComment({
459					parent_id: commentId,
460					page: page
461				});
462			});
463
464			self.wrapElement.on('click', '[nh-trigger-upload]', function(e){
465				var boxComment = $(this).closest('.box-comment');
466				if(boxComment.length == 0) return;
467
468				boxComment.find('input[nh-input-comment-images]').trigger('click');
469			});
470
471			self.wrapElement.on('change', '[nh-input-comment-images]', function(e) {
472				self.showImagesSelect(this);
473			});
474
475			self.wrapElement.on('click', '.comment-images .close-image', function(e){
476				$(this).closest('li').remove();
477			});
478		},
479		addComment: function(){
480			var self = this;
481
482			nhComment.getInfo(self.config);
483
484			var loginRequired = typeof(self.config.login_required) != _UNDEFINED ? self.config.login_required : 0;
485			self.content = $.trim(self.contentElement.val());
486			self.images = [];
487
488			if(self.content.length == 0){
489				nhMain.showAlert(_ERROR, nhMain.getLabel('vui_long_nhap_noi_dung_binh_luan'));
490				self.contentElement.focus();
491				return false;
492			}
493
494			
495			var itemComment = self.contentElement.closest('li[nh-comment-item]');
496			var parent_id = itemComment.length > 0 ? itemComment.attr('nh-comment-item') : null;
497
498			if(loginRequired == 1 && !nhComment.info.logged){
499				nhMain.showAlert(_ERROR, nhMain.getLabel('vui_long_dang_nhap_tai_khoan_de_su_dung_chuc_nang_nay'), function(){
500					nhComment.loginModal.modal('show');
501					nhComment.loginModal.find('input[name="redirect"]').val(window.location.href);
502				});
503				return false;
504			}
505
506			if (loginRequired == 0 && !nhMain.utilities.notEmpty(nhComment.info.full_name)) {
507				self.triggerAdd = true;
508				nhComment.infoModal.modal('show');
509				return false;
510			}
511			
512			var wrapInput = self.contentElement.closest('.edit-comment');
513			wrapInput.find('li[nh-item-comment-image]').each(function(index) {
514				if($(this).hasClass('loading')){
515					nhMain.showAlert(_SUCCESS, nhMain.getLabel('vui_long_cho_he_thong_dang_tai_anh_binh_luan'));
516					return false;
517				}
518				if($(this).find('img.img-comment').length > 0){
519					self.images.push($(this).find('img.img-comment').attr('src'));
520				}			  	
521			});
522
523			var data = {
524				content: self.content,
525				parent_id: parent_id,
526				type_comment: _COMMENT,
527				rating: self.rating,
528				images: self.images,
529				block_code: self.block_code
530			}
531			
532  	    	nhComment.ajaxAddComment(data, function(response){
533  	    		var code = typeof(response.code) != _UNDEFINED ? response.code : _ERROR;
534	        	if (code == _ERROR){
535	        		var message = typeof(response.message) != _UNDEFINED ? response.message : '';
536	        		nhMain.showAlert(_ERROR, message);
537	        	}
538
539	        	if (code == _SUCCESS) {
540	        		if(self.config.awaiting_approval > 0){
541						nhMain.showAlert(_SUCCESS, nhMain.getLabel('cam_on_ban_da_gui_binh_luan_cho_chung_toi_quan_tri_vien_se_xet_duyet_binh_luan_cua_ban_truoc_khi_dang_tai'));
542					}else{
543						var wrapList = null;
544						if(itemComment.length > 0){
545							var numberReply = itemComment.find('.number-reply:first').text();
546							if($.isNumeric(numberReply)){
547								numberReply ++;
548							}else{
549								numberReply = 1;
550							}
551							itemComment.find('.number-reply:first').text(numberReply);
552
553							if(itemComment.find('.list-reply').length == 0){
554								itemComment.find('.edit-comment').before(self.template.wrapReply);
555							}							
556							wrapList = itemComment.find('.list-reply');
557						}
558
559						var data = typeof(response.data) != _UNDEFINED ? response.data : '';
560						self.appendComment(data, wrapList, {load_first: parent_id > 0 ? false : true});
561					}
562					self.clearBoxComment();
563	            }
564	            
565  	    	});
566		},
567		likeComment: function(commentId = null, callback = null){
568			var self = this;
569
570			if (typeof(callback) != 'function') {
571 	        	callback = function () {};
572  	    	}
573
574			if(!commentId > 0){
575				nhMain.showLog(nhMain.getLabel('khong_lay_duoc_ID_binh_luan'));
576				return false;
577			}
578
579			var loginRequired = typeof(self.config.login_required) != _UNDEFINED ? self.config.login_required : 0;
580			if(loginRequired == 1 && !nhComment.info.logged){
581				nhMain.showAlert(_ERROR, nhMain.getLabel('vui_long_dang_nhap_tai_khoan_de_su_dung_chuc_nang_nay'));
582				nhComment.loginModal.modal('show');
583				nhComment.loginModal.find('input[name="redirect"]').val(window.location.href);
584				return false;
585			}
586			
587			if(typeof($.cookie(_LIKE_COMMENT)) == _UNDEFINED){
588				$.cookie(_LIKE_COMMENT, JSON.stringify([]), {expires: self.config.expires_cookie});
589			}
590
591			var type = null;					
592			if($.inArray(parseInt(commentId), JSON.parse($.cookie(_LIKE_COMMENT))) == -1){
593				type = _LIKE;				
594			}else{
595				type = _DISLIKE;				
596			}
597
598			nhMain.callAjax({
599	    		async: false,
600				url: '/comment/like',
601				data: {
602					comment_id: commentId,
603					type: type
604				},
605			}).done(function(response) {
606				var code = typeof(response.code) != _UNDEFINED ? response.code : _ERROR;
607	        	var message = typeof(response.message) != _UNDEFINED ? response.message : '';
608	        	var data = typeof(response.data) != _UNDEFINED ? response.data : '';
609	        	var id = typeof(data.id) != _UNDEFINED ? data.id : null;
610	        	var type = typeof(data.type) != _UNDEFINED ? data.type : null;
611
612	        	if (code == _ERROR){
613	        		nhMain.showAlert(_ERROR, message);
614	        	}
615
616	        	if (code == _SUCCESS) {
617	        		if(id > 0){
618	        			var listLiked = JSON.parse($.cookie(_LIKE_COMMENT));
619		        		if(type == _DISLIKE){
620		        			listLiked.splice( $.inArray(id, listLiked), 1);
621		        		}else{
622		        			listLiked.push(id);
623		        		}
624		        		$.cookie(_LIKE_COMMENT, JSON.stringify(listLiked), {expires: self.config.expires_cookie});
625	        		}
626	        		
627	        		callback(data);
628	            }
629			});
630		},
631		loadComment: function(params = {}){
632			var self = this;
633  	    	var parent_id = typeof(params.parent_id) != _UNDEFINED ? parseInt(params.parent_id) : null;
634
635			nhComment.ajaxLoadComment(
636  	    	{
637  	    		parent_id: parent_id,
638  	    		page: typeof(params.page) != _UNDEFINED ? params.page : null,
639  	    		type_comment: _COMMENT,
640  	    		number_record: typeof(self.config.number_record) != _UNDEFINED ? self.config.number_record : null,
641  	    		sort_field: typeof(self.config.sort_field) != _UNDEFINED ? self.config.sort_field : null,
642  	    		sort_type: typeof(self.config.sort_type) != _UNDEFINED ? self.config.sort_type : null,
643  	    	}, 
644  	    	{
645  	    		show_loading: typeof(params.show_loading) != _UNDEFINED ? Boolean(params.show_loading) : true
646  	    	},
647  	    	function(response){
648  	    		var code = typeof(response.code) != _UNDEFINED ? response.code : _ERROR;
649	        	var data = typeof(response.data) != _UNDEFINED ? response.data : {};
650
651	        	if (code == _ERROR){
652	        		var message =  typeof(response.message) != _UNDEFINED ? response.message : null;
653	        		nhMain.showLog(message);
654	        	}
655	        	
656	        	if (code == _SUCCESS && nhMain.utilities.notEmpty(data.comments)) {
657	        		var wrapReplyElement = null;
658					if(parent_id > 0){
659						wrapReplyElement = self.wrapElement.find('li[nh-comment-item="' + parent_id + '"]').find('.list-reply');
660					}
661
662					var comments = typeof(data.comments) != _UNDEFINED ? data.comments : [];
663					$.each(comments, function( index, comment) {						
664						self.appendComment(comment, wrapReplyElement);
665					});
666
667					var pagination = typeof(data[_PAGINATION]) != _UNDEFINED ? data[_PAGINATION] : [];
668					var total = typeof(pagination.total) ? parseInt(pagination.total) : 0;
669					var page = typeof(pagination.page) ? parseInt(pagination.page) : 0;
670					var pages = typeof(pagination.pages) ? parseInt(pagination.pages) : 0;					
671
672					if(page < pages){
673						if(parent_id > 0){
674							var replyRatingElement = self.wrapElement.find('li[nh-comment-item="' + parent_id + '"]');
675							if(replyRatingElement.length > 0 && replyRatingElement.find('[nh-comment-more]').length == 0){
676								replyRatingElement.find('.child-reply').after(self.template.moreItem);
677							}							
678							replyRatingElement.find('[nh-comment-more]').attr('nh-comment-more', page + 1);
679						}else{
680							if(self.wrapElement.find('> [nh-comment-more]').length == 0){
681								self.listElement.after(self.template.moreItem);
682							}
683							self.wrapElement.find('> [nh-comment-more]').attr('nh-comment-more', page + 1);
684						}						
685					} else { 
686						self.wrapElement.find('[nh-comment-more]').remove();
687					}
688
689					self.wrapElement.find('[nh-total-comment]').text(nhMain.utilities.parseNumberToTextMoney(total));
690	            }
691  	    	});
692		},
693		appendComment: function(comment = {}, wrapReplyElement = null, params = {}){
694			var self = this;
695				
696			var loadFirst = typeof(params.load_first) != _UNDEFINED ? Boolean(params.load_first) : false;
697
698			var wrapElement = null;
699			var htmlItem = null;
700			var appendItem = null;
701			if(!nhMain.utilities.notEmpty(wrapReplyElement)){
702				wrapElement = self.listElement;
703				htmlItem = self.template.item;
704			}else{
705				wrapElement = wrapReplyElement;
706				htmlItem = self.template.itemReply;
707			}
708
709			if(loadFirst){
710				wrapElement.prepend(htmlItem);
711				appendItem = wrapElement.find('li[nh-comment-item]:first-child');
712			}else{
713				wrapElement.append(htmlItem);
714				appendItem = wrapElement.find('li[nh-comment-item]:last-child');
715			}
716			if(appendItem.length == 0) return;
717
718			var commentId = typeof(comment.id) != _UNDEFINED ? parseInt(comment.id) : null;
719			var fullName = typeof(comment.full_name) != _UNDEFINED ? comment.full_name : '';
720			var content = typeof(comment.content) != _UNDEFINED ? comment.content : '';
721			var time = typeof(comment.time) != _UNDEFINED ? comment.time : '';
722			var fullTime = typeof(comment.full_time) != _UNDEFINED ? comment.full_time : '';
723			var numberReply = typeof(comment.number_reply) != _UNDEFINED ? comment.number_reply : null;
724			var numberLike = typeof(comment.number_like) != _UNDEFINED ? comment.number_like : null;
725			var images = typeof(comment.images) != _UNDEFINED ? comment.images : [];
726			var isAdmin = typeof(comment.is_admin) != _UNDEFINED ? parseInt(comment.is_admin) : 0;
727
728
729			if(!nhMain.utilities.notEmpty(fullName) || !nhMain.utilities.notEmpty(content)) return;
730
731			var letterFirst = fullName.slice(0, 1);
732
733			appendItem.attr('nh-comment-item', commentId);
734			appendItem.find('.post-author .name-author').text(fullName);
735			appendItem.find('.post-author .letter-first').text(letterFirst);			
736			appendItem.find('.comment-content .inner-content').html(content.replace(/\n/g, '<br />'));
737			appendItem.find('.comment-content .post-date').text(time);
738			appendItem.find('.comment-content .number-reply').text(numberReply);
739			appendItem.find('.comment-content .number-like').text(numberLike);
740
741			if(isAdmin){				
742				appendItem.find('.post-author').append('<span class="is-admin">'+ nhMain.getLabel('quan_tri_vien') +'</span>')
743			}
744
745			if(images.length > 0){
746				appendItem.find('.comment-content .inner-content').after('<div class="album-images"></div>');
747				var wrapAlbum = appendItem.find('.album-images');
748				$.each(images, function(index, image) {
749					var thumb = nhMain.utilities.getThumbImage(image);
750					wrapAlbum.append('<a href="' + nhMain.cdnUrl + image + '"><img class="image-comment" src="' + nhMain.cdnUrl + thumb + '" ></a>');
751				});
752
753				wrapAlbum.lightGallery({});
754			}
755
756			var loginRequired = typeof(self.config.login_required) != _UNDEFINED ? self.config.login_required : 0;
757			if (loginRequired == 0) {
758				var listLiked = typeof($.cookie(_LIKE_COMMENT)) != _UNDEFINED ? JSON.parse($.cookie(_LIKE_COMMENT)) : [];
759				if($.inArray(commentId, listLiked) > -1){
760					appendItem.find('.inner-like').addClass('liked');
761				}
762			}
763		},
764		showImagesSelect: function(input = null){
765			var self = this;
766			if(input == null || typeof(input.files) == _UNDEFINED){
767				return false;
768			}			
769
770			var wrapComment = $(input).closest('.edit-comment');
771			var boxComment = wrapComment.find('.box-comment');
772			if(wrapComment.length == 0 || boxComment.length == 0){
773				return false;
774			}
775
776			var wrapAlbum = wrapComment.find('.comment-images');
777			if(wrapAlbum.length == 0){
778				boxComment.after(self.template.wrapListImageSelect);
779				wrapAlbum = wrapComment.find('.comment-images');
780			}
781			wrapAlbum.html('');
782
783			$.each(input.files, function(index, file) {
784				if(index >= nhComment.config.max_number_files) return;
785
786				var fileReader = new FileReader();
787				fileReader.readAsDataURL(file);
788				fileReader.onload = function(e) {
789			        self.appendImageSelect(fileReader.result, input);
790			    }				
791			});
792			
793			$.each(input.files, function(index, file) {
794				if(index >= nhComment.config.max_number_files) return;
795
796				var formData = new FormData();
797				formData.append('file', file);
798				formData.append('path', _COMMENT);
799
800				nhComment.ajaxUploadImage(formData, function(data){
801					var urlImage = typeof(data.url) != _UNDEFINED ? data.url : null;
802	        		var liElement = wrapAlbum.find('li:eq('+ index +')');
803					if(liElement.length > 0){
804						liElement.removeClass('loading');
805						liElement.find('img.img-comment').attr('src', nhMain.cdnUrl + urlImage);
806					}
807				});
808			});
809		},
810		appendImageSelect: function(urlImage = null, input = null, params = {}){
811			var self = this;
812
813			var wrapAlbum = $(input).closest('.edit-comment').find('.comment-images');
814			if(wrapAlbum.length == 0){
815				return false;
816			}
817
818			if(urlImage == null || typeof(urlImage) == _UNDEFINED || urlImage.length == 0){
819				return false;
820			}
821
822			wrapAlbum.append(self.template.imageSelect);
823			wrapAlbum.find('li:last-child img.img-comment').attr('src', urlImage);
824			wrapAlbum.removeClass('d-none');
825
826			if(typeof(params.uploaded) != _UNDEFINED && params.uploaded > 0){
827				wrapAlbum.find('li:last-child').removeClass('loading');
828			}
829		},
830		clearBoxComment: function(){
831			var self = this;
832
833			var wrap = self.contentElement.closest('.edit-comment');
834			if(wrap.length == 0){
835				return false;
836			}
837
838			self.contentElement.val('');
839			self.contentElement.css('height', self.scrollHeightDefault + 'px')
840			
841			wrap.find('.comment-images').remove();
842		},
843		showInfo: function(){
844			var self = this;
845			
846			nhComment.getInfo(self.config);
847			if(!nhMain.utilities.notEmpty(nhComment.info.full_name)) return false;
848
849			self.wrapElement.find('[nh-comment-fullname]').text(nhComment.info.full_name);
850			self.wrapElement.find('[nh-comment-info]').removeClass('d-none');
851		}
852	},	
853	rating: {
854		config: {},
855		block_code: null,
856		content: null,
857		rating: null,
858		triggerAdd: false,
859		wrapElement: null,
860		listElement: null,
861		formRating: null,
862		contentElement: null,
863		ratingItem: null,
864		template:{
865			item: '\
866				<li nh-rating-item="" is-parent="true" class="item">\
867					<div class="box-rating">\
868						<div class="author-info">\
869							<span class="letter-first"></span>\
870							<div>\
871								<span class="post-author"></span>\
872								<br />\
873								<span class="post-date"></span>\
874							</div>\
875						</div>\
876						<div class="rating-content">\
877			                <div class="star-rating">\
878			                    <span style="width:100%"></span>\
879			                </div>\
880							<div class="description"></div>\
881							<div class="btn-action">\
882								<div class="inner-reply">\
883									<i class="iconsax isax-message-text"></i>\
884									<span class="number-reply"></span> '+ nhMain.getLabel('tra_loi') +'\
885								</div>	\
886							</div>\
887						</div>\
888					</div>\
889				</li>',
890			itemReply: '\
891				<li nh-rating-item="" class="item">\
892					<div class="author-info">\
893						<div class="meta">\
894							<span class="post-author"></span> - \
895							<span class="post-date"></span>\
896						</div>\
897					</div>\
898					<div class="rating-content">\
899						<div class="description"></div>\
900					</div>\
901				</li>',
902			moreItem: '<a nh-comment-more="" class="comment-more" href="javascript:;">'+ nhMain.getLabel('xem_them_danh_gia') +'</a>',
903			formRating: '',
904			inputReplyRating: '\
905				<div class="rating-form">\
906			    	<div class="form-group">\
907						<textarea nh-input-rating placeholder="'+ nhMain.getLabel('nhan_xet_cua_ban_ve_san_pham_nay') +'"></textarea>\
908					</div>\
909					<div>\
910				        <span nh-btn-reply-rating class="btn btn-dark rounded-0">'+ nhMain.getLabel('gui_danh_gia') +'</span>\
911					</div>\
912				</div>',
913			wrapReply: '<ul class="child-reply"></ul>',	
914			imageSelect: '\
915				<li nh-item-rating-image class="loading">\
916					<img class="img-comment" src="">\
917					<i class="close-image">x</i>\
918				</li>'
919		},		
920		init: function(){
921			var self = this;
922
923			self.wrapElement = $('[nh-rating]');
924			self.formRating = $('form[nh-form-rating]');
925			self.listElement = self.wrapElement.find('[nh-list-rating]');
926			self.contentElement = self.formRating.find('textarea[nh-input-rating]');
927
928			if(self.wrapElement.length == 0) return false;
929
930			var configBlock = nhMain.utilities.parseJsonToObject(self.wrapElement.attr('nh-rating'));
931			if($.isEmptyObject(configBlock)){
932				nhMain.showLog(nhMain.getLabel('chuc_nang_danh_gia_thieu_dieu_kien_de_hoat_dong'));
933				return false;
934			}
935			$.extend(self.config, configBlock);
936
937			var loginRequired = typeof(self.config.login_required) != _UNDEFINED ? self.config.login_required : 0;
938			if(loginRequired == 1 && nhComment.loginModal.length == 0){
939				nhMain.showLog(nhMain.getLabel('chuc_nang_danh_gia_thieu_dieu_kien_de_hoat_dong'));
940				return false;
941			}
942
943			if(self.listElement.length == 0){
944				nhMain.showLog(nhMain.getLabel('chuc_nang_danh_gia_thieu_dieu_kien_de_hoat_dong'));
945				return false;
946			}
947
948			var wrapBlock = self.wrapElement.closest('[nh-block]');
949			if(wrapBlock.length > 0 && wrapBlock.attr('nh-block').length > 0){
950				self.block_code = wrapBlock.attr('nh-block');
951			}
952
953			self.showInfo();
954
955			self.event();			
956			self.loadCommentRating({show_loading: false});
957		},
958		event: function(){
959			var self = this;
960			
961			nhMain.validation.phoneVn();
962			var validatorRating = self.formRating.validate({
963				ignore: ':hidden',
964				rules: {
965					full_name: {
966						required: true,
967						minlength: 6,
968						maxlength: 255
969					},
970					email: {
971						required: true,
972						email: true,
973	                    minlength: 10,
974	                    maxlength: 255
975					},
976					phone: {
977						required: true,
978						phoneVN: true
979					},
980					content: {
981						required: true,
982						minlength: 20,
983						maxlength: 1000
984					}
985				},
986				messages: {
987					full_name: {
988	                    required: nhMain.getLabel('vui_long_nhap_thong_tin'),
989	                    minlength: nhMain.getLabel('thong_tin_nhap_qua_ngan'),
990	                    maxlength: nhMain.getLabel('thong_tin_nhap_qua_dai')
991	                },
992	                email: {
993	                	required: nhMain.getLabel('vui_long_nhap_thong_tin'),
994	                    email: nhMain.getLabel('email_chua_dung_dinh_dang'),
995	                	minlength: nhMain.getLabel('thong_tin_nhap_qua_ngan'),
996	                    maxlength: nhMain.getLabel('thong_tin_nhap_qua_dai')
997	                },
998	                phone: {
999	                    required: nhMain.getLabel('vui_long_nhap_thong_tin'),
1000	                    phoneVN: nhMain.getLabel('so_dien_thoai_chua_chinh_xac')
1001	                },
1002	                content: {
1003	                    required: nhMain.getLabel('vui_long_nhap_thong_tin'),
1004	                    minlength: nhMain.getLabel('thong_tin_nhap_qua_ngan'),
1005	                    maxlength: nhMain.getLabel('thong_tin_nhap_qua_dai')
1006	                }
1007	            },
1008	            errorPlacement: function(error, element) {
1009	                var group = element.closest('.input-group');
1010	                if (group.length) {
1011	                    group.after(error.addClass('invalid-feedback'));
1012	                }else{                	
1013	                    element.after(error.addClass('invalid-feedback'));
1014	                }
1015	            },
1016				invalidHandler: function(event, validator) {
1017					validatorRating.errorList[0].element.focus();
1018				},
1019			});
1020
1021			self.wrapElement.on('click', '[nh-btn-send-rating]', function(e){
1022				e.preventDefault();
1023				if (validatorRating.form()) {
1024
1025					self.ratingItem = null;
1026					self.contentElement = self.formRating.find('textarea[nh-input-rating]');
1027
1028					nhComment.setInfo({
1029						full_name: self.formRating.find('input[name="full_name"]').val(),
1030						email: self.formRating.find('input[name="email"]').val(),
1031						phone: self.formRating.find('input[name="phone"]').val(),
1032						full_name: self.formRating.find('input[name="full_name"]').val(),
1033					});
1034
1035					self.addCommentRating();
1036				}				
1037			});
1038
1039			self.wrapElement.on('click', '[nh-btn-reply-rating]', function(e){
1040				e.preventDefault();
1041
1042				self.ratingItem = $(this).closest('li[nh-rating-item]');
1043				if(self.ratingItem.length == 0) return false;
1044
1045				self.contentElement = self.ratingItem.find('textarea[nh-input-rating]');
1046				if(self.contentElement.length == 0) return false;
1047
1048				self.addCommentRating();
1049			});
1050
1051			self.wrapElement.on('click', '.inner-reply', function(e){
1052				self.ratingItem = $(this).closest('li[nh-rating-item][is-parent]');
1053				if(self.ratingItem.length == 0) return false;
1054
1055				var ratingId = self.ratingItem.attr('nh-rating-item');
1056				if(!nhMain.utilities.notEmpty(ratingId)) return false;
1057
1058				if(self.ratingItem.find('.entry-reply').length == 0){
1059					self.ratingItem.find('.rating-content').append('<div class="entry-reply"></div>');
1060				}
1061
1062				var replyWrap = self.ratingItem.find('.entry-reply');
1063				var numberReply = $(this).find('.number-reply').text();
1064				var loadReply = false;
1065				if(nhMain.utilities.notEmpty(numberReply) && replyWrap.find('.child-reply').length == 0) {
1066					loadReply = true;
1067					replyWrap.prepend(self.template.wrapReply);
1068				}
1069
1070				if(replyWrap.find('.rating-form').length == 0){
1071					replyWrap.append(self.template.inputReplyRating);
1072				}
1073
1074				self.contentElement = self.ratingItem.find('[nh-input-rating]');
1075				self.contentElement.focus();
1076
1077				if(loadReply){
1078					self.loadCommentRating({parent_id: ratingId});
1079				}
1080			});
1081
1082			self.wrapElement.on('click', '[nh-comment-more]', function(e){
1083				e.preventDefault();
1084
1085				self.ratingItem = $(this).closest('li[nh-rating-item]');
1086
1087				var page = $(this).attr('nh-comment-more');
1088				if(!page > 0) return;
1089
1090				var commentId = self.ratingItem.length > 0 ? self.ratingItem.attr('nh-rating-item') : null;
1091				self.loadCommentRating({
1092					parent_id: commentId,
1093					page: page
1094				});
1095			});
1096
1097			self.wrapElement.on('click', '[nh-btn-show-rating]', function(e){
1098				var listRating = !$.isEmptyObject($.cookie(_RATING_LIST)) ? JSON.parse($.cookie(_RATING_LIST)) : [];
1099				if($.inArray(window.location.pathname, listRating) > -1){
1100					nhMain.showAlert(_SUCCESS, nhMain.getLabel('ban_da_danh_gia_san_pham_nay_roi'));
1101					return false
1102				};
1103				self.formRating.collapse('toggle');
1104			});
1105
1106			self.wrapElement.on('click', '[nh-trigger-upload]', function(e){
1107				self.formRating.find('input[nh-input-rating-images]').trigger('click');
1108			});
1109
1110			self.wrapElement.on('change', '[nh-input-rating-images]', function(e) {
1111				self.showImagesRating(this);
1112			});
1113
1114			self.wrapElement.on('change', '[nh-review-star] input[type="radio"]', function(e) {
1115				var star = nhMain.utilities.parseInt($(this).val());
1116				if(star > 5 ) star = 0;
1117
1118				self.rating = star;
1119			});
1120
1121			self.wrapElement.on('click', '.comment-images .close-image', function(e){
1122				$(this).closest('li').remove();
1123			});
1124		},
1125		addCommentRating: function(){
1126			var self = this;
1127
1128			nhComment.getInfo();
1129
1130			self.content = $.trim(self.contentElement.val());
1131			self.images = [];
1132
1133			if(self.content.length == 0){
1134				nhMain.showAlert(_ERROR, nhMain.getLabel('vui_long_nhap_noi_dung_binh_luan'));
1135				self.contentElement.focus();
1136				return false;
1137			}
1138
1139			var loginRequired = typeof(self.config.login_required) != _UNDEFINED ? self.config.login_required : 0;
1140			if(loginRequired == 1 && !nhComment.info.logged){
1141				nhMain.showAlert(_ERROR, nhMain.getLabel('vui_long_dang_nhap_tai_khoan_de_su_dung_chuc_nang_nay'), function(){
1142					nhComment.loginModal.modal('show');
1143					nhComment.loginModal.find('input[name="redirect"]').val(window.location.href);
1144				});
1145				return false;
1146			}
1147
1148			if (loginRequired == 0 && !nhMain.utilities.notEmpty(nhComment.info.full_name)) {
1149				self.triggerAdd = true;
1150				nhComment.infoModal.modal('show');
1151				return false;
1152			}
1153
1154			var parent_id = null;
1155			if(self.contentElement.closest('li[nh-rating-item]').length > 0){
1156				var parent_id = self.contentElement.closest('li[nh-rating-item]').attr('nh-rating-item');
1157			}
1158
1159			if(parent_id != null){
1160				self.rating = null;
1161			}
1162			
1163			self.formRating.find('li[nh-item-rating-image]').each(function(index) {
1164				if($(this).hasClass('loading')){
1165					nhMain.showAlert(_SUCCESS, nhMain.getLabel('vui_long_cho_he_thong_dang_tai_anh_binh_luan'));
1166					return false;
1167				}
1168
1169				if($(this).find('img.img-comment').length > 0){
1170					self.images.push($(this).find('img.img-comment').attr('src'));
1171				}
1172			});
1173
1174			var data = {
1175				content: self.content,
1176				parent_id: parent_id,
1177				type_comment: _RATING,
1178				rating: self.rating,
1179				images: self.images,
1180				block_code: self.block_code
1181			}
1182			
1183  	    	nhComment.ajaxAddComment(data, function(response){
1184  	    		var code = typeof(response.code) != _UNDEFINED ? response.code : _ERROR;
1185	        	if (code == _ERROR){
1186	        		var message = typeof(response.message) != _UNDEFINED ? response.message : '';
1187	        		nhMain.showAlert(_ERROR, message);
1188	        	}
1189
1190	        	if (code == _SUCCESS) {
1191	        		if(self.config.awaiting_approval > 0){
1192						nhMain.showAlert(_SUCCESS, nhMain.getLabel('cam_on_ban_da_gui_binh_luan_cho_chung_toi_quan_tri_vien_se_xet_duyet_binh_luan_cua_ban_truoc_khi_dang_tai'));
1193					}else{
1194						var wrapList = null;
1195						if(nhMain.utilities.notEmpty(self.ratingItem)){
1196							var numberReply = self.ratingItem.find('.number-reply:first').text();
1197							if($.isNumeric(numberReply)){
1198								numberReply ++;
1199							}else{
1200								numberReply = 1;
1201							}
1202							self.ratingItem.find('.number-reply:first').text(numberReply);
1203
1204							if(self.ratingItem.find('.child-reply').length == 0){
1205								self.ratingItem.find('.rating-form').before(self.template.wrapReply);
1206							}
1207							var wrapList = self.ratingItem.find('.child-reply');
1208						}
1209						
1210						var data = typeof(response.data) != _UNDEFINED ? response.data : '';
1211						self.appendCommentRating(data, wrapList, {load_first: parent_id > 0 ? false : true});
1212					}
1213
1214					if(!parent_id > 0){
1215						var listRating = nhMain.utilities.notEmpty($.cookie(_RATING_LIST)) ? JSON.parse($.cookie(_RATING_LIST)) : [];
1216						if($.inArray(window.location.pathname, listRating) == -1){
1217							listRating.push(window.location.pathname);
1218							$.cookie(_RATING_LIST, JSON.stringify(listRating), {expires: self.config.expires_cookie});
1219						}						
1220					}
1221
1222					self.clearBoxRating();
1223	            }
1224	            
1225  	    	});
1226		},
1227		loadCommentRating: function(params = {}){
1228			var self = this;
1229  	    	var parent_id = typeof(params.parent_id) != _UNDEFINED ? params.parent_id : null;
1230
1231  	    	nhComment.ajaxLoadComment(
1232  	    	{
1233  	    		parent_id: parent_id,
1234  	    		page: typeof(params.page) != _UNDEFINED ? params.page : null,
1235  	    		type_comment: _RATING,
1236  	    		number_record: typeof(self.config.number_record) != _UNDEFINED ? self.config.number_record : null,
1237  	    		sort_field: typeof(self.config.sort_field) != _UNDEFINED ? self.config.sort_field : null,
1238  	    		sort_type: typeof(self.config.sort_type) != _UNDEFINED ? self.config.sort_type : null,
1239  	    	}, 
1240  	    	{
1241  	    		show_loading: typeof(params.show_loading) != _UNDEFINED ? Boolean(params.show_loading) : true
1242  	    	},
1243  	    	function(response){
1244  	    		var code = typeof(response.code) != _UNDEFINED ? response.code : _ERROR;
1245	        	var data = typeof(response.data) != _UNDEFINED ? response.data : {};
1246
1247	        	if (code == _ERROR){
1248	        		var message =  typeof(response.message) != _UNDEFINED ? response.message : null;
1249	        		nhMain.showLog(message);
1250	        	}
1251	        	
1252	        	if (code == _SUCCESS && nhMain.utilities.notEmpty(data.comments)) {
1253	        		var wrapReplyElement = null;
1254					if(parent_id > 0){
1255						wrapReplyElement = self.wrapElement.find('li[nh-rating-item="' + parent_id + '"]').find('.child-reply');
1256					}
1257
1258					var comments = typeof(data.comments) != _UNDEFINED ? data.comments : [];
1259					$.each(comments, function( index, comment) {						
1260						self.appendCommentRating(comment, wrapReplyElement);
1261					});
1262
1263					var pagination = typeof(data[_PAGINATION]) != _UNDEFINED ? data[_PAGINATION] : [];
1264					var page = typeof(pagination.page) ? parseInt(pagination.page) : 0;
1265					var pages = typeof(pagination.pages) ? parseInt(pagination.pages) : 0;
1266					if(page < pages){
1267						if(parent_id > 0){
1268							var replyRatingElement = self.wrapElement.find('li[nh-rating-item="' + parent_id + '"]');
1269							if(replyRatingElement.length > 0 && replyRatingElement.find('[nh-comment-more]').length == 0){
1270								replyRatingElement.find('.child-reply').after(self.template.moreItem);
1271							}							
1272							replyRatingElement.find('[nh-comment-more]').attr('nh-comment-more', page + 1);
1273						}else{
1274							if(self.wrapElement.find('> [nh-comment-more]').length == 0){
1275								self.listElement.after(self.template.moreItem);
1276							}
1277							self.wrapElement.find('> [nh-comment-more]').attr('nh-comment-more', page + 1);
1278						}						
1279					} else {
1280						self.wrapElement.find('[nh-comment-more]').remove();
1281					}
1282	            }
1283  	    	});
1284		},
1285		appendCommentRating: function(comment = {}, wrapReplyElement = null, params = {}){
1286			var self = this;
1287				
1288			var loadFirst = typeof(params.load_first) != _UNDEFINED ? Boolean(params.load_first) : false;
1289
1290			var wrapElement = null;
1291			var htmlItem = null;
1292			var appendItem = null;
1293			if(nhMain.utilities.notEmpty(wrapReplyElement)){				
1294				wrapElement = wrapReplyElement;
1295				htmlItem = self.template.itemReply;
1296			}else{
1297				wrapElement = self.listElement;
1298				htmlItem = self.template.item;
1299			}
1300
1301			if(loadFirst){
1302				wrapElement.prepend(htmlItem);
1303				appendItem = wrapElement.find('li[nh-rating-item]:first-child');
1304			}else{
1305				wrapElement.append(htmlItem);
1306				appendItem = wrapElement.find('li[nh-rating-item]:last-child');
1307			}
1308
1309			if(appendItem.length == 0) return;
1310
1311			var commentId = typeof(comment.id) != _UNDEFINED ? parseInt(comment.id) : null;
1312			var fullName = typeof(comment.full_name) != _UNDEFINED ? comment.full_name : '';
1313			var content = typeof(comment.content) != _UNDEFINED ? comment.content : '';
1314			var time = typeof(comment.time) != _UNDEFINED ? comment.time : '';
1315			var fullTime = typeof(comment.full_time) != _UNDEFINED ? comment.full_time : '';
1316			var numberReply = typeof(comment.number_reply) != _UNDEFINED ? comment.number_reply : null;
1317			var numberLike = typeof(comment.number_like) != _UNDEFINED ? comment.number_like : null;
1318			var images = typeof(comment.images) != _UNDEFINED ? comment.images : [];
1319			var isAdmin = typeof(comment.is_admin) != _UNDEFINED ? parseInt(comment.is_admin) : 0;
1320			var rating = typeof(comment.rating) != _UNDEFINED ? parseInt(comment.rating) : 0;
1321			var widthRating = 0;
1322			if(rating >= 1 && rating <= 5){
1323				widthRating = rating * 20;
1324			}
1325
1326			if(!nhMain.utilities.notEmpty(fullName) || !nhMain.utilities.notEmpty(content)) return;
1327
1328			appendItem.attr('nh-rating-item', commentId);
1329			appendItem.find('.author-info .post-author').text(fullName);
1330			appendItem.find('.author-info .letter-first').text(nhComment.convertFullNameToSpell(fullName));
1331			appendItem.find('.author-info .post-date').text(time);
1332			appendItem.find('.rating-content .description').text(content);
1333			appendItem.find('.rating-content .number-reply').text(numberReply);
1334			appendItem.find('.rating-content .number-like').text(numberLike);
1335
1336			appendItem.find('.star-rating span').css('width', widthRating + '%');
1337
1338			if(isAdmin){
1339				appendItem.find('.post-author').append('<span class="is-admin">'+ nhMain.getLabel('quan_tri_vien') +'</span>');
1340			}
1341
1342			if(images.length > 0){
1343				appendItem.find('.rating-content .description').after('<div class="album-images"></div>');
1344				var wrapAlbum = appendItem.find('.album-images');
1345				$.each(images, function(index, image) {
1346					var thumb = nhMain.utilities.getThumbImage(image);
1347					wrapAlbum.append('<a href="' + nhMain.cdnUrl + image + '"><img class="image-comment" src="' + nhMain.cdnUrl + thumb + '" ></a>');
1348				});
1349
1350				wrapAlbum.lightGallery({});
1351			}
1352		},
1353		clearBoxRating: function(){
1354			var self = this;
1355
1356			if(nhMain.utilities.notEmpty(self.contentElement)){
1357				self.contentElement.val('');
1358			};
1359			
1360			self.formRating.find('.comment-images').remove();
1361			self.formRating.collapse('hide');
1362		},
1363		showImagesRating: function(input = null){
1364			var self = this;
1365
1366			if(input == null || typeof(input.files) == _UNDEFINED){
1367				return false;
1368			}
1369
1370			var wrapAlbum = self.formRating.find('.comment-images');
1371			wrapAlbum.html('');
1372
1373			$.each(input.files, function(index, file) {
1374				if(index >= nhComment.config.max_number_files) return;
1375
1376				var fileReader = new FileReader();
1377				fileReader.readAsDataURL(file);
1378				fileReader.onload = function(e) {
1379			        self.appendImageRating(fileReader.result, input);
1380			    }
1381			});
1382
1383			$.each(input.files, function(index, file) {
1384				if(index >= nhComment.config.max_number_files) return;
1385
1386				var formData = new FormData();
1387				formData.append('file', file);
1388				formData.append('path', _RATING);
1389
1390				nhComment.ajaxUploadImage(formData, function(data){
1391					var urlImage = typeof(data.url) != _UNDEFINED ? data.url : null;
1392	        		var liElement = wrapAlbum.find('li:eq('+ index +')');
1393					if(liElement.length > 0){
1394						liElement.removeClass('loading');
1395						liElement.find('img.img-comment').attr('src', nhMain.cdnUrl + urlImage);
1396					}
1397				});
1398			});
1399		},
1400		appendImageRating: function(urlImage = null, input = null, params = {}){
1401			var self = this;
1402
1403			var wrapAlbum = self.formRating.find('.comment-images');
1404			if(wrapAlbum.length == 0) return false;
1405
1406			if(!nhMain.utilities.notEmpty(urlImage)) return false;
1407									
1408			wrapAlbum.append(self.template.imageSelect);
1409			wrapAlbum.find('li:last-child img.img-comment').attr('src', urlImage);
1410			wrapAlbum.removeClass('d-none');
1411
1412			if(typeof(params.uploaded) != _UNDEFINED && params.uploaded > 0){
1413				wrapAlbum.find('li:last-child').removeClass('loading');
1414			}
1415		},
1416		showInfo: function(){
1417			var self = this;
1418			
1419			nhComment.getInfo(self.config);
1420			if(!nhMain.utilities.notEmpty(nhComment.info.full_name)) return false;
1421
1422			self.formRating.find('input[name="full_name"]').val(nhComment.info.full_name);
1423		  	self.formRating.find('input[name="email"]').val(nhComment.info.email);
1424		  	self.formRating.find('input[name="phone"]').val(nhComment.info.phone);
1425		}
1426	}
1427}
1428
1429nhComment.init();

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.