I have bootstrap 4 modal and inside the Modal body, trying to display a containing a bar chart. Below is the code
<!-- Modal body -->
<div class="modal-body">
Modal body..
<!--Markup to display graph-->
<div id="chart1" style="margin-top: 20px; margin-left: 20px; width: 300px; height: 300px;"></div>
</div
when I am keeping "chart1" outside of Modal body, I can see chart displayed whereas same is not happening when its inside body of Modal. Modal is displayed on click of a below button
<button type="submit" class="btn btn-primary mb-2" style=" margin-left:30px; margin-top:20px; display:none" id="analyzeAndPredict" data-toggle="modal" data-target="#graphicalModal" onclick="BarChartAjax('2, 4, 5, 6', ['a', 'b', 'c', 'd'])">Analyze & Predict</button>
What's wrong with above code?
Tried to add code in fiddle
http://jsfiddle.net/r2sd5b0y/
I have removed onClick from a button and call BarChartAjax on shown.bs.modal in js
$('#graphicalModal').on('shown.bs.modal', function () {
BarChartAjax('2, 4, 5, 6', ['a', 'b', 'c', 'd']);
})
Here chart displayed when modal open but I think there is some issue with an array you passed to BarChartAjax function so that chart is not displaying correctly so check your values you passed to function
function DisplayBarChart(data) {
//debugger;
var array = data.split("-");
var s1 = array[0].split(',').map(function (el) { return +el; });
var ticks = array[1].split(',');
$.jqplot.config.enablePlugins = true;
console.log(s1);
plot1 = $.jqplot('chart1', [s1], {
// Only animate if we're not using excanvas (not in IE 7 or IE 8)..
animate: !$.jqplot.use_excanvas,
seriesDefaults: {
renderer: $.jqplot.BarRenderer,
pointLabels: { show: true }
},
axes: {
xaxis: {
renderer: $.jqplot.CategoryAxisRenderer,
ticks: ticks
}
},
highlighter: { show: false }
});
$('#chart1').bind('jqplotDataClick',
function (ev, seriesIndex, pointIndex, data) {
$('#info1').html('series: ' + seriesIndex + ', point: ' + pointIndex + ', data: ' + data);
}
);
}
function BarChartAjax(xdata, ydata) {
var dataToSend = JSON.stringify({ 'GraphData': xdata + "-" + ydata });
DisplayBarChart(dataToSend);
}
$('#graphicalModal').on('shown.bs.modal', function () {
BarChartAjax('2, 4, 5, 6', ['a', 'b', 'c', 'd']);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/jqPlot/1.0.9/jquery.jqplot.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqPlot/1.0.9/jquery.jqplot.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqPlot/1.0.9/plugins/jqplot.barRenderer.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqPlot/1.0.9/plugins/jqplot.categoryAxisRenderer.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqPlot/1.0.9/plugins/jqplot.pointLabels.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>
<button type="submit" class="btn btn-primary mb-2" style=" margin-left:30px; margin-top:20px;" id="analyzeAndPredict" data-toggle="modal" data-target="#graphicalModal" >Analyze & Predict</button>
<div class="modal fade" id="graphicalModal">
<div class="modal-dialog">
<div class="modal-content">
<!-- Modal Header -->
<div class="modal-header">
<h4 class="modal-title">Modal Heading</h4>
<button type="button" class="close" data-dismiss="modal">×</button>
</div>
<!-- Modal body -->
<div class="modal-body" id="graphicalModalBody">
Modal body..
<div id="chart1" style=" margin-top: 20px; margin-left: 20px; width: 300px; height: 300px;"></div>
</div>
<!-- Modal footer -->
<div class="modal-footer">
<button type="button" class="btn btn-danger" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
Related
I have an alert that shows under some conditions. I want the alert to contain a link and execute some code when that link is clicked. However, I'm getting error "ReferenceError: doTheThing is not defined".
function doTheThing() {
document.getElementById("thing").innerHTML = "Done.";
};
var alert = '<div class="alert alert-warning alert-dismissible fade show"
role="alert"><button type="button" class="close" data-dismiss="alert"
aria-label="Close"><span aria-hidden="true">×</span></button>Please
submit your wallet address or <span class="btn-link"
id=btn-donate onclick="doTheThing()">click here to donate your winnings.</span></div>';
var alertHTML = $(alert);
document.getElementById("placeholder").innerHTML = alert;
and html;
<div id=placeholder></div>
<div id=thing></div>
I assume: you defined the function in the dom ready context. If so, move the function outside.
function doTheThing() {
document.getElementById("thing").innerHTML = "Done.";
};
$(function () {
var alert = '<div class="alert alert-warning alert-dismissible fade show"\
role="alert"><button type="button" class="close" data-dismiss="alert"\
aria-label="Close"><span aria-hidden="true">×</span></button>Please\
submit your wallet address or <span class="btn-link"\
id=btn-donate onclick="doTheThing()">click here to donate your winnings.</span></div>';
var alertHTML = $(alert);
document.getElementById("placeholder").innerHTML = alert;
});
.row {
background: #f8f9fa;
margin-top: 20px;
}
.col {
border: solid 1px #6c757d;
padding: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" >
<div id=placeholder></div>
<div id=thing></div>
In your provided example change following settings:
As Renan Souza sad, it has to be included inside its own file.
This code works fine:
function doTheThing() {
document.getElementById("thing").innerHTML = "Done.";
};
var alert = `<div class="alert alert-warning alert-dismissible fade show"
role="alert"><button type="button" class="close" data-dismiss="alert"
aria-label="Close"><span aria-hidden="true">×</span></button>Please
submit your wallet address or <span class="btn-link"
id=btn-donate onclick="doTheThing()">click here to donate your winnings.</span></div>`;
var alertHTML = $(alert);
document.getElementById("placeholder").innerHTML = alert;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='placeholder'>
</div>
<div id='thing'>
</div>
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");
}
Writing some js for an html file where i input a sentence (string). and when i click a button, it outputs the amount of each individual vowel, excluding y and not paying attention to punctuation. I cannot use var so i am trying to make this work using let. I believe i'm on the right path here,starting with the vowel a, yet if the sentence doesn't contain an a i get an error. I can't think of what to do next. Any thoughts?
'use strict';
let vButton = document.querySelectorAll('#vowels');
vButton.forEach(function(blip) {
blip.addEventListener('click', function(evt) {
evt.preventDefault();
console.log('click');
let vowelString = document.getElementById('roboInput'),
sentence = vowelString.value;
if (sentence !== '') {
let aMatches = sentence.match(/a/gi).length;
alert("a - " + aMatches);
}
vowelString.value = '';
});
});
a {
cursor: pointer;
}
.well-robot {
min-height: 340px;
}
.input-robot {
width: 100%;
min-height: 100px;
}
.output-robot {
border: 1px solid #000000;
min-height: 150px;
margin-top: 10px;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css">
<div class="container">
<div class="alert alert-info">
Hello! I'm a smart robot. I can do many interesting things. Type something below and click a button to watch me work!
</div>
<div class="row">
<div class="col-sm-4">
<img src="./robot.gif">
</div>
<div class="col-sm-8 well well-robot">
<textarea id="roboInput" placeholder="Input something here!" class="input-robot"></textarea>
<div class="btn-group btn-group-justified">
<a class="btn btn-default" id="vowels">Count Vowels</a>
<a class="btn btn-default" id="anagrams">Count Anagrams</a>
<a class="btn btn-default" id="distance">Word Distance</a>
</div>
<div id="robotResult" class="output-robot">
</div>
</div>
</div>
</div>
When there's no match for the regular expression, .match() returns null, not an empty array, so you can't get the length. You need to check for that.
let matches = sentence.match(/a/gi);
let matchLength = matches ? matches.length : 0;
alert('a - ' + matchLength);
If I understand your question correctly, you may want something like this:
'use strict';
let vButton = document.querySelectorAll('#vowels');
vButton.forEach(function(blip) {
blip.addEventListener('click', function(evt) {
evt.preventDefault();
//console.log('click');
let vowelString = document.getElementById('roboInput'),
sentence = vowelString.value;
if (sentence) {
let result = {a: 0, e: 0, i: 0, o: 0, u: 0 };
for(var i = 0, l = sentence.length; i < l; i++) {
if(result.hasOwnProperty(sentence[i]))
result[sentence[i]]++;
}
console.log(result);
}
vowelString.value = '';
});
});
a {
cursor: pointer;
}
.well-robot {
min-height: 340px;
}
.input-robot {
width: 100%;
min-height: 100px;
}
.output-robot {
border: 1px solid #000000;
min-height: 150px;
margin-top: 10px;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css">
<div class="container">
<div class="alert alert-info">
Hello! I'm a smart robot. I can do many interesting things. Type something below and click a button to watch me work!
</div>
<div class="row">
<div class="col-sm-4">
<img src="./robot.gif">
</div>
<div class="col-sm-8 well well-robot">
<textarea id="roboInput" placeholder="Input something here!" class="input-robot"></textarea>
<div class="btn-group btn-group-justified">
<a class="btn btn-default" id="vowels">Count Vowels</a>
<a class="btn btn-default" id="anagrams">Count Anagrams</a>
<a class="btn btn-default" id="distance">Word Distance</a>
</div>
<div id="robotResult" class="output-robot">
</div>
</div>
</div>
</div>
I am new to angularjs and I am trying to populate a ui grid with data from a data base. I have tried searching for other issue sbut I haven't found anything similar to my issue online. The table shows just fine but none of my data is populating. I have seen it in the developer tools in Chrome under Source and it appears to be properly formated as a Json object but I cant get it to display anything in the table. I know it is probably something small I am doing or not doing any help would be appreciated.
Below is my controller js
var app = angular.module('skill', ["ui.grid",
"ui.grid.edit",
"ui.grid.selection",
"ui.grid.pagination",
"ui.grid.exporter",
"ui.grid.cellNav"]);
app.controller('SkillEntryController', function ($scope, $http, $interval, uiGridConstants, SkillService) {
$scope.data = [];
SkillService.GetSkills().then(function (d) {
$scope.data = d.data;
}, function () {
alert('Failed');
});
$scope.columns = [
{ name: "SkillName", displayName: "Skill Code", minWidth: 150, width: "33%" },
{ name: "Category", minWidth: 150, width: "33%" },
{ name: "Description", minWidth: 150, width: "33%" }
];
$scope.gridOptions = {
enableSorting: true,
enableRowSelection: true,
enableCellEditOnFocus: true,
exporterHeaderFilterUseName: true,
treeRowHeaderAlwaysVisible: false,
paginationPageSizes: [25, 50, 75],
paginationPageSize: 25,
columnDefs: $scope.columns,
data: $scope.data,
onRegisterApi: function (gridApi) {
$scope.gridApi = gridApi;
}
};
}).factory('SkillService', function ($http) {
var fac = {}
fac.GetSkills = function () {
return $http.get('/Skills/GetSkills');
}
return fac;
});
Here is my factory method:
public JsonResult GetSkills()
{
List<Skill> c = new List<Skill>();
return new JsonResult { Data = c.Select(x => new { x.Category, x.Description, x.SkillCodeID, x.SkillName }), JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
And here is my cshtml file:
#model IEnumerable<SkillResourceCenterApp.Models.Skill>
#using Newtonsoft.Json;
#{
ViewData["Title"] = "Add Skill";
}
#section scripts{
<link href="~/Content/ui-grid.css" rel="stylesheet" />
<script src="~/Scripts/angular.js"></script>
<script src="~/Scripts/ui-grid.js"></script>
<script src="~/Scripts/Controller/skill-entry-controller.js"></script>
}
<style>
.ui-grid-cell.cell-center {
text-align: center;
}
.ui-grid-cell.cell-right {
text-align: right;
}
.no-rows {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
background: rgba(0, 0, 0, 0.4);
}
.no-rows .msg {
opacity: 1;
position: absolute;
top: 30%;
left: 33%;
width: 30%;
height: 25%;
line-height: 200%;
background-color: #eee;
border-radius: 4px;
border: 1px solid #555;
text-align: center;
font-size: 24px;
display: table;
}
.no-rows .msg span {
display: table-cell;
vertical-align: middle;
}
</style>
<h3>#ViewData["Title"]</h3>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<div class="container-fluid" ng-app="skill" ng-controller="SkillEntryController">
<div class="row">
<button type="button" ng-click="addNewRow()" class="btn btn-default col-sm-3 col-md-2">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Add Row
</button>
<button type="button" ng-click="deleteSelected()" class="btn btn-default col-sm-3 col-md-2">
<span class="glyphicon glyphicon-remove" aria-hidden="true"></span> Delete Selected
</button>
<button type="button" ng-click="exportToCSV()" class="btn btn-default col-sm-3 col-md-2">
<span class="glyphicon glyphicon-download" aria-hidden="true"></span> Export to Excel
</button>
<button type="button" ng-click="save()" class="btn btn-primary col-md-offset-4 pull-right col-sm-2">
Save
</button>
</div>
<div class="row">
<div class="grid" ui-grid="gridOptions"
ui-grid-pagination
ui-grid-selection
ui-grid-edit
ui-grid-exporter
ui-grid-cellNav
style="height: 500px;">
<div class="no-rows" ng-show="!gridOptions.data.length">
<div class="msg">
<span>No Results</span>
</div>
</div>
</div>
</div>
</div>
You're missing the field definition in columnDefs. Have a look at https://github.com/angular-ui/ui-grid/wiki/Defining-columns
var columnDefs: [{
field: 'foo',
displayName: 'my foo',
visible: true,
maxWidth: 90,
enableColumnResizing: false,
cellTemplate: "<div>{{row.entity.foo}}</div>"
}];
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.....")
}
});
})