Hide button on outside div tap - javascript

I'm trying to have a button no longer be show when the user isn't interacting with it or it's not the user's focus. I am using react right now in the project
In a desktop setting I accomplish this by saying onmouseleave={this.hideButton} but I'm having a tougher time with the iPad. I've tried onTouchCancel={this.hideButton} but haven't gotten lucky.
I looked at react documentation and see there's a touchTarget list, but I don't see any documentation on how to access these properties, am I going down the right path by looking trying to do it this way?
What I've tried before was having the body element listen with an onClick event and hide the button if it's showing but this didn't work as clicking on the button when it was showing would display the modal that I wanted to appear on button click.
I should also note that this.hideButton just changes a boolean value from true to false.
Any advice?
Note: This is a project for work where we've decided NOT to use jQuery (not my call)
Here is what it looks like currently:
toggleLogoutButton() {
this.setState({
logoutButtonVisible: this.props.shouldShowLogoutButton
&& !this.state.logoutButtonVisible,
});
}
logoutButtonAction() {
this.toggleLogoutButton();
this.props.showModal();
}
hideLogoutButton() {
if (this.state.logoutButtonVisible) {
this.setState({
logoutButtonVisible: false,
});
}
}
render() {
return(
<div className="some-style-1" >
<span
className="some-style-2"
onClick={this.toggleLogoutButton}>{this.props.text}
{this.props.shouldShowLogoutButton && this.caretRender()}
{this.state.logoutButtonVisible &&
<div className="dropmenu show"
onClick={this.logoutButtonAction}
onMouseLeave={this.hideLogoutButton}
onTouchEnd={this.hideLogoutButton}>
Log Out
</div>}
</span>
</div>);
}

Please include more pieces of your code!
In order to diagnose what you need, we need to see what you have already.
First off, change
onMouseLeave={this.hideButton};
to (assuming your button name has id="button-name"),
$('#button-name').onMouseLeave={this.hide()};
Depending on how you want your button to show/hide, I wouldn't suggest using this. Instead, turn the button to disabled=true. If you hide it, it will be gone and will no longer be able to be reached by onMouseEnter.
For example,
$('#button-name').onMouseLeave={this.disabled=true;};
With that said, hiding (and even disabled a button onMouseLeave...) does not make much sense.

Related

Javascript -- Why am I able to show a hidden div, but not hide it?

