collapsible div with checkbox in header, Jquery Mobile - javascript

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(); });

Related

Bootstrap popover not firing after a first popover is initiated

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>

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>

Edit function for to do list

I am working on a homework to do list application based in HTML and Javascript. I am currently trying to implement an edit function but cannot figure out how to call a div tag within a child element. The edit function needs to be able to copy the contents displayed in the tag into the text area.
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>
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>" + "<button type='button' id='delbutton' onclick='edithw(this)'>Edit</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));
}
function edithw(element) {
var conDiv = document.getElementById('contentdiv').innerHTML;
var i;
for (i = 0; i < conDiv.length; i++) {
document.getElementById('addhw').value = conDiv[i].innerHTML;
var container = element.parentElement;
container.parentNode.removeChild(container);
localStorage.removeItem('UserInputCon');
localStorage.setItem('UserInputCon', JSON.stringify(document.getElementById("MainContents").innerHTML));
}
}
</script>
</body>
</html>
This is what you edithw function could be:
function edithw(element)
{
let text = element.parentElement.getElementsByTagName('div')[0].innerHTML
document.getElementById('addhw').value = text;
}
What you are missing in your edithw function is needing to get the innerHtml from a div that was within the generated parent div.
You don't need to worry about looping over anything, since you already have the parent element of the data you want.
element.parentElement gets your the parent div, but you cannot call getElementById from a parentElement, instead use getElementsByTagName, then get the innerHtml of whatever child you want, in this case it was the first element.
You can console.log() it out as you go to see what you get from each call to make it easier to understand:
function edithw(element)
{
console.log('element',element);
console.log('element.parentElement',element.parentElement);
console.log('element.parentElement.getElementsByTagName',element.parentElement.getElementsByTagName('div'));
let text = element.parentElement.getElementsByTagName('div')[0].innerHTML
document.getElementById('addhw').value = text;
}
Here is the full 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>
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>" +
"<button type='button' id='editbutton' onclick='edithw(this)'>Edit</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));
}
function edithw(element)
{
console.log('element',element);
console.log('element.parentElement',element.parentElement);
console.log('element.parentElement.getElementsByTagName',element.parentElement.getElementsByTagName('div'));
let text = element.parentElement.getElementsByTagName('div')[0].innerHTML
document.getElementById('addhw').value = text;
}
</script>
</body>
</html>

How to create a dynamic search page

I am new to javacript. I used an API for implementing custom search feature. But in my search page results show only after I enter the first search key. If I enter another search key, the results for the second key don't show up until I refresh the page.
How can I get the results to auto-update when entering more characters into the search box?
HTML code:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<link href="../css/style.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="../js/jsonData.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
function display() {
document.location = "contentpage.html";
}
$(document).ready(function () {
$("#submit").click(searchAPI);
});
</script>
</head>
<body>
<input type="text" id="search1" >
<button id="submit" >submit</button>
<div id="div1">
<img id="img" >
<p id="desc"> </p>
<p></p>
</div>
</body>
</html>
My JS Code:
function searchAPI(){
var key= $("#search1").val();
var htmlContent="<ul>";
$.getJSON('http://api.duckduckgo.com/?q=' + key + ' &format=json&pretty=1&callback=?', function(data) {
var htmlContent = '<ul>';
for (var i = 0; i < data.RelatedTopics.length; i++) {
var desc = data.RelatedTopics[i].Text;
var url = data.RelatedTopics[i].Icon.URL;
var link = data.RelatedTopics[i].FirstURL;
document.getElementById('link').href = link;
var y = document.getElementById("link");
y.innerHTML = link;
htmlContent += "<li><img src='" + url + "' style='width:100px;height:100px;display:block'/> " +
"<p id='desc'>" + desc + "</p>" + "<a target='_blank' id='link' href=" + link + " >go to website</a></li>";
}
htmlContent += "</ul>";
$('#div1').html(htmlContent);
});
}
Can anyone help me to solve this issue...Thanks in advance.

Jquerymobile Styling the dynamically created List

