Dojo ValidatedTextBox Not Working - dojo

I have searched high and low for solution for this but I have not been able to find anything. I am playing around with the dojo ValidatationTextBox dijit. I have tried to both declarative and programmatic methods and every time it comes up as a readonly input field. The code provided shows my attempt using the declarative method. I got the exact same result using a programmatic route similar to the "new textbox" calls below. In both methods the html for the ValidatationTextBox is generated with two child divs. One with class=dijitReset dijitValidationContainer and one with class=dijitReset dijitInputField dijitInputContainer. It is the later class that holds all of the html input and dijit properties and the former that defines the form as readonly and also gives it a value of 'x'. What am I doing wrong? Any help or explanation regarding why this is not working will be much appreciated. Thanks
<script>
require(["dojo/parser", "dijit/form/TextBox", "dijit/form/ValidationTextBox","dojo/domReady!","dojox/validate","dojox/validate/web"],
function(parser, textbox, ValidationTextBox,validate){
parser.parse();
new textbox({
id: "fName",
maxlength: 25,
name: "fName",
trim: "true",
propercase: "true"
}, "fName");
new textbox({
id: "lName",
maxlength: 25,
name: "lName",
trim: "true",
propercase: "true"
}, "lName");
});
</script>
</head>
<body class="tundra">
<h3>Sign-up for our great offers:</h3>
<form id="registration_form">
<div class="grouping">
<label for="fName">First Name:</label>
<input id="fName" /><br />
<label for="lName">Last Name:</label>
<input id="lName" /><br />
<label for="email">Your Email:</label>
<input type="text" name="email" required="true" readonly="false"
data-dojo-type="dijit/form/ValidationTextBox"
data-dojo-props="regExp:'[a-z0-9._%+-]+#[a-z0-9-]+\.[a-z]{2,4}', invalidMessage:'Please enter a valid e-mail address'" /><br />
<button id="btn">Sign Up!</button>
</div>
</form>
</body>

I think the problem may be with your regExp however you can write a keyup function and call it when the user types it will validate the email address using Dojo's built in email validation. Also for your fname and lname fields try setting required = "true". You can do this to implement on the fly validation since if your fields are not required you need to call validation on your form when you post. You can refer to this Form Validation Fiddle
HTML
<input type= "text" name ="email" data-dojo-type="dijit/form/ValidationTextBox" missingMessage="Email Address Required" invalidMessage="Invalid Email Address" onkeyup="validateMe(this.value);" required="true" />
js
function validateMe(email){
var isValid = false;
isValid = dojox.validate.isEmailAddress(email);
return isValid;
}

Related

Razor tag helper bool Radio buttons clientside 'Required' validation

