unpoly-rails 1.0.3 → 2.0.0.pre.rc2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of unpoly-rails might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.yardopts +1 -1
- data/CHANGELOG.md +43 -25
- data/README.md +5 -6
- data/README_RAILS.md +295 -14
- data/dist/unpoly-bootstrap3.css +9 -14
- data/dist/unpoly-bootstrap3.js +4 -18
- data/dist/unpoly-bootstrap3.min.css +1 -1
- data/dist/unpoly-bootstrap3.min.js +1 -1
- data/dist/unpoly-bootstrap4.css +9 -0
- data/dist/unpoly-bootstrap4.js +16 -0
- data/dist/unpoly-bootstrap4.min.css +1 -0
- data/dist/unpoly-bootstrap4.min.js +1 -0
- data/dist/unpoly-bootstrap5.css +9 -0
- data/dist/unpoly-bootstrap5.js +14 -0
- data/dist/unpoly-bootstrap5.min.css +1 -0
- data/dist/unpoly-bootstrap5.min.js +1 -0
- data/dist/unpoly-migrate.js +1213 -0
- data/dist/unpoly-migrate.min.js +1 -0
- data/dist/unpoly.css +109 -140
- data/dist/unpoly.js +15376 -10484
- data/dist/unpoly.min.css +1 -1
- data/dist/unpoly.min.js +6 -4
- data/lib/unpoly/rails/change/cache.rb +26 -0
- data/lib/unpoly/rails/change/context.rb +80 -0
- data/lib/unpoly/rails/change/field.rb +117 -0
- data/lib/unpoly/rails/change/field_definition.rb +74 -0
- data/lib/unpoly/rails/change/layer.rb +60 -0
- data/lib/unpoly/rails/change.rb +372 -0
- data/lib/unpoly/rails/controller.rb +47 -0
- data/lib/unpoly/rails/error.rb +5 -0
- data/lib/unpoly/rails/request_echo_headers.rb +2 -2
- data/lib/unpoly/rails/version.rb +1 -1
- data/lib/unpoly/tasks.rb +45 -0
- data/lib/unpoly-rails.rb +9 -3
- metadata +42 -316
- data/.gitignore +0 -10
- data/.ruby-version +0 -1
- data/Gemfile +0 -7
- data/Gemfile.lock +0 -39
- data/Rakefile +0 -154
- data/bower.json +0 -27
- data/design/animation-ghosting.txt +0 -72
- data/design/design.txt +0 -34
- data/design/draft.html.erb +0 -48
- data/design/draft.rb +0 -9
- data/design/es6.js +0 -32
- data/design/ghost-debugging.txt +0 -118
- data/design/homepage.txt +0 -236
- data/design/ie11.txt +0 -9
- data/design/measure_import_node.js +0 -330
- data/design/measure_jquery/element_list.js +0 -41
- data/design/measure_jquery/up.on_vs_addEventListener.js +0 -56
- data/design/positioning.txt +0 -28
- data/design/query-params-in-form-actions/cases.html +0 -125
- data/design/rename.txt +0 -0
- data/design/test_rejected_promise.txt +0 -5
- data/design/unpoly errors.txt +0 -19
- data/lib/assets/javascripts/unpoly/browser.coffee.erb +0 -240
- data/lib/assets/javascripts/unpoly/classes/body_shifter.coffee +0 -45
- data/lib/assets/javascripts/unpoly/classes/cache.coffee +0 -127
- data/lib/assets/javascripts/unpoly/classes/compile_pass.coffee +0 -93
- data/lib/assets/javascripts/unpoly/classes/config.coffee +0 -9
- data/lib/assets/javascripts/unpoly/classes/css_transition.coffee +0 -118
- data/lib/assets/javascripts/unpoly/classes/divertible_chain.coffee +0 -39
- data/lib/assets/javascripts/unpoly/classes/event_listener.coffee +0 -116
- data/lib/assets/javascripts/unpoly/classes/extract_cascade.coffee +0 -86
- data/lib/assets/javascripts/unpoly/classes/extract_plan.coffee +0 -111
- data/lib/assets/javascripts/unpoly/classes/field_observer.coffee +0 -80
- data/lib/assets/javascripts/unpoly/classes/focus_follower.coffee +0 -29
- data/lib/assets/javascripts/unpoly/classes/follow_variant.coffee +0 -64
- data/lib/assets/javascripts/unpoly/classes/html_parser.coffee +0 -46
- data/lib/assets/javascripts/unpoly/classes/motion_controller.coffee +0 -157
- data/lib/assets/javascripts/unpoly/classes/params.coffee.erb +0 -544
- data/lib/assets/javascripts/unpoly/classes/record.coffee +0 -22
- data/lib/assets/javascripts/unpoly/classes/rect.js +0 -21
- data/lib/assets/javascripts/unpoly/classes/request.coffee +0 -247
- data/lib/assets/javascripts/unpoly/classes/response.coffee +0 -157
- data/lib/assets/javascripts/unpoly/classes/reveal_motion.coffee +0 -102
- data/lib/assets/javascripts/unpoly/classes/scroll_motion.coffee +0 -67
- data/lib/assets/javascripts/unpoly/classes/selector.coffee +0 -60
- data/lib/assets/javascripts/unpoly/classes/store/memory.coffee +0 -26
- data/lib/assets/javascripts/unpoly/classes/store/session.coffee +0 -59
- data/lib/assets/javascripts/unpoly/classes/tether.coffee +0 -105
- data/lib/assets/javascripts/unpoly/classes/url_set.coffee +0 -32
- data/lib/assets/javascripts/unpoly/cookie.coffee +0 -56
- data/lib/assets/javascripts/unpoly/element.coffee.erb +0 -1129
- data/lib/assets/javascripts/unpoly/event.coffee.erb +0 -445
- data/lib/assets/javascripts/unpoly/feedback.coffee +0 -353
- data/lib/assets/javascripts/unpoly/form.coffee.erb +0 -1084
- data/lib/assets/javascripts/unpoly/fragment.coffee.erb +0 -928
- data/lib/assets/javascripts/unpoly/framework.coffee +0 -65
- data/lib/assets/javascripts/unpoly/history.coffee +0 -268
- data/lib/assets/javascripts/unpoly/legacy.coffee +0 -60
- data/lib/assets/javascripts/unpoly/link.coffee.erb +0 -622
- data/lib/assets/javascripts/unpoly/log.coffee +0 -253
- data/lib/assets/javascripts/unpoly/modal.coffee.erb +0 -827
- data/lib/assets/javascripts/unpoly/motion.coffee.erb +0 -668
- data/lib/assets/javascripts/unpoly/namespace.coffee.erb +0 -5
- data/lib/assets/javascripts/unpoly/popup.coffee.erb +0 -515
- data/lib/assets/javascripts/unpoly/protocol.coffee +0 -300
- data/lib/assets/javascripts/unpoly/proxy.coffee +0 -672
- data/lib/assets/javascripts/unpoly/radio.coffee +0 -60
- data/lib/assets/javascripts/unpoly/rails.coffee +0 -24
- data/lib/assets/javascripts/unpoly/syntax.coffee.erb +0 -476
- data/lib/assets/javascripts/unpoly/toast.coffee +0 -67
- data/lib/assets/javascripts/unpoly/tooltip.coffee +0 -276
- data/lib/assets/javascripts/unpoly/util.coffee.erb +0 -1677
- data/lib/assets/javascripts/unpoly/viewport.coffee.erb +0 -830
- data/lib/assets/javascripts/unpoly-bootstrap3/feedback-ext.coffee +0 -5
- data/lib/assets/javascripts/unpoly-bootstrap3/form-ext.coffee +0 -1
- data/lib/assets/javascripts/unpoly-bootstrap3/modal-ext.coffee +0 -14
- data/lib/assets/javascripts/unpoly-bootstrap3/viewport-ext.coffee +0 -5
- data/lib/assets/javascripts/unpoly-bootstrap3.coffee +0 -2
- data/lib/assets/javascripts/unpoly.coffee +0 -28
- data/lib/assets/stylesheets/unpoly/close.sass +0 -2
- data/lib/assets/stylesheets/unpoly/dom.sass +0 -5
- data/lib/assets/stylesheets/unpoly/layout.sass +0 -2
- data/lib/assets/stylesheets/unpoly/link.sass +0 -2
- data/lib/assets/stylesheets/unpoly/modal.sass +0 -116
- data/lib/assets/stylesheets/unpoly/popup.sass +0 -7
- data/lib/assets/stylesheets/unpoly/toast.sass +0 -33
- data/lib/assets/stylesheets/unpoly/tooltip.sass +0 -62
- data/lib/assets/stylesheets/unpoly-bootstrap3/modal-ext.sass +0 -27
- data/lib/assets/stylesheets/unpoly-bootstrap3.sass +0 -1
- data/lib/assets/stylesheets/unpoly.sass +0 -1
- data/lib/unpoly/rails/inspector.rb +0 -149
- data/lib/unpoly/rails/inspector_accessor.rb +0 -30
- data/package.json +0 -38
- data/spec_app/.firefox-version +0 -1
- data/spec_app/.gitignore +0 -17
- data/spec_app/.rspec +0 -2
- data/spec_app/Gemfile +0 -29
- data/spec_app/Gemfile.lock +0 -223
- data/spec_app/README.rdoc +0 -28
- data/spec_app/Rakefile +0 -6
- data/spec_app/app/assets/images/.keep +0 -0
- data/spec_app/app/assets/images/favicon.png +0 -0
- data/spec_app/app/assets/images/grid.png +0 -0
- data/spec_app/app/assets/javascripts/bootstrap_manifest.coffee +0 -6
- data/spec_app/app/assets/javascripts/integration_test.coffee +0 -5
- data/spec_app/app/assets/javascripts/jasmine_specs.coffee +0 -6
- data/spec_app/app/assets/stylesheets/_helpers.sass +0 -5
- data/spec_app/app/assets/stylesheets/bootstrap_manifest.sass +0 -2
- data/spec_app/app/assets/stylesheets/integration_test.sass +0 -88
- data/spec_app/app/assets/stylesheets/jasmine_specs.sass +0 -20
- data/spec_app/app/controllers/application_controller.rb +0 -14
- data/spec_app/app/controllers/binding_test_controller.rb +0 -51
- data/spec_app/app/controllers/boot_test_controller.rb +0 -31
- data/spec_app/app/controllers/compiler_test_controller.rb +0 -5
- data/spec_app/app/controllers/css_test_controller.rb +0 -5
- data/spec_app/app/controllers/error_test_controller.rb +0 -5
- data/spec_app/app/controllers/form_test/basics_controller.rb +0 -14
- data/spec_app/app/controllers/form_test/redirects_controller.rb +0 -17
- data/spec_app/app/controllers/form_test/uploads_controller.rb +0 -15
- data/spec_app/app/controllers/hash_test_controller.rb +0 -5
- data/spec_app/app/controllers/method_test_controller.rb +0 -16
- data/spec_app/app/controllers/motion_test_controller.rb +0 -5
- data/spec_app/app/controllers/pages_controller.rb +0 -17
- data/spec_app/app/controllers/replace_test_controller.rb +0 -5
- data/spec_app/app/controllers/reveal_test_controller.rb +0 -5
- data/spec_app/app/controllers/scroll_test_controller.rb +0 -5
- data/spec_app/app/helpers/application_helper.rb +0 -11
- data/spec_app/app/mailers/.keep +0 -0
- data/spec_app/app/models/concerns/.keep +0 -0
- data/spec_app/app/views/boot_test/defer.erb +0 -18
- data/spec_app/app/views/boot_test/module.erb +0 -18
- data/spec_app/app/views/boot_test/sync.erb +0 -17
- data/spec_app/app/views/compiler_test/timestamp.erb +0 -10
- data/spec_app/app/views/css_test/modal.erb +0 -47
- data/spec_app/app/views/css_test/modal_contents.erb +0 -5
- data/spec_app/app/views/css_test/modal_contents_wide.erb +0 -5
- data/spec_app/app/views/css_test/popup.erb +0 -81
- data/spec_app/app/views/css_test/popup_contents.erb +0 -5
- data/spec_app/app/views/css_test/tooltip.erb +0 -48
- data/spec_app/app/views/error_test/trigger.erb +0 -80
- data/spec_app/app/views/error_test/unexpected_response.erb +0 -3
- data/spec_app/app/views/form_test/basics/new.erb +0 -60
- data/spec_app/app/views/form_test/redirects/new.erb +0 -27
- data/spec_app/app/views/form_test/redirects/target.erb +0 -6
- data/spec_app/app/views/form_test/submission_result.erb +0 -30
- data/spec_app/app/views/form_test/uploads/new.erb +0 -44
- data/spec_app/app/views/hash_test/unpoly.erb +0 -30
- data/spec_app/app/views/hash_test/vanilla.erb +0 -13
- data/spec_app/app/views/layouts/integration_test.erb +0 -22
- data/spec_app/app/views/layouts/jasmine_rails/spec_runner.html.erb +0 -20
- data/spec_app/app/views/method_test/form_target.erb +0 -17
- data/spec_app/app/views/method_test/page1.erb +0 -11
- data/spec_app/app/views/method_test/page2.erb +0 -6
- data/spec_app/app/views/motion_test/animations.erb +0 -16
- data/spec_app/app/views/motion_test/transitions.erb +0 -13
- data/spec_app/app/views/pages/start.erb +0 -82
- data/spec_app/app/views/replace_test/_nav.erb +0 -6
- data/spec_app/app/views/replace_test/page1.erb +0 -14
- data/spec_app/app/views/replace_test/page2.erb +0 -14
- data/spec_app/app/views/replace_test/table.erb +0 -16
- data/spec_app/app/views/reveal_test/long1.erb +0 -17
- data/spec_app/app/views/reveal_test/long2.erb +0 -17
- data/spec_app/app/views/reveal_test/within_document_viewport.erb +0 -24
- data/spec_app/app/views/reveal_test/within_overflowing_div_viewport.erb +0 -28
- data/spec_app/app/views/scroll_test/long1.erb +0 -30
- data/spec_app/bin/bundle +0 -3
- data/spec_app/bin/rails +0 -8
- data/spec_app/bin/rake +0 -8
- data/spec_app/bin/setup +0 -29
- data/spec_app/bin/spring +0 -18
- data/spec_app/config/application.rb +0 -28
- data/spec_app/config/boot.rb +0 -3
- data/spec_app/config/database.yml +0 -25
- data/spec_app/config/environment.rb +0 -5
- data/spec_app/config/environments/development.rb +0 -41
- data/spec_app/config/environments/production.rb +0 -79
- data/spec_app/config/environments/test.rb +0 -42
- data/spec_app/config/initializers/assets.rb +0 -19
- data/spec_app/config/initializers/backtrace_silencers.rb +0 -7
- data/spec_app/config/initializers/bower_rails.rb +0 -16
- data/spec_app/config/initializers/cookies_serializer.rb +0 -3
- data/spec_app/config/initializers/filter_parameter_logging.rb +0 -4
- data/spec_app/config/initializers/inflections.rb +0 -16
- data/spec_app/config/initializers/mime_types.rb +0 -4
- data/spec_app/config/initializers/session_store.rb +0 -3
- data/spec_app/config/initializers/wrap_parameters.rb +0 -14
- data/spec_app/config/locales/en.yml +0 -23
- data/spec_app/config/routes.rb +0 -33
- data/spec_app/config/secrets.yml +0 -22
- data/spec_app/config.ru +0 -4
- data/spec_app/db/schema.rb +0 -23
- data/spec_app/db/seeds.rb +0 -7
- data/spec_app/lib/assets/.keep +0 -0
- data/spec_app/lib/tasks/.keep +0 -0
- data/spec_app/lib/tasks/cucumber.rake +0 -65
- data/spec_app/log/.keep +0 -0
- data/spec_app/public/404.html +0 -67
- data/spec_app/public/422.html +0 -67
- data/spec_app/public/500.html +0 -66
- data/spec_app/public/favicon.ico +0 -0
- data/spec_app/public/robots.txt +0 -5
- data/spec_app/script/cucumber +0 -10
- data/spec_app/spec/controllers/binding_test_controller_spec.rb +0 -248
- data/spec_app/spec/javascripts/helpers/agent_detector.coffee +0 -20
- data/spec_app/spec/javascripts/helpers/async_sequence.js.coffee +0 -103
- data/spec_app/spec/javascripts/helpers/browser_switches.js.coffee +0 -21
- data/spec_app/spec/javascripts/helpers/enable_logging.js.coffee +0 -2
- data/spec_app/spec/javascripts/helpers/fixture.js.coffee +0 -25
- data/spec_app/spec/javascripts/helpers/index.js.coffee +0 -1
- data/spec_app/spec/javascripts/helpers/jquery_no_conflict.js +0 -1
- data/spec_app/spec/javascripts/helpers/knife.js.coffee +0 -69
- data/spec_app/spec/javascripts/helpers/last_request.js.coffee +0 -25
- data/spec_app/spec/javascripts/helpers/mock_ajax.js.coffee +0 -8
- data/spec_app/spec/javascripts/helpers/mock_clock.js.coffee +0 -2
- data/spec_app/spec/javascripts/helpers/parse_form_data.js.coffee +0 -24
- data/spec_app/spec/javascripts/helpers/promise_state.js +0 -18
- data/spec_app/spec/javascripts/helpers/protect_jasmine_runner.coffee +0 -12
- data/spec_app/spec/javascripts/helpers/remove_body_margin.js.coffee +0 -8
- data/spec_app/spec/javascripts/helpers/reset_history.js.coffee +0 -23
- data/spec_app/spec/javascripts/helpers/reset_knife.js.coffee +0 -2
- data/spec_app/spec/javascripts/helpers/reset_up.js.coffee +0 -25
- data/spec_app/spec/javascripts/helpers/restore_body_scroll.js.coffee +0 -5
- data/spec_app/spec/javascripts/helpers/show_lib_versions.coffee +0 -12
- data/spec_app/spec/javascripts/helpers/spec_util.coffee +0 -47
- data/spec_app/spec/javascripts/helpers/to_be_around.js.coffee +0 -8
- data/spec_app/spec/javascripts/helpers/to_be_array.coffee +0 -5
- data/spec_app/spec/javascripts/helpers/to_be_attached.coffee +0 -9
- data/spec_app/spec/javascripts/helpers/to_be_blank.js.coffee +0 -8
- data/spec_app/spec/javascripts/helpers/to_be_detached.coffee +0 -9
- data/spec_app/spec/javascripts/helpers/to_be_element.js.coffee +0 -8
- data/spec_app/spec/javascripts/helpers/to_be_error.coffee +0 -8
- data/spec_app/spec/javascripts/helpers/to_be_given.js.coffee +0 -8
- data/spec_app/spec/javascripts/helpers/to_be_hidden.js.coffee +0 -8
- data/spec_app/spec/javascripts/helpers/to_be_jquery.js.coffee +0 -5
- data/spec_app/spec/javascripts/helpers/to_be_missing.js.coffee +0 -8
- data/spec_app/spec/javascripts/helpers/to_be_present.js.coffee +0 -8
- data/spec_app/spec/javascripts/helpers/to_be_scrolled_to.coffee +0 -11
- data/spec_app/spec/javascripts/helpers/to_be_visible.js.coffee +0 -9
- data/spec_app/spec/javascripts/helpers/to_contain.js.coffee +0 -8
- data/spec_app/spec/javascripts/helpers/to_end_with.js.coffee +0 -11
- data/spec_app/spec/javascripts/helpers/to_equal_jquery.js.coffee +0 -8
- data/spec_app/spec/javascripts/helpers/to_equal_node_list.coffee +0 -7
- data/spec_app/spec/javascripts/helpers/to_equal_via_is_equal.js.coffee +0 -7
- data/spec_app/spec/javascripts/helpers/to_have_class.js.coffee +0 -10
- data/spec_app/spec/javascripts/helpers/to_have_descendant.js.coffee +0 -10
- data/spec_app/spec/javascripts/helpers/to_have_length.js.coffee +0 -8
- data/spec_app/spec/javascripts/helpers/to_have_opacity.coffee +0 -15
- data/spec_app/spec/javascripts/helpers/to_have_own_property.js.coffee +0 -8
- data/spec_app/spec/javascripts/helpers/to_have_request_method.js.coffee +0 -16
- data/spec_app/spec/javascripts/helpers/to_have_text.js.coffee +0 -9
- data/spec_app/spec/javascripts/helpers/to_have_unhandled_rejections.coffee +0 -18
- data/spec_app/spec/javascripts/helpers/to_match_list.coffee +0 -14
- data/spec_app/spec/javascripts/helpers/to_match_selector.coffee +0 -8
- data/spec_app/spec/javascripts/helpers/to_match_text.js.coffee +0 -13
- data/spec_app/spec/javascripts/helpers/to_match_url.coffee +0 -14
- data/spec_app/spec/javascripts/helpers/trigger.js.coffee +0 -200
- data/spec_app/spec/javascripts/helpers/wait_until_dom_ready.js.coffee +0 -5
- data/spec_app/spec/javascripts/support/jasmine.yml +0 -51
- data/spec_app/spec/javascripts/up/browser_spec.js.coffee +0 -150
- data/spec_app/spec/javascripts/up/classes/cache_spec.js.coffee +0 -82
- data/spec_app/spec/javascripts/up/classes/config_spec.coffee +0 -24
- data/spec_app/spec/javascripts/up/classes/divertible_chain_spec.coffee +0 -45
- data/spec_app/spec/javascripts/up/classes/focus_tracker_spec.coffee +0 -34
- data/spec_app/spec/javascripts/up/classes/params_spec.coffee +0 -557
- data/spec_app/spec/javascripts/up/classes/request_spec.coffee +0 -50
- data/spec_app/spec/javascripts/up/classes/scroll_motion_spec.js.coffee +0 -51
- data/spec_app/spec/javascripts/up/classes/store/memory_spec.js.coffee +0 -70
- data/spec_app/spec/javascripts/up/classes/store/session_spec.js.coffee +0 -114
- data/spec_app/spec/javascripts/up/element_spec.coffee +0 -897
- data/spec_app/spec/javascripts/up/event_spec.js.coffee +0 -530
- data/spec_app/spec/javascripts/up/feedback_spec.js.coffee +0 -401
- data/spec_app/spec/javascripts/up/form_spec.js.coffee +0 -1527
- data/spec_app/spec/javascripts/up/fragment_spec.js.coffee +0 -2624
- data/spec_app/spec/javascripts/up/history_spec.js.coffee +0 -340
- data/spec_app/spec/javascripts/up/jquery_spec.js.coffee +0 -4
- data/spec_app/spec/javascripts/up/legacy_spec.js.coffee +0 -27
- data/spec_app/spec/javascripts/up/link_spec.js.coffee +0 -1098
- data/spec_app/spec/javascripts/up/log_spec.js.coffee +0 -119
- data/spec_app/spec/javascripts/up/modal_spec.js.coffee +0 -939
- data/spec_app/spec/javascripts/up/motion_spec.js.coffee +0 -582
- data/spec_app/spec/javascripts/up/popup_spec.js.coffee +0 -508
- data/spec_app/spec/javascripts/up/protocol_spec.js.coffee +0 -39
- data/spec_app/spec/javascripts/up/proxy_spec.js.coffee +0 -1145
- data/spec_app/spec/javascripts/up/radio_spec.js.coffee +0 -212
- data/spec_app/spec/javascripts/up/rails_spec.js.coffee +0 -118
- data/spec_app/spec/javascripts/up/spec_spec.js.coffee +0 -9
- data/spec_app/spec/javascripts/up/syntax_spec.js.coffee +0 -304
- data/spec_app/spec/javascripts/up/toast_spec.js.coffee +0 -37
- data/spec_app/spec/javascripts/up/tooltip_spec.js.coffee +0 -163
- data/spec_app/spec/javascripts/up/util_spec.js.coffee +0 -1434
- data/spec_app/spec/javascripts/up/viewport_spec.js.coffee +0 -655
- data/spec_app/spec/spec_helper.rb +0 -62
- data/spec_app/test/controllers/.keep +0 -0
- data/spec_app/test/fixtures/.keep +0 -0
- data/spec_app/test/helpers/.keep +0 -0
- data/spec_app/test/integration/.keep +0 -0
- data/spec_app/test/mailers/.keep +0 -0
- data/spec_app/test/models/.keep +0 -0
- data/spec_app/test/test_helper.rb +0 -10
- data/spec_app/vendor/asset-libs/es6-promise-4.1.6/es6-promise.auto.js +0 -1159
- data/spec_app/vendor/asset-libs/jasmine-ajax-3.3.1/.bower.json +0 -43
- data/spec_app/vendor/asset-libs/jasmine-ajax-3.3.1/.gitignore +0 -6
- data/spec_app/vendor/asset-libs/jasmine-ajax-3.3.1/.npmignore +0 -10
- data/spec_app/vendor/asset-libs/jasmine-ajax-3.3.1/.pairs +0 -6
- data/spec_app/vendor/asset-libs/jasmine-ajax-3.3.1/.travis.yml +0 -56
- data/spec_app/vendor/asset-libs/jasmine-ajax-3.3.1/jasmine-ajax.js +0 -790
- data/spec_app/vendor/assets/.keep +0 -0
- data/unpoly-rails.gemspec +0 -24
@@ -1,1084 +0,0 @@
|
|
1
|
-
###**
|
2
|
-
Forms
|
3
|
-
=====
|
4
|
-
|
5
|
-
Unpoly comes with functionality to [submit](/form-up-target) and [validate](/input-up-validate)
|
6
|
-
forms without leaving the current page. This means you can replace page fragments,
|
7
|
-
open dialogs with sub-forms, etc. all without losing form state.
|
8
|
-
|
9
|
-
@module up.form
|
10
|
-
###
|
11
|
-
up.form = do ->
|
12
|
-
|
13
|
-
u = up.util
|
14
|
-
e = up.element
|
15
|
-
|
16
|
-
###**
|
17
|
-
Sets default options for form submission and validation.
|
18
|
-
|
19
|
-
@property up.form.config
|
20
|
-
@param {number} [config.observeDelay=0]
|
21
|
-
The number of miliseconds to wait before [`up.observe()`](/up.observe) runs the callback
|
22
|
-
after the input value changes. Use this to limit how often the callback
|
23
|
-
will be invoked for a fast typist.
|
24
|
-
@param {Array} [config.validateTargets=['[up-fieldset]:has(&)', 'fieldset:has(&)', 'label:has(&)', 'form:has(&)']]
|
25
|
-
An array of CSS selectors that are searched around a form field
|
26
|
-
that wants to [validate](/up.validate). The first matching selector
|
27
|
-
will be updated with the validation messages from the server.
|
28
|
-
|
29
|
-
By default this looks for a `<fieldset>`, `<label>` or `<form>`
|
30
|
-
around the validating input field.
|
31
|
-
@param {string} [config.fields]
|
32
|
-
An array of CSS selectors that represent form fields, such as `input` or `select`.
|
33
|
-
@param {string} [config.submitButtons]
|
34
|
-
An array of CSS selectors that represent submit buttons, such as `input[type=submit]`.
|
35
|
-
@stable
|
36
|
-
###
|
37
|
-
config = new up.Config
|
38
|
-
validateTargets: ['[up-fieldset]:has(&)', 'fieldset:has(&)', 'label:has(&)', 'form:has(&)']
|
39
|
-
fields: ['select', 'input:not([type=submit]):not([type=image])', 'button[type]:not([type=submit])', 'textarea'],
|
40
|
-
submitButtons: ['input[type=submit]', 'input[type=image]', 'button[type=submit]', 'button:not([type])']
|
41
|
-
observeDelay: 0
|
42
|
-
|
43
|
-
reset = ->
|
44
|
-
config.reset()
|
45
|
-
|
46
|
-
###**
|
47
|
-
@function up.form.fieldSelector
|
48
|
-
@internal
|
49
|
-
###
|
50
|
-
fieldSelector = (suffix = '') ->
|
51
|
-
config.fields.map((field) -> field + suffix).join(',')
|
52
|
-
|
53
|
-
###**
|
54
|
-
Returns a list of form fields within the given element.
|
55
|
-
|
56
|
-
You can configure what Unpoly considers a form field by adding CSS selectors to the
|
57
|
-
[`up.form.config.fields`](/up.form.config#config.fields) array.
|
58
|
-
|
59
|
-
If the given element is itself a form field, a list of that given element is returned.
|
60
|
-
|
61
|
-
@function up.form.fields
|
62
|
-
@param {Element|jQuery} root
|
63
|
-
The element to scan for contained form fields.
|
64
|
-
|
65
|
-
If the element is itself a form field, a list of that element is returned.
|
66
|
-
@return {NodeList<Element>|Array<Element>}
|
67
|
-
@experimental
|
68
|
-
###
|
69
|
-
findFields = (root) ->
|
70
|
-
root = e.get(root)
|
71
|
-
fields = e.subtree(root, fieldSelector())
|
72
|
-
if e.matches(root, 'form[id]')
|
73
|
-
outsideFieldSelector = fieldSelector(e.attributeSelector('form', root.id))
|
74
|
-
outsideFields = e.all(outsideFieldSelector)
|
75
|
-
fields.push(outsideFields...)
|
76
|
-
fields = u.uniq(fields)
|
77
|
-
fields
|
78
|
-
|
79
|
-
# findFields = (rootOrRoots) ->
|
80
|
-
# rootOrRoots = e.list(rootOrRoots)
|
81
|
-
# u.flatMap rootOrRoots, (root) -> e.subtree(root, fieldSelector())
|
82
|
-
|
83
|
-
###***
|
84
|
-
@function up.form.submissionFields
|
85
|
-
@internal
|
86
|
-
###
|
87
|
-
findSubmissionFields = (root) ->
|
88
|
-
fields = findFields(root)
|
89
|
-
if button = submittingButton(root)
|
90
|
-
fields = u.toArray(fields)
|
91
|
-
fields.push(button)
|
92
|
-
fields
|
93
|
-
|
94
|
-
###**
|
95
|
-
@function up.form.submittingButton
|
96
|
-
@internal
|
97
|
-
###
|
98
|
-
submittingButton = (form) ->
|
99
|
-
selector = submitButtonSelector()
|
100
|
-
focusedElement = document.activeElement
|
101
|
-
if focusedElement && e.matches(focusedElement, selector) && form.contains(focusedElement)
|
102
|
-
return focusedElement
|
103
|
-
else
|
104
|
-
# If no button is focused, we assume the first button in the form.
|
105
|
-
return e.first(form, selector)
|
106
|
-
|
107
|
-
###**
|
108
|
-
@function up.form.submitButtonSelector
|
109
|
-
@internal
|
110
|
-
###
|
111
|
-
submitButtonSelector = ->
|
112
|
-
config.submitButtons.join(',')
|
113
|
-
|
114
|
-
###**
|
115
|
-
Submits a form via AJAX and updates a page fragment with the response.
|
116
|
-
|
117
|
-
up.submit('form.new-user', { target: '.main' })
|
118
|
-
|
119
|
-
Instead of loading a new page, the form is submitted via AJAX.
|
120
|
-
The response is parsed for a CSS selector and the matching elements will
|
121
|
-
replace corresponding elements on the current page.
|
122
|
-
|
123
|
-
The unobtrusive variant of this is the [`form[up-target]`](/form-up-target) selector.
|
124
|
-
See the documentation for [`form[up-target]`](/form-up-target) for more
|
125
|
-
information on how AJAX form submissions work in Unpoly.
|
126
|
-
|
127
|
-
Emits the event [`up:form:submit`](/up:form:submit).
|
128
|
-
|
129
|
-
@function up.submit
|
130
|
-
@param {Element|jQuery|string} formOrSelector
|
131
|
-
A reference or selector for the form to submit.
|
132
|
-
If the argument points to an element that is not a form,
|
133
|
-
Unpoly will search its ancestors for the closest form.
|
134
|
-
@param {string} [options.url]
|
135
|
-
The URL where to submit the form.
|
136
|
-
Defaults to the form's `action` attribute, or to the current URL of the browser window.
|
137
|
-
@param {string} [options.method='post']
|
138
|
-
The HTTP method used for the form submission.
|
139
|
-
Defaults to the form's `up-method`, `data-method` or `method` attribute, or to `'post'`
|
140
|
-
if none of these attributes are given.
|
141
|
-
@param {string} [options.target]
|
142
|
-
The CSS selector to update when the form submission succeeds (server responds with status 200).
|
143
|
-
Defaults to the form's `up-target` attribute.
|
144
|
-
|
145
|
-
Inside the CSS selector you may refer to the form as `&` ([like in Sass](https://sass-lang.com/documentation/file.SASS_REFERENCE.html#parent-selector)).
|
146
|
-
@param {string} [options.failTarget]
|
147
|
-
The CSS selector to update when the form submission fails (server responds with non-200 status).
|
148
|
-
Defaults to the form's `up-fail-target` attribute, or to an auto-generated
|
149
|
-
selector that matches the form itself.
|
150
|
-
|
151
|
-
Inside the CSS selector you may refer to the form as `&` ([like in Sass](https://sass-lang.com/documentation/file.SASS_REFERENCE.html#parent-selector)).
|
152
|
-
@param {string} [options.fallback]
|
153
|
-
The selector to update when the original target was not found in the page.
|
154
|
-
Defaults to the form's `up-fallback` attribute.
|
155
|
-
@param {boolean|string} [options.history=true]
|
156
|
-
Successful form submissions will add a history entry and change the browser's
|
157
|
-
location bar if the form either uses the `GET` method or the response redirected
|
158
|
-
to another page (this requires the `unpoly-rails` gem).
|
159
|
-
If you want to prevent history changes in any case, set this to `false`.
|
160
|
-
If you pass a string, it is used as the URL for the browser history.
|
161
|
-
@param {string} [options.transition='none']
|
162
|
-
The transition to use when a successful form submission updates the `options.target` selector.
|
163
|
-
Defaults to the form's `up-transition` attribute, or to `'none'`.
|
164
|
-
@param {string} [options.failTransition='none']
|
165
|
-
The transition to use when a failed form submission updates the `options.failTarget` selector.
|
166
|
-
Defaults to the form's `up-fail-transition` attribute, or to `options.transition`, or to `'none'`.
|
167
|
-
@param {number} [options.duration]
|
168
|
-
The duration of the transition. See [`up.morph()`](/up.morph).
|
169
|
-
@param {number} [options.delay]
|
170
|
-
The delay before the transition starts. See [`up.morph()`](/up.morph).
|
171
|
-
@param {string} [options.easing]
|
172
|
-
The timing function that controls the transition's acceleration. [`up.morph()`](/up.morph).
|
173
|
-
@param {Element|string} [options.reveal=true]
|
174
|
-
Whether to reveal the target fragment after it was replaced.
|
175
|
-
|
176
|
-
You can also pass a CSS selector for the element to reveal.
|
177
|
-
@param {boolean|string} [options.failReveal=true]
|
178
|
-
Whether to [reveal](/up.reveal) the target fragment when the server responds with an error.
|
179
|
-
|
180
|
-
You can also pass a CSS selector for the element to reveal.
|
181
|
-
@param {boolean} [options.restoreScroll]
|
182
|
-
If set to `true`, this will attempt to [`restore scroll positions`](/up.restoreScroll)
|
183
|
-
previously seen on the destination URL.
|
184
|
-
@param {boolean} [options.cache]
|
185
|
-
Whether to force the use of a cached response (`true`)
|
186
|
-
or never use the cache (`false`)
|
187
|
-
or make an educated guess (`undefined`).
|
188
|
-
|
189
|
-
By default only responses to `GET` requests are cached
|
190
|
-
for a few minutes.
|
191
|
-
@param {Object} [options.headers={}]
|
192
|
-
An object of additional header key/value pairs to send along
|
193
|
-
with the request.
|
194
|
-
@param {string} [options.layer='auto']
|
195
|
-
The name of the layer that ought to be updated. Valid values are
|
196
|
-
`'auto'`, `'page'`, `'modal'` and `'popup'`.
|
197
|
-
|
198
|
-
If set to `'auto'` (default), Unpoly will try to find a match in the form's layer.
|
199
|
-
@param {string} [options.failLayer='auto']
|
200
|
-
The name of the layer that ought to be updated if the server sends a non-200 status code.
|
201
|
-
@param {Object|FormData|string|Array|up.Params} [options.params]
|
202
|
-
Extra form [parameters](/up.Params) that will be submitted in addition to
|
203
|
-
the parameters from the form.
|
204
|
-
@return {Promise}
|
205
|
-
A promise for the successful form submission.
|
206
|
-
@stable
|
207
|
-
###
|
208
|
-
submit = (formOrSelector, options) ->
|
209
|
-
options = u.options(options)
|
210
|
-
|
211
|
-
form = e.get(formOrSelector)
|
212
|
-
form = e.closest(form, 'form')
|
213
|
-
|
214
|
-
target = options.target ? form.getAttribute('up-target') ? 'body'
|
215
|
-
options.failTarget ?= form.getAttribute('up-fail-target') ? e.toSelector(form)
|
216
|
-
options.reveal ?= e.booleanOrStringAttr(form, 'up-reveal') ? true
|
217
|
-
options.failReveal ?= e.booleanOrStringAttr(form, 'up-fail-reveal') ? true
|
218
|
-
options.fallback ?= form.getAttribute('up-fallback')
|
219
|
-
options.history ?= e.booleanOrStringAttr(form, 'up-history') ? true
|
220
|
-
options.transition ?= e.booleanOrStringAttr(form, 'up-transition')
|
221
|
-
options.failTransition ?= e.booleanOrStringAttr(form, 'up-fail-transition')
|
222
|
-
options.method ?= u.normalizeMethod(form.getAttribute('up-method') ? form.getAttribute('data-method') ? form.getAttribute('method') ? 'post')
|
223
|
-
options.cache ?= e.booleanAttr(form, 'up-cache')
|
224
|
-
options.restoreScroll ?= e.booleanAttr(form, 'up-restore-scroll') # the option supports an object value, but not the attr
|
225
|
-
options.origin ?= form
|
226
|
-
options.layer ?= form.getAttribute('up-layer')
|
227
|
-
options.failLayer ?= form.getAttribute('up-fail-layer')
|
228
|
-
|
229
|
-
# Take params from form, but allow to pass additional params as { params }
|
230
|
-
options.params = up.Params.fromForm(form).addAll(options.params)
|
231
|
-
|
232
|
-
options = u.merge(options, up.motion.animateOptions(options, form))
|
233
|
-
|
234
|
-
if options.validate
|
235
|
-
options.headers ||= {}
|
236
|
-
options.transition = false
|
237
|
-
options.failTransition = false
|
238
|
-
options.headers[up.protocol.config.validateHeader] = options.validate
|
239
|
-
|
240
|
-
url = options.url ? form.getAttribute('action') ? up.browser.url()
|
241
|
-
|
242
|
-
if options.method == 'GET'
|
243
|
-
# Only for GET forms, browsers discard all query params from the form's [action] URL.
|
244
|
-
# The URLs search part will be replaced with the serialized form data.
|
245
|
-
# See design/query-params-in-form-actions/cases.html for
|
246
|
-
# a demo of vanilla browser behavior.
|
247
|
-
url = up.Params.stripURL(url)
|
248
|
-
|
249
|
-
up.event.whenEmitted('up:form:submit', log: 'Submitting form', target: form).then ->
|
250
|
-
up.feedback.start(form)
|
251
|
-
|
252
|
-
# If we can't update the location URL, fall back to a vanilla form submission.
|
253
|
-
unless up.browser.canPushState() || options.history == false
|
254
|
-
# Don't use up.browser.navigate(); It cannot deal with file inputs.
|
255
|
-
form.submit()
|
256
|
-
return u.unresolvablePromise()
|
257
|
-
|
258
|
-
promise = up.replace(target, url, options)
|
259
|
-
u.always promise, -> up.feedback.stop(form)
|
260
|
-
promise
|
261
|
-
|
262
|
-
###**
|
263
|
-
This event is [emitted](/up.emit) when a form is [submitted](/up.submit) through Unpoly.
|
264
|
-
|
265
|
-
The event is emitted on the`<form>` element.
|
266
|
-
|
267
|
-
@event up:form:submit
|
268
|
-
@param {Element} event.target
|
269
|
-
The `<form>` element that will be submitted.
|
270
|
-
@param event.preventDefault()
|
271
|
-
Event listeners may call this method to prevent the form from being submitted.
|
272
|
-
@stable
|
273
|
-
###
|
274
|
-
|
275
|
-
###**
|
276
|
-
Observes form fields and runs a callback when a value changes.
|
277
|
-
|
278
|
-
This is useful for observing text fields while the user is typing.
|
279
|
-
|
280
|
-
The unobtrusive variant of this is the [`[up-observe]`](/up-observe) attribute.
|
281
|
-
|
282
|
-
\#\#\# Example
|
283
|
-
|
284
|
-
The following would print to the console whenever an input field changes:
|
285
|
-
|
286
|
-
up.observe('input.query', function(value) {
|
287
|
-
console.log('Query is now %o', value)
|
288
|
-
})
|
289
|
-
|
290
|
-
Instead of a single form field, you can also pass multiple fields,
|
291
|
-
a `<form>` or any container that contains form fields.
|
292
|
-
The callback will be run if any of the given fields change:
|
293
|
-
|
294
|
-
up.observe('form', function(value, name) {
|
295
|
-
console.log('The value of %o is now %o', name, value)
|
296
|
-
})
|
297
|
-
|
298
|
-
You may also pass the `{ batch: true }` option to receive all
|
299
|
-
changes since the last callback in a single object:
|
300
|
-
|
301
|
-
up.observe('form', { batch: true }, function(diff) {
|
302
|
-
console.log('Observed one or more changes: %o', diff)
|
303
|
-
})
|
304
|
-
|
305
|
-
@function up.observe
|
306
|
-
@param {string|Element|Array<Element>|jQuery} elements
|
307
|
-
The form fields that will be observed.
|
308
|
-
|
309
|
-
You can pass one or more fields, a `<form>` or any container that contains form fields.
|
310
|
-
The callback will be run if any of the given fields change.
|
311
|
-
@param {boolean} [options.batch=false]
|
312
|
-
If set to `true`, the `onChange` callback will receive multiple
|
313
|
-
detected changes in a single diff object as its argument.
|
314
|
-
@param {number} [options.delay=up.form.config.observeDelay]
|
315
|
-
The number of miliseconds to wait before executing the callback
|
316
|
-
after the input value changes. Use this to limit how often the callback
|
317
|
-
will be invoked for a fast typist.
|
318
|
-
@param {Function(value, name): string} onChange
|
319
|
-
The callback to run when the field's value changes.
|
320
|
-
|
321
|
-
If given as a function, it receives two arguments (`value`, `name`).
|
322
|
-
`value` is a string with the new attribute value and `string` is the name
|
323
|
-
of the form field that changed.
|
324
|
-
|
325
|
-
If given as a string, it will be evaled as JavaScript code in a context where
|
326
|
-
(`value`, `name`) are set.
|
327
|
-
@return {Function()}
|
328
|
-
A destructor function that removes the observe watch when called.
|
329
|
-
@stable
|
330
|
-
###
|
331
|
-
observe = (elements, args...) ->
|
332
|
-
elements = e.list(elements)
|
333
|
-
fields = u.flatMap(elements, findFields)
|
334
|
-
callback = u.extractCallback(args) ? observeCallbackFromElement(elements[0]) ? up.fail('up.observe: No change callback given')
|
335
|
-
options = u.extractOptions(args)
|
336
|
-
options.delay = options.delay ? e.numberAttr(elements[0], 'up-delay') ? config.observeDelay
|
337
|
-
observer = new up.FieldObserver(fields, options, callback)
|
338
|
-
observer.start()
|
339
|
-
return observer.stop
|
340
|
-
|
341
|
-
observeCallbackFromElement = (element) ->
|
342
|
-
if rawCallback = element.getAttribute('up-observe')
|
343
|
-
new Function('value', 'name', rawCallback)
|
344
|
-
|
345
|
-
###**
|
346
|
-
[Observes](/up.observe) a field or form and submits the form when a value changes.
|
347
|
-
|
348
|
-
Both the form and the changed field will be assigned a CSS class [`form-up-active`](/form-up-active)
|
349
|
-
while the autosubmitted form is processing.
|
350
|
-
|
351
|
-
The unobtrusive variant of this is the [`up-autosubmit`](/form-up-autosubmit) attribute.
|
352
|
-
|
353
|
-
@function up.autosubmit
|
354
|
-
@param {string|Element|jQuery} selectorOrElement
|
355
|
-
The field or form to observe.
|
356
|
-
@param {Object} [options]
|
357
|
-
See options for [`up.observe()`](/up.observe)
|
358
|
-
@return {Function()}
|
359
|
-
A destructor function that removes the observe watch when called.
|
360
|
-
@stable
|
361
|
-
###
|
362
|
-
autosubmit = (selectorOrElement, options) ->
|
363
|
-
observe(selectorOrElement, options, -> submit(selectorOrElement))
|
364
|
-
|
365
|
-
findValidateTarget = (field, options) ->
|
366
|
-
option = options.target ? field.getAttribute('up-validate')
|
367
|
-
option ||= u.findResult config.validateTargets, (defaultTarget) ->
|
368
|
-
resolvedDefault = e.resolveSelector(defaultTarget, options.origin)
|
369
|
-
if e.first(resolvedDefault)
|
370
|
-
# We want to return the selector, *not* the element. If we returned the element
|
371
|
-
# and derive a selector from that, any :has() expression would be lost.
|
372
|
-
return resolvedDefault
|
373
|
-
|
374
|
-
unless option
|
375
|
-
up.fail('Could not find validation target for %o (tried defaults %o)', field, config.validateTargets)
|
376
|
-
|
377
|
-
# resolveSelector() also creates a selector string if given an element
|
378
|
-
return e.resolveSelector(option, options.origin)
|
379
|
-
|
380
|
-
###**
|
381
|
-
Performs a server-side validation of a form field.
|
382
|
-
|
383
|
-
`up.validate()` submits the given field's form with an additional `X-Up-Validate`
|
384
|
-
HTTP header. Upon seeing this header, the server is expected to validate (but not save)
|
385
|
-
the form submission and render a new copy of the form with validation errors.
|
386
|
-
|
387
|
-
The unobtrusive variant of this is the [`input[up-validate]`](/input-up-validate) selector.
|
388
|
-
See the documentation for [`input[up-validate]`](/input-up-validate) for more information
|
389
|
-
on how server-side validation works in Unpoly.
|
390
|
-
|
391
|
-
\#\#\# Example
|
392
|
-
|
393
|
-
up.validate('input[name=email]', { target: '.email-errors' })
|
394
|
-
|
395
|
-
@function up.validate
|
396
|
-
@param {string|Element|jQuery} fieldOrSelector
|
397
|
-
|
398
|
-
@param {string|Element|jQuery} [options.target]
|
399
|
-
@return {Promise}
|
400
|
-
A promise that is fulfilled when the server-side
|
401
|
-
validation is received and the form was updated.
|
402
|
-
@stable
|
403
|
-
###
|
404
|
-
validate = (fieldOrSelector, options) ->
|
405
|
-
field = e.get(fieldOrSelector)
|
406
|
-
options = u.options(options)
|
407
|
-
options.origin = field
|
408
|
-
options.target = findValidateTarget(field, options)
|
409
|
-
options.failTarget = options.target
|
410
|
-
options.reveal ?= e.booleanOrStringAttr(field, 'up-reveal') ? false
|
411
|
-
options.history = false
|
412
|
-
# Make sure the X-Up-Validate header is present, so the server-side
|
413
|
-
# knows that it should not persist the form submission
|
414
|
-
options.validate = field.getAttribute('name') || ':none'
|
415
|
-
options = u.merge(options, up.motion.animateOptions(options, field))
|
416
|
-
promise = up.submit(field, options)
|
417
|
-
promise
|
418
|
-
|
419
|
-
switcherValues = (field) ->
|
420
|
-
value = undefined
|
421
|
-
meta = undefined
|
422
|
-
|
423
|
-
if e.matches(field, 'input[type=checkbox]')
|
424
|
-
if field.checked
|
425
|
-
value = field.value
|
426
|
-
meta = ':checked'
|
427
|
-
else
|
428
|
-
meta = ':unchecked'
|
429
|
-
else if e.matches(field, 'input[type=radio]')
|
430
|
-
form = closestContainer(field)
|
431
|
-
groupName = field.getAttribute('name')
|
432
|
-
checkedButton = form.querySelector("input[type=radio]#{e.attributeSelector('name', groupName)}:checked")
|
433
|
-
if checkedButton
|
434
|
-
meta = ':checked'
|
435
|
-
value = checkedButton.value
|
436
|
-
else
|
437
|
-
meta = ':unchecked'
|
438
|
-
else
|
439
|
-
value = field.value
|
440
|
-
|
441
|
-
values = []
|
442
|
-
if u.isPresent(value)
|
443
|
-
values.push(value)
|
444
|
-
values.push(':present')
|
445
|
-
else
|
446
|
-
values.push(':blank')
|
447
|
-
if u.isPresent(meta)
|
448
|
-
values.push(meta)
|
449
|
-
values
|
450
|
-
|
451
|
-
###**
|
452
|
-
Shows or hides a target selector depending on the value.
|
453
|
-
|
454
|
-
See [`input[up-switch]`](/input-up-switch) for more documentation and examples.
|
455
|
-
|
456
|
-
This function does not currently have a very useful API outside
|
457
|
-
of our use for `up-switch`'s UJS behavior, that's why it's currently
|
458
|
-
still marked `@internal`.
|
459
|
-
|
460
|
-
@function up.form.switchTargets
|
461
|
-
@param {Element} switcher
|
462
|
-
@param {string} [options.target]
|
463
|
-
The target selectors to switch.
|
464
|
-
Defaults to an `[up-switch]` attribute on the given field.
|
465
|
-
@internal
|
466
|
-
###
|
467
|
-
switchTargets = (switcher, options = {}) ->
|
468
|
-
targetSelector = options.target ? switcher.getAttribute('up-switch')
|
469
|
-
form = closestContainer(switcher)
|
470
|
-
u.isPresent(targetSelector) or up.fail("No switch target given for %o", switcher)
|
471
|
-
fieldValues = switcherValues(switcher)
|
472
|
-
|
473
|
-
u.each e.all(form, targetSelector), (target) ->
|
474
|
-
switchTarget(target, fieldValues)
|
475
|
-
|
476
|
-
###**
|
477
|
-
@internal
|
478
|
-
###
|
479
|
-
switchTarget = (target, fieldValues) ->
|
480
|
-
fieldValues ||= switcherValues(findSwitcherForTarget(target))
|
481
|
-
|
482
|
-
if hideValues = target.getAttribute('up-hide-for')
|
483
|
-
hideValues = u.splitValues(hideValues)
|
484
|
-
show = u.intersect(fieldValues, hideValues).length == 0
|
485
|
-
else
|
486
|
-
if showValues = target.getAttribute('up-show-for')
|
487
|
-
showValues = u.splitValues(showValues)
|
488
|
-
else
|
489
|
-
# If the target has neither up-show-for or up-hide-for attributes,
|
490
|
-
# assume the user wants the target to be visible whenever anything
|
491
|
-
# is checked or entered.
|
492
|
-
showValues = [':present', ':checked']
|
493
|
-
show = u.intersect(fieldValues, showValues).length > 0
|
494
|
-
|
495
|
-
e.toggle(target, show)
|
496
|
-
target.classList.add('up-switched')
|
497
|
-
|
498
|
-
###**
|
499
|
-
@internal
|
500
|
-
###
|
501
|
-
findSwitcherForTarget = (target) ->
|
502
|
-
form = closestContainer(target)
|
503
|
-
switchers = e.all(form, '[up-switch]')
|
504
|
-
switcher = u.find switchers, (switcher) ->
|
505
|
-
targetSelector = switcher.getAttribute('up-switch')
|
506
|
-
e.matches(target, targetSelector)
|
507
|
-
return switcher or u.fail('Could not find [up-switch] field for %o', target)
|
508
|
-
|
509
|
-
closestContainer = (element) ->
|
510
|
-
e.closest(element, 'form, body')
|
511
|
-
|
512
|
-
###**
|
513
|
-
Forms with an `up-target` attribute are [submitted via AJAX](/up.submit)
|
514
|
-
instead of triggering a full page reload.
|
515
|
-
|
516
|
-
<form method="post" action="/users" up-target=".main">
|
517
|
-
...
|
518
|
-
</form>
|
519
|
-
|
520
|
-
The server response is searched for the selector given in `up-target`.
|
521
|
-
The selector content is then [replaced](/up.replace) in the current page.
|
522
|
-
|
523
|
-
The programmatic variant of this is the [`up.submit()`](/up.submit) function.
|
524
|
-
|
525
|
-
\#\#\# Failed submission
|
526
|
-
|
527
|
-
When the server was unable to save the form due to invalid params,
|
528
|
-
it will usually re-render an updated copy of the form with
|
529
|
-
validation messages.
|
530
|
-
|
531
|
-
For Unpoly to be able to detect a failed form submission,
|
532
|
-
the form must be re-rendered with a non-200 HTTP status code.
|
533
|
-
We recommend to use either 400 (bad request) or
|
534
|
-
422 (unprocessable entity).
|
535
|
-
|
536
|
-
In Ruby on Rails, you can pass a
|
537
|
-
[`:status` option to `render`](http://guides.rubyonrails.org/layouts_and_rendering.html#the-status-option)
|
538
|
-
for this:
|
539
|
-
|
540
|
-
class UsersController < ApplicationController
|
541
|
-
|
542
|
-
def create
|
543
|
-
user_params = params[:user].permit(:email, :password)
|
544
|
-
@user = User.new(user_params)
|
545
|
-
if @user.save?
|
546
|
-
sign_in @user
|
547
|
-
else
|
548
|
-
render 'form', status: :bad_request
|
549
|
-
end
|
550
|
-
end
|
551
|
-
|
552
|
-
end
|
553
|
-
|
554
|
-
Note that you can also use
|
555
|
-
[`input[up-validate]`](/input-up-validate) to perform server-side
|
556
|
-
validations while the user is completing fields.
|
557
|
-
|
558
|
-
\#\#\# Redirects
|
559
|
-
|
560
|
-
Unpoly requires an additional response header to detect redirects,
|
561
|
-
which are otherwise undetectable for an AJAX client.
|
562
|
-
|
563
|
-
After the form's action performs a redirect, the next response should echo
|
564
|
-
the new request's URL as a response header `X-Up-Location`.
|
565
|
-
|
566
|
-
If you are using Unpoly via the `unpoly-rails` gem, these headers
|
567
|
-
are set automatically for every request.
|
568
|
-
|
569
|
-
\#\#\# Giving feedback while the form is processing
|
570
|
-
|
571
|
-
The `<form>` element will be assigned a CSS class [`up-active`](/form.up-active) while
|
572
|
-
the submission is loading.
|
573
|
-
|
574
|
-
You can also [implement a spinner](/up.proxy/#spinners)
|
575
|
-
by [listening](/up.on) to the [`up:proxy:slow`](/up:proxy:slow)
|
576
|
-
and [`up:proxy:recover`](/up:proxy:recover) events.
|
577
|
-
|
578
|
-
@selector form[up-target]
|
579
|
-
@param {string} up-target
|
580
|
-
The CSS selector to [replace](/up.replace) if the form submission is successful (200 status code).
|
581
|
-
|
582
|
-
Inside the CSS selector you may refer to this form as `&` ([like in Sass](https://sass-lang.com/documentation/file.SASS_REFERENCE.html#parent-selector)).
|
583
|
-
@param {string} [up-fail-target]
|
584
|
-
The CSS selector to [replace](/up.replace) if the form submission is not successful (non-200 status code).
|
585
|
-
|
586
|
-
Inside the CSS selector you may refer to this form as `&` ([like in Sass](https://sass-lang.com/documentation/file.SASS_REFERENCE.html#parent-selector)).
|
587
|
-
|
588
|
-
If omitted, Unpoly will replace the `<form>` tag itself, assuming that the server has echoed the form with validation errors.
|
589
|
-
@param [up-fallback]
|
590
|
-
The selector to replace if the server responds with an error.
|
591
|
-
@param {string} [up-transition]
|
592
|
-
The animation to use when the form is replaced after a successful submission.
|
593
|
-
@param {string} [up-fail-transition]
|
594
|
-
The animation to use when the form is replaced after a failed submission.
|
595
|
-
@param [up-history]
|
596
|
-
Whether to push a browser history entry after a successful form submission.
|
597
|
-
|
598
|
-
By default the form's target URL is used. If the form redirects to another URL,
|
599
|
-
the redirect target will be used.
|
600
|
-
|
601
|
-
Set this to `'false'` to prevent the URL bar from being updated.
|
602
|
-
Set this to a URL string to update the history with the given URL.
|
603
|
-
@param {string} [up-method]
|
604
|
-
The HTTP method to be used to submit the form (`get`, `post`, `put`, `delete`, `patch`).
|
605
|
-
Alternately you can use an attribute `data-method`
|
606
|
-
([Rails UJS](https://github.com/rails/jquery-ujs/wiki/Unobtrusive-scripting-support-for-jQuery))
|
607
|
-
or `method` (vanilla HTML) for the same purpose.
|
608
|
-
@param {string} [up-layer='auto']
|
609
|
-
The name of the layer that ought to be updated. Valid values are
|
610
|
-
`'auto'`, `'page'`, `'modal'` and `'popup'`.
|
611
|
-
|
612
|
-
If set to `'auto'` (default), Unpoly will try to find a match in the form's layer.
|
613
|
-
If no match was found in that layer,
|
614
|
-
Unpoly will search in other layers, starting from the topmost layer.
|
615
|
-
@param {string} [up-fail-layer='auto']
|
616
|
-
The name of the layer that ought to be updated if the server sends a
|
617
|
-
non-200 status code.
|
618
|
-
@param {string} [up-reveal='true']
|
619
|
-
Whether to reveal the target element after it was replaced.
|
620
|
-
|
621
|
-
You can also pass a CSS selector for the element to reveal.
|
622
|
-
Inside the CSS selector you may refer to the form as `&` ([like in Sass](https://sass-lang.com/documentation/file.SASS_REFERENCE.html#parent-selector)).
|
623
|
-
@param {string} [up-fail-reveal='true']
|
624
|
-
Whether to reveal the target element when the server responds with an error.
|
625
|
-
|
626
|
-
You can also pass a CSS selector for the element to reveal. You may use this, for example,
|
627
|
-
to reveal the first validation error message:
|
628
|
-
|
629
|
-
<form up-target=".content" up-fail-reveal=".error">
|
630
|
-
...
|
631
|
-
</form>
|
632
|
-
|
633
|
-
Inside the CSS selector you may refer to the form as `&` ([like in Sass](https://sass-lang.com/documentation/file.SASS_REFERENCE.html#parent-selector)).
|
634
|
-
@param {string} [up-restore-scroll='false']
|
635
|
-
Whether to restore previously known scroll position of all viewports
|
636
|
-
within the target selector.
|
637
|
-
@param {string} [up-cache]
|
638
|
-
Whether to force the use of a cached response (`true`)
|
639
|
-
or never use the cache (`false`)
|
640
|
-
or make an educated guess (`undefined`).
|
641
|
-
|
642
|
-
By default only responses to `GET` requests are cached for a few minutes.
|
643
|
-
@stable
|
644
|
-
###
|
645
|
-
up.on 'submit', 'form[up-target]', (event, form) ->
|
646
|
-
up.event.consumeAction(event)
|
647
|
-
u.muteRejection submit(form)
|
648
|
-
|
649
|
-
###**
|
650
|
-
When a form field with this attribute is changed, the form is validated on the server
|
651
|
-
and is updated with validation messages.
|
652
|
-
|
653
|
-
To validate the form, Unpoly will submit the form with an additional `X-Up-Validate` HTTP header.
|
654
|
-
When seeing this header, the server is expected to validate (but not save)
|
655
|
-
the form submission and render a new copy of the form with validation errors.
|
656
|
-
|
657
|
-
The programmatic variant of this is the [`up.validate()`](/up.validate) function.
|
658
|
-
|
659
|
-
\#\#\# Example
|
660
|
-
|
661
|
-
Let's look at a standard registration form that asks for an e-mail and password:
|
662
|
-
|
663
|
-
<form action="/users">
|
664
|
-
|
665
|
-
<label>
|
666
|
-
E-mail: <input type="text" name="email" />
|
667
|
-
</label>
|
668
|
-
|
669
|
-
<label>
|
670
|
-
Password: <input type="password" name="password" />
|
671
|
-
</label>
|
672
|
-
|
673
|
-
<button type="submit">Register</button>
|
674
|
-
|
675
|
-
</form>
|
676
|
-
|
677
|
-
When the user changes the `email` field, we want to validate that
|
678
|
-
the e-mail address is valid and still available. Also we want to
|
679
|
-
change the `password` field for the minimum required password length.
|
680
|
-
We can do this by giving both fields an `up-validate` attribute:
|
681
|
-
|
682
|
-
<form action="/users">
|
683
|
-
|
684
|
-
<label>
|
685
|
-
E-mail: <input type="text" name="email" up-validate />
|
686
|
-
</label>
|
687
|
-
|
688
|
-
<label>
|
689
|
-
Password: <input type="password" name="password" up-validate />
|
690
|
-
</label>
|
691
|
-
|
692
|
-
<button type="submit">Register</button>
|
693
|
-
|
694
|
-
</form>
|
695
|
-
|
696
|
-
Whenever a field with `up-validate` changes, the form is POSTed to
|
697
|
-
`/users` with an additional `X-Up-Validate` HTTP header.
|
698
|
-
When seeing this header, the server is expected to validate (but not save)
|
699
|
-
the form submission and render a new copy of the form with validation errors.
|
700
|
-
|
701
|
-
In Ruby on Rails the processing action should behave like this:
|
702
|
-
|
703
|
-
class UsersController < ApplicationController
|
704
|
-
|
705
|
-
# This action handles POST /users
|
706
|
-
def create
|
707
|
-
user_params = params[:user].permit(:email, :password)
|
708
|
-
@user = User.new(user_params)
|
709
|
-
if request.headers['X-Up-Validate']
|
710
|
-
@user.valid? # run validations, but don't save to the database
|
711
|
-
render 'form' # render form with error messages
|
712
|
-
elsif @user.save?
|
713
|
-
sign_in @user
|
714
|
-
else
|
715
|
-
render 'form', status: :bad_request
|
716
|
-
end
|
717
|
-
end
|
718
|
-
|
719
|
-
end
|
720
|
-
|
721
|
-
Note that if you're using the `unpoly-rails` gem you can simply say `up.validate?`
|
722
|
-
instead of manually checking for `request.headers['X-Up-Validate']`.
|
723
|
-
|
724
|
-
The server now renders an updated copy of the form with eventual validation errors:
|
725
|
-
|
726
|
-
<form action="/users">
|
727
|
-
|
728
|
-
<label class="has-error">
|
729
|
-
E-mail: <input type="text" name="email" value="foo@bar.com" />
|
730
|
-
Has already been taken!
|
731
|
-
</label>
|
732
|
-
|
733
|
-
<button type="submit">Register</button>
|
734
|
-
|
735
|
-
</form>
|
736
|
-
|
737
|
-
The `<label>` around the e-mail field is now updated to have the `has-error`
|
738
|
-
class and display the validation message.
|
739
|
-
|
740
|
-
\#\#\# How validation results are displayed
|
741
|
-
|
742
|
-
Although the server will usually respond to a validation with a complete,
|
743
|
-
fresh copy of the form, Unpoly will by default not update the entire form.
|
744
|
-
This is done in order to preserve volatile state such as the scroll position
|
745
|
-
of `<textarea>` elements.
|
746
|
-
|
747
|
-
By default Unpoly looks for a `<fieldset>`, `<label>` or `<form>`
|
748
|
-
around the validating input field, or any element with an
|
749
|
-
`up-fieldset` attribute.
|
750
|
-
With the Bootstrap bindings, Unpoly will also look
|
751
|
-
for a container with the `form-group` class.
|
752
|
-
|
753
|
-
You can change this default behavior by setting [`up.form.config.validateTargets`](/up.form.config#config.validateTargets):
|
754
|
-
|
755
|
-
// Always update the entire form containing the current field ("&")
|
756
|
-
up.form.config.validateTargets = ['form &']
|
757
|
-
|
758
|
-
You can also individually override what to update by setting the `up-validate`
|
759
|
-
attribute to a CSS selector:
|
760
|
-
|
761
|
-
<input type="text" name="email" up-validate=".email-errors">
|
762
|
-
<span class="email-errors"></span>
|
763
|
-
|
764
|
-
\#\#\# Updating dependent fields
|
765
|
-
|
766
|
-
The `[up-validate]` behavior is also a great way to partially update a form
|
767
|
-
when one fields depends on the value of another field.
|
768
|
-
|
769
|
-
Let's say you have a form with one `<select>` to pick a department (sales, engineering, ...)
|
770
|
-
and another `<select>` to pick an employeee from the selected department:
|
771
|
-
|
772
|
-
<form action="/contracts">
|
773
|
-
<select name="department">...</select> <!-- options for all departments -->
|
774
|
-
<select name="employeed">...</select> <!-- options for employees of selected department -->
|
775
|
-
</form>
|
776
|
-
|
777
|
-
The list of employees needs to be updated as the appartment changes:
|
778
|
-
|
779
|
-
<form action="/contracts">
|
780
|
-
<select name="department" up-validate="[name=employee]">...</select>
|
781
|
-
<select name="employee">...</select>
|
782
|
-
</form>
|
783
|
-
|
784
|
-
In order to update the `department` field in addition to the `employee` field, you could say
|
785
|
-
`up-validate="&, [name=employee]"`, or simply `up-validate="form"` to update the entire form.
|
786
|
-
|
787
|
-
@selector input[up-validate]
|
788
|
-
@param {string} up-validate
|
789
|
-
The CSS selector to update with the server response.
|
790
|
-
|
791
|
-
This defaults to a fieldset or form group around the validating field.
|
792
|
-
@stable
|
793
|
-
###
|
794
|
-
|
795
|
-
###**
|
796
|
-
Performs [server-side validation](/input-up-validate) when any fieldset within this form changes.
|
797
|
-
|
798
|
-
You can configure what Unpoly considers a fieldset by adding CSS selectors to the
|
799
|
-
[`up.form.config.validateTargets`](/up.form.config#config.validateTargets) array.
|
800
|
-
|
801
|
-
@selector form[up-validate]
|
802
|
-
@stable
|
803
|
-
###
|
804
|
-
up.on 'change', '[up-validate]', (event) ->
|
805
|
-
field = findFields(event.target)[0]
|
806
|
-
u.muteRejection validate(field)
|
807
|
-
|
808
|
-
###**
|
809
|
-
Show or hide elements when a `<select>` or `<input>` has a given value.
|
810
|
-
|
811
|
-
\#\#\# Example: Select options
|
812
|
-
|
813
|
-
The controlling form field gets an `up-switch` attribute with a selector for the elements to show or hide:
|
814
|
-
|
815
|
-
<select name="advancedness" up-switch=".target">
|
816
|
-
<option value="basic">Basic parts</option>
|
817
|
-
<option value="advanced">Advanced parts</option>
|
818
|
-
<option value="very-advanced">Very advanced parts</option>
|
819
|
-
</select>
|
820
|
-
|
821
|
-
The target elements can use [`[up-show-for]`](/up-show-for) and [`[up-hide-for]`](/up-hide-for)
|
822
|
-
attributes to indicate for which values they should be shown or hidden:
|
823
|
-
|
824
|
-
<div class="target" up-show-for="basic">
|
825
|
-
only shown for advancedness = basic
|
826
|
-
</div>
|
827
|
-
|
828
|
-
<div class="target" up-hide-for="basic">
|
829
|
-
hidden for advancedness = basic
|
830
|
-
</div>
|
831
|
-
|
832
|
-
<div class="target" up-show-for="advanced very-advanced">
|
833
|
-
shown for advancedness = advanced or very-advanced
|
834
|
-
</div>
|
835
|
-
|
836
|
-
\#\#\# Example: Text field
|
837
|
-
|
838
|
-
The controlling `<input>` gets an `up-switch` attribute with a selector for the elements to show or hide:
|
839
|
-
|
840
|
-
<input type="text" name="user" up-switch=".target">
|
841
|
-
|
842
|
-
<div class="target" up-show-for="alice">
|
843
|
-
only shown for user alice
|
844
|
-
</div>
|
845
|
-
|
846
|
-
You can also use the pseudo-values `:blank` to match an empty input value,
|
847
|
-
or `:present` to match a non-empty input value:
|
848
|
-
|
849
|
-
<input type="text" name="user" up-switch=".target">
|
850
|
-
|
851
|
-
<div class="target" up-show-for=":blank">
|
852
|
-
please enter a username
|
853
|
-
</div>
|
854
|
-
|
855
|
-
\#\#\# Example: Checkbox
|
856
|
-
|
857
|
-
For checkboxes you can match against the pseudo-values `:checked` or `:unchecked`:
|
858
|
-
|
859
|
-
<input type="checkbox" name="flag" up-switch=".target">
|
860
|
-
|
861
|
-
<div class="target" up-show-for=":checked">
|
862
|
-
only shown when checkbox is checked
|
863
|
-
</div>
|
864
|
-
|
865
|
-
<div class="target" up-show-for=":cunhecked">
|
866
|
-
only shown when checkbox is unchecked
|
867
|
-
</div>
|
868
|
-
|
869
|
-
Of course you can also match against the `value` property of the checkbox element:
|
870
|
-
|
871
|
-
<input type="checkbox" name="flag" value="active" up-switch=".target">
|
872
|
-
|
873
|
-
<div class="target" up-show-for="active">
|
874
|
-
only shown when checkbox is checked
|
875
|
-
</div>
|
876
|
-
|
877
|
-
@selector input[up-switch]
|
878
|
-
@param {string} up-switch
|
879
|
-
A CSS selector for elements whose visibility depends on this field's value.
|
880
|
-
@stable
|
881
|
-
###
|
882
|
-
|
883
|
-
###**
|
884
|
-
Only shows this element if an input field with [`[up-switch]`](/input-up-switch) has one of the given values.
|
885
|
-
|
886
|
-
See [`input[up-switch]`](/input-up-switch) for more documentation and examples.
|
887
|
-
|
888
|
-
@selector [up-show-for]
|
889
|
-
@param {string} [up-show-for]
|
890
|
-
A space-separated list of input values for which this element should be shown.
|
891
|
-
@stable
|
892
|
-
###
|
893
|
-
|
894
|
-
###**
|
895
|
-
Hides this element if an input field with [`[up-switch]`](/input-up-switch) has one of the given values.
|
896
|
-
|
897
|
-
See [`input[up-switch]`](/input-up-switch) for more documentation and examples.
|
898
|
-
|
899
|
-
@selector [up-hide-for]
|
900
|
-
@param {string} [up-hide-for]
|
901
|
-
A space-separated list of input values for which this element should be hidden.
|
902
|
-
@stable
|
903
|
-
###
|
904
|
-
up.compiler '[up-switch]', (switcher) ->
|
905
|
-
switchTargets(switcher)
|
906
|
-
|
907
|
-
up.on 'change', '[up-switch]', (event, switcher) ->
|
908
|
-
switchTargets(switcher)
|
909
|
-
|
910
|
-
up.compiler '[up-show-for]:not(.up-switched), [up-hide-for]:not(.up-switched)', (element) ->
|
911
|
-
switchTarget(element)
|
912
|
-
|
913
|
-
###**
|
914
|
-
Observes this field and runs a callback when a value changes.
|
915
|
-
|
916
|
-
This is useful for observing text fields while the user is typing.
|
917
|
-
If you want to submit the form after a change see [`input[up-autosubmit]`](/input-up-autosubmit).
|
918
|
-
|
919
|
-
The programmatic variant of this is the [`up.observe()`](/up.observe) function.
|
920
|
-
|
921
|
-
\#\#\# Example
|
922
|
-
|
923
|
-
The following would run a global `showSuggestions(value)` function
|
924
|
-
whenever the `<input>` changes:
|
925
|
-
|
926
|
-
<input name="query" up-observe="showSuggestions(value)">
|
927
|
-
|
928
|
-
Note that the parameter name in the markup must be called `value` or it will not work.
|
929
|
-
The parameter name can be called whatever you want in the JavaScript, however.
|
930
|
-
|
931
|
-
Also note that the function must be declared on the `window` object to work, like so:
|
932
|
-
|
933
|
-
window.showSuggestions = function(selectedValue) {
|
934
|
-
console.log(`Called showSuggestions() with ${selectedValue}`);
|
935
|
-
}
|
936
|
-
|
937
|
-
\#\#\# Callback context
|
938
|
-
|
939
|
-
The script given to `[up-observe]` runs with the following context:
|
940
|
-
|
941
|
-
| Name | Type | Description |
|
942
|
-
| -------- | --------- | ------------------------------------- |
|
943
|
-
| `value` | `string` | The current value of the field |
|
944
|
-
| `this` | `Element` | The form field |
|
945
|
-
| `$field` | `jQuery` | The form field as a jQuery collection |
|
946
|
-
|
947
|
-
\#\#\# Observing radio buttons
|
948
|
-
|
949
|
-
Multiple radio buttons with the same `[name]` (a radio button group)
|
950
|
-
produce a single value for the form.
|
951
|
-
|
952
|
-
To observe radio buttons group, use the `[up-observe]` attribute on an
|
953
|
-
element that contains all radio button elements with a given name:
|
954
|
-
|
955
|
-
<div up-observe="formatSelected(value)">
|
956
|
-
<input type="radio" name="format" value="html"> HTML format
|
957
|
-
<input type="radio" name="format" value="pdf"> PDF format
|
958
|
-
<input type="radio" name="format" value="txt"> Text format
|
959
|
-
</div>
|
960
|
-
|
961
|
-
@selector input[up-observe]
|
962
|
-
@param {string} up-observe
|
963
|
-
The code to run when the field's value changes.
|
964
|
-
@param {string} up-delay
|
965
|
-
The number of miliseconds to wait after a change before the code is run.
|
966
|
-
@stable
|
967
|
-
###
|
968
|
-
|
969
|
-
###**
|
970
|
-
Observes this form and runs a callback when any field changes.
|
971
|
-
|
972
|
-
This is useful for observing text fields while the user is typing.
|
973
|
-
If you want to submit the form after a change see [`input[up-autosubmit]`](/input-up-autosubmit).
|
974
|
-
|
975
|
-
The programmatic variant of this is the [`up.observe()`](/up.observe) function.
|
976
|
-
|
977
|
-
\#\#\# Example
|
978
|
-
|
979
|
-
The would call a function `somethingChanged(value)`
|
980
|
-
when any `<input>` within the `<form>` changes:
|
981
|
-
|
982
|
-
<form up-observe="somethingChanged(value)">
|
983
|
-
<input name="foo">
|
984
|
-
<input name="bar">
|
985
|
-
</form>
|
986
|
-
|
987
|
-
\#\#\# Callback context
|
988
|
-
|
989
|
-
The script given to `up-observe` runs with the following context:
|
990
|
-
|
991
|
-
| Name | Type | Description |
|
992
|
-
| -------- | --------- | ------------------------------------- |
|
993
|
-
| `value` | `string` | The current value of the field |
|
994
|
-
| `this` | `Element` | The form field |
|
995
|
-
| `$field` | `jQuery` | The form field as a jQuery collection |
|
996
|
-
|
997
|
-
@selector form[up-observe]
|
998
|
-
@param {string} up-observe
|
999
|
-
The code to run when any field's value changes.
|
1000
|
-
@param {string} up-delay
|
1001
|
-
The number of miliseconds to wait after a change before the code is run.
|
1002
|
-
@stable
|
1003
|
-
###
|
1004
|
-
up.compiler '[up-observe]', (formOrField) -> observe(formOrField)
|
1005
|
-
|
1006
|
-
###**
|
1007
|
-
Submits this field's form when this field changes its values.
|
1008
|
-
|
1009
|
-
Both the form and the changed field will be assigned a CSS class [`up-active`](/form-up-active)
|
1010
|
-
while the autosubmitted form is loading.
|
1011
|
-
|
1012
|
-
The programmatic variant of this is the [`up.autosubmit()`](/up.autosubmit) function.
|
1013
|
-
|
1014
|
-
\#\#\# Example
|
1015
|
-
|
1016
|
-
The following would automatically submit the form when the query is changed:
|
1017
|
-
|
1018
|
-
<form method="GET" action="/search">
|
1019
|
-
<input type="search" name="query" up-autosubmit>
|
1020
|
-
<input type="checkbox" name="archive"> Include archive
|
1021
|
-
</form>
|
1022
|
-
|
1023
|
-
\#\#\# Auto-submitting radio buttons
|
1024
|
-
|
1025
|
-
Multiple radio buttons with the same `[name]` (a radio button group)
|
1026
|
-
produce a single value for the form.
|
1027
|
-
|
1028
|
-
To auto-submit radio buttons group, use the `[up-submit]` attribute on an
|
1029
|
-
element that contains all radio button elements with a given name:
|
1030
|
-
|
1031
|
-
<div up-autosubmit>
|
1032
|
-
<input type="radio" name="format" value="html"> HTML format
|
1033
|
-
<input type="radio" name="format" value="pdf"> PDF format
|
1034
|
-
<input type="radio" name="format" value="txt"> Text format
|
1035
|
-
</div>
|
1036
|
-
|
1037
|
-
@selector input[up-autosubmit]
|
1038
|
-
@param {string} up-delay
|
1039
|
-
The number of miliseconds to wait after a change before the form is submitted.
|
1040
|
-
@stable
|
1041
|
-
###
|
1042
|
-
|
1043
|
-
###**
|
1044
|
-
Submits the form when *any* field changes.
|
1045
|
-
|
1046
|
-
Both the form and the field will be assigned a CSS class [`up-active`](/form-up-active)
|
1047
|
-
while the autosubmitted form is loading.
|
1048
|
-
|
1049
|
-
The programmatic variant of this is the [`up.autosubmit()`](/up.autosubmit) function.
|
1050
|
-
|
1051
|
-
\#\#\# Example
|
1052
|
-
|
1053
|
-
This will submit the form when either query or checkbox was changed:
|
1054
|
-
|
1055
|
-
<form method="GET" action="/search" up-autosubmit>
|
1056
|
-
<input type="search" name="query">
|
1057
|
-
<input type="checkbox" name="archive"> Include archive
|
1058
|
-
</form>
|
1059
|
-
|
1060
|
-
@selector form[up-autosubmit]
|
1061
|
-
@param {string} up-delay
|
1062
|
-
The number of miliseconds to wait after a change before the form is submitted.
|
1063
|
-
@stable
|
1064
|
-
###
|
1065
|
-
up.compiler '[up-autosubmit]', (formOrField) -> autosubmit(formOrField)
|
1066
|
-
|
1067
|
-
up.compiler '[autofocus]', { batch: true }, (inputs) -> u.last(inputs).focus()
|
1068
|
-
|
1069
|
-
up.on 'up:framework:reset', reset
|
1070
|
-
|
1071
|
-
<% if ENV['JS_KNIFE'] %>knife: eval(Knife.point)<% end %>
|
1072
|
-
config: config
|
1073
|
-
submit: submit
|
1074
|
-
observe: observe
|
1075
|
-
validate: validate
|
1076
|
-
autosubmit: autosubmit
|
1077
|
-
fieldSelector: fieldSelector
|
1078
|
-
fields: findFields
|
1079
|
-
submissionFields: findSubmissionFields
|
1080
|
-
|
1081
|
-
up.submit = up.form.submit
|
1082
|
-
up.observe = up.form.observe
|
1083
|
-
up.autosubmit = up.form.autosubmit
|
1084
|
-
up.validate = up.form.validate
|