jQuery append element duplicates itself - javascript

I have my alert box that appears on every CRUD operation.
<section class="content container-fluid">
<div id="notif-box" style="display: none;" class="alert alert-dismissible">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
<h4 id="head-title"><i id="icon-box" class="icon fa"></i></h4>
<span id="alert-message"></span>
</div>
</section>
I have problem with #head-title where I write headText.
In my methods on success I call:
displayNotif('danger', 'check', 'User added successfully', 'Success!');
and this fucntion:
function displayNotif(type, icon, text, alertTitle) {
$("#notif-box").removeClass();
$("#icon-box").removeClass();
$("#head-title").removeClass(alertTitle);
$("#notif-box").show();
var notifBoxClass = "alert alert-"+type+" alert-dismissible";
var iconClass = "icon fa fa-"+icon;
$("#notif-box").addClass(notifBoxClass);
$("#icon-box").addClass(iconClass);
// this is the issue
$("#head-title").append(alertTitle);
$("#alert-message").html(text);
setTimeout(function () {
$("#notif-box").fadeOut();
}, 5000);
}
When I hit first time add button, head title is 'Success!'
When hit second time head title is 'Succsss!Success'!
Third is ''Success!Success!Success!'
Other elements work as expected! Can not figure where the problem is!

Instead of appending again and again, simply replacing the text should solve the issue.
Change
$("#head-title").append(alertTitle);
To
$("#head-title").html(alertTitle);

Related

Is it possible to update modal content via javascript? [resolved]

[Resolved - I had two modals defined with different Ids but when I disabled one, it worked as expected. Changed it so all content goes through one modal. At some point I may revisit to figure out where the conflict was.]
I have a mvc core page on which I have a modal that uses a partial view. In the modal, I'd like to present a summary list and let the user click an item in the list to view additional details on the modal. However, while the element is reporting it has been changed (via an alert check) it is not visibly updated. I then created a simple test to change the background color of a div to see if the approach itself is valid.
In this case the alerts identify that the color was changed, but again, it does not visually change. So the question is, how can I dynamically update text or CSS within a modal dialog using a js/jquery function? Is it even possible? I'm not interested in reloading the modal.
My test modal content (_TestContentModal):
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close" id="closeMe"><span aria-hidden="true">×</span></button>
</div>
<div class="modal-body">
<div id="test">
background color test
</div>
<div>
<button onclick="UpdateDetails('yellow');">Change background to yellow</button>
</div>
</div>
<div class="modal-footer">
<button data-dismiss="modal" id="cancel" class="btn btn-default" type="button">Close</button>
</div>
</div>
<script>
function UpdateDetails(newColor) {
alert('Before change: ' + $('#test').css("background-color")); // Before change: rgba(0, 0, 0)
$('#test').css("background-color", newColor);
alert('After change: ' + $('#test').css("background-color")); // After change: rgba(255, 255, 0)
// clicking a second time confirms that the color was updated:
// Before change: rgba(255, 255, 0)
// After change: rgba(255, 255, 0)
}
</script>
Clicking the button properly triggers the function and the alerts show/confirm that the background color is being changed, however it is not visibly changed. A second button click confirms the new color was set.
I'm relatively new to modals and it is quite possible that I'm going about this entirely the wrong way. Thanks in advance for any advice or solution.
Edit:
Including some additional code in response to initial answer. Since the above code seems to function as intended elsewhere the problem must lie in the handling of the modal.
On parent page is the reference to the modal:
<partial name="_TestModal" />
This is the content of _TestModal.cs:
<!--Modal-->
<div aria-hidden="true" aria-labelledby="modal-test-label" role="dialog" tabindex="-1" id="modal-test" class="modal fade">
<div class="modal-dialog modal-lg">
</div>
</div>
A button on the parent page activates the modal:
<div>
<a class="btn btn-secondary popup"
style="color: black;"
data-url='#Url.Action("GetTest","Runways")'
data-toggle="modal"
data-target="#modal-test">
Update<i class="fa fa-plus"></i>
</a>
</div>
The GetTest action of the controller returns the partial that contains the modal content shown at the top:
return PartialView("_TestContentModal");
And finally, the parent page has this script to handle the modal:
(function ($) {
function Index() {
var $this = this;
function initialize() {
$(".popup").on('click', function (e) {
modelPopup(this);
});
function modelPopup(reff) {
var url = $(reff).data('url');
$.get(url).done(function (data) {
$('#modal-test').find(".modal-dialog").html(data);
$('#modal-test > .modal', data).modal("show");
});
}
}
$this.init = function () {
initialize();
};
}
$(function () {
var self = new Index();
self.init();
});
}(jQuery));
To be clear: the color is not visibly changing. There are no errors reported in the browser console so the alerts were added to see how the element was responding. Minus the alerts, Brando Zhang's answer demonstrates the expected behavior, but in my case it does not turn yellow, with or without the timer delay. And again, the alerts were only added as a debug aid.
Do you mean you want to show the test backgournd color to yellow before the alert After change?
If this is your requirement, I suggest you could try to use setTimeout to not fired the alert immediately.
More details, you could refer to below codes:
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close" id="closeMe"><span aria-hidden="true">×</span></button>
</div>
<div class="modal-body">
<div id="test">
background color test
</div>
<div>
<button onclick="UpdateDetails('yellow');">Change background to yellow</button>
</div>
</div>
<div class="modal-footer">
<button data-dismiss="modal" id="cancel" class="btn btn-default" type="button">Close</button>
</div>
</div>
<script>
function UpdateDetails(newColor) {
alert('Before change: ' + $('#test').css("background-color")); // Before change: rgba(0, 0, 0)
$('#test').css("background-color", newColor);
setTimeout(function () { alert('After change: ' + $('#test').css("background-color")); }, 1)
// After change: rgba(255, 255, 0)
// clicking a second time confirms that the color was updated:
// Before change: rgba(255, 255, 0)
// After change: rgba(255, 255, 0)
}
</script>
Result:

