Modal and Toast Setup


ДУЖЕ ВАЖЛИВО всі модалки розміщаєм в templates/blocks/modals/

В файлі init.php повинен бути масив із всіх наявних модальних вікон

Приклад: $accepted_modal = ['modal_video','modal_contact'];


Click to open
PHP
<!-- ajax.php -->

<?php
include 'init.php';
$result = 0;
$html = '';
if (isset($_POST['modal']) && $_POST['modal'] != '') {
    if (isset($_POST['dataArray'])){
        $data = $_POST['dataArray'];
    }

    $modal_name = $_POST['modal'];
    if(!isset($modal_name) || empty($modal_name)){
        die(json_encode(['result' => 'error2']));
    }
    if(!in_array($modal_name, $accepted_modal)){
        die(json_encode(['result' => 'error3']));
    }

    ob_start();
    $tmp = 'templates/blocks/modals/'.$modal_name.'.php';
    if(file_exists($tmp)){
        include($tmp);
        $html = ob_get_clean();
        $result = 'ok';
    }else{
        $result = 'error4';
    }
}
die(json_encode(['result' => $result, 'html' => $html]));
PHP
<!-- Modal Button -->
<a href="#" class="button" data-modals="modal_sample">Click to open</a>

<!-- dialog.php -->
<div class="dialog_wrapper">
	<div class="table || main_table">
		<div class="tcell || main_tcell">
			<div class="dialog_bg || dialog_close"></div>
			<div class="modal_ajax || dialog">
                <span class="icon_close || dialog_close">
	                <?= svg('icon_close','') ?>
                </span>
				<div class="modal_content"></div>
			</div>
		</div>
	</div>
</div>

<div id="toast">
	<div class="table">
		<div class="tcell">
			<?= svg('icon_error','toast_icon') ?>
		</div>
		<div class="tcell">
			<p id="toast_text">Please, enter a valid value</p>
		</div>
	</div>
</div>
	
<!-- modal_sample.php -->
<div class="image_wrap">
	<?= svg('iconStars','zoomIn') ?>
</div>
<div class="modal_text">
	<h3 class="modal_title">Tada</h3>
	<p>Sample text</p>
</div>
<div class="modal_buttons">
	<a href="#" class="button || button_success">Success</a>
	<a href="#" class="button || button_danger">Danger</a>
</div>
CSS
@-webkit-keyframes fadeIn { 0%{opacity:0} 100%{opacity:1} }
@-moz-keyframes fadeIn { 0%{opacity:0} 100%{opacity:1} }
@-o-keyframes fadeIn { 0%{opacity:0} 100%{opacity:1} }
@keyframes fadeIn { 0%{opacity:0} 100%{opacity:1} }

@-webkit-keyframes showDialog { 0%{opacity:0;-webkit-transform:translateY(4rem);transform:translateY(4rem)} 100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)} }
@-moz-keyframes showDialog { 0%{opacity:0;-moz-transform:translateY(4rem);transform:translateY(4rem)} 100%{opacity:1;-moz-transform:translateY(0);transform:translateY(0)} }
@-o-keyframes showDialog { 0%{opacity:0;-o-transform:translateY(4rem);transform:translateY(4rem)} 100%{opacity:1;-o-transform:translateY(0);transform:translateY(0)} }
@keyframes showDialog { 0%{opacity:0;-webkit-transform:translateY(4rem);-moz-transform:translateY(4rem);-o-transform:translateY(4rem);transform:translateY(4rem)} 100%{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)} }

@-webkit-keyframes zoomIn { from{opacity:0;-webkit-transform:scale(0.7);transform:scale(0.7)} to{opacity:1;-webkit-transform:scale(1);transform:scale(1)} }
@-moz-keyframes zoomIn { from{opacity:0;-moz-transform:scale(0.7);transform:scale(0.7)} to{opacity:1;-moz-transform:scale(1);transform:scale(1)} }
@-o-keyframes zoomIn { from{opacity:0;-o-transform:scale(0.7);transform:scale(0.7)} to{opacity:1;-o-transform:scale(1);transform:scale(1)} }
@keyframes zoomIn { from{opacity:0;-webkit-transform:scale(0.7);-moz-transform:scale(0.7);-o-transform:scale(0.7);transform:scale(0.7)} to{opacity:1;-webkit-transform:scale(1);-moz-transform:scale(1);-o-transform:scale(1);transform:scale(1)} }

.dialog_wrapper{position:fixed;top:0;left:0;display:none;width:100%;height:100%;padding:4rem 0;z-index:1500}
.dialog_wrapper .main_table{width:100%;height:100%;padding-right:2rem}
.dialog_wrapper .main_tcell{padding:0 2rem}
.dialog{display:none;max-width:40rem;margin:0 auto;padding:2rem 3rem 2.5rem;-webkit-border-radius:1.5rem;-moz-border-radius:1.5rem;border-radius:1.5rem;background-color:#fff;border-top:.6rem solid #066978;z-index:1503;position:relative}
.dialog.modal_small{max-width:31rem}
.dialog.modal_medium{max-width:40rem}
.dialog.modal_large{max-width:85rem}
.dialog.modal_xlarge{max-width:65vw}
.dialog .icon_close{position:absolute;top:.5rem;right:.5rem;color:#066978;cursor:pointer;font-size:3rem;-webkit-transition:color .3s linear;-o-transition:color .3s linear;-moz-transition:color .3s linear;transition:color .3s linear}
.dialog .icon_close:focus{color:#dc3545}
.dialog .icon_close .icon{display:block}
.dialog .image_wrap{position:relative;width:7rem;height:7rem;line-height:7rem;margin:-5.5rem auto 0;-webkit-border-radius:50%;-moz-border-radius:50%;border-radius:50%;text-align:center;background-color:#066978}
.dialog .image_wrap .icon{height:4rem;width:4rem;color:#fff;-webkit-animation:zoomIn .5s both;-moz-animation:zoomIn .5s both;-o-animation:zoomIn .5s both;animation:zoomIn .5s both;-webkit-animation-delay:.2s;-moz-animation-delay:.2s;-o-animation-delay:.2s;animation-delay:.2s}
.dialog .modal_text{text-align:center;margin:2rem 0 .5rem}
.dialog .modal_text .modal_title{font-size:2.4rem;line-height:1.4;font-weight:700;color:#000;text-transform:capitalize;margin:0 auto}
.dialog .modal_text p{margin:0.5rem auto;max-width:88%}
.dialog .modal_buttons{font-size:0;text-align:center;margin:2rem auto 0;max-width:35rem}
.dialog .modal_buttons .button{width:-webkit-calc(100% / 2 - 1.4rem);width:-moz-calc(100% / 2 - 1.4rem);width:calc(100% / 2 - 1.4rem);min-width:unset;margin:.5rem .7rem}
.dialog_bg{position:fixed;left:0;top:0;display:none;width:100%;height:100%;background-color:rgba(33,33,33,0.55)}
.dialog_wrapper.visible,.dialog_bg.visible,.dialog.visible{display:block}
.dialog_opened{position:fixed;overflow-y:auto;width:100%;height:100%}
.dialog_opened .dialog_bg{-webkit-animation-name:fadeIn;-moz-animation-name:fadeIn;-o-animation-name:fadeIn;animation-name:fadeIn;-webkit-animation-duration:.3s;-moz-animation-duration:.3s;-o-animation-duration:.3s;animation-duration:.3s;-webkit-animation-fill-mode:both;-moz-animation-fill-mode:both;-o-animation-fill-mode:both;animation-fill-mode:both}
.dialog_opened .dialog{-webkit-animation-name:showDialog;-moz-animation-name:showDialog;-o-animation-name:showDialog;animation-name:showDialog;-webkit-animation-duration:.3s;-moz-animation-duration:.3s;-o-animation-duration:.3s;animation-duration:.3s;-webkit-animation-fill-mode:both;-moz-animation-fill-mode:both;-o-animation-fill-mode:both;animation-fill-mode:both}
.dialog_opened .dialog_wrapper{display:block}
.dialog_scrollable .dialog_wrapper{overflow-y:auto;width:-webkit-calc(100% + 4rem);width:-moz-calc(100% + 4rem);width:calc(100% + 4rem)}
.dialog_scrollable_mobile .dialog_wrapper{width:100%!important}
.dialog_scrollable_mobile .main_table{padding-right:0!important}

#toast{position:fixed;bottom:2rem;left:2rem;display:none;width:100%;max-width:28rem;padding:1rem 2rem;color:#fff;background-color:#fff;-webkit-box-shadow:.1rem .5rem 1.5rem rgba(0,0,0,0.25);-moz-box-shadow:.1rem .5rem 1.5rem rgba(0,0,0,0.25);box-shadow:.1rem .5rem 1.5rem rgba(0,0,0,0.25);-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;backface-visibility:hidden;z-index:1503}
#toast p{font-family:'Nunito Sans',sans-serif;font-size:1.4rem;color:#fff;display:block;margin:0}
#toast.error{background-color:#dc3545}
#toast.success{background-color:#28a745}
#toast .toast_icon{font-size:3rem;color:#fff;margin:0 1rem 0 0}

@media (-ms-high-contrast: none),(-ms-high-contrast: active),(-moz-touch-enabled: 0),(hover: hover) {
	.dialog .icon_close:hover{color:#dc3545}
}

@media only screen and (max-width: 400px) {
	.dialog .modal_buttons .button {width: 100%;margin: 0 0 1.5rem}
	.dialog .modal_buttons .button:last-child {margin: 0}
}
SCSS
/* Vars */
$font:           'Nunito Sans', sans-serif;
$dark:            #066978;
$success:         #28a745;
$danger:          #dc3545;
$white:           #ffffff;
$cb:              #000000;

$modalWidth:      40rem;
$modalWidthS:     31rem;
$modalWidthL:     85rem;
$modalWidthXL:    65vw;

$modalBg:         $white;
$modalBorder:     $dark;
$modalClose:      $dark;
$modalCloseH:     $danger;

$toastError:      $danger;
$toastSuccess:    $success;

@keyframes fadeIn {
	0% {
		opacity: 0;
	}
	100% {
		opacity: 1;
	}
}

@keyframes showDialog {
	0% {
		opacity: 0;
		transform: translateY(4rem);
	}
	100% {
		opacity: 1;
		transform: translateY(0);
	}
}

@keyframes zoomIn {
	from {
		opacity: 0;
		transform: scale(0.7);
	}
	to {
		opacity: 1;
		transform: scale(1);
	}
}

.dialog_wrapper {
	position: fixed;
	top: 0;
	left: 0;
	display: none;
	width: 100%;
	height: 100%;
	padding: 4rem 0;
	z-index: 1500;
	
	.main_table {
		width: 100%;
		height: 100%;
		padding-right: 2rem;
	}
	
	.main_tcell {
		padding: 0 2rem;
	}
}

.dialog {
	display: none;
	max-width: $modalWidth;
	margin: 0 auto;
	padding: 2rem 3rem 2.5rem;
	border-radius: 1.5rem;
	background-color: $modalBg;
	border-top: 0.6rem solid $modalBorder;
	z-index: 1503;
	position: relative;
	
	&.modal_small {
		max-width: $modalWidthS;
	}
	
	&.modal_medium {
		max-width: $modalWidth;
	}
	
	&.modal_large {
		max-width: $modalWidthL;
	}
	
	&.modal_xlarge {
		max-width: $modalWidthXL;
	}
	
	.icon_close {
		position: absolute;
		top: .5rem;
		right: .5rem;
		color: $modalClose;
		cursor: pointer;
		font-size: 3rem;
		transition: color .3s linear;
		
		&:focus {
			color: $modalCloseH;
		}
		
		.icon {
			display: block;
		}
	}
	
	.image_wrap {
		position: relative;
		width: 7rem;
		height: 7rem;
		line-height: 7rem;
		margin: -5.5rem auto 0;
		border-radius: 50%;
		text-align: center;
		background-color: $dark;
		
		.icon {
			height: 4rem;
			width: 4rem;
			color: $white;
			animation: zoomIn .5s both;
			animation-delay: .2s;
		}
	}
	
	.modal_text {
		text-align: center;
		margin: 2rem 0 .5rem;
		
		.modal_title {
			font-size: 2.4rem;
			line-height: 1.4;
			font-weight: 700;
			color: $cb;
			text-transform: capitalize;
			margin: 0 auto;
		}
		
		p {
			margin: 0.5rem auto;
			max-width: 88%;
		}
	}
	
	.modal_buttons {
		font-size: 0;
		text-align: center;
		margin: 2rem auto 0;
		max-width: 35rem;
		
		.button {
			width: calc(100% / 2 - 1.4rem);
			min-width: unset;
			margin: .5rem .7rem;
		}
	}
}

.dialog_bg {
	position: fixed;
	left: 0;
	top: 0;
	display: none;
	width: 100%;
	height: 100%;
	background-color: rgba(33, 33, 33, 0.55);
}

.dialog_wrapper.visible, .dialog_bg.visible, .dialog.visible {
	display: block;
}

.dialog_opened {
	position: fixed;
	overflow-y: auto;
	width: 100%;
	height: 100%;
	
	.dialog_bg {
		animation-name: fadeIn;
		animation-duration: .3s;
		animation-fill-mode: both;
	}
	
	.dialog {
		animation-name: showDialog;
		animation-duration: .3s;
		animation-fill-mode: both;
	}
	
	.dialog_wrapper {
		display: block;
	}
}

.dialog_scrollable .dialog_wrapper {
	overflow-y: auto;
	width: calc(100% + 4rem)
}

.dialog_scrollable_mobile {
	.dialog_wrapper {
		width: 100% !important;
	}
	
	.main_table {
		padding-right: 0 !important;
	}
}

#toast {
	position: fixed;
	bottom: 2rem;
	left: 2rem;
	display: none;
	width: 100%;
	max-width: 28rem;
	padding: 1rem 2rem;
	color: $white;
	background-color: $white;
	box-shadow: .1rem .5rem 1.5rem rgba(0, 0, 0, 0.25);
	backface-visibility: hidden;
	z-index: 1503;
	
	p {
		font-family: $font;
		font-size: 1.4rem;
		color: $white;
		display: block;
		margin:0;
	}
	
	&.error {
		background-color: $toastError;
	}
	
	&.success {
		background-color: $toastSuccess;
	}
	
	.toast_icon {
		font-size: 3rem;
		color: $white;
		margin:0 1rem 0 0;
	}
}

@media (-ms-high-contrast: none),(-ms-high-contrast: active),(-moz-touch-enabled: 0),(hover: hover) {
	.dialog .icon_close:hover {color: $modalCloseH}
}

@media only screen and (max-width: 400px) {
	.dialog .modal_buttons .button {width: 100%;margin: 0 0 1.5rem}
	.dialog .modal_buttons .button:last-child {margin: 0}
}
JavaScript
var $body = $('body'),
	$window = $(window);

$.fn.dialog = function () {
	var $this = $(this),
		$dialogWrapper = $('.dialog_wrapper'),
		$dialog = $('.dialog'),
		$dialogBg = $('.dialog_bg'),
		wPosSet = $window.scrollTop();
	
	$dialogWrapper.addClass('visible');
	$dialogBg.addClass('visible');
	$this.addClass('visible');
	$body.addClass('dialog_opened');
	$body.css('top', -wPosSet + 'px');
	$body.attr('data-scroll', wPosSet);
	
	if ($this.height() > $dialogWrapper.height()) {
		$body.addClass('dialog_scrollable');
	} else {
		$body.addClass('dialog_scrollable');
	}
	
	if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
		$body.addClass('dialog_scrollable_mobile');
	}
	
	$body.on('click', '.dialog_close', function () {
		$dialog.removeClass('visible');
		$dialogBg.removeClass('visible');
		$dialogWrapper.removeClass('visible');
		$body.removeClass('dialog_opened', 'dialog_scrollable_mobile');
		
		$('.modal_ajax .modal_content').html('');
		$('.dialog')
			.removeClass('modal_small')
			.removeClass('modal_medium')
			.removeClass('modal_large')
			.removeClass('modal_xlarge')
			.removeClass('modal_video');
		
		setTimeout(function () {
			$window.scrollTop(wPosSet);
		}, 400);
		
		$window.scrollTop(wPosSet);
	});
};

$(document).keydown(function (e) {
	if (e.keyCode == 27) {
		$('.dialog_close').trigger('click');
	}
});

var modalArray = {},
	$modalError = 0;

$body.on('click', '[data-modals]', function (e) {
	e.preventDefault();
	
	var type = $(this).data('modals');
	
	if (typeof type == "undefined") {
		$modalError++;
	} else {
		$modalError = 0;
		
		switch (type) {
			case 'modal_video':
				var src = $(this).data('src');
				if (src !== '') {
					modalArray.src = src;
					$modalError = 0
				} else {
					$modalError++;
				}
				break;
			case 'modal_contact':
				var title = $(this).data('title');
				var ref = $(this).data('location-input');
				
				if (typeof title !== "undefined" && title !== "") {
					modalArray.modal_title = title;
				}
				
				if (typeof ref !== "undefined" && ref !== "") {
					modalArray.locationInput = ref;
				}
				break;
		}
	}
	
	if ($modalError === 0) {
		$.ajax({
			type: 'POST',
			url: '/ajax.php',
			dataType: 'json',
			data: {
				modal: type,
				dataArray: modalArray
			},
			beforeSend: function () {
			},
			success: function (data) {
				if (data.result == 'ok') {
					$('.modal_ajax .modal_content').html(data.html);
					$('.modal_ajax').dialog();
					
					if (type == 'modal_contact') {
						$('.phone_us').mask('000.000.0000');
						validate_form();
					}
					
					if (type == 'modal_video') {
						/*setHeight();*/
						$('.dialog').addClass('modal_video');
					}
				}
			},
			
			error:
				function () {
					toast('error', "Error!");
				}
		});
		
	} else {
		toast('error', "Error!");
	}
});

$body.on('click', '[data-modal]', function (e) {
	e.preventDefault();
	var data = $(this).data('modal');
	var modal = $('.' + data);
	
	$('.dialog_close').trigger('click');
	
	modal.dialog();
});

function toast(cssClass, toastText) {
	var $this = $('#toast'),
		tl = new TimelineMax();
	$this.attr('class', false);
	$this.addClass(cssClass);
	$this.find('#toast_text').html(toastText);
	if (!$this.hasClass('active')) {
		tl.fromTo($this, 0.3, {display: 'none', y: '100%', autoAlpha: 0}, {
			display: 'block',
			y: '0%',
			autoAlpha: 1,
			ease: Back.easeOut
		}).to($this, 0.3, {
			display: 'none',
			y: '100%',
			autoAlpha: 0,
			ease: Back.easeIn,
			delay: 3,
			onComplete: function () {
				$this.removeClass('active');
			}
		});
	}
	$this.addClass('active');
}

Please, enter a valid value