bind to ngModel through clickable options instead of select-option (dropdown) - html

I am trying to build a basic colorpicker with predefined colors.
for that I have an object "colors" with color-values as it's properties:
public colors = [
{ value: '#ffffff' },
{ value: '#919191' },
{ value: '#555555' },
// and some more
];
Following some examples on the web, I set up a select-option structure in my html:
<select name="role" [(ngModel)]="item.color">
<option *ngFor="let color of colors" [value]="color.value">
<div class="color-box-modal" [style.background]="color.value"></div>
</option>
</select>
This does create a dropdown menu for the options, though the colors inside don't show up. The class color-box-modal has height and width values as I did not intend to have a dropdown, but several colored boxes to click on in order to select.
Is there an alternative to the select-option structure which allows me to not have a dropdown, but just several colored boxes? Radio-buttons/checkboxes are not the desirerable way either, as I want to have a clickable field on it's own that reacts to being clicked.
If there is no alternative, is it possible to do the ngModel binding on a button-click?
edit:
After testing option 2 on Osman Ceas answer, I now have this:
<ng-template #content let-c="close" let-d="dismiss">
<i class="close icon" (click)="d('Close click x')"></i>
<div class="header">
Choose a new color
</div>
<div class="content">
<label for="col1" class="color-box-modal" style="background-color: #ffffff">
<input (click)="c('#ffffff')" id="col1" type="radio" class="hidden" [(ngModel)]="item.color" [value]="'#ffffff'">
</label>
<label for="col2" class="color-box-modal" style="background-color: #ffff00">
<input (click)="c('#ffff00')" id="col2" type="radio" class="hidden" [(ngModel)]="item.color" [value]="'#ffff00'">
</label>
<label for="col3" class="color-box-modal" style="background-color: #00ffff">
<input (click)="c('#00ffff')" id="col3" type="radio" class="hidden" [(ngModel)]="item.color" [value]="'#00ffff'">
</label>
</div>
<div class="actions">
<div class="ui button" (click)="c('Close click cancel')">Cancel</div>
</div>
</ng-template>
Though the ngModel binding does not seem to work.
The whole thing opens in a modal (the template), which in itself works, just binding to the ngModel, as I said, does not.

A native HTML select will only render text inside and any other tag will be ignored, so that's why your boxes are not showing.
If your wrap your radio button or checkbox in a <label> with the attribute for equals to an ID given to the <input>, you can basically click anywhere on the label, lets say some adjacent text, and the click will propagate to the input so the binding will still work.
You can create your own custom form controls, check out this article. So you could create a custom color picker form element that will work in any form using template forms or reactive forms.
Have a nice day

Now, this might not help everyone, but it was my solution in the end.
I started with a loop, item of items where the template in my question was meant for one single item.
I solved, or rather worked around the binding situation by just moving each item to it's own component, somewhat like this:
<div *ngFor="let item of items>
<app-sub-item [item]="item"></app-sub-item>
</div>
inside I have severel of these:
<label for="col1" class="color-box-modal" style="background-color: #ffffff">
<input (click)="setColor('#ffffff')" id="col1" type="radio" class="hidden">
</label>
With the following being in the ts-file:
setColor(color: string) {
this.item.color = color;
}
This actually works just fine at the moment.
Hope whoever reads this issue can find some use in my solution.

Related

How to make elements disappear based on toggle switch setting

I have a Slideout Menu control that looks something like this
There is a toggle switch on top which is currently switched off(i.e basic mode) and i want the elements to not be visible when the toggle is in basic mode, except for the Definition label and the dropdown next to it. When the switch is turned on (i.e Advanced mode) the menu should look like this (the image).
The html for the toggle switch is
<label class="switch">
<input type="checkbox">
<span class="slider round"></span>
</label>
The UI controls are not properly aligned as I am learning to write HTML/CSS on the go.
This is one of the controls that should not be available in the screen when the toggle switch is in basic mode
<div class="dropdowns-container">
<label kmdFormLabel>Rounding Mode</label>
<kmd-dropdown
[(ngModel)]="roundMode"
[options]="allRoundModes"
[disable]="!editable"
size="medium"
[externalLabel]="true"
inlineLabel="Select Rounding Mode"
(onChange)="roundModeChange($event)">
</kmd-dropdown>
</div>
How can this be done, is there any specific control or Angular setting that i could use?
it's only create a variable, e.g. "advancedShow", and enclosed all the inputs in a ng-container with an "if"
<input type="checkbox" [(ngModel)]="advancedShow">
<span class="slider round"></span>
</label>
...here your inputs always visible..
<ng-container *ngIf="advancedShow">
...here yours inputs only sisible if slider is true...
</ng-container>

AngularJS Variable Reference not Getting Populated on ng-click

