I am asking user (using JOptionPane) to input account number. I would like to ask how could I check that if inputs is all integers, then the program will continue otherwise it will show an error message and would ask the user to input again until valid input. thanks!
Possible a duplicated question : See here:
Check if input is an integer in JOptionPane
But if it was a web form, You could simply attach an onKeyUp event handler and parse the value every time the user types something in that field.
by JavaScript, you can use .isNaN() to determine if the value is a legal numeric value. Or JQuery's .isNumeric() can do this as well.
https://api.jquery.com/jQuery.isNumeric/
You can use jQuery Validate to restrict character on input filed ..
$Validate = $("#form1").validate({
rules: {
accountnumber: {
required: true,
digits: true
}
},
messages: {
CampaignName: {
required: "*"
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.15.1/jquery.validate.min.js"></script>
<form name='form1' id='form1' method='post'>
<input type='text' name='accountnumber' id='txtAccountNumber' />
</form>
Related
I want to convert an API service into a forms the user of my app can fill in. I think I need the right vocabulary to ask farther questions. Is there a term for this process?
Hydra is the only vocab I know about in the topic, though they don't support this kind of conversion. https://www.hydra-cg.com/spec/latest/core/ HAL forms is another solution: https://rwcbook.github.io/hal-forms/ but I guess based on the name that it is not abstract enough. You need to separate hyperlinks from forms. The former is for describing the interface of the webservice the later is for describing the GUI, which can use the webservice amongst many different types of clients. E.g. a select/choice parameter can be converted into radio button, checkbox, select input, range, etc. There needs to be some sort of mapping about this and this decision is made by the client developers, not by the service developers. Supporting multiple languages and labelling must be mapped too.
What you need is very detailed hyperlink descriptions and you can turn your hyperlinks into forms and hyperlink parameters into input fields. There are certain types of parameters e.g.
text (password?, multiline?, lengthRange, verified:regex|url|email|etc.)
repetition (source e.g. password double check)
select(alternatives[], selected[], selectionSize)
date(range, selectedRange, selectionSize)
time(range, selectedRange, selectionSize)
color(alternatives|range, selectedRange, selectionSize)
file(multi?, sizeRange, MIME-types[])
...
Better to support only what you need, because I think you need to write it yourself. Try to be very general, abstract instead of specific in this vocab. E.g. select can support select single and select multiple. The single can be supported with selectionSize=1. The alternatives can be added with a list or with another hyperlink which can be part of the response or lazy loaded, or it can be even an URI template which expects a keyword. The data of the fields can depend on each other, e.g. first you select city and the next field is street selection where you download the data by filling an URI template. So these fields can be interrelated and doing it properly requires a complex vocab.
From the REST API side of story binding these to the hyperlinks is relative easy:
{
id: "/api/users/123"
type: "/docs/User"
userid: 123,
addCar: {
type: "/docs/User/addCar",
method: "PUT",
uri: {
template: "/api/users/{id}/cars/{plateNumber}",
id: {
type: "docs/Text",
range: "docs/Car/id",
value: {
type: "/docs/Query",
context: "./resource",
select: "userid",
},
readOnly: true,
required: true
},
plateNumber: {
type: "/docs/Text",
range: {
id: "/docs/Car/plateNumber",
verified: {
type: "/docs/verification/regex",
pattern: "[A-Z]{4,4}\d{2,2}"
}
},
required: true
}
},
body: {
brand: {
type: "/docs/Selection",
range: "/docs/Car/Brand/id",
alternatives: {
type: "/docs/Car/Brand/listBrands",
method: "GET",
uri: "/api/car-brands"
},
value: null,
selectionSize: [1,1],
required: true
}
}
}
}
The generated HTML form can be something like the following with radio input, but you can use select input too:
<form onsubmit="magic(this); return false">
<input type="hidden" id="user_id" name="user_id" value="123">
<input type="text" id="plate_number" name="plate_number" pattern="[A-Z]{4,4}\d{2,2}" required="required"><br>
<label for="plate_number">Plate Number</label><br>
Select Brand:
<input type="radio" id="brand_vw" name="brand" value="VW" required="required">
<label for="brand_vw">Volkswagen</label><br>
<input type="radio" id="brand_ford" name="brand" value="Ford">
<label for="brand_ford">Ford</label><br>
<input type="submit" value="Add Car">
</form>
The request is something like:
PUT /api/users/123/cars/ABCD12 {brand: "Ford"}
When you do it with an automated client you do:
carService.getUser({id: 123}).addCar({plateNumber: "ABCD12", brand: "Ford"})
When you do it with GUI, then:
carService = new Service("/docs")
// GET /docs/* might be cached
// or you can download a single JSON-LD docs file and use # for terms
// you bookmarked the getUser link from a previous call
// or you get it with GET /api/
// you can fill it with the actual user
user = carService.getUser({id: jwt.userId})
// GET /api/users/123
// you find the addCar link and generate a form from it
// GET /api/car-brands
// the user fills the form and sends it with magic
user.addCar({plateNumber: "ABCD12", brand: "Ford"})
// PUT /api/users/123/cars/ABCD12 {brand: "Ford"}
As you can see this can be very complicated and the upper hyperlink description is ad-hoc. If you need a proper RDF vocab, then it takes serveral years to design it properly. Still this kind of technique could be used in theory.
A complete client cannot be generated, because that involves knowing what you are doing or what you possibly need and in which part of the client. E.g. in this case it is where to display the form, when do we need this form and why, where to get the actual user id and the hyperlink from, etc. If the user has to decide everything about this, then in theory it can be generated and would look like a simple webpage, which can be browsed.
I am currently using Vuelidate for a form. There is an input field where the user is allowed to leave it in blank, which is an optional field.
Minimum value, if entered, should be 0 or higher, but If I leave it empty, it will still throw the error. Validation works well for numbers, it executes the error class when entered value is below 0.
Summary: I need to have minValue(0) but also nullable possibility.
I currently have this:
validations: {
company_name: {
minValue: minValue(0)
}
}
Template looks like this:
<input
id="company_name"
:value="company_name"
type="number"
min="0"
step="0.01"
:class="{ 'error': v$.company_name.minValue.$invalid"
>
I'm creating a dynamic re-usable vue component that wraps a text input and includes the vuelidate validation stylings, etc.:
<template>
<div class="form-group" :class="{'form-group--error': validator.$error}">
<label>{{ label }}<span v-if="validator.$params.required">*</span></label>
<input type="text v-model="validator.$model" />
<div class="error" v-if="validator.$error && !validator.required">* This field is required</div>
</div>
<template>
<script>
export default {
name: "FormTextField",
props: ["validator", "label"]
}
</script>
(validator prop is $v from parent)
The problem I have is trying to show the <span>*</span> dynamically based on if the field is required. This currently works (v-if="validator.$params.required") as long as I only specify the required validator:
fieldName: {
required: required
}
Now, I need to instead declare my validation like this:
fieldName: {
required: requiredIf( ... )
}
The question is how to access the result of the requiredIf function? validator.$params.required will always be true since it's just checking if the param is there. And validator.required is the status of the validation, not the result of the requiredIf call to see whether it SHOULD be required or not.
Any suggestions on how I can show the required star dynamically based on vuelidate state?
Instead of validator.$params.required, check validator.required, which is only defined when there's a required or requiredIf validator rule applied. The value of validator.required is true when the field is missing, or false otherwise.
When the field is optional (has no required/requiredIf rule), the validator.required property does not exist, so we can't use v-if="!validator.required". Instead, explicitly compare validator.require to false:
<label>{{ label }}<span v-if="validator.required === false">*</span></label>
<div class="error" v-if="validator.$error && validator.required === false">* This field is required</div>
demo
I have a text field component for numeric inputs. Basically I'm just wrapping v-text-field but in preparation for implementing it myself. It looks like this.
<template>
<v-text-field v-model.number = "content" />
</template>
<script>
export default {
name: 'NumericTextField',
props: [ 'value' ],
computed: {
content: {
get () { return this.value },
set (v) { this.$emit('input', f) },
},
}
}
</script>
This has generated user feedback that it's annoying when the text field has the string "10.2" in it and then backspace over the '2', then decimal place is automatically delete. I would like to change this behavior so that "10." remains in the text field. I'd also like to understand this from first principles since I'm relatively new to Vue.
So I tried this as a first past, and it's the most instructive of the things I've tried.
<template>
<v-text-field v-model="content" />
</template>
<script>
export default {
name: 'NumericTextField',
props: [ 'value' ],
computed: {
content: {
get () { return this.value },
set (v) {
console.log(v)
try {
const f = parseFloat(v)
console.log(f)
this.$emit('input', f)
} catch (err) {
console.log(err)
}
},
},
}
}
</script>
I read that v-model.number is based on parseFloat so I figured something like this must be happening. So it does fix the issue where the decimal place is automatically deleted. But... it doesn't even auto delete extra letters. So if I were to type "10.2A" the 'A' remains even though I see a console log with "10.2" printed out. Furthermore, there's an even worse misfeature. When I move to the start of the string and change it to "B10.2" it's immediately replaced with "NaN".
So I'd love to know a bunch of things. Why is the body of the text body immediately reactive when I change to a NaN but not immediately reactive when I type "10.2A"? Relatedly, how did I inadvertently get rid of the auto delete decimal place? I haven't even gotten to that part yet. So I'm misunderstanding data flow in Vue.
Lastly, how can I most simply provide a text box that's going to evaluate to a number for putting into my data model but not have the annoying auto delete of decimal places? The existing functionality doesn't auto delete trailing letters so I'm guessing the auto delete of decimal places was a deliberate feature that my users don't like.
I'm not 100% sure of any of this, but consider how v-model works on components. It basically is doing this:
<v-text-field
v-bind:value="content"
v-on:input="content = $event.target.value"
/>
And consider how the .number modifier works. It runs the input through parseFloat, but if parseFloat doesn't work, it leaves it as is.
So with that understanding, I would expect the following:
When you type in "10.2" and then hit backspace, "10." would be emitted via the input event, parseFloat("10.") would transform it to 10, v-on:input="content = $event.target.value" would assign it to content, and v-bind:value="content" would cause the input to display "10". So then, this is the expected behavior.
When you type in "10.2" and then hit "A", "10.2A" would be emitted via the input event, parseFloat("10.2A") would transform it to 10.2, v-on:input="content = $event.target.value" would assign it to content, and v-bind:value="content" would cause the input to display "10.2". It looks like it's failing at that very last step of causing the input to display "10.2", because the state of content is correctly being set to 10.2. If you use <input type="text" v-model.number="content" /> instead of <v-text-field v-model.number="content" />, once you blur, the text field successfully gets updated to "10.2". So it seems that the reason why <v-text-field> doesn't is due to how Vuetify is handling the v-bind:value="content" part.
When you type in "10.2" and then enter "B", in the beginning, "B10.2" would be emitted via the input event, parseFloat("B10.2") would return NaN, and thus the .number modifier would leave it as is, v-on:input="content = $event.target.value" would assign "B10.2" to content, and v-bind:value="content" would cause the input to display "B10.2". I agree that it doesn't seem right for parseFloat("10.2A") to return 10.2 but parseFloat("B10.2") to return "B10.2".
Lastly, how can I most simply provide a text box that's going to evaluate to a number for putting into my data model but not have the annoying auto delete of decimal places?
Given that the default behavior is weird, I think you're going to have to write your own custom logic for transforming the user's input. Eg. so that "10.2A" and "B10.2" both get transformed to 10.2 (or are left as is), and so that decimals are handled like you want. Something like this (CodePen):
<template>
<div id="app">
<input
v-bind:value="content"
v-on:input="handleInputEvent($event)"
/>
<p>{{ content }}</p>
</div>
</template>
<script>
export default {
data() {
return {
content: 0,
};
},
methods: {
handleInputEvent(e) {
this.content = this.transform(e.target.value);
setTimeout(() => this.$forceUpdate(), 500);
},
transform(val) {
val = this.trimLeadingChars(val);
val = this.trimTrailingChars(val);
// continue your custom logic here
return val;
},
trimLeadingChars(val) {
if (!val) {
return "";
}
for (let i = 0; i < val.length; i++) {
if (!isNaN(val[i])) {
return val.slice(i);
}
}
return val;
},
trimTrailingChars(val) {
if (!val) {
return "";
}
for (let i = val.length - 1; i >= 0; i--) {
if (!isNaN(Number(val[i]))) {
return val.slice(0,i+1);
}
}
return val;
},
},
};
</script>
The $forceUpdate seems to be necessary if you want the input field to actually change. However, it only seems to work on <input>, not <v-text-field>. Which is consistent with what we saw in the second bullet point. You can customize your <input> to make it appear and behave like <v-text-field> though.
I put it inside of a setTimeout so the user sees "I tried to type this but it got deleted" rather than "I'm typing characters but they're not appearing" because the former does a better job of indicating "What you tried to type is invalid".
Alternatively, you may want to do the transform on the blur event rather than as they type.
I am facing a problem with my page with VueJS. It's a page for different translations of the website. It has a dropdown on the top for the language selection that once switched will update the fields with the current language.
The problem starts when it loads, because my form is like this:
<form id="trForm">
...
<input type="text" name="header_title" class="form-control" v-model="translations.header.header_title" />
...
</form>
It's trying to access these attributes before the method returns any data, but somehow it will still show the data once it is complete, but it becomes troublesome when I try to switch the language, it won't because of this problem and also, if I do the following:
<form id="trForm">
...
<input type="text" name="header_title" v-if="translations.header" class="form-control" v-model="translations.header.header_title" />
...
</form>
on each field, those that aren't populated will display no field at all for a new input value. I tried something like translations.features || '', but no success.
I also tried to put on the parent block a condition that if the loading is false will display the form, but since the page is loaded first than the method is executed, it will always be false for the first microsecond.
methods: {
fetchTranslations(e) {
let vm = this;
vm.loaded = false;
$.get('/ajax/admin/translations', { 'locale': e }).done((data) => {
if (data.success) {
vm.translations = JSON.parse(data.translations.translation);
vm.loaded = true;
} else {
toastr.error('Something went wrong');
}
});
},
Please, what do I do? It'd be good to show the form after there is data.
Introduce a new variable, e.g. loaded that defaults to false
Use this variable as a v-if condition on the form
In the callback of your data fetch, set loaded to true.