Skip to content
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

Tag field is pre-populated with an unrelated value #622

Closed
2 tasks done
Toshakins opened this issue Sep 20, 2023 · 4 comments · Fixed by #626
Closed
2 tasks done

Tag field is pre-populated with an unrelated value #622

Toshakins opened this issue Sep 20, 2023 · 4 comments · Fixed by #626

Comments

@Toshakins
Copy link
Contributor

Checklist

  • The bug is reproducible against the latest release or master.
  • There are no similar issues or pull requests to fix it yet.

Describe the bug

The select tag field gets prepopulated with the unrelated value. The issue happens both on creation and edit actions. The list of available options is updated with form_args ModelView field.

Steps to reproduce the bug

  1. Start app.
  2. Open the admin panel(http://localhost:8000/admin/).
  3. Open role list.
  4. Click the "New Role" button.

Expected behavior

A form with an empty input is shown up.

Actual behavior

Input is populated with "firmware_schedule:edit" value. The browser debug console has an error trace:

Uncaught TypeError: o is null
    <anonymous> bootstrap.min.js:381
    jQuery 8
    <anonymous> bootstrap.min.js:368
    <anonymous> bootstrap.min.js:11
    <anonymous> bootstrap.min.js:17
image

Debugging material

Please replace postgres engine link while reproducing the error with the provided code sample.

App sample
from enum import Enum
from typing import List

import sqlalchemy as sa
import uvicorn
from fastapi import FastAPI
from sqladmin import Admin, ModelView
from sqlalchemy import create_engine
from sqlalchemy.dialects import postgresql
from sqlalchemy.orm import DeclarativeBase, mapped_column, Mapped


class Base(DeclarativeBase):
    pass


engine = create_engine('postgresql://postgres:example@localhost:5432/iqtools')


class PermissionEnum(Enum):
    firmware_edit = 'firmware_schedule:edit'
    video_edit = 'video:edit'
    lab_edit = 'lab:edit'
    roboarm_edit = 'roboarm:edit'


class Role(Base):
    __tablename__ = "roles"

    id: Mapped[int] = mapped_column(primary_key=True)
    permissions: Mapped[List[PermissionEnum]] = mapped_column(
        postgresql.ARRAY(sa.Text()), nullable=False)


Base.metadata.create_all(engine)

app = FastAPI()
admin = Admin(app, engine)


class RoleAdmin(ModelView, model=Role):
    form_args = {'permissions': dict(choices=[it.value for it in PermissionEnum])}


admin.add_view(RoleAdmin)

if __name__ == "__main__":
    uvicorn.run("main:app", host="127.0.0.1", port=8000)

Environment

Browser: Version 116.0.5845.187
OS: Mac OS Ventura 13.5.2
Postgres: 12.14
Python: 3.11
Requirements.txt:

SQLAlchemy==2.0.21
sqladmin[full]==0.15.0
fastapi==0.103.1
psycopg2-binary==2.9.7
uvicorn

Additional context

No response

@aminalaee
Copy link
Owner

aminalaee commented Sep 21, 2023

Hey, I haven't yet checked your code (BTW you have a nice formatted example code, that's great), but I think choices needs to be a tuple of (value, label) in WTForms: https://wtforms.readthedocs.io/en/2.3.x/fields/#wtforms.fields.SelectField

@Toshakins
Copy link
Contributor Author

@aminalaee Thank you very much for looking into the issue. Open source is a tough job, and I'm all in to make it a bit easier.

As the documentation suggests, the SelectField could also accept the list of values that will be used as labels. The issue is still reproducible for me while sending (value, label) to the class.

For now, I can work around the bug by deliberately using SelectMultipleField but it gives an inferior user experience, therefore I've created this report.

@aminalaee
Copy link
Owner

You're right. But first I need to say that console error is not relevant. I need to check that separately.

About this issue, it is normal that the browser selects the first option, so you need to add an empty option: https://stackoverflow.com/questions/40905579/flask-wtf-dynamic-select-field-with-an-empty-option

But if you try that the UI gets a bit weird, because this is not normal select, it is select2 option, so in addition to that empty option, we also need to add a placeholder which makes it nice: https://groups.google.com/g/select2/c/QCP1srwg48s?pli=1

Screenshot from 2023-09-21 14-18-57

PRs welcome, otherwise I can check it later.

@Toshakins
Copy link
Contributor Author

Thanks for investigating it more deeply, your findings led me to PR, please take a look 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants