javascript confirm dialog keeps appearing sometimes - javascript

Hello I'm using confirm dialog to ensure a user action. But the confirm dialog keeps appearing again and again while I don't see in my code anything which is triggering this. Is it a bug? or am I doing something wrong?
$('#table_trans tbody').on('click', 'tr td button', function() {
var trans_id = $($(this).parents(':eq(1)')[0].childNodes[0]).html();
var r = confirm("Sure!");
if (r == true) {
$.ajax({
url: '?r=transactions/ajaxdelete',
data: {
id: trans_id
},
success: function(response) {
$.notify(response, "error");
}
});
$($(this).parents(':eq(1)')).remove();
} else {
alert("Action Cancelled!");
}
});
One more thing to add, It happens only sometimes that the Javascript confirm dialog keeps appearing. sometimes it behaves correctly, sometimes it appears twice, but sometimes infinitely.
UPDATE
As suggested by Parag Bhayani, Here is the javascript that adds a row to the table #table_trans
// msg is a json response received by making an ajax call
for (var i = 0, l = msg.length; i < l; i++) {
var rowz = "<tr><td>" + msg[i].id +"</td><td>"+msg[i].account_no+"</td><td>" + msg[i].date_of_transac +"</td><td>"+msg[i].description+"</td><td>"+msg[i].amount+"</td><td><button id=\"delete_trans\">Delete</button></td><tr>";
tbl_html = tbl_html + rowz;
}
// sorry for the discomfiture .... but please scroll to extreme right to see the button, clicking which is triggering the event.

This could be happen only if your event is registered multiple times, so one case for that could be causing this issue is that, event registeration code is in loop then your event might have registered n number of times.

Related

Javascript function doesn't trigger