I am using Razor Pages Tag helpers for a Yes/No in a form on a page. All other fields in the form have client side unobtrusive validation, but the bool? Yes/No does not. I have a few radio Yes/No's like this, how do I get the client side to work for them?
[Required]
public bool? Have7DaysWorth { get; set; }
I tried moving away from tag helpers too, butit doesn't hook up with this:
<label asp-for="Have7DaysWorth" class="control-label"></label>
<div>
<input type="radio" id="daysRadio1" name="Have7DaysWorth "
checked="#(Have7DaysWorth == true ? "checked": null)"
class="custom-control-input" value="true">
<label class="custom-control-label" for="daysRadio1">Yes</label>
</div>
<div>
<input type="radio" id="pharmacyRadio2" name="Have7DaysWorth "
checked="#(Have7DaysWorth == false ? "checked": null)"
class="custom-control-input" value="false">
<label class="custom-control-label" for="daysRadio1">No</label>
</div>
<span asp-validation-for="Have7DaysWorth " class="text-danger"></span>
I know from searching there are some suggestions about pre-selecting one, but that isn't then a conscious value that a user has entered into a form, so not an option here.
I have tried some other ways, but they seemed to lose the value when the modelstate wasn't valid and was returned.
How do I get the client side to work for bool radios in the expected way that I want?
You're not using asp-for on the radios, so it has no idea it should be required, as there's no involvement with the model, and thus the Required attribute on that property.
An old thread but if you're having to upgrade a razor page website to Bootstrap 5 you'll run into this issue.
This will not work as you cannot use asp-for with C# statement not inside an attribute
<input asp-for="MarketingPrefs" type="radio" class="btn-check" value="true" #(Model.MarketingPrefs.HasValue && Model.MarketingPrefs.Value ? "checked" : null)>
If you omit the asp-for like this then local validation won't work
<input id="MarketingPrefsYes" name="MarketingPrefs" type="radio" class="btn-check" value="true" #(Model.MarketingPrefs.HasValue && Model.MarketingPrefs.Value ? "checked" : null)>
This is how to do it
<div class="btn-group" role="group">
#Html.RadioButtonFor(model => model.MarketingPrefs, "true", new { #class = "btn-check", #id="MarketingPrefsYes" })
<label class="btn btn-outline-secondary" for="MarketingPrefsYes">Yes</label>
#Html.RadioButtonFor(model => model.MarketingPrefs, "false", new { #class = "btn-check", #id="MarketingPrefsNo" })
<label class="btn btn-outline-secondary" for="MarketingPrefsNo">No</label>
</div>

Getting form data on submit?

When my form is submitted I wish to get an input value:
<input type="text" id="name">
I know I can use form input bindings to update the values to a variable, but how can I just do this on submit. I currently have:
<form v-on:submit.prevent="getFormValues">
But how can I get the value inside of the getFormValues method?
Also, side question, is there any benefit to doing it on submit rather than updating variable when user enters the data via binding?
The form submit action emits a submit event, which provides you with the event target, among other things.
The submit event's target is an HTMLFormElement, which has an elements property. See this MDN link for how to iterate over, or access specific elements by name or index.
If you add a name property to your input, you can access the field like this in your form submit handler:
<form #submit.prevent="getFormValues">
<input type="text" name="name">
</form>
new Vue({
el: '#app',
data: {
name: ''
},
methods: {
getFormValues (submitEvent) {
this.name = submitEvent.target.elements.name.value
}
}
}
As to why you'd want to do this: HTML forms already provide helpful logic like disabling the submit action when a form is not valid, which I prefer not to re-implement in Javascript. So, if I find myself generating a list of items that require a small amount of input before performing an action (like selecting the number of items you'd like to add to a cart), I can put a form in each item, use the native form validation, and then grab the value off of the target form coming in from the submit action.
You should use model binding, especially here as mentioned by Schlangguru in his response.
However, there are other techniques that you can use, like normal Javascript or references. But I really don't see why you would want to do that instead of model binding, it makes no sense to me:
<div id="app">
<form>
<input type="text" ref="my_input">
<button #click.prevent="getFormValues()">Get values</button>
</form>
Output: {{ output }}
</div>
As you see, I put ref="my_input" to get the input DOM element:
new Vue({
el: '#app',
data: {
output: ''
},
methods: {
getFormValues () {
this.output = this.$refs.my_input.value
}
}
})
I made a small jsFiddle if you want to try it out: https://jsfiddle.net/sh70oe4n/
But once again, my response is far from something you could call "good practice"
You have to define a model for your input.
<input type="text" id="name" v-model="name">
Then you you can access the value with
this.name inside your getFormValues method.
This is at least how they do it in the official TodoMVC example: https://v2.vuejs.org/v2/examples/todomvc.html (See v-model="newTodo" in HTML and addTodo() in JS)
Please see below for sample solution, I combined the use of v-model and "submitEvent" i.e. <input type="submit" value="Submit">. Used submitEvent to benefit from the built in form validation.
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/vue"></script>
</head>
<body>
<div id="app">
<form #submit.prevent="getFormValues">
<div class="form-group">
<input type="email" class="form-control form-control-user"
v-model="exampleInputEmail"
placeholder="Enter Email Address...">
</div>
<div class="form-group">
<input type="password" class="form-control"
v-model="exampleInputPassword" placeholder="Password"> </div>
<input type="submit" value="Submit">
</form>
</div>
<script>
const vm = new Vue({
el: '#app',
methods: {
getFormValues (submitEvent) {
alert("Email: "+this.exampleInputEmail+" "+"Password: "+this.exampleInputPassword);
}
}
});
</script>
</body>
</html>
The other answers suggest assembling your json POST body from input or model values, one by one. This is fine, but you also have the option of grabbing the whole FormData of your form and whopping it off to the server in one hit. The following working example uses Vue 3 with Axios, typescript, the composition API and setup, but the same trick will work anywhere.
I like this method because there's less handling. If you're old skool, you can specify the endpoint and the encoding type directly on the form tag.
You'll note that we grab the form from the submit event, so there's no ref, and no document.getElementById(), the horror.
I've left the console.log() there to show that you need the spread operator to see what's inside your FormData before you send it.
<template>
<form #submit.prevent="formOnSubmit">
<input type="file" name="aGrid" />
<input type="text" name="aMessage" />
<input type="submit" />
</form>
</template>
<script setup lang="ts">
import axiosClient from '../../stores/http-common';
const formOnSubmit = (event: SubmitEvent) => {
const formData = new FormData(event.target as HTMLFormElement);
console.log({...formData});
axiosClient.post(`api/my-endpoint`, formData, {
headers: {
"Content-Type": "multipart/form-data",
}
})
}
</script>