Modal won't close and prevent default on no click, and won't execute func on yes click

I have a modal with two buttons. One is a yes button and one is a no button. If yes button is pressed, I would like the remainder of the function to execute. If no btn clicked, I would like the page to prevent default and not execute. However, it seems that regardless of which button is clicked, nothing happens besides the modal closing. I am using a modal example I found elsewhere, so this may be the issue. After glancing at it for some time I cannot seem to find where the issue is. Am I missing something small? Or perhaps my Jquery is wrong? Below is my code:
Modal:
<!-- Modal for delete-->
<div class="modal fade" id="deleteModal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content border-primary mb-3 box-shadow-none img-responsive">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="card-body bg-light">
<div id="del" class="center">
<label>Are you sure you want to delete?</label>
</div>
</div>
<div class="modal-footer">
<div id="deleteYes">
<button type="button" class="btn btn-default" data-dismiss="modal" id="deleteYes">Yes</button>
</div>
<div id="deleteNo">
<button type="button" class="btn btn-default" data-dismiss="modal" id="deleteNo">No</button>
</div>
</div>
</div>
</div>
</div>
And here is my Jquery:
$(".btnDeleteTerminalCommand").click(function (e) {
$("#deleteModal").modal('toggle');
if ($("#deleteNo").click) {
return e.preventDefault();
}
var rowId = "#" + $(this).data("rowindex");
var row = $(rowId);
var termId = row.find(".tdTermId").html().trim();
var cmdId = row.find(".tdCmdId").html().trim();
var cmdVal = row.find(".tdCmdVal").html().trim();
var cmdID = row.find(".cmdID").html().trim();
var data = {
TerminalID: termId,
CommandID: cmdId,
CommandValue: cmdVal,
ID: cmdID
};
$.ajax({
url: '#Url.Action("DeleteTerminalCommand", "TerminalCommand")',
type: "POST",
data: data,
success: function (response) {
console.log("Success");
window.location.href = response.Url;
}
});
});
Any advice helps! Thank you!
Your click handler will toggle the modal and immediately continue to execute the rest of the function before the user can click anything. If your modal has two buttons, create a click handler for each button. Perhaps the No button just closes the modal. The Yes button handler can execute the actions required to accomplish the task.
$(".btnDeleteTerminalCommand").click(function(e){
$("#deleteModal").modal('toggle');
}
$("#deleteNo").click(function(e){
$("#deleteModal").modal('hide');
}
$("#deleteYes").click(function(e){
// build data object
// ajax post
}

Changing data in bootstrap modal

I'm working on jeopardy game where I pass questions into a bootstrap modal based on the button clicked. The button has an attribute data-num, (the index in the array of questions), which is used to to change the title in the modal. It also passes this index as an attribute data-num to the reveal answer button, which, when clicked, will change modal title to the answer.
This works for the first question, but when I click on the second question, the proper question loads, but the answer to the first question loads when I click the getanswer button, even though the proper index shows up in inspect element under button data-num.
What am I doing wrong?
var questions = [{
prompt: "What generic data type should we use when we want to use varying data types for a variable?",
correctAnswer: "Object",
},
{
prompt: "Rewrite the following Javascript statment in C#: var flag = true ",
correctAnswer: "bool flag = true"
},
{
prompt: "double num1 = 9.34534910;\n int num2= (int)num1;\nSystem.Console.WriteLine(num2);",
correctAnswer: "9"
}
];
function showQuestion(event, $modal) {
var button = $(event.relatedTarget);
var num = parseInt(button.data('num'));
var question = questions[num];
$modal.find('.modal-title').text(question.prompt);
$modal.find('.modal-body button').attr('data-num', num)
}
$("#myModal").on('show.bs.modal', function(event) {
showQuestion(event, $(this));
}
);
$("#myModal").on('hidden.bs.modal', function() {
$('#myModal').removeData('bs.modal');
}
);
$("#getanswer").click(function() {
var num = ($(this).data('num'));
console.log(num)
}
)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="bs-example">
<!-- Modal HTML -->
<div id="myModal" class="modal fade">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-body">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<p class="modal-title" data-answer="">Modal Window</p>
<button id="getanswer" type="button" data-num="" class="btn btn-primary clickable">Reveal answer</button>
</div>
</div>
</div>
</div>
<div class="question">
<button type="button" class="btn btn-info gridbtn ten" data-toggle="modal" data-target="#myModal" data-num="0">$10</button>
</div>
<div class="question">
<button type="button" class="btn btn-info gridbtn fifty" data-toggle="modal" data-target="#myModal" data-num="1">$50</button>
</div>
</div>
Use this (on the #getAnswer click event):
var num = ($(this).attr('data-num'));
instead of
var num = ($(this).data('num'));
Perhaps since you set the value with attr, it also works to retrieve it that way.
It DOES seem like your way should work, but this is what I found through trying stuff.

Why is my button propagating event to its parent?

I've made a small trick in a div where I put my own "data" precising what to do if the user clicks on it.
My JavaScript code looks like (lot of code omitted for sake of clarity):
$('[data-hqf-switch]').click(function() {
var t = $(this).attr('data-hqf-switch').split('/'),
i = 0;
if (t % 2) {
alert('Burn the dev. Its the dev. himself who wrote that.');
return;
}
while (i < t.length) {
var ev = sw(t[i++], '$')+'.'+sw(t[i++], 'd')+';';
eval(ev);
}
});
Now in my HTML I have something like that:
<div class="col-lg-12" data-hqf-switch="$.pt().pv()/Xd/$.pt()/Xu">
<h4>25 mars 2016 22:07 - You wrote...</h4>
<p>J'ai refusé votre invitation</p>
<button type="button" class="btn btn-default"
data-toggle="modal"
data-target="#modal-msg-7-24" title="Répondre">
<i class="fa fa-envelope-o"></i> Répondre
</button>
<div class="modal fade" id="modal-msg-7-24" tabindex="-1"
role="dialog"
aria-labelledby="Envoyer un message" aria-hidden="true"
style="display: none;">
<div class="modal-dialog">
<div class="modal-content">
</div>
</div>
</div>
<button class="btn btn-warning"
data-hqf-switch="$.pt().pt().pv()/Xd/$.pt().pt()/Xu">
Fermer
</button>
</div>
The most important is the first button: when clicked it shows the modal dialog box which is declared just after the button.
Everything should work fine except that when you click on the button it's like you click on the button and on the "surrounding" div because the event of the div is launched too.
What am I missing?
Event propagation means the event is handled for the clicked element and all ancestors.
You may want to look into event.stopPropagation().
I believe your small trick will eventually make you regret the day you invented it if you're doing anything moderately complicated.
The solution is here. And it's not a duplicate, even though it's close to.
I just test if the element the user "has pushed" has actually the "switch data". If not, I return instantaneously because I suppose (and I dont imagine a case where it's not) that it's one of the children of this element, not the element itself.
$('[data-hqf-switch]').click(function(e) {
if ($(e.target).filter(':not([data-hqf-switch])').length) {
return;
}
/* ok the target contains a 'data-hqf-switch' attribute */
/* ... blabla ...*/
}

Recommendation system using meteor easysearch

I'm finishing a project whose final challenge is that the system can recommend other websites based on positive vote to a site or comment on it.
The system uses a keywords field on which a search that uses easysearch, and upon which to base I want to make that recommendation system is based.
The algorithm is simple, when the user vote positive to the site the event is all your keywords and sends a easysearch that finds sites with at least one of the keywords, returns only one random site and returns the result in a nice modal message.
The template for the message is:
<template name="recommend_site">
<div class="modal fade" tabindex="-1" role="alertdialog" id="website_recommend">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">×</span></button>
<h4 class="modal-title">{{title}}</h4>
</div>
<div class="modal-body">
<h6 class="text-right">{{momentFormat createdOn}}</h6>
<p>
{{description}}
</p>
See more...
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<span class="badge alert-success">{{votes.Up}}</span>
{{#if currentUser}}
<div class="btn-group" role="group" aria-label="...">
<button class="btn btn-default js-upvote">
<span class="fa fa-thumbs-o-up" aria-hidden="true"></span>
</button>
<button class="btn btn-default js-downvote">
<span class="fa fa-thumbs-o-down" aria-hidden="true"></span>
</button>
</div>
{{/if}}
<span class="badge alert-danger">{{votes.Down}}</span>
</div>
</div>
</div>
</div>
</template>
The event should make use of this search is:
Template.website_item.events({
"click .js-upvote": function (event) {
var website_id = this._id;
var keywords = this.keywords;
console.log("Up voting website with id " + website_id);
Websites.update({_id: website_id},
{$inc: {'votes.Up': 1}});
WebsitesIndex.getComponentMethods().search(keywords);
console.log(keywords);
return false;
}
});
And example of the document website is :
Websites.insert({
title:"Google",
url:"http://www.google.com",
description:"Popular search engine.",
keywords: ['google', 'popular', 'search', 'engine'],
votes:{
Up: 0,
Down: 0
},
createdOn:new Date()
});
As I said before, sarch with easysearch works great, but I can not locate that way to search keywords and taking send the result to the template. As you can see in the event I made an attempt to get the result following the documentation, but then there can not think what else I can do.
Someone can guide me ?
Update
I'm add some code in the event:
WebsitesIndex.getComponentMethods().search(keywords, { limit: 1 });
With limit: 1, i wait get one result for this search, but, i have a problem with this:
Exception in template helper: Error: Match error: Failed Match.OneOf or Match.Optional validation
at check (http://localhost:3000/packages/check.js?9c4972d3f4fe56cd455d3022e70b5195e642fc41:61:15)
at MinimongoEngine.checkSearchParam (http://localhost:3000/packages/easysearch_core.js?a1c2859756f8a6aa5fec4727e1f529e581d0f124:386:7)
at Index.search (http://localhost:3000/packages/easysearch_core.js?a1c2859756f8a6aa5fec4727e1f529e581d0f124:91:26)
at Object.getCursor (http://localhost:3000/packages/easysearch_components.js?aa6c7b1263bc20dda4038492ac0d4fd3c5104ae8:331:26)
at EachComponent.doc (http://localhost:3000/packages/easysearch_components.js?aa6c7b1263bc20dda4038492ac0d4fd3c5104ae8:956:63)
at http://localhost:3000/packages/peerlibrary_blaze-components.js?4eddb4e3f0f660190548347e680d109a51a7050f:1234:23
at http://localhost:3000/packages/blaze.js?9391df93ba5076c2cfc61ee68724eb79b65f00d9:1650:16
at http://localhost:3000/packages/peerlibrary_blaze-components.js?4eddb4e3f0f660190548347e680d109a51a7050f:1287:66
at Function.Template._withTemplateInstanceFunc (http://localhost:3000/packages/blaze.js?9391df93ba5076c2cfc61ee68724eb79b65f00d9:3671:12)
at http://localhost:3000/packages/peerlibrary_blaze-components.js?4eddb4e3f0f660190548347e680d109a51a7050f:1286:27
Well, i can see that problem is a helper problem, so, the global helper for the websiteIndex is:
Template.registerHelper('websiteIndex', () => WebsitesIndex);
But, i don't understand the problem yet.

Categories