@@ -73,204 +73,188 @@ equivalent values: `["hello", 1, 2, 3]`.
7373
7474Should you require lower level API access to FFI features, you can find such
7575builtin functions under the ` pyscript.ffi ` namespace in both Pyodide and
76- MicroPython. The available functions are described in our section on
77- [ builtin helpers ] ( ../builtins ) .
76+ MicroPython. The available functions are described in our section on the
77+ [ builtin API ] ( ../../api ) .
7878
7979Advanced users may wish to explore the
8080[ technical details of the FFI] ( ../ffi ) .
8181
82- ## PyDom
83-
84- The Standard Web APIs are massive and not always very user-friendly. ` PyDom ` is
85- a Python module that exposes the power of the web with an easy and idiomatic
86- Pythonic interface on top.
87-
88- While the [ FFI] ( #ffi ) interface described above focuses on giving full access
89- to the entire Standard Web APIs, ` pydom ` focuses on providing a small,
90- intuitive and yet powerful API that prioritises common use cases fist. For this
91- reason, its first layer is simple (but limited to the most common use cases),
92- but ` pydom ` also provides a secondary layer to directly use full FFI interface
93- of a specific element.
94-
95- PyDom does not aim to replace the regular web (Javascript) API nor to be as
96- wide and offer feature parity. On the contrary, it is intentionally small and
97- focused on the most popular use cases while still providing (backdoor) access
98- to the full JavaScript API.
99-
100- ` Pydom ` draws inspiration from popular Python APIs/Libraries known to be
101- friendly and easy to learn, and other successful projects related the web as
102- well (for instance, ` JQuery ` was a source of inspiration).
82+ ## ` pyscript.web `
10383
10484!!! warning
10585
106- PyDom is currently a work in progress.
86+ The `pyscript.web` module is currently a work in progress.
10787
10888 We welcome feedback and suggestions.
10989
90+ The ` pyscript.web ` module is an idiomatically Pythonic API for interacting with
91+ the DOM. It wraps the FFI in a way that is more familiar to Python developers
92+ and works natively with the Python language. Technical documentation for this
93+ module can be found in [ the API] ( ../../api/#pyscriptweb ) section.
11094
111- ### Core Concepts
95+ There are three core concepts to remember:
11296
113- ` Pydom ` builds on topic of very few and simple core concepts:
114-
115- * __ ` Element ` :__ any component that is part of a web page. This is a rough
116- abstraction of an
117- [ HTMLElement] ( https://developer.mozilla.org/en-US/docs/Glossary/Element ) .
118- In general, ` pydom ` elements always map to an underlying ` HTML ` ` Element ` in
119- a web page
120- * __ ` ElementCollection ` :__ a collection of one or more ` Elements ` . It is a
121- rough abstraction of an
122- [ HTMLCollection] ( https://developer.mozilla.org/en-US/docs/Web/API/HTMLCollection ) .
123- * __ Querying:__ a method to query elements on a page based on a
124- [ selector] ( https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_selectors ) .
125- Pydom supports standard HTML DOM query selectors to
126- [ locate DOM elements] ( https://developer.mozilla.org/en-US/docs/Web/API/Document_object_model/Locating_DOM_elements_using_selectors )
127- as other native ` JavaScript ` methods like ` querySelector ` or
97+ * Find elements on the page via
98+ [ CSS selectors] ( https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_selectors ) .
99+ The ` find ` API uses exactly the [ same queries] ( https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Locating_DOM_elements_using_selectors )
100+ as those used by native browser methods like ` qurerySelector ` or
128101 ` querySelectorAll ` .
102+ * Use classes in the ` pyscript.web.elements ` namespace to create and organise
103+ new elements on the web page.
104+ * Collections of elements allow you to access and change attributes en-mass.
105+ Such collections are returned from ` find ` queries and are also used for the
106+ [ children] ( https://developer.mozilla.org/en-US/docs/Web/API/Element/children )
107+ of an element.
108+
109+ You have several options for accessing the content of the page (i.e. the DOM),
110+ and these can be found in the ` pyscript.web.dom ` object. The ` head ` and ` body `
111+ attributes reference the page's head and body. Furthermore, the ` find ` method
112+ can be used to return collections of elements matching your CSS query. Finally,
113+ all elements have a ` find ` method that searches within their children for
114+ elements matching your CSS query.
129115
130- Let's look into each of these aspects in more in detail.
131-
132- ### Element
116+ ``` python
117+ from pyscript.web import dom
133118
134- A PyDom ` Element ` is simply an abstraction of a tranditional ` Element ` in a web
135- page. Every PyDom ` Element ` maps to an underlying JavaScript ` Element ` in a
136- web page. These two elements are always in sync and any change of state in one
137- is reflected in the other.
138119
139- #### Creating a new element
120+ # Print all the child elements of the document's head.
121+ print (dom.head.children)
122+ # Find all the paragraphs in the DOM.
123+ paragraphs = dom.find(" p" )
124+ ```
140125
141- New elements are created using the ` pydom.create ` method and passing the type
142- of element being created. Here's an example of what it looks like :
126+ The object returned from a query, or used as a reference to an element's
127+ children is iterable :
143128
144129``` python
145- from pyweb import pydom
130+ from pyscript.web import dom
146131
147- # Creating an element directly from pydom creates an unbounded element.
148- new_div = pydom.create(" div" )
149132
150- # Creating an element from another element automatically creates that element
151- # as a child of the original element
152- new_p = new_div.create(
153- " p" ,
154- classes = [" code-description" ],
155- html = " Ciao PyScripters!"
156- )
133+ # Get all the paragraphs in the DOM.
134+ paragraphs = dom.find(" p" )
157135
158- # elements can be appended to any other element on the page
159- pydom[' #element-creation-example' ][0 ].append(new_div)
136+ # Print the inner html of each paragraph.
137+ for p in paragraphs:
138+ print (p.html)
160139```
161140
162- #### Setting an element's content
163-
164- The ` Element ` interface offers two ways to set an element's content: the ` html `
165- and the ` content ` attributes:
166-
167- * ` html ` : directly sets the ` innerHTML ` field of the underlying element without
168- attemnpting any conversion.
169- * ` content ` : sets the ` innerHTML ` field via the PyScript ` display ` function.
170- This takes care of properly rendering the object being passed based on the
171- object mimetype. So, for instance, if the objects is an image, it'll be
172- properly rendered within the element
141+ Alternatively, it is also indexable / sliceable:
173142
174- In general, we suggest using ` content ` directly as it'll take care of most use
175- cases without requiring any extra work from the user.
143+ ``` python
144+ from pyscript.web import dom
176145
177- #### Changing an element's style
178146
179- Elements have a ` style ` attribute to change the element style rules. The
180- ` style ` attribute is a dictionary and, to set a style rule for the element,
181- simply set the correct key on the ` .style ` attribute. For instance, the
182- following code changes the background color (of the element created in the
183- example above):
147+ # Get an ElementCollection of all the paragraphs in the DOM
148+ paragraphs = dom.find(" p" )
184149
185- ``` python
186- new_p.style[" background-color" ] = " yellow"
150+ # Only the final two paragraphs.
151+ for p in paragraphs[- 2 :]:
152+ print (p.html)
187153```
188154
189- To remove a style key, simply use the ` pop ` method as you'd to to remove
190- a key from a dictionary :
155+ It also makes available the following read and writable attributes related to
156+ all contained elements :
191157
192- ``` python
193- new_p.style.pop(" background-color" )
194- ```
158+ * ` classes ` - the list of classes associated with the elements.
159+ * ` innerHTML ` - the innerHTML of each element.
160+ * ` style ` - a dictionary like object for interacting with CSS style rules.
161+ * ` value ` - the ` value ` attribute associated with each element.
162+
163+ For example, to continue the example above, ` paragraphs.innerHTML ` will return
164+ a list of all the values of the ` innerHTML ` attribute on each contained
165+ element. Alternatively, set an attribute for all elements contained in the
166+ collection like this: ` paragraphs.style["background-color"] = "blue" ` .
195167
196- In addition to the dictionary interface to explicitly set CSS rules, the
197- ` style ` attribute also offers a convenient ` visible ` property that can be use
198- show/hide an element.
168+ It's possible to create new elements to add to the DOM:
199169
200170``` python
201- new_p.style.visible = False
171+ from pyscript.web import dom
172+ from pyscript.web.elements import *
173+
174+
175+ dom.body.append(
176+ div(
177+ div(" Hello!" , classes = " a-css-class" , id = " hello" ),
178+ select(
179+ option(" apple" , value = 1 ),
180+ option(" pear" , value = 2 ),
181+ option(" orange" , value = 3 ),
182+ ),
183+ div(
184+ button(span(" Hello! " ), span(" World!" ), id = " my-button" ),
185+ br(),
186+ button(" Click me!" ),
187+ classes = [" css-class1" , " css-class2" ],
188+ style = {" background-color" : " red" }
189+ ),
190+ div(
191+ children = [
192+ button(
193+ children = [
194+ span(" Hello! " ),
195+ span(" Again!" )
196+ ],
197+ id = " another-button"
198+ ),
199+ br(),
200+ button(" b" ),
201+ ],
202+ classes = [" css-class1" , " css-class2" ]
203+ )
204+ )
205+ )
202206```
203207
204- #### Other useful aspects of the Element API
208+ This example demonstrates a declaritive way to add elements to the body of the
209+ DOM. Notice how the first (unnamed) arguments to an element are its children.
210+ The named arguments (such as ` id ` , ` classes ` and ` style ` ) refer to attributes
211+ of the underlying HTML element. If you'd rather be explicit about the children
212+ of an element, you can always pass in a list of such elements as the named
213+ ` children ` argument (you see this in the final ` div ` in the example above).
205214
206- * ` append ` : a method to append a new child to the element.
207- * ` children ` : list of the children of the element.
208- * ` value ` : allows to set the ` value ` attribute of an element.
209- * ` clone ` : a method that creates a clone of the element. NOTE: The cloned
210- elements will not be attached to any other element.
211- * ` show_me ` : a method to scroll the page to where the element is placed.
215+ Of course, you can achieve similar results in an imperative style of
216+ programming:
212217
213- ### Element collections
218+ ``` python
219+ from pyscript.web import dom
220+ from pyscript.web.elements import *
214221
215- Element collections represent a collection of elements typically returned from
216- a query. For instance:
217222
218- ``` python
219- paragraphs = pydom[' p' ]
220- ```
221223
222- In the example above, ` paragraphs ` is an ` ElementCollection ` that maps to all
223- ` p ` elements in the page.
224+ my_div = div()
225+ my_div.style[" background-color" ] = " red"
226+ my_div.classes.append(" a-css-class" )
224227
225- An ` ElementCollection ` can be used to iterate over a collection of elements or
226- to pick specific elements or slices of elements in the collection. For
227- instance:
228+ my_p = p()
229+ my_p.content = " This is a paragraph."
228230
229- ``` python
230- for element in paragraphs:
231- display(element.html)
231+ my_div.append(my_p)
232232
233- # let's now display only the last 2 elements
234- for element in paragraphs[- 2 :]:
235- display(element.html)
233+ # etc...
236234```
237235
238- #### Interacting with an ElementCollection
239-
240- Besides allowing operations as an iterable object, ` ElementCollection ` objects
241- also offer a few convenience methods to directly interact with the elements
242- within the collection. For instance, it's possible to ask for specific
243- attributes of the elements in the collection directly:
236+ It's also important to note that the ` pyscript.when ` decorator understands
237+ element references from ` pyscript.web ` :
244238
245239``` python
246- display(paragraphs.html)
247- ```
248-
249- This displays a list with the values of the ` html ` attribute for all the
250- elements in the ` paragraphs ` collection.
240+ from pyscript import when
241+ from pyscript.web import dom
251242
252- In the same way we can read attributes, we can also set an attribute directly
253- in the collection. For instance, you can directly set the html content of all
254- the elements in the collection:
255243
256- ``` python
257- # This will change the text of all H1 elements in the page
258- pydom[' h1' ].html = " That's cool :)"
259- ```
244+ btn = dom.find(" #my-button" )
260245
261- Or perhaps change their style:
262246
263- ```
264- paragraphs.style['background-color'] = 'lightyellow'
247+ @when (" click" , btn)
248+ def my_button_click_handler (event ):
249+ print (" The button has been clicked!" )
265250```
266251
267- The ` ElementCollection ` class currently supports the following attributes:
252+ Should you wish direct access to the proxy object representing the underlying
253+ HTML element, each Python element has a ` _dom_element ` property for this
254+ purpose.
268255
269- * ` style ` : just like in ` Element ` , this proxy attribute can be used to change
270- the style of the elements in a collection by setting the proper CSS rules,
271- using ` style ` with the same API as a dictionary.
272- * ` html ` : changes the ` html ` attribute on all the elements of a collection.
273- * ` value ` : changes the ` value ` attribute on all the elements of a collection.
256+ Once again, the technical details of these classes are described in the
257+ [ built-in API documentation] ( ../../api/#pyscriptweb ) .
274258
275259## Working with JavaScript
276260
0 commit comments