modal-open is not removing from <body> - javascript

Hi I am showing a modal when person opens my site which works fine but when user closes it modal-open class is not removed from which doesn't allow them to scroll.
<div id="ageModal" class="modal fade" data-backdrop="static" data-keyboard="false" role="dialog" style="padding-right: 0px;">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content" style="background-color: #c9c9f8;" >
<div class="modal-header">
<button type="button" class="close hide" data-dismiss="modal">×</button>
</div>
<div class="modal-body text-center" style="padding-top:10%">
<h1>hi</h1>
<div>
<button type="button" class="btn btn-default" id="ageVerifyYes">Yes</button>
<button type="button" class="btn btn-default" id="ageVerifyNo">No</button>
</div>
<div>
<input type="checkbox" id="rememberMeAge"> Remember Me
</div>
<div id="ageVerifyError" class="hide">
<p class="error-msg">You should agree</p>
</div>
</div>
<div class="modal-footer hide">
<button type="button" class="btn btn-default" data-dismiss="modal">Yes</button>
<button type="button" class="btn btn-default">No</button>
</div>
</div>
</div>
</div>
<style type="text/css">
#ageModal .modal-dialog {
width: 100%;
height: 100%;
margin: 0;
padding: 0px!important;
}
#ageModal .modal-body{
height: 80%;
}
#ageModal .modal-content {
height: 98%;
min-height: 100%;
border-radius: 0;
}
#ageModal .error-msg{
color: #c00;
padding: 10px;
}
.in{
padding:0px!important;
}
</style>
<script type="text/javascript">
$(document).ready(function() {
var isshow = sessionStorage.getItem('isshow');
if (isshow == null || isshow == '') {
sessionStorage.setItem('isshow', 1);
// Show popup here
$('#ageModal').show();
}
else{
//hide popup if opened once
$('#ageModal').hide();
$('.fade').hide();
}
});
$('#ageVerifyNo').on('click', function(){
$('#ageVerifyError').removeClass('hide');
});
$('#ageVerifyYes').on('click', function(){
if($('#rememberMeAge').prop('checked') === true){
setCookie('ageVerified',1,1);
}
$('#ageModal').modal('hide');
$("body").removeClass("modal-open");
});
function setCookie(name,value,days) {
var expires = "";
if (days) {
var date = new Date();
date.setTime(date.getTime() + (days*24*60*60*1000));
expires = "; expires=" + date.toUTCString();
}
document.cookie = name + "=" + (value || "") + expires + "; path=/";
}
function getCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
}
return null;
}
function eraseCookie(name) {
document.cookie = name+'=; Max-Age=-99999999;';
}
I am basically storing in session if pop-up was opened or not. it works as expected but modal-open class stays with body tag even after modal is closed. I did try $("body").removeClass("modal-open"); but no luck I have also created another and tried to append there but again same issue. I can not edit bootstrap as I am using cdn

Try this as well
$('body').removeClass('modal-open');
$('.modal-backdrop').remove();

As an alternative quick solution just remove the fade class from the <div id="ageModal" class="modal fade"....
This issue can be caused by the modal('hide') being called before the fade animation has fully completed

Your .show() and .hide() should be .modal('show') and .modal('hide')

ngDoCheck(){
var x = $(document).find('.modal.show').length;
if(x>0) {
$('body').addClass('modal-open');
} else {
$('body').removeClass('modal-open');
}
}

Related

How could I add a border to make element look like a tree and keep it positioned correctly when resizing?

I am trying to step away from jsTree as this is not as much as configurable as having my own custom code. I am making use of Bootstrap to have a somewhat similar functionality as jsTree. I am also stepping away from jQuery (for now), because of debugging reasons.
//Event delegation
function BindEvent(parent, eventType, ele, func) {
var element = document.querySelector(parent);
element.addEventListener(eventType, function(event) {
var possibleTargets = element.querySelectorAll(ele);
var target = event.target;
for (var i = 0, l = possibleTargets.length; i < l; i++) {
var el = target;
var p = possibleTargets[i];
while (el && el !== element) {
if (el === p) {
return func.call(p, event);
}
el = el.parentNode;
}
}
});
}
//Add content after referenced element
function insertAfter(referenceNode, newNode) {
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}
//Custom function
function LoadSubOptions(ele) {
ele = ele.parentElement.parentElement;
let newEle = document.createElement("div");
newEle.classList.add("row", "flex");
//Generated HTML Content (currently hard coded):
newEle.innerHTML = "<div class='col-xs-1'><div class='tree-border'></div></div><div class='col-xs-11'><div class='row'><div class='col-xs-12'><button class='btn btn-default btn-block btn-lg'>Test</button></div></div></div>";
insertAfter(ele, newEle);
}
//Bind method(s) on button click(s)
BindEvent("#tree-replacement", "click", "button", function(e) {
LoadSubOptions(this);
});
#tree-replacement button {
margin-top: 5px;
}
.tree-border {
border-left: 1px dashed #000;
height: 100%;
margin-left: 15px;
}
.flex {
display: flex;
}
/*Probably not wise to use this method on Bootstrap's grid system: */
#tree-replacement .row.flex>[class*='col-'] {
display: flex;
flex-direction: column;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet" />
<div class="container">
<div id="tree-replacement">
<div class="row">
<div class="col-xs-12">
<button class="btn btn-default btn-block btn-lg">
Option 1
</button>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<button class="btn btn-default btn-block btn-lg">
Option 2
</button>
</div>
</div>
<!--The generated html as example: -->
<!--<div class="row">
<div class="col-xs-1">
<div class="tree-border">
</div>
</div>
<div class="col-xs-11">
<div class="row">
<div class="col-xs-12">
<button class="btn btn-default btn-block btn-lg">
Option 2
</button>
</div>
</div>
</div>
</div>-->
</div>
</div>
JSFiddle
I added a border in a .column-*-1 to allow for some spacing for the border:
The spacing however, I find a bit too much. How could I address this problem? I would like to refrain from styling Bootstrap's grid system (meaning I preferably would not want to touch any styling behind .col-* and .row classes etc.) because this might break the responsiveness or anything else related to Bootstrap.
Edit:
I also noticed that when adding a lot of buttons by just clicking them, the layout of tree will start failing as well. (I am aware this is a different question, so if I need to post another question regarding this problem, please do let me know) Is there a way I could address this so that the element works correctly?
Add this little CSS
#tree-replacement .row.flex > .col-xs-11:nth-child(2):before {
content: ' ';
position: absolute;
left: calc(-100% / 11 + 30px);
top: 2em;
border-top: 1px dashed #000000;
width: calc(100% / 5 - 15px);
}
//Event delegation
function BindEvent(parent, eventType, ele, func) {
var element = document.querySelector(parent);
element.addEventListener(eventType, function(event) {
var possibleTargets = element.querySelectorAll(ele);
var target = event.target;
for (var i = 0, l = possibleTargets.length; i < l; i++) {
var el = target;
var p = possibleTargets[i];
while (el && el !== element) {
if (el === p) {
return func.call(p, event);
}
el = el.parentNode;
}
}
});
}
//Add content after referenced element
function insertAfter(referenceNode, newNode) {
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}
//Custom function
function LoadSubOptions(ele) {
ele = ele.parentElement.parentElement;
let newEle = document.createElement("div");
newEle.classList.add("row", "flex");
//Generated HTML Content (currently hard coded):
newEle.innerHTML = "<div class='col-xs-1'><div class='tree-border'></div></div><div class='col-xs-11'><div class='row'><div class='col-xs-12'><button class='btn btn-default btn-block btn-lg'>Test</button></div></div></div>";
insertAfter(ele, newEle);
}
//Bind method(s) on button click(s)
BindEvent("#tree-replacement", "click", "button", function(e) {
LoadSubOptions(this);
});
#tree-replacement button {
margin-top: 5px;
}
.tree-border {
border-left: 1px dashed #000;
height: 100%;
margin-left: 15px;
}
.flex {
display: flex;
}
/*Probably not wise to use this method on Bootstrap's grid system: */
#tree-replacement .row.flex>[class*='col-'] {
display: flex;
flex-direction: column;
}
#tree-replacement .row.flex > .col-xs-11:nth-child(2):before {
content: ' ';
position: absolute;
left: calc(-100% / 11 + 30px);
top: 2em;
border-top: 1px dashed #000000;
width: calc(100% / 5 - 15px);
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet" />
<div class="container">
<div id="tree-replacement">
<div class="row">
<div class="col-xs-12">
<button class="btn btn-default btn-block btn-lg">
Option 1
</button>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<button class="btn btn-default btn-block btn-lg">
Option 2
</button>
</div>
</div>
<!--The generated html as example: -->
<!--<div class="row">
<div class="col-xs-1">
<div class="tree-border">
</div>
</div>
<div class="col-xs-11">
<div class="row">
<div class="col-xs-12">
<button class="btn btn-default btn-block btn-lg">
Option 2
</button>
</div>
</div>
</div>
</div>-->
</div>
</div>
Here I have used absolute positioning and increased height by 5px which kind of makes it touches the next div element.
Here is the Fiddle Link
and the Code Snippet:
//Event delegation
function BindEvent(parent, eventType, ele, func) {
var element = document.querySelector(parent);
element.addEventListener(eventType, function(event) {
var possibleTargets = element.querySelectorAll(ele);
var target = event.target;
for (var i = 0, l = possibleTargets.length; i < l; i++) {
var el = target;
var p = possibleTargets[i];
while (el && el !== element) {
if (el === p) {
return func.call(p, event);
}
el = el.parentNode;
}
}
});
}
//Add content after referenced element
function insertAfter(referenceNode, newNode) {
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}
//Custom function
function LoadSubOptions(ele) {
ele = ele.parentElement.parentElement;
let newEle = document.createElement("div");
newEle.classList.add("row", "flex");
//Generated HTML Content (currently hard coded):
newEle.innerHTML = "<div class='col-xs-1'><div class='tree-border'></div></div><div class='col-xs-11'><div class='row'><div class='col-xs-12'><button class='btn btn-default btn-block btn-lg'>Test</button></div></div></div>";
insertAfter(ele, newEle);
}
//Bind method(s) on button click(s)
BindEvent("#tree-replacement", "click", "button", function(e) {
LoadSubOptions(this);
});
#tree-replacement button {
margin-top: 5px;
}
.tree-border {
border-left: 1px dashed #000;
height: calc(100% + 5px);
margin-left: 20px;
position: absolute;
}
.flex {
position: relative;
display: flex;
}
.col-xs-11 .col-xs-12 {
padding-left: 0;
}
/*Probably not wise to use this method on Bootstrap's grid system: */
#tree-replacement .row.flex>[class*='col-'] {
display: flex;
flex-direction: column;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container">
<div id="tree-replacement">
<div class="row">
<div class="col-xs-12">
<button class="btn btn-default btn-block btn-lg">
Option 1
</button>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<button class="btn btn-default btn-block btn-lg">
Option 2
</button>
</div>
</div>
<!--<div class="row">
<div class="col-xs-1">
<div class="tree-border">
</div>
</div>
<div class="col-xs-11">
<div class="row">
<div class="col-xs-12">
<button class="btn btn-default btn-block btn-lg">
Option 2
</button>
</div>
</div>
</div>
</div>-->
</div>
</div>

Javascript sending wrong get request

