SAPUI5: Create GenericTile with icon centered - html

I would like to create a tile which is inherited from sap.suite.ui.commons.GenericTile and displays only an icon (centered in the middle of the tile). Due to the centering, I cannot use the standard aggregations or property as they have the icon placed at a specific position (which is on the left lower side).
I have tried the following but with no luck:
$.sap.declare("myAddTile");
sap.suite.ui.commons.GenericTile.extend("myAddTile", {
init: function() {
// do something for initialization...
sap.suite.ui.commons.GenericTile.prototype.init.call(this);
},
renderer: function(oRm, oControl) {
var oPlusIcon = new sap.ui.core.Icon({
src: 'sap-icon://sys-add'
}).placeAt(oControl);
sap.suite.ui.commons.GenericTileRenderer.render(oRm, oControl);
}
});
The resulting tile is empty...

I played around a bit with the renderer and came up with this solution:
rm.write("<div");
rm.addClass("myAddTileIcon");
rm.addClass(oControl.getSize());
rm.writeClasses();
rm.writeAttribute("id", oControl.getId() + "-icon");
rm.write(">");
rm.renderControl(new sap.ui.core.Icon({
src: 'sap-icon://sys-add',
size: "5rem"
}));
rm.write("</div>");
Of course, the right alignment of the icon needs to be taken care of, too:
.myAddTileIcon .sapUiIcon {
font-family: SAP-icons;
font-size: 5rem;
line-height: inherit;
cursor: default;
text-align: center;
display: block;
padding-top: 20%;
vertical-align: middle;
color: grey;
}
If someone has a comment how to solve this in a more elegant way, please post.
Cheers

Related

Is there a pure CSS way to detect whether the text has wrapped and give it different styles?

For example, I have a button with a long text on it:
[Please click this button for more information]
Since the text is very long, on some small screens, it would be wrapped.
[Please click this button for
more information]
I want to make the text-align as left when it's wrapped and center when it's not.
For instance:
Is there any pure CSS solution for it?
There is no general way to apply different styles to elements at different widths using only CSS. This is a very good thing because it could be very easily broken, as the following example shows (using pseudocode with the form of CSS media queries).
#element( min-width: 600px ) {
button {
width: 500px;
}
}
#element( max-width: 600px ) {
button {
width: 700px;
}
}
CSS
The only way to do it using pure CSS is to find the window width at which the button text is rendered over two lines, and write a media query for that width. For example, if you test your page and find that when it is sized at 500px width or less the button is squished so that the text renders on two lines, you might add the style:
.button {
text-align: center;
}
#media( max-width: 500px ) {
.button {
text-align: left;
}
}
Of course, the exact point at which the text is rendered over two lines may differ depending on browser/layout engine.
JavaScript
Using JavaScript you can test the height of each button when the page loads and when the page is resized. If you know the height of the button when it has a single line of text and the button's height is greater than that, then you can apply a different style to those buttons.
For example:
function buttonStyles() {
let buttons = document.querySelectorAll( 'button' )
for ( let button of buttons ) {
if ( button.offsetHeight > 40 ) {
button.classList.add( 'left' )
} else {
button.classList.remove( 'left' )
}
}
}
window.addEventListener( 'load', buttonStyles )
window.addEventListener( 'resize', buttonStyles )
button {
width: 300px;
display: block;
text-align: center;
margin: 10px;
font-size: 15px;
line-height: 15px;
padding: 5px;
}
button.left {
text-align: left;
}
<button>A single line</button>
<button>Two<br>lines</button>

How do I make the width of each character the same?