I'm trying to write a simple function to dynamically show or hide an element. I've written functions like this several times before and have never had an issue...I can't figure out what's going wrong here. I use Javascript to dynamically create the element, and then in the process of creating it and appending it to the page, I also write $(element).css("display", "none") so that it will be hidden on page load.
Now I'm writing an event listener function to display the hidden elements in response to a click event. When I click on the button with this event listener attached to it, the hidden elements DO appear (great!), but then when I click on the box again, they stay on the page. When I console.log out the function, I can see that it's always hitting the show condition and never hitting the hide condition...but I cannot figure out why after spending hours and hours looking at examples and trying different implementations.
To be clear, I did not assign display: none; in the static CSS stylesheet. I added it dynamically in the JS when I created the elements.
// Pass in an array of cards called "filterCards"
const toggleDisplayFilterCards = (filterCards) => {
// Loop through the cards, and for each card, grab the ID tag
for (let card of filterCards) {
card = `#filter-card-container_${card.id}`;
// If "display" style attribute = "none", show the div, else, hide it.
if ($(card).css("display", "none")) {
$(card).css("display", "")
console.log("show");
} else if ($(card).css("display", "")) {
$(card).css("display", "none");
console.log("hide");
}
}
};
Does anyone see a reason why this code would never hit the "hide" condition? I've inspected the element in the console once it's displayed on the page, and confirmed that the style attribute has been changed to "", so when I click the same button, I would expect the function to hit the "hide" condition.
What these two do
$(card).css("display", "none")
$(card).css("display", "")
is they set the style of the card, and then return the jQuery object containing the card. Objects are always truthy in JavaScript, so doing
if ($(card).css("display", "none")) {
doesn't make sense.
You need to retrieve the style (done with a single parameter), then compare it against the possible value.
if ($(card).css("display") === "none") {
...
} else {

Disabling a button via JS if a specific element ID appears on page

I am trying to use JS to change an add to cart button to be disabled if our inventory level (displayed on the front end in a <span>) is "out of stock". This JS is already set up on our site for changing button behaviour for variants (code at the bottom of the post) and so if I can integrate an additional conditional rule using our inventory <span> that would be amazing.
Here's the HTML for when the out of stock message appears:
<span class="LocationNoStock">Currently Sold Out</span>
I honestly have almost zero experience with JS so all I know is that I can look for elements by class name:
(document.getElementsByClassName("LocationNoStock")
Basically I want to add logic that dictates:
if class 'LocationNoStock' exists then disable 'add-to-cart' button
Any help that can be offered would be much appreciated! If it helps, our current JS for modifying the add-to-cart button is as follows - if an additional rule to search for the <span> could be inserted and mimic the behaviour that would be amazing!
updateCartButton: function(evt) {
var variant = evt.variant;
if (variant) {
if (variant.available) {
// Available, enable the submit button and change text
$(selectors.addToCart, this.$container).removeClass(classes.disabled).prop('disabled', false);
$(selectors.addToCartText, this.$container).html(theme.strings.addToCart);
} else {
// Sold out, disable the submit button and change text
$(selectors.addToCart, this.$container).addClass(classes.disabled).prop('disabled', true);
$(selectors.addToCartText, this.$container).html(theme.strings.soldOut);
}
} else {
// The variant doesn't exist, disable submit button
$(selectors.addToCart, this.$container).addClass(classes.disabled).prop('disabled', true);
$(selectors.addToCartText, this.$container).html(theme.strings.unavailable);
}
},
Your using jquery $(...) so you could do the following, look for .LocationNoStock if it's found then disable the .add-to-cart button.
if ($('.LocationNoStock').length) $('.add-to-cart').attr('disabled', 'disabled')
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span class="LocationNoStock">Currently Sold Out</span>
<button type="button" class="add-to-cart">Add to Cart</button>
To disable buttonin javascript on load, can be done by setting attribute of the element
Example :
setAttribute("style","color:red")
In your case you are fetching element using class "add-to-cart" which gives htmlcollection so using index you can access the button element and then using setAttribute function of javascript, can set particular properties.
Try this:
$(document).ready(function(){
if (document.getElementsByClassName("LocationNoStock") != null){
var element = document.getElementsByClassName("add-to-cart");
element[0].setAttribute("disabled", "");
}
});

Material Design Slide Toggle does not have event.StopPropagation, what should I use?

The Slide Toggle in Material Design does not have a stopPropagation event, because the "MdSlideToggle.prototype._onChangeEvent" already calls stopPropagation. What should I be using, instead?
<md-slide-toggle (change)="changeToggle($event, activityType.isActive)" checked="activityType.isActive" value="activityType.activityTypeId" mdTooltip="{{!!activityType.isActive ? 'Active' : 'Inactive'}}" mdTooltipPosition="left"></md-slide-toggle>
public changeToggle(event: MdSlideToggleChange, originalValue){
if (this.hasChange && event.checked !== originalValue){
event.stopPropagation();
//Results in error: [ts] Property 'stopPropagation' does not exist on type 'MdSlideToggleChange'.
} else {
this.hasChange = !this.hasChange;
}
}
I can use a regular event, but that gets an exception saying "event.stopPropagation is not a function".
For the moment, I'm changing that line to:
event.source.checked = !event.checked;
The same is true of event.preventDefault. I need to require the user to save the change, before changing another value on the page, because "business requirements".
Is just changing the value of "checked" back to what it was, the right thing to do? Is there a better way to do this?
"I need to require the user to save the change, before changing
another value on the page"
I know this is off topic, but this pertains to your "business requirements"
If you are saying that the user has to press a separate button in order to confirm the value of the mat-slide-toggle then you should not be using a mat-slide-toggle.
You should be using a checkbox.
mat-slide-toggles are good for 1-off actions, turning a light on or off, not asking if you want the light to be on or off.
Its an action, not a question.
Checkboxes are better suited for questions.

How do I enable arrow navigation on keyboard for a list of Div using jQuery

I am following a tutorial [here][1] to make a Facebook like friend tagging system. But the tutorial lacks the "arrow navigating" capability like Facebook. I would like to figure out how to achieve this.
Basically, when I input text on the contenteditable area, it will generate divs of suggested friends like the following:
<div class="display_box">
<img src="user_img/John.jpg">
John<br>
<span>India</span>
</div>
<div class="display_box">
<img src="user_img/Peter.jpg">
Peter<br>
<span>USA</span>
</div>
<div class="display_box">
<img src="user_img/Mary.jpg>
Mary<br>
<span>UK</span>
</div>
They are all divs with the class name display_box. I can click on the box and select them by:
$('div').on("click",".display_box",function(e) {
// do the stuffs
});
I would like my users to be able to use the keyboard, using key up or key down to navigate between the selections, and use the enter key to trigger the selection. Any ideas how can I make this happen? Many thanks!
You need to bind keyboard events keyup/keydown and then change the css accordingly to give a feel of move up or move down :
use keyup if you want a single move even on a key press no matter the key is long pressed.
use keydown if you want to move in a cycle fashion as long as user holds the key.
$("#search").keyup(function(e)
{
if (e.keyCode == 40)
{
Navigate(1);
}
if(e.keyCode==38)
{
Navigate(-1);
}
});
Check complete code #fiddle: http://jsfiddle.net/MKZSE/77/

JQuery Open/Close Unique Drawers

I am trying to accomplish what may be a simple task for you. I want it so everytime the user clicks one of the "patients" on the left hand bar, a drawer opens. That drawer will be loaded in a hidden div (display:none) on the page. Each div's id will be the last lastname of the patient. My included fiddle shows all of the same last name for demonstration purposes only, obviously.
But the problem is I don't know how to open a unique drawer for each patient. I guess I need to put a toggle on each patient's li somehow?
Also, if they click another patient in the listing, I would like the current open drawer to close, and open the one they just clicked. Also, if the close button is clicked, obviously close the drawer as well.
I got a single drawer to work with this:
$(".patient").toggle(function(){
$(this)
$('#drawer').slideDown("slow")
}, function(){
$(this)
$('#drawer').slideUp("slow")
});
But obviously that isn't going to work... :(
In the fiddle it is opening a standard "drawer" right now. but really I'd like the data for each named div be loaded in the same form. Please comment if you don't understand.
Here's the fiddle:
http://jsfiddle.net/3veht/1/
Add a data element to your HTML indicating an ID, let's say patient ID in this case:
<li class="patient green" data-patientId="1">Josh Doe<img src="img/next.png"><img class="imgfix" src="img/accept.png"></li>
<li class="patient red" data-patientId="2">John Adams<img src="img/next.png"><img class="imgfix" src="img/cancel.png"></li>
Then in your javascript when you load the data, you can use that ID to generate a page request. I also changed the toggle to a click and slid the previous one up before sliding the new one down. In the fiddle example:
$(".patient").click(function(){
var pat = $(this);
if ($("#drawer").is(":visible"))
$("#drawer").slideUp("fast", function () {
$('#drawer').slideDown("slow")
$("#drawer").load("/echo/js?js=" + pat.data("patientid"));
});
else
{
$('#drawer').slideDown("slow")
$("#drawer").load("/echo/js?js=" + pat.data("patientid"));
}
});
Updated fiddle: http://jsfiddle.net/3veht/6/
Check this fiddle updated....
changes made in code
var divud = $(this).text().split(' ')[1];
$('#drawer').slideDown("slow");
$('#'+divud).removeClass('hidden');
$('#'+divud).slideDown("slow");
JSFIDDLE

Categories