Dynamically change style


#1

how can i dynamically change the style of an element.

<nav class=“nav” style=“display:{{shownav}}”>
<a href="{{pathFor ‘home’}}">Home</a>
<a href="{{pathFor ‘nutrition’}}">Nutrition</a>
</nav>

<button type=“button” class=“hamburger”>hidemenue</button>

and in the .js:
Template.navigation.events({
‘click .hamburger’: function(){
shownav=“none”;
alert(shownav);
}
});

it alerts “none” but the nav doesn’t change to display:none;

i thought this updates automatically (and hopefully with no latency) …

i can’t get document.getElementByID to work. are those times over?

any help is highly appreciated.

thx


Dynamic style and class name of element
#2

No you need a helper which returns none. Generally this kind of small examples return a session variable which is being returned.

Generally when you use things like bootstrap you can implement this with a .hidden class.

Btw try this.find() for getting Dom elements in helpers


#3
Template.navigation.events({
    'click .hamburger': function(e,t){
      t.$('.nav').toggleClass( "hidden" )
    }
});

add some css

.hidden {
  display: none;
}    .hidden {
  display: none
}

if you only want to hide it, use t.$('.nav').addClass( "hidden" ) or t.$('.nav').hide() instead, t.$(’.nav’).removeClass( “hidden” )or t.$(’.nav’).show() would show it again

You could also .css() method, but that’s unnecessary when you have the above approaches.


#4

Right also a good one! You could even keep state in the template if needed. As basic example I prefer the session trick but you are totally right!


#5

