Show and Hide the text with stars on clicking the button - javascript

I have a paragraph tag with number init. I want to replace the numbers with stars/round circles on clicking the button beside it. Also, I am attaching a screenshot to which I want to apply the concept(on clicking the eye icon the Patient Id should be replaced with round circles and vice versa). Attaching the code which I have tried. Your solutions are very important for me in learning the things. TIA
enter image description here
$('.hide-id').on('click', function () {
$('.patient-id-content').attr('type', 'password');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<p>
<span class="patient-id-content" type="text">34324345</span>
<button class="hide-id">
Hide
</button>
</p>
</div>

Here is what you need.
$(".hide-id").on("click", function () {
var span = $(".patient-id-content");
var spanText = span.text();
if (!spanText.indexOf("*")) {
$(".patient-id-content").text(span.attr("data-oldText"));
return;
}
var starText = "";
for (let i = 0; i < spanText.length; i++) starText += "*";
$(".patient-id-content")
.attr("data-oldText", spanText)
.text(starText);
});
working example on jsfiddle: https://jsfiddle.net/ynojkf0q/

So your jQuery code from the OP was not correct. You have what you want as the password in a span and are applying a type attribute to that.
If you check the MDN Docs, you will learn that there is no type attribute for a span, as spans only support Global Attributes. The input element uses both the type: text and type: password, see the docs here.
But if you want to have the span as your element, you can change your jQuery event handler to the following: .toggleClass('hidden'); and create a hidden CSS class with the properties display: none;
$('.hide-id').on('click', function () {
$('.patient-id-content').toggleClass('hidden');
});
.hidden { display: none;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<p>
<input class="patient-id-content" type="text" value="34324345">
<button class="hide-id">
Hide
</button>
</p>
</div>

This is a simple solution for the functionality you want. It will need more styling to get it to look exactly the the example you provided above.
HTML
<div class="container">
<p>
<input class="patient-id-content" type="password" value="34324345">
<button id="pass-toggle" class="hide-id" onclick="toggleShowPassword()">
Show
</button>
</p>
</div>
JS
let passwordVisible = false;
function toggleShowPassword() {
let inputType = 'password';
passwordVisible = !passwordVisible;
if (passwordVisible) {
inputType = 'text';
$('#pass-toggle').addClass( "show-id" ).text( 'Hide' );
} else {
$('#pass-toggle').removeClass( "show-id" ).text( 'Show' );
}
$('.patient-id-content').attr('type', inputType);
CSS
.patient-id-content {
border: 0;
}

You could do something like:
to have hidden by default:
<span class="patient-id-content" type="text" data-patient-id="34324345" data-visible="false">********</span>
to show by default:
<span class="patient-id-content" type="text" data-patient-id="34324345" data-visible="true">34324345</span>
$('.hide-id').on('click', function () {
const patientId = $(this).prev('span'); // dependent on this DOM placement
const patientIdValue = patientId.attr('data-patient-id');
const isShowing = patientId.data('visible');
const valueToShow = isShowing ? '********' : patientIdValue;
patientId.text(valueToShow);
patientId.data('visible', !isShowing)
});
Included a JS Fiddle: https://jsfiddle.net/w7shxztp/20/

I have fixed the issue with the below solution:
$(".icofont-eye").on("click", function() {
$('#Patient-id-icon-element').toggleClass('icofont-eye-blocked');
$('#Patient-id-icon-element').toggleClass('icofont-eye');
var patientIdcontent = $(".patient-id-content");
var patientIdcontentText = patientIdcontent.text();
if (patientIdcontentText.indexOf("*")) {
$(".patient-id-content").text('***************');
} else {
$(".patient-id-content").text('3d4532403d453240');
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row mt-1">
<div class="col-4 text-right mychart-label">Patient ID</div>
<div class="col-8 section-content">
<span class="patient-id-content">****************</span> <span class="patient-id-icon">
<a class="icofont icofont-eye cl-icon-1-point-3x mt-1" id="Patient-id-icon-element" type="button">Show</a>
</span>
</div>
</div>

Related

how do i run a javascript function that can interchange text from two different divs?

so i am building a defi app. it has three divs at the top and a table below(there is a main div which is larger than the other 2). i want to make so when i click on one div it becomes the main div and all the text from the large one switches to one of the smaller box. so far i can only move text from div 1 to div 2 but cant figure out how to move text from div 2 to div 1 in the same onclick event. please help.
<div class="row stats-row border rounded">
<div class="col-8 stats1" id="stats1">
<div class="stats1-title-amount" id="stats1-title-amount">
<div class="stats1-title">
Total Volume
</div>
<div class="stats1-amount">
$20,000,000
</div>
</div>
</div>
<div class="col-4">
<div class="row stats2a border rounded" id="stats2a">
<div class="stats2a-title-amount" id="stats2a-title-amount">
<div class="stats2-title">
Total gains
</div>
<div class="stats2-amount">
15%
</div>
</div>
</div>
<div class="row stats2b border" id="stats2b">
<div class="stats2b-title-amount" id="stats2b-title-amount">
<div class="stats2-title">
Total Volume Traded
</div>
<div class="stats2-amount">
$1,500,560
</div>
</div>
</div>
</div>
</div>
document.getElementById('stats2a').addEventListener('click', function(){
changePage1();
changePage2();
});
function changePage1 () {
document.body.style.background = 'red';
document.getElementById('stats1-title-amount').innerText = document.getElementById('stats2a-title-amount').innerText;
}
function changePage2 () {
document.body.style.background = 'red';
document.getElementById('stats2a-title-amount').innerText = document.getElementById('stats1-title-amount').innerText;
}
Use this:
document.getElementById('stats2a').addEventListener('click', function(){
const page1 = getpage1text();
const page2 = getpage2text();
changePage1(page2);
changePage2(page1);
});
function getpage1text(){
return(document.getElementById('stats1-title-amount').innerText);
}
function getpage2text(){
return(document.getElementById('stats2a-title-amount').innerText);
}
function changePage1 (text) {
document.body.style.background = 'red';
document.getElementById('stats1-title-amount').innerText = text;
}
function changePage2 (text) {
document.body.style.background = 'red';
document.getElementById('stats2a-title-amount').innerText = text;
}
document.getElementById('stats2a').addEventListener('click', function(){
let tmp = document.getElementById('stats1-title-amount').innerText;
document.getElementById('stats1-title-amount').innerText = document.getElementById('stats2a-title-amount').innerText;
document.getElementById('stats2a-title-amount').innerText = tmp;
document.body.style.background = 'red';
});
The problem you had is that you set the value of stats1 to the value stats2, and after that you set stats2 to stats1. These run one after each, you cannot run them at the same time, so in the second assignment the stats2 is already overwritten by the first assignment, so you have to store one of the values in a variable temporarily.
you can just define visibiliy for each div instead of moving content :
var visible = true;
function(){
document.getElementById('div1').style.visibility = visible ? 'hidden' : 'visible'; // use short if/else to decide which value to user
document.getElementById('div2').style.visibility = visible ? 'visible' : 'hidden'; // short if/else is called ternairy
visible = !visible; // reverse the value of itself
}

How to separete div blocks with the same class but diffent features

Good day!
I have a pop-up section. There are 2 div blocks in it with identical structure. The idea is to have 2 buttons (one is to edit a profile the other is to create a new card with some info) that will call this pop-up, but i need to track which one is called. The popup itself has a darker background compare to main page and a form. I have thought of a modifier popup__container_type_(edit/create) that has a display: none command so when i toggle it it the popup would appear with the right form. Most likely my logic was mistaken. I dont know how to distiguish them (div blocks) correctly.
Another problem is that closebutton seems to work for one form only.
Any help would be great!
HTML:
<section class="popup">
<div class="popup__container popup__container_type_edit">
<button type="button" class="popup__cancelbutton"></button>
<form class="popup-form" name="form">
<h2 class="popup-form__title">Header 1</h2>
<input type="text" class="popup-form__input popup-form__input_type_name" name="name">
<input type="text" class="popup-form__input popup-form__input_type_job" name="job">
<button type="submit" class="popup-form__savebutton">Save</button>
</form>
</div>
<div class="popup__container popup__container_type_create">
<button type="button" class="popup__cancelbutton"></button>
<form class="popup-form" name="form">
<h2 class="popup-form__title">Header 2</h2>
<input type="text" class="popup-form__input popup-form__input_type_place" placeholder="Name of the place" name="place">
<input type="text" class="popup-form__input popup-form__input_type_imagelink" placeholder="Image link" name="imagelink">
<button type="submit" class="popup-form__savebutton">Create</button>
</form>
</div>
</section>
JS:
let popUpSection = document.querySelector(`.popup`);
let cancelButton = popUpSection.querySelector(`.popup__cancelbutton`);
let popUpContainer = popUpSection.querySelector(`.popup__container`);
let formElement = popUpSection.querySelector(`.popup-form`);
let newInputName = popUpSection.querySelector(`.popup-form__input_type_name`);
let newInputJob = popUpSection.querySelector(`.popup-form__input_type_job`);
let inputName = document.querySelector(`.profile-info__title`);
let inputJob = document.querySelector(`.profile-info__text`);
let editButton = document.querySelector(`.profile-info__editbutton`);
let createButton = document.querySelector(`.profile__addbutton`);
//Open / close popup section
let formTogglePopUp = () => {
if (!popUpSection.classList.contains(`popup_acitve`)){
//Autofill
newInputName.value = inputName.textContent;
newInputJob.value = inputJob.textContent;
}
popUpSection.classList.toggle(`popup_active`);
}
//Save input changes
function popUpFormSaved (event) {
event.preventDefault();
inputName.textContent = newInputName.value;
inputJob.textContent = newInputJob.value;
formTogglePopUp();
}
formElement.addEventListener('submit', popUpFormSaved);
cancelButton.addEventListener('click', formTogglePopUp);
editButton.addEventListener('click', formTogglePopUp);
createButton.addEventListener(`click`, formTogglePopUp);
CSS:
.popup__container
{
display: block; *by default*
}
.popup__container_type_(edit/create)
{
display: none;
}
.popup
{
display:none;
}
.popup__active
{
display: flex;
}
You can do it with js, set ids and use them instead of class, it's more easy.
function popUpEdit() {
document.getElementById("popUp").style.display = "block";
document.getElementById("popUpEdit").style.display = "block";
}
function popUpCreate() {
document.getElementById("popUp").style.display = "block";
document.getElementById("popUpCreate").style.display = "block";
}
#popUp, #popUpEdit, #popUpCreate {
display: none;
}
<div class="smt">
Hello
<button onclick="popUpEdit()">Edit</button>
</div>
<div class="smt">Hello
<button onclick="popUpCreate()">Create</button>
</div>
<section id="popUp">
<div>popUp</div>
<div id="popUpEdit">Edit-popup</div>
<div id="popUpCreate">Create-popup</div>
</section>
Generaly, I do that this way:
const SectionPopUp = document.querySelector('section.popup')
function show(elm)
{
SectionPopUp.classList.toggle('Create','Create'===elm)
SectionPopUp.classList.toggle('Edit','Edit'===elm)
}
section.popup,
section.popup.Edit > div:not(.popup__container_type_edit),
section.popup.Create > div:not(.popup__container_type_create) {
display:none;
}
section.popup.Edit,
section.popup.Create {
display:block;
}
/* cosmetic part, just for testing here */
section.popup > div {
border : 1px solid aqua;
padding : .6em;
margin : 1em;
width : 15em;
}
div.popup__container_type_create {
border-color: orange !important;
}
<button onclick="show('Edit')"> show Edit </button>
<button onclick="show('Create')"> show Create </button>
<button onclick="show('')"> show none </button>
<section class="popup">
<div class="popup__container popup__container_type_edit">
pop-up edit content
</div>
<div class="popup__container popup__container_type_create">
pop-up create content
</div>
</section>

How to change the innerHTML of various divs when clicking on various buttons?

In my web-page I have various buttons (in the class .addbutton). When the first of these is clicked, a <div> appears with a drop-down, from which the user can select any of 2 options (#p1, `#p2), which vary depending on which button was clicked.
When each of these options is clicked, I want it to appear in the <div> that corresponds with the initial .addbutton that was clicked. (e.g if the first .addbutton is clicked (#bradd) I want the options selected in the first div (#bdiv))I managed to do this so that they always appear in the #bdiv, no matter what .addbutton was clicked, but I can't work out how to make each appear in the corresponding one.
JS to set the innerHTML of the 2 options
document.getElementById("bradd").onclick = function() {
document.getElementById("p1").innerHTML = "Cereal"
document.getElementById("p2").innerHTML = "Juice"
}
document.getElementById("mmadd").onclick = function() {
document.getElementById("p1").innerHTML = "2x small fruit"
document.getElementById("p2").innerHTML = "Big fruit"
}
JS to change the innerHTML of the first div (#bdiv)
document.getElementById("p1").onclick = function() {
var newItem = document.createElement("div")
newItem.innerHTML = document.getElementById("p1").innerHTML document.getElementById("bdiv").appendChild(newItem)
}
document.getElementById("p2").onclick = function() {
var newItem = document.createElement("div")
newItem.innerHTML = document.getElementById("p2").innerHTML
document.getElementById("bdiv").appendChild(newItem)
}
My HTML:
<h1>Meal Plan Customizer</h1>
<div id="list">
<input type="checkbox">
<p>Breakfast:</p>
<button class="addbutton" id="bradd">+</button>
<div id="bdiv"></div>
<br>
<input type="checkbox">
<p>Mid-Morning:</p>
<button class="addbutton" id="mmadd">+</button>
<div id="mdiv"></div>
<br>
<input type="checkbox">
<div id="dropdownList">
<p id="p1">Option1</p><br><br>
<p id="p2">Option2</p><br><br>
</div>
</div>
</div>
Your code should work.
Please check this:
https://jsfiddle.net/oliverdev/3wsfgov1/
If your code is not working, it is because Javascript code is loaded before loading the HTML.
You can modify the Javascript code like this:
window.onload = function(e){
document.getElementById("bradd").onclick = function() {
document.getElementById("p1").innerHTML = "Cereal"
document.getElementById("p2").innerHTML = "Juice"
}
document.getElementById("mmadd").onclick = function() {
document.getElementById("p1").innerHTML = "2x small fruit"
document.getElementById("p2").innerHTML = "Big fruit"
}
}
It will work for you
You are making this far more complicated and repetitive than necessary.
By storing your data in a structured object and using classes for the content elements you can make generic event listeners for all of this
Following is by no means complete but will give you a good idea how to approach something like this
var data = {
bradd: {
p1: "Cereal",
p2: "Juice"
},
mmadd: {
p1: "2x small fruit",
p2: "Big fruit"
}
}
var selectedButton = null;
var opts = document.querySelectorAll('#dropdownList p');
for (let p of opts) {
p.addEventListener('click', updateContent)
}
// generic event handler for all the options
function updateContent() {
const content = selectedButton.closest('.item').querySelector('.content')
content.innerHTML = this.innerHTML
togglePopup()
}
document.querySelector('#xbutton').addEventListener('click', togglePopup)
// generic event handler for all buttons
function addButtonClicked() {
selectedButton = this;// store selected for use when option selected
var wantedData = data[selectedButton.id];
for (let p of opts) {
p.innerHTML = wantedData[p.id]
}
togglePopup();
}
for (let btn of document.getElementsByClassName("addbutton")) {
btn.addEventListener("click", addButtonClicked)
}
function togglePopup() {
var popStyle = document.getElementById("addPopUp").style;
popStyle.display = popStyle.display === "block" ? 'none' : 'block'
}
#addPopUp {
display: none
}
<h1>Meal Plan Customizer</h1>
<div id="list">
<div class="item">
<p>Breakfast:</p>
<button class="addbutton" id="bradd">+</button>
<div class="content"></div>
</div>
<div class="item">
<p>Mid-Morning:</p>
<button class="addbutton" id="mmadd">+</button>
<div class="content"></div>
</div>
</div>
<div id="addPopUp">
<h3 id="h3">Select what you would like to add:</h3>
<span id="xbutton"><strong>×</strong></span>
<div class="dropdown">
<div id="dropdownList">
<p id="p1">Option1</p>
<p id="p2">Option2</p>
<!-- <p id="p3">Option3</p><br><br>
<p id="p4">Option4</p>-->
</div>
</div>
</div>

How to add and remove a class to a div element plain javascript

I am trying to add different classes to a div based on what is clicked, which I've managed to do, but need to remove the previously clicked/selected class and replace with the clicked one, Can't seem to get the remove part right. Most of the solutions I've come across are either toggles or adding and removing between two classes, but not 3 or more.
Thanks
This is what I have tried so far and the add part works as expected but when I click a different button it does not remove the previous clicked one
The HTML
<button id="btn-1" data-width="w-1/3">Mobile</button>
<button id="btn-2" data-width="w-2/3">Tablet</button>
<button id="btn-3" data-width="w-full">Desktop</button>
<div class="frame">
Some Content
</div>
The Javascript
let setMobile = document.querySelector('#btn-1');
let setTablet = document.querySelector('#btn-2');
let setDesktop = document.querySelector('#btn-3');
let btns = [setMobile, setTablet, setDesktop];
function getBtnId(btn) {
btn.addEventListener('click', function() {
let frame = document.querySelector('.frame')
frame.classList.add(this.dataset.width)
if(frame.classList.contains(btns)){
frame.classList.remove(this.dataset.width)
}
console.log(this.dataset.width);
});
}
btns.forEach(getBtnId);
Basically, what I am trying to do is a responsive frame which will adjust its width depending on what is clicked.
You can store the current class in a variable and use the remove() to remove the previous class on each click.
let setMobile = document.querySelector('#btn-1');
let setTablet = document.querySelector('#btn-2');
let setDesktop = document.querySelector('#btn-3');
let btns = [setMobile, setTablet, setDesktop];
var currentClass;
function getBtnId(btn) {
btn.addEventListener('click', function() {
let frame = document.querySelector('.frame')
if (currentClass) {
frame.classList.remove(currentClass);
}
currentClass = this.dataset.width;
frame.classList.add(currentClass);
console.log(this.dataset.width);
});
}
btns.forEach(getBtnId);
<button id="btn-1" data-width="w-1/3">Mobile</button>
<button id="btn-2" data-width="w-2/3">Tablet</button>
<button id="btn-3" data-width="w-full">Desktop</button>
<div class="frame">
Some Content
</div>
Here's a generalized version to work with multiple elements. I've wrapped each frame and buttons in a section element. Then I've bound the event listeners to the sections and used event bubbling / event delegation to perform the switch. I've also used a data attribute on the target frame to hold the current state.
function setWidthClass(event) {
var newWidth = event.target.dataset.width;
//This identifies a button click with our dataset
if (newWidth) {
//get the target div
var target = this.querySelector(".frame");
//if the target has a class set remove it
if (target.dataset.width) {
target.classList.remove(target.dataset.width);
}
//Add the new class
target.classList.add(newWidth);
//Update the data on the target element
target.dataset.width = newWidth;
}
}
//Add the event listener
var sections = document.querySelectorAll(".varyWidth");
for (var i = 0; i < sections.length; i++) {
sections[i].addEventListener("click", setWidthClass);
}
.w-third {
color: red;
}
.w-half {
color: blue;
}
.w-full {
color: green;
}
<section class="varyWidth">
<button data-width="w-third">Mobile</button>
<button data-width="w-half">Tablet</button>
<button data-width="w-full">Desktop</button>
<div class="frame">
Some Content
</div>
</section>
<section class="varyWidth">
<button data-width="w-third">Mobile</button>
<button data-width="w-half">Tablet</button>
<button data-width="w-full">Desktop</button>
<div class="frame">
Some Content
</div>
</section>
<section class="varyWidth">
<button data-width="w-third">Mobile</button>
<button data-width="w-half">Tablet</button>
<button data-width="w-full">Desktop</button>
<div class="frame">
Some Content
</div>
</section>
Rather than track the current class, you can also just reset it:
let setMobile = document.querySelector('#btn-1');
let setTablet = document.querySelector('#btn-2');
let setDesktop = document.querySelector('#btn-3');
let btns = [setMobile, setTablet, setDesktop];
function getBtnId(btn) {
btn.addEventListener('click', function() {
let frame = document.querySelector('.frame')
// reset the classList
frame.classList = ["frame"];
frame.classList.add(this.dataset.width)
console.log(this.dataset.width);
});
}
btns.forEach(getBtnId);
<button id="btn-1" data-width="w-1/3">Mobile</button>
<button id="btn-2" data-width="w-2/3">Tablet</button>
<button id="btn-3" data-width="w-full">Desktop</button>
<div class="frame">
Some Content
</div>

event.target.matches() having problem with children

Okay so I'm making a dropdown for my social media website, and I wanted to add a slider button:
<div class = \"dropdown\">
<img id = \"navPFP\" style = \"margin-top: 2px;margin-left:20px; margin-right: 20px;\" class = \"pfp\" width = \"30\" height = \"30\" src=\"$pfpNAV\" alt=\"$userNAV's pfp\">
<div id = \"dropdown\" class = \"dropdown-content\">
<div id = \"names\" style = \"border-bottom: thin solid #BDBDBD;\">
<h2>$fnNAV $lnNAV</h2>
<p style = \"color:grey;margin-top:-40px;\">#$userNAV</p>
</div>
<div id = \"settings\" style = \"border-bottom: thin solid #BDBDBD;\">
Accout Settings
</div>
<label class = \"switch\">
<input type = \"checkbox\">
<span class = \"slider round\"></span>
</label>
Log out #$userNAV
Reset password #$userNAV
</div>
Problem is: unless it is just the #dropdown div, not any children, when you click it the dropdown closes
I have the following JS code to close the dropdown when anything other than the dropdown content is clicked:
window.onclick = function(event) {
if (!event.target.matches('#dropdown') && !event.target.matches('#navPFP')) {
var dropdowns = document.getElementsByClassName("dropdown-content");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}
}
Even if I add a && !event.target.matches('.switch') (or any of the other div ids) to the if statement, the dropdown still closes when the slider is clicked. How can I fix this so that the dropdown stays open?
Instead of matches(), use closest():
if (!event.target.closest('#dropdown')) {
// target is neither #dropdown or one of its descendants; close the dropdown
}
element.closest('#dropdown') starts at element and walks upward through the DOM looking for #dropdown. If closest() finds #dropdown, it returns it, and element must be a child of #dropdown. If not, it returns null, and element must be outside #dropdown.
Recently, I have the same problem with event.target.matches().
Apart from using event.target.closest(), you can set the pointer-events CSS property to none.
document.querySelector("#container").addEventListener("click", (event) => {
if (event.target.matches(".click-here")) {
console.log("You clicked inside 'click-here' div.");
const result = document.querySelector("#result");
result.innerText = "You clicked inside 'click-here' div.";
}
})
.no-click {
pointer-events: none;
}
<div id="container">
<div class="click-here">
<div class="no-click">
<div>div1</div>
<div>
<div>nested</div>
</div>
<p>text</p>
</div>
</div>
</div>
<div id="result">
</div>

Categories