So basically, I have an image upload page where users can upload images.I use laravel for the backend.It hasn't been working since and the server kept returning errors.So I chnaged the post request to GET and I found out that instead of the script sendind something like http://localhost:8000/upload?title='whatever'&body='theimageselected.jpg'
Of course,the title and body values are variables.They will be different according to what the user wants to uploaad..
It sends this:
http://localhost:8000/upload?[object%20Object]&_=1558376643031
Why?
Here is my code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="shortcut icon" type="image/x-icon" href="https://static.codepen.io/assets/favicon/favicon-aec34940fbc1a6e787974dcd360f2c6b63348d4b1f4e06c77743096d55480f33.ico" />
<link rel="mask-icon" type="" href="https://static.codepen.io/assets/favicon/logo-pin-8f3771b1072e3c38bd662872f6b673a722f4b3ca2421637d5596661b4e2132cc.svg" color="#111" />
<title>CodePen - Image Upload With Live Preview using FormData</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
<style>
.container {
padding-top: 3%;
}
.hide-element {
display: none;
}
.glyphicon-remove-circle {
float: right;
font-size: 2em;
cursor: pointer;
}
/*
* http://www.abeautifulsite.net/whipping-file-inputs-into-shape-with-bootstrap-3/
*/
.btn-file {
position: relative;
overflow: hidden;
/*box-shadow: 10px 10px 5px #888888;*/
}
.btn-file input[type=file] {
position: absolute;
top: 0;
right: 0;
min-width: 100%;
min-height: 100%;
font-size: 100px;
text-align: right;
filter: alpha(opacity=0);
opacity: 0;
outline: none;
background: white;
cursor: inherit;
display: block;
}
.alert,
.well {
box-shadow: 10px 10px 5px;
-moz-box-shadow: 10px 10px 5px;
-webkit-box-shadow: 10px 10px 5px;
}
#uploadDataInfo p {
margin-left: 2%;
margin-top: 3%;
font-size: 1.2em;
}
.media-left #edit {
z-index: 1000;
cursor: pointer;
}
.thumbnail #edit {
position: absolute;
display: inline;
z-index: 1000;
top: 1px;
right: 15px;
cursor: pointer;
}
.thumbnail #delete {
position: absolute;
display: inline;
z-index: 1000;
margin-top: 4%;
top: 20px;
right: 15px;
cursor: pointer;
}
.caption input[type="text"] {
/*width: 80%;*/
}
.thumbnail .fa-check-circle {
color: #006dcc;
*color: #0044cc;
}
.thumbnail .fa-times-circle {
color: #E74C3C;
}
.modal-header .close {
float: right !important;
margin-right: -30px !important;
margin-top: -25px !important;
background-color: white !important;
border-radius: 15px !important;
width: 30px !important;
height: 30px !important;
opacity: 1 !important;
}
.modal-header {
padding: 0px;
min-height: 0px;
}
.modal-dialog {
top: 50px;
}
.media-left img {
cursor: pointer;
}
.label-tags {
font-size: 16px;
padding: 1%;
color: black;
background-color: white;
border: 1px solid blue;
border-radius: 4px;
margin: 3px;
}
.label-tags i {
cursor: pointer;
}
</style>
<script>
window.console = window.console || function(t) {};
</script>
<script>
if (document.location.search.match(/type=embed/gi)) {
window.parent.postMessage("resize", "*");
}
</script>
</head>
<body translate="no">
<div id="individualImagePreview" class="modal fade" role="dialog">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><i class="fa fa-times"></i></button>
</div>
<div class="modal-body">
<img src="" alt="default image" class="img-responsive" id="individualPreview" />
</div>
<div class="modal-footer" id="displayTags">
<div class="pull-left">
</div>
</div>
</div>
</div>
</div>
<div id="progressModal" class="modal fade" role="dialog">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
</div>
<div class="modal-body">
<div id="ajaxLoad">
<div class="progress">
<div class="progress-bar progress-bar-striped active" role="progressbar" aria-valuemax="100" id="progressIndicator" style="">
<span class="sr-only">45% Complete</span>
</div>
</div>
<i class="fa fa-cog fa-spin fa-4x"></i> </div>
</div>
<div class="modal-footer hide-element">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<div class="container">
<div class="alert hide-element" role="alert" id="errorMessaage"></div>
<div class="alert hide-element" role="alert" id="file-error-message">
<span class='glyphicon glyphicon-remove-circle'></span>
<p></p>
</div>
<form class="well" id="imagesUploadForm">
<label for="file">Select files to upload</label>
<br />
<span class="btn btn-primary btn-file">
Browse <input type="file" multiple="multiple" accept="image/*" id="uploadImages" /></span>
<p class="help-block">
Only jpg,jpeg,png file with maximum size of 2 MB is allowed.
</p>
<button type="button" data-toggle="modal" data-target="#myModal" class="btn btn-lg btn-primary disabled" value="Preview" name="imagesUpload" id="imagesUpload">Preview</button>
</form>
<div id="uploadDataInfo" class="alert hide-element">
<a href="#" class="close" data-dismiss="alert" aria-label="close">
<i class="fa fa-times"></i>
</a>
<p class="" id="toManyFilesUploaded"></p>
<p class="" id="filesCount"></p>
<p class="" id="filesSupported"></p>
<p class="" id="filesUnsupported"></p>
</div>
<div class="hide-element" id="previewImages">
<div class="media">
<div class="media-left">
<img class="media-object thumbnail" src="img/200x200.gif" alt="" id="0" title="" data-toggle="modal" data-target="#individualImagePreview" />
</div>
<div class="media-body">
<p><label for="description">Description: </label><input type="text" class="form-control" value="" name="description" /></p>
<p><label for="caption">Caption: </label><input type="text" class="form-control" value="" name="caption" /></p>
<p><label for="tags">Tags:max of 3 tags.comma seperated </label><input type="text" class="form-control" value="" name="tags" /></p>
<a role="button" class="btn btn-primary hide-element" id="undo0">Undo</a>
<a role="button" class="btn btn-danger pull-right" id="delete0">Delete</a>
</div>
</div>
<div class="media">
<div class="media-left">
<img class="media-object thumbnail" src="img/200x200.gif" alt="" id="1" title="" data-toggle="modal" data-target="#individualImagePreview" />
</div>
<div class="media-body">
<p><label for="description">Description: </label><input type="text" class="form-control" value="" name="description" /></p>
<p><label for="caption">Caption: </label><input type="text" class="form-control" value="" name="caption" /></p>
<p><label for="tags">Tags: </label><input type="text" class="form-control" value="" name="tags" /></p>
<a role="button" class="btn btn-primary hide-element" id="undo1">Undo</a>
<a role="button" class="btn btn-danger pull-right" id="delete1">Delete</a>
</div>
</div>
<div class="media">
<div class="media-left">
<img class="media-object thumbnail" src="img/200x200.gif" alt="" id="2" title="" data-toggle="modal" data-target="#individualImagePreview" />
</div>
<div class="media-body">
<p><label for="description">Description: </label><input type="text" class="form-control" value="" name="description" /></p>
<p><label for="caption">Caption: </label><input type="text" class="form-control" value="" name="caption" /></p>
<p><label for="tags">Tags: </label><input type="text" class="form-control" value="" name="tags" /></p>
<a role="button" class="btn btn-primary hide-element" id="undo2">Undo</a>
<a role="button" class="btn btn-danger pull-right" id="delete2">Delete</a>
</div>
</div>
<div class="media">
<div class="media-left">
<img class="media-object thumbnail" src="img/200x200.gif" alt="" id="3" data-toggle="modal" data-target="#individualImagePreview" />
</div>
<div class="media-body">
<p><label for="description">Description: </label>
<input type="text" class="form-control" name="description" value="" /></p>
<p><label for="caption">Caption: </label>
<input type="text" class="form-control" name="caption" value="" /></p>
<p><label for="tags">Tags: </label>
<input type="text" class="form-control" name="tags" value="" /></p>
<a role="button" class="btn btn-primary hide-element" id="undo3">Undo</a>
<a role="button" class="btn btn-danger pull-right" id="delete3">Delete</a>
</div>
</div>
<button class="btn btn-primary pull-left" id="sendImagesToServer" data-toggle="modal" data-target="#progressModal" data-keyboard="false" data-backdrop="static">Update & Preview</button>
</div>
<br /><br />
<div id="myModal" class="modal fade" role="dialog">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><i class="fa fa-times"></i></button>
</div>
<div class="modal-body">
<div id="myCarousel" class="carousel slide">
<div class="carousel-inner" role="listbox" id="previewItems">
</div>
<a class="left carousel-control" href="#myCarousel" role="button" data-slide="prev">
<span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="right carousel-control" href="#myCarousel" role="button" data-slide="next">
<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
</div>
<div class="modal-footer hide-element">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
<script src="https://static.codepen.io/assets/common/stopExecutionOnTimeout-de7e2ef6bfefd24b79a3f68b414b87b8db5b08439cac3f1012092b2290c719cd.js"></script>
<script id="rendered-js">
$(document).ready(function () {
$('[data-toggle="tooltip"]').tooltip({
html: true });
$('.media').addClass('hide-element');
$('#imagesUploadForm').submit(function (evt) {
evt.preventDefault();
});
$('#edit').click(function () {
console.log('click detected inside circl-o of edit');
$('#edit').toggleClass('fa-circle-o').toggleClass('fa-check-circle');
if ($('#edit').hasClass('fa-check-circle')) {
$('#captionForImage').toggleClass('hide-element');
} else {
$('#captionForImage').toggleClass('hide-element');
}
});
$('#delete').click(function () {
console.log('click detected inside circl-o of delete');
$('#delete').toggleClass('fa-circle-o').toggleClass('fa-times-circle');
});
//namespace variable to determine whether to continue or not
var proceed = true;
//Ensure that FILE API is supported by the browser to proceed
if (proceed) {
var input = "";
var formData = new FormData();
$('input[type=file]').on("change", function (e) {
var counter = 0;
var modalPreviewItems = "";
input = this.files;
$($(this)[0].files).each(function (i, file) {
formData.append("file[]", file);
});
$('#previewImages').removeClass('hide-element');
$('#imagesUpload').removeClass('disabled');
var successUpload = 0;
var failedUpload = 0;
var extraFiles = 2;
var size = input.length;
$(input).each(function () {
var reader = new FileReader();
var uploadImage = this;
console.log(this);
reader.readAsArrayBuffer(this);
reader.onload = function (e) {
var magicNumbers = validateImage.magicNumbersForExtension(e);
var fileSize = validateImage.isUploadedFileSizeValid(uploadImage);
var extension = validateImage.uploadFileExtension(uploadImage);
var isValidImage = validateImage.validateExtensionToMagicNumbers(magicNumbers);
var thumbnail = validateImage.generateThumbnail(uploadImage);
if (fileSize && isValidImage) {
$('#' + counter).parents('.media').removeClass('hide-element');
$('#' + counter).attr('src', thumbnail).height('200');
$('#uploadDataInfo').removeClass('hide-element').addClass('alert-success');
successUpload++;
modalPreviewItems += carouselInsideModal.createItemsForSlider(thumbnail, counter);
} else {
$('#uploadDataInfo').removeClass('hide-element alert-success').addClass('alert-warning');
failedUpload++;
}
counter++;
if (counter === size) {
$('#myCarousel').append(carouselInsideModal.createIndicators(successUpload, "myCarousel"));
$('#previewItems').append(modalPreviewItems);
$('#previewItems .item').first().addClass('active');
$('#carouselIndicators > li').first().addClass('active');
$('#myCarousel').carousel({
interval: 2000,
cycle: true });
if (size > 4) {
$('#toManyFilesUploaded').html("Only files displayed below will be uploaded");
extraFiles = size - 4;
}
$('#filesCount').html(successUpload + " files are ready to upload");
if (failedUpload !== 0 || extraFiles !== 0) {
failedUpload === 0 ? "" : failedUpload;
extraFiles === 0 ? "" : extraFiles;
$('#filesUnsupported').html(failedUpload + extraFiles + " files were not selected for upload");
}
}
};
});
});
$(document).on('click', '.glyphicon-remove-circle', function () {
$('#file-error-message').addClass('hide-element');
});
$("body").on("click", ".media-object", function () {
var image = $(this).attr('src');
$("#individualPreview").attr('src', image);
var tags = [];
var displayTagsWithFormat = "";
$(this).parents('.media').find('input[type="text"]').each(function () {
if ($(this).attr('name') === 'tags') {
tags = $(this).val().split(",");
$.each(tags, function (index) {
displayTagsWithFormat += "<span class = 'label-tags label'>#" + tags[index] + " <i class='fa fa-times'></i></span>";
});
$("#displayTags").html("<div class='pull-left'>" + displayTagsWithFormat + "</div>");
//console.log(tags);
}
});
});
var toBeDeleted = [];
var eachImageValues = [];
$('.media').each(function (index) {
var imagePresent = "";
$("body").on("click", "#delete" + index, function () {
imagePresent = $("#" + index).attr('src');
$("#undo" + index).removeClass('hide-element');
$("#" + index).attr('src', './img/200x200.gif');
$("#delete" + index).addClass('hide-element');
toBeDeleted.push(index);
//console.log(toBeDeleted);
$("#delete" + index).parent().find('input[type="text"]').each(function () {
var attribute = $(this).attr('name');
var attributeValue = $(this).val();
eachImageValues[attribute + index] = attributeValue;
//console.log(eachImageValues);
});
//console.log(toBeDeleted.length);
if (toBeDeleted.length === 4) {
$('#sendImagesToServer').prop('disabled', true).html('No Files to Upload');
} else {
$('#sendImagesToServer').prop('disabled', false).html('Update & Preview');
}
$("#delete" + index).parent().find('input[type="text"]').prop('disabled', true).addClass('disabled');
});
$("body").on("click", "#undo" + index, function () {
$("#" + index).attr('src', imagePresent);
$("#undo" + index).addClass('hide-element');
$("#delete" + index).removeClass('hide-element');
var indexToDelete = toBeDeleted.indexOf(index);
if (indexToDelete > -1) {
toBeDeleted.splice(indexToDelete, 1);
// console.log(toBeDeleted);
$("#delete" + index).parent().find('input[type="text"]').prop('disabled', false).removeClass('disabled');
}
if (toBeDeleted.length === 4) {
$('#sendImagesToServer').prop('disabled', true).html('No Files to Upload');
} else {
$('#sendImagesToServer').prop('disabled', false).html('Update & Preview');
}
});
});
$('body').on("click", "#sendImagesToServer", function () {
var counter = 0;
var imageData = "";
var consolidatedData = [];
$('.media').each(function () {
var description = "";
var caption = "";
var tags = "";
$('.media').find('input[type="text"]').each(function (index) {
if ((index === 0 || index <= 11) && counter <= 11) {
counter++;
var attributeName = "";
var attributeValue = "";
attributeName = $(this).attr('name');
attributeValue = $(this).val();
switch (attributeName) {
case "title":
title = attributeName;
// console.log(description);
break;
case "caption":
body = attributeName;
// console.log(caption);
break;
case "tags":
tags =attributeName;
// console.log(tags);
break;
default:
break;}
if (counter % 3 === 0) {
imageData = new imageInformation(description, caption, tags);
consolidatedData.push(imageData);
//JSON.stringify(consolidatedData);
//console.log(toBeDeleted);
}
}
});
});
imageData = new deleteList(toBeDeleted);
consolidatedData.push(imageData);
var sendData = JSON.stringify(consolidatedData);
formData.append("important", sendData);
$.ajax({
type: 'GET',
url: '/upload',
xhr: function () {
var customXhr = $.ajaxSettings.xhr();
if (customXhr.upload) {
customXhr.upload.addEventListener('progress', progressHandlingFunction, false); // For handling the progress of the upload
}
return customXhr;
},
data: {title:"test",body:"body"},
dataType: 'json',
cache: false,
contentType: false,
processData: false,
success: function (data) {
$('#ajaxLoad').addClass('hide-element');
$('#successResponse').html(data.message);
console.log(data.message + " inside success function");
},
error: function (data) {
$('#successResponse').html(data.responseJSON.message).addClass('label label-danger').css({
'font-size': '18px' });
console.log(data.responseJSON.message + " inside error function");
} });
function progressHandlingFunction(e) {
if (e.lengthComputable) {
$('#progressIndicator').css({
'width': e.loaded });
}
};
//
//console.log(JSON.stringify(consolidatedData));
});
function imageInformation(description, caption, tags) {
this.description = description;
this.title = caption;
this.tags = tags;
this.type = "image";
};
function deleteList(toBeDeleted) {
this.toBeDeleted = toBeDeleted;
};
var validateImage = {
magicNumbersForExtension: function (event) {
var headerArray = new Uint8Array(event.target.result).subarray(0, 4);
var magicNumber = "";
for (var counter = 0; counter < headerArray.length; counter++) {if (window.CP.shouldStopExecution(0)) break;
magicNumber += headerArray[counter].toString(16);
}window.CP.exitedLoop(0);
return magicNumber;
},
isUploadedFileSizeValid: function (fileUploaded) {
var fileSize = fileUploaded.size;
var maximumSize = 2097125;
var isValid = "";
if (fileSize <= maximumSize) {
isValid = true;
} else {
isValid = false;
}
return isValid;
},
uploadFileExtension: function (fileUploaded) {
var fileExtension = "";
var imageType = "";
imageType = fileUploaded.type.toLowerCase();
fileExtension = imageType.substr(imageType.lastIndexOf('/') + 1);
return fileExtension;
},
validateExtensionToMagicNumbers: function (magicNumbers) {
var properExtension = "";
if (magicNumbers.toLowerCase() === "ffd8ffe0" || magicNumbers.toLowerCase() === "ffd8ffe1" ||
magicNumbers.toLowerCase() === "ffd8ffe8" ||
magicNumbers.toLocaleLowerCase() === "89504e47") {
properExtension = true;
} else {
properExtension = false;
}
return properExtension;
},
generateThumbnail: function (uploadImage) {
if (window.URL)
imageSrc = window.URL.createObjectURL(uploadImage);else
imageSrc = window.webkitURL.createObjectURL(uploadImage);
return imageSrc;
} };
var carouselInsideModal = {
createIndicators: function (carouselLength, dataTarget) {
var carouselIndicators = '<ol class = "carousel-indicators" id="carouselIndicators">';
for (var counter = 0; counter < carouselLength; counter++) {if (window.CP.shouldStopExecution(1)) break;
carouselIndicators += '<li data-target = "#' + dataTarget + '"data-slide-to="' + counter + '"></li>';
}window.CP.exitedLoop(1);
carouselIndicators += "</ol>";
return carouselIndicators;
},
createItemsForSlider: function (imgSrc, counter) {
var item = '<div class = "item">' + '<img src="' + imgSrc + '" id="preview' + counter + '" /></div>';
return item;
} };
}
});
//# sourceURL=pen.js
</script>
<script>
$('.laravel-like').on('click', function(){
if($(this).hasClass('disabled'))
return false;
var item_id = $(this).data('item-id');
var vote = $(this).data('vote');
$.ajax({
method: "post",
url: "/",
data: {item_id: item_id, vote: vote},
dataType: "json"
})
.done(function(msg){
if(msg.flag == 1){
if(msg.vote == 1){
$('#'+item_id+'-like').removeClass('outline');
$('#'+item_id+'-dislike').addClass('outline');
}
else if(msg.vote == -1){
$('#'+item_id+'-dislike').removeClass('outline');
$('#'+item_id+'-like').addClass('outline');
}
else if(msg.vote == 0){
$('#'+item_id+'-like').addClass('outline');
$('#'+item_id+'-dislike').addClass('outline');
}
$('#'+item_id+'-total-like').text(msg.totalLike == null ? 0 : msg.totalLike);
$('#'+item_id+'-total-dislike').text(msg.totalDislike == null ? 0 : msg.totalDislike);
}
})
.fail(function(msg){
alert(msg);
});
});
$(document).on('click', '.reply-button', function(){
if($(this).hasClass("disabled"))
return false;
var toggle = $(this).data('toggle');
$("#"+toggle).fadeToggle('normal');
});
$(document).on('submit', '.laravelComment-form', function(){
var thisForm = $(this);
var parent = $(this).data('parent');
var item_id = $(this).data('item');
var comment = $('textarea#'+parent+'-textarea').val();
$.ajax({
method: "get",
url: "/laravellikecomment/comment/add",
data: {parent: parent, comment: comment, item_id: item_id},
dataType: "json"
})
.done(function(msg){
$(thisForm).toggle('normal');
var newComment = '<div class="comment" id="comment-'+msg.id+'" style="display: initial;"><a class="avatar"><img src="'+msg.userPic+'"></a><div class="content"><a class="author">'+msg.userName+'</a><div class="metadata"><span class="date">Today at 5:42PM</span></div><div class="text">'+msg.comment+'</div><div class="actions"><a class="reply reply-button" data-toggle="'+msg.id+'-reply-form">Reply</a></div><form class="ui laravelComment-form form" id="'+msg.id+'-reply-form" data-parent="'+msg.id+'" data-item="'+item_id+'" style="display: none;"><div class="field"><textarea id="'+msg.id+'-textarea" rows="2"></textarea></div><input type="submit" class="ui basic small submit button" value="Reply"></form></div><div class="ui threaded comments" id="'+item_id+'-comment-'+msg.id+'"></div></div>';
$('#'+item_id+'-comment-'+parent).prepend(newComment);
$('textarea#'+parent+'-textarea').val('');
})
.fail(function(msg){
alert(msg);
});
return false;
});
$(document).on('click', '#showComment', function(){
var show = $(this).data("show-comment");
$('.show-'+$(this).data("item-id")+'-'+show).fadeIn('normal');
$(this).data("show-comment", show+1);
$(this).text("Show more");
});
$(document).on('click', '#write-comment', function(){
$($(this).data("form")).show();
});
</script>
</body>
</html>
you can try
data: JSON.stringify({
title: "Test",
body: "test"
}),

