Angular2 respond to div size - html

I am looking for some advice on how to build my first Angular2 app.
I have been playing around and done some little proff of concepts to get my head around how it works, and now want to check that I am taking the right approach as I think there is likely a better way to achieve what I want.
The project:
I am building myself a dashboard that will consist of tiles/widgets that fill the screen. Each will show different information on some topic. Each widget will also have three states/sizes: small, medium & large. Each widget will show a different amount of information based on its size.
Exg. if the widget showed the time, it may work like so:
Small: Display the time in a small font.
Medium: Display the time in a large font.
Large: Display the time in a large format and a few other timezones in a small format.
All widgets will start as medium. Clicking any widget will make it large and every other widget small. Clicking a large widget will make all widgets medium again.
My approach:
I have build an app.component that contains 1 div per widget, along with a few sample widgets that get loaded in. I would like to separate everything and be as modular as possible, so I plan that app.component will deal with positioning, moving and sizing the divs based on the screen size and number of widgets. As a result, I intend on using a pretty front end that takes care of where to position the divs. It will then also tell each widget if they should be small, medium or large.
The widget will then be responsible for displaying the correct amount of information.
Here is where I run into trouble - The app.component sets the widths as a percentage - currently 20%, 50% and 80%. I want the contents of the widget to display based on the width of its div, including as the window size changes, but I cannot pass the width in as the app.component doesn't know it (it only sets the width as a %).
What I have come up with works, but I'm sure there is a better way...
app.template.html:
<div class="widget-container" (click)="onClick1($event);" [style.width]="widget1Width + '%'"><widget-1></widget-1></div>
<div class="widget-container" (click)="onClick2($event);" [style.width]="widget2Width + '%'"><widget-2></widget-2></div>
<div class="widget-container" (click)="onClick3($event);" [style.width]="widget3Width + '%'"><widget-3></widget-3></div>
app.component.ts:
public widget1Width=50;
public widget2Width=50;
public widget3Width=50;
#ViewChild(Widget1Component) widget1: Widget1Component;
#ViewChild(Widget2Component) widget2: Widget2Component;
#ViewChild(Widget3Component) widget3: Widget3Component;
onClick1(value:any) {
this.widget1Width=80;
this.widget2Width=20;
this.widget3Width=20;
this.widget1.parentResize(this.widget1Width);
this.widget2.parentResize(this.widget2Width);
this.widget3.parentResize(this.widget3Width);
}
widget1.component.ts:
export class WidgetWeatherComponent {
panelLarge = 0;
public widgetWidth:any;
parentResize(value:any) {
console.log(value);
this.widgetWidth=value;
}
}
widget1.template.html:
<div #widget1ParentDiv>
<div *ngIf="widget1ParentDiv.clientWidth>=700"> ... </div>
<div *ngIf="widget1ParentDiv.clientWidth>=300 && widget1ParentDiv.clientWidth<700"> ... </div>
<div *ngIf="widget1ParentDiv.clientWidth<300"> ... </div>
</div>
I understand that I can also change the class and use CSS if I am changing format of text ect.
While I am very happy to take advice on the arranging, sizing, front end stuff, my main focus atm is to work out the right approach for the widgets so that I can go ahead and build a number of them. The code to resize things in app.component.ts is just to get things moving.
The problem
The main concern I have is that accessing widget1ParentDiv.clientWidth seams really bad! Normally I would handle the screen size change in the css using #media, but as each widget has 3 'states/sizes' (small, medium, large) that would cause too much effort. I really want to do exactly like #media, but for the parent div. I have read about that a little, but my understanding is that it doesn't really exist out of the box.
My other frustration with this approach is that I have to keep repeating *ngIf="widget1ParentDiv.clientWidth>400" where I would rather define that somewhere else and use *ngIf="large", but I cannot see how to do this without needing to respond to the screen size changing and update a variable.
Please let me know if this doesn't make sense or more information is needed. Any advice/thoughts would be appreciated.

Related

Web App (Svelte): How to divide screen in distinct sections

I am creating a program calculating flow in piping systems. In the user interface, the program contains a graphical drawing diagram, a ribbon on top of the screen containing functions helping the user drawing, and possibly a side ribbon with additional functions.
Here i've included a picture explaining my intentions:
As of now, my approach to achieve the division of screen, is to have nested elements in a tree structure, where the main branches are the divisions of the screen (the functional areas and the graphical drawing area). In the graphical area, the objects drawn in this area are positioned using absolute coordinates w.r.t. the drawing area element, and are also nested inside this element. As of now, this is the progress that has been made (grey area is the graphical drawing area, the red area is going to contain functions):
To obtain this current division of screen, the general html code looks like this, and the general css code uses mainly certain flex-settings.
App.svelte:
<main class="h-screen w-screen">
<section class="screen">
<!-- Creates a main bar. Will contain several functions and options. -->
<Bar/>
<!-- Creates the drawing board. -->
<DrawBoard/>
</section>
</main>
DrawBoard.svelte:
<section class='board' on:mouseup|self={$selected != null ? createObject : null}>
<!-- Displays all objects contained in the MainDataStructure. -->
{#each $editor.objects as object}
<ObjectOnBoard bind:object={object}/>
{/each}
<ObjectSelection/>
</section>
Using this method leads to several problems. As can be seen in the current progress, one object is moved to the edge of the screen, but instead of going out of the screen, it appears above the functional area. I would want to elements inside elements (the object inside the graphical area) disappear if they went out of the element, as if the graphical area was a screen of its own just like the whole tab. This leads me to my question:
Is this the right approach to achieve the user interface with area divisions i want? It seems so easy to not include a certain combination of setting in css, and then the different sections of the screen will intersect each other. I want to imagine that one solution would be to create one html body for each area, so that elements of each area would never intersect each other (i know that a document only has one body). Is there a totally different approach than the one shown, or do i have to find just the right (imo. kludgy) css settings, so that i make the visuals work as intented? And if this is the right approach, what kind of css-settings and other settings should i look into?
Look into CSS grid for the main layout. (Though this can be done with two flex layouts as well.) You can, for example, use grid-template-areas to set up named areas and then position element in them.
Elements intersecting other areas is just an issue of overflow. Either let the individual sections overflow with scroll (auto/scroll) or cut off their contents (hidden).

Change the size of the label in an IPython notebook widget

This is really a trivial problem, but it is still annoying. I'm writing a tool to allow a user to set a bunch of numerical parameters for an analysis in the IPython notebook. I've set it up as a bunch of FloatTextWidgets in a ContainerWidget. They have rather long labels like "Number of Posture Points" or "Background Disk Radius". They don't line up nicely. This is because of the length: as explained on this page, "The label of the widget has a fixed minimum width. The text of the label is always right aligned and the widget is left aligned... If a label is longer than the minimum width, the widget is shifted to the right."
My labels exceed the "fixed minimum width". What I want to know is how to change it. I have poked around in the Widget source code, and I can't find this anywhere.
EDIT: In response to #Jakob, here is some code, and here is a screenshot
In this example, "Threshold:" is small enough to fit within the label width, but all the others are too long.
To change the style from within the notebook:
from IPython.display import HTML, display
display(HTML('''<style>
.widget-label { min-width: 20ex !important; }
</style>'''))
use the layout argument for each widget. Here's the link to the documentation: https://ipywidgets.readthedocs.io/en/latest/examples/Widget%20Styling.html
In particular it says, you an define description and widget separately in an HBox like this:
from ipywidgets import HBox, Label, Layout
label_layout = Layout(width='100px',height='30px')
HBox([Label('A description',layout=label_layout), IntSlider()])
Well, I found the narrow answer to my question: the minimum field width is defined in site-packages/IPython/html/static/style/ipython.min.css (located wherever your python libraries live -- on my Max that is /Library/Python/2.7/), where widget-hlabel is defined by
.widget-hlabel{min-width:10ex;padding-right:8px;padding-top:3px;text-align:right;vertical-align:text-top}
min-width:10ex is the relevant part.
Although one can override this for an entire document, I don't see an easy way to change it one widget at a time. It would have to be done on the JavaScript side, since the FloatTextWidget class doesn't give separate access to the label component of the Widget from the python side. That would require developing a custom widget subclassed from FloatTextWidget, which seems like way too much effort for such a simple problem, and fragile to boot. At least, that's the only way I see to do it -- corrections welcome.
Instead, I have decided to eschew altogether the automatic labeling of widgets with their descriptions, and instead construct each label as an HTMLWidget, which gives me complete control over its appearance. Here's what that looks like:

Increasing/Decreasing font size on button click

I am sure you guys must have seen that font resizing option on some website where they display alphabet "A" in small, medium and large sizes clicking on which changes the font size of website. I have two questions:
What is that thing called actually? Like if there is a term to describe it?
What arguments can I give against using this on website? One of the client has asked to incorporate it in website and I don't see any real benefit in using it so what arguments can I give to client against using it?
It is called "font size change options", or "font resizer".
Here is a simple and minimal 5 lines of code jQuery tutorial: http://www.programming-free.com/2013/12/increase-decrease-font-size-jquery.html
A bit of the code that enlarges the font size:
newFontSize= parseInt($('#content').css('font-size')) + 2;
$('#content').css('font-size', newFontSize);
The user could just use CTRL+ in browser. The problem is that the final user doesn't know this trick.
This is a fast and simple implementation, no need to convince the client against it. I find myself getting hard to see clear small text after 10 hours of programming. Maybe the client has sight problems and needs to address others like him.
"As of jQuery 1.6, .css() accepts relative values similar to .animate(). Relative values are a string starting with += or -= to increment or decrement the current value. For example, if an element's padding-left was 10px, .css( "padding-left", "+=15" ) would result in a total padding-left of 25px."
Reference
So to do that you can use a function callback which will return the actual value, then you return the new value.
Like the following.
$("#fontPlusBtn").click(function (){
$("#textDiv > *").css("font-size", function(i, value) {
return parseInt(value) * 1.1;
});
});
Working Demo for Increasing Font Size on Button Click:
I hope this helps you as you described font size change on Button Click.
What is the target group of your client? Adding such feature is generally considered good practice of web accessibility. It doesn't really take up too much space on the screen and doesn't mess with the design but gives users the options to enlarge the text in case they are having troubles reading the text.
I wouldn't try to argue against it but instead find a neat way to implement the functionality.
BBC's accessibility policy is a good read: http://www.bbc.co.uk/accessibility/best_practice/policy.shtml

What is the best practice to place an icon on the right of the text input field

I'd like to place an icon in the right part of the text input. I'd use a background image with the following CSS setting:
input[type=text].dropdown {
bachground-image: /images/down.png
background-repeat: no-repeat;
background-position: right center;
}
I foresee the following problems:
the text I will put into the input will overlap the image unless I will made some extra styles for the input basing on the image size (if the size is not predictable it will a real headache!)
if the input size will change - I will have to scale the image by my self
if I will need to place one more image on the left I will not be able to do it
Is there any better practices to do such a thing?
the text I will put into the input will overlap the image unless I will made some extra styles for the input basing on the image size
It is common to simply apply padding-right to the element in this case in order to "clear" the background-image. But you do obviously need to know the approximate size of the image....
However, you seem to have a lot of "what-ifs", which makes me think you are over engineering (or over thinking) the problem? Unless perhaps you are wanting to allow users to customise the interface? But even then I think these could be solved in different ways.
if the size is not predictable it will a real headache!
Why is it not predictable? Something like this would normally be solved at the design stage and is very predictable. If you are allowing users to submit images, then you should perhaps resize the image when submitted.
if the input size will change - I will have to scale the image by my self
That will really depend on how the input size changes. If the element simply grows longer then you may not need to change anything. But again, this would normally be something which is solved at the design stage.
if I will need to place one more image on the left I will not be able to do it
Why would you need to place an image on the left and the right - at the same time? I can imagine if you needed to account for right-to-left text then you might need to swap the image placement, but not normally both at the same time?
However, you can actually use multiple background images with CSS3, as long as you don't need to support IE8 and earlier. Ref: http://caniuse.com/multibackgrounds
But if you did have multiple background images, how would you deal with assigning event handlers (which seems to be what you are doing with the "dropdown")? You'll need a separate element.
w3d raises very good concerns. A lot of the "if's" you are thinking about don't seem too common. And if they do happen because you are setting up an environment that will allow it or need it (hard to say until I see the actual environment) then what you should do is use dynamic code to make the adjustments.
Here is an example I made with the most basic way to do what you're doing
JSFiddle Demo
Now, as far, as covering your 6 on the possibility that another image would be inserted, etc. You will need the following logic:
Assuming the user is the one inputting the images you want to stack next to each other. Have the image post to the database
Dynamically echo it with a conditional statement that says if image != 0 then echo as many as you want
Each instance of a below would be dynamically done as I explained above
HTML
<div class="form-group">
<label for="txtDate">LABEL</label>
<input type="text" class="txtcalendar" id="txtDate" placeholder="E.g. mm/dd/yyyy" />
<span>
<img class="calendar"src="https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcRkW2p-FHKOHJhdBUX1to1VfGMWn18eGlZgDRU5YHLrzw8rkDgB" alt=""/>
<img class="calendar"src="https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcRkW2p-FHKOHJhdBUX1to1VfGMWn18eGlZgDRU5YHLrzw8rkDgB" alt=""/>
</span>
</div>

large number of hidden divs in a pge

Will I have to face any problem if i have large number of hidden divs in my page ??
i mean that in my page there is a loop which contains some hidden divs and some buttons which when clicked shows one of the hidden div...
i just want to ask that will i have to face any problem with these hidden div..
the code here is just an example ....
any help will be appreciated..
thanks in advance
<?php
for ( $a = 1; $a < 10; $a++ ) {
<div style='display:none'>
content goes here....
</div>
}
?>
I have many pages with over half a million divs that work fine. Probably the most important thing with many hidden divs is that you enclose the hidden divs within another element which is of fixed layout. If you have a massive amount of html and a fluid layout and you change the visibility of an element, the browser must calculate all the layout again which can be slow and give the user poor responsiveness.
No problem! but It will be indexed but can be frowned upon by Google if you are hiding/showing content for SEO reasons. In other words, what Google sees should be what the user sees when clicking the link.
No problem! But if you are having more and more your websites load will be heavy. That might cause slower performance and perhaps hangs up. It would take loading time too..
That depends on what you try to do.
If you fill your hidden divs with images and other heavy stuff, it all will be loaded immediately with page and may slow things down. Also, browsers would still take time for parsing everything you hid (but that is actually not much time).
So, if you are talking about like 1000x1000 grid of buttons or something like that (for making kind of a game maybe), it will result in sad performance.
If you are talking about dynamic loading of a lot of heavy content, like a whole facebook timeline, it won't work well neither.
But if you just want to show users some blocks, which would work okay if you didn't hide it at all, you will have no problems.

Categories