Visibility div via 2 variables, different on / off - javascript

I'm probably not fully awake so overseeing the obvious is possible.
But I have 2 variables that decide if a div has a specific class or not.
The class is more acting like a toggle; so the following should happen to trigger the value:
focus => on
!focus && !hover => off
So when the focus var turns on the class should be added, and when the focus is lost and the hover is off it should be removed.
I would preferably do it inline on the following place:
<div ng-class="{'visible' : --FORMULA-- }"> </div>
Here you should only see the "WOhooooo" once you've clicked the input box, and then it should only dissapear when you leave the grey box:
http://codepen.io/cskiwi/pen/MKYNqo

You seem to already know the syntax, dont know what did you try. This should work...
<div ng-class="{'visible' : 'focus', 'notvisible' : '!focus && !hover' }"> </div>

Related

How to focus on a range slider using Javascript?

I would like to be able to focus on an input element of the type 'range', in other words, the default slider, so that the slider could be dragged without the user actually clicking on it.
The obvious solution would be to just use sliderelement.focus().
This however doesn't work.
I found here that the reason for this, is that I have to call this method on the handle of the slider. The class of the slider handle should be 'ui-slider-handle'.But for some reason document.querySelector('.ui-slider-handle') returns null.
The weird part is that this does work with JQuery when I use $('.ui-slider-handle').
I made this fiddle to clarify my problem. I would like to solve this using only Javascript.
--- edit ---
Perhaps I wasn't clear enough in my explanation. The class ui-slider-handle is not a custom class I added to the slider handle, since I cannot access the handle. I expected this to be the default class based on the answer I found (which I stated earlier).
In your fiddle, the querySelector is correct.
Your jQuery will always return true like that though.
For example change var handle2 = document.querySelector('.ui-slider-handle'); to a made up class like var handle2 = document.querySelector('.ui-slider-handlesdfsdfsdfsdf'); and it returns true.
If you want to check if an element exists you can use .length.
So just add .length to your selector and they will both return false.
var handle1 = $('.ui-slider-handle').length;
var handle2 = document.querySelector('.ui-slider-handle');
$('#1').html('JQuery, handle found: ' + (handle1 ? 'true' : 'false'))
$('#2').html('Javascript, handle found: ' + (handle2 ? 'true' : 'false'))
To put focus on the range element simply use .focus().
Here is an example. Use the buttons and your arrow keys to see that it is gaining/losing focus on the element.
function getFocus() {
document.getElementById("myRange").focus();
}
function loseFocus() {
document.getElementById("myRange").blur();
}
<input type="range" id="myRange" value="50">
<p>Click the buttons below to give focus and/or remove focus from the slider control.</p>
<button type="button" onclick="getFocus()">Get focus</button>
<button type="button" onclick="loseFocus()">Lose focus</button>

vue.js - how to update childs data on parent's data update without this.$parent[...]

I am taking my first steps with Vue.js and i like it very much however i met a small problem and i hope for help with solving this one.
Please check my fiddle here:
https://jsfiddle.net/eywraw8t/8410/
What i am trying to achieve is puting some buttons in relationship with others, for now, quite hardcoded, however if you click "settings on" button "setting1" and "setting2" button become visible. It works as intended but i want to root Vue instance to hold information when buttons are visible or not via this.settings = true (visible) or false (not visible). When button is created it is checked and button become visible or not depending on this.settings value.
However because i use:
template: '<div #click="kalregClicker" class="button" :class="{isNotVisible : !this.$parent[this.type]}"><slot></slot> {{ status}} {{ !this.$parent[this.type]}}</div>',
every change root's this.settings causes change of visibility of buttons and it is good. But somehow i guess that using everywhere this.$parent[this.type] is ugly. I'd prefer something like:
template: '<div #click="kalregClicker" class="button" :class="{isNotVisible : !status}"><slot></slot> {{ status }} {{ !this.$parent[this.type]}}</div>',
or
template: '<div #click="kalregClicker" class="button" :class="{isNotVisible : checkVisibility()}"><slot></slot> {{ status }} {{ !this.$parent[this.type]}}</div>',
and checkVisibilty would look like this:
function () {
this.status = this.$parent[this.type];
return this.status;
}
..but it doesnt work.
The question is: how to make updating root's this.settings to true/false to impact 's component this.status so it changes look and behaviour of component without using everywhere this.$parent[...]
I hope i made myself clear :)
Kalreg.
You should have status itself become a computed property.
Remove it from data declaration and do:
computed: {
status() { return this.$parent[this.type] == undefined ? true : this.$parent[this.type]; }
}
You can use it like:
:class="{isNotVisible : !status}"
JSFiddle here.

