-
Notifications
You must be signed in to change notification settings - Fork 329
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding items to the page with ServerLoad
#123
Comments
I'm not clear what you're asking for? |
ServerLoad
ServerLoad
Perhaps I was off-topic a bit at the beginning. Also, I hope I could explain the problem clearly this time. Sorry about my poor English. 🙏 Forget everything I said before this line: "It visually works but there is something wrong with the HTML Source Code". I have sketched an example here: from __future__ import annotations as _annotations
import random
import time
from fastapi import FastAPI
from fastapi.responses import HTMLResponse
from fastui import AnyComponent, FastUI, prebuilt_html
from fastui import components as c
from fastui.events import GoToEvent, PageEvent
def Master(*components: AnyComponent, title: str | None = None) -> list[AnyComponent]:
return [
c.PageTitle(text="Lotto Numbers Generator"),
c.Navbar(
title="Still Lotto Numbers Generator",
title_event=GoToEvent(url="/"),
),
c.Page(
components=[
*((c.Heading(text=title),) if title else ()),
*components,
],
),
]
app = FastAPI()
@app.get("/api/", response_model=FastUI, response_model_exclude_none=True)
def components_view() -> list[AnyComponent]:
return Master(
c.Div(
components=[
c.Heading(text="Lotto Numbers Generator", level=2),
c.Paragraph(text="Generate lotto numbers for your next game."),
c.Button(text="Generate a lotto number!", on_click=PageEvent(name="add-number")),
# When the button is clicked, the client will send a request to `/api/add-number`
# As expected, The response will be rendered in the `ServerLoad` component below.
c.Div(
components=[
c.ServerLoad(
path="/add-number",
load_trigger=PageEvent(name="add-number"),
components=[c.Paragraph(text="What are you waiting for?")],
),
],
class_name="py-2",
),
],
class_name="border-top mt-3 pt-1",
),
title="Quite simple and Understandable Example",
)
@app.get("/api/add-number", response_model=FastUI, response_model_exclude_none=True)
async def modal_view() -> list[AnyComponent]:
time.sleep(0.5)
return [
c.Paragraph(
text=f"Your lotto number is {random.randint(1, 99)}!",
),
# We are sending with another `ServerLoad` component.
# This will help us to keep the previous button working.
c.ServerLoad(
path="/add-number",
load_trigger=PageEvent(name="add-number"),
components=[c.Paragraph(text="Ready for another one?")],
),
]
@app.get("/{path:path}")
async def html_landing() -> HTMLResponse:
"""Simple HTML page which serves the React app, comes last as it matches all paths."""
return HTMLResponse(prebuilt_html(title="FastUI Demo")) When we run this code, it'll generate the following HTML: <div class="py-2">
<p class="">What are you waiting for?</p>
</div> When we click the button, re-rendering will happen and the following HTML will be generated: <div class="py-2">
<div>
<div class="transition-overlay"></div>
<p class="">Your lotto number is 36!</p>
<p class="">Ready for another one?</p>
</div>
</div>
When we click the button again, re-rendering will happen and the following HTML will be generated: <div class="py-2">
<div>
<div class="transition-overlay"></div>
<p class="">Your lotto number is 36!</p>
<div>
<div class="transition-overlay"></div>
<p class="">Your lotto number is 13!</p>
<p class="">Ready for another one?</p>
</div>
</div>
</div>
When we click the button again and again, let's do 10, re-rendering will happen and the following HTML will be generated: <div class="py-2">
<div>
<div class="transition-overlay"></div>
<p class="">Your lotto number is 36!</p>
<div>
<div class="transition-overlay"></div>
<p class="">Your lotto number is 13!</p>
<div>
<div class="transition-overlay"></div>
<p class="">Your lotto number is 82!</p>
<div>
<div class="transition-overlay"></div>
<p class="">Your lotto number is 87!</p>
<div>
<div class="transition-overlay"></div>
<p class="">Your lotto number is 94!</p>
<div>
<div class="transition-overlay"></div>
<p class="">Your lotto number is 51!</p>
<div>
<div class="transition-overlay"></div>
<p class="">Your lotto number is 48!</p>
<div>
<div class="transition-overlay"></div>
<p class="">Your lotto number is 65!</p>
<div>
<div class="transition-overlay"></div>
<p class="">Your lotto number is 2!</p>
<div>
<div class="transition-overlay"></div>
<p class="">Your lotto number is 90!</p>
<div>
<div class="transition-overlay"></div>
<p class="">Your lotto number is 52!</p>
<div>
<div class="transition-overlay"></div>
<p class="">Your lotto number is 10!</p>
<p class="">Ready for another one?</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
The problem I see is nesting the components over and over. I might be implementing it wrong, but I don't know how to achieve the expected behavior. The expected behavior is something like this: <div class="border-top mt-3 pt-1">
<h2 id="lotto-numbers-generator" class="">Lotto Numbers Generator</h2>
<p class="">Generate lotto numbers for your next game.</p>
<button class="btn btn-primary">Generate a lotto number!</button>
<div class="py-2">
<div>
<div class="transition-overlay"></div>
<p class="">Your lotto number is 36!</p>
<div class="transition-overlay"></div>
<p class="">Your lotto number is 13!</p>
<div class="transition-overlay"></div>
<p class="">Your lotto number is 82!</p>
<div class="transition-overlay"></div>
<p class="">Your lotto number is 87!</p>
<div class="transition-overlay"></div>
<p class="">Your lotto number is 94!</p>
<div class="transition-overlay"></div>
<p class="">Your lotto number is 51!</p>
<div class="transition-overlay"></div>
<p class="">Your lotto number is 48!</p>
<div class="transition-overlay"></div>
<p class="">Your lotto number is 65!</p>
<div class="transition-overlay"></div>
<p class="">Your lotto number is 2!</p>
<div class="transition-overlay"></div>
<p class="">Your lotto number is 90!</p>
<div class="transition-overlay"></div>
<p class="">Your lotto number is 52!</p>
<div class="transition-overlay"></div>
<p class="">Your lotto number is 10!</p>
<p class="">Ready for another one?</p>
</div>
</div>
</div>
Instead of nesting the elements, I want to add them to the same level. Can you please help me to achieve this behavior? I hope I could explain the problem clearly. Thank you for your time. 🙏 |
I think this might be fixed on #61. |
I can see that it's not merged yet. I checked the code in it and, I couldn't find any And what's up with the behavior above? Is it supposed to work that way? |
I just found something. Can you run this example above, please? If you navigate to the from __future__ import annotations as _annotations
import random
import time
from fastapi import FastAPI
from fastapi.responses import HTMLResponse
from fastui import AnyComponent, FastUI, prebuilt_html
from fastui import components as c
from fastui.events import GoToEvent, PageEvent
def Master(*components: AnyComponent, title: str | None = None) -> list[AnyComponent]:
return [
c.PageTitle(text="Lotto Numbers Generator"),
c.Navbar(
title="Still Lotto Numbers Generator",
title_event=GoToEvent(url="/"),
),
c.Page(
components=[
*((c.Heading(text=title),) if title else ()),
*components,
],
),
]
app = FastAPI()
@app.get("/api/", response_model=FastUI, response_model_exclude_none=True)
def components_view() -> list[AnyComponent]:
return Master(
c.Div(
components=[
c.Heading(text="Lotto Numbers Generator", level=2),
c.Paragraph(text="Generate lotto numbers for your next game."),
c.Button(text="Generate a lotto number!", on_click=PageEvent(name="add-number")),
# When the button is clicked, the client will send a request to `/api/add-number`
# The response will be rendered in the `ServerLoad` component below, as expected.
c.Div(
components=[
c.ServerLoad(
path="/add-number",
load_trigger=PageEvent(name="add-number"),
),
],
class_name="py-2",
),
],
class_name="border-top mt-3 pt-1",
),
title="Quite simple and Understandable Example",
)
@app.get("/api/add-number", response_model=FastUI, response_model_exclude_none=True)
async def modal_view() -> list[AnyComponent]:
time.sleep(0.5)
return [
c.Paragraph(
text=f"Your lotto number is {random.randint(1, 99)}!",
),
# We are sending with another `ServerLoad` component.
# This will help us to keep the previous button working.
c.ServerLoad(
path="/add-number",
load_trigger=PageEvent(name="add-number"),
),
]
@app.get("/{path:path}")
async def html_landing() -> HTMLResponse:
"""Simple HTML page which serves the React app, comes last as it matches all paths."""
return HTMLResponse(prebuilt_html(title="FastUI Demo")) |
ServerLoad
ServerLoad
0.4.0 fixed this one successfully. |
I cloned the repo and ran the demo and tried to modifie it so that I can
ServerLoad
items one by one, not just swap theServerLoad
I modified this block:
FastUI/demo/components_list.py
Lines 123 to 140 in 106d6c5
... like this:
And I modified this block:
FastUI/demo/components_list.py
Lines 220 to 223 in 106d6c5
... like this:
It visually works but there is something wrong with the HTML Source Code
It's probably not a "bug" or something like that, it probably works as it should be and I probably using it wrong, just asking how to do it? Do what? This...
What I'm implementing? Let's say a simple TODO app, creating tasks but I don't want to get the entire
demo_page
and re-render everything, just append the new item...The text was updated successfully, but these errors were encountered: