I am facing one issue in my html code please check that out below in code:
HTML:
<div class="agent_select_wrap">
<select name="menu-114" class="wpcf7-form-control wpcf7-select" aria-invalid="false">
<option value="Select Category" selected="selected">Select Agent Name</option>
<option>Mr. abc</option>
<option>Mr. abc</option>
<option>Mr. abc</option>
</select>
</div>
<div class="agent_select_wrap02">
<div class="my_textarea"></div>
<button>Send</button>
</div>
CSS
.agent_select_wrap { width: 40%; margin: 30px auto 10px auto;}
.agent_select_wrap02 { width: 40%; margin: 0px auto 50px auto;}
.agent_select_wrap select{font-weight:100; font-family: 'Open Sans', sans-serif; font-size: 13px; color: #494949; background: #fff url('../images/selectbox-arrow02.png') right center no-repeat; outline: 0; margin-bottom: 0px; margin: auto; width: 100%; height: 40px; border: 1px solid #ccc; border-radius: 0; -webkit-appearance: none; -moz-appearance: none; appearance: none; -ms-appearance: none; /*box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.25);*/}
.agent_select_wrap select option { background: #fff; color: #000;}
.my_textarea textarea {font-weight:100; font-family: 'Open Sans', sans-serif; font-size: 13px; color: #494949; width:97.4%; display:block; height: 100px; border: 1px solid #ccc; padding: 6px 0 0 6px; margin: 0; border-radius: 0px; /*box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.25);*/}
.my_textarea p{padding: 0; margin: 0; text-align: center; font-size: 12px;font-family: 'Open Sans', sans-serif;}
.agent_select_wrap02 button { display: block; margin: 16px auto 0 auto; padding: 7px 30px; background: #494949; color: #fff; font-weight: 100; font-family: 'Open Sans', sans-serif; font-size: 18px; border: 0;}
.agent_select_wrap02 button:hover {cursor:pointer;}
JS
$(document).on('change', 'select[name=menu-114]', function () {
$("<textarea> Hello Mr. </textarea>").appendTo(".my_textarea")
$("<p>Please enter your message here..!</p>").appendTo(".my_textarea")
$(function () {
$('select').change(function () {
$that = $(this);
$('textarea').val(function () {
return $(this).prop('defaultValue') + ' ' + $that.val();
});
});
});
});
here is my working example
https://jsfiddle.net/7j623eho/
you just need to change one line of code in javascript code.
$(".my_textarea").html("<textarea> Hello Mr.</textarea><p>Please enter your message here..!</p>");
use above code Instead of yours ..
$("<textarea> Hello Mr. </textarea>").appendTo(".my_textarea")
$("<p>Please enter your message here..!</p>").appendTo(".my_textarea")
Probably your problem is that you don't remove just created textarea. Try to create it in <div id='temp'> element and then remove this element just before you create new one.
$('#temp').remove();
var container = $('<div id="temp">');
$("<textarea> Hello Mr. </textarea>").appendTo(container);
$("<p>Please enter your message here..!</p>").appendTo(container);
container.appendTo(".my_textarea");
I believe what you want is to create the textarea only once, and let the inline handler to handle further change, so the better way to achieve it is
var onMenuSelected = function () {
$("<textarea> Hello Mr. </textarea>").appendTo(".my_textarea")
$("<p>Please enter your message here..!</p>").appendTo(".my_textarea")
$(function () {
$('select').change(function () {
$that = $(this);
console.log('Select');
$('textarea').val(function () {
return $(this).prop('defaultValue') + ' ' + $that.val();
});
});
});
// Just unbind self
$(document).off('change', 'select[name=menu-114]', onMenuSelected);
}
$(document).on('change', 'select[name=menu-114]', onMenuSelected);
By define the function, you can directly remove the $(document).on without remove other possible exist handlers. And the select event will only be registered once.
jsFiddle here.
Here we go, use the following code:
HTML
<div class="agent_select_wrap">
<select name="menu-114" class="wpcf7-form-control wpcf7-select" aria-invalid="false">
<option value="Select Category" selected="selected">Select Agent Name</option>
<option>Mr. abc</option>
<option>Mr. abc</option>
<option>Mr. abc</option>
</select>
</div>
<div class="agent_select_wrap02">
<div id="my_textarea0">
</div>
<textarea id="my_textarea">
</textarea>
<button>Send</button>
</div>
JS
$(document).on('change', 'select[name=menu-114]', function () {
$("#my_textarea0").html("<textarea> Hello Mr. </textarea>")
$("#my_textarea").html("<p>Please enter your message here..!</p>")
$(function () {
$('select').change(function () {
$that = $(this);
$('textarea').val(function () {
return $(this).prop('defaultValue') + ' ' + $that.val();
});
});
});
});
Related
I'm trying to create a GPA calculator (just to practice html, css, javascript) and am having an issue I can't seem to solve. Here's what's happening.
TL;DR: When I click on an input field, the corresponding object is erased.
For each course, there is a form with input fields for course name (text input), grade (select input), and credits earned (number input). When you want to add another course, you're adding another form. When a form is created, so is an object that's associated with it. I create this association by adding an id to the form with a unique number and also adding that id number to the object.
When I console.log the various steps of creating an object and setting its values and saving it to the local storage, everything works fine. However, when I was trying to create functionality to update the values of the objects, I started having troubles. I've pinpointed when they happen. Whenever I click on an input field, the object is erased. Specifically, only the object that's tied to that input field is erased. So if I create 5 forms and I click on the text input of the 3rd one, the 3rd object is erased. I can click on that same field multiple times and nothing else will happen. Then, if I click, say, the number input of the 5th form, then the 5th object is erased. I know it's not the delete function at work because that function would also remove the form from view.
If anyone could help me pinpoint what I can do to fix this, I would greatly appreciate it.
Javascript
// Theme
let lightMode = document.getElementById('light-mode');
let darkMode = document.getElementById('dark-mode');
lightMode.addEventListener('click', () => {themeTransition(); document.documentElement.setAttribute('data-theme', 'light');});
darkMode.addEventListener('click', () => {themeTransition(); document.documentElement.setAttribute('data-theme', 'dark');});
function themeTransition()
{
document.documentElement.classList.add('transition');
window.setTimeout(() => document.documentElement.classList.remove('transition'), 1000);
}
// GPA CALCULATION
// Object ID
var objId = 0;
// Grades class
class Grades
{
constructor(id, course, grade, credits)
{
this.id = id;
this.course = course;
this.grade = grade;
this.credits = credits;
}
}
// Storage class
class Store
{
static getGrades()
{
let grades;
if (localStorage.getItem('grades') == null)
{
grades = [];
}
else
{
grades = JSON.parse(localStorage.getItem('grades'));
objId = localStorage.getItem('objId');
}
return grades;
}
static addGrade(grade, newObjId)
{
const grades = Store.getGrades();
grades.push(grade);
localStorage.setItem('grades', JSON.stringify(grades));
localStorage.setItem('objId', JSON.stringify(newObjId));
console.log(grades);
}
static updateGrade(id, course, grade, credits)
{
const grades = Store.getGrades();
grades.forEach((oldGrade, index) =>
{
if (oldGrade.id == id)
{
oldGrade[index].course = course;
oldGrade[index].grade = grade;
oldGrade[index].credits = credits;
}
});
localStorage.setItem('grades', JSON.stringify(grades));
}
static removeGrade(id)
{
const grades = Store.getGrades();
grades.forEach((grade, index) =>
{
if (grade.id == id)
{
grades.splice(index, 1);
}
});
localStorage.setItem('grades', JSON.stringify(grades));
}
}
// UI class
class UI
{
static displayGrades()
{
const grades = Store.getGrades();
grades.forEach((grade) => UI.addCurrentGrade(grade));
}
static addCurrentGrade(grade)
{
const list = document.querySelector('.add-grades');
const row = document.createElement('form');
const addBefore = document.querySelector('.add');
row.classList.add('add-item');
row.setAttribute('id', `${grade.id}`)
row.innerHTML =
`
<div class="input-node course">
<label for="course">Course</label>
<input type="text" id="course">
</div>
<div class="input-node grade">
<label for="grade">Grade</label>
<select id="grade">
<option value="none"></option>
<option value="A">A</option>
<option value="A-">A-</option>
<option value="B+">B+</option>
<option value="B">B</option>
<option value="B-">B-</option>
<option value="C+">C+</option>
<option value="C">C</option>
<option value="C-">C-</option>
<option value="D+">D+</option>
<option value="D">D</option>
<option value="D-">D-</option>
<option value="F">F</option>
<option value="W">W</option>
<option value="I">I</option>
<option value="P">P</option>
<option value="NP">NP</option>
</select>
</div>
<div class="input-node credits">
<label for="credits">Credits</label>
<input type="number" id="credits">
</div>
<div class="input-node delete">
<i class="fas fa-times-circle"></i>
</div>
`;
list.insertBefore(row, addBefore);
document.querySelector('.delete').addEventListener('click', delGrade);
document.querySelector('.add-grades').addEventListener('input', updateGrades);
}
static addNewGrade(e)
{
if (e.parentElement.classList.contains('add-grade'))
{
objId++;
const currentId = objId;
const list = document.querySelector('.add-grades');
const row = document.createElement('form');
const addBefore = document.querySelector('.add');
row.classList.add('add-item');
row.setAttribute('id', `${currentId}`)
row.innerHTML =
`
<div class="input-node course">
<label for="course">Course</label>
<input type="text" id="course">
</div>
<div class="input-node grade">
<label for="grade">Grade</label>
<select id="grade">
<option value="none"></option>
<option value="A">A</option>
<option value="A-">A-</option>
<option value="B+">B+</option>
<option value="B">B</option>
<option value="B-">B-</option>
<option value="C+">C+</option>
<option value="C">C</option>
<option value="C-">C-</option>
<option value="D+">D+</option>
<option value="D">D</option>
<option value="D-">D-</option>
<option value="F">F</option>
<option value="W">W</option>
<option value="I">I</option>
<option value="P">P</option>
<option value="NP">NP</option>
</select>
</div>
<div class="input-node credits">
<label for="credits">Credits</label>
<input type="number" id="credits">
</div>
<div class="input-node delete">
<i class="fas fa-times-circle"></i>
</div>
`;
list.insertBefore(row, addBefore);
document.querySelector('.delete').addEventListener('click', delGrade);
document.querySelector('.add-grades').addEventListener('input', updateGrades);
const course = e.parentElement.parentElement.querySelector('#course').value;
const grade = e.parentElement.parentElement.querySelector('#grade').value;
const credits = e.parentElement.parentElement.querySelector('#course').value;
const grades = new Grades(currentId, course, grade, credits);
Store.addGrade(grades, currentId);
}
}
static deleteGrade(del)
{
if (del.parentElement.classList.contains('delete'))
{
del.parentElement.parentElement.remove();
}
}
}
// EVENTS
// Display Existing Grades
document.addEventListener('DOMContentLoaded', UI.displayGrades);
// Add Grade
document.querySelector('.add-grade').addEventListener('click', (e) =>
{
UI.addNewGrade(e.target);
});
// Update Grade
document.querySelector('.add-grades').addEventListener('input', updateGrades);
function updateGrades(e)
{
const id = e.target.parentElement.parentElement.getAttribute('id');
const course = e.target.parentElement.parentElement.querySelector('#course').value;
const grade = e.target.parentElement.parentElement.querySelector('#grade').value;
const credits = e.target.parentElement.parentElement.querySelector('#course').value;
Store.updateGrade(id, course, grade, credits);
}
// Remove Grade
document.querySelector('.add-grades').addEventListener('click', delGrade);
function delGrade(e)
{
UI.deleteGrade(e.target);
Store.removeGrade(e.target.parentElement.parentElement.getAttribute('id'));
}
document.body.addEventListener('click', testFun);
function testFun()
{
const grades = Store.getGrades();
console.log(grades);
}
note: function testFun() is to log the objects in the Grades class whenever I click on anything
HTML
<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.13.1/css/all.css" integrity="sha384-xxzQGERXS00kBmZW/6qxqJPyxW3UR0BPsL4c8ILaIWXva5kFi7TxkIIaMiKtqV1Q" crossorigin="anonymous">
<link rel="stylesheet" href="style.css">
<title>GPA Calculator</title>
</head>
<body>
<div class="container">
<div id="view-mode">
<button id="light-mode">Light</button> | <button id="dark-mode">Dark</button>
</div>
<header class="header">
<h1>GPA</h1>
<h2>Calculator</h2>
</header>
<section class="add-grades">
<div class="table-header">
<h1>Semester <span class="semester">–</span></h1>
<h2>Semester GPA: <span class="gpa-semester">–</span></h2>
</div>
<div class="add add-grade">
<i class="fas fa-plus-circle"></i>
</div>
</section>
<div class="add add-semester">
<i class="fas fa-plus-circle"></i>
</div>
<aside class="gpa-total">
<h2>GPA</h2>
<h1><span class="gpa-total">–</span></h1>
</aside>
</div>
<script src="main.js"></script>
</body>
</html>
If you want the full effect, here's the CSS as well
/* Global */
html[data-theme="light"]
{
--background: rgb(235, 235, 235);
--panel: rgb(245, 245, 245);
--panel-head: rgb(0, 80, 190);
--text: rgb(20, 20, 20);
--text-secondary: rgb(60, 60, 60);
--text-panel: rgb(20, 20, 20);
--text-panel-head: rgb(245, 245, 245);
--add: rgb(58, 180, 34);
--delete: rgb(255, 55, 55);
}
html[data-theme="dark"]
{
--background: rgb(40, 40, 40);
--panel: rgb(70, 70, 70);
--panel-head: rgb(0, 106, 255);
--text: rgb(245, 245, 245);
--text-secondary: rgb(120, 120, 120);
--text-panel: rgb(245, 245, 245);
--text-panel-head: rgb(245, 245, 245);
--add: rgb(58, 180, 34);
--delete: rgb(255, 55, 55);
}
*
{
margin: 0;
padding: 0;
box-sizing: border-box;
}
body
{
background: var(--background);
font-family: Cochin, Georgia, Times, 'Times New Roman', serif;
font-size: 16px;
color: var(--text);
}
.container
{
width: 80%;
margin: auto;
}
button
{
background: none;
border: none;
outline: none;
}
/* Header */
#view-mode
{
text-align: right;
margin-top: 20px;
}
#view-mode button
{
font-size: 16px;
color: var(--text);
}
#view-mode button:hover
{
color: var(--panel-head);
text-decoration: underline;
cursor: pointer;
}
.header
{
margin: 20px 0 50px 0;
text-align: center;
text-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
text-transform: uppercase;
}
.header h1
{
font-size: 6em;
}
.header h2
{
font-size: 1.77em;
color: var(--text-secondary);
}
/* User Input */
.add-grades
{
min-width: 400px;
max-width: 500px;
margin: auto;
margin-top: 20px;
background: var(--panel);
color: var(--text-panel);
border-radius: 20px;
display: flex;
flex-direction: column;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
}
.table-header
{
padding: 10px 15px;
display: flex;
justify-content: space-between;
align-items: baseline;
border-top-right-radius: 20px;
border-top-left-radius: 20px;
background: var(--panel-head);
color: var(--text-panel-head);
}
.table-header h1
{
font-size: 2em;
}
.table-header h2
{
font-size: 1.2em;
}
.add-item
{
padding: 10px;
display: flex;
justify-content: space-between;
align-items: center;
}
.add-item .input-node
{
display: flex;
justify-content: space-between;
align-items: center;
}
.add-item .input-node *
{
margin: 0 3px;
}
.input-node #course
{
width: 75px;
padding: 5px;
border: none;
border-radius: 5px;
outline: none;
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.5);
}
.input-node #grade
{
font-size: 1em;
outline: none;
}
.input-node #credits
{
width: 40px;
padding: 5px;
border: none;
border-radius: 5px;
outline: none;
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.5);
}
.delete i
{
font-size: 1.4em;
padding: 0;
color: var(--text-panel);
}
.delete i:hover
{
color: var(--delete);
cursor: pointer;
}
.add-grades .add
{
margin: 13px;
margin-top: 10;
display: flex;
justify-content: flex-end;
}
.add i
{
font-size: 1.4em;
color: var(--text-panel);
}
.add i:hover
{
color: var(--panel-head);
cursor: pointer;
}
.container > .add
{
min-width: 400px;
max-width: 500px;
margin: auto;
margin-top: 20px;
}
/* GPA Calculation */
.gpa-total
{
margin-top: 50px;
text-align: center;
}
.gpa-total h2
{
font-size: 3em;
text-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
}
.gpa-total h1
{
width: 250px;
margin: auto;
margin-top: 10px;
padding: 60px 0;
font-size: 6em;
border-radius: 100%;
background: var(--panel-head);
color: var(--text-panel-head);
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
}
/* Transition */
html.transition,
html.transition body,
html.transition body:before,
html.transition body:after,
html.transition section,
html.transition section:before,
html.transition section:after
{
transition: all 750ms !important;
transition-delay: 0 !important;
}
on my website, there are 2 buttons. one button is to indent text to the left and the other button is to indent text to the right. what I am trying to achieve is that whenever I press the indent left or right button, currently selected (on focus) text should move left or right (depending on what button I press). at the same time, I want the font size of that text to go down by one level, so when compared to the text above, it's smaller to the text above.
// global variable
let onFocus = null;
// this function
function focusedText(event) {
onFocus = event.target;
}
function init() {
const newLineButton = document.querySelector('#newLine');
newLineButton.addEventListener("click", newLine);
newLine();
document.querySelector("#printButton").addEventListener("click", printPage)
}
function newLine() {
const newLine = document.createElement("p");
newLine.setAttribute("contenteditable", true);
newLine.addEventListener("keydown", handleKeyDown)
newLine.addEventListener("focus", focusedText)
newLine.classList.add("textLine")
const parent = document.querySelector('#textBox');
parent.appendChild(newLine);
newLine.focus();
}
function handleKeyDown(event) {
if (event.which === 13) {
event.preventDefault();
newLine();
}
}
// this runs the init(); function
init();
// this prints the page
function printPage() {
window.print();
}
// this fuction changes the text size
function textSize(selectTag) {
const listValue = selectTag.options[selectTag.selectedIndex].value;
onFocus.style.fontSize = listValue;
}
* {
padding-top: 0em;
padding-bottom: 0em;
margin-top: 0em;
margin-bottom: 0em;
}
*:focus {
outline: 0px solid transparent;
}
body {
margin: 0;
}
.title {
font-family: 'Assistant', sans-serif;
font-size: 2em;
text-align: center;
text-transform: uppercase;
color: white;
background: #6a0dad;
letter-spacing: 0.20em;
}
.navMenu {
display: flex;
align-items: stretch;
padding-top: 0.5em;
padding-bottom: 0.5em;
justify-content: center;
}
.navMenu button,
#dropDown {
padding: 0.3em 1.2em;
margin: 0 0.1em 0.1em 0;
border: 0.16em solid rgba(255, 255, 255, 0);
border-radius: 2em;
box-sizing: border-box;
font-family: 'Assistant', sans-serif;
font-weight: bold;
font-size: 1rem;
color: white;
text-shadow: 0 0.04em 0.04em rgba(0, 0, 0, 0.35);
text-align: center;
transition: all 0.2s;
background-color: #6a0dad;
cursor: pointer;
}
.navMenu button:hover,
#dropDown:hover {
border-color: white;
}
#dropDown option {
font-weight: bold;
}
#textBox {
display: flex;
justify-content: left;
width: auto;
flex-flow: column nowrap;
font-family: 'Assistant', sans-serif;
}
.textLine {
color: black;
width: 100%;
padding-left: 0.8em;
padding-right: 0.8em;
box-sizing: border-box;
transition: background-color 0.25s;
}
#media screen {
.textLine:hover {
background-color: #6a0dad;
color: white;
}
}
#media print {
.navMenu,
.title {
display: none;
}
}
.textLine:empty::before {
content: "Enter your text here";
color: grey;
font-family: 'Assistant', sans-serif;
pointer-events: none;
}
.textLine:hover:empty::before {
content: "Enter your text here";
color: white;
font-family: 'Assistant', sans-serif;
}
<!DOCTYPE html>
<html>
<head>
<title>Outline Editing</title>
<link rel="stylesheet" type="text/css" href="main-css.css">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
</head>
<body>
<main>
<h1 class="title">Outline Editing</h1>
<nav class="navMenu">
<button type="button" id="indentLeft"><i class="material-icons">format_indent_decrease</i></button>
<select id="dropDown" onchange="textSize(this);" size="1">
<option value="" selected disabled hidden>Levels</option>
<option value="200%">Level 1</option>
<option value="170%">Level 2</option>
<option value="150%">Level 3</option>
<option value="130%">Level 4</option>
<option value="100%">Level 5</option>
</select>
<button type="button" id="newLine">New Line</button>
<button type="button" id="indentRight"><i class="material-icons">format_indent_increase</i></button>
<button type="button" id="printButton">Print</button>
</nav>
<div id="textBox">
</div>
<script src="main.js"></script>
</main>
</body>
</html>
You could just add "Horizontal Tab" as an HTML entity on your focused text.
First change the <p> to <pre>.
function newLine() {
const newLine = document.createElement("pre");
//...
}
Update your init function:
function init() {
var newLineButton = document.querySelector('#newLine');
newLineButton.addEventListener("click", newLine);
newLine();
document.querySelector("#printButton").addEventListener("click", printPage);
let indentRight = document.getElementById("indentRight");
indentRight.addEventListener("click", IndentRight_Click);
let indentLeft = document.getElementById("indentLeft");
indentLeft.addEventListener("click", IndentLeft_Click);
}
Then you can add the "Horizontal Tab" on the text that is focused, checking if you have already added:
function IndentRight_Click(event) {
let horizontalTab = " ";
let originalHtml = onFocus.innerHTML;
if (!originalHtml.includes("\t")) onFocus.innerHTML = horizontalTab + originalHtml;
onFocus.focus();
}
And finally, check for it again on your "Left Indentation":
function IndentLeft_Click(event) {
var originalHtml = onFocus.innerHTML;
if (originalHtml.includes("\t")) onFocus.innerHTML = originalHtml.replace("\t", "");
onFocus.focus();
}
I have an add and remove button which selects the complete div and adds a green color to the div. The function only works on the "add this extra" and "remove" button. How do I make it work like clicking anywhere on the div instead of the particular button itself?
I would look to hear someone help from you guys.
Regards,
Bilal
$('.btn_extras').addClass('force-hide');
$('.btn-rmv-item').hide();
// Add btn onClick
$('.btn-add-item').on('click', function(e) {
e.preventDefault();
// Show the Adjacent Remove Button
$(e.currentTarget).next("button.btn-rmv-item").show();
// Apply THE DIV class to SELECTED
$(e.currentTarget).closest("div.card-border").addClass('card-bg');
// Show THE btn_extra button
showHideContinueBtn();
// Hide the Button
$(e.currentTarget).hide();
});
// Remove btn onClick
$('.btn-rmv-item').on('click', function(e) {
e.preventDefault();
// Show the Adjacent Remove Button
$(e.currentTarget).prev("button.btn-add-item").show();
// Apply THE DIV class to SELECTED
$(e.currentTarget).closest("div.card-border").removeClass('card-bg');
// Show THE btn_extra button
showHideContinueBtn();
// Hide the Button
$(e.currentTarget).hide();
});
// function to Show/Hide Continue Button w.r.t SELECTIONS
function showHideContinueBtn() {
$('.btn_extras').addClass('force-hide').removeClass('force-block');
$('.btn_skip').removeClass('force-hide').addClass('force-block');
$('div.card').each(function(index) {
if($(this).hasClass('card-bg')) {
$('.btn_extras').removeClass('force-hide').addClass('force-block');
$('.btn_skip').removeClass('force-block').addClass('force-hide');
}
});
}
.card-border {
border: 1px solid #c7c7c7;
border-radius: .25rem;
padding: 15px 18px 10px 18px;
margin-bottom: 30px;
}
div.ho-border:hover {
border: 1px solid #59d389;
}
.upsell-pricing {
float: right;
font-size: 18px;
font-weight: 600;
}
.upsell-text {
font-size: 15px;
margin-top: 10px;
color: #333333;
}
.btn-add-item {
font-weight: 600;
letter-spacing: -0.02px;
text-transform: none;
padding: 3px 10px 3px 10px;
margin-left: 20px;
margin-top: 1px;
color: #c7c7c7;
opacity: 0.65;
}
.btn-add-item:focus {
outline: none;
box-shadow: none;
}
.btn-rmv-item {
background-color: transparent;
color: #59d389;
font-weight: 600;
letter-spacing: -0.02px;
text-transform: none;
padding: 3px 8px 3px 8px;
margin-left: 20px;
margin-top: 1px;
}
.btn-rmv-item:focus {
outline: none;
box-shadow: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- Fuel Replacement -->
<div class="card-border ho-border">
<h4 class="float-left">Fuel replacement</h4>
<div class="upsell-pricing">£49/trip</div>
<div class="clearfix"></div>
<div class="upsell-text">Save time and return the vehicle at any fuel level. The price include upto a full tank of petrol/gas.</div>
<div class="mt-3 float-right">
<button class="btn btn-add-item">Add this extra</button>
<button class="btn btn-rmv-item">Remove</button>
</div>
<div class="clearfix"></div>
</div>
You can have the click handler directly on the div (I assume it is .card-border here).
And you need only one button which you toggle the classes and change the text.
I added a .card-bg CSS rule that seemed to be missing in the question...
I also added type="button" to prevent form submission if the button is clicked.
Have a look at the comments in the code below. It replaces the two click handlers you had... And the showHideContinueBtn() function.
$(".card-border").on("click",function(){
// Toggle the div background color
$(this).toggleClass("card-bg");
// Find the button
var btn = $(this).find(".btn");
// Toggle classes for ONE button
btn.toggleClass('btn-add-item btn-rmv-item');
// Depending on a button's class, change it's text
(btn.hasClass("btn-rmv-item"))?btn.text("Remove"):btn.text("Add this extra");
});
.card-border {
border: 1px solid #c7c7c7;
border-radius: .25rem;
padding: 15px 18px 10px 18px;
margin-bottom: 30px;
}
div.ho-border:hover {
border: 1px solid #59d389;
}
.upsell-pricing {
float: right;
font-size: 18px;
font-weight: 600;
}
.upsell-text {
font-size: 15px;
margin-top: 10px;
color: #333333;
}
.btn-add-item {
font-weight: 600;
letter-spacing: -0.02px;
text-transform: none;
padding: 3px 10px 3px 10px;
margin-left: 20px;
margin-top: 1px;
color: #c7c7c7;
opacity: 0.65;
}
.btn-add-item:focus {
outline: none;
box-shadow: none;
}
.btn-rmv-item {
background-color: transparent;
color: #59d389;
font-weight: 600;
letter-spacing: -0.02px;
text-transform: none;
padding: 3px 8px 3px 8px;
margin-left: 20px;
margin-top: 1px;
}
.btn-rmv-item:focus {
outline: none;
box-shadow: none;
}
/* This class was not posted in question... So I improvised one */
.card-bg{
background-color:#44bb44;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- Fuel Replacement -->
<div class="card-border ho-border">
<h4 class="float-left">Fuel replacement</h4>
<div class="upsell-pricing">£49/trip</div>
<div class="clearfix"></div>
<div class="upsell-text">Save time and return the vehicle at any fuel level. The price include upto a full tank of petrol/gas.</div>
<div class="mt-3 float-right">
<button type="button" class="btn btn-add-item">Add this extra</button>
<!--button class="btn btn-rmv-item">Remove</button-->
</div>
<div class="clearfix"></div>
</div>
Change
$('.btn-add-item').on('click', function(e) {
to
$(e.currentTarget).closest("div.card-border").on('click', function(e) {
If you want a toggle functionality, also add a variable that holds the crt state:
var state="default";
...on('click',function(){
if(state=='default'){
state='checked';
....
} else {
state='default';
....
}
});
If I understood you question right then this is answer you are looking for.
<!DOCTYPE html>
<html>
<body>
<p id="demo" onclick="myFunction()" style="width:200px; height:100px; border: 1px solid black;">
This Div's background color will change.
</p>
<script>
var color=0;
function myFunction() {
// Just Specify The Id you need
var myDiv = document.getElementById("demo");
if(color == 0)
{
myDiv.style.backgroundColor = "red"; color=1;
}
else
{
myDiv.style.backgroundColor = "white"; color=0;
}
}
</script>
</body>
</html>
Hope This Solves the Issue.
When a select changes, the text should change. Here's a fiddle.
(function($) {
'use strict';
function funcFormCalc() {
var s1_is_1 = $("#s1").value === '1',
s1_is_2 = $("#s1").value === '2';
var s2_is_1 = $("#s2").value === '1',
s2_is_2 = $("#s2").value === '2';
$('#myForm').onchange = function() {
if (s1_is_1 && s2_is_1) {
$('#result').html('result 1');
} else if (s1_is_2 && s2_is_1) {
$('#result').html('result 2');
} else if (s1_is_1 && s2_is_2) {
$('#result').html('result 3');
} else {
$('#result').html('result 4');
}
};
}
funcFormCalc();
})(window.jQuery);
<form action="#" method="post" id="myForm">
<label for="s1">
Tree Number
<select id="s1">
<option value="1">1</option>
<option value="2">2</option>
</select>
</label><br>
<label for="s2">
Tree Height
<select id="s2">
<option value="1">1 story house</option>
<option value="2">2 story house</option>
</select>
</label>
<div id="result">Result Displays Here</div>
</form>
Why does the result text not change when a selection changes?
You are using the selectVariant booleans to determine which value to show, however these variables are only being calculated once on load. You probably meant to have the calculations in your onchange function.
Also your values do not match the options for select2.
<option value="1 story house">1 story house</option>
<option value="2 story house">2 story house</option>
<option value="3 story house +">3 story house +</option>
-- See snippet at bottom for original answer with some additional refactoring. --
EDIT: You completely changed the code in your question since my first answer...
Though my answer is the same. You need to recalculate selectVariant1, selectVariant2, select2Variant1, and select2Variant2 inside the onchange method.
(function($) {
'use strict';
function funcFormCalc() {
var formCalc = document.getElementsByClassName('form-calc')[0],
formCalcResult = document.getElementsByClassName('form-calc__result')[0],
selectHowManyTrees = document.getElementById('selectHowManyTrees'),
selectApproximateHeightTree = document.getElementById('selectApproximateHeightTree');
formCalc.onchange = function() {
var selectVariant1 = selectHowManyTrees.value === '1',
selectVariant2 = selectHowManyTrees.value === '2';
var select2Variant1 = selectApproximateHeightTree.value === '1',
select2Variant2 = selectApproximateHeightTree.value === '2';
if (selectVariant1 && select2Variant1) {
formCalcResult.innerHTML = 'variant text 1';
} else if (selectVariant2 && select2Variant1) {
formCalcResult.innerHTML = 'variant text 2';
} else if (selectVariant1 && select2Variant2) {
formCalcResult.innerHTML = 'variant text 3';
} else {
formCalcResult.innerHTML = 'for all variants';
}
};
}
funcFormCalc();
})(window.jQuery);
* {
padding: 0;
margin: 0;
}
*,
*:before,
*:after {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
html,
body {
overflow-x: hidden;
}
html {
font-family: sans-serif;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
body {
background: #fff;
color: #2C2D2C;
text-align: left;
font-family: 'Montserrat', Arial, "Helvetica CY", "Nimbus Sans L", sans-serif;
font-size: 16px;
line-height: 1.5;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
}
.form-calc {
max-width: 400px;
margin: 15px auto;
background: #FAFAFA;
padding: 15px 30px;
}
.form-calc__item {
margin-bottom: 28px;
}
.form-calc__label {
font-size: 14px;
display: block;
margin: 6px 0 9px;
letter-spacing: 0.25px;
}
.form-calc__select-container {
position: relative;
display: inline-block;
vertical-align: top;
width: 100%;
}
.form-calc__select-container:before,
.form-calc__select-container:after {
content: '';
position: absolute;
right: 7px;
width: 0;
height: 0;
border-style: solid;
pointer-events: none;
}
.form-calc__select-container:before {
top: 16.5px;
border-width: 0 3.5px 4px 3.5px;
border-color: transparent transparent #333 transparent;
}
.form-calc__select-container:after {
bottom: 16.5px;
border-width: 4px 3.5px 0 3.5px;
border-color: #333 transparent transparent transparent;
}
.form-calc__select {
font-family: 'Montserrat', Arial, "Helvetica CY", "Nimbus Sans L", sans-serif;
-webkit-appearance: none;
-moz-appearance: none;
text-indent: 1px;
text-overflow: '';
width: 100%;
height: 43px;
line-height: 43px;
border: 1px solid #D9D9D9;
padding: 0 7px;
color: #2C2D2C;
}
.form-calc__select::-ms-expand {
display: none;
}
.form-calc__select option {
padding: 3px 7px;
border: none;
}
.form-calc__result {
font-size: 36px;
font-weight: 500;
color: #3E3F3E;
line-height: 1.4;
margin-bottom: 6px;
}
.form-calc__result-subtext {
font-size: 12px;
text-transform: uppercase;
color: #3E3F3E;
letter-spacing: .6px;
line-height: 1.25;
}
.form-calc__submit {
font-family: 'Montserrat', Arial, "Helvetica CY", "Nimbus Sans L", sans-serif;
display: inline-block;
vertical-align: top;
color: #fff;
text-align: center;
min-width: 170px;
padding: 14px 20px;
background: #42BF8D;
text-transform: uppercase;
text-decoration: none;
border: none;
letter-spacing: 0.5px;
font-size: 12px;
cursor: pointer;
-webkit-transition: .3s;
transition: .3s;
}
.form-calc__submit:hover,
.form-calc__submit:focus,
.form-calc__submit:active {
color: #fff;
background: #2F8B66;
}
.form-calc__submit:focus {
box-shadow: inset 0 0 6px rgba(0, 0, 0, .25);
}
<link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,500,600,700&subset=latin-ext" rel="stylesheet">
<form action="#" method="post" class="form-calc" autocomplete="off">
<div class="form-calc__item">
<label for="selectHowManyTrees" class="form-calc__label">Label 1</label>
<div class="form-calc__select-container">
<select name="select1" id="selectHowManyTrees" class="form-calc__select">
<option value="1" selected>1</option>
<option value="2">2</option>
</select>
</div>
</div>
<div class="form-calc__item">
<label for="selectApproximateHeightTree" class="form-calc__label">Label 2</label>
<div class="form-calc__select-container">
<select name="select2" id="selectApproximateHeightTree" class="form-calc__select">
<option value="1">1 story house</option>
<option value="2">2 story house</option>
</select>
</div>
</div>
<div class="form-calc__item">
<div class="form-calc__result">variant text 1</div>
</div>
</form>
Edit 2: Responding to question in comment.
Excuse me! Not a big question. How would you solve this problem? (other logic).
This is a pretty opinionated question, so this answer is just my opinion. In general I think you have a pretty decent solution.
Your problem is essentially:
Display a result dependent on a combination of inputs.
So there needs to be some way to calculate a value based on the inputs. It would be best if you could do this mathematically, like value1 + value2 + value3 = result. Unfortunately this doesn't seem possible for your problem, but if you are able to do a slight design change then you could try this alternative:
Modify your form so each option has a low-value and high-value.
<select name="select1" id="selectHowManyTrees" class="form-calc__select">
<option low-value="20" high-value="30" selected>1</option>
<option low-value="30" high-value="40">2</option>
<option low-value="40" high-value="50">3</option>
<option low-value="50" high-value="60">4</option>
</select>
<select name="select2" id="selectApproximateHeightTree" class="form-calc__select">
<option low-value="100" high-value="180" story house">1 story house</option>
<option low-value="170" high-value="300" story house">2 story house</option>
<option low-value="220" high-value="600" story house +">3 story house +</option>
</select>
Sum up all the selected low-value and all the selected high-value to calculate the result.
var low = 0, high = 0;
var selects = document.getElementsByClassName('form-calc__select');
for(var s of selects) {
var selectedOption = s.options[ s.selectedIndex ];
low += selectedOption.getAttribute('low-value');
high += selectedOption.getAttribute('high-value');
}
Display this as a range for your result.
formCalcResult.innerHTML = '$' + low + ' - $' + high;
or with ES6 string interpolation
formCalcResult.innerHTML = `$${low} - $${high}`;
Now it may be that you cannot do this, and that there is no way to mathematically calculate the result. In this scenario you are forced to find a way to link a combination of inputs to a result, which is what you did using a bunch of booleans.
How could you do it better? A database.
The ideal place for storing data relationships is in a database. Then your application can dynamically display all the options and results. This will allow you whenever there is a change to a value you just update the data rather than updating the entire application. It is also a very readable way of storing the different option combinations. For example you could have a table that looks like this:
NumberOfTreesId | TreeHeightId | JobTypeId | LocationPropertyId |Result
1 | 1 | 1 | 1 | '$250 - $610'
1 | 1 | 1 | 2 | '$350 - $825'
This example resembles SQL, but you could do something very similar using a non-relational database if you wanted.
Of course, using a database adds a lot of complexity to your application and you are just doing a JS tutorial, so definitely overkill. So after all that I would say design-wise your code is perfectly fine. There is a lot of ways you could refactor to make it more readable and less code, but in the end the concept will be the same.
There are a lot of ways this could be written differently, here is one way:
(function($) {
'use strict';
var results = [ ];
function addResult(s1, s2, s3, s4, r) {
results.push({
select1 : s1,
select2 : s2,
select3 : s3,
select4 : s4,
result : r
});
}
var defaultResult = '$450 - $750';
addResult('1', '1', '1', '1', '$250 - $610');
addResult('1', '1', '1', '2', '$350 - $825');
addResult('1', '1', '1', '3', '$250 - $610');
addResult('1', '2', '1', '1', '$425 - $1200');
addResult('1', '2', '1', '2', '$546 - $1620');
addResult('1', '2', '1', '3', '$420 - $1200');
addResult('1', '3', '1', '1', '$750 - $1800');
addResult('1', '3', '1', '2', '$900 - $2000');
addResult('2', '1', '1', '1', '$500 - $850');
addResult('2', '1', '1', '2', '$650 - $1000');
addResult('2', '1', '1', '3', '$500 - $850');
function funcFormCalc() {
var formCalc = document.getElementsByClassName('form-calc')[0],
formCalcResult = document.getElementsByClassName('form-calc__result')[0],
selectHowManyTrees = document.getElementById('selectHowManyTrees'),
selectApproximateHeightTree = document.getElementById('selectApproximateHeightTree'),
selectJobType = document.getElementById('selectJobType'),
selectLocationProperty = document.getElementById('selectLocationProperty');
formCalc.onchange = function() {
var s1 = selectHowManyTrees.value,
s2 = selectApproximateHeightTree.value,
s3 = selectJobType.value,
s4 = selectLocationProperty.value;
var text = defaultResult;
for(var result of results)
{
if(s1 === result.select1 &&
s2 === result.select2 &&
s3 === result.select3 &&
s4 === result.select4) {
text = result.result;
}
}
formCalcResult.innerHTML = text;
//console.log(`${s1} ${s2} ${s3} ${s4}`);
};
}
funcFormCalc();
})(window.jQuery);
* {
padding: 0;
margin: 0;
}
*,
*:before,
*:after {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
html,
body {
overflow-x: hidden;
}
html {
font-family: sans-serif;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
body {
background: #fff;
color: #2C2D2C;
text-align: left;
font-family: 'Montserrat', Arial, "Helvetica CY", "Nimbus Sans L", sans-serif;
font-size: 16px;
line-height: 1.5;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
}
.form-calc {
max-width: 400px;
margin: 15px auto;
background: #FAFAFA;
padding: 15px 30px;
}
.form-calc__item {
margin-bottom: 28px;
}
.form-calc__label {
font-size: 14px;
display: block;
margin: 6px 0 9px;
letter-spacing: 0.25px;
}
.form-calc__select-container {
position: relative;
display: inline-block;
vertical-align: top;
width: 100%;
}
.form-calc__select-container:before,
.form-calc__select-container:after {
content: '';
position: absolute;
right: 7px;
width: 0;
height: 0;
border-style: solid;
pointer-events: none;
}
.form-calc__select-container:before {
top: 16.5px;
border-width: 0 3.5px 4px 3.5px;
border-color: transparent transparent #333 transparent;
}
.form-calc__select-container:after {
bottom: 16.5px;
border-width: 4px 3.5px 0 3.5px;
border-color: #333 transparent transparent transparent;
}
.form-calc__select {
font-family: 'Montserrat', Arial, "Helvetica CY", "Nimbus Sans L", sans-serif;
-webkit-appearance: none;
-moz-appearance: none;
text-indent: 1px;
text-overflow: '';
width: 100%;
height: 43px;
line-height: 43px;
border: 1px solid #D9D9D9;
padding: 0 7px;
color: #2C2D2C;
}
.form-calc__select::-ms-expand {
display: none;
}
.form-calc__select option {
padding: 3px 7px;
border: none;
}
.form-calc__result {
font-size: 36px;
font-weight: 500;
color: #3E3F3E;
line-height: 1.4;
margin-bottom: 6px;
}
.form-calc__result-subtext {
font-size: 12px;
text-transform: uppercase;
color: #3E3F3E;
letter-spacing: .6px;
line-height: 1.25;
}
.form-calc__submit {
font-family: 'Montserrat', Arial, "Helvetica CY", "Nimbus Sans L", sans-serif;
display: inline-block;
vertical-align: top;
color: #fff;
text-align: center;
min-width: 170px;
padding: 14px 20px;
background: #42BF8D;
text-transform: uppercase;
text-decoration: none;
border: none;
letter-spacing: 0.5px;
font-size: 12px;
cursor: pointer;
-webkit-transition: .3s;
transition: .3s;
}
.form-calc__submit:hover,
.form-calc__submit:focus,
.form-calc__submit:active {
color: #fff;
background: #2F8B66;
}
.form-calc__submit:focus {
box-shadow: inset 0 0 6px rgba(0, 0, 0, .25);
}
<link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,500,600,700&subset=latin-ext" rel="stylesheet">
<form action="#" method="post" class="form-calc" autocomplete="off">
<div class="form-calc__item">
<label for="selectHowManyTrees" class="form-calc__label">How many trees?</label>
<div class="form-calc__select-container">
<select name="select1" id="selectHowManyTrees" class="form-calc__select">
<option value="1" selected>1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
</div>
</div>
<div class="form-calc__item">
<label for="selectApproximateHeightTree" class="form-calc__label">What is the approximate height of the tree?</label>
<div class="form-calc__select-container">
<select name="select2" id="selectApproximateHeightTree" class="form-calc__select">
<option value="1">1 story house</option>
<option value="2">2 story house</option>
<option value="3">3 story house +</option>
</select>
</div>
</div>
<div class="form-calc__item">
<label for="selectJobType" class="form-calc__label">Job Type?</label>
<div class="form-calc__select-container">
<select name="select3" id="selectJobType" class="form-calc__select">
<option value="-1">Complete tree removal</option>
<option value="1">Tree Removal</option>
<option value="2">Tree Prune</option>
<option value="3">Palm Removal</option>
<option value="4">Palm Prune</option>
<option value="5">Arborist Report</option>
</select>
</div>
</div>
<div class="form-calc__item">
<label for="selectLocationProperty" class="form-calc__label">Trees location on your property?</label>
<div class="form-calc__select-container">
<select name="select4" id="selectLocationProperty" class="form-calc__select">
<option selected>Front Yard</option>
<option value="1">Access via a driveway (wide)</option>
<option value="2">Access via a gate (narrow)</option>
<option value="3">Vacant land</option>
</select>
</div>
</div>
<div class="form-calc__item">
<div class="form-calc__result">$250 - $610</div>
<div class="form-calc__result-subtext">Expected price range in Australia</div>
</div>
<div class="form-calc__item">
<button type="submit" class="form-calc__submit">Request a quote</button>
</div>
</form>
I have a styled-select dropdown menu, and I created it's own .css and .js.
This is what happens when I use only one dropdown menu in a page, which works fine as expected:
jsFiddle OK
Instead when I use two dropdown menu it's a mess, and it's normal, because my .js file will do it's functions to all those dropdown menu which exists on the page. This is how it appears when I use two dropdown menu with the same .js and .css files:
jsFiddle NOT OK
Now my questions is how can I use the same .js and .css files for multiple dropdown's which all of them act as expected?
$(function () {
$('.styled-select select').hide();
$("select#elem").val('2');
$('.styled-select div').html($('.styled-select select option:selected').text());
$('.styled-select div').click(function () {
$('.styled-select select').show();
$('.styled-select select').attr('size', 5);
$('.styled-select select').focus();
});
$('.styled-select select').click(function () {
$('.styled-select div').html($('.styled-select select option:selected').text());
$('.styled-select select').hide();
});
$('.styled-select select').focusout(function () {
$('.styled-select select').hide();
});
});
.styled-select select {
position: absolute;
background: transparent;
width: 420px;
padding-top: 5px;
font-size: 18px;
font-family: 'PT Sans', sans-serif;
color: black;
border: 0;
border-radius: 4;
-webkit-appearance: none;
-moz-appearance: none;
-o-appearance: none;
z-index: 1;
outline: none;
left: -7px;
}
.styled-select {
background: url('../img/campaignSelector.png') no-repeat right;
background-color: white;
width: 420px;
height: 42px;
position: relative;
margin: 0 auto;
box-shadow: 0 2px 2px 0 #C2C2C2;
background-position: 97% 50%;
}
.styled-select option {
font-size: 18px;
background-color: white;
margin-left: 3px;
}
::-webkit-scrollbar {
display: none;
}
<script src="https://code.jquery.com/jquery-1.9.1.js"></script>
<div style="width:800px; height: 600px; background: grey;">
<div class="styled-select" style="left:-250px; top:90px; width:200px;">
<div style="font-size:18px; height:42px; position:relative; top:10px; left: 4px;"></div>
<select id="" name="" style="margin:0 0 0 5px; border: none;" onblur="this.size=0; width:200px;" onchange="this.size=0;">
<option value="0">Marco P</option>
<option value="1">Marco F</option>
<option value="2">Daniele</option>
<option value="3">Cristina</option>
<option value="4">Angine</option>
</select>
</div>
<div class="styled-select" style=" width:200px; left:50px; top:48px;">
<div style="font-size:18px; height:42px; position:relative; top:10px; left: 4px;"></div>
<select id="" name="" style="margin:0 0 0 5px; border: none;" onblur="this.size=0; width:200px;" onchange="this.size=0;">
<option value="0">ReshaD</option>
<option value="1">Rasheed</option>
<option value="2">Reza</option>
<option value="3">Davin</option>
<option value="4">Ariya</option>
</select>
</div>
</div>
To make your code work for multiple instances of the .styled-select container you need to use $(this) to reference the element which is raising the event and then use closest() to get the nearest parent .style-select. From there you can use find() to get the required element. Try this:
$('.styled-select select').hide();
$("select#elem").val('2');
$('.styled-select div').each(function() {
var $container = $(this).closest('.styled-select');
$(this).html($container.find('select option:selected').text());
});
$('.styled-select div').click(function() {
var $container = $(this).closest('.styled-select');
$container.find('select').show().attr('size', 5).focus();
});
$('.styled-select select').click(function() {
var $container = $(this).closest('.styled-select');
var text = $container.find('select option:selected').text();
$container.find('div').html(text);
$container.find('select').hide();
});
$('.styled-select select').focusout(function() {
var $container = $(this).closest('.styled-select');
$container.find('select').hide();
});
Updated fiddle