$("tbody").on('click', '#update', function () {
$("#UpdateModal").modal("show");
var id = $(this).data("id");
console.log(id);
$.ajax({
type: 'Get',
url: "/Users/GetUser?id=" + id,
data: {
"cusid": id
},
success: function (response) {
console.log(response);
console.log(response.data.userName);
var departments = #Html.Raw(Json.Serialize(#ViewBag.departments));
var duties = #Html.Raw(Json.Serialize(#ViewBag.duties));
var roles = #Html.Raw(Json.Serialize(#ViewBag.roles));
$('#UpdateModal #Id').attr('value', response.data.id);
$('#UpdateModal #UserName').attr('value', response.data.userName);
$('#UpdateModal #FirstName').attr('value', response.data.firstName);
$('#UpdateModal #LastName').attr('value', response.data.lastName);
$('#UpdateModal #Password').attr('value', response.data.password);
$("#UpdateModal #DepartmentId option:first-child").prop("selected", "selected").text(response.data.departmentName);
$("#UpdateModal #DutyId option:first-child").prop("selected", "selected").text(response.data.dutyName);
$("#UpdateModal #RoleId option:first-child").prop("selected", "selected").text(response.data.roleName);
if (response.data.isActive) {
$("#UpdateModal #IsActive #true").prop("selected", "true")
console.log(response.data.isActive);
}
else {
$("#UpdateModal #IsActive #false").prop("selected", "false")
console.log(response.data.isActive);
}
for (var i = 0; i < departments.length; i++) {
if (response.data.departmentName == departments[i].departmentName) { $("#UpdateModal #DepartmentId option:first-child").prop("selected", "selected").val(departments[i].id); }
}
for (var i = 0; i < duties.length; i++) {
if (response.data.dutyName == duties[i].dutyName) {
$("#UpdateModal #DutyId option:first-child").prop("selected", "selected").val(duties[i].id);
}
}
for (var i = 0; i < roles.length; i++) {
if (response.data.roleName == roles[i].roleName) { $("#UpdateModal #RoleId option:first-child").prop("selected", "selected").text(response.data.roleName).val(roles[i].id); }
}
}
});
});
What I want to do here is to pull the data into my update modal with API. But it can't do it. Actually it was working before but suddenly the code stopped working. Can anyone see the error?
What do I need to do for this function to work? It gets triggered when I use the same code in another view. But it never gets triggered here. Please help.
There could be multiple reasons why this code is not working. Here are a few possible solutions:
1 - Check if the target element (#update) exists in the DOM when the click event handler is attached to it. If the element is dynamically generated, you may need to use event delegation, as follows:
$("tbody").on('click', '#update', function() {}
2 - Verify if the AJAX request is being sent and if the server is returning a valid response. You can use the browser's network tab or your browser's developer tools to see the network requests and the responses.
3 - Check the values of id, departments, duties, and roles in the console. They should have valid values.
4 - Ensure that the selectors used in the code are correct and that they match the actual HTML structure. You can use your browser's developer tools to inspect the elements and see if the selectors match the elements.
5 - Make sure that the jQuery library is loaded correctly and that there are no errors in the console.

How do you repeatedly click two buttons when you have to wait for the second button to appear?

I am working on a simple script that loops through all elements on a page and shares them in vanilla JavaScript. Here is what I have so far
var buttons = document.getElementsByClassName('share-gray-large');
for(var i=0; i<buttons.length; i++){
buttons[i].click();
document.getElementsByClassName('internal-share__link')[0].click();
}
The share-gray-large button is the class of the "share" buttons. Once the first share button is clicked, a modal appears that asks the user where they want to share the items to. I need to click the first item in the modal with class name internal-share__link. The problem that I am running up against is the fact that the last line of my code results in the following error
Uncaught TypeError: Cannot read property 'click' of undefined
which makes sense, as the modal hasn't appeared yet at the time of the second click() function being called. I need to wait for the element to appear, then click it, then wait until the modal disappears to share the next item. I've looked into async/await functions, setTimeout(), and the solutions from similar StackOverflow questions. I adapted this secondary solution
var waitForEl = function(className, callback) {
if (document.getElementsByClassName(className).length) {
callback();
} else {
setTimeout(function() {
waitForEl(className, callback);
}, 100);
}
};
var buttons = document.getElementsByClassName('share-gray-large');
for(var i=0; i< buttons.length; i++){
waitForEl('share-gray-large', function() {
document.getElementsByClassName('share-gray-large')[i].click();
});
waitForEl('internal-share__link', function() {
document.getElementsByClassName('internal-share__link')[0].click();
});
}
which kind of works, but I believe that it actually ends up sharing the last item multiple times instead of sharing all of them in order. I ran into this issue of needing to wait for a button to appear as well with a different project, so any help would be greatly appreciated!
TL;DR I'm working on projects with the following sequence of steps. Using a page with 3 items that need to be shared:
Click "share" on first button
Wait for confirmation button to appear in a modal
Click confirm
Wait for modal to disappear
Click "share" on second button
Repeat steps 2-4
Click "share" on third button
Repeat steps 2-4
How do you do this in VanillaJS?
This will click from the last to first share button, email share exluded and make sure the browser is allowed to click/open multiple popup.
function waitForElement(selector) {
var element = document.querySelectorAll(selector);
if (element.length) {
if (shareLinkCount == 999) { // set to real number of elements
shareLinkCount = element.length;
}
shareLinkCount--;
var shareElement = element[shareLinkCount];
if(shareElement.textContent != "Email") // Do not click email share
element[shareLinkCount].click();
if (shareLinkCount) { // not 0
setTimeout(clickShareButton, 500);
}
else{
alert('Click Finished');
document.body.click();
}
} else {
setTimeout(waitForElement, 500, selector);
}
}
function clickShareButton() {
var button = document.querySelector('.share-gray-large');
button.click();
waitForElement('internal-share__link');
}
var shareLinkCount = 999; // dummy number
clickShareButton();
This is the answer that worked for me. Credit goes to #uingtea for most of the solution. Since I did not post the link to the website, I was able to test it and modify their solution to suit my needs.
function waitForElement(selector) {
var element = document.querySelector(selector);
if (element) {
shareLinkCount--;
element.click();
if (shareLinkCount) { // not 0
setTimeout(clickShareButton, 500);
}
else{
element.click();
alert('Click Finished');
}
} else {
setTimeout(waitForElement, 500, selector);
}
}
function clickShareButton() {
document.querySelectorAll('.share-gray-large')[shareLinkCount].click();
waitForElement('.internal-share__link');
}
var shareLinkCount = document.querySelectorAll('.share-gray-large').length - 1;
clickShareButton();

AJAX call not firing from inside if statement

I have the following code. There is a button in the UI that when clicked executes the if statement. I pass in a URL from a database and compare it to the current URL the user is on. If they match I want to run the code below, else I want to open the correct tab then run the code below.
With this code below I mean everything below starting from $('#sceanrioDropdownList').change(function () {...}. The code then checks a drop down and gets the selected Id from which an AJAX call is made to my web API that uses that Id in a stored procedure to return the results. The returned data is then iterated over and stored in variables which I am using to append to specific inputs, buttons and drop downs.
This is what I have so far and I think I have developed this correctly. The issue that I am currently having is that the UI wants everything from ... to be run if the if statement is true. I have tried CTRL+C and CTRL+V to copy the code into the if statement. I have also tried putting it in a new function and referencing that function n the if statement. Both do not work and I was using console.log to inspect the returned data.
It does however when I attempt to call it from inside i statement it doesn't return any data or error. It just doesn't seem to fire.
Is there a way in which I can achieve the functionality I desire? Do you have any suggestions as to if I have done something wrong. Thanks in advance.
$('#automate').click(automateButton);
function automateButton() {
if (webpageUrl == activeTabUrl) {
// do nothing
} else {
// Window opens
window.open(webpageUrl);
}
}
$('#scenarioDropdownList').change(function() {
var scenarioId = $('#scenarioDropdownList option:selected').prop('id');
getData(scenarioId);
});
function getData(scenarioId) {
$.ajax({
type: "GET",
url: 'http://localhost:54442/api/scenariodatas/GetScenarioData',
data: {
scenarioId: scenarioId
},
dataType: 'JSON',
success: scenarioData,
error: function() {
console.log("There has been an error retrieving the data");
}
});
}
function scenarioData(response) {
$.each(response, function(key, val) {
var fieldType = val.fieldType;
var fieldName = val.fieldName;
var fieldValue = val.fieldValue;
var field = $(fieldName);
if (field != undefined) {
switch (fieldType) {
case "Input":
$(field).val(fieldValue);
break;
case "Button":
$(field).click();
break;
case "Select":
$(field).val(fieldValue);
break;
}
}
})
}
onChange don´t work well with buttons because onChange detect a change in the value of your component, because of this, it´s highly recommended to use onClick when you use a button.
$('#scenarioDropdownList').click(function() {
var scenarioId = $('#scenarioDropdownList option:selected').prop('id');
getData(scenarioId);
});
I recommend you to put alerts when you are trying to test this sort of JS
EJM:
$('#scenarioDropdownList').change(function() {
alert('button active');
var scenarioId = $('#scenarioDropdownList option:selected').prop('id');
getData(scenarioId);
});
this alert allow you to know if the code is firing or not

JQuery $.post callback firing a function that never finishes

Here's the problem. I'm making a callback to the server that receives an MVC partial page. It's been working great, it calls the success function and all that. However, I'm calling a function after which iterates through specific elements:
$(".tool-fields.in div.collapse, .common-fields div.collapse").each(...)
Inside this, I'm checking for a specific attribute (custom one using data-) which is also working great; however; the iterator never finishes. No error messages are given, the program doesn't hold up. It just quits.
Here's the function with the iterator
function HideShow() {
$(".tool-fields.in div.collapse, .common-fields div.collapse").each(function () {
if (IsDataYesNoHide(this)) {
$(this).collapse("show");
}
else
$(this).collapse("hide");
});
alert("test");
}
Here's the function called in that, "IsDataYesNoHide":
function IsDataYesNoHide(element) {
var $element = $(element);
var datayesnohide = $element.attr("data-yes-no-hide");
if (datayesnohide !== undefined) {
var array = datayesnohide.split(";");
var returnAnswer = true;
for (var i in array) {
var answer = array[i].split("=")[1];
returnAnswer = returnAnswer && (answer.toLowerCase() === "true");
}
return returnAnswer;
}
else {
return false;
}
}
This is the way the attribute appears
data-yes-no-hide="pKanban_Val=true;pTwoBoxSystem_Val=true;"
EDIT: Per request, here is the jquery $.post
$.post(path + conPath + '/GrabDetails', $.param({ data: dataArr }, true), function (data) {
ToggleLoader(false); //Page load finished so the spinner should stop
if (data !== "") { //if we got anything back of if there wasn't a ghost record
$container.find(".container").first().append(data); //add the content
var $changes = $("#Changes"); //grab the changes
var $details = $("#details"); //grab the current
SplitPage($container, $details, $changes); //Just CSS changes
MoveApproveReject($changes); //Moves buttons to the left of the screen
MarkAsDifferent($changes, $details) //Adds the data- attribute and colors differences
}
else {
$(".Details .modal-content").removeClass("extra-wide"); //Normal page
$(".Details input[type=radio]").each(function () {
CheckOptionalFields(this);
});
}
HideShow(); //Hide or show fields by business logic
});
For a while, I thought the jquery collapse was breaking, but putting the simple alert('test') showed me what was happening. It just was never finishing.
Are there specific lengths of time a callback function can be called from a jquery postback? I'm loading everything in modal views which would indicate "oh maybe jquery is included twice", but I've already had that problem for other things and have made sure that it only ever includes once. As in the include is only once in the entire app and the layout is only applied to the main page.
I'm open to any possibilities.
Thanks!
~Brandon
Found the problem. I had a variable that was sometimes being set as undefined cause it to silently crash. I have no idea why there was no error message.

Jquery scroll is not picking changed variable value to be sent to ajax

I am not a regular programmer and has learnt whatever programming I know by google or by asking things here from Stackoverflow.
I am trying to create a ajax function which will fetch feeds from database on scrolling based on selected parameter. User can select either to select public feeds or personal feeds. His chosen value is updated in hidden text field. Code follows as below.
//feed menu switch between personal and public
$('.menu_selection').iCheck({
checkboxClass: 'icheckbox_square',
radioClass: 'iradio_square-blue',
increaseArea: '20%' // optional
});
$("body").on("ifChecked",".menu_selection",function(){
var feed_menu_selected = $(this).val();
$("#feed_menu_selected").val(feed_menu_selected);
$("#member_menu_area").html(loader);
IndexFeederLoader('0','0','0');
});
Now this is function which is fetching records where group_no is the record set being fetched, total_m_group is total number of records, feed_menu_selected is the choice between public or private.
function IndexFeederLoader(group_no,total_m_group,movie_shown){
var feed_menu_selected = $("#feed_menu_selected").val();
$.ajax({
url: '../index-feeds.php',
type: "POST",
dataType:"text",
data: 'feed_menu_selected='+feed_menu_selected+'&group_no='+group_no+'&movie_shown='+movie_shown,
cache: false,
async: false,
success: function(data){
if(group_no == 0)
{
$("#member_menu_area").html(data);
//when personal is checked and not signed in
var notsigned = $(data).filter('#notsigned').text();
if( notsigned !== '')
{
$("#SignInForPersonal").show();
}
}
else
{
$("#member_menu_area").append(data);
}
total_m_group = $("#total_page_no").text();
$("#total_m_group").remove(); // removing extra
movie_shown = $("#movie_shown").text();
$("#movie_shown").remove(); // removing extra
},
complete: function(){
$(window).on("scroll",function(){
var closeToBottom = ($(window).scrollTop() + $(window).height() > $(document).height() - 500);
var AtBottom = ($(window).scrollTop() + $(window).height() == $(document).height());
if (closeToBottom || AtBottom)
{
if( total_m_group != 0 )
{
if( group_no < total_m_group )
{
group_no++;
IndexFeederLoader(group_no,total_m_group,movie_shown); // group_no is not changing
}
}
else
{
group_no = 0;
}
}
});
},
error:function (xhr, ajaxOptions, thrownError){
alert(thrownError);
}
});
}
Now the problem. If I do not switch between public and personal, everything goes well and I get records in order of group_no set. But when I select personal and then come back to private, it does not work giving feeds from start but from where it has left. It seems like group_nois not changing.
Thanks for reading. It would be great if anyone can help me pls.
First problem i can see - in your $.ajax in complete callback you attach new event on $(window) each time it's executed. So when you execute 2 times it'll be 2 events called and so on. Change logic to attaching event once and changing context of it if it's needed.
Second - don't mix up variable types. You're executing IndexFeederLoader passing Strings, but using Numbers
JsFiddle to understand what's happening
So, like you're doing - i'm attaching an event over and over again, passing context variable. Try pressing button - it will fire a lot of different events with it's own context eventually. That is what probably causing bugs in your code.

Categories