chatbot window got closed each time after pressed the send message button - javascript

I 'm trying to build a chatbot for my Django application. Based on this tutorial, I have made the following javascript and html. The problem is that after sending each message (pressed send button), the chatbot window get closed. Normally it should only be closed after a discussion is finished. I am not sure what has happened. I tried to use prevent default event method(not sure though if I did it correctly), problem still exists.
class Chatbox {
constructor() {
this.args = {
openButton: document.querySelector('.chatbox__button'),
chatBox: document.querySelector('.chatbox__support'),
sendButton: document.querySelector('.send__button')
}
this.state = false;
this.messages = [];
}
display() {
const {openButton, chatBox, sendButton} = this.args;
openButton.addEventListener('click', () => this.toggleState(chatBox))
sendButton.addEventListener('click', () => this.onSendButton(chatBox))
const node = chatBox.querySelector('input');
node.addEventListener("keyup", ({key}) => {
if (key === "Enter") {
this.onSendButton(chatBox)
}
})
}
toggleState(chatbox) {
this.state = !this.state;
// show or hides the box
if(this.state) {
chatbox.classList.add('chatbox--active')
} else {
chatbox.classList.remove('chatbox--active')
}
}
onSendButton(chatbox) {
var textField = chatbox.querySelector('input');
let text1 = textField.value
if (text1 === "") {
return;
}
let msg1 = { name: "User", message: text1 }
this.messages.push(msg1);
fetch('/chatbot', {
method: 'POST',
body: JSON.stringify({ message: text1 }),
headers: {'X-CSRFToken': Cookies.get('csrftoken')},
mode: 'same-origin' //
})
.then(r => r.json())
.then(r => {
let msg2 = { name: "Sam", message: r.answer };
this.messages.push(msg2);
console.log("msg2")
this.updateChatText(chatbox)
console.log("updated chat text")
textField.value = ''
}).catch((error) => {
console.error('Error:', error);
this.updateChatText(chatbox)
textField.value = ''
});
}
updateChatText(chatbox) {
let html = '';
this.messages.slice().reverse().forEach(function(item, index) {
if (item.name === "Sam")
{
html += '<div class="messages__item messages__item--visitor">' + item.message + '</div>'
}
else
{
html += '<div class="messages__item messages__item--operator">' + item.message + '</div>'
}
});
const chatMessages = chatbox.querySelector('.chatbox__messages');
chatMessages.innerHTML = html + chatMessages.innerHTML;
// chatMessages.innerHTML = html;
}
}
const chatbox = new Chatbox();
chatbox.display();
Here is the html:
{% load static %}
<!DOCTYPE html>
<link rel="stylesheet" type="text/css" href="{% static 'css/bot.css' %}">
<head>
<meta charset="UTF-8">
<title>Chatbot</title>
</head>
<body>
<div class="container">
<div class="chatbox">
<div class="chatbox__support">
<div class="chatbox__header">
<div class="chatbox__image--header">
<img src="https://files.softicons.com/download/social-media-icons/free-social-media-icons-by-uiconstock/png/48x48/Reddit-Icon.png" alt="image">
</div>
<div class="chatbox__content--header">
<h4 class="chatbox__heading--header">Chat support</h4>
<p class="chatbox__description--header">Hi. My name is Sam. How can I help you?</p>
</div>
</div>
<div class="chatbox__messages">
{% for message, response,timestamp in chat_history %}
<!-- Response -->
{% if response %}
<div class="messages__item messages__item--visitor">
{{ response }}
</div>
<!-- Message -->
<div class="messages__item {% if response %}messages__item--operator{% else %}messages__item--{% endif %}">
{{ message }}
</div>
{% endif %}
{% endfor %}
</div>
<div class="chatbox__footer">
<form method="post" action="{% url 'chatbot' %}">
{% csrf_token %}
<!-- Input -->
<input type="text" name="message" class="input" placeholder="Type your message here...">
<button type="submit" class="chatbox__send__footer send__button" >Send</button>
</form>
</div>
</div>
<div class="chatbox__button">
<button><img src="https://raw.githubusercontent.com/patrickloeber/chatbot-deployment/ce309f3aae1ccc3783059876a1b66e4d7d77ca9f/standalone-frontend/images/chatbox-icon.svg" /></button>
</div>
</div>
</div>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/js-cookie#2/src/js.cookie.min.js"></script>
<script type="text/javascript" src="{% static 'js/bot.js' %}"></script>
</body>
</html>
In console, the error message is :
Note:
bot.js:69:21 from this line: console.error('Error:', error);
Error: TypeError: NetworkError when attempting to fetch resource.
onSendButton http://127.0.0.1:8000/static/js/bot.js:69
(Async: promise callback)
onSendButton http://127.0.0.1:8000/static/js/bot.js:68
display http://127.0.0.1:8000/static/js/bot.js:19
(Async: EventListener.handleEvent)
display http://127.0.0.1:8000/static/js/bot.js:19
<anonymous> http://127.0.0.1:8000/static/js/bot.js:99
Any ideas? Thank you!

