Create autocomplete box in Syncfusion - syncfusion

How to create autocomplete box when edit mode is inlineFormTemplate
for eg:
<script id="template" type="text/template">
<input type="text" name="test" value="{{:test}}"/>
//here i need autocomplete textbox like this
<ej-autocomplete id="search1" filter-type="Contains" highlight-search="true" show-rounded-corner="true" enable-auto-fill="true"
enable-distinct="true" show-popup-button="true" watermark-text="Country name" items-count="20" min-character="2"
width="150" popup-width="500px" popup-height="250px"
template="<div width='5%'>${CountryName} ${CountryId}</div>">
<e-autocomplete-fields key="CountryId" text="CountryName" />
<e-datamanager adaptor="UrlAdaptor" url="/country/SelectCountry"></e-datamanager>
</ej-autocomplete>
</script>

We would like to inform you that, In Asp.Net Core, control has been rendered initially. When using the render Template concepts, the control will not be created. To handle this, we have achieved your requirement by rendering the Autocomplete control from client side.Please find code of the sample in the Grid to use the Autocomplete in a Grid column when Editing.
Code:
<ej-grid id="Edittemplate" allow-paging="true">
<e-datamanager url="//mvc.syncfusion.com/Services/Northwnd.svc/Orders/?$top=45" offline="true"></e-datamanager>
<e-edit-settings allow-adding="true" allow-deleting="true" allow-editing="true" edit-mode="Normal" />
<e-toolbar-settings show-toolbar="true" toolbar-items='new List<string>() { "add", "edit", "delete", "update", "cancel", "search" }' />
<e-columns>
<e-column field="OrderID" is-primary-key="true" header-text="Order ID" text-align="Right" width="70"></e-column>
<e-column field="CustomerID" header-text="Customer ID" width="80">
<e-edit-template create="create" read="read" write="write"></e-edit-template>
</e-column>
<e-column field="EmployeeID" header-text="Employee ID" text-align="Left" width="75"></e-column>
<e-column field="Freight" header-text="Freight" text-align="Right" format="{0:C2}" width="75"></e-column>
<e-column field="OrderDate" header-text="Order Date" text-align="Right" width="80" format="{0:MM/dd/yyyy}"></e-column>
<e-column field="ShipCity" header-text="Ship City" width="110"></e-column>
</e-columns>
</ej-grid>
<script type="text/javascript">
function create() {
return $("<input>");
}
function write(args) {
obj = $('#Edittemplate').ejGrid('instance');
args.element.ejAutocomplete({
width: "100%", dataSource: obj.model.dataSource,
query: ej.Query().from("Suppliers").select("CustomerID"),
filterType: "contains",
multiColumnSettings: {
stringFormat: "{0} ({2}) ({1})",
enable: true,
showHeader: true,
columns: [{
field: "CustomerID",
headerText: "CustomerID",
},
{
field: "OrderID",
headerText: "OrderID"
},
{
field: "EmployeeID",
headerText: "EmployeeID"
},
{
field: "ShipCity",
headerText: "ShipCity"
}
]
}, value: args.rowdata !== undefined ? args.rowdata["CustomerID"] : ""
});
}
function read(args) {
args.ejAutocomplete('suggestionList').css('display', 'none');
return args.ejAutocomplete("getValue");
}
$("#Edittemplate").keyup(function (e) {
if (e.keyCode == 40 && $(e.target).hasClass("e-autocomplete")) {
var autocomp = $("#EdittemplateCustomerID").ejAutocomplete("instance")
if (autocomp.getValue() != "" && autocomp.getActiveText() != "No suggestions")
$(e.target).val(autocomp.getActiveText());
}
});

Related

Formik - arrayfields -- validation handling

I am working with formik/material ui -- and yup validation. I am struggling to get validation showing/working on field arrays
my schema and validation looks like this currently for each field.
"fields": [
{
"type": "date",
"label": "Start Date",
"name": "startDate",
"validation": yup.date().default(function () { return new Date() }).required("date is required").nullable().typeError(''),
"minDate": moment().add(1, 'weeks'),
"maxDate": moment().add(8, 'weeks'),
"disablePast": true,
"disableFuture": false,
//"disabled": true
},
{
"type": "date",
"label": "End Date",
"name": "endDate",
"validation": yup.date().default(function () { return new Date() }).required("date is required").nullable().typeError(''),
"minDate": moment().add(1, 'weeks'),
"maxDate": moment().add(8, 'weeks'),
"disablePast": true,
"disableFuture": false,
//"disabled": true
}
]
I've seen on formik - they have some validation like this - but how do I apply it my code base for dates?
https://formik.org/docs/api/fieldarray
const schema = Yup.object().shape({
friends: Yup.array()
.of(
Yup.object().shape({
name: Yup.string().min(4, 'too short').required('Required'), // these constraints take precedence
salary: Yup.string().min(3, 'cmon').required('Required'), // these constraints take precedence
})
)
.required('Must have friends') // these constraints are shown if and only if inner constraints are satisfied
.min(3, 'Minimum of 3 friends'),
});
my fieldarray looks like this -- and I believe errors should appear under the field group -- the fields outer border goes red -- but it doesn't seem to work for when I null the date - like is required date working?
<>
<FieldArray
name={item.name}
onChange={event => {
console.log("event field array change", event)
}}
>
{({ insert, remove, push }) => (
<div className="field field-array">
<div className="row" key={0}>
{item.fields.map((ch, inx) => (
<span key={"x"+inx}>
<div className="col-x">
<Field
name={`${item.name}.${ch.name}`}
>
{({
field, // { name, value, onChange, onBlur }
form,
meta,
}) => (
<>
<LocalizationProvider dateAdapter={AdapterDayjs}>
<DatePicker
label={ch.label}
disablePast={ch.disablePast}
disableFuture={ch.disableFuture}
minDate={moment(ch.minDate)}
maxDate={moment(ch.maxDate)}
value={field.value? moment(field.value).format('YYYY-MM-DD'): moment().format('YYYY-MM-DD')}
{...field}
onChange={(value) => {
form.setFieldValue(field.name, value);
this.props.onHandle(field.name, value);
}}
renderInput={(params) => {
return (<TextField {...params} name={field.name} />)
}}
/>
</LocalizationProvider>
{meta.touched && meta.error && (
<div className="error">{meta.error}</div>
)}
</>
)}
</Field>
</div>
{inx === 0 &&
(<span></span>)
}
</span>
))}
</div>
</div>
)}
</FieldArray>
</>
I worked this out
"validation": yup.array().of( yup.object().shape({ firstName: yup.string().min(4, 'too short').required('Required'), lastName: yup.string().min(3, 'cmon').required('Required'), }) ).min(1, 'Minimum of 1 friends')
-- but in the display of errors had to check if it was an array or a string to avoid a render error
under the add more button to display array errors of the main list.
<FormHelperText
error={(form.errors[parent.name] && form.errors[parent.name].length > 0 ? true : false)}
>
{typeof form.errors[parent.name] === "string" &&
<>{form.errors[parent.name]}</>
}
</FormHelperText>
and under the fields - meta errors
{(getHelperVisibility(values, ch)) &&
<FormHelperText
error={meta.touched && (meta.error && meta.error.length > 0 ? true : false)}
>
{meta.error}
</FormHelperText>
}

VUEJS - Submit Form with EmailJS Error "The 3rd parameter is expected to be the HTML form element or the style selector of form"

