Skip to content

Commit 2b145c0

Browse files
committed
[IMP] add exercise_solved
1 parent 434f40e commit 2b145c0

File tree

5 files changed

+257
-0
lines changed

5 files changed

+257
-0
lines changed

docs/playground/playground.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,11 @@ const SAMPLES = [
109109
folder: "exercise",
110110
code: ["js", "xml", "css"],
111111
},
112+
{
113+
description: "Exercise Solution",
114+
folder: "exercise_solved",
115+
code: ["js", "xml", "css"],
116+
},
112117
{
113118
description: "Components",
114119
folder: "components",

docs/playground/samples/exercise/exercise.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@ import { Component, useEnv, useSubEnv, useState, mount } from "@odoo/owl";
33

44
export class Parent extends Component {
55
static template = 'training_oca.Parent';
6+
setup() {
7+
this.state = useState({
8+
name: 'Parent',
9+
value: 0,
10+
});
11+
}
612
}
713

814
mount(Parent, document.body, { templates: TEMPLATES, dev: true });
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
.row {
2+
--bs-gutter-x: 1.5rem;
3+
--bs-gutter-y: 0;
4+
display: flex;
5+
flex-wrap: wrap;
6+
margin-top: calc(-1 * var(--bs-gutter-y));
7+
margin-right: calc(-0.5 * var(--bs-gutter-x));
8+
margin-left: calc(-0.5 * var(--bs-gutter-x));
9+
}
10+
.row > * {
11+
flex-shrink: 0;
12+
width: 100%;
13+
max-width: 100%;
14+
padding-right: calc(var(--bs-gutter-x) * 0.5);
15+
padding-left: calc(var(--bs-gutter-x) * 0.5);
16+
margin-top: var(--bs-gutter-y);
17+
}
18+
19+
.col {
20+
flex: 1 0 0%;
21+
}
22+
23+
24+
.row-cols-auto > * {
25+
flex: 0 0 auto;
26+
width: auto;
27+
}
28+
29+
.row-cols-1 > * {
30+
flex: 0 0 auto;
31+
width: 100%;
32+
}
33+
34+
.row-cols-2 > * {
35+
flex: 0 0 auto;
36+
width: 50%;
37+
}
38+
39+
.row-cols-3 > * {
40+
flex: 0 0 auto;
41+
width: 33.3333333333%;
42+
}
43+
44+
.row-cols-4 > * {
45+
flex: 0 0 auto;
46+
width: 25%;
47+
}
48+
49+
.row-cols-5 > * {
50+
flex: 0 0 auto;
51+
width: 20%;
52+
}
53+
54+
.row-cols-6 > * {
55+
flex: 0 0 auto;
56+
width: 16.6666666667%;
57+
}
58+
59+
.col-auto {
60+
flex: 0 0 auto;
61+
width: auto;
62+
}
63+
64+
.col-1 {
65+
flex: 0 0 auto;
66+
width: 8.33333333%;
67+
}
68+
69+
.col-2 {
70+
flex: 0 0 auto;
71+
width: 16.66666667%;
72+
}
73+
74+
.col-3 {
75+
flex: 0 0 auto;
76+
width: 25%;
77+
}
78+
79+
.col-4 {
80+
flex: 0 0 auto;
81+
width: 33.33333333%;
82+
}
83+
84+
.col-5 {
85+
flex: 0 0 auto;
86+
width: 41.66666667%;
87+
}
88+
89+
.col-6 {
90+
flex: 0 0 auto;
91+
width: 50%;
92+
}
93+
94+
.col-7 {
95+
flex: 0 0 auto;
96+
width: 58.33333333%;
97+
}
98+
99+
.col-8 {
100+
flex: 0 0 auto;
101+
width: 66.66666667%;
102+
}
103+
104+
.col-9 {
105+
flex: 0 0 auto;
106+
width: 75%;
107+
}
108+
109+
.col-10 {
110+
flex: 0 0 auto;
111+
width: 83.33333333%;
112+
}
113+
114+
.col-11 {
115+
flex: 0 0 auto;
116+
width: 91.66666667%;
117+
}
118+
119+
.col-12 {
120+
flex: 0 0 auto;
121+
width: 100%;
122+
}
123+
124+
.o_counter {
125+
padding: 1rem;
126+
margin: 1rem;
127+
border: 1px solid black;
128+
}
129+
.o_counter .o_counter_header {
130+
display: flex;
131+
justify-content: flex-end;
132+
}
133+
.o_counter .o_counter_body {
134+
display: flex;
135+
}
136+
137+
.o_counter .o_counter_body input{
138+
max-width:100%;
139+
width: 100%;
140+
}
141+
.o_counter .o_counter_body .o_counter_name{
142+
font-size: 1.2rem;
143+
font-weight: bold;
144+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// In this example, we show how components can be defined and created.
2+
import { Component, onWillStart, useSubEnv, useState, mount } from "@odoo/owl";
3+
4+
class Counter extends Component {
5+
static template="oca_training.Counter";
6+
static props = {name:String, value: Number, id: Number}
7+
setup() {
8+
this.state = useState({
9+
edit: false,
10+
name: this.props.name,
11+
value: this.props.value,
12+
});
13+
}
14+
toggleEdit() {
15+
if (this.state.edit) {
16+
this.env.updateValues(this.props.id, this.state.name, parseInt(this.state.value, 10))
17+
}
18+
this.state.edit = !this.state.edit;
19+
}
20+
incrementCounter() {
21+
this.env.incrementCounter(this.props.id);
22+
}
23+
removeCounter() {
24+
this.env.removeCounter(this.props.id)
25+
}
26+
}
27+
28+
class CounterDashboard extends Component {
29+
static template = "oca_training.CounterDashboard";
30+
static components = { Counter }
31+
setup() {
32+
this.id = 1;
33+
this.counters = useState({});
34+
onWillStart(() => {this.addCounter()})
35+
useSubEnv({
36+
incrementCounter: this.incrementCounter.bind(this),
37+
removeCounter: this.removeCounter.bind(this),
38+
updateValues: (id, name, value) => {
39+
if (this.counters[id]) {
40+
this.counters[id].name = name;
41+
this.counters[id].value = value;
42+
}
43+
},
44+
});
45+
}
46+
addCounter() {
47+
const newId = this.id++;
48+
this.counters[newId] = {
49+
id: newId,
50+
name: "New Counter",
51+
value: 0,
52+
};
53+
}
54+
resetAll() {
55+
for (const counterId in this.counters) {
56+
this.counters[counterId].value = 0;
57+
}
58+
}
59+
removeCounter(id) {
60+
if (this.counters[id]) {
61+
delete this.counters[id];
62+
}
63+
}
64+
incrementCounter(id) {
65+
if (this.counters[id]) {
66+
this.counters[id].value++;
67+
}
68+
}
69+
}
70+
71+
72+
mount(CounterDashboard, document.body, { templates: TEMPLATES, dev: true });
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<templates xml:space="preserve">
2+
<t t-name="oca_training.Counter">
3+
<div class="col-2 o_counter" >
4+
<div class=" o_counter_header">
5+
<button t-on-click="toggleEdit" t-if="!state.edit">Edit</button>
6+
<button t-on-click="toggleEdit" t-if="state.edit">Save</button>
7+
<button t-on-click="removeCounter">X</button>
8+
</div>
9+
<div class="o_counter_body">
10+
<div t-if="!state.edit"><div class="o_counter_name" t-esc="props.name" /><div t-esc="props.value"/></div>
11+
<div t-if="state.edit">
12+
<input type="text" t-model="state.name" placeholder="Counter Name"/>
13+
<input type="number" t-model="state.value" placeholder="Counter Value"/>
14+
</div>
15+
</div>
16+
<div class="o_counter_footer">
17+
<button t-on-click="incrementCounter">+1</button>
18+
</div>
19+
</div>
20+
</t>
21+
<t t-name="oca_training.CounterDashboard">
22+
<button t-on-click="addCounter">Add Counter</button>
23+
<button t-on-click="resetAll">Reset All</button>
24+
<div class="row">
25+
<t t-foreach="this.counters" t-as="counter_id" t-key="counter_id">
26+
<Counter t-props="this.counters[counter_id]" />
27+
</t>
28+
</div>
29+
</t>
30+
</templates>

0 commit comments

Comments
 (0)