Bootstrap modal darkens screen but won't show

I'm trying to get a modal to display upon my page loading. The problem is, the screen darkens, but the modal itself does not display.
As per the site's suggestion, here is an abbreviated version of my code. Here is the head:
<head>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- Latest compiled JavaScript -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<style>
#ball {
position: absolute;
left: 208px;
top: 40px;
z-index: 1;
width: 20px;
height: 20px;
transition: top 1s;
}
#wheel {
}
#da_panel
{
position: relative;
z-index:1;
}
.row {
padding: 20px;
}
</style>
</head>
Here is where the modal loads
<body onload = "populate(); loadModal();">
<div class="modal hide fade" id="myModal">
<div class="modal-header">
<a class="close" data-dismiss="modal">×</a>
<h3>Modal header</h3>
</div>
<div class="modal-body">
<p>One fine body…</p>
</div>
<div class="modal-footer">
Close
Save changes
</div>
</div>
And here is the function:
<script>
function loadModal(){
$('#myModal').modal('show');
}
Also, if you just want to look at the whole shabang, here it is:
<!DOCTYPE html>
<html>
<head>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- Latest compiled JavaScript -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<style>
#ball {
position: absolute;
left: 208px;
top: 40px;
z-index: 1;
width: 20px;
height: 20px;
transition: top 1s;
}
#wheel {
}
#da_panel
{
position: relative;
z-index:1;
}
.row {
padding: 20px;
}
</style>
</head>
<body onload = "populate(); loadModal();">
<div class="modal hide fade" id="myModal">
<div class="modal-header">
<a class="close" data-dismiss="modal">×</a>
<h3>Modal header</h3>
</div>
<div class="modal-body">
<p>One fine body…</p>
</div>
<div class="modal-footer">
Close
Save changes
</div>
</div>
<div class = "container">
<div class = "row">
<div class = "col-lg-5">
<img id = "ball" src = "ball.png" onclick="spin()"></img>
<img id = "wheel" src = "Rwheelbg.png" onclick="spin()"></img>
</div>
<div class = "col-lg-1">
<button id = "reset" onclick="reset()">Reset Wheel</button>
</div>
<div class = "col-lg-6">
<div class="well well-lg">
<span><center>Chips</center></span>
<br>
<div class = "text-center" style = "font-size: 180px;" id = "chipsInv">10</div>
<!-- Why won't this center!? -->
<br>
<span style = "float:left" id = "earnings">Your earnings:</span>
<span style = "float:right;" id ="purchase" onclick="purchase()"><a style = "color:green !important;" href = "#">$ Purchase More Chips?</a></span>
<!-- Must find way to override link color -->
</div>
</div>
<!-- Row ends here -->
<!-- FIND A WAY TO MAKE IMAGE TRANSPARENT!!! -->
</div>
<div class="panel panel-default" id = "da_panel">
<div class="panel-heading">Bet on:</div>
<div class="panel-body">
<form action="">
<input type="checkbox" name="21" value="310" id = "310"> 21<br>
<input type="checkbox" name="9" value="100" id = "100"> 9<br>
<input type="checkbox" name="14" value="120" id = "120"> 14<br>
<input type="checkbox" name="13" value="240" id = "240"> 13
</form>
</div>
</div>
<!-- <p>Bet on:</p>
<form action="">
<input type="checkbox" name="21" value="310" id = "310"> 21<br>
<input type="checkbox" name="9" value="100" id = "100"> 9<br>
<input type="checkbox" name="14" value="120" id = "120"> 14<br>
<input type="checkbox" name="13" value="240" id = "240"> 13
</form> -->
<p>Bet on up to four numbers. However, be warned, the more numbers you bet on, the lower your chip return will be.</p>
<!-- container ends here -->
</div>
<script>
function loadModal(){
$('#myModal').modal('show');
}
var chips = 5;
var earnings = chips * (-1);
function populate()
{
$("#chipsInv").text(chips);
$("#earnings").text("Your earnings: " + earnings)
}
function purchase()
{
chips = chips + 1;
$("#chipsInv").text(chips);
earnings = earnings - 1;
$("#earnings").text("Your earnings: " + earnings);
}
function gainChips(number)
{
chips = chips + number;
$("#chipsInv").text(chips);
earnings = earnings + number;
$("#earnings").text("Your earnings: " + earnings);
}
function loseChip()
{
chips--;
$("#chipsInv").text(chips);
if (chips == 0)
{
alert("You are out of chips. Purchase more chips to continue betting.")
}
}
// 21 = 310
// 23 = 190 degrees
// 9 = 100
// 14 = 120 degrees
// 13 = 240
var randomNum = Math.floor(Math.random() * 355) + 1;
var rw=document.getElementById('wheel');
var rb = document.getElementById('ball');
function rotate(degrees){
rw.setAttribute('style', 'transition: transform 1s; transform:rotate(' + 360 + degrees + 'deg)');
console.log(degrees);
}
function spin(){
for (i = 0; i < randomNum; i = i + 10) {
console.log("2");
rotate(i);
}
var winningDegrees = i - 10;
console.log(winningDegrees);
function winLoss()
{
//some kind of array to run through.
var possBets = [310, 100, 120, 240];
var checkedBets = [];
var divisor = 0;
var winner = false;
for (i = 0; i < possBets.length; i++) {
//check which boxes were checks, and pushes them to a
//checked array
if (document.getElementById(possBets[i]).checked == true)
{
checkedBets.push(possBets[i]);
}
}
divisor = checkedBets.length;
//now you have to ask do any of the checkBets == winningDegrees
//checks if any of the checked bets were winning bets
for (i = 0; i < checkedBets.length; i++) {
if (checkedBets[i] == winningDegrees)
{
winner = true;
}
}
if (winner == true)
{
var earnings = 36/divisor;
alert("Yay! U r teh winz! You earned " + earnings + " chips.");
gainChips(earnings);
}
else if (divisor > 0)
{
alert("You lost 1 chip.")
loseChip();
}
//function winLoss ends here
}
function ballDrop() {
setTimeout(function(){ rb.style.top = "90px";}, 1050);
if (chips > 0)
{
setTimeout(winLoss, 2000);
}
}
ballDrop();
//end of spin function()
}
function reset(){
rw.setAttribute('style', 'transform:rotate(0deg)');
rb.style.top = "50px";
randomNum = Math.floor(Math.random() * 355) + 1;
}
</script>
</body>
</html>
That is because of the hide class you gave to #myModal.
Here is what is seen in the code inspector:
.hide{
display: none!important;
}
So you can remove that class from this markup: <div class="modal hide fade" id="myModal">
Or use .removeClass() like this: $('#myModal').removeClass("hide").modal('show');