I'm using a custom font. The design doesn't allow me to change font.
While the number change, the content after it got pushed around due to the different width of digits.
Is there a way to make all the digits same width? I don't want to assign the width of the span component because I need this to be inline and the width should be determined by the number of digits it has.
const numberDom = document.querySelector('.number');
let number = 0;
function tick() {
number += 1;
numberDom.innerText = number;
}
setInterval(tick, 50);
p {
font-size: 1rem;
}
.number {
font-family: 'Carter One', cursive;
font-size: 1.5rem;
color: #365;
}
.number::after {
content: 'pt';
font-size: 0.75em;
margin-left: 0.1em;
color: #587;
}
<link href="https://fonts.googleapis.com/css?family=Carter+One&display=swap" rel="stylesheet">
<p>You got <span class="number"></span>, good job!</p>
Okay so first I made a function that it changes the looks of your <p>. after that the only solution I could find to stop the jiggling was to put the number in an inline-block.
Here is my fiddle
Edit
I made a script that changes the width of the inline-block. It's an if statement that if your number is 1000 or higher the width will change.
Fiddle
You can always make an else if with over 10000 et cetera.
Change your number class as:
.number {
font-family: 'Carter One', cursive;
font-size: 1.5rem;
color: #365;
width: 56px;
display: inline-flex;
}
You can use
.numbers{
font-family: Tahoma;
}
It will fix the number jumping/height abnormality issue.

right aligned placeholder in <input>

I have a text input that I want to be specifically for currency. Inside the text field, it should say [$Other CAD]."$Other" should be aligned left and "CAD" should be aligned right, I currently just have a bunch of spaces between the "$Other" and the "CAD". This isn't ideal for different browsers, etc. Is there an easy way to get only the "CAD" portion of the placeholder to align right so it'll always fit regardless of the browser? Also, can I set two different text colors for the placeholder? For example, have the "$" and "CAD" in grey and the "Other" in black
<style>
.donation-amount-input {
height: 65px;
font-size: 34px;
}
.form-control::placeholder {
font-size: 34px;
}
#S {
color: #aaaaaa;
position: absolute;
font-size: 36px;
padding-left: 10px
}
#Other {
position: absolute;
font-size: 36px;
padding-left: 35px;
}
#CAD {
color: #aaaaaa;
position: absolute;
font-size: 36px;
padding-left: 40%;
}
</style>
<body>
<p onclick="fakePlaceholder()" id="S">$</p>
<p onclick="fakePlaceholder()" id="Other">Other</p>
<p onclick="fakePlaceholder()" id="CAD">CAD</p>
<input
type="text"
onselect="fakePlaceholder()"
class="form-control donation-amount-input"
id="other-amount"
/>
</body>
<script>
function fakePlaceholder() {
var S = document.querySelector('S');
S.style.display = 'none';
var Other = document.querySelector('Other');
Other.style.display = 'none';
var CAD = document.querySelector('CAD');
CAD.style.display = 'none';
}
</script>
You can't do that with a placeholder, you will have to create a fake one with javascript for the effect. You have to add three elements : one for the $, one for Other and one for CAD. Then you can styles them and positioning them with position: absolute; in the input to create a fake placeholder. ( Don't forget: you can't put html elements in an input, so you will have to wrap the input and the three elements into another element so you position everything according to it ).
After that, you will have to use javascript to hide this fake placeholder when someone clicks or moves with keyboard on it.
Try something, and if you need help, come back here and show us your code.

How to fix star rating css and html

