I'm trying to animate a chat. Every time the user clicks on the input field or "send" icon, I want the chat bubbles to appear one after the other. This is my part of my code so far. Right now, they all have "display: none." The picture below shows them without it.
<div class="messages">
<div class="message" id="msg1" style="display: none;">Hi! I'm looking for an old friend. She attended Martin Grove a few years ago.</div>
<div class="message" id="msg2" style="display: none;">Her name is Sam.<br>
<i>*insert pic of Sam and MC*</i></div>
<div class="message" id="msg3" style="display: none;">Did you know her or her last name by any chance? </div>
<div id="msg4" class="message-teacher" style="display: none;">Hello there!</div>
<div class="message-teacher" id="msg5" style="display: none;">Unfortunately, I did not have the pleasure of teaching Sam. Her last name and whereabouts are a mystery to me as well. </div>
<div class="message-teacher" id="msg6" style="display: none;">However, I do know she was in the photography club. I always saw her carrying a camera, always taking pictures. </div>
<div class="message-teacher" id="msg7" style="display: none;">In fact, I believe she won a contest for one of them. </div>
<div class="message-teacher" id="msg8" style="display: none;">She’s a super talented girl!</div>
<div class="message-teacher" id="msg9" style="display: none;">Best of luck on your search. I hope you two are reunited soon!</div>
</div>
<div class="input">
<div class="plus-icon" style="font-size: 25px; color: #2A84FF; margin: auto;">
<i class="fas fa-plus-circle"></i>
</div>
<div class="subinput" style="font-size: 25px; color: #2A84FF; margin: auto;">
<input type="text" placeholder="|" />
<i class="fas fa-smile"></i>
</div>
<div class="btn" style="font-size: 23px; color: #2A84FF; margin: auto;"><i class="fas fa-paper-plane"></i></div>
</div>
I would query for the required elements, create an array out of it, and shift() (aka remove the first element of the array - or you can use pop() to remove the last element, depending on your needs). When you pop or shift an element from an array, those functions return the removed element and we can remove the CSS class that hides those elements in the DOM.
const myHTMLCollection = document.getElementsByClassName("invisible");
const HTMLElementsArr = [...myHTMLCollection];
function showMessage() {
if (HTMLElementsArr.length > 0) {
HTMLElementsArr.shift().classList.remove('invisible');
}
}
.invisible {
display: none;
}
<p class="invisible">Some text 1 click</p>
<p class="invisible">Some text 2 clicks</p>
<p class="invisible">Some text 3 clicks</p>
<button onClick="showMessage()">Show a message</button>
Related
I have multiple div which has the same class and I want to display only one div per click which belongs to the parent div. I want to hide and show div "post-reply-box".
HTML
<div class="comet-avatar">
<img src="images/resources/comet-3.jpg" alt="">
</div>
<div class="we-comment">
<div class="coment-head">
<h5>Olivia</h5>
<span>16 days ago</span>
<a class="we-reply" href="javascript:void(0)" title="Reply"><i class="fa fa-reply"></i></a>
<ins>280</ins>
</span>
</div>
<p>i like lexus cars, lexus cars are most beautiful with the awesome features, but this car is really outstanding than lexus</p> </div>
<div class="comnt comnt-reply">
<div class="post-reply-box" style="padding:10px; display: none;">
<form method="post">
<textarea placeholder="You are Replying..."></textarea>
<button class="replyButton" type="submit">send</button>
<button class="cancelButton">cancel</button>
</form>
</div>
</div>
jQuery
$(document).ready(function(){
$(".fa-reply").on("click",function(){
$(".post-reply-box").css("display","block");
});
});
$(document).ready(function(){
$(".cancelButton").on("click",function(){
$(".post-reply-box").css("display","none");
});
});
The issue in your code is because you're using a class selector which retrieves all the .post-reply-box elements in the DOM, not just the one relevant to the button which was clicked.
To fix this use DOM traversal to relate the elements to each other. In this specific example use closest() to get the .we-comment related to the button, then next() to get the .comnt-reply container, then find().
In addition there some other issues which need to be addressed:
There's no need to duplicate document.ready handlers. Put all the logic in a single one.
Use show() and hide() instead of css() to set the display state of the element.
Use a CSS file instead of inline style elements to set style rules.
Attach the event handler to the a element, not the child i, and call preventDefault() on the event that's raised.
Add the type="button" attribute to the Cancel button so that clicking it does not submit the form.
With all that said, try this:
jQuery($ => { // updated document.ready handler
$(".we-reply").on("click", e => {
e.preventDefault()
$('.post-reply-box').hide(); // hide all
$(e.target).closest('.we-comment').next('.comnt-reply').find(".post-reply-box").show(); // show relevant
});
$(".cancelButton").on("click", function() {
$(".post-reply-box").hide();
});
});
.post-reply-box {
padding: 10px;
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="comet-avatar">
<img src="images/resources/comet-3.jpg" alt="">
</div>
<div class="we-comment">
<div class="coment-head">
<h5>Olivia</h5>
<span>16 days ago</span>
<a class="we-reply" href="javascript:void(0)" title="Reply"><i class="fa fa-reply"></i> Reply</a>
<span class="like-comment" data-toggle="tooltip" title="like">
<i class="ti-heart"></i>
<ins>280</ins>
</span>
</div>
<p>i like lexus cars, lexus cars are most beautiful with the awesome features, but this car is really outstanding than lexus</p>
</div>
<div class="comnt comnt-reply">
<div class="post-reply-box">
<form method="post">
<textarea placeholder="You are Replying..."></textarea>
<button class="replyButton" type="submit">send</button>
<button class="cancelButton" type="button">cancel</button>
</form>
</div>
</div>
<div class="comet-avatar">
<img src="images/resources/comet-3.jpg" alt="">
</div>
<div class="we-comment">
<div class="coment-head">
<h5>Olivia</h5>
<span>16 days ago</span>
<a class="we-reply" href="javascript:void(0)" title="Reply"><i class="fa fa-reply"></i> Reply</a>
<span class="like-comment" data-toggle="tooltip" title="like">
<i class="ti-heart"></i>
<ins>280</ins>
</span>
</div>
<p>i like lexus cars, lexus cars are most beautiful with the awesome features, but this car is really outstanding than lexus</p>
</div>
<div class="comnt comnt-reply">
<div class="post-reply-box">
<form method="post">
<textarea placeholder="You are Replying..."></textarea>
<button class="replyButton" type="submit">send</button>
<button class="cancelButton" type="button">cancel</button>
</form>
</div>
</div>
I've looked everywhere on StackOverflow and there doesn't seem to be anyone else solving this issue or I'm just using the wrong wording or keywords which results in me not finding what I want. If that's the case and this is a duplicate, I would be glad if you could link me to a case like this. Thanks.
I have an HTML/CSS, AngularJS, PHP and MySQL project.
POST and GET requests work perfectly.
What I'm trying to do is similar to what is already done on Google Keep.
When the user clicks on the blue pencil, I want the opacity on the selected item to be 100% but all the parents divs and sibling divs at opacity value 0.3 or something.
I would like to try and avoid jQuery if possible.
I believe I read somewhere that it is bad practice to use a whole bunch of frameworks together and that when you use a framework, that you should stick with it.
I have no idea how to approach this problem.
I don't even know where to start.
Could you please also provide me with a working example JSFiddle or Plnkr please?
Any help or suggestion would be greatly appreciated!
Thanks in advance!
What I want
What I have
HTML
<body ng-app="myApp">
<font face="Source Sans Pro">
<div class="left">
<center>
<div ng-controller="insertController">
<h2> What I learned today </h2>
<form>
Date <br>
<input type="text" ng-model="date"><br><br>
Content <br>
<textarea rows="10" cols="50" ng-model="content"></textarea><br><br>
<input type="button" value="Submit" ng-click="insertdata()">
</form>
</div>
</center>
</div>
<div class="right">
<center>
<div ng-controller="fetchController"><br>
<span ng-repeat="item in results">
<div class="card">
<div class="theText">
<span class="bold-underline">{{item.date}}</span><br>
{{item.content}}
</div>
<div ng-controller="deleteController">
<input type="button" class="deleteButton" ng-click="deleteThisItem(item)" value="x">
</div>
<div ng-controller="editController">
<input type="button" class="editButton" ng-click="editThisItem(item)" value="✎">
</div>
</div>
<br><br>
</span>
</div>
</center>
</div>
</font>
</body>
EDIT
I just got it working.
New HTML
<div class="right">
<center>
<div ng-controller="fetchController"><br>
<span ng-repeat="item in results">
<div ng-controller="fadeController">
<div class="card" ng-class="cardFade">
<div class="theText">
<span class="bold-underline">{{item.date}}</span><br>
{{item.content}}
</div><!-- theText -->
<div ng-controller="deleteController">
<input type="button" class="deleteButton" ng-click="deleteThisItem(item)" value="x">
</div><!-- deleteController -->
<div ng-controller="editController">
<input type="button" class="editButton" ng-click="editThisItem(item)" value="✎">
</div><!-- editController -->
</div><!-- card -->
</div><!-- fadeController -->
<br>
</span><!-- ng-repeat -->
<div class="overlay"></div>
</div><!-- fetchController -->
</center>
</div><!-- right -->
New CSS
.someCSS {
background-color: white;
z-index: 200;
opacity: 1;
}
.noCSS {
}
.overlay {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: black;
opacity: 0.6;
z-index: 100;
pointer-events: none; /* required to be able to click buttons under overlay */
}
fadeController.js
app.controller("fadeController", function($scope, $http, resultsService) {
$scope.cardFade = "noCSS";
$scope.editThisItem = function(item) {
if($scope.cardFade === "noCSS") {
$scope.cardFade = "someCSS";
}
else if($scope.cardFade === "someCSS") {
$scope.cardFade = "noCSS";
}
else {
alert("FATAL ERROR!");
}
};
});
you can add a div as overlay
<div class="overlay"></div>
.overlay {
backgound-color: gray;
opacity: 0.5;
z-index: 100; //<= so the overlay with cover the page
}
next you will need to add a css class like this
.someCss {
z-index: 101; // <=so it would be on top on the overlay
}
and it will be added to the ng-repeat element when you click on the blue pencil.
I would even go and make the class as ng-class ng-class
so it would be something like this:
<span ng-repeat="item in results">
<div class="card" ng-class="{someCss : item.selected}">
<div class="theText">
<span class="bold-underline">{{item.date}}</span><br>
{{item.content}}
</div>
<div ng-controller="deleteController">
<input type="button" class="deleteButton" ng-click="deleteThisItem(item)" value="x">
</div>
<div ng-controller="editController">
<input type="button" class="editButton" ng-click="editThisItem(item)" value="✎">
</div>
</div>
<br><br>
</span>
and now on the blue pencil click you can add the property selected or change it
I'm trying to learn JS and jQuery and I'm using a project to do this. I've been scratching my head for the last 4 hours trying to figure out how to do something and I'm completely stuck.
Basically I want to update a div's content based on clicks from other div's using HTML data- attributes on the ".blue". I have price and description fields. I have managed to collect the data from the first div no matter where I click but then can't get this updated correctly based on the DIV I click in.
I've tried multiple combinations of $(this) keyword to try and make this work but couldn't figure it out. I've searched these forums and found somewhat a solution but couldn't get it, I think my mind is just too overwhelmed with this.
Here's the one I looked at: Update content in div, on click of another div
I'm sure this must be super simple but I can't get my head around it today.
Here's my code:
var upload = $('.blue').data('target1');
var download = $('.blue').data('target2');
var price = $(this).data('price');
$(document).ready(function() {
$('.blue').on('click', function() {
$(upload).removeClass('hide');
$(download).removeClass('hide');
});
$('#price').text(price);
});
div {
margin:0;
padding:0;
}
.blue {
background-color: #ddddEE;
border: 1px solid black;
}
.blue:hover {
cursor: pointer;
background-color: #aaaaEE;
}
.red {
background-color: #EEdddd;
border: 1px solid black;
}
.bold {
font-weight: 600;
text-align: center;
}
.hide {
display:none;
}
#price {
font-size: 22px;
color: blue;
font-weight: 400;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="col-xs-3">
<div class="col-xs-12 blue" data-target1="#target1" data-target2="#target2">
<span>$</span><span data-price="300" id="1">300</span><br>
<p id="desc1" class="hide">Description 1</p>
<span>text here</span><br>
<span>text here</span><br>
<span>text here</span>
</div>
</div>
<div class="col-xs-3">
<div class="col-xs-12 blue" data-target1="#target3" data-target2="#target4">
<span>$</span><span data-price="600" id="2">600</span><br>
<p id="desc2" class="hide">Description 2</p>
<span>text here</span><br>
<span>text here</span><br>
<span>text here</span>
</div>
</div><div class="col-xs-3">
<div class="col-xs-12 blue" data-target1="#target5" data-target2="#target6">
<span>$</span><span class="prices" data-price="1200" id="3">1200</span><br>
<p id="desc3" class="hide">Description 3</p>
<span>text here</span><br>
<span>text here</span><br>
<span>text here</span>
</div>
</div>
<div class="col-xs-3">
<div class="col-xs-12 red">
<span class="bold">Summary</span><br>
<div id="target1" class="hide"><span>TARGET 1</span></div>
<div id="target2" class="hide"><span>TARGET 2</span></div>.
<div id="target3" class="hide"><span>TARGET 3</span></div>
<div id="target4" class="hide"><span>TARGET 4</span></div>
<div id="target5" class="hide"><span>TARGET 5</span></div>
<div id="target6" class="hide"><span>TARGET 6</span></div>
<span id="price" class=""></span>
</div>
</div>
Here is my fiddle: https://jsfiddle.net/rodcunha/qav9sn6n/42/
Thank you in advance for any help for this newbie.
To understand the cause of your problem, and how to solve it, you have to be careful in the present case of when the various instructions you've written are evaluated, and also how some of the jQuery instructions you use work.
First thing to note: the first three lines of your Javascript code are evaluated just after they have been read. So after they are evaluated, the state of your variables is as follows :
upload = '#target1'
download = '#target2'
price = undefined
Since these are the values used in the rest of the code, in all cases, you can see why it always shows what you expect for the first <div> only. To understand why, let's analyze the first line :
var upload =
$('.blue') [1]
.data('target1') [2]
[1] returns the jQuery collection containing the DOM <div> elements that have the blue class. So far, so good?
[2] returns the value associated with the data-target1 attribute of the first element of the jQuery collection (see documentation for the .data method)
What you probably want is for upload, download and price to contain the values of the data-* attributes corresponding to the <div> the user clicks on. You cannot know in advance which element the user will click on, so it does not make sense to read the values before the user clicks on anything. So you should read the values when the event is processed.
According to jQuery's documentation for the event handlers, this is the element the event is currently associated with. So your <div> element.
Now that you know that, you probably realized what you should do to correct your code. By moving your existing code around and making the smallest changes possible, you end up with the following working code.
$(document).ready(function() {
$('.blue').on('click', function() {
var upload = $(this).data('target1');
$(upload).removeClass('hide');
var download = $(this).data('target2');
$(download).removeClass('hide');
var price = $(this).find('[data-price]').data('price');
$('#price').text(price);
});
});
I'm not sure is this the behaviour you want, can you check it?
https://jsfiddle.net/rodcunha/qav9sn6n/42/
$(document).ready(function() {
$('.blue').click(function() {
var x = $(this).attr('data-target1');
$(x).removeClass('hide');
});
$('#price').text(price);
});
if You want to add or remove class hide clicking again on the div you can change the removeClass to toggleClass.
Replace you code by:
$(document).ready(function() {
$('.blue').on('click', function(e) {
$($(e.currentTarget).data('target1')).removeClass('hide');
$($(e.currentTarget).data('target2')).removeClass('hide');
$('#price').text($(e.target).parent().find('.price').data('price'));
});
});
Add a price class for every span data-price.
<span>$</span><span class="price" data-price="300" id="1">300</span><br>
HTML:
<div class="col-xs-3">
<div class="col-xs-12 blue" data-target1="#target1" data-target2="#target2">
<span>$</span><span class="price" data-price="300" id="1">300</span><br>
<p id="desc1" class="hide">Description 1</p>
<span>text here</span><br>
</div>
</div>
<div class="col-xs-3">
<div class="col-xs-12 blue" data-target1="#target3" data-target2="#target4">
<span>$</span><span class="price" data-price="600" id="2">600</span><br>
<p id="desc2" class="hide">Description 2</p>
<span>text here</span><br>
</div>
</div>
<div class="col-xs-3">
<div class="col-xs-12 blue" data-target1="#target5" data-target2="#target6">
<span>$</span><span class="prices price" data-price="1200" id="3">1200</span><br>
<p id="desc3" class="hide">Description 3</p>
<span>text here</span><br>
</div>
</div>
<div class="col-xs-3">
<div class="col-xs-12 red">
<span class="bold">Summary</span><br>
<!-- add 'summary' class for all div -->
<div id="target1" class="hide summary"><span>TARGET 1</span></div>
<div id="target2" class="hide summary"><span>TARGET 2</span></div>
<div id="target3" class="hide summary"><span>TARGET 3</span></div>
<div id="target4" class="hide summary"><span>TARGET 4</span></div>
<div id="target5" class="hide summary"><span>TARGET 5</span></div>
<div id="target6" class="hide summary"><span>TARGET 6</span></div>
<span id="price" class=""></span>
</div>
</div>
To get the current clicked div use currentTarget instead of target because currentTarget always return .blue contains div as event listner is set on '.blue' but target results can be different depending on your click position into .blue class div.
jQuery:
$(document).ready(function() {
$('.blue').on('click', function(e) {
var upload = $(e.currentTarget).data('target1');
var download = $(e.currentTarget).data('target2');
var price = $(e.target).parent().find('.price').data('price');
// add a new class 'summary' for all 'summary id div'.
// loop over all '.summary' class and add 'hide' class
$('.summary').each(function(index, item) {
// console.log(item);
$(item).removeClass('hide').addClass('hide');
});
$(upload).removeClass('hide');
$(download).removeClass('hide');
$('#price').text(price);
});
});
jsfiddle link: https://jsfiddle.net/sajibcse68/qav9sn6n/49/
I'm trying to center an input box on the center of the page. When you click the button "Prices" It should show a text box right under the button centered. Instead, it's showing all the way to the left.
Here is what I have:
<div class="header-content">
<div class="header-content-inner">
<h1 class="text text-primary vintage-retro sr-intro">IFixIT Repair</h1>
<hr class ="sr-intro">
<p style="font-family:Arial;" class ="text sr-intro">Repairs By Students, For Students</p>
Schedule Repair
</div>
Prices
<div id="repair-prices" class="text-center collapse">
<input class="typeahead form-control" name="search" placeholder="Model of Device (i.e. iPhone 6)">
</div>
</div>
With this, I get this result after the button click:
The box is all the way to the left.
Any help would be awesome! If you need to see anything else, let me know. Thanks!
Try using the <center> tag, that may help.
If you are using HTML5, this does not work and you must center using CSS.
Try using add some css in input class. Because when you used form-control class it has display:block property, so that it will take 100% of width.
.typeahead.form-control{
display:inline-block;
width:auto;
min-width:280px;
}
.btn.btn-primary.sr-intro{
margin-bottom:10px;
}
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<div class="header-content text-center">
<div class="header-content-inner ">
<h1 class="text text-primary vintage-retro sr-intro">IFixIT Repair</h1>
<hr class ="sr-intro">
<p style="font-family:Arial;" class ="text sr-intro">Repairs By Students, For Students</p>
Schedule Repair
</div>
Prices
<div id="repair-prices" class="text-center">
<input class="typeahead form-control" name="search" placeholder="Model of Device (i.e. iPhone 6)">
</div>
</div>
I dont know whether is correct, but i have tried your code with fiddle
>>> fiddle demo <<< without form-control class
add this and remove form-control class
.text-center {
text-align: center;
}
your form-control class in search is 100% width, so you cant center it.
I have 7 icons all with the same size. The icons are displayed next to each other using display: inline-block; For the sake of explaining the problem I like to name the icons (A, B, C, D, E, F, and G.)
5 of these icons are viable "ie. (A, B, D, F, G)" and 2 are hidden "(ie. C, E)"
When a user clicks on icon B, I want to hide icon B and show icon C instead. Also, when a user click on icon D I want to hide icon D and show E.
I am able to use show() and hide() to accomplish what I need. however, the problem is in that the gap between the icons as it is not the same size.
In other words, when icon C becomes viable after clicking on icon B the gap/margin between icon A and icon C will show larger than the gap that was between icon A and icon B.
To demonstrate the problem virtually, I created a fiddle page for review
How can I do the show/hide without changing the gaps "margin" between the 2 images?
Below is my html markup "it is also in the fiddle.
<div style="text-align: center; display: block;">
<div style="display: inline-block;">
<div id="icwsButtonPhoneOff"><img class="interaction" id="disconnect" src="http://s13.postimg.org/4i0cnu18z/icws_red.png" alt="Disconnect Call" title="Disconnect Call"></div>
</div>
<div style="display: inline-block;">
<div id="icwsButtonHoldOn"><img class="interaction" id="resume" src="http://s15.postimg.org/fbpwulmcn/icws_hold.png" alt="Resume Call" title="Resume"></div>
</div>
<div style="display: inline-block;">
<div id="icwsButtonHoldOff" style="display: none;"><img class="interaction" id="hold" src="http://s17.postimg.org/jsbh1libf/icws_resume.png" alt="Place On Hold" title="Place On Hold"></div>
</div>
<div style="display: inline-block;">
<div id="icwsButtonMuteOn"><img class="interaction" id="unmute" src="http://s7.postimg.org/mgr5tqqpz/icws_unmute.png" alt="Un-Mute Call" title="Un-Mute Call"></div>
</div>
<div style="display: inline-block;">
<div id="icwsButtonMuteOff" style="display: none;"><img class="interaction" id="mute" src="http://s8.postimg.org/vd71colmp/icws_mute.png" alt="Mute Call" title="Mute Call"></div>
</div>
<div style="display: inline-block;">
<div id="icwsButtonTransferCall"><img class="interaction" id="mute" src="http://s18.postimg.org/n4jxcru3p/icws_transfer.png" alt="Transfer Call" title="Transfer Call"></div>
</div>
<div style="display: inline-block;">
<div id="icwsButtonConferenceCall"><img class="interaction" id="mute" src="http://s8.postimg.org/i42b42bnl/icws_conference.png" alt="Start a Conference With all Parties" title="Start a Conference With all Parties"></div>
</div>
</div>
You are doing the display:none; on the wrong elements. Do the display:none; on the parent elements of the image you want to hide.
For example, instead of :
<div style="display: inline-block;">
<div id="icwsButtonMuteOff" style="display: none;"><img class="interaction" id="mute" src="http://s8.postimg.org/vd71colmp/icws_mute.png" alt="Mute Call" title="Mute Call"></div>
</div>
do:
<div style="display:none;">
<div id="icwsButtonMuteOff"><img class="interaction" id="mute" src="http://s8.postimg.org/vd71colmp/icws_mute.png" alt="Mute Call" title="Mute Call"></div>
</div>
The reason is that all of the blanks spaces and/or line breaks are adding up.
EDIT:
I didn't want to spend much time at all on this fiddle, but look at what i did for the pause icons. Lot less code.
https://jsfiddle.net/grtLd0qk/10/
This is because you're show/hide the inner div ( the one with id ) but not the outer one. Just do
$('#icwsButtonHoldOff').click(function() {
$('#icwsButtonHoldOn').parent().show();
$(this).parent().hide();
});
and move style="display:none;" to the outer div will do.
Or even better, you can have only one div and assign a common css class to all 7 icons that set display:inline-block. This way your javascript will just need to toggle the status, no more .parent()