How to open a Bootstrap modal without jQuery or bootstrap.js javascript?

I'm working on a VERY LIGHT survey application. This application runs in third world countries in locations with very limited connection.
We found that the loading-time is proportional to user Engagement (Very important to us).
Today I'm using 2 libs - VueJS and a custom bootstrap build. I would like to invoke a modal. But the modal requires to add the Bootstrap Javascript and the jQuery. those libs almost doubles the loading time.
How can I open a modal without adding those two libs?
#uday's link to CSS only modal is a nice trick, but might be awkward to use if you use #tag's for other purposes (eg, Routing & param passing).
So here is an example that uses very little JS to achieve something very similar. I've tried to keep the Snippet as small as possible so that it's easy to see what's happening.
var modal = document.querySelector(".modal");
var container = modal.querySelector(".container");
document.querySelector("button").addEventListener("click", function (e) {
modal.classList.remove("hidden")
});
document.querySelector(".modal").addEventListener("click", function (e) {
if (e.target !== modal && e.target !== container) return;
modal.classList.add("hidden");
});
.modal {
background-color: rgba(0,0,0,0.4); /* Transparent dimmed overlay */
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: table;
}
.modal.hidden {
display: none;
}
.modal .container {
display: table-cell;
text-align: center;
vertical-align: middle;
width: 200px;
}
.modal .body {
box-shadow: 5px 10px #888888;
display: inline-block;
background-color: white;
border: 1px solid black;
padding: 10px;
}
<button>Show Modal</button>
<div class="modal hidden">
<div class="container">
<div class="body">
<p>Click outside this box to close the modal.<p>
<p>You could of course add a close button etc</p>
<p>But this is left for the OP todo</p>
</div>
</div>
</div>
You don't need any css style. You should create the bootstrap modal in your HTML, then in your js, you have to simply give it some style according to the following description:
var locModal = document.getElementById('locModal');
var btnclose = document.getElementById('w-change-close');
var btnShow= document.getElementById('w-change-location');
//show the modal
btnShow.addEventListener('click', (e) => {
locModal.style.display = "block";
locModal.style.paddingRight = "17px";
locModal.className="modal fade show";
});
//hide the modal
btnclose.addEventListener('click', (e) => {
locModal.style.display = "none";
locModal.className="modal fade";
});
The HTML should be like this:
<!-- Button trigger modal -->
<button id="w-change-location" type="button" class="btn btn-primary mt-3" data-toggle="modal" data-target="#locModal">
Change Location
</button>
<!-- Modal -->
<div class="modal fade" id="locModal" tabindex="-1" role="dialog" aria-labelledby="locModalLabel"
aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="locModalLabel">Choose Location</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form action="" id="w-form">
<div class="form-group">
<label for="city"> City</label>
<input type="text" class="form-control" id="city">
</div>
<div class="form-group">
<label for="state"> State </label>
<input type="text" class="form-control" id="state">
</div>
</form>
</div>
<div class="modal-footer">
<button id="w-change-close" type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button id="w-change-btn" type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
We write private code for our modal.
let modal = document.getElementById('our-modal');
let modalContentElm = modal.querySelector('.modal-content');
let allModalButtons = modal.querySelectorAll('.modal-footer > .btn');
let outerClick = true;
let openStyle = () => { //MODAL SHOW
modal.style.backgroundColor = 'rgba(0,0,0,0.5)';
modal.style.display = 'block';
setTimeout(() => { modal.style.opacity = 1; }); //FOR TRANSITION
};
let closeStyle = () => { //MODAL HIDE
modal.style.display = 'none';
modal.style.opacity = 0;
};
//NO CLOSE MODAL WHEN YOU CLICK INSIDE MODAL
modalContentElm.onclick = () => {
outerClick = false;
};
//CLOSE MODAL WHEN YOU CLICK OUTSIDE MODAL
modal.onclick = () => {
if(outerClick){ closeStyle(); }
outerClick = true;
};
for(let btn of allModalButtons){
btn.onclick = () => {
closeStyle();
if(btn.getAttribute('id') === 'success-btn'){
//PLEASE WRITE 'success-btn' IN THE ID VALUE OF THE CONFIRM BUTTON
console.log('Click Yes');
}
else{
console.log('Click Cancel');
}
//..... more else if or else for more modal buttons
};
}
Whenever we want to open modal
openStyle();
Whenever we want to close modal on manuel
closeStyle();
It's a bit laborious, but it works. A more general class can be written.
If you are using bootstrap 5, you can easily show and hide modal with js:
Documentation
const myModal = new bootstrap.Modal(document.getElementById('myModal')); // creating modal object
myModal.show(); // show modal
myModal.hide(); // hide modal
If you open the modal using a button. you can add the bootstrap options to that button data-bs-toggle="modal" data-bs-target="#modalTarget" and also a onclick function like onclick="whenOpenModal();"
function whenOpenModal(){
console.log("modal opened");
}

