Bootstrap popover not firing after a first popover is initiated - javascript

I have taken a small look around here and I can see this is a problem that does occur, but I am still not sure of the solution:
I have a JS Bin illustrating this issue:
https://jsbin.com/toqirix/edit?html,js,output
To replicate the issue:
Put "0" into the first input.
Put "2" into both the next inputs (or any number that is identical).
Click the button and the result should be a popover that says "You have chosen 0, this needs to be non-zero"
Change the "0" in input-a to any non-zero number.
Click the button again - now nothing happens.
What is meant to happen is the next "if" statement should be called. This will tell you that b and c should not be the same.
So, why is this not happening?
How can I make it so that after the button is clicked and the popup is removed that the next popup will come up if the button is clicked again?
The JS (located at JSBin)
Snippet
document.getElementById("submit").addEventListener("click", calc);
function calc() {
let a = parseFloat(document.getElementById("a").value);
let b = parseFloat(document.getElementById("b").value);
let c = parseFloat(document.getElementById("c").value);
let output = document.getElementById("output");
if (a === 0) {
$(this).popover({
placement: "bottom",
content: '<textarea class="popover-textarea"></textarea>',
template: '<div class="popover"><div class="arrow"></div>' +
'<div class="row"><div class="col-3 my-auto">' +
'</div><div class="popover-content col-9">You have chosen 0, this needs to be non-zero' +
"</div></div>",
});
$(this).popover("show");
$(this).click(function() {
$(this).popover("hide");
});
return false;
} else if (b === c) {
$(this).popover({
placement: "bottom",
content: '<textarea class="popover-textarea"></textarea>',
template: '<div class="popover"><div class="arrow"></div>' +
'<div class="row"><div class="col-3 my-auto">' +
'</div><div class="popover-content col-9">You have chosen b and c to be the same, they need to be different' +
"</div></div>",
});
$(this).popover("show");
$(this).click(function() {
$(this).popover("hide");
});
return false;
}
}
<form>
<input type="number" id="a">
<input type="number" id="b">
<input type="number" id="c">
<button type="button" id="submit">Hit me</button>
</form>
<p id="output"></p>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" />
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.16.1/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>

