Can this popup feature be applied for many users? - javascript

I made a popup feature, which shows the phone number of a user. I was able to apply this feature to one instance. A single user.
Normally, each user has a unique phone number. Each user's number's already embedded, it's just to reveal the numbers, for multiple users.
But then, I thought, what if I have lots of users as they come, to the site? How do I dynamically apply the same popup feature without writing the same lines of code I wrote for the single user, over and over again?
Please, help me out.
This is the JavaScript I wrote...
let tansform_scale_0 = document.querySelector('.transform_scale_0');
let num_btn = document.querySelector('.num_btn');
num_btn.addEventListener('click', ()=>{
if (!tansform_scale_0.classList.contains('scale_to_1')) {
tansform_scale_0.classList.add('scale_to_1');
} else {
tansform_scale_0.classList.remove('scale_to_1');
}
})
Please view the code here: https://codepen.io/matthewdon/pen/MWQEvJM

You need to extend the logic you've applied to each of your cards. For example, the simplest way is to use querySelectorAll rather than the querySelector you currently have.
This is very similar in that it will return you a list of matching elements which you can then loop over and add your event listeners to in much the same way you are doing now.
However to make things a bit easier, you will be better off looping over each of the containing .card elements first. That way you can scope a second querySelector to the containing element and leave the rest of your logic largely intact.
You can shortcut the click handler itself though, by using classList.toggle rather than manually checking the class and then adding/removing it as required.
const cards = document.querySelectorAll('.card');
cards.forEach((card) => {
// rest of your click handler logic
})
Here's a snippet that brings all that together. I've put it on codepen as the editor on here isn't really suited to such a large amount of html: https://codepen.io/29b6/pen/VwQQqrw?editors=1111

Related

How do I use Javascript to delay visibility of a text box and then hide another box after the first becomes visible

Im very new to this and have reviewed other posts similar to this question. However, I'm finding that those solutions don't work for me.
Background: I'm working in Wix's Velo platform for Javascript. (forgive me if that's not the right technical terminology here)
My goal: When my website home page loads, I want one of the text boxes on the page (#text45) to NOT be visible until 5 seconds have passed. Then, when box #text45 is visible, I want another plain box (#box2) to turn to hidden.
I have found some examples like the one below: (not all code has been pasted and I realize some elements like div1 would need to change to my specific element names)
document.getElementById("div1").style.visibility = "visible";
}
setTimeout("showIt()", 5000);
However, I get an error code: Cannot find name 'document'. Do you need to change your target library? Try changing the 'lib' compiler option to include 'dom'.
When researching this, I found out that Velo cannot access the dom and elements can only be accessed via "$w".
Would someone be kind enough to set me in the right direction on how to accomplish the "goal" above? I would really appreciate it! Thank you in advance.
Here's how you would do it. Note, that it's good practice to change the IDs of your elements to more descriptive names, but I've stuck with the names you provided in your question.
Start by setting #text45 to hidden in using the Properties & Events panel.
Then use this code (note that your page might already have an onReady. If it's there an you're not using it yet, delete all the code on the page and replace it with this):
$w.onReady( () => {
setTimeout(() => {
$w('#text45').show();
$w('#box2').hide();
}, 5000)
} );

Get DOM element that has been created within a foreach loop

I have a node application and I have a pug template that are coded up, the pug template represents one project, and within that are shown related targets (so a one to many relationship - one project can have many targets).
What I want to do, is have a user be able to click on the DOM element representing a target, and it open up a modal form or something similar, and allow it to be edited. I'm not sure of the best way to do this. So this is my pug template element for each:
each target in project.targets
.target__card
.target__avatar
h6.target__title= target.title
input#targetId(type='hidden' value=`${target._id}`)
So I've got my hidden id in there and it's all peachy. I want to be able to click on it and it open a form that can edit it and then submit to my endpoint. But if I have a javascript function like this:
const targetCard = document.querySelector('.target__card')
if (targetCard) {
targetCard.addEventListener('click', async (e) => {
const target = document.getElementById('targetId').value
console.log('target is ', target)
})
}
then this is only going to work for the first DOM element. But do I really need to loop through again, in my javascript, or something like that? I'm already looping in the template, and the information is ' just sitting there' already, I can see it. It seems wasteful to loop through it again in a js function, even if I did know the best way to do that (which I'm not sure I do). Is there something obvious that I'm missing? Can I embed a form in each element that can simply be hidden and unhidden? That seems a bit wasteful too.