I have the following HTML which should generate a radio button with accompanying text for each element in regionList:
<div ng-repeat="region in regionList">
<input type="radio" name="syncType" ng-model="model.syncType" value="REGION_{{region.id}}" />
<span class="radio-text" ng-click="setSyncType('REGION_{{region.id}}');">Specified Region: {{region.region}} - {{region.projectCount}} Projects</span>
<br />
</div>
The {{region.id}} references appear to be correctly populated when I inspect within Chrome:
<div ng-repeat="region in regionList" class="ng-scope">
<input type="radio" name="syncType" ng-model="model.syncType" value="REGION_f29a6d22-3bf5-4aa5-a564-b19451548288" class="ng-pristine ng-untouched ng-valid">
<span class="radio-text ng-binding" ng-click="setSyncType('REGION_f29a6d22-3bf5-4aa5-a564-b19451548288');">Specified Region: Utah - 12 Projects</span>
<br>
</div>
And when I click the radio button, it works fine. When I click the accompanying text, setSyncType() receives the literal string "REGION_{{region.id}}". What am I doing wrong? Or possibly, what should I look for?
Worth mentioning: the regionList is populated asynchronously/as part of a Promise, and I still haven't completely wrapped my head around javascript promises. There are other buttons in the radio group that are not part of this regionList, and they display. Then the list refreshes including the regionList radio buttons.
Thanks to #isherwood for pointing me in the right direction. Using the appropriate tag, label, to decorate a radio button solved the problem:
<div ng-repeat="region in regionList">
<input type="radio" name="syncType" ng-model="model.syncType" id="REGION_{{region.id}}" value="REGION_{{region.id}}" />
<label for="REGION_{{region.id}}" class="radio-text">Specified Region: {{region.region}} - {{region.projectCount}} Projects</label>
</div>

Show clarity radio buttons based on a condition in Angular

I have a div which has a couple of clr radio buttons wrapped in a .I want to generate the radioButtons based on a boolean value. Following is the code.
<div class="clr-col-4">
<clr-radio-container>
<label class="display-label">Radio Div</label>
<clr-radio-wrapper *ngFor="let col of cols">
<input type="radio" clrRadio />
<label class="display-label" {{col.headerName}}</label>
</clr-radio-wrapper>
</clr-radio-container>
</div>
I have a variable named enableButton. If the enableButton is true, I want to show the radio button, else I don't want to. Could you please help me how to do this?
You can use the ngIf directive. It is an essential thing to have in mind when creating Angular templates.
<div class="clr-col-4">
<clr-radio-container *ngIf="enableButton">
<label class="display-label">Radio Div</label>
<clr-radio-wrapper *ngFor="let col of cols">
<input type="radio" clrRadio />
<label class="display-label" {{col.headerName}}</label>
</clr-radio-wrapper>
</clr-radio-container>
</div>
I suggest you read the docs to familiarise more with the directive and its other conditional variations like then, else, etc.

Handling multiple radio buttons in a Quiz Angular 5

I'm new to Angular and Implementing a Quiz containing multiple MCQs.
But I am having trouble in radio button selection.
My Questions are coming from the database and Options too.
mcq.component.html
<form (ngSubmit)="ff.form.valid && answer(ff)" #ff="ngForm">
<div *ngFor="let question of questions">
<p style="font-size: 25px;">{{question.title}}</p>
<div *ngFor="let option of question.options">
<input [(ngModel)]="option_model.selected_option_id" #selected_option_id="ngModel" type="radio" value="{{option.id}}" name="{{question.id}}">
<!-- <input type="radio" value="{{option.id}}" name="{{question.id}}" ngModel > --> //This way it works fine but I need to use [(ngModel)] to submit the form
{{option.title}}
</div>
</div>
<input style="float: right" type="submit" value="Submit"/>
</form>
Note: The {{question.id}} is unique for each question. Also, this works well if I remove the [(ngModel)] attribute.
And here is what I'm trying to accomplish
The Problem: When I select an option from the second question it deselects the selected option from the First Question. Means I am only able to select one option from both questions.
Please Help me, what I am doing wrong. I've been stuck here for two days.
Okay, Git it Sorted. The issue was with the ngModel and name attribute
It works fine like this
<input [(ngModel)]="options[question.id]" [checked]="options[question.id]" value="{{question.id}}-{{option.id}}" type="radio"
name="option{{question.id}}">
And in typescript
options: any = [];
option: any = [];

select element with multiple checkboxes

Gmail has the feature where you can select labels using checkboxes and it is hidden inside a div element where you can scroll up and down.
It also allows you to have customized actions like create new label at the bottom.
It also allows you to do filtering at the top with a simple search bar.
What is the simplest way to implement something like that and allow me to put in customized actions like the Create new label at the bottom?
At the barest minimum have a way to display all the checkboxes in a scrollable div or select element.
UPDATE:
Currently, I have only the following checkboxes
<div class="input select">
<label for="SiteSite">Sites</label>
<input type="hidden" name="data[Site][Site]" value="" id="SiteSite">
<div class="checkbox"><input type="checkbox" name="data[Site][Site][]" value="1" id="SiteSite1"><label for="SiteSite1">ODSite:P11379-440YishunAve11 HWSW_ESTA ENO21.000070.10001 92640145</label></div>
<div class="checkbox"><input type="checkbox" name="data[Site][Site][]" value="2" id="SiteSite2"><label for="SiteSite2">ODSite:P11374-SGRecClub HWSW_ESTA ENO21.000070.10002 92640147</label></div>
</div>
You can use a plugin called Select2, which has all the options you expect from a <SELECT> tag.
http://img594.imageshack.us/img594/543/select2.png