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.
Related
I want to make a button that changes the text inside the button by pressing the button, but I don't know how! :(
I used :hover, but when I move the mouse pointer away, it goes back to its previous state.
There is the possibility of solving it with the pseudo-class :hover and the use of data attributes. The idea of this solution is that you hide the original button text, add an empty content and then use hover over the element to show the content of the data attribute.
I'll show you how in the following example:
body {
background-color: #F2CD5C;
text-align: center;
}
.container {
margin-top: 30vh;
}
/*
MARK BUTTON:
In the button styles, it is necessary to hide the original text that we generated, to create the correct spacing and the data attribute text can overlap
The text color must be the same as the button background.
Position must be relative.
*/
.button {
position: relative;
padding: 0.5em 1em;
border: 2px solid #fff;
border-radius: 15px;
font-size: 2em;
color: black;
background: black;
}
/*
MARK USE :before and :after
Setup pseudo-element ::before with content: ""; and position must be absolute and setup with the original position text inside the button.
Write ::after with the exact text inside button = Click me! with the same position and setup to ::before pseudo-element
*/
.button::before {
content: "";
position: absolute;
left:0;
width: 100%;
text-align: center;
opacity: 0;
color: white;
}
.button::after {
content: "Click me!";
position: absolute;
left:0;
width: 100%;
text-align: center;
opacity: 1;
color: white;
}
.button::before {
content: attr(data-hover);
}
.button:hover:before{
opacity: 1;
}
.button:hover:after{
opacity: 0;
}
<div class="container">
<button class="button" type="button" data-hover="Hello world!">Click me!</button>
</div>
The code uses pseudo-elements ::before and ::after to display different text when the button is hovered over. The text "Click me!" is set as the content for the ::after pseudo-element, while the ::before pseudo-element gets its content from the "data-hover" attribute. When the button is hovered over, the ::before pseudo-element's opacity becomes 1 and the ::after pseudo-element's opacity becomes 0, effectively hiding and showing different text on the button.
I hope this can help you solve your question. Anyway, this solution is not clean, we should handle the DOM using JavaScript.
Reference Links
Using data attributes
I only know how to do this using javascript, hope that helps.
HTML
<button class="btn">Hey, click me!</button>
JS
first I store the button in a variable
var button = document.querySelector(".btn")
then I add an event listener to the button with the "click" event, which will make the function "function()" be executed whenever the button is clicked
button.addEventListener("click", function(){})
now, I define the function to change the text of the button using "this" to access the button of the function and ".textContent" to change the text that was inside
button.addEventListener("click", function(){
this.textContent = "Hey, you clicked me!"
})
Click "run" for a preview
var button = document.querySelector(".btn")
button.addEventListener("click", function(){
this.textContent = "Hey, you clicked me!"
})
<button class="btn">Hey, click me!</button>
I am new to Angular 2 and I'm after do a custom button display when selected. For questions I have 2 buttons for the answer which only one is allowed to be selected (I have all this working) but what I'd like to do is add a tick in from of the selected buttons value.
I know it will need to be done in CSS, which is fine, but I don't know how to do it.
I tried the below but it doesn't seem to work:
.md-fab.md-primary.md-grey-ajb-red-theme.md-button, .md-raised.md-primary.md-grey-ajb-red-theme.md-button
{
font-family:'Glyphicons Halflings';
content:"\e089";
}
Below is an example of what I want. When the button not selected or un-selected the button should just say 'Yes' and obviously have a different colour:
Try this:
.md-fab.md-primary.md-grey-ajb-red-theme.md-button, .md-raised.md-primary.md-grey-ajb-red-theme.md-button
{
position: relative;
text-align: center;
}
.md-fab.md-primary.md-grey-ajb-red-theme.md-button:before, .md-raised.md-primary.md-grey-ajb-red-theme.md-button:before
{
content:"\e089";
display: block;
font-family:'Glyphicons Halflings';
font-size: 20px;
position: absolute;
top: 7px; // adjust as per your need
left: 110px; // adjust as per your need
}
take a boolean variable to set the class on off and render the text on button click. Call a method on click which will change the button text.
Let's say I have two sibling divs that shouldn't be showed at the same time. Inside both divs there are about 50 images.
Div 1 is showed by default with the class "active". But when the user clicks a certain button, it triggers an event that remove class "active" from Div 1 and append it to Div 2.
This toggle of divs works fine on a pc, but on some mobile devices, the response is TOO slow.
This is what I've tried so far:
First attempt:
div {
display: none;
&.active {
display: block;
}
img { display: block; /* always */ }
}
Second attempt:
div {
position: absolute;
left: 9999px; // in a viewport far far away
&.active {
position: relative;
left: 0;
}
img { display: block; /* always */ }
}
Regardless the device specifications, I'm sure there must be a way to get the better performance on ALL devices. Any ideas?
Thanks :)
I need to create an HTML text input element that features multicolored placeholder text. All of the text should be gray except, but a closing asterisk should be red, as in:
This strikes me as a seemingly simple task that is actually a lot more complicated because of how browsers restrict our ability to style native input elements.
I have heard of people using CSS to override native input styles so they can use custom fonts, etc., but is there away to have two special text styles (gray and red)? Or do I need to use an alternative (non-native) input?
Try something like this: http://jsfiddle.net/vmuJm/
The trick: address the placeholder text, add a "required" class to required inputs, and use the :after pseudo element to add an appropriately colored asterisk.
[EDIT] It looks like this is only working for Webkit browsers.
I have a rather fun way to do this and seems to work great in all browsers.
(Works fine in IE 8+, chrome, and Firefox.)
What I am doing is using the spans I put inside of the label to act as the value text.
Here is the html structure,
<label><span class="title">Name<span class="symbol">*</span></span>
<input type="text" />
</label>
The css,
label {
position: relative;
}
label:hover span {
display: none;
}
input[type="text"]:focus, input[type="text"]:active {
z-index: 2;
}
label input[type="text"] {
position: relative;
}
.title {
color: gray;
position: absolute;
left: 5px;
top: 1px;
z-index: 1;
}
.symbol {
color: red;
}
Last here is the jQuery I wrote to not allow the span to hover over your input if the input is filled in.
$('input[type="text"]').blur(function() {
if( $(this).val().length >= 1) {
$(this).toggleClass('active');
}
else {
$(this).removeClass('active');
}
});
Here is a JSFIDDLE to play with.
Is there a freely available jQuery plugin that changes placeholder behavior to match HTML5 spec?
Before Focus
On Focus Good (Safari)
On Focus Bad (Chrome, Firefox)
You can what your browser does with this simple fiddle.
HTML5 draft spec says:
User agents should present this hint to the user, after having stripped line breaks from it, when the element's value is the empty string and/or the control is not focused (e.g. by displaying it inside a blank unfocused control and hiding it otherwise).
The "/or" is new in current draft so I suppose that's why Chrome and Firefox don't support it yet. See WebKit bug #73629, Chromium bug #103025.
Stefano J. Attardi wrote a nice jQuery plugin that just does that.
It is more stable than Robert's and also fades to a lighter grey when the field gets focused.
See the demo page
Grab it on GitHub
Play with the fiddle
I modified his plugin to read placeholder attribute as opposed to manually creating a span.
This fiddle has complete code:
HTML
<input type="text" placeholder="Hello, world!">
JS
// Original code by Stefano J. Attardi, MIT license
(function($) {
function toggleLabel() {
var input = $(this);
if (!input.parent().hasClass('placeholder')) {
var label = $('<label>').addClass('placeholder');
input.wrap(label);
var span = $('<span>');
span.text(input.attr('placeholder'))
input.removeAttr('placeholder');
span.insertBefore(input);
}
setTimeout(function() {
var def = input.attr('title');
if (!input.val() || (input.val() == def)) {
input.prev('span').css('visibility', '');
if (def) {
var dummy = $('<label></label>').text(def).css('visibility','hidden').appendTo('body');
input.prev('span').css('margin-left', dummy.width() + 3 + 'px');
dummy.remove();
}
} else {
input.prev('span').css('visibility', 'hidden');
}
}, 0);
};
function resetField() {
var def = $(this).attr('title');
if (!$(this).val() || ($(this).val() == def)) {
$(this).val(def);
$(this).prev('span').css('visibility', '');
}
};
var fields = $('input, textarea');
fields.live('mouseup', toggleLabel); // needed for IE reset icon [X]
fields.live('keydown', toggleLabel);
fields.live('paste', toggleLabel);
fields.live('focusin', function() {
$(this).prev('span').css('color', '#ccc');
});
fields.live('focusout', function() {
$(this).prev('span').css('color', '#999');
});
$(function() {
$('input[placeholder], textarea[placeholder]').each(
function() { toggleLabel.call(this); }
);
});
})(jQuery);
CSS
.placeholder {
background: white;
float: left;
clear: both;
}
.placeholder span {
position: absolute;
padding: 5px;
margin-left: 3px;
color: #999;
}
.placeholder input, .placeholder textarea {
position: relative;
margin: 0;
border-width: 1px;
padding: 6px;
background: transparent;
font: inherit;
}
/* Hack to remove Safari's extra padding. Remove if you don't care about pixel-perfection. */
#media screen and (-webkit-min-device-pixel-ratio:0) {
.placeholder input, .placeholder textarea { padding: 4px; }
}
Robert Nyman discusses the problem and documents his approach in his blog.
This fiddle that has all the neccessary HTML, CSS and JS.
Unfortunately, he solves the problem by changing value.
This will not work by definition if placeholder text is itself a valid input.
I found this question by googling out the solution to the same problem. It seems that existing plugins either don't work in elder browsers or hide placeholder on focus.
So I decided to roll on my own solution while trying to combine best parts from existing plugins.
You may check it out here and open an issue if you face any problems.
How about something simple like this? On focus save out the placeholder attribute value and remove the attribute entirely; on blur, put the attribute back:
$('input[type="text"]').focus( function(){
$(this).attr("data-placeholder",$(this).attr('placeholder')).removeAttr("placeholder");
});
$('input[type="text"]').blur( function(){
$(this).attr("placeholder",$(this).attr('data-placeholder'));
});
I wrote my own css3 only solution. See if that fullfills all your needs.
http://codepen.io/fabiandarga/pen/MayNWm
This is my solution:
the input element is set to "required"
an aditional span element for the placeholder is needed. This element is moved on top of the input element (position: absolute;)
with css selectors the input element is tested for validity (required fields are invalid as long as there is no input) and the placeholder is then hidden.
Pitfall: The placeholder is blocking mouseevents to the input! This problem is circumvented by hiding the placeholder element when the mouse is inside the parent (wrapper).
<div class="wrapper">
<input txpe="text" autofocus="autofocus" required/>
<span class="placeholder">Hier text</span>
</div>
.placeholder {
display: none;
position: absolute;
left: 0px;
right: 0;
top: 0px;
color: #A1A1A1;
}
input:invalid + .placeholder {
display: block; /* show the placeholder as long as the "required" field is empty */
}
.wrapper:hover .placeholder {
display: none; /* required to guarantee the input is clickable */
}
.wrapper{
position: relative;
display: inline-block;
}
Maybe you can try with Float Label Pattern :)
See Float labels in CSS