Cannot DELETE mongodb entry - javascript

I am creating a blog app using node.js/express/mongoose/mongodb. I am creating a delete route so I can delete posts from my admin panel. I am also using method-override to delete. Whenever I press the button I created to delete a post I am met with an error saying cannot DELETE blogs/(blog name here). Not sure why it is not working, and any help would be greatly appreciated.
Here is the Delete route code
//DELETE BLOG ROUTE
app.delete("/blogs/:slug", function(req, res){
//DESTROY BLOG
Blog.findOneAndRemove({ slug: req.params.slug}, function(err){
if(err){
res.redirect("/admin");
} else {
res.redirect("/admin");
}
})
});
Here is my button to delete on my admin panel
<div class="d-flex justify-content-between">
View Post
Edit Post
<form action="/blogs/<%= blog.slug %>?_method=DELETE" method="POST">
<button class="btn btn-danger"><i class="far fa-trash-alt"></i> Post</button>
</form>
</div>

use blog._slug instead of blog.slug.
Because , mongoose extracts "id" as collections._id

In the Delete Route, you are passing slug as parameter so instead of using the blog.slug.
Use slug only. Example:
<div class="d-flex justify-content-between">
View Post
Edit Post
<form action="/blogs/<%=slug %>?_method=DELETE" method="POST">
<button class="btn btn-danger"><i class="far fa-trash-alt"></i> Post</button>
</form>
</div>

Related

Pre-populate current value of WTForms field in order to edit it

