jquery add exception to click outside of div - exception

I have several overlapping divs on my website and I try to close the second one when the first one is clicked outside only if the outer div of the second overlapping div does not exist or is clicked.
When the first overlay (menu) is displayed, clicking outside closes it.
When clicking on one of the three radio inputs inside the (menu, a second overlay is displayed and must interrupt the "CloseBigMenu()" function which made it possible to close the "menu": first overlay, only if this second overlay exists and a button inside is clicked.
$(document).on('click', function(e){
if(BigMenu.hasClass('active')){
if (!BigMenu.is(e.target) && !$("#BtnMenu").is(e.target) &&
BigMenu.has(e.target).length === 0 && $("#BtnMenu").has(e.target).length === 0 ){
if($("#WinChangeSpace").length === 0 && !$("#ChangeSpaceNo").is(e.target)){
CloseBigMenu();
$("#ListShortKeys").removeClass('active').addClass('SlideY');
}
}
}
});
I also tried to interrupt the function CloseBigMenu(), without result .
structure :
<div id="BigMenu">
<input type="radio" name="radioSpace" id="radio-1" value="">
<input type="radio" name="radioSpace" id="radio-2" value="2">
<input type="radio" name="radioSpace" id="radio-3" value="3">
</div>
<div id='WinChangeSpace'><span id='ChangeSpaceNO' ></span></div>
#WinChangeSpace is added with jquery append on click to input radio
The function :
function CloseBigMenu(){
BigMenu.removeClass('active').addClass('bounceT');
setTimeout(ReinitializeHeight, 700);
function ReinitializeHeight() {
BigMenu.removeClass('ptop66 bounceB').addClass('ptop-500');
}
}
bounceB and bouceT is an css animation.
Currently when I click on "#WinChangeSpace" or "#ChangeSpaceNO" the two overlays closed in same time instead of only second.
Is it possible to add an exception on a click outside an element ? can you help me to reason?

Related

How to redirect from one html page to another on button click in javascript?

I have two html pages page_1.html and page_2.html. In page_1.html, I have a button, which upon being clicked should redirect to page_2.html. But it should redirect only when the button has a charteuse background color.
So, in page_1.html, I have a button:
Organization:<div id="org"><input type="checkbox" id="cb1" >ID no: <input type="number" id="org_number" style="visibility: hidden"><br><br>
<input type="checkbox" id="cb2" >Mobile No: <input type="tel" id="ph_number" style="visibility: hidden" required></div><br><br>
<button id="button" onmouseover="hovar()" onclick="submit()" >Register</button>
<script src="back_end.js" async></script>
My javascript (back_end.js):
function hovar(){
var phone=document.getElementById("ph_number").value;
var btn=document.getElementById("button");
if (phone.length!=10){
btn.style.backgroundColor="lightsalmon"
}
else{
btn.style.backgroundColor="chartreuse"
btn.style.color="black"
}
}
function submit(){
var btn=document.getElementById("button");
if (getComputedStyle(btn).backgroundColor == "charteuse"){
window.location.href="page_2.html";
}
}
But, it doesn't redirect to page_2.html. What am I missing here? I have also tried window.location.replace("page_2.html"), but it's the same.
EDIT: I have changed the code a little, it's from a project I'm doing. I have also tried getComputedStyle(document.getElementById("button")).backgroundColor, but it doesn't work.
Another thing that I've noticed, is that when I use:
if (btn.style.backgroundColor == "charteuse"){
//console.log(true)
location.href="page_2.html";
}
it prints true into the console but still doesn't redirect to page_2.html.
But if I use:
if (getComputedStyle(btn).backgroundColor == "charteuse"){
//console.log(true)
window.location.href="page_2.html";
}
it doesn't print true into the console.
But nevertheless, in both the cases, it doesn't redirect to page_2.html
ElementCSSInlineStyle.style
The style property is used to get as well as set the inline style of
an element. When getting, it returns a CSSStyleDeclaration object that
contains a list of all styles properties for that element with values
assigned for the attributes that are defined in the element's inline
style attribute.
https://developer.mozilla.org/en-US/docs/Web/API/ElementCSSInlineStyle/style
So your if-conditon document.getElementById("button").style.backgoundColor == "red" does never return true because the color is defined in your css-file and not as an inline argument.
A solution would be using getComputedStyle(element) which returns the actuall style from the css-file.
getComputedStyle(document.getElementById("button")).backgroundColor == "red"
as explained here https://zellwk.com/blog/css-values-in-js/
Also in your css, you can remove the quotationmarks around "red" as mentioned by #George
The styles property doesn't directly reflect your CSS, so running
if(document.getElementById("button").style.backgoundColor=="red"){
never works.
What you can do is change the color to red using javascript:
function changeButtonColor(color) {
document.getElementById("button").style.backgoundColor = color;
}
changeButtonColor('red');
So you do this, wherever you need to change the background color, your if statement will work correctly and you can switch.
so you should compare like this
var btn=document.getElementById("button");
if (getComputedStyle(btn).backgroundColor == "rgb(127, 255, 0)"){
window.location.href="page_2.html";
}
}

How do I combine onclick and onkeypress events for one button in HTML?

So I am making a simple calculator app. Now I have a button to input '1' in the calculator. What I want is whenever I click on '1' button or press '1' on my keyboard, 1 should be input into the calculator. Here is my code -
<td><input type="button" class="button" name="one" value="1" onclick="calculator.display.value += '1'" onkeypress="if(event.keyCode == 49){calculator.display.value += '1'}"></td>
And my calculator display box is -
<input type="text" name="display" id="display" disabled>
Now what happens is when I click '1' button, 1 is displayed in my display box. But when I press '1' on my keyboard, nothing happens.
But when I click '1' button first, then press '1' on my keyboard, '11' gets into the display box, that is, the input is accepted through the keyboard.
I want this input via keyboard without having to click the button.
Please help.
Thanks in advance.
When you apply the onkeypress event to a specific element, it won't act the way you want it to because the element must be focused in order to catch the key press event, because the event is relative to that element.
let display = document.getElementById("display");
document.body.onkeypress = function() {
// Include all numbers, 0-10
for (var i = 0; i < 10; i++) {
if (event.keyCode == i + 48) display.value += i;
}
};
<html>
<body>
<input type="text" id="display" disabled />
<br>
<button id="btn1" onclick="display.value += '1'">1</button>
<button id="btn2" onclick="display.value += '2'">2</button>
<button id="btn3" onclick="display.value += '3'">3</button>
</body>
</html>
And on another note, somehow unrelated to the question but has been brought up here, regarding inline JS - it is generally considered bad practice. Some cases might justify it, but it is general consensus that it should be avoided. Read more:
Is inline JavaScript good or bad?
Why Inline CSS And JavaScript Code Is Such A Bad Thing
Reddit - why is inline onclick="function()" considered such a bad practice?
The problem is the position of your onkeypress(), if you move that out of the input tag for example in the <body> or in your <table> you could have a bigger "focus zone" where the event could be caught:
<head>
<script>
function onClick(val)
{
document.getElementById("display").value += val;
}
function onPress()
{
switch(event.keyCode)
{
case 49: document.getElementById("display").value += 1;
break;
case 50: document.getElementById("display").value += 2;
break;
}
}
</script>
</head>
<body onkeypress="onPress()">
<table>
<td>
<input type="button" class="button" name="one" value="1" onclick="onClick(1)">
</td>
</table>
<input type="text" name="display" id="display" disabled/>
</body>
Hope this help :)
onkeypress works only if the focus is on the button. If you don't click the button first, the focus isn't on the button and the button can't recognize the keypress. As soon as you click the button, it gets the focus and it can recognize the keypress.
You could try adding the onkeypress event to your body tag.
<body onkeypress="if(event.keyCode == 49){calculator.display.value += '1'}">
As mentioned in another answer onkeypress will only work if the element is focused. Also you should no use inline JS but let both event refer to a function which you execute when the event occurs. Here is an example with an input element.
function myFunc () {
alert("event happening");
}
input:focus {
background-color: red;
}
<input onkeypress="myFunc()" onclick="myFunc()"/>
When the element is clicked the event fires. Also when the element is focused and a key is pressed the event fires. Hopefully this is helpful.

Check if a Popup is being closed Jquery Mobile

so i have a little problem i have code like that trying to create a mobile website with jquerymobile...
HTML:
<div>
<input type="text" id="first">
</div>
<div>
<input type="text" id="second">
</div>
<button id="testButton">
Checking
</button>
<div data-role="popup" id="popup"><p>I am a Popup</p></div>
js/jquery...
var begin = $("#first").val();
var end = $("#second").val();
$(document).on("click","#testButton", function(){
if(begin > end){
$("#popup").popup("open");
$("#second").css({"border": "2px solid red"});
}
})
So what i wanna do is, if the inserted value of Begin is greater then the value of End. A Popup should be activated and then AFTER the popup is clicked away by the user the End input element should get a red border. I can only make it work that the border and the popup take effect at the same moment the button is clicked and not step by step. Is there a way to check if the popup is closed and then set the border?
You can use the popup's afterClose event:
$("#popup").on( "popupafterclose", function( event, ui ) {
$("#second").css({"border": "2px solid red"});
});
DEMO

How to use nested conditions for displaying a hidden block using angular js

I am trying to put conditions for displaying a hidden div. I want that after entering some value in 'name' textbox and if we click on search link then the hidden block should appear. But in my code, if we click on search link first then enter any value in textbox then also the hidden div is appearing. But I need that only after entering value in textbox , if we click on search then only hidden div should appear.
Iam using below code for hiding the div-
<div ng-show="name.length>0 && IsVisible">
and in script I am writing this code-
$scope.isVisible = false;
$scope.ShowHide = function () {
//If DIV is hidden it will be visible and vice versa.
$scope.IsVisible = true;
}
I have created a plunker here-
https://plnkr.co/edit/oVwZONrn4gtQs1BaiMbO?p=preview
Can any one help me how can I achieve this?
You should add a condition in the method ShowHide itself:
$scope.ShowHide = function () {
if($scope.name) {
//If DIV is hidden it will be visible and vice versa.
$scope.IsVisible = true;
}
}
If you wish the hidden section to be visible only when 'Search' is clicked, then make changes as per following in the HTML file:
<div ng-show="IsVisible">
Refer to the demo here
Check this plnkr. Added a watch on name change:
<input type="text" name="name" class="form-control" ng-change="resetShowHide()" ng-class="" ng-model="name" required/>
and if the name length is 0, reset is IsVisible
$scope.resetShowHide = function(){
if($scope.name.length) $scope.IsVisible = false;
}

How to extend radio button clickable area to other elements using css or jquery

I have this html/smarty code for a radio button. I would like to extend the area for the selection of the radio button so that the user can more easily select it on this page?
The classic trick of using label is insufficient here. All the actions performed when clicking the button must be performed, see the onchange parameters. I need to make a clickable zone including at least the whole table that contains this line, or even better: a zone that also contains the image above each radio button.
Is that possible in html, css, jquery?
Thanks
<tr>
<td valign="top">
<input value="{$id_attribute|intval}" class="{$groupName}" type="radio" name="{$groupName}" id="group_{$id_attribute_group|intval}" onchange="javascript:findCombination({$groupName});changeCombinationPrice();{if $groupName=='group_1'}getCheckedValue(document.forms['buy_block_form'].elements['group_1']);scaleImage('{$group_attribute|escape:'htmlall':'UTF-8'}','{$cover.id_image}.jpg');{else if $groupName=='group_2'}changeImage('{$group_attribute|escape:'htmlall':'UTF-8'}','{$cover.id_image}',{$id_attribute|intval}); {/if}" {if ($groupName=='group_1' and $countGroup1==1) } checked {/if} />
</td>
{assign var="hrup" value=$group_attribute|escape:'htmlall':'UTF-8'|lower}
{if $feact==$hrup}
<td width="17" valign="top">
<script language="javascript" >
Tooltips('{$feact},{$hrup}');
</script>
<div class="tooltip">
<div class="toolimg"><img src="/pixelart/img/layout/corazon.jpg">
</div>
<div class="tooldescrip">{l s="Finition recommandée par l'artiste"}
</div>
</div>
{/if}
</td>
<td>
<div class="imputgroup_{$id_attribute|intval}">{$group_attribute|escape:'htmlall':'UTF-8'}
</div>
</td>
</tr>
<tr>
You need to wrap the clickable content in another tag (A is appropriate) and hook up the event handler to that tag. You'll also have to switch the radio buttons in JavaScript accordingly.
wrapped the area with a a tag:
<a href="Javascript:void()" id="radioClickAreaid{$id_attribute|intval}" onclick="radioClickArea(document.forms['buy_block_form'].elements['{$groupName}'], '{$id_attribute|intval}');javascript:findCombination({$groupName});changeCombinationPrice();{if $groupName=='group_1'}getCheckedValue(document.forms['buy_block_form'].elements['group_1']);scaleImage('{$group_attribute|escape:'htmlall':'UTF-8'}','{$cover.id_image}.jpg');{else if $groupName=='group_2'}changeImage('{$group_attribute|escape:'htmlall':'UTF-8'}','{$cover.id_image}',{$id_attribute|intval}); {/if}">
that has the same onclick parameters as the onchange from the radio button (not very elegant though!), and that calls a javascript function:
function radioClickArea(radioObj, id_attribute) {
if(!radioObj)
return;
var radioLength = radioObj.length;
if(radioLength == undefined) {
radioObj.checked = (radioObj.value == id_attribute.toString());
return;
}
for(var i = 0; i < radioLength; i++) {
radioObj[i].checked = false;
if(radioObj[i].value == id_attribute.toString()) {
radioObj[i].checked = true;
}
}
return false; // so that the link goes nowhere
}
The radio button gets selected OK.
Is there a way not to repeat the onchange/onclick parameters?
Or like suggested here - use tag surrounding your radiobutton or checkbox:
How can I make an HTML radiobutton with a big target area?