I'm building my vue app where we can submit form, I'm using EmailJS and Vuetify, and I 've encountered some issue The 3rd parameter is expected to be the HTML form element or the style selector of form. Here's the code:
ContactForm.vue
<v-form class="mx-8" ref="form" #submit.prevent="sendEmail">
<v-col>
<v-text-field
v-model="from_name"
name="from_name"
label="Full Name"
required
></v-text-field>
</v-col>
<v-col>
<v-text-field
v-model="from_email"
name="from_email"
label="Email"
required
></v-text-field>
</v-col>
<v-col>
<v-textarea
v-model="message"
name="message"
outlined
label="Tell us about your ideas, the type of website you want, your target market, and your desired style."
:rules="textareaRules"
></v-textarea>
</v-col>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="#99d215b9" class="card-button mb-4" type="submit">
Submit
</v-btn>
</v-card-actions>
</v-form>
script
import emailjs from "#emailjs/browser";
export default {
data() {
return {
from_name: "",
from_email: "",
message: "",
};
},
methods: {
sendEmail() {
emailjs
.sendForm(
"service_id",
"template_id",
{
from_name: this.from_name,
from_email: this.from_email,
message: this.message,
},
"public_id"
)
.then(
(result) => {
console.log("SUCCESS!", result.text);
},
(error) => {
console.log("FAILED...", error.text);
}
);
},
Does anyone know where my mistake is, to resolve this error The 3rd parameter is expected to be the HTML form element or the style selector of form?
I tried this parameter this.$refs.form from emailjs doc but got the same issue
hello i think you must edit your method like this
methods: {
sendEmail() {
emailjs
.send(
"service_id",
"template_id",
{
from_name: this.from_name,
from_email: this.from_email,
message: this.message,
},
"public_id"
)
.then(
(result) => {
console.log("SUCCESS!", result.text);
},
(error) => {
console.log("FAILED...", error.text);
}
);
},

Simple v-model not disappearing when false

i'm having a little problem with my code, i think it's a simple problem but i'm having a hard time to figure it out, maybe you guys could lend me a hand!
So i have a that i have to show on/off when the user clicks on the button, i've already did the same thing in other projects before, but for some reason, the v-model:"table" or the #click="table = !table" are not working! i keep clicking at the button but does not seens to work at all, the table keeps showing static. I will leave here a screenshot of the table/btn and the code (template and script).
Thank you guys so much in advance!
CODE:
v-model="dialog"
fullscreen
>
<v-card>
<v-app-bar color="#39a0ed" dark>
<v-card-title>Menu Analista</v-card-title>
<v-btn
text
class="white justify-end"
color="#32322c"
#click="dialog = false"
>
Fechar
</v-btn>
</v-app-bar>
<v-btn #click="table = !table" >Visualizar</v-btn>
<v-btn class="primary" elevation="10" >Pesquisar Cadastro</v-btn>
<v-btn class="primary" elevation="10" >Erros de Cadastro ( 2 )</v-btn>
<v-data-table :value="true" :headers="headers" :items="infos" item-key="email" v-model="table" ></v-data-table>
<v-img
src="../assets/analyst1.svg"
style="max-width:500px; right:-75%;"
>
</v-img>
<v-card-actions>
<v-spacer></v-spacer>
</v-card-actions>
</v-card>
</v-dialog>
<script>
import firebase from 'firebase';
import { db, auth } from '../services/firebase';
import logo1 from '../assets/logo1.png'
import axios from 'axios'
import Table1 from './Table1'
export default {
data() {
return {
dialog: false,
hidden: false,
drawer: false,
table: false,
name: null,
email: null,
photoURL: null,
sector: null,
position: null,
client: null,
clientlogo: null,
infos: null,
headers: [
{
text: "Email",
align: "center",
value: "email",
},
]
} },
mounted () {
axios
.get('http://localhost:5566/users')
.then(response => (this.infos = response.data.rows))
},
computed: {
headersList() {
return this.headers
},
userList() {
return this.infos
}
}
}
</script>

Vuetify datatable reload when performing CRUD operations

I have a simple vuetify datatable that performs CRUD operations. I am using axios and a mongo database. When I add a new item, the information is correctly displayed in the client side and posted in the mongo database. However, I cannot access to updated information of the mongo database, particularly the id that mongo created, unless I reload the webpage. I am newcomer in Vue, please be patient. A simplified version of the problem:
axios
.post('http://localhost:5000/dessert', {
name: this.editedItem.name
})
console.log(this.editedItem.name) // I CAN ACCES WITHOUT PROBLEM
console.log(this.editedItem._id) // I NEED TO RELOAD THE WEBPAGE IN ORDER TO ACCES THIS ELEMENT. THE ID THAT MONGO CREATED.
Vue file:
<template>
<v-data-table
:headers="headers"
:items="desserts"
sort-by="calories"
class="elevation-1"
>
<template v-slot:top>
<v-toolbar flat color="white">
<v-toolbar-title>My CRUD</v-toolbar-title>
<v-divider
class="mx-4"
inset
vertical
></v-divider>
<v-spacer></v-spacer>
<v-dialog v-model="dialog" max-width="500px">
<template v-slot:activator="{ on }">
<v-btn color="primary" dark class="mb-2" v-on="on">New Item</v-btn>
</template>
<v-card>
<v-card-title>
<span class="headline">{{ formTitle }}</span>
</v-card-title>
<v-card-text>
<v-container>
<v-row>
<v-col cols="12" sm="6" md="4">
<v-text-field v-model="editedItem.name" label="Dessert name"></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="4">
<v-text-field v-model="editedItem.calories" label="Calories"></v-text-field>
</v-col>
</v-row>
</v-container>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="blue darken-1" text #click="close">Cancel</v-btn>
<v-btn color="blue darken-1" text #click="save">Save</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</v-toolbar>
</template>
<template v-slot:item.action="{ item }">
<v-icon
small
class="mr-2"
#click="editItem(item)"
>
edit
</v-icon>
<v-icon
small
#click="deleteItem(item)"
>
delete
</v-icon>
</template>
<template v-slot:no-data>
<v-btn color="primary" #click="initialize">Reset</v-btn>
</template>
</v-data-table>
</template>
<script>
import axios from 'axios'
export default {
data: () => ({
dialog: false,
headers: [
{
text: 'Dessert (100g serving)',
value: 'name',
},
{ text: 'Calories', value: 'calories' },
{ text: 'Actions', value: 'action', sortable: false },
],
desserts: [],
editedIndex: -1,
editedItem: {
name: '',
calories: 0,
},
defaultItem: {
name: '',
calories: 0,
},
}),
mounted() {
this.fetchItems()
},
computed: {
formTitle () {
return this.editedIndex === -1 ? 'New Item' : 'Edit Item'
},
},
watch: {
dialog (val) {
val || this.close()
},
},
created () {
this.initialize()
},
methods: {
fetchItems(){
axios
.get('http://localhost:5000/dessert')
.then(response => (this.desserts = response.data.data))
},
editItem (item) {
this.editedIndex = this.desserts.indexOf(item)
this.editedItem = Object.assign({}, item)
this.editedID = this.editedItem._id
this.name = this.editedItem.name
this.calories = this.editedItem.calories
this.dialog = true
},
deleteItem (item) {
const index = this.desserts.indexOf(item)
this.deletedItem = Object.assign({}, item)
console.log(this.deletedItem)
this.deletedID = this.deletedItem._id
console.log(this.deletedID)
if (confirm("Do you really want to delete?")) {
axios.delete(`http://localhost:5000/dessert/${this.deletedID}`);
this.desserts.splice(index, 1);
}
},
close () {
this.dialog = false
setTimeout(() => {
this.editedItem = Object.assign({}, this.defaultItem)
this.editedIndex = -1
}, 300)
},
save () { // Edit Item
if (this.editedIndex > -1) {
Object.assign(this.desserts[this.editedIndex], this.editedItem)
axios.delete(`http://localhost:5000/dessert/${this.editedItem._id}`)
axios
.post('http://localhost:5000/dessert', {
name: this.editedItem.name,
calories: this.editedItem.calories
})
// New Item
} else {
this.desserts.push(this.editedItem)
axios.post('http://localhost:5000/dessert', {
name: this.editedItem.name,
calories: this.editedItem.calories
})
}
this.close()
},
},
}
</script>
Python file:
from flask import Flask
from flask import jsonify
from flask import request
from flask_pymongo import PyMongo
from flask_cors import CORS
from bson.objectid import ObjectId
app = Flask(__name__)
#CORS(app)
# instantiate
app.config.from_object(__name__)
# enable CORS
CORS(app, resources={r'/*': {'origins': '*'}})
app.config['MONGO_DBNAME'] = 'restdb'
app.config['MONGO_URI'] = 'mongodb://localhost:27017/restdb'
mongo = PyMongo(app)
#app.route('/dessert', methods=['POST'])
def add_dessert():
dessert = mongo.db.desserts
name = request.json['name']
calories = request.json['calories']
dessert_id = dessert.insert({
'name': name,
'calories': calories
})
new_dessert = dessert.find_one({'_id': dessert_id })
output = {
'name' : new_dessert['name'],
'calories' : new_dessert['calories']
}
return jsonify({'result' : output})
#app.route('/dessert', methods=['GET'])
def get_all_desserts():
dessert = mongo.db.desserts
output = []
for s in dessert.find():
s['_id'] = str(s['_id'])
output.append({'_id' : s['_id'],
'name' : s['name'],
'calories' : s['calories']
})
return jsonify({'data' : output})
#app.route('/dessert/<dessert_id>', methods=['GET'])
def get_one_dessert(dessert_id):
dessert = mongo.db.desserts
s = dessert.find_one({"_id" : ObjectId(dessert_id)})
s['_id'] = str(s['_id'])
if s:
output = {'_id' : s['_id'], 'name' : s['name'], 'calories' : s['calories']}
else:
output = "No such name"
return jsonify({'result' : output})
#app.route('/dessert/<dessert_id>', methods=['DELETE'])
def delete_one_dessert(dessert_id):
dessert = mongo.db.desserts
s = dessert.find_one({"_id" : ObjectId(dessert_id)})
s['_id'] = str(s['_id'])
dessert.remove({"_id" : ObjectId(dessert_id)})
if s:
output = {'_id' : s['_id'], 'name' : s['name'], 'calories' : s['calories']}
else:
output = "No such name"
return jsonify({'result' : output})
if __name__ == '__main__':
app.run(debug=True)
If I understood it correctly, you want to be able to see in the front-end the newly added item, including the generated ID, after posting it to backend, right?
So, you can just simply call the fetchItems() once you finish posting the new item. It will automaticly update the array of the shown items, including the newly added ID.
The ID property is created when the item is added to the database, so it's not possible to have it unless the back-end gives it back to the front-end.
axios.post('http://localhost:5000/dessert', {
name: this.editedItem.name,
calories: this.editedItem.calories
}).then(response => {
this.fetchItems()
})
That means, once finishing the POST, fetchItems() again.

Bootstrap-vue: Auto-select first hardcoded <option> in <b-form-select>

I'm using b-form-select with server-side generated option tags:
<b-form-select :state="errors.has('type') ? false : null"
v-model="type"
v-validate="'required'"
name="type"
plain>
<option value="note" >Note</option>
<option value="reminder" >Reminder</option>
</b-form-select>
When no data is set for this field I want to auto-select the first option in the list.
Is this possible? I have not found how to access the component's options from within my Vue instance.
your v-model should have the value of the first option.
example
<template>
<div>
<b-form-select v-model="selected" :options="options" />
<div class="mt-3">Selected: <strong>{{ selected }}</strong></div>
</div>
</template>
<script>
export default {
data() {
return {
selected: 'a',
options: [
{ value: null, text: 'Please select an option' },
{ value: 'a', text: 'This is First option' },
{ value: 'b', text: 'Selected Option' },
{ value: { C: '3PO' }, text: 'This is an option with object value' },
{ value: 'd', text: 'This one is disabled', disabled: true }
]
}
}
}
</script>
You can trigger this.selected=${firstOptionValue} when no data is set.
what if we don't know what the first option is. The list is generated?
if you have dynamic data, something like this will work.
<template>
<div>
<b-form-select v-model="selected" :options="options" />
<div class="mt-3">Selected: <strong>{{ selected }}</strong></div>
</div>
</template>
<script>
export default {
data() {
return {
selected: [],
options: [],
};
},
mounted: function() {
this.getOptions();
},
methods: {
getOptions() {
//Your logic goes here for data fetch from API
const options = res.data;
this.options = res.data;
this.selected = options[0].fieldName; // Assigns first index of Options to model
return options;
},
},
};
</script>
If your options are stored in a property which is loaded dynamically:
computed property
async computed (using AsyncComputed plugin)
through props, which may change
Then you can #Watch the property to set the first option.
That way the behavior of selecting the first item is separated from data-loading and your code is more understandable.
Example using Typescript and #AsyncComputed
export default class PersonComponent extends Vue {
selectedPersonId: string = undefined;
// ...
// Example method that loads persons data from API
#AsyncComputed()
async persons(): Promise<Person[]> {
return await apiClient.persons.getAll();
}
// Computed property that transforms api data to option list
get personSelectOptions() {
const persons = this.persons as Person[];
return persons.map((person) => ({
text: person.name,
value: person.id
}));
}
// Select the first person in the options list whenever the options change
#Watch('personSelectOptions')
automaticallySelectFirstPerson(persons: {value: string}[]) {
this.selectedPersonId = persons[0].value;
}
}