TextInput vs input number issue

When using the TextInput with the type=“number”, the value is set a string for the model that is bound causing an issue when attempting to save a model that expects a number is instead given a string. Is there anything extra that I need to do when using this control? I don’t want to start casting the value back to a number from a string for numerical fields.

     <TextInput id="t" v-model="numberValueSSInput" help="" min="0"
                 placeholder="Penalty Points" type="number"/>


Using the regular input component with type=“number” behaves as expected.

see below for a quick demo

<script lang="ts" setup>
import {ref} from "vue";


const numberValueStandardInput = ref();
const numberValueSSInput = ref();
const submit = async (e: Event) => {

  console.log({numberValueStandardInput: numberValueStandardInput.value, numberValueSSInput: numberValueSSInput.value});
}
</script>


<template>

  <div>

    <form @submit.prevent="submit">
      <p>standard</p>
      <input v-model="numberValueStandardInput" type="number"/>
      <p>ss</p>
      <TextInput id="t" v-model="numberValueSSInput" help="" min="0"
                 placeholder="" type="number"/>

      <PrimaryButton>Save</PrimaryButton>
    </form>
  </div>
</template>

image

It’s the default behavior of TextInput which is too prevalently used everywhere to try to change.

Here’s the source code of TextInput.vue if you want to create a custom component that behaves how you want.

This has been a time drain would have expected it to just work for something so simple.

How does the autoforms deal with properties that are numbers under the hood?

I don’t know what this is asking?

Either way, entire source code for @servicestack/vue is at github.com/ServiceStack/servicestack-vue and AutoForm.vue.

Does AutoForm use the ServiceStack TextInput component for fields of numeric types (e.g., int , double )? If so, how does it handle marshalling the input value from a string back to a number when binding to the DTO?

The documentation that SS has for the controls mention nothing about having to do extra work to get the bindings done, and for someone using these controls for the first time it has been annoying and non productive

I’ve linked to the source code of the component, it uses it and handles it fine.
It’s used in many of ServiceStack’s built-in UIs.

Note for Form Posts it sends the FormData of the form which is also needed for forms which upload files.

You can also change your APIs to use ServiceStack JSON for deserializing Request DTOs which is a less strict and more flexible JSON Serializer:

[SystemJson(UseSystemJson.Response)]
public class CreateUser : IReturn<IdResponse>
{
    //...
}

Yes and I wanted to know why it works. I just wanted to get going and not jump through hoops for something so trivial.

See this example below updating the Booking from the Vue spa template, I want to manually create the form, looking at the SS documentation for Vue components I assume just use the TextInput with the required type.

<script lang="ts" setup>
import {ref} from "vue";
import {UpdateBooking} from "@/dtos.ts";
import {useClient} from "@servicestack/vue";

const client = useClient()

const booking = ref(new UpdateBooking());
const submit = async (e: Event) => {
  booking.value.id = 1;
  await client.api(booking.value);
}
</script>

<template>
  <div>
    <form @submit.prevent="submit">
<!--      <input v-model="booking.roomNumber" step="1" type="number"/>-->
      <TextInput id="roomNumber" v-model="booking.roomNumber" step="1" type="number"/>

      <PrimaryButton>Save</PrimaryButton>
    </form>
  </div>
</template>

But this results in a error message

---> System.Text.Json.JsonException: The JSON value could not be converted to System.Nullable`1[System.Int32]. Path: $.roomNumber | LineNumber: 0 | BytePositionInLine: 24.
       ---> System.InvalidOperationException: Cannot get the value of a token type 'String' as a number.

I’m just giving you the perspective of someone new coming into ecosystem and running into these trivial issues where I have to now apply [SystemJson(UseSystemJson.Response)] to a model with that has number properties is frustrating as it isn’t documented anywhere you would just expect it to work. I’m using these SS and these components to save time and I’ve spent more time doing side quests as opposed to real work.

I’ve already linked to why, it uses apiForm to send FormData requests:

Or you can configure it once for the entire App:

app.UseServiceStack(new AppHost(), options => {
    // Use only for serializing API Responses
    options.MapEndpoints(useSystemJson:UseSystemJson.Response);
});

Thanks… hope can be documented somewhere to help someone using the vue templates if they intend on hand crafting forms.