it-roy-ru.com

Переключатель с тремя состояниями в angular

В моем приложении angular 6 мне нужно использовать тумблер с тремя состояниями, который имеет порядок,

---ON---NA---OFF---

Для которого я использовал следующий HTML ,

<div class="switch-toggle switch-3 switch-candy">
   <input id="on" name="state-d" type="radio" checked="">
   <label for="on" onclick="">ON</label>

   <input id="na" name="state-d" type="radio" checked="checked">
   <label for="na" onclick="">N/A</label>

   <input id="off" name="state-d" type="radio">
   <label for="off" onclick="">OFF</label>

   <a></a>
</div>

Не удалось открыть файл css , так как в нем много кодов ..

Рабочий пример: https://stackblitz.com/edit/angular-6-template-driven-form-validation-z2rsig знак равно

В котором вы могли видеть два раза сделанные переключатели, в которых первый полностью жестко закодированы переключатели.

Но во-вторых, я пытаюсь сделать его динамичным, но я не могу получить тот же интерфейс и значение выбранного переключателя ..

Я нуждаюсь в том, чтобы сделать три переключателя состояния , которые будут иметь значения как On --- NA --- Off. Если пользователь переключается на Off, тогда значение state-d должно быть Off, а если его On, то значение state-d должно быть On и аналогично для NA. По умолчанию NA должен быть выбран (отмечен).

Мне нужен результат, как первый в ссылке https://stackblitz.com/edit/angular-6-template-driven-form-validation-z2rsig

Но переключатели должны быть динамическими, как будто меня пробовали во второй по той же ссылке .. (это не работает).

Html:

<div *ngFor="let option of options" class="switch-toggle switch-3 switch-candy">
        <div class="radio">
            <input type="radio"
               name="state-d"
               id="{{option.id}}"
               [(ngModel)]="value"
               [value]="option.value"
               />
        <label for="{{option.id}}">{{option.id}}
        </label>
    </div>
  </div>

Ts:

    public options = [
    {value: "on", id:"On"},
    {value: "na", id:"NA"},
    {value: "off", id:"Off"},
  ]

Также мне нужно получить значение текущего переключателя.

Пожалуйста, помогите мне достичь ожидаемого результата с помощью динамической генерации переключателей и установите значение по умолчанию NA при переключении кнопок, соответственно измените значения.

Ожидается результат без с использованием любых сторонних библиотек (даже angular материал не разрешен) или jquery .. Хорошо, если есть изменения в пользовательском интерфейсе, но ожидаемый результат в чисто угловом, на основе TypeScript/javascript.

1
Maniraj from Karur

мне очень нравятся переключатели ng-bootstrap https://ng-bootstrap.github.io/#/components/buttons/examples#radio (ну, вы можете добавить их как стиль 

.btn-primary.focus, .btn-primary:focus {  
   box-shadow: 0 0 0 0; 
}

Чтобы избежать "некрасивой" тени в фокусе)

Сделать несколько похожих без сторонних библиотек - поиграть с css. если у нас есть варианты, такие как

<div *ngFor="let option of options" style="display:inline"  
    [className]="value==option.value?'active':'noactive'" >
    <input class="radio" type="radio" name="state-d" id="{{option.id}}"
            [(ngModel)]="value" [value]="option.value" />
        <label for="{{option.id}}">
           {{option.id}}
        </label>
</div>

Просто добавь

[type="radio"].radio {
  border: 0; 
  clip: rect(0 0 0 0); 
  height: 1px; margin: -1px; 
  overflow: hidden; 
  padding: 0; 
  position: absolute; 
  width: 1px;
}
.active{
   color:red;
}
.noactive{
   color:blue;
}

удалите "каретку" и добавьте стиль радио-кнопкам. ну, сделай анимацию сложнее. Я попробую использовать Angular Animations, определяющие три состояния, но я не совсем уверен, как это сделать

Обновлено с использованием Angular-анимации В этом случае анимация Angulars проста. Только что определили три состояния (я делаю очень простой пример (мои опции будут простым массивом)

Анимация определяется только состояниями и как переходить из одного состояния в другое

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  animations: [
    trigger('posX',[
      state('uno',style({transform:'translateX(0)'})),
      state('dos',style({transform:'translateX(100px)'})),
      state('tres',style({transform:'translateX(200px)'})),
      transition('* => uno',animate(200)),
      transition('* => dos',animate(200)),
      transition('* => tres',animate(200)),
    ])
  ]
})
export class AppComponent {
  pos:string='uno';
  pos2:string='uno';
  options=['uno','dos','tres'];
}

Анимация говорит только о том, что, когда [@posX] был 'uno', нет перевода, когда [@posX] был 'dos', переводите 100px влево и когда [@posX] был 'tres', переводите 200px

HTML будет двумя div, которые находятся в одной позиции (я использую margin-top: -2rem)

