Edit and save a document using Flask and Mongodb - mongodb

#app.route('/edit_book/<id>', methods=['POST', 'GET'])
def edit_book_id(id):
books = connexion.db.books
item = books.find_one({'_id': ObjectId(id)})
if request.method == 'GET':
if session['username'] is not None:
return render_template('edit_book.html', username=session['username'], mybooks=item)
books.update_one({"id": id},
{
"$set": {"title": request.form.get('title'),
"author": request.form.get('author'),
"edition": request.form.get('edition'),
"price": request.form.get('price'),
"image": request.files.get('image'),
"date": datetime.datetime.utcnow()
}
})
return 'Updated, success'
The html file:
<form action="" method="POST" enctype=multipart/form-data>
<h2>Title</h2>
<input type="text" name="title" size="60" value="{{mybooks.title}}"><br>
<h2>Author</h2>
<input type="text" name="author" size="60" value="{{mybooks.author}}"><br>
<h2>Edition</h2>
<input type="text" name="edition" size="60" value="{{mybooks.edition}}"><br>
<h2>Price</h2>
<input type="text" name="price" size="60" value="{{mybooks.price}}"><br>
<h2>Upload </h2>
<input type="file" name="image"/><br>
<br>
<input type="submit" value="Submit">
</form>
I use a form to edit a document from the Mongodb database. I can edit the document with the GET method but the problem is with the POST method, I can't update the document. I'm new in Flask.
I think I can't get the fields back after editing.

books.update_one({"_id": ObjectId(id)},
{ "$set": {
"title": request.form.get('title'),
"author": request.form.get('author'),
"edition": request.form.get('edition'),
"price": request.form.get('price'),
"image": request.files.get('image'),
"date": datetime.datetime.utcnow()
}
})
Forgot ObjectId(id)

Related

Vue.js Phone field not required, but not letting me submit if empty