Custom "confirm" dialog in JavaScript?

I've been working on an ASP.net project that uses custom 'modal dialogs'. I use scare quotes here because I understand that the 'modal dialog' is simply a div in my html document that is set to appear "on top" of the rest of the document and is not a modal dialog in the true sense of the word.
In many parts of the web site, I have code that looks like this:
var warning = 'Are you sure you want to do this?';
if (confirm(warning)) {
// Do something
}
else {
// Do something else
}
This is okay, but it would be nice to make the confirm dialog match the style of the rest of the page.
However, since it is not a true modal dialog, I think that I need to write something like this: (I use jQuery-UI in this example)
<div id='modal_dialog'>
<div class='title'>
</div>
<input type='button' value='yes' id='btnYes' />
<input type='button' value='no' id='btnNo' />
</div>
<script>
function DoSomethingDangerous() {
var warning = 'Are you sure you want to do this?';
$('.title').html(warning);
var dialog = $('#modal_dialog').dialog();
function Yes() {
dialog.dialog('close');
// Do something
}
function No() {
dialog.dialog('close');
// Do something else
}
$('#btnYes').click(Yes);
$('#btnNo').click(No);
}
Is this a good way to accomplish what I want, or is there a better way?
You might want to consider abstracting it out into a function like this:
function dialog(message, yesCallback, noCallback) {
$('.title').html(message);
var dialog = $('#modal_dialog').dialog();
$('#btnYes').click(function() {
dialog.dialog('close');
yesCallback();
});
$('#btnNo').click(function() {
dialog.dialog('close');
noCallback();
});
}
You can then use it like this:
dialog('Are you sure you want to do this?',
function() {
// Do something
},
function() {
// Do something else
}
);
SweetAlert
You should take a look at SweetAlert as an option to save some work. It's beautiful from the default state and is highly customizable.
Confirm Example
sweetAlert(
{
title: "Are you sure?",
text: "You will not be able to recover this imaginary file!",
type: "warning",
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: "Yes, delete it!"
},
deleteIt()
);
To enable you to use the confirm box like the normal confirm dialog, I would use Promises which will enable you to await on the result of the outcome and then act on this, rather than having to use callbacks.
This will allow you to follow the same pattern you have in other parts of your code with code such as...
const confirm = await ui.confirm('Are you sure you want to do this?');
if(confirm){
alert('yes clicked');
} else{
alert('no clicked');
}
See codepen for example, or run the snippet below.
https://codepen.io/larnott/pen/rNNQoNp
const ui = {
confirm: async (message) => createConfirm(message)
}
const createConfirm = (message) => {
return new Promise((complete, failed)=>{
$('#confirmMessage').text(message)
$('#confirmYes').off('click');
$('#confirmNo').off('click');
$('#confirmYes').on('click', ()=> { $('.confirm').hide(); complete(true); });
$('#confirmNo').on('click', ()=> { $('.confirm').hide(); complete(false); });
$('.confirm').show();
});
}
const saveForm = async () => {
const confirm = await ui.confirm('Are you sure you want to do this?');
if(confirm){
alert('yes clicked');
} else{
alert('no clicked');
}
}
body {
margin: 0px;
font-family: "Arial";
}
.example {
padding: 20px;
}
input[type=button] {
padding: 5px 10px;
margin: 10px 5px;
border-radius: 5px;
cursor: pointer;
background: #ddd;
border: 1px solid #ccc;
}
input[type=button]:hover {
background: #ccc;
}
.confirm {
display: none;
}
.confirm > div:first-of-type {
position: fixed;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
top: 0px;
left: 0px;
}
.confirm > div:last-of-type {
padding: 10px 20px;
background: white;
position: absolute;
width: auto;
height: auto;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
border-radius: 5px;
border: 1px solid #333;
}
.confirm > div:last-of-type div:first-of-type {
min-width: 150px;
padding: 10px;
}
.confirm > div:last-of-type div:last-of-type {
text-align: right;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="example">
<input type="button" onclick="saveForm()" value="Save" />
</div>
<!-- Hidden confirm markup somewhere at the bottom of page -->
<div class="confirm">
<div></div>
<div>
<div id="confirmMessage"></div>
<div>
<input id="confirmYes" type="button" value="Yes" />
<input id="confirmNo" type="button" value="No" />
</div>
</div>
</div>
I would use the example given on jQuery UI's site as a template:
$( "#modal_dialog" ).dialog({
resizable: false,
height:140,
modal: true,
buttons: {
"Yes": function() {
$( this ).dialog( "close" );
},
"No": function() {
$( this ).dialog( "close" );
}
}
});
var confirmBox = '<div class="modal fade confirm-modal">' +
'<div class="modal-dialog modal-sm" role="document">' +
'<div class="modal-content">' +
'<button type="button" class="close m-4 c-pointer" data-dismiss="modal" aria-label="Close">' +
'<span aria-hidden="true">×</span>' +
'</button>' +
'<div class="modal-body pb-5"></div>' +
'<div class="modal-footer pt-3 pb-3">' +
'OK' +
'<button type="button" class="btn btn-secondary abortBtn btn-sm" data-dismiss="modal">Abbrechen</button>' +
'</div>' +
'</div>' +
'</div>' +
'</div>';
var dialog = function(el, text, trueCallback, abortCallback) {
el.click(function(e) {
var thisConfirm = $(confirmBox).clone();
thisConfirm.find('.modal-body').text(text);
e.preventDefault();
$('body').append(thisConfirm);
$(thisConfirm).modal('show');
if (abortCallback) {
$(thisConfirm).find('.abortBtn').click(function(e) {
e.preventDefault();
abortCallback();
$(thisConfirm).modal('hide');
});
}
if (trueCallback) {
$(thisConfirm).find('.yesBtn').click(function(e) {
e.preventDefault();
trueCallback();
$(thisConfirm).modal('hide');
});
} else {
if (el.prop('nodeName') == 'A') {
$(thisConfirm).find('.yesBtn').attr('href', el.attr('href'));
}
if (el.attr('type') == 'submit') {
$(thisConfirm).find('.yesBtn').click(function(e) {
e.preventDefault();
el.off().click();
});
}
}
$(thisConfirm).on('hidden.bs.modal', function(e) {
$(this).remove();
});
});
}
// custom confirm
$(function() {
$('[data-confirm]').each(function() {
dialog($(this), $(this).attr('data-confirm'));
});
dialog($('#customCallback'), "dialog with custom callback", function() {
alert("hi there");
});
});
.test {
display:block;
padding: 5p 10px;
background:orange;
color:white;
border-radius:4px;
margin:0;
border:0;
width:150px;
text-align:center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
example 1
<a class="test" href="http://example" data-confirm="do you want really leave the website?">leave website</a><br><br>
example 2
<form action="">
<button class="test" type="submit" data-confirm="send form to delete some files?">delete some files</button>
</form><br><br>
example 3
<span class="test" id="customCallback">with callback</span>
One other way would be using colorbox
function createConfirm(message, okHandler) {
var confirm = '<p id="confirmMessage">'+message+'</p><div class="clearfix dropbig">'+
'<input type="button" id="confirmYes" class="alignleft ui-button ui-widget ui-state-default" value="Yes" />' +
'<input type="button" id="confirmNo" class="ui-button ui-widget ui-state-default" value="No" /></div>';
$.fn.colorbox({html:confirm,
onComplete: function(){
$("#confirmYes").click(function(){
okHandler();
$.fn.colorbox.close();
});
$("#confirmNo").click(function(){
$.fn.colorbox.close();
});
}});
}
Faced with the same problem, I was able to solve it using only vanilla JS, but in an ugly way. To be more accurate, in a non-procedural way. I removed all my function parameters and return values and replaced them with global variables, and now the functions only serve as containers for lines of code - they're no longer logical units.
In my case, I also had the added complication of needing many confirmations (as a parser works through a text). My solution was to put everything up to the first confirmation in a JS function that ends by painting my custom popup on the screen, and then terminating.
Then the buttons in my popup call another function that uses the answer and then continues working (parsing) as usual up to the next confirmation, when it again paints the screen and then terminates. This second function is called as often as needed.
Both functions also recognize when the work is done - they do a little cleanup and then finish for good. The result is that I have complete control of the popups; the price I paid is in elegance.
I managed to find the solution that will allow you to do this using default confirm() with minimum of changes if you have a lot of confirm() actions through out you code. This example uses jQuery and Bootstrap but the same thing can be accomplished using other libraries as well. You can just copy paste this and it should work right away
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Project Title</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<!--[if lt IE 9]>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div class="container">
<h1>Custom Confirm</h1>
<button id="action"> Action </button>
<button class='another-one'> Another </button>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script type="text/javascript">
document.body.innerHTML += `<div class="modal fade" style="top:20vh" id="customDialog" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
</div>
<div class="modal-footer">
<button type="button" id='dialog-cancel' class="btn btn-secondary">Cancel</button>
<button type="button" id='dialog-ok' class="btn btn-primary">Ok</button>
</div>
</div>
</div>
</div>`;
function showModal(text) {
$('#customDialog .modal-body').html(text);
$('#customDialog').modal('show');
}
function startInterval(element) {
interval = setInterval(function(){
if ( window.isConfirmed != null ) {
window.confirm = function() {
return window.isConfirmed;
}
elConfrimInit.trigger('click');
clearInterval(interval);
window.isConfirmed = null;
window.confirm = function(text) {
showModal(text);
startInterval();
}
}
}, 500);
}
window.isConfirmed = null;
window.confirm = function(text,elem = null) {
elConfrimInit = elem;
showModal(text);
startInterval();
}
$(document).on('click','#dialog-ok', function(){
isConfirmed = true;
$('#customDialog').modal('hide');
});
$(document).on('click','#dialog-cancel', function(){
isConfirmed = false;
$('#customDialog').modal('hide');
});
$('#action').on('click', function(e) {
if ( confirm('Are you sure?',$(this)) ) {
alert('confrmed');
}
else {
alert('not confimed');
}
});
$('.another-one').on('click', function(e) {
if ( confirm('Are really, really, really sure ? you sure?',$(this)) ) {
alert('confirmed');
}
else {
alert('not confimed');
}
});
</script>
</body>
</html>
This is the whole example. After you implement it you will be able to use it like this:
if ( confirm('Are you sure?',$(this)) )
I created a js file with below given code and named it newconfirm.js
function confirm(q,yes){
var elem='<div class="modal fade" id="confirmmodal" role="dialog" style="z-index: 1500;">';
elem+='<div class="modal-dialog" style="width: 25vw;">';
elem+='<div class="modal-content">';
elem+='<div class="modal-header" style="padding:8px;background-color:lavender;">';
elem+='<button type="button" class="close" data-dismiss="modal">×</button>';
elem+='<h3 class="modal-title" style="color:black;">Message</h3></div>';
elem+='<div class="modal-body col-xs-12" style="padding:;background-color: ghostwhite;height:auto;">';
elem+='<div class="col-xs-3 pull-left" style="margin-top: 0px;">';
elem+='<img class="img-rounded" src="msgimage.jpg" style="width: 49%;object-fit: contain;" /></div><div class="col-xs-9 pull-left "><p class="aconfdiv"></p></div></div>';
elem+='<div class="modal-footer col-xs-12" style="padding:6px;background-color:lavender;"><div class="btn btn-sm btn-success yes pull-left">Yes</div><button type="button" class="btn btn-default btn-sm" data-dismiss="modal">No</button></div></div></div></div>';
$('body').append(elem);
$('body').append('<div class="lead cresp"></div>');
$('.aconfdiv').html(q);
$('#confirmmodal').modal('show');
$('.yes').on('click',function(){
$('body').find('.cresp').html('Yes');
$('#confirmmodal').modal('hide');
yes();
})
}
and in my main php file calling confirm in the javascript like this
$('.cnf').off().on('click',function(){
confirm("Do you want to save the data to Database?<br />Kindly check the data properly as You cannot undo this action",function(){
var resp=$('body').find('.cresp').html();
$('body').find('.cresp').remove();
if(resp=='Yes'){
alert("You clicked on Yes Bro.....")
}
});
})

Categories

Resources