Skip to content

Commit d2f8620

Browse files
Update hyper-component.md
1 parent 15b0fcf commit d2f8620

File tree

1 file changed

+31
-33
lines changed

1 file changed

+31
-33
lines changed

docs/dsl-client/hyper-component.md

Lines changed: 31 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1434,12 +1434,12 @@ npm install [email protected] [email protected] --save
14341434

14351435
Rails famously used scaffolding for Model CRUD (Create, Read, Update and Delete). There is no scaffolding in Hyperstack today, so here is an example which demonstrates how those simple Rails pages would work in Hyperstack.
14361436

1437-
This examples uses components from the [Material UI](https://material-ui.com/) framework but the principals would be similar for any framework (or just HTML elements).
1438-
1439-
In this example, we will have a table of users and the ability to add new users or edit a user from the list.
1437+
This example uses components from the [Material UI](https://material-ui.com/) framework, but the principals would be similar for any framework (or just HTML elements).
14401438

1439+
In this example, we will have a table of users and the ability to add new users or edit a user from the list. As the user edits the values in the UserDialog, they will appear in the underlying table. You can avoid this behaviour if you choose by copying the values in the `before_mount` of the UserDialog, so you are not interacting with the model directly.
14411440
Firstly the table of users:
14421441

1442+
14431443
```ruby
14441444
class UserIndex < HyperComponent
14451445
render(DIV, class: 'mo-page') do
@@ -1463,7 +1463,8 @@ class UserIndex < HyperComponent
14631463
TableRow do
14641464
TableCell { "#{user.first_name} #{user.last_name}" }
14651465
TableCell { user.is_female ? 'Female' : 'Male' }
1466-
TableCell { UserDialog(user: user) } # this will render as an edit button
1466+
# below note the use of key so React knows which Component is which else the erong params can be passed
1467+
TableCell { UserDialog(user: user, key: user.id) } # this will render as an edit button
14671468
end
14681469
end
14691470
end
@@ -1478,18 +1479,9 @@ class UserDialog < HyperComponent
14781479

14791480
before_mount do
14801481
@open = false
1481-
# we care copying the model instance variables to local instance variables
1482-
# because we do not want updates made to the model to be reflected in the
1483-
# underlying table as the user types. If you did want this, you would not
1484-
# need to do this - just use the model itself
1485-
@first_name = @User.first_name
1486-
@last_name = @User.last_name
1487-
@is_female = @User.is_female
14881482
end
14891483

14901484
render do
1491-
# notice that the same component renders in three different ways
1492-
# as an Add button, and Edit button or a Dialog
14931485
if @open
14941486
render_dialog
14951487
else
@@ -1522,11 +1514,12 @@ class UserDialog < HyperComponent
15221514

15231515
def content
15241516
FormGroup(row: true) do
1525-
TextField(label: 'First Name', value: @first_name.to_s).on(:change) do |e|
1526-
mutate @first_name = e.target.value
1517+
# note .to_s to specifically cast to a String
1518+
TextField(label: 'First Name', value: @User.first_name.to_s).on(:change) do |e|
1519+
@User.first_name = e.target.value
15271520
end
1528-
TextField(label: 'Last Name', value: @last_name.to_s).on(:change) do |e|
1529-
mutate @last_name = e.target.value
1521+
TextField(label: 'Last Name', value: @User.last_name.to_s).on(:change) do |e|
1522+
@User.last_name = e.target.value
15301523
end
15311524
end
15321525

@@ -1535,31 +1528,37 @@ class UserDialog < HyperComponent
15351528
FormLabel(component: 'legend') { 'Gender' }
15361529
RadioGroup(row: true) do
15371530
FormControlLabel(label: 'Male',
1538-
control: Radio(value: false, checked: !@is_female).as_node.to_n)
1531+
control: Radio(value: false, checked: !is_checked(@User.is_female)).as_node.to_n)
15391532
FormControlLabel(label: 'Female',
1540-
control: Radio(value: true, checked: @is_female).as_node.to_n)
1533+
control: Radio(value: true, checked: is_checked(@User.is_female)).as_node.to_n)
15411534
end.on(:change) do |e|
1542-
# for some unknown reason Radio() returns a String
1543-
mutate @is_female = e.target.value == 'true' ? true : false
1535+
@User.is_female = e.target.value
15441536
end
15451537
end
15461538

1539+
def is_checked value
1540+
# we need a true or false and not an object
1541+
value ? true : false
1542+
end
1543+
15471544
def actions
15481545
Button { 'Cancel' }.on(:click) { cancel }
15491546

1550-
return unless ready_to_save?
1551-
Button(color: :primary, variant: :contained, disabled: (@User.saving? ? true : false)) do
1552-
'Save'
1553-
end.on(:click) { save }
1547+
if @User.changed? && validate_content
1548+
Button(color: :primary, variant: :contained, disabled: (@User.saving? ? true : false)) do
1549+
'Save'
1550+
end.on(:click) { save }
1551+
end
15541552
end
15551553

15561554
def save
1557-
@User.update(first_name: @first_name, last_name: @last_name, is_female: @is_female).then do |result|
1555+
@User.save(validate: true).then do |result|
15581556
mutate @open = false if result[:success]
15591557
end
15601558
end
15611559

15621560
def cancel
1561+
@User.revert
15631562
mutate @open = false
15641563
end
15651564

@@ -1569,13 +1568,12 @@ class UserDialog < HyperComponent
15691568
end
15701569
end
15711570

1572-
def ready_to_save?
1573-
return false if @first_name.to_s.empty?
1574-
return false if @last_name.to_s.empty?
1575-
return false if @is_female.nil?
1576-
return true if @first_name != @User.first_name
1577-
return true if @last_name != @User.last_name
1578-
return true if @is_female != @User.is_female
1571+
def validate_content
1572+
return false if @User.first_name.to_s.empty?
1573+
return false if @User.last_name.to_s.empty?
1574+
return false if @User.is_female.nil?
1575+
1576+
true
15791577
end
15801578
end
15811579
```

0 commit comments

Comments
 (0)