Yes / No button - meteor

I'm using autoform to ask a yes, no question and I would like to have two buttons, one that says yes, the other says no. By using aldeed:autoform-bs-button-group-input I can generate two buttons using the code below in my schema however this doesn't give the ability to style each button separately. For instance, I would like one to be green and one to be red. How can I do this?
Path: Schema.js
answer: {
type: String,
optional: true,
allowedValues: ['Yes', 'No'],
autoform: {
type: "select-radio",
options: function () {
return [
{label: "Yes", value: 'Yes'},
{label: "No", value: 'No'},
];
}
}
}
Path: template.js
{{#autoForm collection="questions" id=makeUniqueID doc=this type="update" autosave=true}}
{{> afQuickField name="answer" type="select-radio" template="buttonGroup" label=false}}
{{/autoForm}}

First let's add a class attribute autoform:
{{#autoForm class="YesNoStyles" collection="questions" id=makeUniqueID doc=this type="update" autosave=true }}
{{> afQuickField name="answer" type="select-radio" template="buttonGroup" label=false}}
{{/autoForm}}
This is passed to the generated <form> tag, which we can inspect and see it looks like this:
<form class="YesNoStyles" id="makeUniqueID" novalidate="novalidate">
<div class="form-group">
<div class="af-radio-group" data-schema-key="answer">
<div>
<label>
<input type="radio" value="Yes" name="answer" id="6gWEaAr2ZWQzqtj7H"> Yes</label>
</div>
<div>
<label>
<input type="radio" value="No" name="answer" id="6gWEaAr2ZWQzqtj7H"> No</label>
</div>
</div>
<span class="help-block"></span>
</div>
</form>
Now there are two options:
Find the input[value="Yes"] and input[value="No"]elements, then apply css to their parent elements. This however can't be done just with css as css selectors do not allow the selection of parent elements. Meteor's onRendered callback allows us to do the following:
Template.Question.onRendered(function(){
$('input[value="Yes"]')[0].parentElement.classList.add('yes');
$('input[value="No"]')[0].parentElement.classList.add('no');
});
with the following defined css classes:
.yes {
background-color: green;
}
.no {
background-color: red
}
:nth-child(i) css selector, no javascript required!
Define the following css rules (starting with the class I added above):
.YesNoStyles > div > div > div:nth-child(1) > label {
background-color: green;
}
.YesNoStyles > div > div > div:nth-child(2) > label {
background-color: red;
}

Related

Combinators for multiple ::slotted elements

I am interested if there's a way to achieve something like the following:
::slotted(input[type="checkbox"]:disabled) ~ ::slotted(label) {
cursor: not-allowed;
}
By testing it on some of the examples, it does not work.
Specification does not describe if this should be possible or not. MDN does not cover this case as well.
I do not want to enclose neither input nor label inside the shadow-dom as I do not want to handle and/or duplicate the native behavior of those elements.
P.S. I know that I can do that with javascript (for example, by adding class to slotted label), but I'm looking for a plain css solution.
Full example:
<script>
customElements.define('my-element', class extends HTMLElement {
constructor() {
super();
const shadowRoot = this.attachShadow({mode: 'open'});
shadowRoot.innerHTML = `
<style>
::slotted(input:disabled) ~ ::slotted(label) {
color: red;
}
::slotted(input:disabled) + ::slotted(label) {
color: red;
}
</style>
<slot name="inputel"></slot>
<slot name="inputlabel"></slot>`;
}
});
</script>
<my-element>
<input disabled id="input1" type="text" slot="inputel"/>
<label for="input1" slot="inputlabel">label</label>
</my-element>
The full detailed explanation is at: ::slotted CSS selector for nested children in shadowDOM slot
<my-element>
<input disabled id="input1" type="text" slot="inputel"/>
<label for="input1" slot="inputlabel">label</label>
</my-element>
ShadowDOM SLOTs turn off the light
The input and label are in lightDOM,
and remain there invisible when reflected (not moved!) to shadowDOM SLOTs
So you have to style them in lightDOM:
<style>
/* style lightDOM!! */
my-element input:disabled ~ label {
color: red;
}
</style>
<template id="MY-ELEMENT">
<style>
::slotted(input:disabled){
border:1px dashed red;
}
</style>
INPUT <slot name="inputElement"></slot> <slot name="inputLabel"></slot>
</template>
<script>
customElements.define('my-element', class extends HTMLElement {
constructor() {
super().attachShadow({mode: 'open'})
.append(document.getElementById(this.nodeName).content.cloneNode(true));
}
});
</script>
<style>
/* style lightDOM!! */
my-element input:disabled ~ label {
color: red;
font-weight: bold;
}
</style>
<my-element>
<input disabled id="inp1" placeholder="This is disabled" type="text" slot="inputElement"/>
<label for="inp1" slot="inputLabel">input label 1</label>
</my-element>
<br>
<my-element>
<input id="inp2" placeholder="Not disabled" type="text" slot="inputElement"/>
<label for="inp2" slot="inputLabel">input label 2</label>
</my-element>
This use case is a bit contrived, there is nothing gained with my-element, user still has to declare input and label
Maybe create a <input-element type="text" label="A Label"> to create above HTML, you then have the disabled CSS in its shadowDOM (no need for SLOTs)
or (pseudo code)
<template id="INPUT-ELEMENT">
<style>
input:disabled~label{
color:red;
}
</style>
<input id="i"/>
<label for="i"><slot name="label"></slot></label>
</template>
...
connectedCallback(){
let inp=this.shadowRoot.querySelector("input");
inp.type = this.getAttribute("type");
inp.toggleAttribute( "disabled" , this.hasAttribute("disabled"));
}
<input-element type="text" disabled>
<span slot="label"><b>Fancy Label<b></slot>
</input-element>
if you want to give the user more control
::slotted came got into WebComponents V1 spec after its predecessor caused performance issues in V0
Thus it only takes simple selectors as parameter, and can only style first-level elements in the slot
So in above example ::slotted can style the <span slot="label">, but not the <b> inside.
Note: SLOTs are LIVE connections, you can re-apply CSS at any time, and content changes are immediately reflected to shadowDOM:
document.querySelector("input-element > b").innerHTML="Better Label!";
More SLOT related answers can be found with StackOverflow Search: Custom Elements SLOTs

not of nth child selector not working in sass

I am trying to apply certain styles to all items in list besides the first child. I think I set up the sass correctly, however the style is not being applied currently.
html
<div class="list">
<div *ngFor="let item of data; index as i; first as isFirst; last as isLast"class="list-item">
<input class="radio" name="radio" type="radio" />
<label for="radio1">Buttom</label>
</div>
</div>
sass
.list label:not(:nth-of-type(1))::before{
background-color:blue;
}
You can achieve this doing by all the items bg blue and the first one's bg to white or whatever your background is.
<div class="list">
<div *ngFor="let item of data; let i=index" [class.first]="i === 0">
<input class="radio" name="radio" type="radio" />
<label for="radio1" class="lbl">{{item.name}}</label>
and your css should be like this:
label {
background-color:blue;
}
.first label {
background-color: #fff;
}
I assume your data is like that:
data = [
{name: "car"},
{name: "truck"},
{name: "bike"}
]
This is working example
If you mean selecting all .list-item except the first one, the CSS will be like:
.list-item:not(:nth-of-type(1))::before {
content: '';
background-color:blue;
}
Since you are using pseudo element ::before, you may want to use content: '' to specify some content, otherwise background-color will has no effect.

How to change style based on sibling child attribute

I'm working with Vuetify and Stylus on this snipped of HTML
<div class="input-group input-group--dirty input-group--text-field">
<label>Language</label>
<div class="input-group__input">
<input readonly="readonly" type="text"/>
</div>
<div class="input-group__details"></div>
</div>
Is there a CSS/Stylus way to edit input-group__details based on what the status of input[readonly] is?
Something like:
if (.input-group > input has readonly)
.input-group__details
height: 0px
else
.input-group__details
height: 5px
Basically, how do I change a class based on the sibling's child attribute?
Unfortunately as of now, this cannot be achieved in CSS, and as all CSS preprocessors need to generate CSS, it also cannot be done with any pre- or post-processing whatsoever.
You will either have to change your HTML structure (make sure the targeted element comes after the readonly input, and they share the parent element), or resort to Javascript.
If you have enough time, you can also wait for selectors level 4 to arrive.
which would solve your problem with this
.input-group__input:has(input[readonly]) + .input-group__details { ... }
Well not possible with the provided markup, but if you allowed to change some markup you can get this...try to make the .input-group__details next sibling of input..
Also you don't need to assign a value to readonly...just use readonly
input[readonly]+.input-group__details {
color: red;
}
<div class="input-group input-group--dirty input-group--text-field">
<label>Language</label>
<input class="input-group__input" type="text" readonly />
<div class="input-group__details">Welcome</div>
</div>
<br>
<div class="input-group input-group--dirty input-group--text-field">
<label>Language</label>
<input class="input-group__input" type="text" />
<div class="input-group__details">Welcome</div>
</div>
You can bind class.
<div class="input-group input-group--dirty input-group--text-field" :class="'className': trueFalse">
<label>Language</label>
<div class="input-group__input">
<input readonly="readonly" type="text"/>
</div>
<div class="input-group__details"></div>
</div>
Now in your vue script:
data: {
trueFalse: false,
},
methods: {
someClassName() {
//condition of your input field
//if condition true make 'trueFalse' to true else to false
this.trueFalse = true
}
}
at last in your css:
.className {
//add your style with !important
}

Meteor Stripe Elements not rendering

Am attempting to use Stripe elements form (v3) with a meteor form. All code runs without blowing up but nothing is rendered after mount() is called. Any ideas?
js:
Template.billing.onRendered(function(){
let elements = stripe.elements();
let style = {
base: {
// Add your base input styles here. For example:
fontSize: '16px',
color: "#32325d",
}
};
let card = elements.create('card', {style: style});
card.mount('#card-element');
console.log("done");
})
html:
<template name="billing">
<form id="payment-form">
<div class="form-row">
<label for="card-element">
Credit or debit card
</label>
<div id="card-element">
</div>
<div id="card-errors" role="alert"></div>
</div>
<input type="submit" class="submit" value="Submit Payment">
</form>
</template>
Nevermind, it was actually rendering but the width was 0 for some reason, so messing around with the css works.

apply CSS for the first label of div

i would like to apply a specific css to a specific label in my html
this is my HTML
<div id="registration">
<div>
<label>Localisation</label>**//this is the target label to apply css**
<div id="registration_localisation">
<div>
<label>Gouvernorat</label>
<select id="registration_localisation_gouvernorat">
<option value="1">Ariana</option>
<option value="2">Ben Arous</option>
<option value="3">Bizerte</option>
</select>
</div>
<div>
<label for="registration_localisation_ville">Ville</label>
<input type="text" id="registration_localisation_ville">
</div>
</div>
</div>
<div>
<label>Annonceur</label>**//this is the target label to apply the css**
<div id="registration_annonceur">
<div>
<label for="registration_annonceur_Nom">Nom</label>
<input type="text" id="registration_annonceur_Nom">
</div>
<div>
<label for="registration_annonceur_Email">Email</label>
<input type="text" id="registration_annonceur_Email">
</div>
<div>
<label for="registration_Telephone" >Telephone</label>
<input type="text" id="registration_annonceur_Telephone">
</div>
</div>
</div>
</div>
i used many pseudo classes but i didn't find any solution
any idea please ?
try this way where you can style all your label inside the div contained into registration
#registration > div > label{
//your css
}
DEMO
Just give it a class. Classes may be repeated in HTML, like;
<label class="class1">Localisation</label>
and in your css,
.class1{
//styling
}
CSS3 way
#registration div label:first-child {
// specific styles for just the first label item
}
Or
#registration div label:nth-first-of-type{
// specific styles for just the first label item
}
jQuery Way
<script>
$( "#registration div label:first" ).css( "font-style", "italic" );
</script>
How about
#registration > div > label:first-of-type {}
?
Match labels who are the first, direct child of a div.
div > label:first-child {}
Actually it would be much better if you could add some classes to your elements. Matching wide selector such as div is a bad idea for future maintainability. Changing your markup will break your style.

Resources