{"action":"created","comment":{"url":"https://api.github.com/repos/mojotech/dill/pulls/comments/34745638","id":34745638,"diff_hunk":"@@ -131,15 +141,364 @@ class Admin < Dill::Role\n end\n ```\n \n-##To Be Continued...\n+That's it for the walkthrough, but Dill has a lot more to offer. We recommend digging into Widgets next, as Widget is the fundamental class common to all the Dill elements.\n+\n+\n+#Widgets<a name=\"widgets\"></a>\n+A widget is the fundamental Dill element. A widget wraps a DOM element, allowing you to call methods on that element, like checking for text or clicking.\n+\n+\n+## Widget Declaration\n+A widget can be declared with the `widget` macro, or as a class. We prefer the macro declaration where possible.\n+\n+Maco widget declarations take a CSS selector as the first argument.\n+\n+```ruby\n+  widget :todo_item, '.todo-item'\n+```\n+\n+Class widget declarations define the widget with CSS selectors via the `root` macro.\n+\n+```ruby\n+class TodoItem < Dill::Widget\n+  root '.todo-item'\n+end\n+```\n+\n+## Nested Widgets\n+Widgets can be defined within widgets. CSS classes of child widgets are scoped within the class of the parent widget.\n+\n+Child widgets are available via the `widget` method.\n+\n+```ruby\n+class TodoManager < Dill::Role\n+  widget :todo_item, '.todo-item' do\n+    widget :delete_link, '.delete' # :delete_link looks for a .delete class within a .todo-item element\n+  end\n+\n+  # to access the delete_link widget:\n+  # widget(:todo_item).widget(:delete_link)\n+end\n+```\n+\n+\n+## Widget Methods\n+You can define custom methods on a widget object, or use the built-in methods.\n+\n+```ruby\n+class TodoManager < Dill::Role\n+  widget :todo_item, '.todo-item' do\n+    widget :delete_link, '.delete'\n+\n+    def delete\n+      click :delete_link\n+    end\n+  end\n+\n+  def delete_item\n+    widget(:todo_item).delete\n+  end\n+\n+  def can_delete?\n+    # check for widget presence with the widget? method\n+    widget(:todo_item).widget?(:delete_link)\n+  end\n+end\n+```\n+\n+\n+## Widgets As Procs\n+Widgets can take a Proc instead of just a class, allowing us to more precisely define the widget at call time.\n+\n+```ruby\n+class TodoManager < Dill::Role\n+  widget :todo_item, -> (text) { ['.todo-item', text: text] } do\n+    widget :delete_link, '.delete'\n+\n+    def delete\n+      click :delete_link\n+    end\n+  end\n+\n+  def delete_item(description)\n+    # find the widget that includes the\n+    # description text and click delete\n+\n+    widget(:todo_item, description).delete\n+  end\n+end\n+```\n+\n+\n+## Widgets Wait to Find an Element\n+Widgets block, meaning they pause code execution, and check the page for that element until they find it or they reach Capybara's timeout limit. This is handy for dynamic UI tests.\n+\n+```ruby\n+  roles.myrole.create_todo_item(\"Buy Milk\")\n+  # the item form is submitted to server and on response\n+  # from the server, a new item is appended to the list.\n+  # 'widget' waits until the item appears on the list,\n+  # or Capybara's timeout limit is reached\n+\n+  expect(roles.myrole).to see :todo_item, \"Buy Milk\"\n+```\n+\n+\n+## Widget Root\n+The **root** of a widget is the element itself, a bit like `this` is in Javascript. When a widget is declared with the widget macro, the root declaration is implicit and equal to the element with the css class in the definition.\n+\n+```ruby\n+class TodoManager < Dill::Role\n+  widget :todo_item, '.todo-item' do\n+    def delete\n+      root.find('a.delete').click\n+    end\n+  end\n+end\n+```\n+\n+\n+## HTML Attributes\n+We can access the id and classes of the widget as well.\n+\n+```ruby\n+  # <div id=\"todo_form\" class=\"todo-item right-aligned\">\n+  widget(:todo_item).id #=> \"todo_form\"\n+  widget(:todo_item).classes #=> [\"todo-item\", \"right-aligned\"]\n+```\n+\n+\n+#Forms<a name=\"forms\"></a>\n+Forms inherit all the properties of widgets, and have some of their own.\n+\n+\n+## Form Declaration\n+```ruby\n+  # with explicit class\n+  widget :todo_form, '.todo-form', Dill::Form do\n+  end\n+\n+  # with the form macro\n+  form :todo_form, '.todo-form' do\n+  end\n+```\n+\n+\n+## Form Fields\n+Forms can have form-field widgets defined, as well as any regular sub-widgets. Form field widgets by default try to match their second argument with the text of a label, an input name or an input id.\n+\n+```ruby\n+  form :form_with_everything, '.form-with-everything' do\n+    # text field\n+    text_field :request, 'request'\n+\n+    # select field\n+    select :state, 'state'\n+\n+    # checkbox field\n+    check_box :receive_email, 'receive_email'\n+\n+    # regular sub-widget\n+    widget :hidden_field, '.hidden-field'\n+\n+    # currently no built-in form support for radio buttons.\n+  end\n+```\n+\n+\n+#### Defining Fields with CSS Selectors\n+If you'd rather use a CSS selector, you can do that by passing the second argument as an array, with the selector as the array's first element.\n+\n+```ruby\n+  text_field :request, ['.request-field-class'],\n+```\n+\n+\n+#### Getting Field Values\n+You can get the current value of any of these elements at any time by referencing them on the form object.\n+\n+```\n+  widget(:form_with_everything).state #=> 'CO'\n+```\n+\n+\n+## Submitting a Form\n+Dill will easily submit a form for you, via the UI, with either of these methods.\n+\n+```ruby\n+  params = { request: 'Call me', state: 'CO', receive_email: true }\n+\n+  # the submit macro\n+  submit :form_with_everything, params\n+\n+  # the submit widget method\n+  widget(:form_with_everything).submit_with(params)\n+```\n+\n+You can also submit a form by setting the fields individually.\n+```ruby\n+  widget(:form_with_everything).tap do |f|\n+    f.request = 'Call me'\n+    f.state = 'CO'\n+    f.receive_email = true\n+    f.submit\n+  end\n+```\n+\n+\n+#Field Groups<a name=\"field_groups\"></a>\n+A field group is like a form without a submit button, and is more semantically appropriate for forms that are not submitted traditionally. It has all the same functionality as a Form object, minus the submitting function.\n+\n+\n+## Field Group Declaration\n+```ruby\n+  widget :todo_form, '.todo-form', Dill::FieldGroup do\n+  end\n+```\n+\n+\n+# Lists<a name=\"lists\"></a>\n+A list is a collection of Dill ListItem objects, and is a good way to map a simple list format with a Dill element. (For more complicated lists, consider the [table](#tables) element.)\n+\n+\n+## List Declaration\n+```ruby\n+  # with explicit class\n+  class TodoList < Dill::List\n+    root '.todo-list'\n+  end\n+\n+  # with widget macro and explicit class\n+  widget :todo_list, '.todo-list', Dill::List do\n+  end\n+\n+  # with the list macro\n+  list :todo_list, '.todo-list' do\n+  end","path":"README.md","position":271,"original_position":271,"commit_id":"04aa500a1dc9b97d87bbafa61e80b8284c8e7e94","original_commit_id":"bea9ec0c405bf46b0ee89c7efb04a4c9ae77058e","user":{"login":"adsteel","id":4186462,"avatar_url":"https://avatars.githubusercontent.com/u/4186462?v=3","gravatar_id":"","url":"https://api.github.com/users/adsteel","html_url":"https://github.com/adsteel","followers_url":"https://api.github.com/users/adsteel/followers","following_url":"https://api.github.com/users/adsteel/following{/other_user}","gists_url":"https://api.github.com/users/adsteel/gists{/gist_id}","starred_url":"https://api.github.com/users/adsteel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/adsteel/subscriptions","organizations_url":"https://api.github.com/users/adsteel/orgs","repos_url":"https://api.github.com/users/adsteel/repos","events_url":"https://api.github.com/users/adsteel/events{/privacy}","received_events_url":"https://api.github.com/users/adsteel/received_events","type":"User","site_admin":false},"body":"I know, but I want folks to remember that/how it takes a block. Savvy programmers will know that the block can be dumped, but un-savvy programmers might forget how to add it.","created_at":"2015-07-16T00:32:53Z","updated_at":"2015-07-16T00:32:53Z","html_url":"https://github.com/mojotech/dill/pull/101#discussion_r34745638","pull_request_url":"https://api.github.com/repos/mojotech/dill/pulls/101","_links":{"self":{"href":"https://api.github.com/repos/mojotech/dill/pulls/comments/34745638"},"html":{"href":"https://github.com/mojotech/dill/pull/101#discussion_r34745638"},"pull_request":{"href":"https://api.github.com/repos/mojotech/dill/pulls/101"}}},"pull_request":{"url":"https://api.github.com/repos/mojotech/dill/pulls/101","id":39728480,"html_url":"https://github.com/mojotech/dill/pull/101","diff_url":"https://github.com/mojotech/dill/pull/101.diff","patch_url":"https://github.com/mojotech/dill/pull/101.patch","issue_url":"https://api.github.com/repos/mojotech/dill/issues/101","number":101,"state":"open","locked":false,"title":"Update Docs with Major Widget Descriptions","user":{"login":"adsteel","id":4186462,"avatar_url":"https://avatars.githubusercontent.com/u/4186462?v=3","gravatar_id":"","url":"https://api.github.com/users/adsteel","html_url":"https://github.com/adsteel","followers_url":"https://api.github.com/users/adsteel/followers","following_url":"https://api.github.com/users/adsteel/following{/other_user}","gists_url":"https://api.github.com/users/adsteel/gists{/gist_id}","starred_url":"https://api.github.com/users/adsteel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/adsteel/subscriptions","organizations_url":"https://api.github.com/users/adsteel/orgs","repos_url":"https://api.github.com/users/adsteel/repos","events_url":"https://api.github.com/users/adsteel/events{/privacy}","received_events_url":"https://api.github.com/users/adsteel/received_events","type":"User","site_admin":false},"body":"","created_at":"2015-07-10T21:59:05Z","updated_at":"2015-07-16T00:32:53Z","closed_at":null,"merged_at":null,"merge_commit_sha":"56455f51c3bb036a192de9243c99e9e6c105a14e","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/mojotech/dill/pulls/101/commits","review_comments_url":"https://api.github.com/repos/mojotech/dill/pulls/101/comments","review_comment_url":"https://api.github.com/repos/mojotech/dill/pulls/comments{/number}","comments_url":"https://api.github.com/repos/mojotech/dill/issues/101/comments","statuses_url":"https://api.github.com/repos/mojotech/dill/statuses/04aa500a1dc9b97d87bbafa61e80b8284c8e7e94","head":{"label":"adsteel:ags/update-docs","ref":"ags/update-docs","sha":"04aa500a1dc9b97d87bbafa61e80b8284c8e7e94","user":{"login":"adsteel","id":4186462,"avatar_url":"https://avatars.githubusercontent.com/u/4186462?v=3","gravatar_id":"","url":"https://api.github.com/users/adsteel","html_url":"https://github.com/adsteel","followers_url":"https://api.github.com/users/adsteel/followers","following_url":"https://api.github.com/users/adsteel/following{/other_user}","gists_url":"https://api.github.com/users/adsteel/gists{/gist_id}","starred_url":"https://api.github.com/users/adsteel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/adsteel/subscriptions","organizations_url":"https://api.github.com/users/adsteel/orgs","repos_url":"https://api.github.com/users/adsteel/repos","events_url":"https://api.github.com/users/adsteel/events{/privacy}","received_events_url":"https://api.github.com/users/adsteel/received_events","type":"User","site_admin":false},"repo":{"id":36958392,"name":"dill","full_name":"adsteel/dill","owner":{"login":"adsteel","id":4186462,"avatar_url":"https://avatars.githubusercontent.com/u/4186462?v=3","gravatar_id":"","url":"https://api.github.com/users/adsteel","html_url":"https://github.com/adsteel","followers_url":"https://api.github.com/users/adsteel/followers","following_url":"https://api.github.com/users/adsteel/following{/other_user}","gists_url":"https://api.github.com/users/adsteel/gists{/gist_id}","starred_url":"https://api.github.com/users/adsteel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/adsteel/subscriptions","organizations_url":"https://api.github.com/users/adsteel/orgs","repos_url":"https://api.github.com/users/adsteel/repos","events_url":"https://api.github.com/users/adsteel/events{/privacy}","received_events_url":"https://api.github.com/users/adsteel/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/adsteel/dill","description":"Chop up all the cucumbers into a fresh delicious salad.","fork":true,"url":"https://api.github.com/repos/adsteel/dill","forks_url":"https://api.github.com/repos/adsteel/dill/forks","keys_url":"https://api.github.com/repos/adsteel/dill/keys{/key_id}","collaborators_url":"https://api.github.com/repos/adsteel/dill/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/adsteel/dill/teams","hooks_url":"https://api.github.com/repos/adsteel/dill/hooks","issue_events_url":"https://api.github.com/repos/adsteel/dill/issues/events{/number}","events_url":"https://api.github.com/repos/adsteel/dill/events","assignees_url":"https://api.github.com/repos/adsteel/dill/assignees{/user}","branches_url":"https://api.github.com/repos/adsteel/dill/branches{/branch}","tags_url":"https://api.github.com/repos/adsteel/dill/tags","blobs_url":"https://api.github.com/repos/adsteel/dill/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/adsteel/dill/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/adsteel/dill/git/refs{/sha}","trees_url":"https://api.github.com/repos/adsteel/dill/git/trees{/sha}","statuses_url":"https://api.github.com/repos/adsteel/dill/statuses/{sha}","languages_url":"https://api.github.com/repos/adsteel/dill/languages","stargazers_url":"https://api.github.com/repos/adsteel/dill/stargazers","contributors_url":"https://api.github.com/repos/adsteel/dill/contributors","subscribers_url":"https://api.github.com/repos/adsteel/dill/subscribers","subscription_url":"https://api.github.com/repos/adsteel/dill/subscription","commits_url":"https://api.github.com/repos/adsteel/dill/commits{/sha}","git_commits_url":"https://api.github.com/repos/adsteel/dill/git/commits{/sha}","comments_url":"https://api.github.com/repos/adsteel/dill/comments{/number}","issue_comment_url":"https://api.github.com/repos/adsteel/dill/issues/comments{/number}","contents_url":"https://api.github.com/repos/adsteel/dill/contents/{+path}","compare_url":"https://api.github.com/repos/adsteel/dill/compare/{base}...{head}","merges_url":"https://api.github.com/repos/adsteel/dill/merges","archive_url":"https://api.github.com/repos/adsteel/dill/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/adsteel/dill/downloads","issues_url":"https://api.github.com/repos/adsteel/dill/issues{/number}","pulls_url":"https://api.github.com/repos/adsteel/dill/pulls{/number}","milestones_url":"https://api.github.com/repos/adsteel/dill/milestones{/number}","notifications_url":"https://api.github.com/repos/adsteel/dill/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/adsteel/dill/labels{/name}","releases_url":"https://api.github.com/repos/adsteel/dill/releases{/id}","created_at":"2015-06-05T22:24:31Z","updated_at":"2015-06-05T22:24:31Z","pushed_at":"2015-07-16T00:16:52Z","git_url":"git://github.com/adsteel/dill.git","ssh_url":"git@github.com:adsteel/dill.git","clone_url":"https://github.com/adsteel/dill.git","svn_url":"https://github.com/adsteel/dill","homepage":null,"size":671,"stargazers_count":0,"watchers_count":0,"language":"Ruby","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"mojotech:master","ref":"master","sha":"4f8160efc51222e4c7b918e57eff428b553de53e","user":{"login":"mojotech","id":314035,"avatar_url":"https://avatars.githubusercontent.com/u/314035?v=3","gravatar_id":"","url":"https://api.github.com/users/mojotech","html_url":"https://github.com/mojotech","followers_url":"https://api.github.com/users/mojotech/followers","following_url":"https://api.github.com/users/mojotech/following{/other_user}","gists_url":"https://api.github.com/users/mojotech/gists{/gist_id}","starred_url":"https://api.github.com/users/mojotech/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mojotech/subscriptions","organizations_url":"https://api.github.com/users/mojotech/orgs","repos_url":"https://api.github.com/users/mojotech/repos","events_url":"https://api.github.com/users/mojotech/events{/privacy}","received_events_url":"https://api.github.com/users/mojotech/received_events","type":"Organization","site_admin":false},"repo":{"id":9579367,"name":"dill","full_name":"mojotech/dill","owner":{"login":"mojotech","id":314035,"avatar_url":"https://avatars.githubusercontent.com/u/314035?v=3","gravatar_id":"","url":"https://api.github.com/users/mojotech","html_url":"https://github.com/mojotech","followers_url":"https://api.github.com/users/mojotech/followers","following_url":"https://api.github.com/users/mojotech/following{/other_user}","gists_url":"https://api.github.com/users/mojotech/gists{/gist_id}","starred_url":"https://api.github.com/users/mojotech/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mojotech/subscriptions","organizations_url":"https://api.github.com/users/mojotech/orgs","repos_url":"https://api.github.com/users/mojotech/repos","events_url":"https://api.github.com/users/mojotech/events{/privacy}","received_events_url":"https://api.github.com/users/mojotech/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/mojotech/dill","description":"Chop up all the cucumbers into a fresh delicious salad.","fork":false,"url":"https://api.github.com/repos/mojotech/dill","forks_url":"https://api.github.com/repos/mojotech/dill/forks","keys_url":"https://api.github.com/repos/mojotech/dill/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mojotech/dill/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mojotech/dill/teams","hooks_url":"https://api.github.com/repos/mojotech/dill/hooks","issue_events_url":"https://api.github.com/repos/mojotech/dill/issues/events{/number}","events_url":"https://api.github.com/repos/mojotech/dill/events","assignees_url":"https://api.github.com/repos/mojotech/dill/assignees{/user}","branches_url":"https://api.github.com/repos/mojotech/dill/branches{/branch}","tags_url":"https://api.github.com/repos/mojotech/dill/tags","blobs_url":"https://api.github.com/repos/mojotech/dill/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mojotech/dill/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mojotech/dill/git/refs{/sha}","trees_url":"https://api.github.com/repos/mojotech/dill/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mojotech/dill/statuses/{sha}","languages_url":"https://api.github.com/repos/mojotech/dill/languages","stargazers_url":"https://api.github.com/repos/mojotech/dill/stargazers","contributors_url":"https://api.github.com/repos/mojotech/dill/contributors","subscribers_url":"https://api.github.com/repos/mojotech/dill/subscribers","subscription_url":"https://api.github.com/repos/mojotech/dill/subscription","commits_url":"https://api.github.com/repos/mojotech/dill/commits{/sha}","git_commits_url":"https://api.github.com/repos/mojotech/dill/git/commits{/sha}","comments_url":"https://api.github.com/repos/mojotech/dill/comments{/number}","issue_comment_url":"https://api.github.com/repos/mojotech/dill/issues/comments{/number}","contents_url":"https://api.github.com/repos/mojotech/dill/contents/{+path}","compare_url":"https://api.github.com/repos/mojotech/dill/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mojotech/dill/merges","archive_url":"https://api.github.com/repos/mojotech/dill/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mojotech/dill/downloads","issues_url":"https://api.github.com/repos/mojotech/dill/issues{/number}","pulls_url":"https://api.github.com/repos/mojotech/dill/pulls{/number}","milestones_url":"https://api.github.com/repos/mojotech/dill/milestones{/number}","notifications_url":"https://api.github.com/repos/mojotech/dill/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mojotech/dill/labels{/name}","releases_url":"https://api.github.com/repos/mojotech/dill/releases{/id}","created_at":"2013-04-21T12:54:56Z","updated_at":"2015-03-24T17:44:46Z","pushed_at":"2015-07-16T00:16:52Z","git_url":"git://github.com/mojotech/dill.git","ssh_url":"git@github.com:mojotech/dill.git","clone_url":"https://github.com/mojotech/dill.git","svn_url":"https://github.com/mojotech/dill","homepage":null,"size":1981,"stargazers_count":8,"watchers_count":8,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":2,"mirror_url":null,"open_issues_count":30,"forks":2,"open_issues":30,"watchers":8,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/mojotech/dill/pulls/101"},"html":{"href":"https://github.com/mojotech/dill/pull/101"},"issue":{"href":"https://api.github.com/repos/mojotech/dill/issues/101"},"comments":{"href":"https://api.github.com/repos/mojotech/dill/issues/101/comments"},"review_comments":{"href":"https://api.github.com/repos/mojotech/dill/pulls/101/comments"},"review_comment":{"href":"https://api.github.com/repos/mojotech/dill/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/mojotech/dill/pulls/101/commits"},"statuses":{"href":"https://api.github.com/repos/mojotech/dill/statuses/04aa500a1dc9b97d87bbafa61e80b8284c8e7e94"}}}}