asp-for tag adds required field validation on checkbox in asp.net core

I have asp.net core application and im trying to add simple checkbox without any validation. Checkbox is bound to boolean property on model. Below is the code
Model
public class MyModel
{
public bool IsEmployee { get; set; }
}
cshtml
<form>
<div>
<label asp-for="IsEmployee">Is Employee</label>
<input type="checkbox" asp-for="IsEmployee"/>
</div>
<button id="btnSave" class="btn btn-primary" type="button">Save</button>
</form>
<script src="~/js/test.js"></script>
javascript
$(function () {
var kendoValidator = $('form').kendoValidator().data("kendoValidator");
$('#btnSave').click(function () {
if (kendoValidator.validate()) {
alert('true');
}
else {
alert('false');
}
})
})
I am using asp-for tag helper on input element. Note that IsEmployee property DOES NOT have [Required] attribute. But because of asp-for tag helper the rendered html has data-val-required and data-val attributes on input element. It also adds one more hiddden input element with same name.
Below is rendered html.
(also note that i think it only happens when input type is checkbox. for textboxes its working fine)
<form novalidate="novalidate" data-role="validator">
<div>
<label for="IsEmployee">Is Employee</label>
<input name="IsEmployee" id="IsEmployee" type="checkbox" value="true" data-val-required="The IsEmployee field is required." data-val="true">
</div>
<button class="btn btn-primary" id="btnSave" type="button">Save</button>
<input name="IsEmployee" type="hidden" value="false">
</form>
I am using kendovalidator as well which adds data-role="validator" on form element.
Issues
There are 2 issues here
1> As soon as i click on check the box error message appears as The IsEmployee field is required.
2>kendoValidator.validate() method always returns false regardless of checkbox is selected or not.
Demo here JSFiddle
Update 2
We cannot bind nullable bool to checkbox. I am using asp.net core. I am not sure what the equivalent syntax in asp.net core for the suggestion here which is valid for classic asp.net
Add data-validate="false" to the checkbox input. The kendoValidator will ignore all inputs with that attribute set to false.
<input type="checkbox" asp-for="IsEmployee" data-validate="false" />
If you don't wan't the default generated html you have 2 choices.
Don't use it ! You are not forced to use the tag helpers, they are there for when you do need other html attributes generated. In this case just use < input name="IsEmployee" ...>
Change the way asp-for behaves for your checkbox. You can do this be either creating your own IHtmlGenerater or by extending the DefaultHtmlGenerator and overriding GenerateCheckBox and possibly GenerateInput and then registering it with something like services.TryAddSingleton();
Hope this helpes you.

