PageSourceSearch

https://txdconstruction.com/wp-content/plugins/txd-construction-costs/txdcc-script.js

js txdconstruction.com collected 2026-10-09 21:44:06 UTC 15,819 bytes, 479 lines download raw bytes

1window.addEventListener('DOMContentLoaded', function(){
2	jQuery(function($){
3		var mangso = ['không','một','hai','ba','bốn','năm','sáu','bảy','tám','chín'];
4		function dochangchuc(so,daydu) {
5			var chuoi = "";
6			chuc = Math.floor(so/10);
7			donvi = so%10;
8			if (chuc>1) {
9				chuoi = " " + mangso[chuc] + " mươi";
10				if (donvi==1) { 
11					chuoi += " mốt";
12				} 
13			} else if (chuc==1) {
14				chuoi = " mười";
15				if (donvi==1) { 
16					chuoi += " một";
17				} 
18			} else if (daydu && donvi>0) {
19				chuoi = " lẻ";
20			}
21			if (donvi==5 && chuc>1) {
22				chuoi += " lăm";
23			} else if (donvi>1||(donvi==1&&chuc==0)) {
24				chuoi += " " + mangso[ donvi ];
25			}
26			return chuoi;
27		}
28		function docblock(so,daydu) {
29			var chuoi = "";
30				tram = Math.floor(so/100);
31				so = so%100;
32			if (daydu || tram>0) {
33				chuoi = " " + mangso[tram] + " trăm";
34				chuoi += dochangchuc(so,true);
35			} else {
36				chuoi = dochangchuc(so,false);
37			}
38			return chuoi;
39		}
40		function dochangtrieu(so,daydu) {
41			var chuoi = "";
42				trieu = Math.floor(so/1000000);
43				so = so%1000000;
44			if (trieu>0) {
45				chuoi = docblock(trieu,daydu) + " triệu";
46				daydu = true;
47			}
48			nghin = Math.floor(so/1000);
49			so = so%1000;
50			if (nghin>0) {
51				chuoi += docblock(nghin,daydu) + " nghìn";
52				daydu = true;
53			}
54			if (so>0) {
55				chuoi += docblock(so,daydu);
56			} return chuoi;
57		}
58		function docso(so) {
59			if (so==0)
60				return mangso[0];
61			var chuoi = "", hauto = "";
62			do {
63				ty = so%1000000000;
64				so = Math.floor(so/1000000000);
65				if (so>0) {
66					chuoi = dochangtrieu(ty,true) + hauto + chuoi;
67				} else {
68					chuoi = dochangtrieu(ty,false) + hauto + chuoi;
69				}
70				hauto = " tá»·";
71			} while (so>0);
72			return chuoi;
73		}
74
75		function format_number(number, decimals=0, thousandsSep=',', decPoint='.', negative=true) {
76			number = (number + '').replace(/[^0-9+\-\.]/g, '');
77			
78			let sigFix = function(number) {
79				number = ''+number;
80				if (number.length > 1) {
81					return number.slice(0, 1) + number.slice(1).replace(/\-|\+/g, '');
82				}
83				return number;
84			}
85
86			if(negative) {
87				number = sigFix(number);
88			} else {
89				number = number.replace(/\-|\+/g,'');
90			}
91
92			let prec = (!isFinite(+decimals)) ? -1 : Math.abs(decimals);
93			let sep = (typeof thousandsSep === 'undefined') ? ',' : thousandsSep;
94
95			if(prec<0) { // là số nguyên
96				number = (number!='') ? parseInt(number.replace(/\./g, '')) : '';
97				number = (''+number).replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);
98			} else {
99				number = parseFloat(number).toFixed(prec);
100				
101				let dec = (typeof decPoint === 'undefined') ? '.' : decPoint;
102				let s = '';
103				let sn = [];
104
105				s = number.split('.');
106				sn[0] = ''+( (s[0]!='')?parseInt(s[0]):'');
107
108				if(s.length>1) {
109					s.shift();
110					let decimals = s.join().replace(/\D/g, '');
111					if(prec>0) {
112						decimals = decimals.slice(0,prec).match(/^\d*[^0]+/);
113						if(decimals) {
114							sn[1] = decimals[0];
115						}
116					}
117				}
118
119				if (sn[0].length > 3) {
120					sn[0] = sn[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);
121				}
122
123				if(sn.length>1) {
124					if (sn[1].length > 3) {
125						sn[1]=sn[1].replace(/\B(?=(?:\d{3})+(?!\d))/g,sep);
126					}
127				}
128				number = sn.join(dec);
129			}
130			return number;
131		}
132		//-------------------------------------------------
133
134		$('.txdcc-input-group-checkbox input[type="checkbox"]').on('change', function(e){
135			//console.log($(this));
136			$(this).parent().siblings().find('input[type="checkbox"]').prop('checked', false);
137		});
138
139		//--------------------------------------------------
140		let chart = null;
141
142		function txdcc_calculate(form) {
143			// if(chart!=null)
144			// 	console.log(Object.keys(chart).length);
145
146			if(chart!=null && Object.keys(chart).length > 0) {
147				chart.destroy();
148			}
149
150			// thông số cấu hình
151			let params = form.data('params');
152
153			// console.log(params);
154
155			// dữ liệu người dùng nhập
156			let client_inputs = new URLSearchParams(form.serialize());
157
158			let length = (client_inputs.get('length')!='')?parseFloat(client_inputs.get('length')):0;
159			let width = (client_inputs.get('width')!='')?parseFloat(client_inputs.get('width')):0;
160			let basement = (client_inputs.get('basement')!='')?parseFloat(client_inputs.get('basement')):0;
161			let floor = (client_inputs.get('floor')!='')?parseFloat(client_inputs.get('floor')):0;
162
163			// tồn tại loại nhà đúng
164			if( params.house_type.hasOwnProperty(client_inputs.get('house_type')) 
165				&& length>=0 
166				&& width>=0 
167				&& floor>=0 ) {				
168				//console.log(params.house_type[client_inputs.get('house_type')]);
169
170				// diện tích mặt đất xây dựng
171				let ground_area = length*width;
172
173				// diện tích sàn xd tầng hầm
174				let underground_area = ground_area*params.ufc*basement;
175
176				// diện tích sàn xd tầng nổi
177				let floor_area = ground_area*floor;
178
179				// diện tích xây dựng
180				let area = underground_area + floor_area;
181
182				// chu vi mặt đất xây dựng
183				let ground_perimeter = 2*(length + width);
184
185				// hiển thị chi phí thiết kế
186				form.find('.txdcc-area').html(format_number(area, 3));
187				form.find('.txdcc-floor-area').html(format_number(floor_area, 3));
188
189				// có design ?
190				let has_design = params.design_type.hasOwnProperty(client_inputs.get('design_type'));
191
192				let design_costs = 0;
193				let exterior_design_price = 0;
194				let interior_design_price = 0;
195				let exterior_design_costs = 0;
196				let interior_design_costs = 0;
197
198				if( has_design ) {
199
200					exterior_design_price = parseInt(params.design_pricing[client_inputs.get('design_type')].ex);
201					exterior_design_costs = area*exterior_design_price;
202
203					interior_design_price = parseInt(params.design_pricing[client_inputs.get('design_type')].in);
204					interior_design_costs = floor_area*interior_design_price;
205
206					design_costs = exterior_design_costs + interior_design_costs;
207					
208				}
209
210				form.find('.txdcc-exterior-design-price').html(format_number(exterior_design_price));
211				form.find('.txdcc-exterior-design-costs').html(format_number(exterior_design_costs,0));
212				
213				form.find('.txdcc-interior-design-price').html(format_number(interior_design_price));
214				form.find('.txdcc-interior-design-costs').html(format_number(interior_design_costs,0));
215
216				form.find('.txdcc-design-costs').html(format_number(design_costs,0));
217
218				// số tim cọc
219				let piles = ground_area * params.pile_table[client_inputs.get('pile_type')].coefficient;
220				//console.log();
221
222				// chiều sâu ép cọc
223				let piles_depth = piles*params.average_pile_depth;
224
225				let pressed_pile_costs = piles_depth*params.pile_table[client_inputs.get('pile_type')].price;
226
227				// Hiển thị chi phí ép cọc
228				form.find('.txdcc-piles-depth').html(format_number(piles_depth,3));
229				
230				form.find('.txdcc-pressed-pile-price').html(format_number(params.pile_table[client_inputs.get('pile_type')].price));
231				
232				form.find('.txdcc-pressed-pile-costs').html(format_number(pressed_pile_costs));
233
234				// Chi phí ép cừ
235				let plank_length = ground_perimeter*params.plank_width;
236				let pressed_plank_costs = 0;
237
238				if(client_inputs.get('pressed_plank')=='on') {
239					form.find('.txdcc-plank-area').html(format_number(plank_length,3));
240					form.find('.txdcc-pressed-plank-price').html(format_number(params.pressed_plank_price));
241					pressed_plank_costs = plank_length*params.pressed_plank_price*params.ppc;
242					
243				} else {
244					pressed_plank_costs = 0;
245					form.find('.txdcc-plank-area').html(0);
246					form.find('.txdcc-pressed-plank-price').html(0);
247				}
248				form.find('.txdcc-pressed-plank-costs').html(format_number(pressed_plank_costs));
249
250				form.find('.txdcc-ground-area').html(format_number(ground_area,3));
251
252				// chi phí móng
253				let foundation_price = parseInt(params.house_pricing.build[client_inputs.get('house_type')].foundation);
254
255				form.find('.txdcc-foundation-price').html(format_number(foundation_price));
256
257				let foundation_costs = ground_area*foundation_price;
258
259				form.find('.txdcc-foundation-costs').html(format_number(foundation_costs))
260
261				// chi phí ngầm
262				let underground_costs = 0;
263				
264				underground_costs = pressed_pile_costs + pressed_plank_costs + foundation_costs;
265
266				form.find('.txdcc-underground-costs').html(format_number(underground_costs));
267
268				// chi phí phần thô
269				// phần thô xây dựng
270				let rough_build_costs = 0;
271				let water_electricity_costs = 0;
272				let rough_costs = 0;
273
274				let rough_build_price = parseInt(params.house_pricing.build[client_inputs.get('house_type')].rough_build);
275				let water_electricity_price = parseInt(params.house_pricing.build[client_inputs.get('house_type')].water_electricity);
276				rough_build_costs = rough_build_price*area;
277				water_electricity_costs = water_electricity_price*area;
278				rough_costs = rough_build_costs+water_electricity_costs;
279
280				form.find('.txdcc-rough-build-price').html(format_number(rough_build_price));
281				form.find('.txdcc-water-electricity-price').html(format_number(water_electricity_price));
282
283				form.find('.txdcc-rough-build-costs').html(format_number(rough_build_costs));
284				form.find('.txdcc-water-electricity-costs').html(format_number(water_electricity_costs));
285				
286				form.find('.txdcc-rough-costs').html(format_number(rough_costs));
287
288				// chi phí hoàn thiện
289				let complete_price = parseInt(params.house_pricing.complete[client_inputs.get('house_type')][client_inputs.get('complete_quality')]);
290				let complete_costs =  complete_price*area;
291				
292				form.find('.txdcc-complete-price').html(format_number(complete_price));
293				form.find('.txdcc-complete-costs').html(format_number(complete_costs));
294
295				// chi phí nội thất
296				let interior_price = parseInt(params.house_pricing.interior[client_inputs.get('house_type')][client_inputs.get('interior_quality')]);
297				let interior_costs =  interior_price*floor_area;
298				
299				form.find('.txdcc-interior-price').html(format_number(interior_price));
300				form.find('.txdcc-interior-costs').html(format_number(interior_costs));
301
302				// tổng chi phí trước dự phòng
303				let costs = design_costs+underground_costs+rough_costs+complete_costs+interior_costs;
304
305				// chi phí dự phòng
306				let contingency_costs = params.contingency_rate*costs;
307				form.find('.txdcc-contingency-costs').html(format_number(contingency_costs));
308
309				// tổng chi phí bao gồm dự phòng
310				let cost = costs + contingency_costs;
311				form.find('.txdcc-cost').html(format_number(cost));
312
313				// vẽ biểu đồ
314				// if(chart!==null)
315				// 	chart.destroy();
316
317				let chart_id = client_inputs.get('chart_id');
318				
319				if(ground_area>0) {
320					chart = new Highcharts.chart(chart_id, {
321						chart: {
322							type: 'pie',
323							options3d: {
324								enabled: true,
325								alpha: 60,
326								beta: 5,
327      							axisLabelPosition: 'auto'
328							}
329						},
330						credits: {
331						    enabled: false
332						},
333						title: {
334							text: '',
335							align: 'left'
336						},
337						subtitle: {
338							text: '',
339							align: 'left'
340						},
341						accessibility: {
342							point: {
343								valueSuffix: '%'
344							}
345						},
346						tooltip: {
347							pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>'
348						},
349						plotOptions: {
350							pie: {
351								allowPointSelect: true,
352								cursor: 'pointer',
353								depth: 35,
354								dataLabels: {
355									enabled: true,
356									format: '{point.name}: {point.percentage:.1f}%'
357								}
358							}
359						},
360						series: [{
361							type: 'pie',
362							name: 'Tỷ lệ',
363							data: [
364								['Thiết kế', Math.round(design_costs)],
365								['Phần ngầm', Math.round(underground_costs)],
366								['Phần thô', Math.round(rough_costs)], 
367								['Hoàn thiện', Math.round(complete_costs)],
368								['Nội thất', Math.round(interior_costs)],
369								['Dự phòng', Math.round(contingency_costs)]
370							]
371						}],
372						colors: ['#4BB2C5', '#EAA228', '#C5B47F', '#579575', '#839557', '#f5d025']
373					});
374				}
375				
376			} else {
377				//console.log('chưa đủ thông tin!');
378			}
379
380		}
381
382		$('.txdcc-input-group-fields input, .txdcc-tab-content-collapse select, .txdcc-tab-content-collapse input').on('keyup change', function(e){
383			txdcc_calculate($(this).closest('.txdcc-form'));
384		});
385
386		$('.txdcc-form').each(function() {
387			txdcc_calculate($(this));
388		});
389
390		function send_pricing(event, token) {
391			let form = $(event.target);
392			//console.log(form.serialize());
393			let btnsubmit = form.find('[type=submit]');
394			let btnsubmit_txt = btnsubmit.html();
395
396			// thông số cấu hình
397			// let params = form.data('params');
398			// console.log(params);
399
400			// dữ liệu người dùng nhập
401			let client_inputs = new URLSearchParams(form.serialize());
402
403			let length = (client_inputs.get('length')!='')?parseFloat(client_inputs.get('length')):0;
404			let width = (client_inputs.get('width')!='')?parseFloat(client_inputs.get('width')):0;
405			let basement = (client_inputs.get('basement')!='')?parseFloat(client_inputs.get('basement')):0;
406			let floor = (client_inputs.get('floor')!='')?parseFloat(client_inputs.get('floor')):0;
407
408			let data = {
409				action:'send_pricing',
410				token: token,
411				house_type: client_inputs.get('house_type'),
412				design_type: client_inputs.get('design_type'),
413				pile_type: client_inputs.get('pile_type'),
414				pressed_plank: client_inputs.get('pressed_plank'),
415				complete_quality: client_inputs.get('complete_quality'),
416				interior_quality: client_inputs.get('interior_quality'),
417				length: length,
418				width: width,
419				basement: basement,
420				floor: floor
421			};
422
423			data.customer_name = form.find('[name="customer_name"]').val();
424			data.customer_phone = form.find('[name="customer_phone"]').val();
425			data.customer_email = form.find('[name="customer_email"]').val();
426			//console.log(data);
427			if(data.customer_name!='' && data.customer_phone!='' && data.customer_email!='') {
428				btnsubmit.prop('disabled', true);
429				btnsubmit.html('Đang gửi...');
430				$.ajax({
431					url:txdcc.ajax_url,
432					type:'POST',
433					dataType:'json',
434					data: data,
435					success: function(response) {
436						alert(response.code+': '+response.msg);
437					},
438					error: function (xhr) {
439						alert('Lỗi kết nối! Vui lòng thử lại.');
440					},
441					complete: function(xhr) {
442						btnsubmit.prop('disabled', false);
443						btnsubmit.html(btnsubmit_txt);
444					}
445				});
446			}
447		}
448
449		$('.txdcc-form').on('submit', function(e){
450			if(typeof grecaptcha != 'undefined') {
451				grecaptcha.ready(function() {
452					grecaptcha.execute(txdcc.recaptcha_sitekey, {action: 'send_pricing'}).then(function(token) {
453						send_pricing(e, token);
454					}); // recaptcha execute
455				}); // recaptcha ready
456			} else {
457				send_pricing(e, '');
458			}
459			return false;
460		});
461
462		$('.txdcc-tabs .txdcc-content-button').on('click', function(e){
463			e.preventDefault();
464			$(this).closest('.txdcc-tab-content').toggleClass('open');
465		});
466
467		//console.log($('.txdcc-nav-tab-item a'));
468		
469		$('.txdcc-nav-tab-item a').on('click', function(e){
470			e.preventDefault();
471			//console.log(e);
472			let that = $(this);
473			let tabs = that.closest('.txdcc-tabs');
474			tabs.find('.txdcc-tab-content').removeClass('open');
475			tabs.find('.txdcc-tab-content-'+that.data('tab')).addClass('open');
476			that.closest('.txdcc-nav-tab-item').addClass('active').siblings().removeClass('active');
477		});
478	});
479});

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.