how to fix this function so it keeps detecting clicks? - javascript

This is my first question please go easy on me.
The issue I am having is I have a for each PHP loop to map out (populate) the divs based on how many customer profiles are in the database.
each div has the same class name, so... I use querySelectorAll('.customerBox') to create a NodeList with x amount of divs based on rows in the database.
With this, I am able to change styles based on the index of each item.
Below is a quick example of the script i'm running to do this:
for (let i = 0; i < customerBox1.length; i++) {
(function(e){
openCustBoxBtn1[e].onclick = function(){
if(customerBox1[e].style.minWidth == '100%'){
custCreationBox.style.display = 'flex';
customerBox1[e].style.minWidth = '25%';
customerBox1[e].style.minHeight = '50%';
}
if(customerBox1[e].style.minWidth < '100%'){
custCreationBox.style.display = 'none';
customerBox1[e].style.minWidth = '100%';
customerBox1[e].style.minHeight = '100%';
}
}
})(i);
}
This works perfectly fine the only issue is that the function only runs for two clicks on any element, so let's say there are three elements (.customerBox1)'s... I can click the button within the box to make it take up the 'full screen' then if I click that button again and element (.customerBox1) at the index of whichever you clicked has a minWidth of 100% it will shrink back to its original size, BUT after this that individual elements cannot be re-opened, but any other element at another index can.
gonna be honest I have a vague understanding of how this function works I found it here on stack overflow when searching how to run an onClick for querySelectorAll() at the index of the element you clicked.
Anything helps thank you, if you need more information please let me know. I tried to describe my issue as in-depth as possible.

First of all this condition
customerBox1[e].style.minWidth < '100%'
It will not work as expected as you compare strings, you need map the value of minWidth to a number with parseInt(customerBox1[e].style.minWidth)
ex:
const minWidth = parseInt(customerBox1[e].style.minWidth)
if(minWidth === 100){
// code ...
}
if(minWidth < 100){
// code ...
}

Related

Select all text frames and ALIGN RIGHT in all ODD numbered pages of InDesign (Javascript)

I want to select all text frames and then ALIGN its content to the right of the page of all the ODD numbered pages of my document in InDesign using only Javascript.
here's my progress so far and I know I can determine the odd numbers but still can't make selecting a page work thus no progress to select its text frames too.
main();
function main() {
var myDocument = app.documents.item(0);
var myPage = myDocument.pages.item(0);
var i = 0;
for (i = 1; i < myDocument.pages.count(); i = i + 2) {
\\ select the page, then find all text frames in that page, then align right
}
}
any help is appreciated. thank you.
To get all of the frames on a page:
var myFrames = myDocument.pages[i].textFrames;
Then you can loop through the frames and their paragraphs and apply (use different counter variables, e.g "c" and "b")
myFrames[c].paragraphs[b].justification = Justification.RIGHT_ALIGN;
You can also try everyItem()
myDocument.pages[i].textFrames.everyItem().paragraphs.everyItem().justification = Justification.RIGHT_ALIGN;
Here is a simplest solution:
var pages = app.activeDocument.pages;
for (var i = 1; i < pages.length; i = i + 2) {
app.select(pages[i].textFrames);
try {
app.menuActions.item("$ID/Horizontal Page Align Left").invoke()
} catch(e) {}
}
It relies on selection objects and invoke the menu action. Sometimes this is not the best idea (that is why try/catch). The solution can be more complicated and robust. It depends on your limitations and additional details.
Update
I didn't get that you need to align CONTENT of the frames rather than the frames. It can be done, but the solution differs for linked and non-linked text frames. Except when one paragraph belongs two neighboring pages.

How to get the maximum Z-Index of multiple elements (JQuery)