I'm not sure why you get the error, but I have been able to reproduce the error on my machine, and the fix is simple. Change your button to type button instead of submit:
<button type="button" class="chatbox__send__footer send__button" >Send</button>
When the button type is submit, then it will try to send the form the normal route, but you want your JavaScript to handle it instead. If you had a submit event listener, you would use preventDefault() to prevent the button from causing the form to be submitted the normal, default way.
The way you have it now, the button is both trying to send the form the normal route and the JavaScript is also trying to handle the event, and I think that is what is causing the issue.
You could leave the button as type submit and then use preventDefault() by giving the button an id:
<button id="send__button" type="submit" class="chatbox__send__footer send__button" >Send</button>
And then and adding this to your script, outside of chatbox
document.getElementById('send__button').addEventListener('click', (e) => {
e.preventDefault();
});

Related

Send data to another django template/view after specific process using ajax

I have a page where I load 2 files. After a click to the load button, this page reload to display a major part of the data, allowing the user to modified it. After a click to lunch button, I want to launch the process and I want to send to another page the path of results files to allow the user to download it.
My problem is after clicking on lunch button and send data to the other page. I have 2 versions :
The first one, send data to the result page, but I do not find a way to take back in the view the data modified by the user, the ajax seems to be ignored because of the type "summit" for the button launch :
<body>
<section class="bg-light py-5 border-bottom">
<div class="container px-5 my-5 px-5">
<div>
<h1 class="display-5 fw-bolder mb-2"> Convert to Dose </h1>
<br>
</div>
<form id="formCTD" action="{% url 'json:convertToDose' %}" method="POST" enctype="multipart/form-data">
{% csrf_token %}
##here some fields to modified one of them following
<div class="row gx-5 justify-content-center">
<div class="col-lg-4 col-xl-4">
{% if factors %}
<input name="img_path" readonly
class="form-control" {{ pathAnalyseForm.img_path }}>
{% else %}
<input id="btn-submit-form-jsonfile"
class="btn btn-lg" {{ formImgFile.imgFile }}>
{% endif %}
</div>
</div>
<div class="text-center">
<div class="d-grid">
{% if factors %}
<button class="btn btn-primary btn-lg" id="launchButton" type="submit">
Launch
</button>
{% else %}
<button class="btn btn-primary btn-lg" id="submitButton" type="submit">
Load
</button>
{% endif %}
/div>
</div>
</form>
</div>
</section>
</body>
And the js block :
<script type="text/javascript">
$(document).ready(function () {
$("#launchButton").on('submit', function(e) {
e.preventDefault();
var form = $("#formCTD").get(0) //recup en html
// Est-ce que le formulaire est valide ?
console.log("valid? ")
if (form.checkValidity()) {
console.log("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ")
nam = $("input[name='img_path']").val()
json = $("input[name='json_path']").val()
console.log(nam)
data = {"img_path" : nam,
"json_path": json}
console.log("bef ajax")
$.ajax({
url: "/filmchromique/convertToDose/",
type: "POST",
data: data,
beforeSend: function (xhr, settings) {
xhr.setRequestHeader("X-CSRFToken", $('input[name="csrfmiddlewaretoken"]').val());
},
success: function (response) {
console.log("ok")
},
error: function(xhr, status, error) {
alert(xhr.responseText);
}
})
console.log("after ajax")
}
});
});
</script>
And the view :
def launchCtd(request):
if request.method == 'POST':
#2 after click load
if bool(request.FILES.get('calibrationFile', False)) == True and bool(request.FILES.get('imgFile', False)) == True :
#do some test ok
context = {
'factors': True,
'factorsCalib': factorsCalib,
'formCtd': formCtd,
'formJsonFile': formJsonFile,
'formImgFile': formImgFile,
'pathAnalyseForm': pathAnalyseForm,
'doseRect': doseRect,
'ctrlRect': ctrlRect,
}
return render(request, 'convertToDose.html', context)
after click lunch
else:
if request.is_ajax:
print ("here")#check
img_path = request.POST.get("img_path")
doseRectStr = request.POST.getlist('form[]')
json_pactrlRectth = request.POST.get("json_path")
method = request.POST.get("analyse_type")
if method == 'rb':
#init var
if method == 'multi':
#init var
img_out_path, json_pactrlRectth = functionTOLaunch()
context = {
'filename': img_out_path,
'protocol_file': json_pactrlRectth,
}
return render(request, 'result.html', context)
#1 load init
else:
formCtd = CtdForm()
formJsonFile = JsonFileForm()
formImgFile = ImgFileForm()
context = {
'factors': False,
'formCtd': formCtd,
'formJsonFile': formJsonFile,
'formImgFile' : formImgFile,
}
return render(request, 'convertToDose.html', context)
and the result page is a basic TemplateView.
In this first case, console.log in the ajax are not printed, I do not understand why and I supposed the function is not called (and so the ajax part)
in the second version, views are identical but I modified this on the html :
<button class="btn btn-primary btn-lg" id="launchButton" type="button">
Launch</button>
and this in the js part :
$("#launchButton").on('click', function(e) {....}
Data are sended to the view, I can read it but when I do the render to display the result page with out process data, nothing append... I supposed I have to implement something in the succes ajax part, but I do not understand what I have to do. I supposed I have to implement a new ajax request, to send the new context to the result page but how I take back the context sended by the render in the success ajax ... I'am totaly new and lost on this tech
Thanks for reading :)