Prototype not defined when accessing children on creation of custom-tag

__What I am trying todo____
Right now I am working with custom HTML5 tags. I am trying to create a tab-control element that is easy to set up. Todo this I create a parent element called 'tab-set' which works much like the 'ul' tag.
To insert tabs, you simply insert 'tab-element' tags (like 'li' tags). The tags can implement own behavior through custom prototypes which extend standardized element-prototypes such as the basic HTMLElement and are then registered with 'document.registerElement()'. At that point there are also opportunities to set callbacks that let you know whenever your element has been created or attached to something, which is what I use to do the necessary calculations on the placement of the individual tabs on the tab-control.
Let me say up-front that I've had trouble with this at first, then got it working, but upon rewriting the whole thing had troubles again for who knows why.
So, in the creation routine of the tab-set I iterate through all the child-tab-elements, calling their custom function 'setDimension', or atleast I am trying to. For some reason Chrome won't initialize the tab-element prototype (setDimension etc) before it has called both 'createdCallback' and 'attachedCallback' on my tab-set. This means that I can't call the child elements custom functions to set it's placement on creation of the tab-set.
Here you have some code samples of what I just described.
simple.html
...
<tab-set>
<tab-element>
<img>guybrush</img>
</tab-element>
<tab-element>
<img>le chuck</img>
</tab-element>
</tab-set>
...
tabs.js
...
tabSet = Object.create(HTMLDivElement.prototype);
tabSet.attachedCallback = function(){
for(/** calculations here **/)
listOfChildren[index].setDimensions(/** placement info **/);
//
// Chrome console: 'setDimensions' is not a function!
//
}
tabElement = Object.create(HTMLDivElement.prototype);
tabElement.setDimensions = function(/** placement info **/){
$(this).css(...);
}
document.registerElement('tab-set',tabSet);
document.registerElement('tab-element',tabElement);
...
The weird thing is that I have a working version of this, and yes, I have tried to emulate it's particular conditions such as for example loading the html-portion through jquery's .load() routine. But no matter what I do, I can not get this to work in my current script. What knowledge am I missing?
Thanks in advance for any help.
__ Solved __
All I had todo was add a link-tag inside the tab-set and have the tab-elements load it's containing style-class. I guess making the tab-elements have a css-class is somehow provoking Chrome to load their prototypes 'prematurely'.

Best way to rearrange positioning of images/divs with javascript/jquery?

I took a peek at the source of http://wonderwall.msn.com and noticed how all the span tags that the blocks of the wall have don't seem to be associated with any ID. It makes me very curious how they are able to accomplish the animated repositioning of elements when you click on one of the blocks/images without associated ID.
I am curious how you can click on say an image and get other images around it to move to the side. Is it some sort of formula or algoirthm?
I would like to accomplish getting say, 5 spans/blocks, clicking on one, and getting others to animate/move to the sides.
IDs are not necessary and often harmful. You don't need them, generated or otherwise.
When you put an element on a page with an ID, you're making the claim that there should be only one of whatever it is. Seldom is this true. More often, what you want to do is associate some behavior with some of the elements on the page, of which there may be many, one or zero.
In this case, there are lots of little image dealies, which when clicked, rearrange themselves. I don't have an algorithm for you for calculating how they should move, but here's a framework for how you could achieve the same with jQuery.
// create jQuery plugin for highlighting and shuffling brick dealies
(function($){
function expandify() {
var href = this.attr('href');
// create a popup containing the href
return this;
}
function shuffle() {
this.each(function(index, elem){
// calculate new position and move the element there.
});
return this;
}
$.fn.expandify = expandify;
$.fn.shuffle = shuffle;
})(jQuery);
// attaches behaviors to elements on the page after they've loaded
// either $.ready, or window onload, or after some ajaxing takes place
$('.wallBrick')
.click(function(e){
$(e.target)
.expandify();
$('.wallBrick')
.not(e.target)
.shuffle();
});
The IDs are generated via JavaScript on-the-fly. You won't see it in the source, but you'll see it if you inspect it with Firebug.

jQuery Graceful Degradation

