Adding errors to form validation doesn't work? - semantic-ui

According to the Semantic UI docs on form validation, I can add errors manually:
add errors(errors) | Adds errors to form, given an array errors
(I want to use this feature because I submit my form via AJAX, do server-side validation, then want to display the results.)
I tried the following code:
$('#my-form').form("add errors", [ 'error' ]);
$('#my-form').form("validate form");
I get this contradictory output from the console when calling the above methods, and the form validates as successful when it obviously shouldn't.
Any idea?

To perform server-side validation via AJAX, use a custom rule:
$myForm = $('.ui.form');
var settings = {
rules: {
custom: function () {
// Perform AJAX validation here
return false;
}
}
};
var rules = {
ajaxField: {
identifier: 'ajaxField',
rules: [{
type: 'custom',
prompt: 'Custom error!'
}]
}
};
$myForm.form(rules, settings);
Here it is in action: http://jsbin.com/sufiwafe/1/edit
For how to use callbacks and form validation in general, there is an important discussion on the Semantic-UI issues page on GitHub. The author mentions:
... the documentation was ambiguous but validation + settings is passed
like $(".form').form(rules, settings);

It appears like you are trying to recreate the wheel when using semantic ui.
Assuming you have included the complete versions of semantic.css in the head and semantic.js just above the body closing tag, here is an abbreviated version of working code for a simple contact form with some of the error work done by semantic and some by html5. For completeness I have included a user side captcha.
HTML
<form class="ui form" name="contact_sdta" action="" method="post">
<div class="field">
<label>Your Email </label>
<div class="ui left labeled icon input">
<input name="email" id="email" placeholder="name#mail.com" type="email">
<i class="mail icon"></i>
<div class="ui corner label">
<i class="asterisk red icon"></i>
</div>
</div>
</div>
<div class="field">
<label>Subject</label>
<div class="ui left labeled icon input">
<input name="subject" id="subject" placeholder="I am interested in more information about" type="text">
<i class="text file outline icon"></i>
<div class="ui corner label">
<i class="asterisk red icon"></i>
</div>
</div>
</div>
<div class="field">
<label>Message</label>
<div class="ui left labeled icon input">
<textarea name="message"></textarea>
<i class="text file outline icon"></i>
<div class="ui corner label">
<i class="asterisk red icon"></i>
</div>
</div>
</div>
<div class="ui buttons">
<input type="reset" value="Cancel" class="ui button">
<div class="or"></div>
<input type="submit" value="Submit" class="ui blue submit button">
</div>
<div class="ui error message"></div>
</form>
mainjs
$(function(){
$('form input[type=reset]')
.before('<div>Are you a human? <input type="checkbox" name="captcha" /><i class="asterisk red icon"></i></div><br />');
$('.ui.form').form({
email: {
identifier: 'email',
rules: [
{
type: 'empty',
prompt: 'Please enter your email'
}
]
},
subject: {
identifier: 'subject',
rules: [
{
type: 'empty',
prompt: 'Please enter a subject'
}
]
},
message: {
identifier: 'message',
rules: [
{
type: 'empty',
prompt: 'Please enter a message'
}
]
},
human: {
identifier: 'captcha',
rules: [
{
type: 'checked',
prompt: 'You must behuman'
}
]
}
});
});
I hope this helps to clear things up.

The developer confirmed this was a bug on GitHub:
https://github.com/Semantic-Org/Semantic-UI/issues/959

MVC5: Try Add this in the lowermost part of your View
#section Scripts {
#Scripts.Render("~/bundles/jqueryval") }

Related

KnockoutJS Required (ifonly) not being honored when observable changes

I have 2 fields that I need to required based on another field in my model. The first field is functioning as desired, however the second field (similar logic) doesn't honor the required attribute. I have verified that the onlyif code is firing when the observable is changed. However the form allows submission if the required fields are not filled in.
JS Code
//Works As Expected
self.model.RecentLocations.LastDayOnSite.extend({
required: {
onlyIf: function () {
return ((!self.model.RecentLocations.IsLastDayOnSiteNA()) && (self.model.CaseType() != 'Quarantine'));
}
}
});
//Not Requiring Field as expected.
self.model.ContactTracingStartDate.extend = ko.observable().extend({
required: {
onlyIf: function () {
return (self.model.IsContactTracingRequired() == "Y");
}
}
});
HTML Code
//Works As Expected
<div class="col-md-2 form-group">
<i id="lastDayOnSite-asterisk" class="fas fa-asterisk fa-fw" style="font-size: 7px; color:red; vertical-align:super" data-bind="hidden: (model.RecentLocations.IsLastDayOnSiteNA() || model.CaseType() === 'Quarantine')"></i>
<label for="lastDayOnSite-datepicker_nfd">Last Day on Site</label>
<input type="text" class="form-control datepicker_nfd" id="lastDayOnSite-datepicker_nfd" data-bind="value: model.RecentLocations.LastDayOnSite, preventFutureDate: model.RecentLocations.LastDayOnSite, disable: model.RecentLocations.IsLastDayOnSiteNA()" data-emessage="Last Day on Site" placeholder="Date">
</div>
//Not Requiring Field as expected.
<div class="col-md-2 form-group">
<i id="contactTracingStartDate-asterisk" class="fas fa-asterisk fa-fw" style="font-size: 7px; color:red; vertical-align:super" data-bind="visible: (model.IsContactTracingRequired() === 'Y')"></i>
<label for="contactTracingStartDate-datepicker_nfd">Contact Tracing Start Date</label>
<input type="text" class="form-control datepicker_nfd" id="contactTracingStartDate-datepicker_nfd"
data-bind="value: model.ContactTracingStartDate,
preventFutureDate: model.ContactTracingStartDate, enable: (model.IsContactTracingRequired() === 'Y')" data-emessage="Contract Tracing Start Date" placeholder="Date">
</div>
Not Sure what I am missing here but I am fairly new to KnockoutJS but I can't see where the disconnect is. Any Help or suggestions would be appreciated.
The answer is change the line of code
self.model.ContactTracingStartDate.extend = ko.observable().extend({
TO:
self.model.ContactTracingStartDate.extend({
The problem was the observerable was reset by the ko.observable().extend instead of just extending the existing observable.

Multiple submit button fail to find the handler method in asp.net core 3.1 razor page application

I have a single form which has two button one to upload image using ajax call & other is main submit button which saves all the data.
I am still very new to asp.net core and trying different thing to learn asp.net core with razor page.
I read lot of article about multiple form submit but most of then where using two form with submit button for each.
My issue is when i hit the submit button it fails to find the handler method, after full days troubleshoot nothing worked and last few article point to error/failure to antiforgery, i not sure how to implement it in below code as i tried few but they gave error may be article where old referencing core 2.2 etc example1 example2
I am not sure about the what exactly is causing the issue any help would be appreciate.
I am trying to upload Image using Ajax method in asp.net core Razor pages, I am main form in will all input fields are kept and with the form for Fileupload i am also added addition button which is for file upload using Ajax, When i hit the
<input type="submit" value="Upload Image" asp-page-handler="OnPostUploadImage" id="btnUploadImage" />
i want it to call OnPostUploadImage method in pageModel file but it alway goes to default OnPost method. when i rename the OnPost to OnPost2 nothing happend..
How can i call OnPostUploadImage() on button btnUploadImage click event.
When i hit click btnUploadImage it generates following error on browser console
Error in FF
XML Parsing Error: no root element found Location:
https://localhost:44364/Admin/News/NewsCreate?handler=OnPostUploadImage
Line Number 1, Column 1:
Error in Chrome
jquery.min.js:2 POST
https://localhost:44364/Admin/News/NewsCreateMultipleSubmit?handler=OnPostUpLoadImage
400 (Bad Request)
event though path looks fine but it cant find it as per error message
#page
#model BookListRazor.Pages.Admin.News.NewsCreateModel
#{
ViewData["Title"] = "News Create";
Layout = "~/Pages/Shared/_LayoutAdmin.cshtml";
}
<div class="border container" style="padding:30px;">
<form method="post" enctype="multipart/form-data">
<div class="text-danger" asp-validation-summary="ModelOnly"></div>
<input hidden asp-for="News.NewsImage" />
<input id="fileName" hidden value="" />
<div class="form-group row">
<div class="col-2">
<label asp-for="News.NewsHeading"></label>
</div>
<div class="col-10">
<input asp-for="News.NewsHeading" class="form-control" />
</div>
<span asp-validation-for="News.NewsHeading" class="text-danger"></span>
</div>
<div class="form-group row">
<div class="col-2">
<label asp-for="News.NewsImage"></label>
</div>
<div class="col-10">
#*<input asp-for="News.NewsImage" type="file" class="form-control" id="NewsImage">*#
#*Photo property type is IFormFile, so ASP.NET Core automatically creates a FileUpload control *#
<div class="custom-file">
<input asp-for="NewsImageForUpload" class="custom-file-input form-control">
<label class="custom-file-label">Click here to change photo</label>
<input type="submit" value="Upload Image" asp-page-handler="OnPostUploadImage" id="btnUploadImage" />
</div>
</div>
<span id="imageStatus" class="text-danger"></span>
<span asp-validation-for="NewsImageForUpload" class="text-danger"></span>
</div>
<div class="form-group row">
<div class="col-3 offset-3">
<input id="btnSave" type="submit" value="Create" class="btn btn-primary form-control" />
</div>
<div class="col-3">
<a asp-page="Index" class="btn btn-success form-control">Back to List</a>
</div>
</div>
</form>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="https://cdn.ckeditor.com/4.14.0/full/ckeditor.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<script>
$(document).ready(function () {
$("#btnSave").addClass("disable-button");
$('.custom-file-input').on("change", function () {
var fileName = $(this).val().split("\\").pop();
$(this).next('.custom-file-label').html(fileName);
$("#fileName").val(fileName);
$("#btnSave").removeClass("disable-button");
});
if ($("#fileName").val() == "") {
//alert("Select Image...");;
}
});
</script>
</div>
#section Scripts{
<partial name="_ValidationScriptsPartial" />
<script>
$(function () {
$('#btnUploadImage').on('click', function (evt) {
console.log("btnUploadImage");
evt.preventDefault();
console.log("btnUploadImage after evt.preventDefault()");
$.ajax({
url: '#Url.Page("", "OnPostUploadImage")',
//data: new FormData(document.forms[0]),
contentType: false,
processData: false,
type: 'post',
success: function () {
alert('Uploaded by jQuery');
}
});
});
});
</script>
}
.cs file CODE
public async Task<IActionResult> OnPost()
{
if (ModelState.IsValid)
{
return Page();
}
else
{
return Page();
}
}
public IActionResult OnPostUploadImage()
{
//Some code here
}
Verify that you add the following code to the ConfigureServices method of startup.cs:
services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");
If you want to enter the OnPostUploadImage method, the url of the Ajax request needs to be changed to #Url.Page("", "UploadImage") without adding OnPost.
And the Ajax request should send the anti-forgery token in request header to the server.
Change your ajax as follow:
#section Scripts{
<partial name="_ValidationScriptsPartial" />
<script>
$(function () {
$('#btnUploadImage').on('click', function (evt) {
console.log("btnUploadImage");
evt.preventDefault();
console.log("btnUploadImage after evt.preventDefault()");
$.ajax({
url: '#Url.Page("", "UploadImage")',
//data: new FormData(document.forms[0]),
contentType: false,
processData: false,
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
type: 'post',
success: function () {
alert('Uploaded by jQuery');
}
});
});
});
</script>
}
You can refer to this for more details.

$(...).jqBootstrapValidation is not a function at HTMLDocument.<anonymous>

i am trying to implement a contact us page using bootstrap template. I am a really beginner in asp.net and its my first time using a template.
I cant really get it where is the problem that is causing the above error.
I want to when the user click the send Message button to send emails to a current business email.
Can anyone help me?
contact.cshtml
<div class="row">
<div class="col-lg-8 mb-4">
<h3>Send us a Message</h3>
<form name="sentMessage" id="contactForm" novalidate>
<div class="control-group form-group">
<div class="controls">
<label>Full Name:</label>
<input type="text" class="form-control" id="name" required data-validation-required-message="Please enter your name.">
<p class="help-block"></p>
</div>
</div>
<div class="control-group form-group">
<div class="controls">
<label>Phone Number:</label>
<input type="tel" class="form-control" id="phone" required data-validation-required-message="Please enter your phone number.">
</div>
</div>
<div class="control-group form-group">
<div class="controls">
<label>Email Address:</label>
<input type="email" class="form-control" id="email" required data-validation-required-message="Please enter your email address.">
</div>
</div>
<div class="control-group form-group">
<div class="controls">
<label>Message:</label>
<textarea rows="10" cols="100" class="form-control" id="message" required data-validation-required-message="Please enter your message" maxlength="999" style="resize:none"></textarea>
</div>
</div>
<div id="success"></div>
<!-- For success/fail messages -->
<button type="submit" class="btn btn-primary" id="sendMessageButton">Send Message</button>
</form>
</div>
</div>
</div>
<script src="~/Content/vendor/jquery/jquery.min.js"></script>
<script src="~/Scripts/contact_me.js"></script>
<script src="~/Scripts/jqBootstrapValidation.js"></script>
<script src="~/Content/vendor/bootstrap/js/bootstrap.min.js"></script>
contact_me.js
$(function () {
$('#contactForm input,#contactForm textarea').jqBootstrapValidation({
preventSubmit: true,
submitError: function($form, event, errors) {
// additional error messages or events
},
submitSuccess: function($form, event) {
event.preventDefault(); // prevent default submit behaviour
// get values from FORM
var name = $("input#name").val();
var email = $("input#email").val();
var phone = $("input#phone").val();
var message = $("textarea#message").val();
var firstName = name; // For Success/Failure Message
// Check for white space in name for Success/Fail message
if (firstName.indexOf(' ') >= 0) {
firstName = name.split(' ').slice(0, -1).join(' ');
}
$this = $("#sendMessageButton");
$this.prop("disabled", true); // Disable submit button until AJAX call is complete to prevent duplicate messages
$.ajax({
url: "mail/contact_me.php",
type: "POST",
data: {
name: name,
phone: phone,
email: email,
message: message
},
cache: false,
success: function() {
// Success message
$('#success').html("<div class='alert alert-success'>");
$('#success > .alert-success').html("<button type='button' class='close' data-dismiss='alert' aria-hidden='true'>×")
.append("</button>");
$('#success > .alert-success')
.append("<strong>Your message has been sent. </strong>");
$('#success > .alert-success')
.append('</div>');
//clear all fields
$('#contactForm').trigger("reset");
},
error: function() {
// Fail message
$('#success').html("<div class='alert alert-danger'>");
$('#success > .alert-danger').html("<button type='button' class='close' data-dismiss='alert' aria-hidden='true'>×")
.append("</button>");
$('#success > .alert-danger').append($("<strong>").text("Sorry " + firstName + ", it seems that my mail server is not responding. Please try again later!"));
$('#success > .alert-danger').append('</div>');
//clear all fields
$('#contactForm').trigger("reset");
},
complete: function() {
setTimeout(function() {
$this.prop("disabled", false); // Re-enable submit button when AJAX call is complete
}, 1000);
}
});
},
filter: function() {
return $(this).is(":visible");
},
});
$("a[data-toggle=\"tab\"]").click(function(e) {
e.preventDefault();
$(this).tab("show");
});
});
/*When clicking on Full hide fail/success boxes */
$('#name').focus(function() {
$('#success').html('');
});
As my answer morphed through the comments:
the answer was that the OP added Jquery twice making a conflict in
file jqBootstrapValidation.js
Also, to help others based on the OP's post, this next part could be helpful as well:
Javascript files need to be loaded in the order of their dependence. Since your custom javascript file, contact_me.js depends on functions contained in the javascript file, jqBootstrapValidation.js, you need to load jqBootstrapValidation.js before contact_me.js, to fix this switch the order in which these files are loaded:
<script src="~/Content/vendor/bootstrap/js/bootstrap.min.js"></script>
<script src="~/Scripts/jqBootstrapValidation.js"></script>
<script src="~/Content/vendor/jquery/jquery.min.js"></script>
<script src="~/Scripts/contact_me.js"></script>

Any Crud example for Meteor and react with SimpleSchema

I make a simple page where data is inserted into database by a form using Refs of react.Can any body help me out how i can insert the data using aldeed:Simple schema or any curd example using that package.
please check my simple code for insertion.
import React,{Component} from 'react';
import {DoctorsList} from '../../../api/lists/DoctorsList.js';
export class DoctorCreate extends Component
{
addDoctor(event){
event.preventDefault();
var text= this.refs.DoctorName.value.trim();
console.log(text);
DoctorsList.insert({
name:text,
createdAt: new Date(),
owner: Meteor.userId(), // _id of logged in user
username: Meteor.user().username, // username of logged in user
});
this.refs.DoctorName.value="";
}
render()
{
return (
<div className="container">
<div className="row">
<div className="col-sm-12">
<form className="form" onSubmit={this.addDoctor.bind(this)}>
<div className="form-group">
<label> Name</label>
<input ref="DoctorName" type="text" className="form-control" placeholder="name..."/>
</div>
<div className="form-group">
<input type="submit" value="save" className="btn btn-primary"/>
</div>
</form>
</div>
<br/>
<a href="/doctors" >Back to list </a>
<hr/>
</div>
</div>
)
}
}
Thanks in advance.
Meteor official TODOs app is using simple schema. Link to github source https://github.com/meteor/todos/blob/1.3-module-exports/imports/api/lists/methods.js

Meteor: No context for #each loop event handlers

I'm using an #each loop with an unmanaged local collection to generate a sequence of input fields for a form. However, when I try to use this._id in the event handler it is undefined. In fact, the context being passed to the event handler is for the window. Any help to find what is going wrong and how I should be getting the proper context as this within my event handler is much appreciated.
The code is:
<h4 class="page-header">Children on this account</h4>
{{#each children}}
<div id={{_id}} class="form-group col-md-12 child-form-instance">
<div class="form-group col-sm-5 col-xs-12">
<input type="text" name="childFirstName" class="form-control" placeholder="Child's First Name">
</div>
<div class="form-group col-sm-5 col-xs-10">
<input type="text" name="childLastName" class="form-control" placeholder="Child's Last Name" value="{{_id}}">
</div>
<div class="form-group col-xs-2">
<button type="button" class="btn btn-danger remove-child" aria-label="remove child">
<span class="glyphicon glyphicon-trash"></span>
</button>
</div>
</div>
{{/each}}
<div class="form-group">
<input type="button" id="addChild" class="btn btn-success" value="Add child">
</div>
and the js:
var children = new Mongo.Collection(null);
Template.signup.onRendered( () => {
Modules.client.signupValidateSubmit({
form: "#signup",
template: Template.instance()
});
children.remove({});
children.insert({}); //create one empty child
});
Template.signup.events({
'submit form': ( event ) => event.preventDefault(),
'click #addChild': () => {
children.insert({});
console.log(children.find().fetch());
},
'click .remove-child': () => {
console.log(this);
}
});
Template.signup.helpers({
children () {
return children.find();
}
});
Everything is working fine with the addChild button, and the _ids are getting properly assigned in the DOM, but the remove-child class is logging the window context.
You are using ES6 arrow functions which will lexically bind this with the parent scope. As a consequence, you don't get the scope of children.
In order to solve the issue, just change the template event to:
Template.signup.events({
// ...
'click .remove-child': function (event, template) {
console.log(this);
}
// ...
});

Resources