Control JavaScript window open and close

I have a modal window that allows me to create new instances but I'm getting some strange behaviour:
If I get an error because the site already exists the window closes
If I manage to insert the new site the window stays open
I need to reverse the behaviour.
const addBtn = document.getElementById('add-btn')
const modalBody = document.getElementById('model-body')
const siteForm = document.getElementById('site-form')
const alertBox = document.getElementById('alert-box')
const siteName = document.getElementById('id_name')
const siteCity = document.getElementById('id_city')
const csrf = document.getElementsByName('csrfmiddlewaretoken')[0].value
const handleAlerts = (type, msg) => {
alertBox.innerHTML = `
<div class="alert alert-${type}" role="alert">
${msg}
</div>
`
}
addBtn.addEventListener('click', ()=>{
siteForm.addEventListener('submit', e=>{
if (siteName.value ===''){
handleAlerts('danger', 'Name field cannot be left empty')
siteName.focus()
}else{
e.preventDefault()
const formData = new FormData()
formData.append('csrfmiddlewaretoken', csrf)
formData.append('name', siteName.value)
formData.append('city', siteCity.value)
$.ajax({
type: 'POST',
url: '/savesite/',
data: formData,
success: function(response){
handleAlerts('success', 'Site added')
siteForm.reset()
window.close();
},
error: function(error){
console.log(error)
handleAlerts('danger', 'Site already exists in that city')
},
processData: false,
contentType: false,
})
}
})
})
After changing the above code I now get the message at the console:
Scripts may close only windows that were opened by them.
This is the HTML file that opens the modal window:
{% extends 'base.html' %}
{% load static %}
{% load crispy_forms_tags %}
{% block scripts %}
<script src="{% static 'objects/home.js' %}" defer></script>
{% endblock scripts %}
{% block title %}
Site List
{% endblock title %}
{% block content %}
<!-- Modal -->
<div class="modal fade" id="addModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Add Site</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body" id="modal-body">
<div id="alert-box"></div>
<form id="site-form">
{% csrf_token %}
{{site_form|crispy}}
<button type="submit" class="btn btn-info mt-3">Save</button>
</form>
</div>
</div>
</div>
</div>
<h1>Site List</h1>
<hr>
<button type="submit" class="btn btn-danger mb-5" id="add-btn" data-bs-toggle="modal" data-bs-target="#addModal">Add new Site</button>
{% for obj in object_list %}
<div class="card mb-3">
<div class="card-body">
<h5 class="card-title">{{obj.name}}</h5>
<p class="card-text">{{obj.city}}</p>
Details
</div>
</div>
<br>
{% endfor %}
<br>
{% endblock content %}
After some struggle I think I managed to make it working. I'm sure it is not perfect but... I appretiate any comments so I can turn it better:
const addBtn = document.getElementById('add-btn')
const modalBody = document.getElementById('model-body')
const siteForm = document.getElementById('site-form')
const alertBox = document.getElementById('alert-box')
const siteName = document.getElementById('id_name')
const siteCity = document.getElementById('id_city')
const csrf = document.getElementsByName('csrfmiddlewaretoken')[0].value
const handleAlerts = (type, msg) => {
alertBox.innerHTML = `
<div class="alert alert-${type}" role="alert">
${msg}
</div>
`
}
addBtn.addEventListener('click', ()=>{
siteForm.addEventListener('submit', e=>{
if (siteName.value ===''){
e.preventDefault()
handleAlerts('danger', 'Name field cannot be left empty')
siteName.focus()
}else{
console.log('Campo preenchido')
e.preventDefault()
const formData = new FormData()
formData.append('csrfmiddlewaretoken', csrf)
formData.append('name', siteName.value)
formData.append('city', siteCity.value)
$.ajax({
type: 'POST',
url: '/savesite/',
data: formData,
success: function(response){
handleAlerts('success', 'Site added')
siteForm.reset()
window.close();
},
error: function(error){
console.log(error)
handleAlerts('danger', 'Site already exists in that city')
},
processData: false,
contentType: false,
})
}
})
})
The HTML is the same.