I am currently working on a bug and do not seem to find a solution that satisfies my senior dev. I have the following problem:
I have a dashboard where the user can drag and drop multiple elements into it and set them the way he wants. Now, whenever a new element is dragged into the dashboard, its z-index gets set to 'auto' and it appears behind the other elements. I want to get the highest z-index available on the dashboard.
I already have written a function that gets me the highest z-index just fine, as you can see below.
function getZIndexOfElementAndAddOne() {
let temp = -1;
$('.elementIwant').each(function() {
let zIndex = $(this).css('z-index');
while (temp <= zIndex) {
temp++;
}
However, my senior dev tells me that it consumes to many resources and that I should swap the while loop with an if statement like so.
function getZIndexOfElementAndAddOne() {
let temp = -1;
$('.elementIwant').each(function() {
let zIndex = $(this).css('z-index');
if (temp <= zIndex) {
temp++;
}
But if I actually do that, the function does not return me the z-indexes of the elements but instead something else I don't even know what it is.
I would be really glad if someone could help me with this. Even an advice on how to approach the problem another way is more than welcomed
function getZIndexOfElementAndAddOne() {
const newElement = document.querySelectorAll(".newElement")[0];
const aElements = document.querySelectorAll(".elementIwant");
let temp = -1;
aElements.forEach(el => {
let zIndex = parseInt(el.style.zIndex);
if (temp <= zIndex) temp = zIndex + 1;
});
newElement.style.zIndex = temp;
console.log("Z-Index new element: " + newElement.style.zIndex);
}
getZIndexOfElementAndAddOne();
<div class="newElement"></div>
<div class="elementIwant" style="z-index: 1;"></div>
<div class="elementIwant" style="z-index: 2;"></div>
<div class="elementIwant" style="z-index: 100;"></div>
<div class="elementIwant" style="z-index: 50;"></div>
Without doing an iteration loop, I think you can combine both CSS and JS. Here's what I would attempt to solve your ticket.
The idea is, whenever a new element is being added / dragged or whatever, you should have something UNIQUE to specific it. I'd suggest adding a CSS class like current-item or something like that to the element.
Once the element is added into the DOM tree, CSS will shine with this simple selector:
.whatever .item.current-item {
z-index: 99999 !important;
}
Notice that this approach utilizes the !important flag that most jQuery or js lib use to override the styling of a DOM element. Here we're using it to make sure it will be the highest element, of course, when there's no item being dragged/added, the CSS won't apply.
You can even easily toggle the state of any DOM with something like $('.item').toggleClass('current-item') in jQuery.
I hope this approach would satisfy your "Senior Dev", the mindset behind this is based on the state of an item, and the DOM will reflect this state, the same like React guys do.
Update:
- My suggestion is to try your best to inspect the "new element", if it already has its unique CSS class, then re-use this class. Otherwise, try to add a specific class for this "new element" and proceed

Making Buttons Appear and Disappear

http://www.jsfiddle.net/Akmedrah/1cf6obpu/
Here is a fiddle of a picture button 'scroller' that I have. It is crappy but what I am really trying to figure out is the easiest way to make the arrow buttons that move the pictures right or left fade in and out when at the end of the order of pictures.
I was thinking of a java script function that essential knew the total number, something like this (I have no idea what i'm doing when it comes to JS but here is the best of what I guess it would look like):
function fadeinout(){
var total = 2; //because two in fiddle example, but theoretical could have hundreds
var current = //somehow get the current image based off id or class or some other identifier, or file name.
if (current < 2) { //set up so i can expand??? maybe?
document.getElementById("left-arrow").style.display = "true";
document.getElementById("right-arrow").style.display = "true";
}
if (current == 1) {
document.getElementById("left-arrow").style.display = "false";
}
if (current == 2) {
document.getElementById("right-arrow").style.display = "false";
}
}
I just want to know if I am headed in the right direction or if I am making this way to complicated. Thanks!
Tou can use jquery for this
http://www.w3schools.com/jquery/tryit.asp?filename=tryjquery_hide_id
$("#left-arrow").hide();
$("#left-arrow").show();
You can also use the following to toogle show and hide
$("#left-arrow").toggle();
To check if an elemnent is visible or not you can use this:
$("#left-arrow").is(":visible")

Hide dynamic JS buttons based on a var value

I am having a similar problem to this: Hide dynamically added buttons based on an if statement. With a JS mod for A Dark Room I am working on to increase my JS skills. Neither of these snippets are mine, and both are working perfectly.
This is the code snippet to create the buttons:
build: function(buildBtn) {
var thing = $(buildBtn).attr('buildThing');
if($SM.get('game.temperature.value') <= Room.TempEnum.Cold.value) {
Notifications.notify(Room, _("builder just shivers"));
return false;
}
This snippet makes sure that buttons stay visible, but I would like to change it so that when a max value is met the button is hidden.
//show button if one has already been built
if($SM.get('game.buildings["'+thing+'"]') > 0){
Room.buttons[thing] = true;
return true;
}
Hiding and showing elements is typically done through a class. Have a css class like this
.hidden {
display : none'
}
Then in your javascript, add or remove hidden class according to your condition
if(condition) {
$(element).addClass('hidden');
} else {
$(element).removeClass('hidden');
}
It's hard to suggest because there isn't enough context. The snippet you show may not just be exclusively responsible for controlling the visibility of the button (despite the inline comment saying it is). As a result the following suggestion may not work and more information on what you're trying to do and more code would be needed.
If you have access to modify the snippet then you can include the max value there. If the max value is a variable (i.e myCustomMaxValue) and it's in scope then my best guess would be to add it here:
var myCustomMaxValue = 88;
var someOtherVariableInScope = 50
//show button if one has already been built
if($SM.get('game.buildings["'+thing+'"]') > 0){
//add your condition here and yield true/false
var myCustomCondition = someVariableInScope > myCustomMaxValue;
Room.buttons[thing] = myCustomCondition;
return myCustomCondition;
}
I would suggest the debug; keyword. Place it in the snippet and open your browsers' developer tools and its debugger will get hit. You can then inspect the variables in scope and verify the snippet is in fact responsible for dynamically showing and hiding the button.
//show button if one has already been built
if($SM.get('game.buildings["'+thing+'"]') > 0){
debug;
Room.buttons[thing] = myCustomCondition;
return myCustomCondition;
}

Toggle display:none to all tags in JavaScript (no jQuery) without classes : is it possible?

I've read similar posts but i only found where it says to add class to the HTML to do what i want, so, basically i have a button, that when i want to click it hides ALL code HTML tags, and when i click it again it shows them. Since i have a lot of code tags in a page it would take me quite a lot to add a class to each one. I've been trying a few things such as
if(document.getElementsByTagName("CODE").style.display === "block"){
document.getElementsByTagName("CODE").style.display = "none"
}
and something around that, all similar code, but they all either made my browser crash or didn't work. My question is, is it really a MUST to use the class name and check for the class name of it's possible to compare, as i "did" above in the code here, the display content of all tags? ( maybe looping with a for loop each element, i tried that too, with no result. )
i tried every possible thing with my few knowledge so far ( im still studying javascript ). I would really like to know if i am trying to do something really advanced or i just dont see how it can be done.
Thanks, i hope there wasnt another question like this, i've read all of the ones suggested and none ( except one it said to use class ) was like this.
They all recommend to add classes, so i feel like im trying to do something really impossible. Im not into jQuery yet, so dont talk about it please, thanks. ( first i must learn for good JavaScript )
You have to iterate through the results of document.getElementsByTagName("CODE"), it is an array-like variable. It is a jQuery feature that lets you write .css() to a list of objects and have them all processed. You need something like
ar = document.getElementsByTagName("code");
for (i = 0; i < ar.length; ++i)
ar[i].style.display = "none";
If you need to toggle code visibility, use this code
ar = document.getElementsByTagName("code");
for (i = 0; i < ar.length; ++i)
{
if(ar[i].style.display != "none") //the element is visible
{
ar[i].style.display = "none";
}
else
{
ar[i].style.display = "block"; //If you need to make it block explicitly, otherwise ""
}
}
Note that the style.display property is initially empty and defaults to inline for code tag but can be set explicitly to other values. Resetting it to '' results in restoring the state.
If you need to change the visibility back and forth without the modification of display mode, you need to save the previous mode (code tags can be displayed not only in block mode). Can be done like this:
ar = document.getElementsByTagName("code");
for (i = 0; i < ar.length; ++i)
{
if(ar[i].style.display != "none") //the element is visible, "" or "blocK" or some other value
{
ar[i].saved_display = ar[i].style.display; //Save the display mode to a new property of the tag
ar[i].style.display = "none"; //And hide the element
}
else
{
if (typeof ar[i].saved_display === "undefined") //It's the first time we see the element. Display it in default mode
ar[i].style.display = "";
else
ar[i].style.display = ar[i].saved_display; //We know how the element was shown before we hid it, restoring
}
}
As Aneri says, getElementsByTagName returns a NodeList that you can iterate over by index.
Note that the display property only has a value if it's been explicitly set, it does not inherit a value from CSS so you should do something like the following, which will hide all the CODE elements if their display hasn't been set to none and display them if it has:
var element, elements = document.getElementsByTagName("CODE");
for (var i=0, iLen=elements.length; i<iLen; i++) {
element = elements[i];
// If element hasn't been hidden, hide it
if (element.style.display == '') {
element.style.display = 'none';
// Otherwise show it
} else {
element.style.display = '';
}
}
Note that you should return the display value to "" (empty string) so that the elements return to their default or inherited value, which might not be "block".
Also, child elements will be hidden if their parent element has display: none.
You can add a class just to BODY or HTML element and attach needed styles to this class via e.g. context selectors. For example:
HTML.hide-code CODE {display: none; }

Categories

Resources