I would like to be able to submit the following form without the phone field being required.
However, I would still like the phone field to be validated with regex before being able to be submit if a user inputs a phone number value.
So if blank, submit, ELSE check that it's valid before submitting. I thought had worked this out, but apparently not...
Any help is very much appreciated!
const app = Vue.createApp({
data() {
return {
currentYear: new Date().getFullYear(),
now: new Date().toISOString(),
imgSrc:
"",
contact: {
firstName: "",
lastName: "",
email: "",
phone: "",
address: "",
city: "",
state: "",
zip: "",
checked: false,
},
states: [
{
name: "Alabama",
abr: "AL",
},
{
name: "Alaska",
abr: "AK",
},
{
name: "American Samoa",
abr: "AS",
},
{
name: "Arizona",
abr: "AZ",
},
{
name: "Arkansas",
abr: "AR",
},
{
name: "California",
abr: "CA",
},
{
name: "Colorado",
abr: "CO",
},
{
name: "Connecticut",
abr: "CT",
},
{
name: "Delaware",
abr: "DE",
},
{
name: "District Of Columbia",
abr: "DC",
},
{
name: "Federated States Of Micronesia",
abr: "FM",
},
{
name: "Florida",
abr: "FL",
},
{
name: "Georgia",
abr: "GA",
},
{
name: "Guam",
abr: "GU",
},
{
name: "Hawaii",
abr: "HI",
},
{
name: "Idaho",
abr: "ID",
},
{
name: "Illinois",
abr: "IL",
},
{
name: "Indiana",
abr: "IN",
},
{
name: "Iowa",
abr: "IA",
},
{
name: "Kansas",
abr: "KS",
},
{
name: "Kentucky",
abr: "KY",
},
{
name: "Louisiana",
abr: "LA",
},
{
name: "Maine",
abr: "ME",
},
{
name: "Marshall Islands",
abr: "MH",
},
{
name: "Maryland",
abr: "MD",
},
{
name: "Massachusetts",
abr: "MA",
},
{
name: "Michigan",
abr: "MI",
},
{
name: "Minnesota",
abr: "MN",
},
{
name: "Mississippi",
abr: "MS",
},
{
name: "Missouri",
abr: "MO",
},
{
name: "Montana",
abr: "MT",
},
{
name: "Nebraska",
abr: "NE",
},
{
name: "Nevada",
abr: "NV",
},
{
name: "New Hampshire",
abr: "NH",
},
{
name: "New Jersey",
abr: "NJ",
},
{
name: "New Mexico",
abr: "NM",
},
{
name: "New York",
abr: "NY",
},
{
name: "North Carolina",
abr: "NC",
},
{
name: "North Dakota",
abr: "ND",
},
{
name: "Northern Mariana Islands",
abr: "MP",
},
{
name: "Ohio",
abr: "OH",
},
{
name: "Oklahoma",
abr: "OK",
},
{
name: "Oregon",
abr: "OR",
},
{
name: "Palau",
abr: "PW",
},
{
name: "Pennsylvania",
abr: "PA",
},
{
name: "Puerto Rico",
abr: "PR",
},
{
name: "Rhode Island",
abr: "RI",
},
{
name: "South Carolina",
abr: "SC",
},
{
name: "South Dakota",
abr: "SD",
},
{
name: "Tennessee",
abr: "TN",
},
{
name: "Texas",
abr: "TX",
},
{
name: "Utah",
abr: "UT",
},
{
name: "Vermont",
abr: "VT",
},
{
name: "Virgin Islands",
abr: "VI",
},
{
name: "Virginia",
abr: "VA",
},
{
name: "Washington",
abr: "WA",
},
{
name: "West Virginia",
abr: "WV",
},
{
name: "Wisconsin",
abr: "WI",
},
{
name: "Wyoming",
abr: "WY",
},
],
};
},
methods: {
submitForm(e) {
const isValid =
this.contact.firstName &&
this.contact.lastName &&
this.contact.email &&
this.validEmail(this.contact.email) &&
this.validPhone(this.contact.phone) &&
this.validZip(this.contact.zip);
e.target.classList.add("was-validated");
if (!isValid) {
e.preventDefault();
}
},
validEmail: function (email) {
const re =
/^(([^<>()[\]\\.,;:\s#"]+(\.[^<>()[\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(email);
},
validPhone: function (phone) {
const re = /^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$/;
return re.test(phone);
},
validZip: function (zip) {
const re = /^\d{5}(?:[-\s]\d{4})?$/;
return re.test(zip);
},
},
});
app.mount("#awApp");
<!DOCTYPE html>
<html lang="en" class="vh-100">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="" />
<meta name="author" content="" />
<!-- Bootstrap 5 CSS -->
<link
href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
crossorigin="anonymous"
/>
<!-- /Bootstrap 5 CSS-->
<style>
main > .container {
padding: 60px 15px 0;
}
</style>
<script src="https://cdn.jsdelivr.net/npm/vue#3.0.11"></script>
</head>
<body>
<div id="awApp" class="d-flex flex-column vh-100">
<!-- FIXED NAVBAR AND/OR HEADER -->
<header>
<nav class="navbar navbar-expand-md navbar-light fixed-top bg-light">
<div class="container-fluid">
<a class="navbar-brand" href="#">
<img :src="imgSrc" alt="logo" width="120" />
</a>
</div>
</nav>
</header>
<!-- / HEADER/NAVBAR -->
<!-- MAIN CONTENT -->
<main role="main" class="flex-shrink-0">
<div class="container">
<div class="row my-5">
<div class="col-md-7">
<img
src="http://placehold.it/1200x400"
alt="hero image"
class="img-fluid"
/>
<h2 class="mt-3">Headline goes here...</h2>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit.
Corporis dolore eaque, facere id molestias perspiciatis sit?
</p>
<ul>
<li>benefit 1</li>
<li>benefit 2</li>
<li>benefit 3</li>
</ul>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ad
aliquid assumenda consectetur deleniti est ipsam nemo nobis
officiis quasi, quod!
</p>
</div>
<div class="col-md-5">
<div class="card shadow p-3">
<!--<img class="card-img-top rz-card-img-top" src="http://placehold.it/400x100" alt="Card image cap">-->
<div class="card-body">
<h5 class="card-title">Headline</h5>
<p class="card-text">
Some quick example text to build on the card title and make
up the bulk of the card's content.
</p>
<form
novalidate
class="needs-validation"
name="mainForm"
#submit="submitForm"
method="post"
>
<div class="row mb-2">
<div class="col-md-6 mb-3">
<label for="firstname" class="form-label mb-0"
>First Name*</label
>
<input
id="firstname"
type="text"
name="firstname"
class="form-control"
v-model="contact.firstName"
id="awValid"
required
/>
<div class="valid-feedback">Looks good!</div>
<div class="invalid-feedback">
Please enter a first name.
</div>
</div>
<div class="col-md-6 mb-3">
<label for="lastname" class="form-label mb-0"
>Last Name*</label
>
<input
id="lastname"
type="text"
name="lastname"
class="form-control"
v-model="contact.lastName"
required
/>
<div class="invalid-feedback">
Please enter a last name.
</div>
</div>
</div>
<div class="row mb-3">
<div class="col">
<label for="email" class="form-label mb-0"
>Email Address*</label
>
<input
id="email"
type="text"
name="email"
class="form-control"
v-model="contact.email"
pattern="^[_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*#[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*(\.[a-zA-Z]{2,20})$"
required
/>
<div class="invalid-feedback">
Please enter a valid email.
</div>
</div>
</div>
<div class="row mb-3">
<div class="col">
<label for="phone" class="form-label mb-0"
>Phone
</label>
<input
id="phone"
type="text"
name="phone"
class="form-control"
pattern="^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$"
v-model="contact.phone"
/>
<div class="invalid-feedback">
Please enter a valid phone number.
</div>
</div>
</div>
<div class="row mb-3">
<div class="col">
<label for="address1" class="form-label mb-0"
>Street Address
</label>
<input
id="address1"
type="text"
name="address1"
class="form-control"
v-model="contact.address"
/>
</div>
</div>
<div class="row mb-2">
<div class="col-md-5 mb-3">
<label for="city" class="form-label mb-0">City</label>
<input
id="city"
type="text"
name="city"
class="form-control"
v-model="contact.city"
/>
</div>
<div class="col-md-3 mb-3">
<label for="state" class="form-label mb-0">State</label>
<select
id="state"
name="state"
v-model="contact.state"
class="form-select"
>
<option>##state##</option>
<option
v-for="state in states"
v-bind:value="state.abr"
>
{{state.name}}
</option>
</select>
</div>
<div class="col-md-4 mb-3">
<label for="zip" class="form-label mb-0"
>Zip Code</label
>
<input
id="zip"
type="text"
name="zip"
class="form-control"
v-model="contact.zip"
pattern="^\d{5}(?:[-\s]\d{4})?$"
/>
<div class="invalid-feedback">
Please enter a valid zip code.
</div>
</div>
</div>
<div class="row mb-2">
<div class="col">
<div class="form-check">
<input
id="checkbox1"
type="checkbox"
class="form-check-input"
name="check-me-out"
v-model="contact.checked"
/>
<label for="checkbox1" class="form-check-label"
>Check me out</label
>
<div></div>
</div>
</div>
</div>
<input
type="submit"
class="btn btn-primary"
value="Submit"
/>
<div>
<small class="form-text text-muted">
<em>* Denotes a required field.</em>
</small>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</main>
<!-- /MAIN CONTENT -->
<!-- FOOTER -->
<footer class="footer mt-auto py-3 bg-light text-center">
<div class="container">
<span class="text-muted"
>© {{currentYear}} |
Privacy Policy |
Legal</span
>
</div>
</footer>
<!-- /FOOTER -->
</div>
<!--Bootstrap 5 JS-->
<script
src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/js/bootstrap.bundle.min.js"
integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
crossorigin="anonymous"
></script>
<!--/Bootstrap 5 JS-->
</body>
</html>
You could add a condition to the isValid Boolean that checks whether the phone field is empty:
export default {
methods: {
submitForm(e) {
const isValid =
this.contact.firstName &&
this.contact.lastName &&
this.contact.email &&
this.validEmail(this.contact.email) &&
👇
(!this.contact.phone || this.validPhone(this.contact.phone)) &&
this.validZip(this.contact.zip);
//...
}
}
}
const app = Vue.createApp({
data() {
return {
currentYear: new Date().getFullYear(),
now: new Date().toISOString(),
imgSrc:
"",
contact: {
firstName: "",
lastName: "",
email: "",
phone: "",
address: "",
city: "",
state: "",
zip: "",
checked: false,
},
states: [
{
name: "Alabama",
abr: "AL",
},
{
name: "Alaska",
abr: "AK",
},
{
name: "American Samoa",
abr: "AS",
},
{
name: "Arizona",
abr: "AZ",
},
{
name: "Arkansas",
abr: "AR",
},
{
name: "California",
abr: "CA",
},
{
name: "Colorado",
abr: "CO",
},
{
name: "Connecticut",
abr: "CT",
},
{
name: "Delaware",
abr: "DE",
},
{
name: "District Of Columbia",
abr: "DC",
},
{
name: "Federated States Of Micronesia",
abr: "FM",
},
{
name: "Florida",
abr: "FL",
},
{
name: "Georgia",
abr: "GA",
},
{
name: "Guam",
abr: "GU",
},
{
name: "Hawaii",
abr: "HI",
},
{
name: "Idaho",
abr: "ID",
},
{
name: "Illinois",
abr: "IL",
},
{
name: "Indiana",
abr: "IN",
},
{
name: "Iowa",
abr: "IA",
},
{
name: "Kansas",
abr: "KS",
},
{
name: "Kentucky",
abr: "KY",
},
{
name: "Louisiana",
abr: "LA",
},
{
name: "Maine",
abr: "ME",
},
{
name: "Marshall Islands",
abr: "MH",
},
{
name: "Maryland",
abr: "MD",
},
{
name: "Massachusetts",
abr: "MA",
},
{
name: "Michigan",
abr: "MI",
},
{
name: "Minnesota",
abr: "MN",
},
{
name: "Mississippi",
abr: "MS",
},
{
name: "Missouri",
abr: "MO",
},
{
name: "Montana",
abr: "MT",
},
{
name: "Nebraska",
abr: "NE",
},
{
name: "Nevada",
abr: "NV",
},
{
name: "New Hampshire",
abr: "NH",
},
{
name: "New Jersey",
abr: "NJ",
},
{
name: "New Mexico",
abr: "NM",
},
{
name: "New York",
abr: "NY",
},
{
name: "North Carolina",
abr: "NC",
},
{
name: "North Dakota",
abr: "ND",
},
{
name: "Northern Mariana Islands",
abr: "MP",
},
{
name: "Ohio",
abr: "OH",
},
{
name: "Oklahoma",
abr: "OK",
},
{
name: "Oregon",
abr: "OR",
},
{
name: "Palau",
abr: "PW",
},
{
name: "Pennsylvania",
abr: "PA",
},
{
name: "Puerto Rico",
abr: "PR",
},
{
name: "Rhode Island",
abr: "RI",
},
{
name: "South Carolina",
abr: "SC",
},
{
name: "South Dakota",
abr: "SD",
},
{
name: "Tennessee",
abr: "TN",
},
{
name: "Texas",
abr: "TX",
},
{
name: "Utah",
abr: "UT",
},
{
name: "Vermont",
abr: "VT",
},
{
name: "Virgin Islands",
abr: "VI",
},
{
name: "Virginia",
abr: "VA",
},
{
name: "Washington",
abr: "WA",
},
{
name: "West Virginia",
abr: "WV",
},
{
name: "Wisconsin",
abr: "WI",
},
{
name: "Wyoming",
abr: "WY",
},
],
};
},
methods: {
submitForm(e) {
const isValid =
this.contact.firstName &&
this.contact.lastName &&
this.contact.email &&
this.validEmail(this.contact.email) &&
(!this.contact.phone || this.validPhone(this.contact.phone)) &&
this.validZip(this.contact.zip);
e.target.classList.add("was-validated");
if (!isValid) {
e.preventDefault();
}
},
validEmail: function (email) {
const re =
/^(([^<>()[\]\\.,;:\s#"]+(\.[^<>()[\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(email);
},
validPhone: function (phone) {
const re = /^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$/;
return re.test(phone);
},
validZip: function (zip) {
const re = /^\d{5}(?:[-\s]\d{4})?$/;
return re.test(zip);
},
},
});
app.mount("#awApp");
<!DOCTYPE html>
<html lang="en" class="vh-100">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="" />
<meta name="author" content="" />
<!-- Bootstrap 5 CSS -->
<link
href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
crossorigin="anonymous"
/>
<!-- /Bootstrap 5 CSS-->
<style>
main > .container {
padding: 60px 15px 0;
}
</style>
<script src="https://cdn.jsdelivr.net/npm/vue#3.0.11"></script>
</head>
<body>
<div id="awApp" class="d-flex flex-column vh-100">
<!-- FIXED NAVBAR AND/OR HEADER -->
<header>
<nav class="navbar navbar-expand-md navbar-light fixed-top bg-light">
<div class="container-fluid">
<a class="navbar-brand" href="#">
<img :src="imgSrc" alt="logo" width="120" />
</a>
</div>
</nav>
</header>
<!-- / HEADER/NAVBAR -->
<!-- MAIN CONTENT -->
<main role="main" class="flex-shrink-0">
<div class="container">
<div class="row my-5">
<div class="col-md-7">
<img
src="http://placehold.it/1200x400"
alt="hero image"
class="img-fluid"
/>
<h2 class="mt-3">Headline goes here...</h2>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit.
Corporis dolore eaque, facere id molestias perspiciatis sit?
</p>
<ul>
<li>benefit 1</li>
<li>benefit 2</li>
<li>benefit 3</li>
</ul>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ad
aliquid assumenda consectetur deleniti est ipsam nemo nobis
officiis quasi, quod!
</p>
</div>
<div class="col-md-5">
<div class="card shadow p-3">
<!--<img class="card-img-top rz-card-img-top" src="http://placehold.it/400x100" alt="Card image cap">-->
<div class="card-body">
<h5 class="card-title">Headline</h5>
<p class="card-text">
Some quick example text to build on the card title and make
up the bulk of the card's content.
</p>
<form
novalidate
class="needs-validation"
name="mainForm"
#submit="submitForm"
method="post"
>
<div class="row mb-2">
<div class="col-md-6 mb-3">
<label for="firstname" class="form-label mb-0"
>First Name*</label
>
<input
id="firstname"
type="text"
name="firstname"
class="form-control"
v-model="contact.firstName"
id="awValid"
required
/>
<div class="valid-feedback">Looks good!</div>
<div class="invalid-feedback">
Please enter a first name.
</div>
</div>
<div class="col-md-6 mb-3">
<label for="lastname" class="form-label mb-0"
>Last Name*</label
>
<input
id="lastname"
type="text"
name="lastname"
class="form-control"
v-model="contact.lastName"
required
/>
<div class="invalid-feedback">
Please enter a last name.
</div>
</div>
</div>
<div class="row mb-3">
<div class="col">
<label for="email" class="form-label mb-0"
>Email Address*</label
>
<input
id="email"
type="text"
name="email"
class="form-control"
v-model="contact.email"
pattern="^[_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*#[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*(\.[a-zA-Z]{2,20})$"
required
/>
<div class="invalid-feedback">
Please enter a valid email.
</div>
</div>
</div>
<div class="row mb-3">
<div class="col">
<label for="phone" class="form-label mb-0"
>Phone
</label>
<input
id="phone"
type="text"
name="phone"
class="form-control"
pattern="^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$"
v-model="contact.phone"
/>
<div class="invalid-feedback">
Please enter a valid phone number.
</div>
</div>
</div>
<div class="row mb-3">
<div class="col">
<label for="address1" class="form-label mb-0"
>Street Address
</label>
<input
id="address1"
type="text"
name="address1"
class="form-control"
v-model="contact.address"
/>
</div>
</div>
<div class="row mb-2">
<div class="col-md-5 mb-3">
<label for="city" class="form-label mb-0">City</label>
<input
id="city"
type="text"
name="city"
class="form-control"
v-model="contact.city"
/>
</div>
<div class="col-md-3 mb-3">
<label for="state" class="form-label mb-0">State</label>
<select
id="state"
name="state"
v-model="contact.state"
class="form-select"
>
<option>##state##</option>
<option
v-for="state in states"
v-bind:value="state.abr"
>
{{state.name}}
</option>
</select>
</div>
<div class="col-md-4 mb-3">
<label for="zip" class="form-label mb-0"
>Zip Code</label
>
<input
id="zip"
type="text"
name="zip"
class="form-control"
v-model="contact.zip"
pattern="^\d{5}(?:[-\s]\d{4})?$"
/>
<div class="invalid-feedback">
Please enter a valid zip code.
</div>
</div>
</div>
<div class="row mb-2">
<div class="col">
<div class="form-check">
<input
id="checkbox1"
type="checkbox"
class="form-check-input"
name="check-me-out"
v-model="contact.checked"
/>
<label for="checkbox1" class="form-check-label"
>Check me out</label
>
<div></div>
</div>
</div>
</div>
<input
type="submit"
class="btn btn-primary"
value="Submit"
/>
<div>
<small class="form-text text-muted">
<em>* Denotes a required field.</em>
</small>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</main>
<!-- /MAIN CONTENT -->
<!-- FOOTER -->
<footer class="footer mt-auto py-3 bg-light text-center">
<div class="container">
<span class="text-muted"
>© {{currentYear}} |
Privacy Policy |
Legal</span
>
</div>
</footer>
<!-- /FOOTER -->
</div>
<!--Bootstrap 5 JS-->
<script
src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/js/bootstrap.bundle.min.js"
integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
crossorigin="anonymous"
></script>
<!--/Bootstrap 5 JS-->
</body>
</html>

amp-list won't show data from firebase rest api while query parameters are added

I am using amp-list with firebase REST api. The thing is when I use
"https://kitchentocustomer.firebaseio.com/restaurants/Yiecu6fL2Pas0XFhCsT06Q0dSOp1/menu.json"
I get the amp-list populated,but when I add query parameters
"https://kitchentocustomer.firebaseio.com/restaurants/Yiecu6fL2Pas0XFhCsT06Q0dSOp1/menu.json?orderBy=%22first_cat%22&equalTo=%22BREAKFAST%22&print=pretty"
I get empty amp-list.
Here is the code
<amp-list width="300"
height="250"
single-item
items="."
layout="responsive"
src="https://kitchentocustomer.firebaseio.com/restaurants/Yiecu6fL2Pas0XFhCsT06Q0dSOp1/menu.json?orderBy=%22first_cat%22&equalTo=%22BREAKFAST%22&print=pretty">
<template type="amp-mustache">
<div>
<dt class="col col-10 h3 mb1">{{title}}</dt>
<dd class="col col-2 m0 mb1 self-center right-align">₹{{price}}</dd>
</div>
</template>
</amp-list>
The amp-list response must be a JSON object containing an array property.
Your filtered query (second link) returns a JSON object which does not contain an array.
Your response for this should be something like below
[
{
"discounted": 157,
"first_cat": "BREAKFAST",
"id": "eEaVn8",
"onSale": false,
"price": 167,
"third_cat": "Egg",
"title": "Egg omlete"
},
{
"discounted": 210,
"first_cat": "BREAKFAST",
"id": "pia9nL",
"onSale": false,
"price": 228,
"third_cat": "Waffles",
"title": "Banana & Nutella waffles"
}
]

How can I add a <table> to a child node when is lazyloaded in fancytree?

Ive just started using fancytree this week, I'd like to add a table when a node is lazy loaded,the data for the that table will be the output of a GET request and I have the code to generate the table as I want it with jquery but when its time to add it to data.result I have no clue how to do it, it is expecting a list of children and the output for my function will be the table as it is in the snippet
I've tried many and most likely stupid things and I cant find any help in the examples, please help!
const SOURCEDATA = [
{
"title": "group1",
expanded: true,
children: [
{
"title": "Users",
expanded: true,
children: [
{"title": "User1", "lazy": true},
{"title": "User2", "lazy": true},
{"title": "User3", "lazy": true}
]
}]
},
{
"title": "group2",
children: [
{
"title": "Users",
expanded: true,
children: [
{"title": "User4", "lazy": true},
{"title": "User5", "lazy": true},
{"title": "User6", "lazy": true}
]
}]
}
]
$(function() {
$("#tree").fancytree({
source: SOURCEDATA,
focusOnSelect: true,
activeVisible: true,
lazyLoad: function(event, data){
var node = data.node
data.result = [{"title":"this should be the place for the table"}]
}
});
});
<link href="//cdn.jsdelivr.net/npm/jquery.fancytree#2.25/dist/skin-win8/ui.fancytree.min.css" rel="stylesheet">
<script src="//code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="//code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/jquery.fancytree#2.27/dist/jquery.fancytree-all.min.js"></script>
<div id="tree">my tree</div>
<table id="user_2">
<thead>
<tr>
<th>Process Name</th>
<th>Process Hashes</th>
<th>Process Author</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<select id="process_name">
<option>Foo.exe</option>
<option></option>
</select>
</td>
<td>
<select id="process_hash">
<option></option>
<option value="0123ABC">0123ABC</option>
<option value="ABC0123">ABC0123</option>
</select>
</td>
<td>
<select id="process_author">
<option></option>
<option value="Someone">Someone</option>
<option value="Somebody">Somebody</option>
</select>
</td>
<td>
<input id="act_allow" type="radio" name="action" value="allow">Allow</input>
<input id="act_deny" type="radio" name="action" value="deny">Deny</input>
<input id="act_warn" type="radio" name="action" value="warn">Warn</input>
</td>
</tr>
</tbody>
</table>
As long as the escapeTitles option is not enabled, you should be able to add raw HTML markup as a title.
Did you try
lazyLoad: function(event, data){
var node = data.node
data.result = [{title: "<table>...</table>", icon: false}]
}
});
Not sure however how good this will play with styling and event handling of the standard tree.

Schema markup for logo

I have this markup for Dentist https://schema.org/Dentist
<div itemscope itemtype="http://schema.org/Dentist">
// address is ok
<span itemprop="address" itemscope itemtype="http://schema.org/PostalAddress">
<span itemprop="streetAddress">asdfd sf412</span>
<span itemprop="postalCode">12345</span>
<span itemprop="addressLocality">sadfsdf</span>
</span>
// this fails
<span itemprop="logo" itemscope itemtype="http://schema.org/ImageObject">
<meta itemprop="url" content="logo.gif'; ?>" />
</span>
</div>
When trying to test code for itemprop="logo" https://schema.org/logo
Google testing gives me error: "A value for the url field is required."
What am I missing?
I don't want logo to be visible on page, thats why I have put it as meta.
The error in Google’s SDTT is about the Dentist item, not about the ImageObject item. You can see this from the nesting level, the url row is on the same level as logo and address.
So adding a url property to the Dentist item would get rid of the error.
<div itemscope itemtype="http://schema.org/Dentist">
<span itemprop="address" itemscope itemtype="http://schema.org/PostalAddress">
<span itemprop="streetAddress">asdfd sf412</span>
<span itemprop="postalCode">12345</span>
<span itemprop="addressLocality">sadfsdf</span>
</span>
<span itemprop="logo" itemscope itemtype="http://schema.org/ImageObject">
<link itemprop="url" href="logo.gif" />
</span>
<link itemprop="url" href="http://example.com/" />
</div>
I changed the meta to link, because HTML5 and Microdata require that you use link (instead of meta) if the value is a URI.
Just in case if you are looking for a JSON-LD format, look over the below code and give it a shot.
"publisher": {
"#type": "Organization",
"name": "Lokaci",
"url": "https://lokaci.com",
"logo": {
"#type": "ImageObject",
"url": "https://res.cloudinary.com/lokaci/image/upload/v1580448186/logo/lokaci_logo_black-corp-comp_nzkooj.png"
}
},
Here is the full code if you wanna have a look, the schema micro-data was about a news article.
------------------full JSON-LD format below ----------------
{
"#context": "https://schema.org",
"#type": "NewsArticle",
"url": "https://lokaci.com/news/Diwali-Countdown-Offer-A-Brothers-Gift",
"publisher": {
"#type": "Organization",
"name": "Lokaci",
"url": "https://lokaci.com",
"logo": {
"#type": "ImageObject",
"url": "https://res.cloudinary.com/lokaci/image/upload/v1580448186/logo/lokaci_logo_black-corp-comp_nzkooj.png"
}
},
"dateline": "Laxminagar Delhi, 26 October 2019",
"headline": "Diwali Countdown Offer: A Brother’s Gift",
"mainEntityOfPage": "https://lokaci.com/newsroom",
"author": {
"#type": "Organization",
"name": "Lokaci",
"logo": "https://res.cloudinary.com/lokaci/image/upload/v1580448186/logo/lokaci_logo_black-corp-comp_nzkooj.png"
},
"image": "https://res.cloudinary.com/lokaci/image/upload/v1575284148/Newsroom/A-One-Salon-Lokaci-wins-Oppo-phone_dfvzdl.jpg",
"datePublished": " 26 October 2019",
"dateModified": " 26 October 2019",
"wordCount": 165,
"keywords": "Lokaci, News"
}

Using JQuery event.target to work with children

My question refers specifically to http://api.jquery.com/event.target/#example-1
If you use a span in the <li> or other tag to change the style such as <b> as I have done here, that part of the element won't trigger the JQuery function to toggle it's children. How might one go about making this work?
HTML:
<ul>
<li><b>This doesn't work,</b> this does
<ul>
<li>sub item 1-a</li>
<li>sub item 1-b</li>
</ul>
</li>
<li>item 2
<ul>
<li>sub item 2-a</li>
<li>sub item 2-b</li>
</ul>
</li>
</ul>
JavaScript:
function handler(event) {
var $target = $(event.target);
if( $target.is("li") ) {
$target.children("ul").toggle();
}
}
$("ul").click(handler).find("ul").hide();
To keep using your current form, I'd suggest using closest():
function handler(event) {
$(event.target).closest('li').children("ul").toggle();
}
$("ul").click(handler).find("ul").hide();
JS Fiddle demo.
Though for my own use I'd prefer:
$('li').on('click', function(e){
e.stopPropagation();
$(this).find('ul').toggle();
});
JS Fiddle demo.
References:
closest().
on().
A complete example of e.target children and closest with datatable and external data.
HtML
<!DOCTYPE html>
<html lang="en">
<head>
<title>example</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.16/css/jquery.dataTables.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script type="text/javascript" charset="utf8" src="js/jquery.dataTables.js"></script>
<script src="js/script.js"></script>
</head>
<body>
<div class="col-md-12 sectionone">
<div id="coxtable">
<div class="col-md-3 outerblock" id="section1"><div class="blocks section1"><h6 class="span1">Section1</h6><span class="span1a">Section1a</span></div></div>
<div class="col-md-3 outerblock" id="section2"><div class="blocks section2"><h6 class="span1">Section2</h6><span class="span1a">Section2a</span></div></div>
<div class="col-md-3 outerblock" id="section3"><div class="blocks section3"><h6 class="span1">Section3</h6><span class="span1a">Section3a</span></div></div>
<div class="col-md-3 outerblock" id="section4"><div class="blocks section4"><h6 class="span1">Section4</h6><span class="span1a">Section4a</span></div></div>
</div>
</div>
<div class="sectiontwo col-md-12">
<table id="example">
<thead>
<tr>
<th>name</th>
<th>stargazerscount</th>
<th>forkscount</th>
<th>description</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
<div id="testmodal" class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Modal Header</h4>
</div>
<div class="modal-body">
<p>Some text in the modal.</p>
</div>
<div class="modal-footer">
<button type="button" class="modalbtn btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</body>
</html>
Javascript
$(document).ready( function () {
var tables=$('#example').DataTable( {
"ajax": {
"type" : "POST",
"url": "http://localhost/example/json/members.json",
"dataSrc": function (json) {
var return_data = new Array();
for(var i=0;i< json.length; i++){
return_data.push({
'name': json[i].name,
'stargazerscount' : json[i].stargazerscount,
'forkscount' : json[i].forkscount,
'description' : json[i].description
})
$('.overlay').hide();
$(".loader").hide();
}
return return_data;
}
},
"columns": [
{ "data": "name" },
{ "data": "stargazerscount" },
{ "data": "forkscount" },
{ "data": "description" }
]
});
/*onclick filter*/
$(".outerblock").click(function(e){
$("#testmodal").modal('show');
var item=$(e.target).closest('span').text();
$( ".modalbtn" ).one( "click", function(event) {
$(this).off(event);
alert(item)
var tables=$('#example').DataTable( {
"destroy":true,
"ajax": {
"type" : "POST",
"url": "http://localhost/example/json/members.json?id="+item,
"dataSrc": function (json) {
var return_data = new Array();
for(var i=0;i< json.length; i++){
return_data.push({
'name': json[i].name,
'stargazerscount' : json[i].stargazerscount,
'forkscount' : json[i].forkscount,
'description' : json[i].description
})
$('.overlay').hide();
$(".loader").hide();
}
return return_data;
}
},
"columns": [
{ "data": "name" },
{ "data": "stargazerscount" },
{ "data": "forkscount" },
{ "data": "description" }
]
});
});
});
$("#example").delegate("tbody tr td:first-child", "click", function(e){
var item=$(e.target).text();
//alert(item);
$("#testmodal").modal('show');
$( ".modalbtn" ).one( "click", function(event) {
$(this).off(event);
alert(item);
var tables=$('#example').DataTable( {
"destroy":true,
"ajax": {
"type" : "POST",
"url": "http://localhost/example/json/members.json?id="+item,
"dataSrc": function (json) {
var return_data = new Array();
for(var i=0;i< json.length; i++){
return_data.push({
'name': json[i].name,
'stargazerscount' : json[i].stargazerscount,
'forkscount' : json[i].forkscount,
'description' : json[i].description
})
$('.overlay').hide();
$(".loader").hide();
}
return return_data;
}
},
"columns": [
{ "data": "name" },
{ "data": "stargazerscount" },
{ "data": "forkscount" },
{ "data": "description" }
]
});
});
});
});
json
[{
"name": "mango",
"stargazerscount": 526,
"forkscount": "critical",
"description": "fruits"
},
{
"name": "mobiles",
"stargazerscount": 526,
"forkscount": "major",
"description": "electronics"
},
{
"name": "mobiles",
"stargazerscount": 526,
"forkscount": "major",
"description": "electronics"
}
]