Vue : Accessing Nested Object Component's Values

I have problems accessing this "name" property on the component. I can only access it statically.
<template>
<div class="col-md-12">
<p
v-for="channel in channels"
:key="channel.id"
class="channel"
:class="{ 'active': channel.id == activeChannel }"
#click="setChannel(channel.id)">
{{ channel.users[0].name }}
</p>
</div>
</template>
Here is an Image of my Vue Devtools
So I have an v-for loop over channels, and I want to: Access the Usernames for each channel (if it is not my own preferably as "username" is set on my own i think its easy to exclude it right?) So that in the end In Channel 1 when there are 2 Users , I want to show the corresponding username, so the "other username", the one i am chatting with, and he should see my name that is the initial goal.
I thought of doing something like this:
<template>
<div class="col-md-12">
<p
v-for="channel in channels"
:key="channel.id"
class="channel"
:class="{ 'active': channel.id == activeChannel }"
#click="setChannel(channel.id)">
<!-- {{ channel.users[0].name }} -->
<span v-for="user,key in channel">{{key}}</span>
</p>
</div>
it at least displays the content of the channels object for each channel, but something like this isnt gonna work: key.user.name , unfortunately im stuck here. please help :)
edit: here is a dd() of the view
click
EDIT 2: Parent Data Provided:
//chat-app.blade.php
<div id="app">
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">Chats</div>
<vue-chat :channels="{{ $channels }}" ></vue-chat>
</div>
</div>
</div>
</div>
</div>
</div>
//<vue-chat> component
<template>
<div class="chat">
<div class="container">
<div class="row">
<div class="col-md-3">
<vue-chat-channels
:channels="channels"
:active-channel="activeChannel"
#channelChanged="onChannelChanged"
:username="sername"
></vue-chat-channels>
</div>
<div class="col-md-3">
<vue-chat-messages :messages="messages"></vue-chat-messages>
</div>
<div class="col-md-3">participants</div>
</div>
<div class="message-input-wrapper col-md-12"><vue-chat-new-message :active-channel="activeChannel"
:username="username"></vue-chat-new-message></div>
</div>
</div>
</template>
<script>
export default {
props: ["channels"],
data() {
return {
activeChannel: this.channels[0].id,
messages: [],
username: ''
};
},
methods: {
fetchMessages() {
let endpoint = `/channels/${this.activeChannel}/messages`;
axios.get(endpoint).then(({ data }) => {
this.messages = data;
});
},
onChannelChanged(id) {
this.activeChannel = id;
this.fetchMessages();
}
},
created() {
this.fetchMessages();
axios.get('/userfetch').then( ({data}) => {
console.log("Current User: "+data.name);
this.username = data.name;
});
console.log(this.channels[0].name);
// for (let channel of this.channels) {
this.channels.forEach(channel => {
// Channelname
window.Echo.channel('presence-'+channel.name)
.listen('MessageSent', (channel) => {
console.log(channel.data.message);
this.messages.push({ message: channel.data.message, author_username: channel.data.author_username});
if (this.activeChannel == channel.id) {
console.log("received message");
}
});
});
}
};
</script>
<style>
</style>
//ChatController.php
public function index()
{
$channels = Channel::with('users')->whereHas('users', function($q) {
$q->where('user_id',Auth::id());
})->get();
$user = Auth::user()->name;
return view('chat-app' , compact('channels','user'));
}
Short Explanation: ChatController returns the blade view, which has the data channels and user (my username) , and then vue comes into play which should pass down the prop of my username but i couldnt get it to work just yet
So you need to access users in every channel.
You can try like this:
<div class="col-md-12">
<p
v-for="channel in channels"
:key="channel.id"
class="channel"
:class="{ 'active': channel.id == activeChannel }"
#click="setChannel(channel.id)">
<span v-for="user in channel.users">
{{ user.name }}
</span>
</p>
</div>
This should work. If you have errors provide it here.
If you need to compare every user you can do it simply with v-if:
<span v-for="user in channel.users">
<span v-if="user.name === parentdata">
{{ user.name }}
</span>
</span>

