Yogit Yogit - 12 days ago 5
Javascript Question

I am not able to access correct id of my ques in my website

Hey i am making a website in meteor in which people can add ques and get their answers. And i want to add a delete feature to each question so that the user can delete their questions. If I pull id of the question directly and delete it right away, it works. But if i try to take their confirmation through a bootstrap modal like "Are u sure : Yes/ No" and want that if they click yes, the question should be deleted. But instead of that particular ques the first ques in the window is deleted.

Here is my html code:

<template>
<div class="container margin-top">
<div class="row">
{{#each ques}}
<div class="col-xs-12" id="{{_id}}">
<div class="thumbnail">
<div class="caption">
<h3><span>Q.</span> {{ques}}</h3>
<p>
<span><b><i>Ans.</i></b></span>
<span>{{&gt; editableText collection="ques" field="ans"}}</span>
</p>
<button class="js-show-del-ques">Delete</button>
<div class="modal fade" id="ques_del_form">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<div class="modal-title">
<h1>Are you sure?</h1>
</div>
</div>
<div class="modal-body">
<button class="js-del-ques">Delete</button> <button class="" data-dismiss="modal">cancel</button>
</div>
<div class="modal-footer"></div>
</div>
</div>
</div>
</div>
</div>
</div>
{{/each}}
</div>
</div>
</template>


Here is my js code:

Template.ques.events({
'click .js-show-del-ques': function(event) {
$("#ques_del_form").modal('show');
},
'click .js-del-ques': function(event) {
var ques_id = this._id;
console.log(ques_id);
$("#" + ques_id).hide('slow', function() {
Ques.remove({
"_id": ques_id
});
})
$("#ques_del_form").modal('hide');
},
});


whereas if i do it like this:

<template>
<div class="container margin-top">
<div class="row">
{{#each ques}}
<div class="col-xs-12" id="{{_id}}">
<div class="thumbnail">
<div class="caption">
<h3><span>Q.</span> {{ques}}</h3>
<p><span><b><i>Ans.</i></b></span> <span>{{&gt; editableText collection="ques" field="ans"}}</span></p><button class="js-del-ques">Delete</button>
</div>
</div>
</div>
{{/each}}
</div>
</div>
</template>


in js:

Template.ques.events({
'click .js-del-ques': function(event) {
var ques_id = this._id;
console.log(ques_id);
$("#" + ques_id).hide('slow', function() {
Ques.remove({
"_id": ques_id
});
})
},
});


Then it works perfectly well and deletes the particular question.

Why is it not working? What's the reason the particular question is not getting deleted from modal?

Help is appreciated.

Thanks.

Answer

In your version that works, this._id in your event handler identifies the question you expect, as the data context (this) is being set by the #each block in the template.

Your version that doesn't work has a few issues:

First, inside your #each block you have <div class="modal fade" id="ques_del_form">. The #each will create this div multiple times, putting multiple elements with the same id into the DOM. This is invalid, and the root cause of the behaviour you are seeing.

Your click .js-show-del-ques event is then trying to find this element to show the appropriate modal dialog, but of course there are multiple copies of this and in your case it appears to be showing the first one it finds. As this is invalid markup though, you may get different non-standard behaviour from other browsers.

Even better is to move the modal dialog out of the #each, as you only need one copy of it. Try the following:

ques.html

<template>
    <div class="container margin-top">
        <div class="row">
            {{#each ques}}
                <div class="col-xs-12" id="{{_id}}">
                    <div class="thumbnail">
                        <div class="caption">
                            <h3><span>Q.</span> {{ques}}</h3>
                            <p>
                                <span><b><i>Ans.</i></b></span> 
                                <span>{{&gt; editableText collection="ques" field="ans"}}</span>
                            </p>
                            <button class="js-show-del-ques">Delete</button>
                        </div>
                    </div>
                </div>
            {{/each}}
        </div>
        <div class="modal fade" id="ques_del_form">
            <div class="modal-dialog">
                <div class="modal-content">
                    <div class="modal-header">
                        <div class="modal-title">
                            <h1>Are you sure?</h1>
                        </div>
                    </div>
                    <div class="modal-body">
                        <button class="js-del-ques">Delete</button> <button class="" data-dismiss="modal">cancel</button>
                    </div>
                    <div class="modal-footer"></div>
                </div>
            </div>
        </div>

    </div>
</template>

ques.js

import { ReactiveVar } from 'meteor/reactive-var'

Template.ques.onCreated(function() {
  this.SelectedQuestionToDelete = new ReactiveVar();
});

Template.ques.events({
    'click .js-show-del-ques': function(event, template) {
        template.SelectedQuestionToDelete.set(this._id);
        $("#ques_del_form").modal('show');
    },
    'click .js-del-ques': function(event, template) {
        var ques_id = template.SelectedQuestionToDelete.get();
        console.log('deleting ' ques_id);
        $("#" + ques_id).hide('slow', function() {
            Ques.remove({
                "_id": ques_id
            });
        })
        $("#ques_del_form").modal('hide');
    },
});

For an explanation of ReactiveVar see here.