What can cause click() method to fail?

I have an element (a checkbox), with this HTML:
<button type="button" class="_f_V1 noMargin o365button" aria-labelledby="_ariaId_28" role="checkbox" aria-checked="false">
<span class="_fc_3 owaimg checkboxImage wf-size-checkboxMultiselectSize ms-bg-color-white ms-border-color-neutralSecondaryAlt"> </span>
<span class="_fc_4 o365buttonLabel _fc_2" id="_ariaId_28" style="display: none;"></span>
</button>
Note it's a button element even though it behaves like an <input [type="checkbox"]>.
I aim to select and click on this element with the click() method. The selection is correct, but the click() method fails.
What I did:
document.querySelector('._f_V1.noMargin.o365button').click();
Yet nothing happens - the checkbox won't be checked.
Given this (first) element is but one of a list of similar elements, I've also tried:
(()=>{
document.querySelectorAll('button span').forEach((e)=>{
e.click()
});
})();
Again, neither the first, nor any other checkbox is selected.
From running querySelector() and querySelectorAll() (with their relevant selectors) in console, I get the elements I want (I don't get undefined), so it means my selections are correct.
Given the selections are correct, why would the click() method have no effect?
When I click with the mouse --- the checkbox is checked but when I use click() on the same element, it doesn't.
If you want to try to reproduce online, you need to have an Hotmail email account with messages that you've already deleted. If this is the case:
Go to "Deleted items".
Go to "recover deleted items".
a window will be opened with deleted conversations.
Near to each conversation there will be a checkbox (after mouseover). This is the element I'm having the trouble with.
Note: The mouseover just changes opacity of the checkboxes.
If the question is:
What can cause click() method to fail?
Then the Answer is: Kinda NOTHING! If the click-method is available for an HTMLElement then calling HTMLElement.click() can not "fail" (in that sense). What could happen is that calling click on this element will not have the desired effect/impact - which is the case for the questions author! "just for the sake of completeness..."
After deeper investigation, here is my conclusion.
The actual event handlers that are responsible for checking and unchecking (and all that is related to it) are callbacks "listen to" mousedown-events on these button._f_V1.noMargin.o365button-elements (boot.worldwide.0.mouse.js:37); so you will not get anywhere triggering click-events. One may ask: "how can you say so?". I can say so because I removed ALL other event listeners first traversing up two parents and then from there on all the way down with each and every child element except for the button where I left the mousedown-eventListener. And the functionality was still intact. After removing also this last event listener the functionality was gone. So I guess: yep I can say so :)
My next step was to trigger a mousedown-event on the button like this:
$('._f_V1.noMargin.o365button').each(function() {
$(this).mousedown();
})
But NO this doesn't work.
So what about hysterically triggering events on every maybe-relevant element like this:
var $El = $('._f_V1.noMargin.o365button').parent().parent();
$El.add( $El.find('*') ).each(function() {
$(this).mousedown().mouseup().click();
// may be one event is cancelling the result of another one out
// so I also tried $(this).mousedown()
});
NO - this also doesn't work.
So I came up with my last approach which didn't work either. Let’s mimic the attributes and properties from selected button. BTW the element that is actually responsible for making the "pseudo checkbox" look like checked/unchecked is the first span-childNode of the button-element. So if you type in the following code in the console of your browsers devtool everything will look exactly as it was properly clicked (or mousedowned so to say):
$('._f_V1.noMargin.o365button').each(function() {
$(this).trigger('mousedown').addClass('_f_V1 noMargin o365button _f_W1').attr('aria-checked', 'true').prop('aria-checked', true)
.children(':first').trigger('mousedown').addClass('_fc_3 owaimg ms-Icon--check wf-size-checkboxMultiselectSize ms-bgc-w ms-fcl-nsa-b ms-fcl-ns-b ms-border-color-neutralSecondaryAlt')
.parent().parent().parent().trigger('mousedown').attr('aria-selected', 'true').prop('aria-selected', true)
})
See the screen capture below where I pastet the above snippet straight into devtools console and the "pseudo checkbox" appear as they where clicked.
So what to do now? Ask another question! One that is much more specific. Something like: "How to [recover|deepDelete] all deleted messages in hotmail.com" Because this is what the intent of the question actually is - not sure about it but I guess.
Just want to emphasize this once more: In general the code from OP and also the code in this answer works. It does right, so to say. But it’s not able to achieve what the author wants to achieve.
Additionally here is a proof that the OPs code is actually working:
document.querySelector('._f_V1.noMargin.o365button').addEventListener(
'click', function() { console.log('jepp') }
);
document.querySelector('._f_V1.noMargin.o365button').click();
// BTW: yep HTMLElement.click() returns undefined
console.log(
'yep HTMLElement.click() returns: ',
document.querySelector('._f_V1.noMargin.o365button').click()
)
button {width: 100%; height: 100%; position: fixed}
<button type="button" class="_f_V1 noMargin o365button" aria-labelledby="_ariaId_28" role="checkbox" aria-checked="false">
<span class="_fc_3 owaimg checkboxImage wf-size-checkboxMultiselectSize ms-bg-color-white ms-border-color-neutralSecondaryAlt"> </span>
<span class="_fc_4 o365buttonLabel _fc_2" id="_ariaId_28" style="display: none;"></span>
</button>
function handelClick(){
if(this.getAttribute("aria-checked")=="true"){
this.setAttribute("aria-checked", "false");
}else{
this.setAttribute("aria-checked", "true");
}
}
var button=document.getElementsByTagName('button');
for (var i = 0; i < button.length; i++) {
button[i].addEventListener('click', handelClick);}
goto https://jsfiddle.net/7xnwpgbk/5/
it may help you
You can try it with jQuery
click method which will only work on jQuery collections created like:
jQuery( 'your whatever selector(s) here' ) // form here on you can call .click() now
So for your specific approach you can do:
jQuery('._f_V1.noMargin.o365button').click();
as well as:
jQuery('button span').click();
Since jQuery click method does only trigger an on click event on the first DOM element of a jQuery collection you can combine it with jQuery method each as follows:
jQuery('._f_V1.noMargin.o365button').each(function() {
$(this).click();
});
as well as:
jQuery('button span').each(function() {
$(this).click();
});