Cannot display angularJS scope components

I am making a web application using AngularJS and Laravel. The application is meant to allow the user to post a note on a board. With the code I have, when submitting the note it gets saved to the database but it does not display on the page.
angulartest.blade.php:
<!doctype html>
<html lang="en" ng-app="app">
<title>Test angular</title>
<link rel="stylesheet" href="css/bootstrap.css">
<body>
<div class="container" ng-controller="NoteController">
<h3>Add note</h3>
<form ng-submit="addNote()">
<input type="text" ng-model="newNote.content">
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
<ul>
<li ng-repeat="note in notes">
#{{ note.content }}
</li>
</ul>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.28/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0rc1/angular-route.min.js"></script>
<script type="text/javascript" src="js/app.js"></script>
</body>
</html>
app.js
var app = angular.module('app', ['ngRoute']);
app.factory('Data', function Data($http) {
return {
getNotes: function getNotes() { return $http.get('/notes/all'); },
addNote: function addNote(data) { return $http.post('/notes', data); },
removeNote: function removeNote(id) { return $http.delete('/notes?id='+ id); }
}
});
app.controller('NoteController', function NoteController($scope, Data) {
Data.getNotes().success(parseNotes);
function parseNotes(data) {
$scope.notes = data;
}
$scope.newNote = { content: '', poster: '' };
$scope.addNote = function addNote() {
Data.addNote({
content: $scope.newNote.content,
poster: $scope.newNote.post
})
.success(noteAddSuccess).error(noteAddError);
}
function noteAddSuccess(data) {
$scope.error = null;
$scope.notes.push(data);
console.log($scope.notes);
$scope.newNote = { content: '', poster: '' };
}
function noteAddError(data) {
$scope.error = data;
}
$scope.removeNote = function removeNote(id) {
if (confirm('Do you really want to remove this note?')) {
Data.removeNote(id).success(noteRemoveSuccess);
}
}
function noteRemoveSuccess(data) {
var i = $scope.notes.length;
while (i--) {
if ($scope.notes[i].id == data) {
$scope.notes.splice(i, 1);
}
}
}
});
I believe this is all the relevant code. I'm not sure why it is not displaying note.content
Thank you
Since the data update is not triggered from UI, i.e on user clicks or similar activity the scope might be unaware of the changes. In your code you are updating the data from the service, thus my first suggestion will be is to use $scope.$apply() to propagate the changes on the model to the UI.
function parseNotes(data) {
$scope.notes = data;
if (!$scope.$$phase) {
$scope.$apply();
}
}
This might help. If not then, please post back
I found my error, really simple. I was closing div tag before I was requesting {{note.content}}. It should look like:
<div class="container" ng-controller="NoteController">
<h3>Add note</h3>
<form ng-submit="addNote()">
<input type="text" ng-model="newNote.content">
<button type="submit" class="btn btn-primary">Submit</button>
</form>
<ul>
<li ng-repeat="note in notes">
#{{ note.content }}
</li>
</ul>
</div>
thank you for the replies!

change js confirm to a twitter bootstrap modal

