Skip to main content

FileField

Struct FileField 

Source
pub struct FileField<F = ()>(/* private fields */);
Expand description

A file field: Field::file, or a record form’s file control (F is the form).

Implementations§

Source§

impl<F: EditsRecords> FileField<F>

Source

pub fn hidden_on_create(self) -> Self

Renders nothing for the field on the create form. The create stores the field’s default, else its blank answer: a required field with neither cannot mount. A field hidden on both forms only ever stores that: set it in the record instead.

Source

pub fn hidden_on_edit(self) -> Self

Renders nothing for the field on the edit form, and keeps its stored value whatever an edit posts: the create form sets the value, and no edit changes it, as disabled_on_edit does without showing it.

Source§

impl<F> FileField<F>

Source

pub fn disabled_when( self, watched: &impl Watched<F>, values: impl IntoIterator<Item = impl Into<String>>, ) -> Self

Renders the control disabled while watched posts one of values: an option’s value, or true or false for a toggle. Disabled, the control posts nothing, so an edit keeps the stored value and a create takes the field’s default, else its blank answer.

let status = Field::choice(Order::fields().status()).options(["draft", "sent"]);
let total = Field::text(Order::fields().total()).disabled_when(&status, ["sent"]);
Schema::new((status, total));
  • The browser enables and disables the control as the watched field changes, with no request, through a disabled fieldset around it. An app’s own Control follows it only through the form controls it renders. Without JavaScript, the control starts as the form’s initial values set it, the stored ones on an edit, and stays that way.
  • The panel reads a submission the same way and drops the field’s posted key, and a file field’s carried upload, while the condition holds. The condition reads what the user may post, so it is no access check: ResourceDef::field_access is.
  • Mounting refuses what it refuses for visible_when: an unplaced watched field, a value it never posts, a multiple choice, and a watched field another condition hides while this one still shows. It also refuses a required field with no non-blank default, which a create could not fill while the condition holds, and a condition or a dependent choice watching this field: a disabled control posts nothing, so the browser and the server would read different values.
  • A later call replaces an earlier one.
Source§

impl<F> FileField<F>

Source

pub fn extensions<I>(self, extensions: I) -> Self
where I: IntoIterator, I::Item: AsRef<str>,

Refuse a file whose name does not end in one of extensions, listed without the dot and matched without case, and hint them to the browser’s file picker through accept.

Field::file(lens!(Doc.cover))
    .extensions(["png", "jpg", "jpeg", "webp"])
    .max_bytes(2 * 1024 * 1024);
  • The extension is the check, not the bytes. A served upload’s type comes from its extension, under X-Content-Type-Options: nosniff, so the extension is what decides how a browser treats the file: sniffing the content would pass PNG bytes named page.html. Nothing checks that the bytes are what the extension says; parse them in the Uploader when that matters, as before resizing an image.
  • The name checked is the sanitized one the Uploader receives. A custom uploader that names the stored file otherwise should keep its extension.
  • Only the server’s check refuses: accept is a hint the browser’s picker may ignore. A refused file is not stored, and the error renders on the field.
  • A refused submission carries a stored upload back through keep_<field>, signed for the field, so a carry names only a file this field’s rules passed; a carried path whose extension the field does not take is dropped too, as one the uploader does not hold is. A value the record already stores is not checked again.
  • Mounting refuses an empty list, and an extension that is not letters and digits.
Source

pub fn max_bytes(self, max_bytes: usize) -> Self

Refuse a file larger than max_bytes; the error spells the size in KiB or MiB when it divides evenly. Only the server checks it, before the Uploader stores the file; a carried upload passed it when it was stored. Mounting refuses a size at or above the panel’s Limits::body_bytes, which refuses a larger body first.

Source

pub fn image(self) -> Self

Show each stored file as a thumbnail beside its name, and each file the user picks or drops as one before the form saves it.

Field::files(lens!(Product.gallery))
    .image()
    .extensions(["png", "jpg", "jpeg", "webp"])
    .max_files(5);
  • It changes what the field shows, not what it takes: pair it with extensions, or a file that is no image shows as a broken one. The thumbnail loads from the same signed link as the file’s name.
  • Only a stored value that may become a link has a thumbnail: a rooted path or an http(s) URL.
Source

pub fn max_files(self, count: usize) -> Self

