Style through components not created - javascript

New question:
So, im looking for a way to toggle the display of two css classes called hotel-in and hotel-out.
These two classes will be in all of my 22 components.
To toggle the display, im using a variable called inHotel that contains wherever the user is in a hotel or not.
when the variable is true, the hotel-in will be visible, and hotel-out be hidden.
when the variable is false, the hotel-out will be visible, and hotel-in be hidden.
How can i achieve this in the best manner?
Is it something general i could do in my main controller, that loads all the components?
Or do i have to do something spesific in every of the 22+ controllers?
Old question:
IN My main app component, where i have router outlets, i have the following:
<style *ngIf="inHotel">
.hotel-in {
display:block;
}
.hotel-out {
display:none;
}
</style>
<style *ngIf="inHotel == false">
.hotel-in {
display:none;
}
.hotel-out {
display:block;
}
</style>
but when checking, even when that the inhotel is false, it dosent create that style.
The idea is that a function will toggle this inhotel.
and everything within the other components will have a div class hotel-out and hotel-in . and that will be visible/invisible depending of the inhotel class / style .
But for some reason it wont work.
What do i need to do to make this work?
edit 2:
I could use ngclass as mentioned, and get the hotelstate by every controller/route.
But in PHP and angular1, i had the option to put that piece of style code in the main file, ( where the router-outlet is located), and it would work as supposed.
The ideal would be that i only one place changes the display of hotel-in and hotel-out to toggle display none and display block.
then everything that had hotel-in and hotel-out in the other routes/views would act according to id.
edit3:
an example of html style that would be in different routes.
<div class=hotel-in">You are in hotel , more html...</div>
<div class="hotel-out">Something completely diff here </div>
edit3:
even when im style *ngIf, it wont produce any acual tags with content on the page.
edit4:
It seems like i cant even post a style tag in the angular/angular-cli html. how come? and how can i make so i can make the style tag?
for some reason, even this wont come up to the page.
<style>
.test {
color:black;
}
</style>

You see change the style rules if they are written inside html page itself using https://github.com/deanmcpherson/angular-inline-style.
The idea is to rebuild style rules each time scope changes, by default this functionality is not provided by angular. But we can write a directive that links to style tag and recompiles it based on scope.

Related

Stimulus controller not registering CSS styles?

I'm using rails, tailwind, and stimulus together. The application also integrates hotwire, but I'm not sure how relevant that is. Most of the code was written by others, so I don't know what someone could have potentially introduced that could cause this result.
I have html similar to this
<div data-controller="modal" data-action="click->modal#doStuff" data-modal-target="myModal" class="block bg-red-500">
</div>
and a controller
import { Controller } from '#hotwired/stimulus`;
export default class extends Controller {
static targets = ['myModal']
doStuff(){
console.log(this.myModalTarget.style)
}
}
Visually, I can see a red background as expected
If I inspect the html, I can see the appropriate classes and css
but when I click on the div, it calls console.log this.myModalTarget.style and everything in the CSSStyleDeclaration object is empty strings, including display and backgroundColor
At first, I thought it might be a race condition thing. It doesn't fully make sense, but maybe for some reason the controller is getting the myModalTarget before the CSS changes are being applied on the initial page render. But then I modified the controller to this:
import { Controller } from '#hotwired/stimulus`;
export default class extends Controller {
static targets = ['myModal']
doStuff(){
console.log(this.myModalTarget.style)
this.myModalTarget.style.display = 'block'
}
}
After clicking on the div twice, it correctly applies the 'block' style to the div to the point where if I console.log(this.myModalTarget.style) I can see in the CSSStyleDeclaration object that display: block as I expected.
However, the value for backgroundColor is still showing as ""
The entire time, I can visually see a red background, but if I console.log(this.myModalTarget.style.backgroundColor) the result I get continues to be ""
I would think that if this were a race condition like the one I described, the backgroundColor details would be updated and show a value of "red" eventually.
Can anyone see an issue, or at least offer some ideas for what could possibly cause this to happen?
I feel like I've seen this behavior multiple times throughout this application, unfortunately and I haven't been able to figure out for the life of me why the behavior of things are the way they are.
You're confusing two very different things.
Element.style:
The style read-only property returns the inline style of an element in the form of 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.
And inherited CSS rules from CSS files or tags which are available through Window.getComputedStyle().
import { Controller } from '#hotwired/stimulus`;
export default class extends Controller {
static targets = ['myModal']
doStuff(){
console.log(window.getComputedStyle(myModalTarget).display)
this.myModalTarget.style.display = 'block'
}
}

Updating a simple jQuery / CSS code