I have some JavaScript that displays a confirm dialog box to the user to confirm their action with passed in variables.
However, I must change the plain confirm dialog to a twitter-bootstrap modal.
I have tried several times, read a lot of SO posts and read the twitter bootstrap docs, but I cannot get it to work as my knowledge of js is not good enough. I am getting stuck on the display of the variables in the twitter bootstrap modal.
I am hoping that some one can help me out by giving me some pointers.
Here is my current js dialog code:
function checkboxUpdated(checkbox, count, label, id) {
if (checkbox.checked) {
$('#menu_entry_' + id).show();
} else {
if (count > 0) {
if (! confirm('{% trans "You have '+ count +' saved '+ label +'.\n\nIf you leave this option un-checked your saved '+ label +' will be deleted only after you update this page.\n\nAre you sure you want to delete your ' + count + ' saved ' + label +'?" %}')) {
checkbox.checked = true;
return;
}
}
$('#menu_entry_' + id).hide();
}
}
EDIT: ADDED CODE OF #menu_entry_ as requested in comment:
{% for id, menu_entry, selected, item_count in menu_entries %}
<li id="menu_entry_{{ id }}" {% if not selected %}style="display:none;"{% endif %}>
<a
{% if id == 4 %}
href="{% url summary_details %}"
{% elif id == 8 %}
href="{% url objective_details %}"
{% elif id == 12 %}
href="{% url leading_employment_details %}"
{% elif id == 16 %}
href="{% url desired_occupation_details %}"
....
{% elif id == 112 %}
href="/"
{% else %}
href="/"
{% endif %}
onclick="showProgressAnimation();">
Note that I need to transform the following js confirm code to twitter bootstrap modal code:
if (! confirm('{% trans "You have '+ count +' saved '+ label +'.\n\nIf you leave this option un-checked your saved '+ label +' will be deleted only after you update this page.\n\nAre you sure you want to delete your ' + count + ' saved ' + label +'?" %}')) {
You can write your own jQuery plugin. First, add the Bootsrap's modal component to your document.
<div class="modal fade" id="confirm" tabindex="-1" role="dialog" aria-labelledby="confirm-label" aria-hidden="true">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
<h4 class="modal-title" id="confirm-label"></h4>
</div>
<div class="modal-body">
<p class="message"></p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default dismiss" data-dismiss="modal"></button>
<button type="button" class="btn btn-primary confirm" data-dismiss="modal"></button>
</div>
</div>
</div>
</div>
Basically, the plugin should display the modal when invoked and trigger a confirm event if the confirmation button is pressed or dismiss otherwise.
$.fn.confirm = function (options) {
var settings = $.extend({}, $.fn.confirm.defaults, options);
return this.each(function () {
var element = this;
$('.modal-title', this).html(settings.title);
$('.message', this).html(settings.message);
$('.confirm', this).html(settings.confirm);
$('.dismiss', this).html(settings.dismiss);
$(this).on('click', '.confirm', function (event) {
$(element).data('confirm', true);
});
$(this).on('hide.bs.modal', function (event) {
if ($(this).data('confirm')) {
$(this).trigger('confirm', event);
$(this).removeData('confirm');
} else {
$(this).trigger('dismiss', event);
}
$(this).off('confirm dismiss');
});
$(this).modal('show');
});
};
An improvement we can make to the code above is to expose the default plugin settings.
$.fn.confirm.defaults = {
title: 'Modal title',
message: 'One fine body…',
confirm: 'OK',
dismiss: 'Cancel'
};
Usage example:
$('#confirm').confirm().on({
confirm: function () {
console.log('confirm');
},
dismiss: function () {
console.log('dismiss');
}
});
See live example here: http://jsfiddle.net/cdog/4q9t9pk5/.
If you don't want to write your own solution you can try existing projects like: https://github.com/nakupanda/bootstrap3-dialog. It looks like what you were looking for. Docs and demos available here: http://nakupanda.github.io/bootstrap3-dialog/.
DEMO
You want to change your function as shown below. Then there's modal markup to add to the page (see demo) and the event listeners shown below:
function checkboxUpdated(checkbox, count, label, id) {
if (checkbox.checked) {
$('#menu_entry_' + id).show();
} else {
if (count > 0) {
//save data to use later
$('#message_p').text( '<the-message-to-show-on-the-modal>' )
.data('elem', '#menu_entry_' + id)
.data('chkbox', checkbox);
//set modal title
$('#title_h4').text( '<Modal Title>' );
//show modal
$('#confirm_modal').modal('show');
}
}
}
$(document).ready(function() {
$('.button-yes').on('click',function() {
var checkbox = $('#message_p').data('chkbox');
checkbox.checked = true;
$('#confirm_modal').modal('hide');
});
$('#confirm_modal').on('hidden.bs.modal', function() {
var elem = $('#message_p').data('elem');
$(elem).hide();
});
});
NOTE: Let us know if you have any questions.

Categories

Resources