@@ -1395,6 +1395,123 @@ def form_config
1395
1395
1396
1396
end
1397
1397
1398
+ describe "supports addition of nested forms/models on top of EXISTING instances" do
1399
+
1400
+ before do
1401
+ @dummy_model = DummyModel . create ( title : "existing-dummy-model-title" )
1402
+
1403
+ class ExamplePage < Matestack ::Ui ::Page
1404
+
1405
+ def prepare
1406
+ @dummy_model = DummyModel . last
1407
+ end
1408
+
1409
+ def response
1410
+ matestack_form form_config do
1411
+ form_input key : :title , type : :text , label : "dummy_model_title_input" , id : "dummy_model_title_input"
1412
+
1413
+ @dummy_model . dummy_child_models . each do |dummy_child_model |
1414
+ dummy_child_model_form dummy_child_model
1415
+ end
1416
+
1417
+ form_fields_for_add_item key : :dummy_child_models_attributes , prototype : method ( :dummy_child_model_form ) do
1418
+ button "add" , type : :button # type: :button is important! otherwise remove on first item is triggered on enter
1419
+ end
1420
+
1421
+ br
1422
+ plain "data: {{data}}"
1423
+ br
1424
+
1425
+ button "Submit me!"
1426
+
1427
+ toggle show_on : "success" , hide_after : 1000 do
1428
+ plain "success!"
1429
+ end
1430
+ toggle show_on : "failure" , hide_after : 1000 do
1431
+ plain "failure!"
1432
+ end
1433
+ end
1434
+ end
1435
+
1436
+ def dummy_child_model_form dummy_child_model = DummyChildModel . new ( title : "init-value" )
1437
+ form_fields_for dummy_child_model , key : :dummy_child_models_attributes do
1438
+ form_input key : :title , type : :text , label : "dummy-child-model-title-input"
1439
+ form_fields_for_remove_item do
1440
+ button "remove" , ":id" : "'remove'+nestedFormRuntimeId" , type : :button # id is just required in this spec, but type: :button is important! otherwise remove on first item is triggered on enter
1441
+ end
1442
+ end
1443
+ end
1444
+
1445
+ def form_config
1446
+ {
1447
+ for : @dummy_model ,
1448
+ method : :put ,
1449
+ path : nested_forms_spec_submit_update_path ( id : @dummy_model . id ) ,
1450
+ success : { emit : "success" } ,
1451
+ failure : { emit : "failure" }
1452
+ }
1453
+ end
1454
+ end
1455
+ end
1456
+
1457
+ it "dynamically adds unlimited new nested forms and enable proper clientside data binding" do
1458
+
1459
+ visit "/example"
1460
+ # sleep
1461
+ expect ( page ) . to have_selector ( '#dummy_model_title_input' )
1462
+ expect ( page ) . not_to have_selector ( '#title_dummy_child_models_attributes_child_0' )
1463
+ expect ( page ) . not_to have_selector ( '#title_dummy_child_models_attributes_child_1' )
1464
+
1465
+ expect ( page ) . to have_content ( 'data: { "title": "existing-dummy-model-title" }' )
1466
+
1467
+ click_on "add"
1468
+ expect ( page ) . to have_selector ( '#title_dummy_child_models_attributes_child_0' )
1469
+
1470
+ expect ( page ) . to have_content ( 'data: { "title": "existing-dummy-model-title", "dummy_child_models_attributes": [ { "_destroy": false, "id": null, "title": "init-value" } ] }' )
1471
+
1472
+ click_on "add"
1473
+ expect ( page ) . to have_selector ( '#title_dummy_child_models_attributes_child_1' )
1474
+
1475
+ expect ( page ) . to have_content ( 'data: { "title": "existing-dummy-model-title", "dummy_child_models_attributes": [ { "_destroy": false, "id": null, "title": "init-value" }, { "_destroy": false, "id": null, "title": "init-value" } ] }' )
1476
+
1477
+ fill_in "title_dummy_child_models_attributes_child_1" , with : "new-value"
1478
+
1479
+ expect ( page ) . to have_content ( 'data: { "title": "existing-dummy-model-title", "dummy_child_models_attributes": [ { "_destroy": false, "id": null, "title": "init-value" }, { "_destroy": false, "id": null, "title": "new-value" } ] }' )
1480
+
1481
+ click_on ( "remove_dummy_child_models_attributes_child_0" )
1482
+
1483
+ expect ( page ) . to have_content ( 'data: { "title": "existing-dummy-model-title", "dummy_child_models_attributes": [ { "_destroy": true, "id": null, "title": "init-value" }, { "_destroy": false, "id": null, "title": "new-value" } ] }' )
1484
+ end
1485
+
1486
+ it "dynamically adds unlimited new nested forms and enable proper clientside data binding with initially present child models" do
1487
+
1488
+ dummy_model = DummyModel . last
1489
+ child_model_0 = dummy_model . dummy_child_models . create ( title : "existing-child-model-title" )
1490
+
1491
+ visit "/example"
1492
+ # sleep
1493
+ expect ( page ) . to have_selector ( '#dummy_model_title_input' )
1494
+ expect ( page ) . to have_selector ( '#title_dummy_child_models_attributes_child_0' )
1495
+ expect ( page ) . not_to have_selector ( '#title_dummy_child_models_attributes_child_1' )
1496
+
1497
+ expect ( page ) . to have_content ( "data: { \" dummy_child_models_attributes\" : [ { \" _destroy\" : false, \" id\" : \" #{ child_model_0 . id } \" , \" title\" : \" existing-child-model-title\" } ], \" title\" : \" existing-dummy-model-title\" }" )
1498
+
1499
+ click_on "add"
1500
+ expect ( page ) . to have_selector ( '#title_dummy_child_models_attributes_child_1' )
1501
+
1502
+ expect ( page ) . to have_content ( "data: { \" dummy_child_models_attributes\" : [ { \" _destroy\" : false, \" id\" : \" #{ child_model_0 . id } \" , \" title\" : \" existing-child-model-title\" }, { \" _destroy\" : false, \" id\" : null, \" title\" : \" init-value\" } ], \" title\" : \" existing-dummy-model-title\" }" )
1503
+
1504
+ fill_in "title_dummy_child_models_attributes_child_1" , with : "new-value"
1505
+
1506
+ expect ( page ) . to have_content ( "data: { \" dummy_child_models_attributes\" : [ { \" _destroy\" : false, \" id\" : \" #{ child_model_0 . id } \" , \" title\" : \" existing-child-model-title\" }, { \" _destroy\" : false, \" id\" : null, \" title\" : \" new-value\" } ], \" title\" : \" existing-dummy-model-title\" }" )
1507
+
1508
+ click_on ( "remove_dummy_child_models_attributes_child_0" )
1509
+
1510
+ expect ( page ) . to have_content ( "data: { \" dummy_child_models_attributes\" : [ { \" _destroy\" : true, \" id\" : \" #{ child_model_0 . id } \" , \" title\" : \" existing-child-model-title\" }, { \" _destroy\" : false, \" id\" : null, \" title\" : \" new-value\" } ], \" title\" : \" existing-dummy-model-title\" }" )
1511
+ end
1512
+
1513
+ end
1514
+
1398
1515
end
1399
1516
1400
1517
end
0 commit comments