Situation:
I created a HTML Grid, the div's can be replaced by using jquery sort (drag and drop). Users can change the order of this grid. When the users press the save button function getMapping(); is called.
The function getMapping(); gets the order of the div's by id.
Inside the "map" loop i have created an if/else function to see if the id is an header div or not. When i check the function with console.log i have no errors and receive the correct array data ( console.log(getMapping());
The issue:
When i try to send the created array from getMapping(); trough ajax i receive a error (1). The error only occurs when i try to send variable with Ajax. So the function creates the array correctly but when i trying to send the array to Ajax i receive error (1)
(1) Error on send using ajax: Uncaught TypeError: 'click' called on an object that does not implement interface HTMLElement.
$(".dropzone").sortable({
connectWith: ".dropzone",
update: function(event, ui) {
showResult();
},
placeholder: "dashed"
});
var headerCount = 1;
function addHeader() {
$(".dropzone").prepend(
$("#prefab-header")
.clone()
.attr("id", "header-" + headerCount)
.html("Header " + headerCount++)
);
}
function showResult() {
var arr = $(".dropzone > div").map(function() {
return this.id;
});
$("#result").html("");
$("#result").append(arr.get().join(", "));
}
function getMapping() {
var sort = 1;
var data = $(".dropzone > div").map(function() {
var array = [];
var add = {};
if (this.id.includes("head-")) {
add["data"] = 0;
add["name"] = this.innerText;
add["sort"] = sort++;
array.push(add);
} else {
add["data"] = this.id;
add["sort"] = sort++;
array.push(add);
}
return array;
});
return data;
}
function sendAjax() {
var data = getMapping();
console.log(data);
/*
$.ajax({
url: "cal-admin.php",
type: "post",
data: { data: data },
success: function (response) {}
});
*/
}
.grid-view {
margin-top: 50px;
width: 700px;
background-color: #f5f2f2;
padding: 50px;
min-height: 350px;
}
.grid-trash {
margin-top: 20px;
width: 700px;
background-color: #f5f2f2;
color: #999;
padding: 10px;
height: 50px;
padding: 10px;
border: 2px dashed #999;
text-align: center;
}
.grid-trash-hover {
background-color: #f34541;
color: #fff;
border: 2px dashed #fff;
}
.grid-result {
margin-top: 20px;
width: 700px;
background-color: #f5f2f2;
padding: 10px;
height: 100px;
}
.grid-users {
background: #f5f5f5;
padding-bottom: 20px;
padding-top: 20px;
padding-right: 0px;
padding-left: 0px;
cursor: move;
border: #000 1px solid;
text-align: center;
font-weight: bold;
}
.grid-header {
background: #34bdeb;
padding-bottom: 5px;
padding-top: 5px;
padding-right: 0px;
padding-left: 0px;
cursor: move;
border: #000 1px solid;
text-align: center;
font-weight: bold;
}
.dashed {
border: 2px dashed #999;
background: #ede8e8;
height: 75px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<div class="container ">
<div class="row justify-content-center align-items-center">
<div class="grid-view">
<div style="padding-bottom: 10px">
<button type="button" class="btn btn-primary" onclick="addHeader();">Add header</button>
<button type="button" class="btn btn-info" onclick="showResult();">Display DIV id order</button>
</div>
<div id="dropzone" class="dropzone">
<div id="team-1" class="grid-users">TEAM 1</div>
<div id="team-2" class="grid-users">TEAM 2</div>
</div>
<div style="margin-top: 20px">
<button type="button" class="btn btn-info" onclick="sendAjax();">Send Ajax</button>
</div>
</div>
</div>
</div>
<div class="container">
<div class="row justify-content-center align-items-center">
<div class="grid-result">
<span><b>Console log:</b></span>
<div id="result" style="height: 50px; padding: 10px; border: 2px dashed #999"></div>
</div>
</div>
</div>
<div style="display:none">
<div id="prefab-header" class="drag grid-header"></div>
</div>
I have moved my var array out of the map() function which results in Ajax accepting the variable and sending it to PHP.
function getMapping() {
var sort = 1;
var arr = $("#dropzone > div").map(function () {
return this.id;
});
var array = [];
for (const a of arr) {
var add = { };
console.log(a)
if (a.includes('head-')) {
add['data'] = 0;
add['sort'] = sort++;
array.push(add);
} else {
add['data'] = a.id;
add['sort'] = sort++;
array.push(add);
}
}
return array;
}
Related
there is a filter on the js, which consists of three identical buttons (named "green", "yellow", "red"), which are responsible for setting/removing the blur effect for the set of pictures located below.
When pressing the "green" button, a blur effect should be set for all pictures that have a value "green" of data-card property.
At the second click on the same button, the blur effect should be canceled for this category of pictures.
I solved this problem with a reception with a boolean flag:
let firstClick = true;
if (firstClick){
//..do at first click
firstClick = !firstClick;
}
else{
//..do at second click
firstClick = !firstClick;
}
However, the problem occurs when I click on the "green" button (this is the first click on the "green" button), and after that on another button, for example "red" (this is the first click on the "red" button). But the compiler perceives a click on the "red" button as a second click, although it is a different button.
The question is how to distinguish the behavior in different buttons?
In general, I solved the problem through a complete search and many if statements. Maybe there is an alternative way?
Project demo in codepen
//main.js
function app() {
const buttons = document.querySelectorAll('.service__btn');
const cards = document.querySelectorAll('.service__item');
let firstClick = true;
function setBlour(listOfCards) {
listOfCards.forEach(item => {
if (item.classList.contains(currentCategory)) {
item.classList.add('blur');
}
});
}
function resetBlour(listOfCards) {
listOfCards.forEach(item => {
if (item.classList.contains(currentCategory)) {
item.classList.remove('blur');
}
});
}
function highlightButton(butt) {
if (!butt.classList.contains('service__btn__clicked')) {
butt.classList.add('service__btn__clicked');
}
firstClick = !firstClick;
}
function unhighlight(butt) {
if (butt.classList.contains('service__btn__clicked')) {
butt.classList.remove('service__btn__clicked');
}
firstClick = !firstClick;
}
buttons.forEach(button => {
button.addEventListener('click', (event) => {
currentCategory = event.target.dataset.filter; //current category we get from clicked button
let matchedCards = document.querySelectorAll(`[data-card="${button.dataset.filter}"]`);
//is it first click?
if (firstClick) {
if (!matchedCards[0].classList.contains('blur')) { // each click we have set of matchedCards, it's easy to check one of them (the first for example) if it have blur
setBlour(matchedCards);
highlightButton(button);
} else { //it is a first clcik, but card have blur - so remove blur
resetBlour(matchedCards);
unhighlight(button);
}
}
//second click
else {
if (!matchedCards[0].classList.contains('blur')) { //if there is no blur - add blur
setBlour(matchedCards);
highlightButton(button);
} else { //second click and blur is present - so we need to remove it
resetBlour(matchedCards);
unhighlight(button);
}
}
});
});
}
app()
html {
box-sizing: border-box;
}
*,
*::before,
*::after {
box-sizing: inherit;
}
body {
margin: 0;
padding: 0;
}
a {
text-decoration: none;
}
li {
list-style-type: none;
}
.container {
width: 1220px;
margin: 0 auto;
}
.service {
background: #EDF2EC;
padding-top: 40px;
padding-bottom: 70px;
}
.service__top {
display: flex;
align-items: center;
margin-bottom: 20px;
}
.service__top-title {
font-family: 'Inika', serif;
font-weight: 400;
font-size: 40px;
line-height: 52px;
color: #499A18;
max-width: 306px;
}
.service__filter-btn {
margin-left: 142px;
}
.service__btn {
border: 1px solid #E06733;
border-radius: 5px;
padding: 12px 40px;
font-family: 'Inika', serif;
font-weight: 400;
font-size: 20px;
line-height: 26px;
color: #E06733;
}
.service__btn__clicked {
background: #E06733;
border: 1px solid #E06733;
border-radius: 5px;
color: #FFFFFF;
}
.service__btn+.service__btn {
margin-left: 32px;
}
.service__content {
column-count: 3;
gap: 0 116px;
}
.service__item {
margin-bottom: 55px;
text-align: center;
width: 330px;
height: 350px;
border-radius: 20px;
}
.red {
background-color: red;
}
.green {
background-color: green;
}
.yellow {
background-color: yellow;
}
.service__item-title {
font-family: 'Inter', sans-serif;
font-weight: 700;
font-size: 20px;
line-height: 20px;
color: #E06733;
margin-top: 10px;
margin-bottom: 10px;
}
.service__item-text {
font-family: 'Inter', sans-serif;
font-weight: 400;
font-size: 16px;
line-height: 20px;
color: #717171;
margin-bottom: 36px;
}
.service__item-description {
border-radius: 0px 0px 20px 20px;
border: 1px solid #e3e1d5;
display: none;
}
.blur {
filter: blur(5px);
}
.animation {
transform: scale(0);
opacity: 0;
}
<body>
<section class="service">
<div class="container">
<div class="service__top">
<h3 class="service__top-title">
Caption and Description
</h3>
<div class="service__filter-btn">
<button class="service__btn service__btn-type_green" data-filter="green"> Green</button>
<button class="service__btn service__btn-type_yellow" data-filter="yellow">Yellow</button>
<button class="service__btn service__btn-type_red" data-filter="red">Red</button>
</div>
</div>
<div class="service__content">
<div class="service__item green" data-card="green">
<div class="service__item-description">
<h4 class="service__item-title">Green color</h4>
<p class="service__item-text">Description</p>
</div>
</div>
<div class="service__item red" data-card="red">
<div class="service__item-description">
<h4 class="service__item-title">Red color</h4>
<p class="service__item-text">Description</p>
</div>
</div>
<div class="service__item yellow" data-card="yellow">
<div class="service__item-description">
<h4 class="service__item-title">Yellow color</h4>
<p class="service__item-text">Description</p>
</div>
</div>
<div class="service__item red" data-card="red">
<div class="service__item-description">
<h4 class="service__item-title">Red color</h4>
<p class="service__item-text">Description</p>
</div>
</div>
<div class="service__item green" data-card="green">
<div class="service__item-description">
<h4 class="service__item-title">Green color</h4>
<p class="service__item-text">Description</p>
</div>
</div>
<div class="service__item red" data-card="red">
<div class="service__item-description">
<h4 class="service__item-title">Red color</h4>
<p class="service__item-text">Description</p>
</div>
</div>
</div>
</div>
</section>
</body>
I have built an accordion which I can add dynamically from an input and everything works fine except when I click on accordion heading text it doesn't work and also when I click on the chevron icon on the right side I get an error!! I am not sure why this happening. if I click on an empty space area it just works fine without any error. you can check the demo & code here on codepen -> https://codepen.io/tauhidul-islam/pen/eYZBzLY
Also here is some screenshot so you can understand. please let me understand what's happening and why. Thank you.
const addForm = document.querySelector(".add");
const list = document.querySelector(".section-list");
// Template Generator Function
const generateTemplate = (section) => {
let html = `
<div class="accordion">
<span>${section}</span>
<i class="fa fa-chevron-down"></i>
</div>
<div class="panel">
<span>Hey there you did it! :-)</span>
</div>
`;
list.innerHTML += html;
// accordion Selector
const accordion = document.querySelectorAll(".accordion");
// Show/Hide accordion Content on Click
for (i = 0; i < accordion.length; i++) {
accordion[i].addEventListener("click", (e) => {
let panel = e.target.nextElementSibling;
if (panel.classList.contains("panel")) {
panel.classList.toggle("active");
}
});
}
};
// Add Section
addForm.addEventListener("submit", (e) => {
e.preventDefault();
const section = addForm.add.value.trim();
if (section.length) {
generateTemplate(section);
addForm.reset();
}
});
.container {
width: 960px;
margin: auto;
}
.add-input {
padding: 15px;
border: 1px solid #dadada;
}
.add-btn {
background: white;
padding: 15px 25px;
margin-bottom: 10px;
border: 1px solid #dadada;
cursor: pointer;
}
/* Accordian Panel */
.accordion {
display: flex;
justify-content: space-between;
background: #03a9f4;
color: white;
padding: 15px;
box-shadow: 0px 0px 4px 0px #dadada;
cursor: pointer;
}
.panel {
display: none;
background-color: white;
padding: 15px;
}
.active {
display: block;
}
<div class="container">
<!-- Add Section -->
<form class="add">
<input type="text" name="add" class="add-input">
<button type="submit" class="add-btn">Add Section</button>
</form>
<!-- Section List -->
<div class="section-list"></div>
</div>
Because you are using e.target in the click event of the generated div, that will reference the template span when you click on the text and the div when you click on the blue bar, so .nextElementSibling won't always point to the same element. Instead, you want to always be calling .nextElementSibling on the div. This can be accomplished by using this.nextElementSibling, however because you are also using an arrow function, this binding won't correctly reference the element that received the event (the div), so if you change to using an anonymous function and this, it works.
const addForm = document.querySelector(".add");
const list = document.querySelector(".section-list");
// Template Generator Function
const generateTemplate = (section) => {
let html = `
<div class="accordion">
<span>${section}</span>
<i class="fa fa-chevron-down">^</i>
</div>
<div class="panel">
<span>Hey there you did it! :-)</span>
</div>
`;
list.innerHTML += html;
// accordion Selector
const accordion = document.querySelectorAll(".accordion");
// Show/Hide accordion Content on Click
for (i = 0; i < accordion.length; i++) {
// Use an anonymous function for the event listener so that
// "this" will bind to the element that recieved the event,
// which is the `div` in this case.
accordion[i].addEventListener("click", function(e) {
// We don't want to reference the element that triggered the event
// because that might be the span or the div and you won't always get
// the correct reference with .nextElementSibling. We always want to
// start from the div, which recieves the event.
let panel = this.nextElementSibling;
if (panel.classList.contains("panel")) {
panel.classList.toggle("active");
}
});
}
};
// Add Section
addForm.addEventListener("submit", (e) => {
e.preventDefault();
const section = addForm.add.value.trim();
if (section.length) {
generateTemplate(section);
addForm.reset();
}
});
.container {
width: 960px;
margin: auto;
}
.add-input {
padding: 15px;
border: 1px solid #dadada;
}
.add-btn {
background: white;
padding: 15px 25px;
margin-bottom: 10px;
border: 1px solid #dadada;
cursor: pointer;
}
/* Accordian Panel */
.accordion {
display: flex;
justify-content: space-between;
background: #03a9f4;
color: white;
padding: 15px;
box-shadow: 0px 0px 4px 0px #dadada;
cursor: pointer;
}
.panel {
display: none;
background-color: white;
padding: 15px;
}
.active {
display: block;
}
<div class="container">
<!-- Add Section -->
<form class="add">
<input type="text" name="add" class="add-input">
<button type="submit" class="add-btn">Add Section</button>
</form>
<!-- Section List -->
<div class="section-list"></div>
</div>
Without the loop for assigning the click handlers:
const addForm = document.querySelector(".add");
const list = document.querySelector(".section-list");
const expand = (element) => {
let panel = element.nextElementSibling;
if (panel.classList.contains("panel")) {
panel.classList.toggle("active");
}
};
// Template Generator Function
const getAccordionItem = (section) => {
let html = `
<div class="accordion" onclick="expand(this)">
<span>${section}</span>
<i class="fa fa-chevron-down"></i>
</div>
<div class="panel">
<span>Hey there you did it! :-)</span>
</div>
`;
return html;
};
// Add Section
addForm.addEventListener("submit", (e) => {
e.preventDefault();
const section = addForm.add.value.trim();
if (section.length) {
list.innerHTML += getAccordionItem(section);
addForm.reset();
}
});
body {
margin: 50px 0;
background-color: #f2f2f2;
font-family: Arial, Helvetica, sans-serif;
}
.container {
width: 960px;
margin: auto;
}
.add-input {
padding: 15px;
border: 1px solid #dadada;
}
.add-btn {
background: white;
padding: 15px 25px;
margin-bottom: 10px;
border: 1px solid #dadada;
cursor: pointer;
}
/* Accordian Panel */
.accordion {
display: flex;
justify-content: space-between;
background: #03a9f4;
color: white;
padding: 15px;
box-shadow: 0px 0px 4px 0px #dadada;
cursor: pointer;
}
.panel {
display: none;
background-color: white;
padding: 15px;
}
.active {
display: block;
}
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dynamic Accordian</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.1/css/all.min.css">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="container">
<!-- Add Section -->
<form class="add">
<input type="text" name="add" class="add-input">
<button type="submit" class="add-btn">Add Section</button>
</form>
<!-- Section List -->
<div class="section-list"></div>
</div>
<script src="app.js"></script>
</body>
</html>
So I taught myself coding a few years ago, and got it just enough to put together a few tools for work. I recently had to migrate my site out of CodePen and onto an actual web server. Now I'm having an issue where part of my javascript is executing properly (a portion that empties all other input fields when a user enters an input field using JQuery), but the button that calculates an answer will not work. I believe the .click is not picking it up. Either way I'm not getting error messages, the button just does nothing when I press it.
When I put the code in a snippet to share with you guys, it works (just like it did in CodePen), but the exact same code on my web host does not work. I'm really at a loss here and any help would be greatly appreciated. I feel like I'm missing some small line of code that's supposed to be included in all web files.
$(document).ready(function() {
//Clear out input fields when not selected
$("#sg").focusin(function() {
$("#density").val("");
});
$("#density").focusin(function() {
$("#sg").val("");
});
$("#pounds").focusin(function() {
$("#grams").val("");
$("#percentage").val("");
});
$("#grams").focusin(function() {
$("#percentage").val("");
$("#pounds").val("");
});
$("#percentage").focusin(function() {
$("#pounds").val("");
$("#grams").val("");
});
$(".input_field").focusin(function() {
$("#density").removeClass('highlight');
$("#sg").removeClass('highlight');
$("#pounds").removeClass('highlight');
$("#grams").removeClass('highlight');
$("#percentage").removeClass('highlight');
});
//Calculate on press of enter
$("#button").keypress(function(e) {
if (e.which == 13) {
alert("this is working");
}
});
$("#button").click(function() {
calculateButton();
});
//Calculate values on button hit
function calculateButton() {
function numberWithCommas(x) {
x = x.toString();
var pattern = /(-?\d+)(\d{3})/;
while (pattern.test(x))
x = x.replace(pattern, "$1,$2");
return x;
}
function removeCommas(x) {
x = x.replace(",", "");
return x;
}
var results = 0;
//Pulling information from input cells
var densityStr = document.getElementById("density").value;
var sgStr = document.getElementById("sg").value;
var poundsStr = document.getElementById("pounds").value;
var gramsStr = document.getElementById("grams").value;
var percentageStr = document.getElementById("percentage").value;
//remove commas from string and then convert string to number
var densityNum = Number(removeCommas(densityStr));
var sgNum = Number(removeCommas(sgStr));
var poundsNum = Number(removeCommas(poundsStr));
var gramsNum = Number(removeCommas(gramsStr));
var percentageNum = Number(removeCommas(percentageStr));
if (densityStr.length !== 0) {
var sgConversion = densityNum / 8.3454;
$("#sg").val(sgConversion.toFixed(3));
$("#density").addClass('highlight');
} else if (sgStr.length !== 0) {
var densityConversion = sgNum * 8.3454;
$("#density").val(densityConversion.toFixed(3));
$("#sg").addClass('highlight');
}
if (poundsStr.length !== 0) {
$("#pounds").addClass("highlight");
densityNum = document.getElementById("density").value;
var gramsConversion = poundsNum * 119.83;
var percentageConversion = poundsNum / densityNum * 100;
$("#grams").val(gramsConversion.toFixed(0));
$("#percentage").val(percentageConversion.toFixed(2));
} else if (gramsStr.length !== 0) {
$("#grams").addClass("highlight");
densityNum = document.getElementById("density").value;
var poundsConversion = gramsNum / 119.83;
var percentageConversion = poundsConversion / densityNum * 100;
$("#pounds").val(poundsConversion.toFixed(2));
$("#percentage").val(percentageConversion.toFixed(2));
} else if (percentageStr.length !== 0) {
$("#percentage").addClass("highlight");
densityNum = document.getElementById("density").value;
var percentageDec = percentageNum / 100;
var poundsConversion = densityNum * percentageDec;
var gramsConversion = poundsConversion * 119.83;
$("#pounds").val(poundsConversion.toFixed(2));
$("#grams").val(gramsConversion.toFixed(2));
}
}
});
body {
margin: 0;
font-family: 'Lato', sans-serif;
background: #d2d2d2;
}
p {
text-align: center;
}
conatiner {
max-width: 1024px;
margin: 0 auto;
}
#navbarContainer {
background: #F44336;
overflow: hidden;
width: 100%;
margin: 0;
}
.navbar {
float: left;
display: block;
font-family: 'Lato', sans-serif;
height: 40px;
width: 200px;
line-height: 40px;
text-align: center;
background: #F44336;
text-decoration: none;
color: #212121;
}
.navbar:hover {
background: #E57373;
color: white;
}
.active {
background: #C62828;
color: white;
}
#formContainer {
width: 450px;
background: #FDFFFC;
margin: 50px auto;
padding: 0px;
border-radius: 8px;
overflow: hidden;
}
#formContainer header {
width: 100%;
height: 130px;
background-color: #3cba54;
overflow: auto;
color: white;
}
header h1 {
margin: 35px 0 0 0;
text-align: center;
line-height: 30px;
}
header h3 {
line-height: 40px;
text-align: center;
margin: 0;
}
#heading {
background-color: #3cba54;
height: 40px;
color: white;
margin-bottom: 25px;
margin-left: -30px;
}
#heading h3 {
line-height: 40px;
}
form {
padding: 20px 0 0 20px;
text-align: center;
}
label {
display: inline-block;
width: 220px;
text-align: right;
}
#myForm .input_field {
margin-left: 20px;
margin-bottom: 10px;
font-size: 20px;
padding-left: 10px;
width: 125px;
height: 35px;
font-size: 17px;
border-radius: 3px;
background-color: #E0E0E0;
border: none;
}
#button {
display: block;
border-radius: 6px;
width: 200px;
height: 50px;
padding: 8px 15px 8px 15px;
margin: 0 auto;
margin-bottom: 50px;
font-size: 16px;
box-shadow: 0 6px #540000;
background-color: #FF3636;
border: none;
outline: none;
}
#button:active {
background-color: #B81B1B;
box-shadow: 0 1px #27496d;
transform: translateY(5px);
}
.highlight {
background: #FFEB3B !important;
}
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<link rel="stylesheet" href="style.css">
<script type="text/javascript" src="script.js"></script>
</head>
<body>
<div id="container">
<div id="navbarContainer">
<a class="navbar" id="62" href="https://s.codepen.io/awheat/debug/MpMrEo/yYAyLDjQWgKr">326 IAC 6-2 Tool</a>
<a class="navbar" id="63" href="https://s.codepen.io/awheat/debug/gWmazm/NQkzYnjeQZyA">326 IAC 6-3 Tool</a>
<a class="navbar active" id="voc" href="https://s.codepen.io/awheat/debug/qVpPNm/VGAWNnJYBjZr">VOC Conversion Tool</a>
</div>
<div id="formContainer">
<header>
<h1>VOC Conversion Tool</h1>
<h3>(for conversion of VOC data to other units)</h3>
</header>
<form id="myForm">
<label>Density of Coating (lbs/gal): </label><input type="text" id="density" class="input_field">
<label>Specific Graviy: </label><input type="text" id="sg" class="input_field">
<div id="heading">
<h3>VOC Content</h3>
</div>
<label>Pounds per Gallon (lbs/gal): </label><input type="text" id="pounds" class="input_field">
<label>Grams per Liter (g/L): </label><input type="text" id="grams" class="input_field">
<label>Percentage (%): </label><input type="text" id="percentage" class="input_field"><br><br>
<input type="button" id="button" value="Calculate" autofocus>
</form>
</div>
</div>
</body>
</html>
Sometimes putting script tags before the elements on the page can cause issues. You can try to put the scripts at the bottom of the body like this:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="container">
<div id="navbarContainer">
<a class="navbar" id="62" href="https://s.codepen.io/awheat/debug/MpMrEo/yYAyLDjQWgKr">326 IAC 6-2 Tool</a>
<a class="navbar" id="63" href="https://s.codepen.io/awheat/debug/gWmazm/NQkzYnjeQZyA">326 IAC 6-3 Tool</a>
<a class="navbar active" id="voc" href="https://s.codepen.io/awheat/debug/qVpPNm/VGAWNnJYBjZr">VOC Conversion Tool</a>
</div>
<div id="formContainer">
<header>
<h1>VOC Conversion Tool</h1>
<h3>(for conversion of VOC data to other units)</h3>
</header>
<form id="myForm">
<label>Density of Coating (lbs/gal): </label><input type="text" id="density" class="input_field">
<label>Specific Graviy: </label><input type="text" id="sg" class="input_field">
<div id="heading">
<h3>VOC Content</h3>
</div>
<label>Pounds per Gallon (lbs/gal): </label><input type="text" id="pounds" class="input_field">
<label>Grams per Liter (g/L): </label><input type="text" id="grams" class="input_field">
<label>Percentage (%): </label><input type="text" id="percentage" class="input_field"><br><br>
<input type="button" id="button" value="Calculate" autofocus>
</form>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript" src="script.js"></script>
</body>
</html>
I have a function that copies the data attribute and gives it an active class. I need to be able to clear the active class from .copy-btn when either .close1 or .close2 is clicked.
$(document).ready(function() {
$(".copy-btn").click(function(event) {
event.preventDefault();
});
});
var clip = new Clipboard(".copy-btn");
$(".copy-btn").click(function(e) {
$.each($(".copy-btn"), function(index, value) {
if (
$(value).attr("data-text") ==
$(e.target).attr("data-text")
) {
$(value).addClass("active");
}
});
});
.btn {
width: 50px;
height: 20px;
border: 2px solid;
cursor: pointer;
}
.copy-btn {
outline: none;
cursor: pointer;
border: none;
background-color: white;
font-size: 21px;
}
.active {
border-bottom: 3px dotted green;
padding-bottom: 4px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/1.5.12/clipboard.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p class="copy-btn" data-text="CODE1">CODE1</p>
<p class="copy-btn" data-text="CODE2">CODE2</p>
<p class="copy-btn" data-text="CODE3">CODE3</p>
<div class="btn close1">Close 1</div>
<div class="btn close2">Close 2</div>
Just using removeClass()
$('.close1, .close2').on('click', function() {
$('.copy-btn').removeClass('active');
})
I using jQuery-UI sortable which works fine. The problem that I am having is that the message "New order saved!" or "Save failed" is not displaying in the < p > area. The function is either not executing or something.
Below is the code for the .aspx page
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title></title>
<link href="jQuery/jquery-ui.css" rel="stylesheet" type="text/css" />
<script src="jQuery/jquery.min.js" type="text/javascript"></script>
<script src="jQuery/jquery-ui.min.js" type="text/javascript"></script>
<script src="jQuery/json2.js" type="text/javascript"></script>
<script src="jQuery/jquery-ui-i18n.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(function () {
$("#sortable").sortable({ placeholder: "vacant" });
$("#sortable").disableSelection();
$("#sortable input[type=text]").width($("#sortable img").width() - 10);
$("#sortable label").mouseover(function () {
$(this).parent().children("input[type=text]").show().val($(this).html());
$(this).hide();
});
$("#sortable input[type=text]").mouseout(function () {
$(this).parent().children("label").show().html($(this).val());
$(this).hide();
});
$(".ContainerDiv").hover(
function () {
$(this).find(".deleteClass").show();
},
function () {
$(this).find(".deleteClass").hide();
});
$(".deleteClass").click(function () {
$(this).closest("li").remove();
});
$("#orderPhoto").click(function () {
var photos = $.map($("li.ui-state-default"), function (item, index) {
var imgDetail = new Object();
imgDetail.Id = $(item).find("img").attr("id");
imgDetail.Caption = $(item).find("label").html();
imgDetail.Order = index + 1;
return imgDetail;
});
var jsonPhotos = JSON.stringify(photos);
$.ajax({
type: "POST",
contentType: "application/json",
data: "{photos:" + jsonPhotos + "}",
url: "WebService.asmx/updatePhoto",
dataType: "json",
success: function (data) {
if (data.d === "saved") {
$("<p>").text("New order saved!")
.addClass("success").appendTo("#left");
} else {
$("<p>").text("Save failed")
.addClass("failure").appendTo("#left");
}
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
debugger;
}
});
});
});
</script>
<style type="text/css">
#sortable
{
list-style-type: none;
margin: 0;
padding: 0;
}
#sortable li
{
position: relative;
margin: 3px 3px 3px 0;
padding: 1px;
float: left;
text-align: left;
}
#sortable .vacant
{
border: 3px dotted #66d164;
width: 150px;
height: 175px;
background-color: #fff;
}
#outerWrap
{
width: 1004px;
margin: auto;
position: relative;
background-color: #eee;
border: 1px solid #999;
}
#outerWrap:after
{
content: ".";
display: block;
visibility: hidden;
clear: both;
}
#left
{
width: 218px;
float: left;
}
#images
{
margin: 0;
padding: 0;
float: left;
width: 786px;
}
h1
{
font: italic normal 24px Georgia, Serif;
text-align: center;
margin: 10px 0;
}
p
{
margin: 0;
font: 12px Arial, Sans-serif;
padding: 0 10px;
}
.deleteClass
{
/* PhotoListItem is relative so relative to it */
position: absolute;
top: 1px;
right: 3px;
background: black;
color: Red;
font-weight: bold;
font-size: 12px;
padding: 5px;
opacity: 0.60;
filter: alpha(opacity="60");
margin-top: 3px;
display: none;
cursor: pointer;
}
.deleteClass:hover
{
opacity: 0.90;
filter: alpha(opacity="90");
}
.image_resize
{
width: 150px;
height: 150px;
border: 0;
}
.success, .failure
{
margin: 0 0 0 10px;
padding: 4px 0 4px 26px;
position: absolute;
bottom: 18px;
font-weight: bold;
}
.success
{
background: url('../img/tick.png') no-repeat 0 1px;
color: #12751c;
}
.failure
{
background: url('../img/cross.png') no-repeat 0 0;
color: #861b16;
}
</style>
</head>
<body>
<form id="form2" runat="server">
<div id="outerWrap">
<div id="left">
<h1>
Image Organiser</h1>
<p>
Re-order the images by dragging an image to a new location. Your changes will be
saved automatically.</p>
</div>
<div id="images">
<asp:ListView ID="ListViewAlbumPhotoView" runat="server" GroupItemCount="15">
<LayoutTemplate>
<ul id="sortable">
<li id="groupPlaceholder" runat="server">1</li>
</ul>
</LayoutTemplate>
<GroupTemplate>
<tr id="itemPlaceholderContainer" runat="server">
<td id="itemPlaceholder" runat="server">
</td>
</tr>
</GroupTemplate>
<ItemTemplate>
<li class="ui-state-default">
<div class="ContainerDiv">
<div class="deleteClass">
X</div>
<img id='<%#Eval("photo_id")%>' src='<%# "uploads/" + Eval("photo_file_name")%>'
alt="" class="image_resize" />
<div style="height: 25px; margin-top: 3px">
<label>
<%# Eval("photo_title")%></label>
<input type="text" style="display: none" />
</div>
</div>
</li>
</ItemTemplate>
</asp:ListView>
<input type="button" id="orderPhoto" value="Save change" />
</div>
</div>
</form>
</body>
</html>
The problem is with
success: function (data) {
if (data.d === "saved") {
$("<p>").text("New order saved!")
.addClass("success").appendTo("#left");
} else {
$("<p>").text("Save failed")
.addClass("failure").appendTo("#left");
}
},
Could someone tell me how to message display in the < p > area?
Any help would be greatly appreciated.
Thanks
Be sure to add the closing tag as well:
$("<p></p>").text("Save failed").addClass("failure").appendTo("#left");
Update: Also make sure the success function is even being called--Use a tool like Firebug (Firefox) or Developer tools in Chrome or Safari to inspect net traffic to see what the result of your call is.
You don't use brackets around the p inside the jquery function
try $('p')
Are you trying to update the single paragraph element already there? Or do you want to insert
a new paragraph element every single time. If you want the second case, just combine everything at once.
if (data.d === "saved") {
$("<p class='success'>New order saved!</p>").appendTo("#left");
}
else {
$("<p class='failure'>Save failed!</p>").appendTo("#left");
}