I want to spruce up some areas of my website with a few jQuery animations here and there, and I'm looking to replace my AJAX code entirely since my existing code is having some cross-browser compatibility issues. However, since jQuery is a JavaScript library, I'm worried about my pages not functioning correctly when JavaScript is turned off or doesn't exist in a user's browser.
I'll give an example: Currently, I'm using a pure CSS tooltip to give my users (players, the site is a browser game) information on other users. For example, if the other players in the game satisfy one or more conditions, a target icon is displayed next to their name, and upon hovering over that target icon information regarding the reasons behind the target is displayed. This is useful information, as it helps my players to know who they should plan to attack next in the game.
Currently, I do such tooltips using CSS. I have a parent div that holds the image of the target icon of class "info". I then have a div inside of that with class "tooltip" that, on the hover state of the "info" class that it is contained in, is shown, but on the normal state is hidden. I thought it was rather clever when I read about it, and since no JavaScript is used it works on any CSS compliant browser.
I would like to use jQuery to achieve the same effect, mostly because it would look much cleaner, but also because I believe quick and subtle animations can make such things "randomly appearing" make a lot more sense to the user, especially on the first encounter. I'm just wondering if the two will conflict. This is only one example of this, there are numerous other examples where the inability to use JavaScript would hinder the site.
So what I'm asking I guess is, how does one make a jQuery site degrade gracefully on browsers that do not support JavaScript, but otherwise do support most CSS? My goal is for the site to function on a basic level for all users, regardless of choice in browser. The animation is a good example, but I'm also worried about the more dynamic bits, like the auto-updating with AJAX, etc. Are there any good resources on how to achieve this, or do you have any advice about the best way such degradability could be achieved?
Thanks
PS: Totally irrelevant, but Firefox seems to think that "degradability" isn't a word, but "biodegradability" (with the "bio" prefix) is. Weird...
If you consider the "Cascading Order" of css, could you not just add a css style at the very end of all your previous css definition in order to cancel any css effect you currently have for tooltip effect ?
That css rule would only be declared if Javascript is activated and JQuery detected.
That way, you are sure your css tooltip effect is not in conflict with your JQuery effect.
Something like:
a.info:hover span{ display:none}
with the use of "js_enabled" class to make this css rule conditional.
You also can do it by adding css rule on the fly:
function createCSSRule(rule,attributes)
{
//Create the CSS rule
var newRule = "\n"+rule+"{\n";
for (var attribute in attributes)
{
newRule += "\t" + attribute + ": " + attributes[attribute] + ";\n";
}
newRule += "}\n";
//Inject it in the style element or create a new one if it doesn't exist
styleTag = $E('style[type="text/css"]') || new Element("style").setProperty('type','text/css').injectInside(document.head);
if(window.ie)
{
styleTag.styleSheet.cssText += newRule;
}
else
{
styleTag.appendText(newRule);
}
}
The most simple solution for Separation of CSS and Javascrip is to remove your css class
function jscss(a,o,c1,c2)
{
switch (a){
case 'swap':
o.className=!jscss('check',o,c1)?o.className.replace(c2,c1): <-
o.className.replace(c1,c2);
break;
case 'add':
if(!jscss('check',o,c1)){o.className+=o.className?' '+c1:c1;}
break;
case 'remove':
var rep=o.className.match(' '+c1)?' '+c1:c1;
o.className=o.className.replace(rep,'');
break;
case 'check':
return new RegExp('\\b'+c1+'\\b').test(o.className)
break;
}
}
This example function takes four parameters:
a
defines the action you want the function to perform.
o
the object in question.
c1
the name of the first class
c2
the name of the second class
Possible actions are:
swap
replaces class c1 with class c2 in object o.
add
adds class c1 to the object o.
remove
removes class c1 from the object o.
check
test if class c1 is already applied to object o and returns true or false.
If something can be done completely in CSS I say keep it that way. If lack of javascript in the browser is a concern, then most of the time I show the entire page unaffected.
Say for instance I'm going to use jQuery to toggle an element when a checkbox is clicked. On page load I look at the checkbox and update the element accordingly. If javascript is not enabled the element will still appear and the site will still be usable. Just not as nice.
Man, you have a browser-based game, right? You have less than 1% users with JS disabled! And that 1% is the apocalyptic number because I can BET that you have less than that ;)
Anyhow, if you are really concerned about this, just do the site without any JavaScript. And make it functional 100%. After your site works completely without any JS flavour, just start to improve with jQuery (or any other library; jQuery is the best :P ). But with careful: do not change ANY of you HTML. It's easier than it looks ;)
And yes, if you have things that work without JS (like those tooltips) keep it!

Categories

Resources