I have extensively searched on google and stackoverflow for this and didn't find any solution.
I am dynamically creating nested collapsibles and in the innermost layer there is a list view .My collapsibles are getting stlyed but not the list.
Comparing to other questions on the stackoverflow , this is diff as the multilevel hierarchy is generated while parsing the received json from the string.
Please have a look at the code and help me to style the list elements.
<div data-role="page" id="pageone">
<div data-role="header">
<h1>My items</h1>
</div>
<div data-role="main" class="ui-content">
<div data-role = "collapsible-set" id="set">
<div>
Javascript:
<script>
var commodity;
var variety;
var grade;
var content;
var text;
var xmlhttp;
var jsons ='[{"Turmeric":[{"Bulb":["Grade 2","Grade 1"]},{"Finger":["Grade 1"]}]}]';
console.log(jsons);
var data = $.parseJSON(jsons);
var nextId = 0;
$.each(data, function(key, value){
$.each(value, function(key, value){ //Runs for each commodity
commodity = key;
var data1 = value;
$(document).on("pageinit", function() {
nextId++;
content = "<div data-role='collapsible' data-collapsed-icon='arrow-r' data-expanded-icon='arrow-d' id='setk'><h3> " + commodity + "</h3><p>";
$.each(data1, function(key, value){
$.each(value, function(key, value){
variety = key;
content = content + "<div data-role='collapsible' data-collapsed-icon='arrow-r' and data-expanded-icon='arrow-d' id='setk'><h3> " + variety + "</h3><p>"+
'<ul data-role="listview" id="noth">';
for(var i=0, len=value.length; i < len; i++){
grade = value[i];
content=content+'<li>'+grade+'</li>';
}
content = content + '</ul>';
content = content + "</p></div>";
});
});
content = content +"</p></div>";
$("#set").append( content );//.collapsibleset('refresh');
$("#set").enhanceWithin();
});
});
});
</script>
Working example: http://jsfiddle.net/eL9qL/
HTML:
<!DOCTYPE html>
<html>
<head>
<title>jQM Complex Demo</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8'/>
<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; minimum-scale=1.0; user-scalable=no; target-densityDpi=device-dpi"/>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.2/jquery.mobile-1.4.2.min.css" />
<!--<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>-->
<script src="http://code.jquery.com/mobile/1.4.2/jquery.mobile-1.4.2.min.js"></script>
</head>
<body>
<div data-role="page" id="index" data-theme="a" >
<div data-role="header">
<h3>
First Page
</h3>
Next
</div>
<div data-role="content">
<div data-role = "collapsible-set" id="set">
<div>
</div>
<div data-role="footer" data-position="fixed">
</div>
</div>
<div data-role="page" id="second" data-theme="a" >
<div data-role="header">
<h3>
Second Page
</h3>
Back
</div>
<div data-role="content">
</div>
<div data-role="footer" data-position="fixed">
</div>
</div>
</body>
</html>
JavaScript:
var commodity;
var variety;
var grade;
var content;
var text;
var xmlhttp;
var jsons ='[{"Turmeric":[{"Bulb":["Grade 2","Grade 1"]},{"Finger":["Grade 1"]}]}]';
console.log(jsons);
var data = $.parseJSON(jsons);
var nextId = 0;
$.each(data, function(key, value){
$.each(value, function(key, value){ //Runs for each commodity
commodity = key;
var data1 = value;
$(document).on("pageinit", function() {
nextId++;
content = "<div data-role='collapsible' data-collapsed-icon='arrow-r' data-expanded-icon='arrow-d' id='setk'><h3> " + commodity + "</h3><p>";
$.each(data1, function(key, value){
$.each(value, function(key, value){
variety = key;
content = content + "<div data-role='collapsible' data-collapsed-icon='arrow-r' and data-expanded-icon='arrow-d' id='setk'><h3> " + variety + "</h3><p>"+
'<ul data-role="listview" id="noth">';
for(var i=0, len=value.length; i < len; i++){
grade = value[i];
content=content+'<li>'+grade+'</li>';
}
content = content + '</ul>';
content = content + "</p></div>";
});
});
content = content +"</p></div>";
$("#set").append( content );//.collapsibleset('refresh');
$("#set").enhanceWithin();
});
});
});
Solution:
You should use .enhanceWithin(); function if you want to enhance your content correctly. Remember, you are using two different widgets but you are enhancing only one of them. This function will enhance everything added dynamically. Of course this function works only on jQuery Mobile 1.4 +. If you are using older jQuery Mobile version just tell me and I will make a necessary change.

Categories

Resources