independently working div in Jquery

I am trying to make an independently working div which has a form inside of it.
I use jquery to calculate the price of a product depending of the user's selections in the form. However the user is able to add multiple items in his 'cart' so the form is duplicated to another div. The problem is that the calculation pattern can't separate these two divs and the calculation will be incorrect. The form is also interactive so it will be generated by the user's input. This is really complex set and renaming every variable by the 'product number' doesn't sound really efficient to me.
I'm kind of stuck here and i don't really know how to solve this problem. I had an idea that what if I put an iframe inside of the div and load my form and its calculation script inside of it, and then use post command to transfer the price of the product to the 'main page' to calculate the total price of all of the products the user wanted.
However it seems that jQuery scripts doesn't work independently inside of these iframes, they still have connection so they broke each other.
i will appreciate any kind of suggestions and help to solve this matter, thank you!
here's the code so far
Heres the body
var productNumber = 1;
<div id="div_structure">
</div>
<button id="newProduct" >Add new product</button><br \>
add new item
<!-- language: lang-javascript -->
$('#newProduct').click(function ()
{
$('<div id="productNo'+productNumber+'">')
.appendTo('#div_structure')
.html('<label onclick="$(\'#div_productNo'+productNumber+'\').slideToggle()">Product '+productNumber +' </label>'+
'<button onclick="$(\'#product'+productNumber+'\').remove()">Remove</button>');
$('<div id="div_product'+productNumber+'" style="display: none;">').appendTo('#product'+productNumber+'');
$('<iframe src="productform.html" seamless frameborder="0" crolling="no" height="600" width="1000">').appendTo('#div_product'+productNumber+'');
productNumber++;
});
it also has a function that allows the user to remove the inserted div.
Here's just few lines from the productform
$(document).ready(function()
{
$('#productCalculation').change(function ()
{
shape = $('input[name=productShape]:checked', '#productCalculation').val();
alert(shape);
});
});
<form id="productCalculation">
<div id="div_productShape" class="product1">
<h1>Select the shape of the product</h1>
<input type="radio" name="productShape" value="r1">R1</input><br \>
<input type="radio" name="productShape" value="r2">R2</input><br \>
<input type="radio" name="productShape" value="r3">R3</input><br \>
</div>
.
.
.
</form>
I translated all of the variables so they may not function correctly since i didn't test the translated version. So the problem is, if i try to make selections in the second generated div it wont even alert() the selected variable
There are two problems with this code: You say somewhere "I translated all of the variables so they may not function correctly since i didn't test the translated version. So the problem is, if i try to make selections in the second generated div it wont even alert() the selected variable". This is because event handlers are attached to elements that are in the DOM at that specific moment. To get it to work for all elements, use event delegation:
$(document).ready(function()
{
$(document).on( 'change', '#productCalculation', function ()
{
shape = $('input[name=productShape]:checked', '#productCalculation').val();
alert(shape);
});
});
Your other question is "My question in a nutshell: Is there a way to restrict jquery to function only in certain div even though i use the same variable names in the second div ". You can use the this variable to access the element the click was invoked on. From this element you can traverse the DOM if needed, for example with .parent().
$('div').on( 'change', function( e ) {
console.log( $(this).val() );
} );