I was hoping someone could help me out with this simple question: I’ve just started to learn jQuery and found a code to show hidden text after selecting an item.
I’d like to update it so that:
a.) The selected item is bold
b.) I can add placeholder text instead of starting off with a blank hidden text field
I foolishly assumed I could solve a.) by using the :active property in css, but that only works as long as the link is clicked on. (As soon as you release the mouse button it’s gone.) Just like b.), this is probably only possible by using jQuery as well? If so, would be really great if you could show me how to solve it. :)
The codes: http://jsfiddle.net/KUtY5/1/
JS
$(document).ready(function(){
$("#nav a").click(function(){
var id = $(this).attr('id');
id = id.split('_');
$("#menu_container div").hide();
$("#menu_container #menu_"+id[1]).show();
});
});
CSS
#menu_container {
width: 650px;
height: auto;
padding-left: 30px;
}
#menu_container div {
display:none;
}
HTML
<div id='nav'>
<a id="show_apps">Appetizers</a> | <a id="show_soups">Soups and Salads</a> | <a id="show_entrees">Entrees</a>
</div>
<div id="menu_container">
<div id="menu_apps">
Content of the App Section Here
</div>
<div id="menu_soups">
Content of the Soups Section Here
</div>
<div id="menu_entrees">
Content of the Entrees Section Here
</div>
</div>
Updated fiddle
You can realize a) using a custom class bold for example and the following code :
CSS
.bold{ font-weight: bold;}
JS
$(this).addClass('bold').siblings('a').removeClass('bold');
For b) I can't find any textfield in your code.
Hope this helps.
I have added some extra lines to your code and you can check it from here http://jsfiddle.net/KUtY5/483/.
You bold like this
$("#nav a").css("font-weight", 400); // First you make them thin
$(this).css("font-weight", 800); // Than you make them bold
You put placeholder like this
<div id="placeholder">
Placeholder
</div>
$("#placeholder").hide();
On the other hand I recommend you not to hide menu container. Rather hide the elements inside the menu_container. So you can put a plcaeholder in menu container and you can hide it.
To figure this out 2 questions must be asked / solved
how do you normally make text bold on a page... css right?
where do you want those styles to be defined? There are 2 places:
a. You can define it inside the javascript.
b. You can define it inside the projects css through normal methods (inline, external, embedded).
What's the difference? If you define it inside the javascript the code is self-contained. What i mean by that is you can copy/paste the JS code from one project to the next and you don't need to worry about copying related styles from the stylesheets or other sources because it's all in the JQuery that you've written.
In contrast if you define it outside the javascript in the regular places the code may not be self-contained however some find it easier to manage in the scope of that particular project because all your css is contained in one place (external stylesheet typically).
If you want to take option a, see the .css() method
If you want to take option b, see the style manipulation (toggle class in particular)
Note the examples in the above references should get you 90% of the way to understanding it.
Some final words. Learn Jquery, but i advise you to stay away from it as much as possible because it implements DOM thrashing instead of DOM caching (sizzle engine).
This video series will briefly go into why Jquery sucks for performance in the first video and the rest of the series is about how to create modular vanilla JS.
JQuery goes back and searches the DOM every time you need to make a change that is what
$.(*element*) is doing instead of just caching it.
The more nodes you have in the DOM the more processing power is used searching (because it has to go through the entire tree).
Then on top of that the more elements you have to make changes to (say if you use a css class selector) you have to add even more processing on top of that.
All this is fine if you're on a desktop, but what about a mobile platform? Where would you get all this processing power from?... It doesn't exist.

Inserting CSS for an Element from a input field

Is there any easy way to take in a block of CSS from the user from an textarea and add this styling to the styling for a specific div?
See I'm creating a simple code preview tool like codePen, so far I have two textarea inputs, one for Html and one for CSS, as the user types in the Html input this updates the preview pane, this works, now I want to do it for CSS.
CSS textarea could contain a few blocks like:
h1 {
font-size:23px;
}
.myClass {
//Somestyle
}
Now I want this CSS to be contained in the
<div id="preview"></div>
So it doesnt effect the rest of the page, so a manual example would be
$('preview h1').css('font-size','23px');
Anyway to automate this?
Do it like this. Hope it works.
Add a style block for dynamic styling.
<style id="dynamicCss">
</style>
on the apply button click handler, set the style
$('#btnApplyStyle').click(function(){
$('#dynamicCss').html('').html($('#txtaCustomCss').val());
});
See the Fiddle here.
Please use developer tools to see the new style tag added to head section.
This script simply adds rule to the document. If you don't want that behavior, you can use this plugin in combination with my logic to set scope for rule. You will need to place the style tag inside of the container and add a scoped attribute to style for it to work. Please see the documentation.
If you want to use the iframe approach instead, you'll first need an HTML document to host inside of the iframe. The iframe document should be loaded for the same origin (protocol + domain) as the host document (cross-document cross-domain stuff is tricky otherwise). With your application, this is probably not an issue.
Host page:
<iframe id="preview" src="preview.html"></iframe>
To make things easier on yourself, this iframe document could load a script with convenience functions for injecting the HTML and CSS from the host.
preview.html:
<html>
<head>
<script src="preview.js"></script>
<style type="text/css" id="page-css"></style>
</head>
<body></body>
</html>
preview.js:
function setHTML(html) {
document.querySelector('body').innerHTML = html;
}
function setCSS(css) {
var stylesheet = document.querySelector('#page-css');
// Empty the stylesheet
while (stylesheet.firstChild) {
stylesheet.removeChild(stylesheet.firstChild);
}
// Inject new CSS
stylesheet.appendChild(document.createTextNode(css));
}
Now, from the host page, you can call these functions whenever your text inputs change:
document.querySelector('#preview').contentWindow.setCSS(someCSS);
This plugin may come in handy: https://github.com/websanova/wJSNova/downloads .
Edited
Insert the text of the rules in one of the existing cssStyleSheets you have.
It will be something like
window.document.styleSheets[0].insertRule("a{color:red;}",window.document.styleSheets[0].cssRules.length)
The first parameter is the rule to insert and the second is the index.
Fiddle
The only problem here is that this will affect all the DOM on the page maybe looking for a way to add the #preview before each css rule to get something like
#preview h1{}