Using #Rob Lao's suggestion:
Put $(this).popover("dispose"); before each of the $(this).popover and remove all the $(this).click(function() { $(this).popover("hide"); });
This gives:
document.getElementById("submit").addEventListener("click", calc);
function calc() {
let a = parseFloat(document.getElementById("a").value);
let b = parseFloat(document.getElementById("b").value);
let c = parseFloat(document.getElementById("c").value);
let output = document.getElementById("output");
if (a === 0) {
$(this).popover("dispose");
$(this).popover({
placement: "bottom",
content: '<textarea class="popover-textarea"></textarea>',
template:
'<div class="popover"><div class="arrow"></div>' +
'<div class="row"><div class="col-3 my-auto">' +
'</div><div class="popover-content col-9">You have chosen 0, this needs to be non-zero' +
"</div></div>",
});
$(this).popover("show");
return false;
} else if (b === c) {
$(this).popover("dispose");
$(this).popover({
placement: "bottom",
content: '<textarea class="popover-textarea"></textarea>',
template:
'<div class="popover"><div class="arrow"></div>' +
'<div class="row"><div class="col-3 my-auto">' +
'</div><div class="popover-content col-9">You have chosen b and c to be the same, they need to be different' +
"</div></div>",
});
$(this).popover("show");
return false;
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#4.0.0/dist/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"><link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" />
<title>JS Bin</title>
</head>
<body>
<form>
<input type="number" id="a">
<input type="number" id="b">
<input type="number" id="c">
<button type="button" id="submit">Hit me</button>
</form>
<p id="output"></p>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.16.1/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</body>
</html>

Related

Javascript dynamic dropdown I can see it in the button also

I am dynamically creating start and end time drop down fields. I have one more remove link fileds also in my app. But when I use 'tab' key I can see the dropdown in remove button also. How should I avoid the droopdown in my remove button. How should I get rid of the time picker drop down in my remove button
my script is
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/timepicker/1.3.5/jquery.timepicker.min.css">
<link href="https://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"
id="bootstrap-css">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/timepicker/1.3.5/jquery.timepicker.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
</head>
<body>
<div>
<input class="btn btn-link" onclick="addtextbox()" type="button" value="Add">
</div>
<div id="ToolsGroup">
</div>
</div>
<script>
var count = 0;
function addtextbox() {
var newTextBoxDiv = document.createElement('div');
newTextBoxDiv.id = 'Tools';
document.getElementById("ToolsGroup").appendChild(newTextBoxDiv);
newTextBoxDiv.innerHTML = '<form class="form-inline"><div class="form-group"><label class="col-md-4 control-label" for="starttime">Start time</label><div class="col-md-4"><input type="time" class="form-control input-md" id="dstarttime' + count + '" placeholder="starttime" required> </div></div>' +
'<div class="form-group"><label class="col-md-4 control-label" for="endtime">End time</label><div class="col-md-4"><input type="time" class="form-control input-md" id="dendtime' + count + '" placeholder="endtime"></div></div>' +
'<input type="button" value="Remove" class="reomvetools" onclick="removeTextArea(this);"></div><div id="dresultDiv' + count + '"></div></form>'
count++;
$('#Tools input').timepicker({
timeFormat: 'HH:mm',
interval: 30,
use24hours: true,
scrollbar: true,
});
};
function removeTextArea(inputElement) {
var el = inputElement;
while (el.tagName != 'DIV') el = el.parentElement;
el.parentElement.removeChild(el);
counter--;
}
</script>
</body>
</html>
Instead of ("#tools input").timepicker ,I have tried giving the ("#form -group").timpicker,that doesnt work.
I tried changing the remove button class to 'btn btn-link' .That didnt work.
how should i do this? If I use the mouse I dont see the time dropdown in 'remove' button .If I use tab I see the dropdown. Can someone help me to get rid of the drop down in remove button?
Just define the input type explicity for time and you are good to go
$('#Tools input[type=time]').timepicker({
timeFormat: 'HH:mm',
interval: 30,
use24hours: true,
scrollbar: true,
});

Javascript and HTML Homework tracker. Delete function not working correctly

I have been working on a homework tracker. I am currently able to add and delete homework items which are inputted by the user. However, there is a problem where if you delete an item by clicking the delete button, you can click anywhere on any other homework item and it will delete it even though you did not press the delete button.
Here is my code:
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<meta charset="utf-8">
<title>Homework</title>
</head>
<body>
<h1>Homework Tracker</h1>
<br>
<div class="AddNewSub">
<i class="material-icons" style="font-size:30px; vertical-align: middle;">receipt</i>
<textarea id="addhw" placeholder="Input Homework"></textarea>
<button type="button" id="addbutton" onclick="add()"> Add </button>
</div>
<br>
<div id="MainContents">
</div>
<script>
var close = document.getElementsByClassName("close");
document.getElementById("MainContents").innerHTML = JSON.parse(localStorage.getItem('UserInputCon'));
function add() {
var contents = document.getElementById('addhw').value;
contents = contents.replace(/\r?\n/g, '<br />');
var newline = document.createElement('div');
newline.setAttribute("class", "close");
newline.setAttribute("id", "UserConDiv")
newline.innerHTML = "<div id='contentdiv'>" + contents + "</div>" + " " + "<button type='button' id='delbutton' onclick='deletehw()'>Delete</button>" + "<br>";
document.getElementById("MainContents").appendChild(newline);
localStorage.setItem('UserInputCon', JSON.stringify(document.getElementById("MainContents").innerHTML));
}
function deletehw() {
var i;
for (i = 0; i < close.length; i++) {
close[i].onclick = function() {
var div = this.parentElement;
this.parentNode.removeChild(this);
localStorage.removeItem('UserInputCon');
localStorage.setItem('UserInputCon', JSON.stringify(document.getElementById("MainContents").innerHTML));
}
}
}
</script>
</body>
</html>
You have to change your delete function. At the moment you are iteration over the "close" items, but close is not the button but the whole homework entry, so on click on any of this, you will delete them.
Try this code:
But i would suggest you to use event binding and not directly print onclick in the element. Also you should use a template for your homework entry
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<meta charset="utf-8">
<title>Homework</title>
</head>
<body>
<h1>Homework Tracker</h1>
<br>
<div class="AddNewSub">
<i class="material-icons" style="font-size:30px; vertical-align: middle;">receipt</i>
<textarea id="addhw" placeholder="Input Homework"></textarea>
<button type="button" id="addbutton" onclick="add()"> Add </button>
</div>
<br>
<div id="MainContents">
</div>
<script>
var close = document.getElementsByClassName("close");
document.getElementById("MainContents").innerHTML = JSON.parse(localStorage.getItem('UserInputCon'));
function add() {
var contents = document.getElementById('addhw').value;
contents = contents.replace(/\r?\n/g, '<br />');
var newline = document.createElement('div');
newline.setAttribute("class", "close");
newline.setAttribute("id", "UserConDiv")
newline.innerHTML = "<div id='contentdiv'>" + contents + "</div>" + " " + "<button type='button' id='delbutton' onclick='deletehw(this)'>Delete</button>" + "<br>";
document.getElementById("MainContents").appendChild(newline);
localStorage.setItem('UserInputCon', JSON.stringify(document.getElementById("MainContents").innerHTML));
}
function deletehw(element) {
let container = element.parentElement;
container.parentNode.removeChild(container);
localStorage.removeItem('UserInputCon');
localStorage.setItem('UserInputCon', JSON.stringify(document.getElementById("MainContents").innerHTML));
}
</script>
</body>
</html>

How to Call a JavaScript Function in a Mustache Template

I am trying to call a JavaScript function in my mustache template, but I keep getting errors when using a script tag to call it.
I have tried using escape tags on the script but it still does not work. I have searched around a bit and have not been able to find anything that helps with my problem.
<head>
<meta charset="UTF-8">
<title>Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="main.css" rel="stylesheet" type="text/css"> <!--So far there may be multiple CSS pages to manage the overall layout -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js" type="text/javascript"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mustache.js/3.0.1/mustache.min.js" type="text/javascript"></script>
<script>
function generateFields(amt){
var htmlElements = "";
for(var i = 0; i < amt; i++)
{
htmlElements += '<div>{{i}}: <input type="text" class="inputAnswer"></div>'
}
}
</script>
</head>
<body>
<script id="studentAnswerTemplate">
var data = {
assignmentName: "Assignment 2",
questionAmt: 5,
generateFields: function(amt){
var htmlElements = "";
for(var i = 0; i < amt; i++)
{
htmlElements += '<div>{{i}}: <input type="text" class="inputAnswer"></div>'
}
}
};
var template = [
'<div class="container">',
'<div class="row">',
'<div class="jumbotron text-center">',
'<div class="col-4"></div>',
'<div class="col-4 mx-auto text-center">',
'<img class="img-fluid" src="UTPB_LOGO.png" alt="n/a">',
'</div>',
'<div class="col-4"></div>',
'<div class="row"></div>',
'<h3>{{assignmentName}}</h3>',
'</div>',
'<nav class="navbar navbar-expand-sm">',
'</nav>',
'</div>',
'<br><br>',
'<div class="row">',
'<div class="col-md-3">',
'<br>',
'</div>',
'<div class="col-md-5" id="middle">',
'<h2>Answers</h2>',
'<form action="/action_page.php">',
'<p>Please answer each question to the best of your ability.</p>',
'<div>',
'<form action="/action_page.php">',
/*need to autogenerate blanks using data from DB here*/
'<script>{{generateFields(5)}}</script>',
/*here is where I run into issues ^^*/
'</form>',
'</div>',
'<button type="submit" class="btn btn-primary">Submit</button>',
'</form>',
'</div>',
'<div class="col-md-4">',
'</div>',
'</div>',
'<br><br><br><br>',
'<div class="row">',
'<footer class="page-footer font-small black">',
'<div class="footer-copyright text-center py-3">© 2019 Copyright --, All rights reserved',
'<br>',
'</div>',
'</footer>',
'</div>',
'</div>'
].join("\n");
var html = Mustache.render(template, data);
$("body").append(html);
</script>
</body>
I'm hoping to generate a number of text fields using this function, but I am unable to execute the function at this point in time. Thank you!

Adding new date-picker input field when button click

I have a button that add a new bootstrap date-picker input field when the add button is clicked.
The problem I am facing is when the new bootstrap date-picker input field is added, it doesn't allow me to select date and the size of those newly added bootstrap date-picker input field isn't the same as the first input field
$(document).ready(function() {
var counter = 2;
$("#addBtn").click(function() {
var newRowDiv = $(document.createElement('div')).attr("class", 'row');
var newStartDateLabel = $(document.createElement('div')).attr("class", 'col-md-2');
var newStartDateInput = $(document.createElement('div')).attr("class", 'col-md-2', 'input-group', 'input-daterange');
newStartDateLabel.appendTo(newRowDiv);
newStartDateLabel.after().html("Start Date " + counter);
newStartDateInput.insertAfter(newStartDateLabel).html('<input "id="startDate"' + counter + 'name="startDate' + counter + 'type="text class="form-control" >');
newRowDiv.appendTo(".container");
counter++;
});
});
<body>
<form id="form" name="form" action="DateServlet" method="POST">
<div class="container">
<div class="row">
<div class="col-md-2">
Start Date 1
</div>
<div class="col-md-2 input-group input-daterange">
<input id="startDate1" name="startDate1" type="text" class="form-control">
</div>
</div>
</div>
<button id="addBtn" type="button" class="btn btn-default">Add</button>
</form>
<script type="text/javascript">
$('.input-daterange input').each(function() {
$(this).datepicker("clearDates");
});
</script>
</body>
Please look at below code. Specifically made changes at:
var newStartDateInput = $(document.createElement('div'))
.attr("class", 'col-md-2 input-group input-daterange');
AND
var dateText = $('<input id="startDate' + counter + '" name="startDate' + counter + '" type="text" class="form-control" >');
newStartDateInput.insertAfter(newStartDateLabel).html(dateText);
dateText.datepicker(); //initializing the datepicker on newly added text field
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.6.4/css/bootstrap-datepicker.min.css">
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.6.4/js/bootstrap-datepicker.min.js"></script>
<script type="text/javascript" src="js/addInput.js" charset="UTF-8"></script>
<script>
$(document)
.ready(
function() {
var counter = 2;
$("#addBtn")
.click(
function() {
var newRowDiv = $(
document
.createElement('div'))
.attr("class", 'row');
var newStartDateLabel = $(
document
.createElement('div'))
.attr("class", 'col-md-2');
var newStartDateInput = $(
document
.createElement('div'))
.attr("class", 'col-md-2 input-group input-daterange');
newStartDateLabel
.appendTo(newRowDiv);
newStartDateLabel.after().html(
"Start Date " + counter);
var dateText = $('<input id="startDate' + counter + '" name="startDate' + counter + '" type="text" class="form-control" >');
newStartDateInput
.insertAfter(
newStartDateLabel)
.html(dateText);
dateText.datepicker(); //initializing the datepicker on newly added text field
newRowDiv.appendTo(".container");
counter++;
});
});
</script>
</head>
<body>
<form id="form" name="form" action="DateServlet" method="POST">
<div class="container">
<div class="row">
<div class="col-md-2">
Start Date 1
</div>
<div class="col-md-2 input-group input-daterange">
<input id="startDate1" name="startDate1" type="text" class="form-control">
</div>
</div>
</div>
<button id="addBtn" type="button" class="btn btn-default">Add</button>
</form>
<script type="text/javascript">
$('.input-daterange input').each(function() {
$(this).datepicker("clearDates");
});
</script>
</body>
</html>

collapsible div with checkbox in header, Jquery Mobile

This is my html code:
<!DOCTYPE HTML>
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1"/>
<link rel="stylesheet" href="css/jquery.mobile-1.2.0.min.css" />
<link rel="stylesheet" href="css/styles.css" />
</head>
<body>
<div id="questionsPage" data-role="page" data-add-back-btn="true">
<div data-role="header">
<h1>Questions</h1>
</div>
<div data-role="content">
<div id="questions_list" data-role="collapsible-set" data-theme="a" data-content-theme="d" data-inset="false"></div>
</div>
</div>
<script src="js/jquery.js"></script>
<script src="js/jquery.mobile-1.2.0.min.js"></script>
<script src="js/questions_list.js"></script>
</body>
</html>
and this is question_list.js:
$('#questionsPage').live('pageshow', function(event) {
var id = getUrlVars()["id"];
$.getJSON(serviceURL + 'api/questions.json?id=' + id, function(data) {
questions = data;
$.each(questions, function(index, question) {
$('#questions_list').append('<div data-role="collapsible" id="section_' + question.id + '">' +
'<h2>' + question.question + '<input type="checkbox" id="checkbox_' + question.id + '" /></h2>' +
'<p>test</p></div>');
$('#section_' + question.id).collapsible();
});
});
});
function getUrlVars() {
var vars = [], hash;
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
for(var i = 0; i < hashes.length; i++)
{
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1];
}
return vars;
}
Well, i can see the divs with the checkbox.
But when i click on the checkbox, the div is collapsed and the checkbox is not being checked.
What i am trying to is, when i click on the checkbox, it would be checked.
And when i click anywhere else, only the div would collapse without the checkbox being checked.
Thank you very much!
Right after:
$('#questions_list').append('<div data-role="collapsible" id="section_' + question.id + '">' +
'<h2>' + question.question + '<input type="checkbox" id="checkbox_' + question.id + '" /></h2>' +
'<p>test</p></div>');
Insert:
// This will simply stop the check box from allowing its parent to be clicked (collapsed) while the checkbox itself is clicked
// I havn't tested, but should work
$('#checkbox_' + question.id).on("click", function(e) { e.stopPropagation(); });

Categories

Resources