Polymer Get Paper Input Value

I am using Polymer for a short time and now i want to get the value of a paper input. I don't know how can I do this.
This is not working:
this.form.password
I want to get the Value of this field:
<paper-input label="Password" type="password" id="password" name="password" size="25" value=""></paper-input>
I also want get the Input for submitting of the e-mail input:
<paper-input label="Login" id="email" name="email" size="25" value=""></paper-input>
For submitting I am using:
<paper-button raised value="Login" type="submit" onclick="formhash(this.form, this.form.password);">Login</paper-button>
With normal input fields is this working.
You can use document.querySelector('#password').value to get the value of paper-input with id password in the formhash() function call or inside the function definition.
You can also use polymer's Automatic node finding to get value of an element using its id. In which keep the form/input in custom-element and use this.$.password.value to get the value of an element with id password. Like this
<!-- create a custom component my-form -->
<dom-module id="my-form">
<template>
<form is="iron-form" id="form" method="post">
<paper-input name="name" label="name" id="name"></paper-input>
<paper-button raised on-click="submitForm">Submit</paper-button>
</form>
</template>
<script type="text/javascript">
Polymer({
is: "my-form",
submitForm: function() {
alert(this.$.name.value);
if(this.$.name.value != "") // whatever input check
this.$.form.submit();
}
})
</script>
</dom-module>
<my-form></my-form> <!-- use custom-component my-form -->
If you don't want to use <form> you can also simply store the paper-input values in instance variables and use them later wherever you want.
All you have to do is store the input inside a value like this:
<paper-input label="Password" type="password" id="password" name="password" size="25" value="{{valueNameToStore}}"></paper-input>
And later access it like this:
var myPassword = this.valueNameToStore;
Using <form is="iron-form"> allows you to use <paper-input> and other input elements in forms https://elements.polymer-project.org/elements/iron-form
<form is="iron-form" id="form" method="post" action="/form/handler">
<paper-input name="name" label="name"></paper-input>
<input name="address">
...
<paper-button raised onclick="submitForm()">Submit</paper-button>
</form>
function submitForm() {
document.getElementById('form').submit();
}
or, sometimes you can try this.$.password.value to get the value for password.

how to show dojo validation error tool tip?

Question:--
I am using following HTML code showing error message using tool tip whenever length of Textbook equal to zero,
but i couldn't set my defined message inside tool tip.
<body class="claro">
<form action="">
Enter Name:--
<input type="text" name="firstname" data-dojo-props="" data-dojo-type="dijit.form.TextBox"
trim="true" id="firstname" propercase="true">
<button id="button4" data-dojo-type="dijit.form.Button" type="button">Submit
<script type="dojo/method" event="onClick" args="newValue">
alert("Value selected is: "+newValue);
var firstNameId=dijit.byId("firstname").value;
alert('firstNameId.length:----'+firstNameId.length);
if(firstNameId.length==0)
{
var textBox = dijit.byId("firstname");
dijit.showTooltip(
textBox.get("invalidMessage"),
textBox.domNode,
textBox.get("justMessage"),
!textBox.isLeftToRight()
);
}
else
{
alert('wrong');
);
}
<br>
Help me out....
It's been a while since you posted this question, but if you still need it, here's an answer.
Dijit/form/TextBox doesn't have a showTooltip method. To show a tooltip you can instead call something like:
var textBox = dijit.byId("firstname");
textBox.invalidMessage = "Whatever you want";
Tooltip.show(textBox.get("invalidMessage"),
textBox.domNode, textBox.get("tooltipPosition"),
!textBox.isLeftToRight());
Be sure to include dijit/Tooltip!