<div style="background-color:transparent;">
  <div *ngFor="let option of options" style="display:inline;" >
    <input class="radio" type="radio" name="state-d" id="{{'l'+option}}"
            [(ngModel)]="pos" [value]="option" />
        <label class="radio" for="{{'l'+option}}">
           {{option}}
        </label>
  </div>
</div>
<div style="overflow:hidden;margin-top:-2rem">
   <div  [@posX]="pos" (@posX.done)="pos2=pos" style="background:blue;width:100px" >
      {{pos2}}
  </div>
</div>

И CSS, чтобы скрыть «каретку» и придать ширину меткам.

[type="radio"].radio {
  border: 0; 
  clip: rect(0 0 0 0); 
  height: 1px; margin: -1px; 
  overflow: hidden; 
  padding: 0; 
  position: absolute; 
  width: 1px;
}
label.radio
{
  width:100px;
}

вы можете увидеть в stackblitz

ПРИМЕЧАНИЕ. Очевидно, это ужасный пример со встроенным стилем, а не в .css.

2
Eliseo

Вот обновленная ссылка Stackbilz https://stackblitz.com/edit/angular-qkmkvu HTML code`

<h3>Angular 6 Template-Driven Form Validation</h3>
<form name="form" (ngSubmit)="f.form.valid && onSubmit()" #f="ngForm" novalidate>
  <div class="switch-toggle switch-3 switch-candy">
    <div class="radio" *ngFor="let option of options">
      <input type="radio" name="state-d" id="{{option.id}}" [(ngModel)]="value" [value]="option.value" />
      <label for="{{option.id}}">{{option.id}}
      </label>
    </div>
  </div>
</form>

`

Код TS `

export class AppComponent {
  model: any = {};
  value = "na";
  public options = [
    { value: "on", id: "On" },
    { value: "na", id: "NA" },
    { value: "off", id: "Off" }
  ];

  onSubmit() {
    alert("SUCCESS!! :-)\n\n" + JSON.stringify(this.model));
  }
}

Я просто инициализирую значение первого переключателя и меняю некоторые стили

0
Syamkumar S

Попробуй это

 <form name="form" (ngSubmit)="fM.form.valid && onSubmit()" #fM="ngForm" novalidate>
        <div class="switch-toggle switch-3 switch-candy">
      <ng-container *ngFor="let option of options">
              <input type="radio" name="state-d" id="{{option.id}}" [(ngModel)]="value" [value]="option.value"/>
        <label for="{{option.id}}"> {{option.id}}</label>
      </ng-container>
      <a></a>
    </div>
 </form>
<pre> {{ fM.form?.value | json }}</pre>

ng-container поможет вам повторить контент (aka * ngFor) без элемента переноса

установить значение по умолчанию в TS как value = "na";

0
Parshwa Shah

Вам нужно привязать значения в соответствии с выбранной вкладкой, как это.

[checked]="value === 'on'" вход будет проверяться каждый раз при изменении входного значения, а при изменении значения вы можете привязаться к модели value, как этот (change)="onSelectionChange('on')". Ваша модель формы выглядит хорошо, без изменений, но переключатель можно обработать так, чтобы они синхронизировались.

<form name="form" (ngSubmit)="f.form.valid && onSubmit()" #f="ngForm" novalidate>
                    <div class="form-group">
                        <div class="switch-toggle switch-3 switch-candy">
                            <input id="on" name="state-d" [value]="on"  [checked]="value === 'on'"  type="radio" (change)="onSelectionChange('on')" >
                            <label for="on">ON</label>

                            <input id="na" name="state-d"  [value]="na" [checked]="value === 'na'"  type="radio" checked="checked" (change)="onSelectionChange('na')">
                            <label for="na" >N/A</label>

                            <input id="off" name="state-d"  [value]="off"  [checked]="value === 'off'"  type="radio" (change)="onSelectionChange('off')">
                            <label for="off" >OFF</label>

                            <a></a>
                        </div>
                    </div>
                </form>

Ваш компонент

export class AppComponent {
  model: any = {};

  public options = [
    { value: "on", id: "On" },
    { value: "na", id: "NA" },
    { value: "off", id: "Off" },
  ]

  onSubmit() {
    alert('SUCCESS!! :-)\n\n' + JSON.stringify(this.model))
  }

  onSelectionChange(entry) {
    this.value = entry;
  }
}

Демо

Правка:

добавили демо с динамическими входами,

Вам нужно использовать ng-container, как это

<form name="form" (ngSubmit)="f.form.valid && onSubmit()" #f="ngForm" novalidate>
                    <div class="form-group">

<div class="switch-toggle switch-3 switch-candy">
<ng-container *ngFor="let option of options" ><input type="radio"
               name="state-d"
               id="state-d"
               [checked]="value === option.value"
               [value]="option.value" 
               />
        <label (click)="onSelectionChange(option.value)"  for="{{option.id}}">{{option.id}}
        </label></ng-container> <a></a>
          </div> </div> </form>

Демо

0
Just code