I have a form inside a modal that I use to edit a review on an item (a perfume). A perfume can have multiple reviews, and the reviews live in an array of nested documents, each one with its own _id.
I'm editing each particular review (in case an user wants to edit their review on the perfume once it's been submitted) by submitting the EditReviewForm to this edit_review route:
#reviews.route("/review", methods=["GET", "POST"])
#login_required
def edit_review():
form = EditReviewForm()
review_id = request.form.get("review_id")
perfume_id = request.form.get("perfume_id")
if form.validate_on_submit():
mongo.db.perfumes.update(
{"_id": ObjectId(perfume_id), <I edit my review here> })
return redirect(url_for("perfumes.perfume", perfume_id=perfume_id))
return redirect(url_for("perfumes.perfume", perfume_id=perfume_id))
And this route redirects to my perfume route, which shows the perfume and all the reviews it contains.
This is the perfume route:
#perfumes.route("/perfume/<perfume_id>", methods=["GET"])
def perfume(perfume_id):
current_perfume = mongo.db.perfumes.find_one({"_id": ObjectId(perfume_id)})
add_review_form = AddReviewForm()
edit_review_form = EditReviewForm()
cur = mongo.db.perfumes.aggregate(etc)
edit_review_form.review.data = current_perfume['reviews'][0]['review_content']
return render_template(
"pages/perfume.html",
title="Perfumes",
cursor=cur,
perfume=current_perfume,
add_review_form=add_review_form,
edit_review_form=edit_review_form
)
My issue
To find a way to get the review _id in that process and have it in my perfume route, so I can pre-populate my EditReviewForm with the current value. Otherwise the form looks empty to the user editing their review.
By hardcoding an index (index [0] in this case):
edit_review_form.review.data = current_perfume['reviews'][0]['review_content']
I am indeed displaying current values, but of course the same value for all reviews, as the reviews are in a loop in the template, and I need to get the value each review_id has.
Is there a way to do this, before I give up with the idea of allowing users to edit their reviews? :D
Please do let me know if my question is clear or if there's more information needed.
Thanks so much in advance!!
UPDATE 2:
Trying to reduce further my current template situation to make it clearer:
The modal with the review is fired from perfume-reviews.html, from this button:
<div class="card-header">
<button type="button" class="btn edit-review" data-perfume_id="{{perfume['_id']}}" data-review_id="{{review['_id']}}" data-toggle="modal" data-target="#editReviewPerfumeModal" id="editFormButton">Edit</button>
</div>
And that opens the modal where my form with the review is (the field in question is a textarea currently displaying a WYSIWYG from CKEditor:
<div class="modal-body">
<form method=POST action="{{ url_for('reviews.edit_review') }}" id="form-edit-review">
<div class="form-group" id="reviewContent">
{{ edit_review_form.review(class="form-control ckeditor", placeholder="Review")}}
</div>
</form>
</div>
Currently this isn't working:
$(document).on("click", "#editFormButton", function (e) {
var reviewText = $(this)
.parents(div.card.container)
.siblings("div#reviewContent")
.children()
.text();
$("input#editReviewContent").val(reviewText);
});
and throws a ReferenceError: div is not defined.
Where am I failing here? (Perhaps in more than one place?)
UPDATE 3:
this is where the button opens the modal, and underneath it's where the review content displays:
<div class="card container">
<div class="row">
<div class="card-header col-9">
<h5>{{review['reviewer'] }} said on {{ review.date_reviewed.strftime('%d-%m-%Y') }}</h5>
</div>
<div class="card-header col-3">
<button type="button" class="btn btn-success btn-sm mt-2 edit-review float-right ml-2" data-perfume_id="{{perfume['_id']}}" data-review_id="{{review['_id']}}" data-toggle="modal" data-target="#editReviewPerfumeModal" id="editFormButton">Edit</button>
</div>
</div>
<div class="p-3 row">
<div class=" col-10" id="reviewContent">
<li>{{ review['review_content'] | safe }}</li>
</div>
</div>
</div>
You can do this with jQuery as when you open the form, the form will automatically show the review content in there. It will be done by manipulating the dom.
Also, add an id to your edit button, in this example, I have given it an id "editFormButton".
Similarly, add an id to the div in which review content lies so that it is easier to select, I have given it an id "reviewContent"
Similarly, add an id to edit_review_form.review like this edit_review_form.review(id='editReviewContent')
<script>
$(document).on("click", "#editFormButton", function (e) {
var reviewText = $(this)
.parents("div.row")
.siblings("div.p-3.row")
.children("div#reviewContent")
.children()
.text();
$("input#editReviewContent").val(reviewText);
});
</script>
Don't forget to include jQuery.
Also, you can do it with pure javascript. You can easily search the above equivalents on google. This article is a good start!

Bootstrap 4 Modal PHP Dynamic Variable Access

I have a PDO object with a certain number of DB entries. I'm looping through every result generating HTML content. Furhtermore, if a user is logged in, I am displaying extra buttons to edit and delete the content, like so:
if (isset($_SESSION['login']) and $_SESSION['idMembre'] == $id_utilisateur) { ?>
<br>
<a class="btn btn-outline-secondary btn-sm" href="" id="modify" data-toggle="modal" data-target="#modifierRecette" data-id="<?=$recette->idRecette;?>" onclick="modifierRecette(<?= $recette->idRecette; ?>)">Modifier</a>
<span>|</span>
<a class="btn btn-outline-danger btn-sm" href="" value="submit" onclick="supprimerRecette(<?=$recette->idRecette;?>)">Supprimer</a>
<?php } ?>
When the user clicks on "Modifier", a modal pops-up. Idea is that user can change some data inside the modal and click on a "Save Changes" button to commit the changes to the DB.
However, I have a hard time accessing to my PDO loop-through from within the modal.
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Annuler</button>
<button type="button" class="btn btn-primary" data-dismiss="modal" onclick="sauvegarderRecette(<?= $recette->idRecette; ?>)">Sauvegarder</button>
</div>
Idea being in every loop-through, the function "sauvegarderRecette()" would get the unique ID of the data object I am working with. This in turn fires off an AJAX script to send the data to the DB:
function sauvegarderRecette(idRecette) {
let request = $.ajax({
'url' : 'ajax/sauvegarderRecette.php',
'type' : 'POST',
'data' : {
'idRecette' : idRecette
}
});
The issue now is that every loop-through, the ajax function sends off the same idRecette to the PHP script.
Any ideas on how I can dynamically access variable from JavaScript so it 'preserves' the value from the loop-through?
I thank you in advance for your help.

implement bootstrap notification or profile

good morning:
<html>
<button type="button" class="btn btn-primary">Notifications <span class="badge badge-light">4</span>
</button>
<button type="button" class="btn btn-primary">Profile <span class="badge badge-light">9</span>
<span class="sr-only">unread messages</span>
</button>
</html>
now how I implement these ?
for example like facebook when i click the notification appear a little submenu
anyone can help me ?
thanks
You can get the notifications from the database in your controller, put them in a variable, and pass it to a view.
In the view itself you can do something like this:
// $notificationsCount is the variable with number of notifications you passed to the
view in your controller
<button type="button" class="btn btn-primary">Notifications
<span class="badge badge-light"><?php echo $notificationsCount ?></span>
</button>
If you don't want to refresh the page, you could use ajax or some kind of event.
Example:
$('#someElement').on('click', function () {
//change value of the notification btn
});

Pass multiple params handlebars each block

So I'm trying to render two form information within a view I can get the one forms information to render however I can't get the second form to render the necessary information.
Here is what I have so far.
<tbody>
{{#each poemRegistrations}}
<tr>
<td>{{schoolName}}</td>
<td>{{competitionResults.winnersName}}</td>
<td>{{poem1AuthorName}}</td>
<td>{{poem1Title}}</td>
<td>{{poem1Url}}</td>
<td>{{poem2AuthorName}}</td>
<td>{{poem2Title}}</td>
<td>{{poem2Url}}</td>
<td>{{poem3AuthorName}}</td>
<td>{{poem3Title}}</td>
<td>{{poem3Url}}</td>
<td>
<div class="btn-group">
<a href="/dashboard/users/forms/poem-registrations/{{_id}}">
<button class="btn">Show</button>
</a>
<a href="/dashboard/users/forms/poem-registrations/edit/{{_id}}">
<button class="btn">Edit</button>
</a>
<a href="/dashboard/users/forms/poem-registrations/delete/{{_id}}">
<button class="btn user-btn-danger">Delete</button>
</a>
</div>
</td>
</tr>
{{/each}}
router.get('/dashboard/all-poems', ensureAuthenticated, (req, res) => {
PoemRegistrations.find({}, function(err, poemRegistrations, competitionResults) {
res.render('dashboard/all-poems.hbs', {
pageTitle: 'All Poems',
poemRegistrations: poemRegistrations,
competitionResults: competitionResults
});
});
});
The PoemRegistration form information is rendering however I just want to get the winners name from another form.
How would I go about doing this?
You may use the {{#root}} helper in Handlebars V2.0.0 :{{#root.competitionResults.winnersName}}
Or you could also include ../ segments to change the context to the root : {{../competitionResults.winnersName}}
Hope this helps.

PHP & Jquery Refresh id with external file

I'm trying to refresh one ID of my page within the click of a button.
I've tried several ways but none of them work. Although I've created the button to refresh it, it keep the submission of the page (triggering the validation event). So, each time I click that button, he tries to submit the form, validation the inputs instead refresh that div.
Here's my code right now:
function refreshCaptcha() {
$("#captcha_code").attr('src','./inc/captcha.php');
}
<div class="form-group">
<div class="col-xs-4">
<button class="btn btn-sm btn-warning" id="refreshcap" name="refreshcap" onclick="refreshCaptcha();">
<i class="fa fa-refresh push-5-r"></i>
<img id="captcha_code" src="inc/captcha.php" />
</button>
</div>
<div class="col-xs-8">
<div class="form-material floating">
<input class="form-control" type="text" id="cap" name="cap">
<label for="cap">Captcha</label>
</div>
</div>
</div>
Can someone help me trying to get what's wrong?
Thanks.
Assuming that your button is inside the form,
add type in your button
which will stop button from submitting your form
<button type="button" class="btn btn-sm btn-warning" id="refreshcap" name="refreshcap" onclick="refreshCaptcha();">
<i class="fa fa-refresh push-5-r"></i>
<img id="captcha_code" src="inc/captcha.php" />
</button>
other than that you can use javascript return false; in your function end
with js
<script>
$(document).ready(function() {
$("#refreshcap").on("click",function(event){
event.preventDefault();
$("#captcha_code").attr('src','./inc/captcha.php');
});
});
</script>
with this you wont need to call on click event this will do it for you, no matter type is button or submit
I think your JS function should return false; in order to not submit the form.
<script>
function refreshCaptcha() {
$("#captcha_code").attr('src','./inc/captcha.php');
return false;
}
</script>

Categories

Resources