Lesson 1.4: Creating new elements #
The previous lessons used variations on print to push text to screen. We will want to do a bit more than that, and a common improvement is to start creating new HTML elements using PyScript code.
We might think to use the write function for this, as we have done in the previous lessons. Instead of pushing just text, we could instead push the HTML code for a new element
Give this a go, and inspect the created element in your browser.
<div id="new_element"></div>.
<py-script>
pyscript.write('new_element', "<h1>What does this do?</h1>")
</py-script>
Note: we only include the relevant parts of the code for this lesson in snippets from here on out.
Take the code above, and include in the body tag of your HTML file.
Don’t forget the script tag to include PyScript!
As you can see, the HTML is stripped from the write, resulting in just the text being displayed, but not as a heading.
Inspecting the resulting page, the HTML code generated looks like this:
<div id="new_element">What does this do?</div>
This is a security feature - having functions write raw HTML by default is an insecure option and can result in vulnerabilities.
Consider a user who inputs their name as Bob <script>alert("!")</script>, or even Little Bobbie Tables.
Instead, what we want to do is explicitly write the output as HTML, by creating an element (again, explicitly) and then writing that element. This has the added advantage of not having to manage your HTML with a bunch of strings. It is very easy to get “lost” in code that generates large amounts of HTML, and ensuring the resulting HTML is functionally valid.
Instead, try this code inside your <py-script> tags:
new_heading = document.createElement("h1")
new_heading.innerText = "What does this do?"
container = Element("new_element") # document.querySelector works as well
container.element.appendChild(new_heading);
This code works very similarly to the JavaScript version. In our PyScript tag, we start by creating a “h1” element, i.e. a heading.
new_heading = document.createElement("h1")
Next, we set the text of our new element:
new_heading.innerText = "What does this do?"
Next, we use the Element selector to get the “parent” element, that this “child” will be created within:
container = Element("new_element") # document.querySelector works as well
Finally, we append the child to the parent:
container.element.appendChild(new_heading);
It is important to note that the element in the above code is a wrapper around the JavaScript code for the same object.
This means you can use JavaScript like functions, in much the same way as they are used in JS.
For example, here is the JavaScript documentation for the appendChild function used above: https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild
Exercises #
Take your learning further with some exercises.
- Elements have functions
add_classandremove_class. Use these to add and remove CSS selector classes to the heading, turning it blue and then turning it red after five seconds. - Use the function
insertBeforeoncontainer.elementobject to insert a heading before the H1 tag. Hint: search for the function using the link provided above for theappendChildfunction. - Write a python function
create_headingthat takes text and a container (parent) element, and creates a new heading in that parent. - Update the function to have a parameter that, if true, inserts the heading as the first child of the container object.
- Create a function that takes a python object as input, calls
diron it, and creates a HTML list of all the functions and attributes on that object. Bonus points if you can annotate with whether it is a function or attribute!