I've looked for tutorials about AutoForm's custom field templates but I'm not sure where I'm going wrong with mine. If anyone has any suggestions it would be greatly appreciated.
My Schema: One field is an Array of Objects.
guests: {
type: Array,
minCount: 1,
maxCount: 10,
label: "Guests in Party"
},
"guests.$": {
type: Object,
label: "Guest Object"
},
"guests.$.firstName": {
type: String,
label: "First Name"
},
"guests.$.lastName": {
type: String,
label: "Last Name"
}
Template Code:
<template name='afArrayField_guestsObjectField'>
{{#afEachArrayItem name="guests" minCount="this.atts.minCount" maxCount="this.atts.maxCount"}}
<div class="form-group">
<label class="control-label col-sm-2">Guest</label>
{{> afObjectField name="this.name" label="false" template='customObjectField'}}
<div class="col-sm-2">
{{#if afArrayFieldHasLessThanMaximum name="guests"}}
<button type="button" class="btn btn-primary autoform-add-item" data-autoform-field="{{guests}}" data-autoform-minCount="{{this.atts.minCount}}" data-autoform-maxCount="{{this.atts.maxCount}}"><span class="glyphicon glyphicon-plus"></span></button>
{{/if}}
{{#if afArrayFieldHasMoreThanMinimum name="guests"}}
<button type="button" class="btn btn-primary autoform-remove-item pull-left"><span class="glyphicon glyphicon-minus"></span></button>
{{/if}}
</div>
</div>
{{/afEachArrayItem}}
</template>
<template name="afObjectField_customObjectField">
<div class="col-sm-4">
{{> afFieldInput name="this.firstName" class="form-control" placeholder="First Name"}}
{{#if afFieldIsInvalid name='this.firstName'}}
<span class="help-block">{{{afFieldMessage name='this.firstName'}}}</span>
{{/if}}
</div>
<div class="col-sm-4">
{{> afFieldInput name="this.lastName" class="form-control" placeholder="Last Name"}}
{{#if afFieldIsInvalid name='this.lastName'}}
<span class="help-block">{{{afFieldMessage name='this.lastName'}}}</span>
{{/if}}
</div>
</template>
The problem I am having is that the plus buttons shows up after the firstName and lastName field how I want it to, but when I press it another guest object (in the form) does not generate. Any thoughts?
Related
I'm using vue 3 with vee-validate:
package.json file
"vee-validate": "^4.7.3",
Code
...
...
...
<ValidationObserver ref="form" v-slot="{ passes }">
<form #submit.prevent="passes(onSubmit)">
<h1>Login</h1>
<p class="text-medium-emphasis">Sign In to your account</p>
<div class="mb-3">
<div class="input-group ">
<ValidationProvider vid="email" name="email" v-slot="{ errors }">
<input v-model="email" placeholder="Email" name="email" autocomplete="Email" class="form-control">
<div class="error-message">{{ errors[0] }}</div>
</ValidationProvider>
</div>
</div>
<div class="mb-4">
<div class="input-group ">
<ValidationProvider vid="password" name="password" v-slot="{ errors }">
<input v-model="password" placeholder="Password" name="password" autocomplete="current-password" class="form-control" type="password">
<span>{{ errors[0] }}</span>
</ValidationProvider>
</div>
</div>
<div class="row">
<div class="col-6">
<button class="btn btn-primary px-4">Sign in</button>
</div>
<div class="col-6 text-right">
<button class="btn btn-link px-0" type="button"> Forgot password? </button>
</div>
</div>
</form>
</ValidationObserver>
...
...
...
<script>
import { Form, Field, ErrorMessage, ValidationProvider,
ValidationObserver } from "vee-validate";
export default {
components: { Form, Field, ErrorMessage, ValidationProvider, ValidationObserver },
...
...
...
But has warning:
export 'ValidationObserver' (imported as 'ValidationObserver') was not found in 'vee-validate' (possible exports: ErrorMessage, Field, FieldArray, FieldContextKey, Form, FormContextKey, IS_ABSENT, configure, defineRule, useField, useFieldArray, useFieldError, useFieldValue, useForm, useFormErrors, useFormValues, useIsFieldDirty, useIsFieldTouched, useIsFieldValid, useIsFormDirty, useIsFormTouched, useIsFormValid, useIsSubmitting, useResetForm, useSubmitCount, useSubmitForm, useValidateField, useValidateForm, validate)
And in console:
Has anyone had the same situation as me?
None of that stuff is in Vee-Validate version 4.7.3. You need to use an older version if you want ValidationObserver and ValidationProvider. Try this:
"vee-validate": "^3.1.0",
I want to create a form that shows different sections depending on which template it belongs to. I want the data that the user enters to be reactive: if the user changes from one template to another, her previous entries should still be visible. I plan to create a "form" template, so that I can have a single Template.form.events function that will set the appropriate Session variables as the form is filled in.
My question is about how to populate the form dynamically. Here's how I've attempted to go about this, but all the fields appear all the time.
<body>
{{> form1}}
{{> form2}}
<h1>Log in</h1>
{{> form name=1 password=1}}
</body>
<template name="form1">
{{#form name=1 species=1}}
<h1>Form 1</h1>
{{/form}}
</template>
<template name="form2">
<h1>Form 2</h1>
{{>form name=1 planet=1 asMenu=1}}
</template>
<template name="form">
{{#if name=1}}
<input type="text" name="name" placeholder="Name" value="">
{{/if}}
{{#if species=1}}
<input type="text" name="species" placeholder="Species" value="">
{{/if}}
{{#if planet=1}}
{{#if asMenu=1}}
<select name="">
<option value="Erth">Erth</option>
<option value="Othr">Othr</option>
</select>
{{else}}
<input type="text" name="planet" placeholder="Planet" value="">
{{/if}}
{{/if}}
{{#if password=1}}
<input type="password" name="password" value="">
{{/if}}
<br />
<button type="submit">Submit</button>
</template>
Can you help me to understand how to resolve this?
Firstly spacebars doesn't support comparisons so {{#if var=1}} is invalid syntax. However 1 is true so I'm going to take advantage of that to replace {{#if name=1}} with {{#if name}}:
<body>
{{> form1}}
{{> form2}}
<h1>Log in</h1>
{{> form name=1 password=1}}
</body>
<template name="form1">
<h1>Form 1</h1>
{{>form name=1 species=1}}
</template>
<template name="form2">
<h1>Form 2</h1>
{{>form name=1 planet=1 asMenu=1}}
</template>
<template name="form">
{{#if name}}
<input type="text" name="name" placeholder="Name" value="">
{{/if}}
{{#if species}}
<input type="text" name="species" placeholder="Species" value="">
{{/if}}
{{#if planet}}
{{#if asMenu}}
<select name="">
<option value="Erth">Erth</option>
<option value="Othr">Othr</option>
</select>
{{else}}
<input type="text" name="planet" placeholder="Planet" value="">
{{/if}}
{{/if}}
{{#if password}}
<input type="password" name="password" value="">
{{/if}}
<br />
<button type="submit">Submit</button>
</template>
I am writing a simple meteor app and finding that IntelliJ IDEA 14.1.4 (with the Meteor and Handlebars plugins installed and enabled) does not recognize spacebars templates:
After googling, I tried File > Invalidate Caches/Restart but this did not work.
I also find that when I run Code > Reformat Code, the resulting indentation is not correct. I assume both problems are related.
Here is an even simpler illustration of the problem:
How can I debug this?
Finally, I find the really tricky syntax error in my IntelliJ IDEA 14.
The main problem is the space between {{ and # or /.
{{#if currentUser}} is right in syntax but {{ #if currentUser }} is wrong.
Alike, user {{/if}} instead of {{ /if }}.
So the spacebars usage is really strict here. Actually, there should be no extra spaces.
<template name="home">
{{#if currentUser}}
<div class="template-home">
<div class="well">
<form class="form-inline syllabus-chooser">
<div class="form-group">
<select name="syllabusChooser" id="syllabusChooser" class="form-control">
<option value="0">(Select a syllabus to edit)</option>
{{#each syllabusSelectors}}
<option value="{{ value }}">{{ label }}</option>
{{/each}}
</select>
</div>
<button type="submit" id="syllabusChooserButton" class="btn btn-default">Edit</button>
</form>
</div>
{{#if displayID}}
<div class="well">
{{#autoForm collection="Syllabuses" doc=selectedSyllabusDoc id="insertSyllabusForm" type="update"}}
<fieldset>
<div class="row">
<div class="col-sm-2">{{> afQuickField name='alphaNumber' placeholder="ICS 101"}}</div>
<div class="col-sm-2">{{> afQuickField name='creditHours' placeholder="3"}}</div>
<div class="col-sm-2">{{> afQuickField name='prerequisites' placeholder="311 or consent"}}</div>
<div class="col-sm-6">{{> afQuickField name='title' placeholder="Course title"}}</div>
</div>
<div class="row">
<div class="col-sm-6">{{> afQuickField name='instructor' rows=2 placeholder="Name\noffice address, email"}}</div>
<div class="col-sm-6">{{> afQuickField name='textbooks' rows=2 placeholder= "Textbook title and author, or 'none'"}}</div>
</div>
<div class="row">
<div class="col-sm-6">{{> afQuickField name='objectives' rows=4 placeholder='* Students have ...\n* Students can ...\n* Students can ....'}}</div>
<div class="col-sm-6">{{> afQuickField name='policies' rows=4 placeholder="Can be 'none'."}}</div>
</div>
<div class="row">
<div class="col-sm-6">{{> afQuickField name='description' rows=4 placeholder='Insert course catalog description: http://www.catalog.hawaii.edu/courses/departments/ics.htm'}}</div>
<div class="col-sm-6">{{> afQuickField name='grading' rows=4 placeholder="5 homework assignments (10% each)\n1 midterm (15%)\n1 final exam (15%)\n1 final project (20%)"}}</div>
</div>
<div class="row">
<div class="col-sm-6">{{> afFormGroup name='learningOutcomes' type="select-checkbox"}}</div>
<div class="col-sm-6">
{{> afQuickField name='courseLearningOutcomes' rows=12 placeholder="* Learning Outcome 1\n* Learning outcome 2"}}
{{> afQuickField name='schedule' rows=12 placeholder="Week 1: ...\nWeek 2: ...\nWeek 3: ..."}}
</div>
</div>
</fieldset>
<button type="submit" class="btn btn-default btn-success btn-block">Save</button>
{{/autoForm}}
</div>
{{/if}}
</div>
<div class="well" style="padding: 0; max-height: 100px; overflow-y: auto">
<ul>
{{#each editStatusList}}
<li>Started editing {{ syllabusName }} {{ editTimestamp }} {{#if editFinished}} ... finished. {{/if}} </li>
{{/each}}
</ul>
</div>
{{/if}}
</template>
I have implemented the following code from insert autoform
Schemas = {};
Template.registerHelper("Schemas", Schemas);
Schemas.Person = new SimpleSchema({
firstName: {
type: String,
index: 1,
unique: true
},
lastName: {
type: String,
optional: true
},
age: {
type: Number,
optional: true
}
});
var Collections = {};
Template.registerHelper("Collections", Collections);
People = Collections.People = new Mongo.Collection("People");
People.attachSchema(Schemas.Person);
Meteor.publish(null, function () {
return People.find();
});
People.allow({
insert: function () {
return true;
},
remove: function () {
return true;
}
});
{{#autoForm id="afInsertDemo" type="insert" collection=Collections.People}}
<div class="form-group {{#if afFieldIsInvalid name='firstName'}}has-error{{/if}}">
<label class="control-label">{{afFieldLabelText name='firstName'}}</label>
{{> afFieldInput name='firstName'}}
{{#if afFieldIsInvalid name='firstName'}}
<span class="help-block">{{{afFieldMessage name='firstName'}}}</span>
{{/if}}
</div>
<div class="form-group {{#if afFieldIsInvalid name='lastName'}}has-error{{/if}}">
<label class="control-label">{{afFieldLabelText name='lastName'}}</label>
{{> afFieldInput name='lastName'}}
{{#if afFieldIsInvalid name='lastName'}}
<span class="help-block">{{{afFieldMessage name='lastName'}}}</span>
{{/if}}
</div>
<div class="form-group {{#if afFieldIsInvalid name='age'}}has-error{{/if}}">
<label class="control-label">{{afFieldLabelText name='age'}}</label>
{{> afFieldInput name='age'}}
{{#if afFieldIsInvalid name='age'}}
<span class="help-block">{{{afFieldMessage name='age'}}}</span>
{{/if}}
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Add Person</button>
<button type="reset" class="btn btn-default">Reset Form</button>
</div>
{{/autoForm}}
Database entries are not being created, where am I going wrong.
Added this to 2_collections.js in common folder and it works fine.
People.allow({
insert: function () {
return true;
},
remove: function () {
return true;
}
lets say I have the following markup:
<div class="fild-group">
<label for="form-users">User</label>
<button type="button" class="inactive btn btn-default" data-id="form-users"><span>Select an User</span></button>
</div>
<div class="fild-group to-hide">
<label for="form-projects">Projects</label>
<button type="button" class="inactive" data-id="form-projects"><span>Select a Project</span></button>
</div>
<div class="fild-group to-hide">
<label for="form-parallel-env">Parallel Environment</label>
<button type="button" class="inactive" data-id="form-parallel-env"><span>Select a PE</span></button>
</div>
<div class="fild-group to-hide">
<label for="form-start-date">Start Date</label>
<button type="button" class="inactive" data-id="date1"><span>Select a Date</span></button>
</div>
<div class="fild-group to-hide">
<label for="form-end-date">End Date</label>
<button type="button" class="inactive" data-id="date2"><span>Select a Date</span></button>
</div>
<div class="fild-group to-hide">
<label for="form-no-slots">Number of slots</label>
<button type="button" class="inactive btn" data-id="form-slots"><span>Slots</span></button>
<input type="number" class="form-control" id="form-no-slots" min="1" max="9999">
</div>
depending on where the user is I would like to show some, all or none of these div.fild-group so I was thinking to create ONLY one template like this
<template name="first-line-button">
<div class="fild-group">
<label for="{{ id }}">{{ label }}</label>
<button type="button" class="inactive btn btn-default " data-id="{{ data }}"><span>{{ message }}</span></button>
</div>
</template>
but so far I know how to use that template for one thing at the time, so the question is how can I use this single template for multiple things at the same time???
thanks in advance!
You need to provide a data context for the template to render. You can do that individually, or pass an array of button data.
Template.parent.formUsers = function () {
return {
id: "for-users",
label: "User",
message: "Select a User"
}
};
or
Template.parent.formButtons = function () {
return [{
id: "form-users",
label: "User",
message: "Select a User"
}, {
id: "form-projects",
label: "Projects",
message: "Select a Project"
}, {
...
}]
};
And the parent template would have this in it somewhere.
{{> first-line-button formUsers}}
or
{{#each formButtons}}
{{> first-line-button}}
{{/each}}