I tried it also with the "Form initialValues={system}" but the Input fields are still empty. My object has only string values.
Why cant the setFieldsValue or the initialValues read my object?
const ResetFields = () => {
form.resetFields();
form.setFieldsValue({
'name': 'Test', //working
'street': system.street, //not working (type is string)
houseNumber: system.houseNumber, //not working (type is string)
postCode: system.postCode,
city: system.city
});
}
return (
<div>
<Form
{...layout}
size={"large"}
form={form}
validateTrigger="submit"
onReset={ResetFields}
onFinish={Submit}
validateMessages={validateMessages}
>
<Form.Item
name='name'
label="Name"
rules={[{ required: true }]}
>
<Input autoComplete="off" />
</Form.Item>
//More Form.Item and Buttons Submit and Reset...
</Form>
</div>
);
I had a similar issue, try this. maybe that will help.
'street': system?.street
Related
Q: If the value in one dropdown changed, how to reload the values for the second dropdown?
When user change the category dropdown, then I want to show the subcategory in the dropdown
Frontend: VueJs (v3)
Server Side Rendering: IneratiaJs
Backend: Laravel (v9)
VueComponent
const props = defineProps({
errors: Object,
categories: Object,
subcategories: Object,
})
const form = useForm({
category_id: '',
subcategory_id: '',
name: '',
price: '',
discount: '',
image: 'sample',
description: ''
});
let getSubcategory = (event) => {
if(event.target.value !== "") {
Inertia.reload({
'category_id': event.target.value
},
{ only: ['subcategories'],
onSuccess: page => {
alert();
console.log('onSuccess');
console.log(props.categories);
console.log(props.subcategories);
console.log(page);
}
}
);
}
}
const submit = () => {
form.post(route('store.subcategory'), {
onFinish: () => form.reset(),
});
};
Vue Template
<template>
<Head title="Add Product" />
<BreezeAuthenticatedLayout>
<template #header>
<form #submit.prevent="submit">
<div class="mt-4">
<BreezeLabel for="category_id" value="Category Name" />
<select #change="getSubcategory" v-model="form.category_id" id="category_id" class="block mt-1 w-full">
<option value="">Select Category</option>
<option v-for="category in categories" :value="category.id">{{ category.name }}</option>
</select>
<div v-if="errors.category_id" class="text-red-400">
{{ errors.category_id }}
</div>
</div>
<div class="mt-4">
<BreezeLabel for="subcategory_id" value="Subcategory Name" />
<select v-model="form.subcategory_id" id="subcategory_id" class="block mt-1 w-full">
<option value="">Select Sategory</option>
<option v-for="subcategory in subcategories" :value="subcategory.id">{{ subcategory.name }}</option>
</select>
<div v-if="errors.subcategory_id" class="text-red-400">
{{ errors.subcategory_id }}
</div>
</div>
</form>
</BreezeAuthenticatedLayout>
</template>
Laravel Route: routes/web.php
Route::get('/create/product/{category_id?}', [ProductController::class, 'create'])->name('create.product'); //Form: Create Product
Product Controller: ProductController.php
public function create($category_id = null)
{
return Inertia::render('Product/Create', [
//I want Evaluated immediately on Page Load.
'categories' => $categories = Category::all(),
//Want Lazy load here.
'subcategories' => function(){
if(!empty($category_id)){
$category = Category::find($category_id);
$subcategories = $category->subcategories()->get();
}
},
]);
}
After fixing Create method in Product Controller and script setup it's working
public function create($category_id = null)
{
return Inertia::render('Product/Create', [
// ALWAYS included on first visit - OPTIONALLY included on partial reloads - ALWAYS evaluated
'categories' => Category::has('subcategories')->get(),
// NEVER included on first visit - OPTIONALLY included on partial reloads - ONLY evaluated when needed
'subcategories' => Inertia::lazy(fn () =>
Subcategory::with('category')->where('category_id', '=', $category_id)->get()
),
]);
}
Vue SCRIPT: I was sending wrong parameters. Then I saw correct way of partial relaod on official site
let getSubcategory = (event) => {
if(event.target.value !== "") {
Inertia.visit(
route('create.product', {
category_id: event.target.value
}),{
only: ['subcategories'],
preserveState: true,
preserveScroll: true,
}
);
}
}
i have a password and password confirm field, which is connected using a directive. beside that i have css that set border color when ng-invalid. the issue is that when i for instance enter the confirm_password first and then same in password it does not remove the 'ng-invalid'. is there a way to tell angular to update other fields classes when editing password?
html
<div class="form-group">
<label>Adgangskode</label>
<input type="password" class="form-control" name="password"
ng-model="vm.password" ng-minlength="6" ng-maxlength="24"
placeholder="Din adgangskode"
equals="vm.confirm_password" required>
<p ng-show="SignUp.password.$invalid
&& (SignUp.password.$dirty || vm.submitted)"
class="help-block ng-binding" style="">Adgangskode er invalid.</p>
</div>
<div class="form-group">
<label>Adgangskode bekræftelse</label>
<input type="password" class="form-control" name="confirm_password"
ng-model="vm.confirm_password"
ng-minlength="6" ng-maxlength="24"
ng-model="vm.confirm_password"
placeholder="Bekræft din adgangskode"
required nx-equal="vm.password">
<p ng-show="SignUp.confirm_password.$error.nxEqual
&& (SignUp.confirm_password.$dirty || vm.submitted)"
class="help-block ng-binding">Adgangskoderne er ikke ens.</p>
</div>
css
input.ng-dirty.ng-invalid {
border-color: #a94442;
}
.ng-submitted input.ng-invalid {
border-color: #a94442;
}
directive funciton
function ComparePassword() {
return {
require: 'ngModel',
link: function (scope, elem, attrs, model) {
if (!attrs.nxEqual) {
console.error('nxEqual expects a model as an argument!');
return;
}
scope.$watch(attrs.nxEqual, function (value) {
model.$setValidity('nxEqual', value === model.$viewValue);
});
model.$parsers.push(function (value) {
var isValid = value === scope.$eval(attrs.nxEqual);
model.$setValidity('nxEqual', isValid);
return isValid ? value : undefined;
});
}
}
}
Have the compare directive watch the other field:
app.directve("compareTo", compareTo);
function compareTo() {
return {
require: "ngModel",
link: function(scope, elem, attrs, ngModel) {
ngModel.$validators.compareTo = function(modelValue) {
return modelValue == scope.$eval(attrs.compareTo);
};
scope.$watch(attrs.compareTo, function() {
ngModel.$validate();
});
}
};
}
Usage:
<form name="form1">
<input type="password" name="password" required
ng-model="user.password" />
<input type="password" name="confirmPassword" required
ng-model="user.confirmPassword" compare-to="user.password" />
</form>
<div ng-show="form1.comfirmPassword.$error.compareTo">
Error: Password entries must match
</div>
Think carefully about double entry
Double entry:
increases the workload for every single user;
can be bypassed by copying and pasting, or automatic form-filling tools;
only ensures the two fields match, not that they contain the valid information;
and
may be seen as belittling the user;
Alternatives to double entry are worth serious consideration. These alternatives include authentication and/or simple methods of reset or recovery.
— Formulate Information Design Blog - Double entry of form fields
Currently I'm working on a project based on Meteor as back end and React as front end. I really enjoyed simplicity untill I removed insecure package and have to deal with Meteor methods. Right now I need to perform a basic insert operation and I'm just stucked!
I have a form as component (in case eventually I'd like to use this form not only for inserting items but for editing those items as well) and here's my code for this form:
AddItemForm = React.createClass({
propTypes: {
submitAction: React.PropTypes.func.isRequired
},
getDefaultProps() {
return {
submitButtonLabel: "Add Item"
};
},
render() {
return (
<div className="row">
<form onSubmit={this.submitAction} className="col s12">
<div className="row">
<div className="input-field col s6">
<input
id="name"
placeholder="What"
type="text"
/>
</div>
<div className="input-field col s6">
<input
placeholder="Amount"
id="amount"
type="text"
/>
</div>
</div>
<div className="row">
<div className="input-field col s12">
<textarea
placeholder="Description"
id="description"
className="materialize-textarea">
</textarea>
</div>
</div>
<div className="row center">
<button className="btn waves-effect waves-light" type="submit">{this.props.submitButtonLabel}</button>
</div>
</form>
</div>
);
}
});
This chunk of code is used as a form component, I have a prop submitAction which I use in let's say add view:
AddItem = React.createClass({
handleSubmit(event) {
event.preventDefault();
const
name = $('#name').val(),
amount = $('#amount').val(),
description = $('#description').val();
Items.insert(
{
name: name,
range: range,
description: description,
createdAt: new Date(),
ownerId: Meteor.userId()
},
function(error) {
if (error) {
console.log("error");
} else {
FlowRouter.go('items');
};
}
);
},
render() {
return (
<div className="row">
<h1 className="center">Add Item</h1>
<AddItemForm
submitButtonLabel="Add Event"
submitAction={this.handleSubmit}
/>
</div>
);
}
});
As you can see I directly grab values by IDs then perform insert operation which works absolutely correct, I can even get this data displayed.
So now I have to remove insecure package and rebuild the whole operation stack using methods, where I actually stucked.
As I understand all I should do is to grab same data and after that perform Meteor.call, but I don't know how to pass this data correctly into current method call. I tried considering this data right in the method's body which doesn't work (I used the same const set as in AddItem view). Correct me if I'm wrong, but I don't think this method knows something about where I took the data (or may be I don't really get Meteor's method workflow), so by this moment I ended up with this code as my insert method:
Meteor.methods({
addItem() {
Items.insert({
name: name,
amount: amount,
description: description,
createdAt: new Date(),
ownerId: Meteor.userId()
});
}
});
and this is how I changed my handleSubmit function:
handleSubmit(event) {
event.preventDefault();
const
name = $('#name').val(),
amount = $('#amount').val(),
description = $('#description').val();
Meteor.call('addItem');
},
Also I tried declaring method like this:
'addItem': function() {
Items.insert({
// same code
});
}
but it also didn't work for me.
Again, as I understand the problem isn't about data itself, as I wrote before it works just right with insecure package, the problem is how the heck should I get this data on the server first and right after that pass this to the client using methods (also console gives no even warnings and right after I submit the form, the page reloads)?
I've already seen some tutorials and articles in the web and didn't find desicion, hope to get help here.
You can add your data as parameters in your Meteor call function. You can also add a callback function to check on the success of the call.
handleSubmit(event) {
event.preventDefault();
const
name = $('#name').val(),
amount = $('#amount').val(),
description = $('#description').val();
Meteor.call('addItem', name, amount, description, function(err, res) {
if (err){
console.log(JSON.stringify(err,null,2))
}else{
console.log(res, "success!")
}
});
},
In your Meteor methods:
Meteor.methods({
addItem(name, amount, description) {
var Added = Items.insert({
name: name,
amount: amount,
description: description,
createdAt: new Date(),
ownerId: Meteor.userId()
});
return Added
}
});
I have a form in which I have 2 fields, ssn and phone. I would like the user to enter anyone of the field. I'm using semantic validation, here is my code, can you please let me know how to validate the form using Semantic?
<form class="ui error form basic segment" role="form" method="POST" action="{{ url('/username/email') }}">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<input type="hidden" name="_method" value="patch">
<div class="ui info message">
Please enter either SSN or phone to email you the username.
</div>
<div class="field">
<label for="ssn">SSN</label>
<div class="ui icon input">
<input type="text" class="form-control" name="ssn" value="{{ old('ssn') }}">
</div>
</div>
<div class="field">
<label for="phone">Phone</label>
<div class="ui icon input">
<input type="text" class="form-control" name="phone" value="{{ old('phone') }}">
</div>
</div>
<input type="submit" value="Email Username" class="ui primary button">
</form>
<script type="text/javascript">
$('.ui.form')
.form({
inline : true,
on: 'blur',
fields: {
username: {
identifier : 'ssn',
rules: [
{
type : 'empty',
prompt : 'Please enter a SSN'
}
]
},
}
})
;
</script>
`
Here's a little bit more elegant solution that follows Semantic UI fields identification standard.
Field could be identified not only via input[name="…"] CSS selector offered in Oniisaki's accepted answer, but also by DOM element id or data-validation attribute:
/**
* Checks whether current field value or at least one of additionally
* given fields values is not empty, neither blank string.
* #param {string} value Current field value.
* #param {string} fieldIdentifiers Comma separated field identifiers.
* #return {boolean}
*/
$.fn.form.settings.rules.allEmpty = function(value, fieldIdentifiers) {
var $form = $(this);
return !!value || fieldIdentifiers.split(',').some(function(fieldIdentifier) {
return $form.find('#' + fieldIdentifier).val() ||
$form.find('[name="' + fieldIdentifier +'"]').val() ||
$form.find('[data-validate="'+ fieldIdentifier +'"]').val();
});
};
// Using newly created custom validation rule.
// Notice how multiple fields are defined, if required.
$('.ui.form').form({
ssn: {
identifier: 'ssn',
rules: [{
// Multiple field identifiers could be defined,
// like `allEmpty[phone,email,skype]`.
type: 'allEmpty[phone]',
prompt: 'SSN or Phone (at least one field) must be filled.'
}]
}
});
I would create a Semantic UI custom validation function that accepts parameters for your purpose.
Here's the link: http://jsfiddle.net/owcfuhtq/
The code:
$(document).ready(function(){
// function to check if at least one text is not empty for a collection of elements
// text is the value of the input device
// csv is the argument as string. It's the string inside "[" and "]"
$.fn.form.settings.rules.isAllEmpty = function(text,csv){
//If the text of the field itself isn't empty, then it is valid
if (text)
return true;
var array = csv.split(','); // you're separating the string by commas
var isValid = false; // return value
$.each(array,function(index,elem){
// for each item in array, get an input element with the specified name, and check if it has any values
var element = $("input[name='"+elem+"']");
//If element is found, and it's value is not empty, then it is valid
if (element && element.val())
isValid = true;
});
return isValid;
};
var formValidationRules =
{
ssn: {
identifier: 'ssn',
rules: [{
type: "isAllEmpty[phone]",
//If you got additional fields to compare, append it inside the [] with a "," separator
//E.g. isAllEmpty[field1, field2]
prompt: 'An error occurred'
}]
}
}
$('.ui.form').form(formValidationRules);
});
If you want to include select box you can use it sth like this :
$.fn.form.settings.rules.isAllEmpty = function (text, csv) {
if (text) {
return true;
}
var array = csv.split(',');
var isValid = false;
$.each(array, function (index, elem) {
var element = $("input[name='" + elem + "']");
if (element.length == 0) {
element = $("select[name='" + elem + "']")
}
if (element && element.val()) {
isValid = true;
}
});
return isValid;
};
I'm using MVC4,Kendo tabstrip along with jQuery Tooltipster for showing validation messages.
My issue is the validation message from Tab 1 is getting overlapped on Tab 2 due to z-index. I have tried setting z-index for tooltipster-base but isn't working.
My HTML code looks like something this:
<div id="tabstrip">
<ul>
<li>Tab 1</li>
<li>Tab 2</li>
</ul>
<div><form id="myform">
<input type="text" name="field1" />
<input type="text" name="field2" />
<br/>
<input type="submit" />
</form></div>
<div><form id="myform2">
<input type="text" name="field3" />
<input type="text" name="field4" />
<br/>
<input type="submit" />
</form></div>
</div>
Script:
$(document).ready(function () {
var tabstrip = $("#tabstrip").kendoTabStrip().data("kendoTabStrip");
tabstrip.select(0);
// initialize tooltipster on text input elements
$('#myform input[type="text"]').tooltipster({
trigger: 'custom',
onlyOne: false,
position: 'right'
});
$('#myform2 input[type="text"]').tooltipster({
trigger: 'custom',
onlyOne: false,
position: 'right'
});
// initialize validate plugin on the form
$('#myform').validate({
errorPlacement: function (error, element) {
$(element).tooltipster('update', $(error).text());
$(element).tooltipster('show');
},
success: function (label, element) {
$(element).tooltipster('hide');
},
rules: {
field1: {
required: true,
email: true
},
field2: {
required: true,
minlength: 5
}
},
submitHandler: function (form) { // for demo
alert('valid form');
return false;
}
});
// initialize validate plugin on the form2
$('#myform2').validate({
errorPlacement: function (error, element) {
$(element).tooltipster('update', $(error).text());
$(element).tooltipster('show');
},
success: function (label, element) {
$(element).tooltipster('hide');
},
rules: {
field3: {
required: true,
email: true
},
field4: {
required: true,
minlength: 5
}
},
submitHandler: function (form) { // for demo
alert('valid form');
return false;
}
});
});
Please check this:
JSFiddle: http://jsfiddle.net/vishalvaishya/bCZWd/2/
Please help me for setting proper css style.
Found solution myself only. Might be helpful for someone.
Done some updation in tooltipster logic.
Added extra option (appendTo) to place tooltip over specific element only:
c = {
animation: "fade",
appendTo: "body",
arrow: true,
...
And changed parameter of tooltipster.appendTo('body') in showTooltip function like;
tooltipster.appendTo($(l.options.appendTo));
Usage:
$('#profileForm input[type="text"]').tooltipster({
trigger: 'custom',
onlyOne: false,
position: 'right',
appendTo: '#profileForm'
});
Like this you can use tooltipster on different kendo-tabs or on different divs.
See on JSFiddle:
Previous : http://jsfiddle.net/vishalvaishya/bCZWd/2/
Working : http://jsfiddle.net/vishalvaishya/bCZWd/3/