mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-16 01:52:19 +08:00
feat(checkbox): implement indeterminate state (#16951)
This adds an `indeterminate` prop to the `ion-checkbox` component, which visually renders the checkbox with a dash to indicate an indeterminate state. closes #16943
This commit is contained in:

committed by
Brandy Carney

parent
28fd75ee6b
commit
c641ae10ed
@ -140,7 +140,7 @@ export class IonCardTitle {
|
|||||||
proxyInputs(IonCardTitle, ['color', 'mode']);
|
proxyInputs(IonCardTitle, ['color', 'mode']);
|
||||||
|
|
||||||
export declare interface IonCheckbox extends StencilComponents<'IonCheckbox'> {}
|
export declare interface IonCheckbox extends StencilComponents<'IonCheckbox'> {}
|
||||||
@Component({ selector: 'ion-checkbox', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['color', 'mode', 'name', 'checked', 'disabled', 'value'] })
|
@Component({ selector: 'ion-checkbox', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['color', 'mode', 'name', 'checked', 'indeterminate', 'disabled', 'value'] })
|
||||||
export class IonCheckbox {
|
export class IonCheckbox {
|
||||||
ionChange!: EventEmitter<CustomEvent>;
|
ionChange!: EventEmitter<CustomEvent>;
|
||||||
ionFocus!: EventEmitter<CustomEvent>;
|
ionFocus!: EventEmitter<CustomEvent>;
|
||||||
@ -152,7 +152,7 @@ export class IonCheckbox {
|
|||||||
proxyOutputs(this, this.el, ['ionChange', 'ionFocus', 'ionBlur']);
|
proxyOutputs(this, this.el, ['ionChange', 'ionFocus', 'ionBlur']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
proxyInputs(IonCheckbox, ['color', 'mode', 'name', 'checked', 'disabled', 'value']);
|
proxyInputs(IonCheckbox, ['color', 'mode', 'name', 'checked', 'indeterminate', 'disabled', 'value']);
|
||||||
|
|
||||||
export declare interface IonChip extends StencilComponents<'IonChip'> {}
|
export declare interface IonChip extends StencilComponents<'IonChip'> {}
|
||||||
@Component({ selector: 'ion-chip', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['color', 'mode', 'outline'] })
|
@Component({ selector: 'ion-chip', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['color', 'mode', 'outline'] })
|
||||||
|
@ -195,6 +195,7 @@ ion-checkbox,shadow
|
|||||||
ion-checkbox,prop,checked,boolean,false,false,false
|
ion-checkbox,prop,checked,boolean,false,false,false
|
||||||
ion-checkbox,prop,color,string | undefined,undefined,false,false
|
ion-checkbox,prop,color,string | undefined,undefined,false,false
|
||||||
ion-checkbox,prop,disabled,boolean,false,false,false
|
ion-checkbox,prop,disabled,boolean,false,false,false
|
||||||
|
ion-checkbox,prop,indeterminate,boolean,false,false,false
|
||||||
ion-checkbox,prop,mode,"ios" | "md",undefined,false,false
|
ion-checkbox,prop,mode,"ios" | "md",undefined,false,false
|
||||||
ion-checkbox,prop,name,string,this.inputId,false,false
|
ion-checkbox,prop,name,string,this.inputId,false,false
|
||||||
ion-checkbox,prop,value,string,'on',false,false
|
ion-checkbox,prop,value,string,'on',false,false
|
||||||
|
8
core/src/components.d.ts
vendored
8
core/src/components.d.ts
vendored
@ -749,6 +749,10 @@ export namespace Components {
|
|||||||
*/
|
*/
|
||||||
'disabled': boolean;
|
'disabled': boolean;
|
||||||
/**
|
/**
|
||||||
|
* If `true`, the checkbox will visually appear as indeterminate.
|
||||||
|
*/
|
||||||
|
'indeterminate': boolean;
|
||||||
|
/**
|
||||||
* The mode determines which platform styles to use.
|
* The mode determines which platform styles to use.
|
||||||
*/
|
*/
|
||||||
'mode': Mode;
|
'mode': Mode;
|
||||||
@ -775,6 +779,10 @@ export namespace Components {
|
|||||||
*/
|
*/
|
||||||
'disabled'?: boolean;
|
'disabled'?: boolean;
|
||||||
/**
|
/**
|
||||||
|
* If `true`, the checkbox will visually appear as indeterminate.
|
||||||
|
*/
|
||||||
|
'indeterminate'?: boolean;
|
||||||
|
/**
|
||||||
* The mode determines which platform styles to use.
|
* The mode determines which platform styles to use.
|
||||||
*/
|
*/
|
||||||
'mode'?: Mode;
|
'mode'?: Mode;
|
||||||
|
@ -16,8 +16,8 @@
|
|||||||
|
|
||||||
// Size
|
// Size
|
||||||
--size: #{$checkbox-ios-icon-size};
|
--size: #{$checkbox-ios-icon-size};
|
||||||
width: var(--size);
|
|
||||||
|
|
||||||
|
width: var(--size);
|
||||||
height: var(--size);
|
height: var(--size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,6 +39,7 @@
|
|||||||
@include margin($checkbox-ios-item-end-margin-top, $checkbox-ios-item-end-margin-end, $checkbox-ios-item-end-margin-bottom, $checkbox-ios-item-end-margin-start);
|
@include margin($checkbox-ios-item-end-margin-top, $checkbox-ios-item-end-margin-end, $checkbox-ios-item-end-margin-bottom, $checkbox-ios-item-end-margin-start);
|
||||||
|
|
||||||
display: block;
|
display: block;
|
||||||
|
|
||||||
position: static;
|
position: static;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,23 +13,28 @@
|
|||||||
|
|
||||||
// Background
|
// Background
|
||||||
--background: #{$checkbox-md-icon-background-color-off};
|
--background: #{$checkbox-md-icon-background-color-off};
|
||||||
|
|
||||||
|
// Transition
|
||||||
--transition: #{background $checkbox-md-transition-duration $checkbox-md-transition-easing};
|
--transition: #{background $checkbox-md-transition-duration $checkbox-md-transition-easing};
|
||||||
|
|
||||||
// Size
|
// Size
|
||||||
--size: #{$checkbox-md-icon-size};
|
--size: #{$checkbox-md-icon-size};
|
||||||
width: var(--size);
|
|
||||||
|
|
||||||
|
width: var(--size);
|
||||||
height: var(--size);
|
height: var(--size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.checkbox-icon path {
|
.checkbox-icon path {
|
||||||
stroke-dasharray: 30;
|
stroke-dasharray: 30;
|
||||||
stroke-dashoffset: 30;
|
stroke-dashoffset: 30;
|
||||||
stroke-width: 3;
|
stroke-width: 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
:host(.checkbox-checked) .checkbox-icon path {
|
// Material Design Checkbox: Checked / Indeterminate
|
||||||
|
// --------------------------------------------------------
|
||||||
|
|
||||||
|
:host(.checkbox-checked) .checkbox-icon path,
|
||||||
|
:host(.checkbox-indeterminate) .checkbox-icon path {
|
||||||
stroke-dashoffset: 0;
|
stroke-dashoffset: 0;
|
||||||
|
|
||||||
transition: stroke-dashoffset 90ms linear 90ms;
|
transition: stroke-dashoffset 90ms linear 90ms;
|
||||||
@ -37,21 +42,23 @@
|
|||||||
|
|
||||||
|
|
||||||
// Material Design Checkbox: Disabled
|
// Material Design Checkbox: Disabled
|
||||||
// -----------------------------------------
|
// --------------------------------------------------------
|
||||||
|
|
||||||
// TODO .item-md.item-checkbox-disabled ion-label
|
// TODO .item-md.item-checkbox-disabled ion-label
|
||||||
:host(.checkbox-disabled) {
|
:host(.checkbox-disabled) {
|
||||||
opacity: $checkbox-md-disabled-opacity;
|
opacity: $checkbox-md-disabled-opacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Material Design Checkbox Within An Item
|
// Material Design Checkbox Within An Item
|
||||||
// -----------------------------------------
|
// --------------------------------------------------------
|
||||||
|
|
||||||
:host(.in-item) {
|
:host(.in-item) {
|
||||||
// end position by default
|
// end position by default
|
||||||
@include margin($checkbox-md-item-end-margin-top, $checkbox-md-item-end-margin-end, $checkbox-md-item-end-margin-bottom, $checkbox-md-item-end-margin-start);
|
@include margin($checkbox-md-item-end-margin-top, $checkbox-md-item-end-margin-end, $checkbox-md-item-end-margin-bottom, $checkbox-md-item-end-margin-start);
|
||||||
|
|
||||||
display: block;
|
display: block;
|
||||||
|
|
||||||
position: static;
|
position: static;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,14 +6,18 @@
|
|||||||
:host {
|
:host {
|
||||||
/**
|
/**
|
||||||
* @prop --size: Size of the checkbox icon
|
* @prop --size: Size of the checkbox icon
|
||||||
|
*
|
||||||
* @prop --background: Background of the checkbox icon
|
* @prop --background: Background of the checkbox icon
|
||||||
|
* @prop --background-checked: Background of the checkbox icon when checked
|
||||||
|
*
|
||||||
* @prop --border-color: Border color of the checkbox icon
|
* @prop --border-color: Border color of the checkbox icon
|
||||||
* @prop --border-radius: Border radius of the checkbox icon
|
* @prop --border-radius: Border radius of the checkbox icon
|
||||||
* @prop --border-width: Border width of the checkbox icon
|
* @prop --border-width: Border width of the checkbox icon
|
||||||
* @prop --border-style: Border style of the checkbox icon
|
* @prop --border-style: Border style of the checkbox icon
|
||||||
* @prop --transition: Transition of the checkbox icon
|
|
||||||
* @prop --background-checked: Background of the checkbox icon when checked
|
|
||||||
* @prop --border-color-checked: Border color of the checkbox icon when checked
|
* @prop --border-color-checked: Border color of the checkbox icon when checked
|
||||||
|
*
|
||||||
|
* @prop --transition: Transition of the checkbox icon
|
||||||
|
*
|
||||||
* @prop --checkmark-color: Color of the checkbox checkmark when checked
|
* @prop --checkmark-color: Color of the checkbox checkmark when checked
|
||||||
*/
|
*/
|
||||||
--background-checked: #{ion-color(primary, base)};
|
--background-checked: #{ion-color(primary, base)};
|
||||||
@ -67,19 +71,23 @@ button {
|
|||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checked Checkbox
|
|
||||||
|
// Checked / Indeterminate Checkbox
|
||||||
// ---------------------------------------------
|
// ---------------------------------------------
|
||||||
|
|
||||||
:host(.checkbox-checked) .checkbox-icon {
|
:host(.checkbox-checked) .checkbox-icon,
|
||||||
|
:host(.checkbox-indeterminate) .checkbox-icon {
|
||||||
border-color: var(--border-color-checked);
|
border-color: var(--border-color-checked);
|
||||||
|
|
||||||
background: var(--background-checked);
|
background: var(--background-checked);
|
||||||
}
|
}
|
||||||
|
|
||||||
:host(.checkbox-checked) .checkbox-icon path {
|
:host(.checkbox-checked) .checkbox-icon path,
|
||||||
|
:host(.checkbox-indeterminate) .checkbox-icon path {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Disabled Checkbox
|
// Disabled Checkbox
|
||||||
// ---------------------------------------------
|
// ---------------------------------------------
|
||||||
|
|
||||||
|
@ -41,6 +41,11 @@ export class Checkbox implements ComponentInterface {
|
|||||||
*/
|
*/
|
||||||
@Prop({ mutable: true }) checked = false;
|
@Prop({ mutable: true }) checked = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If `true`, the checkbox will visually appear as indeterminate.
|
||||||
|
*/
|
||||||
|
@Prop({ mutable: true }) indeterminate = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If `true`, the user cannot interact with the checkbox.
|
* If `true`, the user cannot interact with the checkbox.
|
||||||
*/
|
*/
|
||||||
@ -101,6 +106,7 @@ export class Checkbox implements ComponentInterface {
|
|||||||
onClick() {
|
onClick() {
|
||||||
this.setFocus();
|
this.setFocus();
|
||||||
this.checked = !this.checked;
|
this.checked = !this.checked;
|
||||||
|
this.indeterminate = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private setFocus() {
|
private setFocus() {
|
||||||
@ -134,6 +140,7 @@ export class Checkbox implements ComponentInterface {
|
|||||||
'in-item': hostContext('ion-item', el),
|
'in-item': hostContext('ion-item', el),
|
||||||
'checkbox-checked': checked,
|
'checkbox-checked': checked,
|
||||||
'checkbox-disabled': disabled,
|
'checkbox-disabled': disabled,
|
||||||
|
'checkbox-indeterminate': this.indeterminate,
|
||||||
'interactive': true
|
'interactive': true
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -142,12 +149,19 @@ export class Checkbox implements ComponentInterface {
|
|||||||
render() {
|
render() {
|
||||||
renderHiddenInput(true, this.el, this.name, (this.checked ? this.value : ''), this.disabled);
|
renderHiddenInput(true, this.el, this.name, (this.checked ? this.value : ''), this.disabled);
|
||||||
|
|
||||||
|
let path = this.indeterminate
|
||||||
|
? <path d="M6 12L18 12"/>
|
||||||
|
: <path d="M5.9,12.5l3.8,3.8l8.8-8.8" />;
|
||||||
|
|
||||||
|
if (this.mode === 'md') {
|
||||||
|
path = this.indeterminate
|
||||||
|
? <path d="M2 12H22"/>
|
||||||
|
: <path d="M1.73,12.91 8.1,19.28 22.79,4.59"/>;
|
||||||
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
<svg class="checkbox-icon" viewBox="0 0 24 24">
|
<svg class="checkbox-icon" viewBox="0 0 24 24">
|
||||||
{ this.mode === 'md'
|
{path}
|
||||||
? <path d="M1.73,12.91 8.1,19.28 22.79,4.59"></path>
|
|
||||||
: <path d="M5.9,12.5l3.8,3.8l8.8-8.8"/>
|
|
||||||
}
|
|
||||||
</svg>,
|
</svg>,
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
@ -188,14 +188,15 @@ export default CheckboxExample;
|
|||||||
|
|
||||||
## Properties
|
## Properties
|
||||||
|
|
||||||
| Property | Attribute | Description | Type | Default |
|
| Property | Attribute | Description | Type | Default |
|
||||||
| ---------- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- | -------------- |
|
| --------------- | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- | -------------- |
|
||||||
| `checked` | `checked` | If `true`, the checkbox is selected. | `boolean` | `false` |
|
| `checked` | `checked` | If `true`, the checkbox is selected. | `boolean` | `false` |
|
||||||
| `color` | `color` | The color to use from your application's color palette. Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. For more information on colors, see [theming](/docs/theming/basics). | `string \| undefined` | `undefined` |
|
| `color` | `color` | The color to use from your application's color palette. Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. For more information on colors, see [theming](/docs/theming/basics). | `string \| undefined` | `undefined` |
|
||||||
| `disabled` | `disabled` | If `true`, the user cannot interact with the checkbox. | `boolean` | `false` |
|
| `disabled` | `disabled` | If `true`, the user cannot interact with the checkbox. | `boolean` | `false` |
|
||||||
| `mode` | `mode` | The mode determines which platform styles to use. | `"ios" \| "md"` | `undefined` |
|
| `indeterminate` | `indeterminate` | If `true`, the checkbox will visually appear as indeterminate. | `boolean` | `false` |
|
||||||
| `name` | `name` | The name of the control, which is submitted with the form data. | `string` | `this.inputId` |
|
| `mode` | `mode` | The mode determines which platform styles to use. | `"ios" \| "md"` | `undefined` |
|
||||||
| `value` | `value` | The value of the toggle does not mean if it's checked or not, use the `checked` property for that. The value of a toggle is analogous to the value of a `<input type="checkbox">`, it's only used when the toggle participates in a native `<form>`. | `string` | `'on'` |
|
| `name` | `name` | The name of the control, which is submitted with the form data. | `string` | `this.inputId` |
|
||||||
|
| `value` | `value` | The value of the toggle does not mean if it's checked or not, use the `checked` property for that. The value of a toggle is analogous to the value of a `<input type="checkbox">`, it's only used when the toggle participates in a native `<form>`. | `string` | `'on'` |
|
||||||
|
|
||||||
|
|
||||||
## Events
|
## Events
|
||||||
|
10
core/src/components/checkbox/test/indeterminate/e2e.ts
Normal file
10
core/src/components/checkbox/test/indeterminate/e2e.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import { newE2EPage } from '@stencil/core/testing';
|
||||||
|
|
||||||
|
test('checkbox: indeterminate', async () => {
|
||||||
|
const page = await newE2EPage({
|
||||||
|
url: '/src/components/checkbox/test/indeterminate?ionic:_testing=true'
|
||||||
|
});
|
||||||
|
|
||||||
|
const compare = await page.compareScreenshot();
|
||||||
|
expect(compare).toMatchScreenshot();
|
||||||
|
});
|
203
core/src/components/checkbox/test/indeterminate/index.html
Normal file
203
core/src/components/checkbox/test/indeterminate/index.html
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html dir="ltr">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Checkbox - Indeterminate</title>
|
||||||
|
<meta name="viewport"
|
||||||
|
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||||
|
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet">
|
||||||
|
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet">
|
||||||
|
<script src="../../../../../scripts/testing/scripts.js"></script>
|
||||||
|
<script src="../../../../../dist/ionic.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body onLoad="onLoad()">
|
||||||
|
<ion-app>
|
||||||
|
|
||||||
|
<ion-header>
|
||||||
|
<ion-toolbar>
|
||||||
|
<ion-title>Checkbox - Indeterminate</ion-title>
|
||||||
|
</ion-toolbar>
|
||||||
|
</ion-header>
|
||||||
|
|
||||||
|
<ion-content id="content">
|
||||||
|
<ion-list-header>
|
||||||
|
Native
|
||||||
|
</ion-list-header>
|
||||||
|
|
||||||
|
<div class="ion-padding-start">
|
||||||
|
<!-- Default to unchecked -->
|
||||||
|
<label for="unchecked">Unchecked</label>
|
||||||
|
<input name="unchecked" type="checkbox">
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<!-- Default to checked -->
|
||||||
|
<label for="checked">Checked</label>
|
||||||
|
<input name="checked" type="checkbox" checked />
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<!-- Default to indeterminate -->
|
||||||
|
<label for="indeterminate">Indeterminate</label>
|
||||||
|
<input name="indeterminate" type="checkbox" class="indeterminate">
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<!-- Default to checked / indeterminate -->
|
||||||
|
<label for="both">Checked / Indeterminate</label>
|
||||||
|
<input name="both" type="checkbox" checked class="indeterminate">
|
||||||
|
<br>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ion-list-header>
|
||||||
|
Ionic
|
||||||
|
</ion-list-header>
|
||||||
|
<ion-item>
|
||||||
|
<ion-label>Unchecked</ion-label>
|
||||||
|
<ion-checkbox slot="end"></ion-checkbox>
|
||||||
|
</ion-item>
|
||||||
|
|
||||||
|
<ion-item>
|
||||||
|
<ion-label>Checked</ion-label>
|
||||||
|
<ion-checkbox slot="end" checked></ion-checkbox>
|
||||||
|
</ion-item>
|
||||||
|
|
||||||
|
<ion-item>
|
||||||
|
<ion-label>Indeterminate</ion-label>
|
||||||
|
<ion-checkbox slot="end" indeterminate></ion-checkbox>
|
||||||
|
</ion-item>
|
||||||
|
|
||||||
|
<ion-item>
|
||||||
|
<ion-label>Checked / Indeterminate</ion-label>
|
||||||
|
<ion-checkbox slot="end" checked indeterminate></ion-checkbox>
|
||||||
|
</ion-item>
|
||||||
|
|
||||||
|
<ion-list-header>
|
||||||
|
Colors
|
||||||
|
</ion-list-header>
|
||||||
|
<div class="ion-padding-start">
|
||||||
|
<ion-checkbox indeterminate></ion-checkbox>
|
||||||
|
<ion-checkbox indeterminate color="secondary"></ion-checkbox>
|
||||||
|
<ion-checkbox indeterminate color="tertiary"></ion-checkbox>
|
||||||
|
<ion-checkbox indeterminate color="success"></ion-checkbox>
|
||||||
|
<ion-checkbox indeterminate color="warning"></ion-checkbox>
|
||||||
|
<ion-checkbox indeterminate color="danger"></ion-checkbox>
|
||||||
|
<ion-checkbox indeterminate color="dark"></ion-checkbox>
|
||||||
|
<ion-checkbox indeterminate color="medium"></ion-checkbox>
|
||||||
|
<ion-checkbox indeterminate color="light"></ion-checkbox>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ion-list-header>
|
||||||
|
Parent
|
||||||
|
</ion-list-header>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<ion-checkbox name="tall" id="tall" indeterminate></ion-checkbox>
|
||||||
|
<label for="tall">Tall Things</label>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<ion-checkbox name="tall-1" id="tall-1" checked></ion-checkbox>
|
||||||
|
<label for="tall-1">Skyscrapers</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<ion-checkbox name="tall-2" id="tall-2"></ion-checkbox>
|
||||||
|
<label for="tall-2">Trees</label>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<ion-checkbox name="tall-2" id="tall-2"></ion-checkbox>
|
||||||
|
<label for="tall-2">Giants</label>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</ion-content>
|
||||||
|
</ion-app>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
margin: 5px 20px;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul label {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: top;
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var indeterminateCheckboxes = document.getElementsByClassName("indeterminate");
|
||||||
|
|
||||||
|
for (var i = 0; i < indeterminateCheckboxes.length; i++) {
|
||||||
|
var checkbox = indeterminateCheckboxes[i];
|
||||||
|
checkbox.indeterminate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function onLoad() {
|
||||||
|
var checkboxes = document.getElementsByTagName("ion-checkbox");
|
||||||
|
|
||||||
|
for (var i = 0; i < checkboxes.length; i++) {
|
||||||
|
var checkbox = checkboxes[i];
|
||||||
|
checkbox.addEventListener('ionChange', function (event) {
|
||||||
|
checkboxChanged(this, event);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkboxChanged(el, ev) {
|
||||||
|
var isParent = el.id === "tall";
|
||||||
|
|
||||||
|
if (isParent) {
|
||||||
|
checkChildren(el.checked);
|
||||||
|
} else {
|
||||||
|
checkParent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkParent() {
|
||||||
|
var parent = document.getElementById("tall");
|
||||||
|
var children = getChildren();
|
||||||
|
var countChecked = 0;
|
||||||
|
|
||||||
|
for(var i = 0; i < children.length; i++) {
|
||||||
|
var child = children[i];
|
||||||
|
if (child.checked) {
|
||||||
|
countChecked = ++countChecked;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// None checked, uncheck parent
|
||||||
|
if (countChecked == 0) {
|
||||||
|
parent.checked = false;
|
||||||
|
parent.indeterminate = false;
|
||||||
|
// All checked, check parent
|
||||||
|
} else if (countChecked == children.length) {
|
||||||
|
parent.checked = true;
|
||||||
|
parent.indeterminate = false;
|
||||||
|
// One checked, indeterminate parent
|
||||||
|
} else {
|
||||||
|
parent.indeterminate = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkChildren(shouldCheck) {
|
||||||
|
var children = getChildren();
|
||||||
|
for (var i = 0; i < children.length; i++) {
|
||||||
|
var child = children[i];
|
||||||
|
child.checked = shouldCheck;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getChildren() {
|
||||||
|
return document.querySelectorAll("ion-checkbox[name^=tall-]");
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
Reference in New Issue
Block a user