Progressive enhancement and "flash of unhidden content"?

I am trying to build a progressively enhanced page that works for JS and non-JS users. I would like to hide some form controls initially for JS users, but always show them for non-JS users.
My question is about how to do this without creating a distracting "visible, then instantly hidden" flash of content for JS users.
For example, in the JS version, I want to collapse part of my search form, and instead show a 'click here for extra options' button. I do this as follows:
$(document).ready(function() {
$("#extra-options").hide();
...
$("#show-extra-options").click(function() {
$("#extra-options").slideToggle();
});
});
This works, but it means that for JS users, when the page loads, the extra options are visible for 500ms or so, then they vanish. It's rather distracting.
Is there any sensible way to get around this?
StackOverflow has just suggested this answer: is this sensible? Sorry if this is now a duplicate question, but I figure it's still worth writing this question in my own language, as I didn't find the answer during searching.
Add this in your script tag in the head:
$('html').addClass('js');
Then you can use that to show and hide elements:
.hasJs { display: none; }
.js .hasJs { display: block; }
.js .noJs { display: none; }
You can hide content for either users with or without Javascript:
<div class="hasJs">Some content only visible for JS users.</div>
<div class="noJs">Some content only visible for non-JS users.</div>
As the class and CSS are in the head, the elements will already be styled when they come into existance when the body is parsed.
Demo: http://jsfiddle.net/Guffa/YuAyr/
This is a similar approach to the one in the first answer to the question that you linked to, but this is somewhat cleaner because you don't have to add a class to the html element in the markup, and the code simply adds the class instead of removing it.

create css class on the fly in codebehind

I have a search page that is used in multiple places with multiple 'themes' throughout my site. I have a few divs that can have their background color changed based on a radio button selection (whether they are enabled or not). I can do this just fine by changing the css class of the div on the fly with javascript.
However, these themes could potentially change, and the background color is grabbed from a database when the page is created. Right now I do this in the C# codebehind:
string bgStyle = "background-color:" +theme.searchTextHeaderColor +";";
OwnerSearchHeader.Attributes.Add("style", bgStyle);
In the Javascript I need to change this color to make it look disabled, and when the user clicks back to this div I need to re-enable it by changing it back to its original color. But since I only knew this color in the code-behind, I don't know what it was in the Javascript.
So my thought was to create a css class in the resulting HTML page when the page is loaded with the background color I need. Then I could simply switch from the divEnabled and divDisabled class in the javascript. But I'm not exactly sure how to do that.
Alternatively I could create a hidden element, assign it the 'enabled' style, and use that as a reference in the JavaScript when enabling my div. This seems like a hack but maybe its the easiest way. I'm still new to a lot of this, so I'd appreciate any suggestions. Thanks for the input!
So my thought was to create a css class in the resulting HTML page when the page is loaded with the background color I need. Then I could simply switch from the divEnabled and divDisabled class in the javascript. But I'm not exactly sure how to do that.
Yes, this is the anser; do this. In the <head> of your document add a <style> and put your CSS in there like so: (my Asp.NET is a little rusty so forgive me if it has some hicups ;) )
<style>
<!--
.divEnabled {
background-color:<%=theme.searchTextHeaderColor%>;
}
.divDisabled {
background-color:gray; /* or wtv */
}
-->
</style>
You could also put it in an external CSS file, which may be a good idea.
Then write some JavaScript to add/remove the class attribute (I'm going to ask that you don't call is the "CSS Class" ;) )
var ownersearchheader = document.getElementById("<%=OwnerSearchHeader.ClientId%>");
// changing the class attribute to `divDisabled`
var newClassAttribute = ownersearchheader.getAttribute("class").replace(/\bdivEnabled\b/, "divDisabled")
ownersearchheader.setAttribute("class", newClassAttribute);
// ... or,
// changing the class attribute to `divEnabled`
var newClassAttribute = ownersearchheader.getAttribute("class").replace(/\bdivDisabled\b/, "divEnabled")
ownersearchheader.setAttribute("class", newClassAttribute);
This is indeed a mouthfull, so, like #Haydar says, you might want to use jQuery, which offers easy-as-pie addClass(), removeClass() and toggleClass() methods.
You can use the jquery .toggleClass method.
Description: Add or remove one or more classes from each element in the set of matched elements, depending on either the class's presence or the value of the switch argument.
Here is the link to the api doc.
Jquery API

Categories