Just for the sake of variety, you can also achieve similar thing by using a boolean helper and {{#if shownav}}. It won’t keep the state though.


#6

as you mentioned, reactiveVar do not keep state, but if you use ReactiveDict it is same as Session. And these keep states between hotcode pushes.


#7

thanks. i am reluctant to learn bootstrap or jquery and how to integrate it and all, since i really just want to change the style of an element.
this used to be really easy with i.e. document.getElementById(“xyz”).style.display = “none”.

i don’t understand the helper. is a helper the only way to dynamically change a variable in the html, or in other words, can this not be done with an event directly?

i am really trying to understand the concept, i thought the idea is that variables magically update and can be passed into the code via spacebars.

i am not there yet, :slight_smile:

thanks, i appreciate you taking the time to help me.


#8

garilla shows the direct way but it’s not really a Meteor way. The issue off course is that it has it’s limits. For example: If you want to make one element hidden and the others visible you start programming loops in the event handler etcetera. Then it becomes more a mess. Generally in Meteor with Blaze the “correct” way is with a separate event handler and separate helper.

In react it’s more direct (even with inline events) which might fit your idea more.


#9

hi garrilla, thanks for taking the time, i appreciated it.

your solution is jquery, right? i am wrestling with meteor and want to accomplish this with basic css and javascript. dynamically changing the style is super basic and important, i am really trying to understand how this works in meteor.

i thought the idea in meteor is that it magically updates all variables and that they can be sent to the html with events (or helpers).

on click - change style of an element. any ideas how to do this directly.

sorry for asking again, but i am really lost at this point.
thx! m!


#10

hi brajt, sorry, i don’t understand.

my problem is: on click - change style of an element.
this used to be simple with

document.getelementbyid(‘bla’).style.display = “none”;


#11

Meteor has a wide use of jQuery, it is part of the templating system http://docs.meteor.com/#/full/template_$

Meteor does not update anything magically, you will still need to update the reactive source, such as a Session variable. What is magic about meteor is those changes are tracked through the app where you use them. So in the following example, when you click on the button, the Session variable is set to hold the value of “none” and the helper ‘magically’ sees this change and tells the template, which makes the change

<template name="nav">
  <nav class="nav" style="display:{{shownav}}">
    <a href="{{pathFor 'home'}}">Home</a>
    <a href="{{pathFor 'nutrition'}}">Nutrition</a>
  </nav>

  <button type="button" class="hamburger">hidemenue</button>
</template>

 Template.navigation.helpers({
    shownav : function () {
      return Session.get("shownav") || "block"; // if Session.get("shownav") is undefined, use "block" instead
    }
  })    

  Template.navigation.events({
    'click .hamburger': function(){
      Session.set("shownav","none");
    }
  });

another way, more in keeping with your ‘direct approach’ would be to use in the event map

t.find('#nav').style.display = 'none'

by the way, if wanted to still use vanilla js document.getElementById('yourElementId').style.display = "none"; would still work. However, in the context of your first post you would need to add an id attribute to the <nav> element or use document.getElementsByClassName('nav').style.display = "none";


#12

This is actually something I’ve been struggling with as well. So is jQuery the way to go when, for instance, toggling classes on an element? Or would you rather rely on session variables/reactivevars? I suppose you could do it both ways, but I was under the impression that Blaze should be responsible of manipulating the DOM out of performance benefits, rather than doing it manually with jQuery.
I’m just looking for “the Meteor way” of doing things.


#13

[quote=“Andi, post:12, topic:11829”]
This is actually something I’ve been struggling with as well. So is jQuery the way to go when, for instance, toggling classes on an element? Or would you rather rely on session variables/reactivevars? I suppose you could do it both ways, but I was under the impression that Blaze should be responsible of manipulating the DOM out of performance benefits, rather than doing it manually with jQuery.
[/quote]The example in this topic is very small. Try to make a testcase with data. For example show some text when no records available etcetera. Then you will find that the template way actually makes sense. If it’s really javascript/frontend only stuff like jQuery things it is different.


#14

In most cases you are not toggling stuff just to affect UI.
But there is real data/logic behind it and clicking something do also some backend operation.
When dealing with latency compensation, it is much easier to update reactive var in callback and revert in case of error than manipulating DOM directly and using this as indication that something failed.
And you can do more stuff with reactive var etc…


#15

hi brajt, sorry, i don’t understand. my problem is: on click - change style of an element.

No. Your main problem is how to make that navigation hidden, not how to change styles of an element (which is only one of the ways to achieve it).

Do not focus on the implementation of an algorithm you thought of, but on the feature you want to build. Otherwise, in a more complex situation than this one (which is a basic one so it doesn’t matter what way you chose) you will get stuck trying to implement some difficult, not optimal algorithm even if there are few other, better solutions to the same problem. This will lead you to lose both time and power.

That’s why I presented an alternative solution to show and hide elements, that can be helpful for you in the future, depending on a particular case.


#16

In addition the feature needed here is already available in existing frameworks like bootstrap which you can use by just taking a package. If you need something always take a look to see if you can just use an existing, proven and tested solution. Sure in the beginning so you can speed up working on your real app features.


#17

jQuery is a fast and concise JavaScript Library that simplifies HTML document traversing, event handling, animating, and Ajax interactions for rapid web development.

Source: https://github.com/meteor/meteor/tree/devel/packages/jquery

Since Blaze only makes the smallest possible updates to the DOM, apps written with Blaze can take advantage of jQuery plugins or other JavaScript libraries that modify elements in your app — including the same elements managed by Blaze.

Source: http://meteor.github.io/blaze/

Blaze is an overhaul of Meteor’s rendering system – including Spark and the Template API – to support fine-grained DOM updates, jQuery integration and simpler APIs.

source: https://github.com/meteor/meteor/wiki/Using-Blaze

Event delegation uses jQuery’s implementation rather than a custom-built global event capturing system. Attaching event handlers closer to the templates that declare them has performance benefits, and jQuery’s event implementation is the best out there at papering over IE quirks, and even differences in more recent browsers. (Early Android browsers, for example, are now in the picture.) Meteor developers who already use jQuery also benefit from an increasing level of interoperability. For example, when Meteor removes elements from the DOM, it also cleans up jQuery event handlers that you bound external to Meteor.

Source: https://github.com/meteor/meteor/wiki/Using-Blaze#events-use-jquery

The new rendering model doesn’t replace a template when its data changes, it just replaces its parts, like text nodes and element attributes. This approach is not only more efficient, it means that DOM elements generally remain in place as long their parent elements and templates are not removed by an #if, an #each, or other conditional logic. Even if a template’s data context changes, or its parent’s data context, or an attribute on an enclosing element, the changes are reactively propagated to where they affect the DOM, rather than causing whole parts of the DOM to replaced as before. Structural changes to the DOM or template hierarchy are only made when a clear reason exists, and you can expect critical elements such as text fields and videos to be automatically preserved.

Thanks to this new model, Meteor will no longer assume it has complete control over rendered templates. This allows jQuery plugins to mostly work out of the box, even in the presence of template re-renders. For example, an element created with <div class=“foo {{bar}}” interoperates perfectly with jQuery’s $(’.foo’).addClass(…). Here’s a short video demonstating using jQuery UI to create a reorderable list.

source: https://github.com/meteor/meteor/wiki/Using-Blaze#fine-grained-updates-that-play-nicely-with-jquery
The ‘short video’ is available here: https://www.youtube.com/watch?v=ISNEhPG0wnA

I think you get the picture.


#18

garilla, you are the man. this is a great answer, thank you very much!


#19

i totally agree. bootstrap is just it’s own thing - getting it to run, understanding what it is, learning a syntax. i tried to avoid this, since step one of my app is mostly static text (i don’t want to overexcert myself, so i took it easy in my concept). but bootstrap seems fun. same with jquery. i just should be doing something else - like producing the actual content.

meteor claims to make it easy to build an app, and it’s true, i saw in the tutorial, that the whole communication between server, db, clients, etc. is solved very ellgantly. but when i tried to do something even more simple - slap up a few pages and a menue, i got stuck really badly. all of a sudden jquery and bootstrap as TWO more alien concepts (task one: understand what it actually IS …) show up. i tried to hide from them, since what i am trying to achieve is simple.
and then iron router!!! ??? it’s a total mystery and unlike meteor it seems secretive and not too eager to explain to the world.
luc, i know you are probably not the right addressee for this, but i suspect the meteor folks are listening and i would like to give this as a feedback:

meteor is awesome, and the community is great and fast, but building a bunch of static pages with a simple navigation has been quite challenging (painful) and distracted me from my actual goal: build an app.
a tutorial on this would be cool. iron router???!! :slight_smile:
:slight_smile: thanks! <<


#20

and then iron router!!! ??? it’s a total mystery and unlike meteor it
seems secretive and not too eager to explain to the world.

You mean the concept of a router and why it is needed in a website is unfamiliar for you as a web developer?