Refuse a submission leaving a Field::files list with more than count files: the stored ones it keeps and the ones it adds. The error renders on the field, and the files the submission stored are carried to the next one, so the user removes some and saves again; one choosing more than count files at once stores none. Mounting refuses it on a field over one path.

Source§

impl<F> FileField<F>

Source

pub fn label(self, label: impl Into<Text>) -> Self

Source

pub fn name(&self) -> &str

Source

pub fn visible_when( self, watched: &impl Watched<F>, values: impl IntoIterator<Item = impl Into<String>>, ) -> Self

Shows the field only while watched posts one of values: an option’s value, or true for a checked toggle. A hidden field posts nothing, so an edit keeps its stored value and a create takes its blank answer; a field with no blank answer cannot be conditional. A field shows under one condition: a later call replaces an earlier one, so a field depending on two watched fields sits in a Section guarded by the other.

let kind = Field::choice(Customer::fields().kind()).options(["person", "company"]);
let vat = Field::text(Customer::fields().vat_number()).visible_when(&kind, ["company"]);
Schema::new((kind, vat));
  • The browser shows and hides the field as the watched one changes, with no request. A hidden field’s control is disabled, so the browser neither validates nor posts it. Without JavaScript, the fields start as the stored values show them and stay that way.
  • The panel reads a submission the same way and drops a hidden field’s posted key, and a file field’s carried upload: an edit keeps the stored value, and a create stores the blank answer. A conditional field therefore needs a blank answer, and mounting refuses one without.
  • Mounting also refuses a value the watched field never posts (a choice’s option or a toggle’s true and false are checked), and a condition watching a field that another condition hides while the guarded field still shows: place the guarded field inside the block that hides the watched one. A schema also refuses a condition watching a field it does not place, which only a page’s or an action’s schema can do: a resource’s form places every record-form field.
  • A toggle is followed through its checkbox. An app’s own checkbox Control posts the same value checked or not, so a condition cannot follow it.
  • A multiple choice’s key holds a list, which no condition value spells: mounting refuses a condition watching one.
Source

pub fn span(self, columns: u8) -> Self

Spans columns of the Grid holding the field, clamped to 1..12. While the grid stacks its children, or lays out fewer columns, the field spans them all. Outside a grid, the span does nothing.

Source

pub fn span_full(self) -> Self

Spans every column of the Grid holding the field.

Source§

impl<F> FileField<F>

Source

pub fn help(self, text: impl Into<Text>) -> Self

Renders text under the control, which the control names as its description.

Source

pub fn disabled(self) -> Self

Renders the control disabled on the create and edit forms. The server drops a value posted for it anyway, so an edit keeps the stored value and a create takes the field’s default, else its blank answer; a field with neither cannot be created, and its panel refuses to mount.

Source

pub fn disabled_on_edit(self) -> Self

Renders the control disabled on the edit form only: the create form sets the value, and no edit changes it.

Source

pub fn custom(self, control: impl Control + 'static) -> CustomField<F>

Renders the field with an app’s Control instead, as Field::custom does: how a record form’s control takes a custom input. The field keeps its key and label; the replaced control’s own modifiers, such as email, unique or options, are dropped with it.

Source§

impl<F> FileField<F>

Source

pub fn choice(self) -> ChoiceField<F>

Renders the field as a choice instead, as Field::choice does, ready for options or relationship. The replaced control’s own modifiers are dropped with it.

Trait Implementations§

Source§

impl<F> From<FileField<F>> for Field

Source§

fn from(builder: FileField<F>) -> Field

Converts to this type from the input type.
Source§

impl<F> IntoSchema<F> for FileField<F>

Auto Trait Implementations§

§

impl<F = ()> !RefUnwindSafe for FileField<F>

§

impl<F = ()> !UnwindSafe for FileField<F>

§

impl<F> Forget for FileField<F>

§

impl<F> Freeze for FileField<F>
where PhantomData<fn() -> F>: Freeze,

§

impl<F> Send for FileField<F>
where PhantomData<fn() -> F>: Send,

§

impl<F> Sync for FileField<F>
where PhantomData<fn() -> F>: Sync,

§

impl<F> Unpin for FileField<F>
where PhantomData<fn() -> F>: Unpin,

§

impl<F> UnsafeUnpin for FileField<F>
where PhantomData<fn() -> F>: UnsafeUnpin,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more