Javascript styling toggle doesn't work first click

I'm making this little html app with a sidebar menu that pops up on click. It works fine except that it only starts to work after the second click. On the first click nothing happens.
CSS:
#menubalk{
margin-left: -260px;
}
HTML:
<div id="menubutton">
<img src="design/images/menu.png" id="menu" onclick="toggle()" alt=""/>
</div>
<div id="menubalk">
<h5>Menu</h5>
</div>
Javascript:
function toggle () {
var el = document.getElementById("menubalk");
var kop = document.getElementById("kop");
var pag = document.getElementById("pagina");
if ( el.style.marginLeft=="-260px" ) {
el.style.marginLeft="0px";
kop.style.marginLeft="260px";
pag.style.marginLeft="260px";
} else {
el.style.marginLeft="-260px";
kop.style.marginLeft="0px";
pag.style.marginLeft="0px";
}
}
I think I might have to set the margin somewhere in the javascript also but I can't figure it out.
All help is greatly appreciated!
style.marginLeft is looking at your inline styles. As you haven't defined any inline style initially style.marginLeft is undefined.
To fix this, you could simply reverse your if/else statement:
if ( el.style.marginLeft=="0px" )
element.style only search for inline style, to get actual style you can use getComputedStyle
i.e.
if ( window.getComputedStyle(el).marginLeft=="-260px" ) {...
Reference: https://developer.mozilla.org/en-US/docs/DOM/window.getComputedStyle
Note: For IE, this only works for IE9 or above.
With this line
if(el.style.marginLeft=="-260px") {
You are checking if the inline style of the element is a specific value. However, this style is set in the css. I recommend adding a className to the menu to expand it. You can check for this classname and add/remove it accordingly:
if ( el.className == "expanded" ) {
el.className = "";
} else {
el.className = "expanded";
}
With this addition to the css:
#menubalk.expanded {
margin-left:0;
}
You say you set the menu style in the JavaScript somewhere but I would actually recommend doing that as part of your initialisation, rather than setting the left margin with CSS.
I suspect (it's hard to see without an example) that on the first click the JavaScript is going straight to the else condition because it's not recognising that you've set the margin in CSS (or elsewhere). Then on the second click, JavaScript has been used to set the left margin so it can read it and perform accordingly.

Categories

Resources