So basically I have a ionic mobile application. One of the many modules in the app is the review and ratings. So by implementing such module, I added stars in which a user can click whether he wants to rate a certain user by tapping one star to five stars. So the problem here is that, once a choose a certain star, example 5 then he taps other parts in the app the stars will be gone.
After choosing a star:
and the user taps other than the star rating, the star choosen will be gone. How to fix such error?
Code below:
html
<div class="rating">
<!-- <ion-icon name="star"></ion-icon> -->
<span (click)="rate(5)">☆</span>
<span (click)="rate(4)">☆</span>
<span (click)="rate(3)">☆</span>
<span (click)="rate(2)">☆</span>
<span (click)="rate(1)">☆</span>
CSS
page-review {
.rating {
display: flex;
justify-content: center;
}
.rating>span:hover:before {
content: "\2605";
position: absolute;
}
.rating {
unicode-bidi: bidi-override;
direction: rtl;
}
.rating>span:hover:before,
.rating>span:hover~span:before {
content: "\2605";
position: absolute;
}
.rating {
unicode-bidi: bidi-override;
direction: rtl;
}
.rating>span {
display: inline-block;
position: relative;
width: 1.1em;
font-size: 40px;
color: #F2AF01;
}
.rating>span:hover:before,
.rating>span:hover~span:before {
content: "\2605";
position: absolute;
}
p{
font-size: 20px;
}
.review-description{
margin-bottom: 50px;
}
}
you can use ionic-ratings
when you do all steps to install and import then you can use it like
$scope.ratingsObject = {
iconOn: 'ion-ios-star', //Optional
iconOff: 'ion-ios-star-outline', //Optional
iconOnColor: 'rgb(200, 200, 100)', //Optional
iconOffColor: 'rgb(200, 100, 100)', //Optional
rating: 2, //Optional
minRating:1, //Optional
readOnly: true, //Optional
callback: function(rating, index) { //Mandatory
$scope.ratingsCallback(rating, index);
}
};
$scope.ratingsCallback = function(rating, index) {
console.log('Selected rating is : ', rating, ' and the index is : ', index);
};
Well, you're using :hover and a really interesting combination of inverted HTML order and text direction switching in order to use the ~ general sibling selector to fill the previous stars, which is awesome.
But you're making so by using CSS :hover, which is really meant for when the mouse hovers an element on desktop. As soon as the pointer leaves, the :hover state ends, and therefore, any style that was applied on hover by CSS will go away.
On mobile, there's no really :hover state as theres no mouse pointer to begin with, but some engines use the taps instead.. but then again, when you tap anywhere else, the "pointer" will no longer be over the element, so the :hover state ends.
I'm not familiar with ionic, but it seems you'll need to modify whatever your rate() method is (or add another method on click) to display the current value.
A simple approach from the CSS point of view would be to use a CSS "selected" class identical to the :hover state, which you would add to the selected element on click (and remove from the others if present).
From the CSS point of view, should be something like this:
.rating>span.selected:before,
.rating>span.selected~span:before {
content: "\2605";
position: absolute;
}
To keep it DRY, you might just add it on the same rule as you're setting the hovers
.rating>span:hover:before,
.rating>span:hover~span:before,
.rating>span.selected:before,
.rating>span.selected~span:before {
content: "\2605";
position: absolute;
}
BTW, you have 2 identical copies of your .rating and .rating>span:hover~span:before rules, and 3 identical copies of .rating>span:hover:before rule, you might want to clean that as well.

How to prevent text from getting pushed left and right when adding text or removing text

I am working on front end part of a loading page in an Angular project. I want to show loading with three dots starting from one dot then two and then three to create a sense of loading. But when I add the dots the text of loading, it gets pushed to the left and as dots reduces to one the loading text is moving to the right.
The code is written in angular
Here is the code:
For HTML file:
<div class="textCamel">Loading<span id="loader-loading-dots"></span></div>
For CSS file:
.textCamel {
position:absolute;
width: 100%;
text-align: center;
font-size: 18px;
margin: 0 auto;
}
For type script file
export class LoaderComponent implements OnInit {
ngOnInit() {
// TODO: start CSS animation
this.initLoadingDots();
}
// This method initializes the loading dots animation
initLoadingDots() {
let x=0;
setInterval(function() {
let dots = "";
x++;
for (let y=0; y <= x%3; y++) {
dots+=".";
}
$("#loader-loading-dots").text(dots);
} , 500);
}
}
I really appreciate if anyone can offer some tips to fix this issue.
You can use text-align:left instead and put everything inside a container that you align center and use fixed width to always have the same behavior.
Simply be sure the width you use will contain the maximum text (loading + the 3 dots) to avoid overflow even if it's not a big issue as by default the overflow is shown unless you have another style that hide it :
.textCamel {
/*position:absolute; removed this to show the result of the 3 divs */
width: 100%;
text-align: center;
font-size: 18px;
margin: 0 auto;
}
.load {
display: inline-block;
text-align: left;
width: 80px;
}
<div class="textCamel">
<div class="load">Loading<span id="loader-loading-dots"></span></div>
</div>
<div class="textCamel">
<div class="load">Loading<span id="loader-loading-dots">.</span></div>
</div>
<div class="textCamel">
<div class="load">Loading<span id="loader-loading-dots">..</span></div>
</div>
<div class="textCamel">
<div class="load">Loading<span id="loader-loading-dots">...</span></div>
</div>