jQuery: Confirm box loops on every page refresh - javascript

I am looping through an array of data with each having there own delete button with class="delete_thereid". when the page loads the delete button works fine.. now
after the page loads again (start_timer()) and I try to delete a different record, the native js confirmation box pops up two times.. actually the popup increments each time the page gets refreshed. I really have been at trying to find a solution for this for a few days now with out a success. Here is my code.
var refreshSpeed = 8000;
var intValID = 0;
function get_post ()
{
$.ajax ({
url: "postComments.php",
type: "post",
cache: false,
dataType: "json",
data: {type: "getComments"},
success: function (d) {
var c = [];
var r = [];
v ar cp = [];
//Check for new post, update page.
$(d.results.com).each (function (k, v)
{
if ($("#showComments").find ("div#"+$(v).attr ("id")).length == 0) {
cp.push (v);
}
c.push ($(v).attr ("id"));
if ($.inArray ($(v).attr ("id"), c_hashid) == -1) {
c_hashid.push ($(v).attr ("id"));
}
});
$("#showComments").prepend (cp).fadeIn ("slow");
remove_deleted (c_hashid, c); //remove post
remove_deleted (r_hashid, r); //remove replies
deletePost ();
start_timer ();
//optionBttn ();
return false;
}
});
}
function remove_deleted (ids, r)
{
$.each (ids, function (k, v){
if ($.inArray (v, r) == -1)
{
$("#showComments").find ("div#"+v).slideUp ("slow");
}
});
}
function confirmDelete ()
{
if (confirm ("Are you sure you wish to delete this post?")) {
return true;
}
return false;
}
function deletePost ()
{
$("[class^=delete]").each (function () {
$(this).on("click", function (e)
{
e.preventDefault ();
//stop_timer ();
if (confirmDelete ())
{
$(this).die ("click"); //test
$(this).unbind ().click(); //test
//e.stopPropagation();
//start_timer ();
}
});
});
}
function start_timer () {
intValID = setTimeout (function () {
get_post ();
}, refreshSpeed);
}
function stop_timer () {
clearTimeout (intValID);
}
$(document).ready (function ()
{
$("#cbutton").attr("disabled", "disabled");
$(document).mouseup (function (e)
{
if ($("#layerOne").has (e.target).length === 0)
{
$("div[id^=replybox]").fadeOut ("fast");
}
});
get_post ();
textAreaAnim ();
play_video ();
});
the function that is making the call is deletePost from get_post, you can see what its doing here
EDIT
After all this time!!! and all I had to do was
$("[class^=delete]").on ("click", function (e)
{
if (confirmDelete ())
{
e.stopImmediatePropagation () //<----this!!! this is all I needed
//dorestofstuff ();
}
});
No more incremented confirmation box on each page load. stopImmediatePropagation () is magical!

You could try changing your deletePost method,
Instead of iterating through a set of matching elements you can directly bind an event to them:
function deletePost () {
$("[class^=delete]").on("click", function(e) {
e.preventDefault ();
//stop_timer ();
if (confirmDelete()) {
$(form).die ("click");
$(form).unbind ().click();
//e.stopPropagation();
//start_timer ();
}
});
}

Related

How do I capture if the enter key has been pressed?

I'm trying to capture if the enter key has been pressed and execute a search. This is the viewmodel for the search page.
(function ()
{
a.viewModels.userSearch = function (view, params) {
$view = $(view);
var self = a.viewModel({
users: a.collection({
url: '/admin/Account/SearchUsers',
query: {
SearchText: null
}
}).fetch(),
setPageIndex: setPageIndex,
search: search
});
$view.keypress(function (e) {
if (e.keyCode == 13) {
self.search(e);
}
});
function search(e) {
self.users.query.rowCount = 0;
self.users.query.pageIndex = 1;
self.users.fetch();
}
function setPageIndex(e) {
e.preventDefault();
self.users.query.set('pageIndex', $(e.currentTarget).data('page-index'));
self.users.fetch();
}
return self;
}
Now, this works. The problem is that it works only after pressing the 'Enter' key 2 times. Seems like I'm missing something related to the scope but js ain't my cup of tea.
If it is of any help, here goes my view model function:
function viewModel(viewModelConfig) {
var self = kendo.observable($.extend({
busy: 0,
resultMessage: null,
clearResultMessage: clearResultMessage
}, viewModelConfig));
self.bind('change', onChange);
function onChange(change) {
var errorProp, errorMsg, infoProp, infoMsg;
if (change.field.endsWith('.busy')) {
if (self.get(change.field))
self.set('busy', self.busy + 1);
else if (self.busy > 0)
self.set('busy', self.busy - 1);
}
else if (change.field.endsWith('.resultMessage')) {
var data = self.get(change.field);
self.set('resultMessage', data);
}
}
function clearResultMessage(e)
{
if (e) e.preventDefault();
self.set('resultMessage', null);
return false;
}
return self;
}
I have a similar setup on my site, and using MVVM, just add the custom enter binding within the data-bind attribute of the element to link to the function within the view-model you wish to execute.
The code to add the custom binder is as such:
kendo.data.binders.widget.enter = kendo.data.Binder.extend({
init: function(element, bindings, options) {
kendo.data.Binder.fn.init.call(this, element, bindings, options);
var binding = this.bindings.enter;
$(element.element).keyup(function(e) {
if( e.which === 13 )
bindings.get();
});
},
refresh: $.noop
});

pjax/ajax and browser back button issues

I use pjax to ajaxify my menu links. This works fine until I use the browser back button. In my javascript file I use Common Script files (to load all the necessary js files when the user hits the url) and Script files with respect to each menu links (when navigated through pjax)
function myFunction(){
/*All the script files */
}
$(document).ready(function(){
myFunction();
/*pjax menu loading block*/
$(document).on('click', 'a[data-pjax]', function(event) {
$.pjax.click(event, '#pjax-container');
$(document).on('pjax:end', function() {
myFunction();
});
});
});
Now when I navigate to a menu item and try to come back by clicking the browser back button, the script files are getting duplicated (eg: slider images getting duplicated and table sorting not working).How to overcome this issue?
You can implement the url specific loading this way, create a queue of functions which you want to load and unload on pjax complete
The solution is based on js prototyping
// create queue for load and unload
var onLoad = new PjaxExecQueue();
var onUnload = new PjaxExecQueue();
// way to add functions to queue to run on pjax load
onLoad.queue(function() {
someFunction();
});
// way to add functions to queue to unload on pjax load
onUnload.queue(function() {
someOtherFunction();
});
// load function if url contain particular path name
onLoad.queue_for_url(function_name, 'url_section');
// check for url specific function
var URLPjaxQueueElement = function(exec_function, url) {
this.method = exec_function;
if(url) {
this.url = new RegExp(url);
} else {
this.url = /.*/;
}
};
// create a queue object
var PjaxExecQueue = function () {
this.url_exec_queue = [];
this.id_exec_queue = [];
this.fired = false;
this.indicating_loading = false;
this.content = $('#content');
};
PjaxExecQueue.prototype = {
queue: function (exec_function) {
this.url_exec_queue.unshift(new URLPjaxQueueElement(exec_function));
},
queue_for_url: function (exec_function, url_pattern) {
this.url_exec_queue.unshift(new URLPjaxQueueElement(exec_function, url_pattern));
},
queue_if_id_present: function(exec_function, id) {
this.id_exec_queue.unshift(new IDPjaxQueueElement(exec_function, id));
},
fire: function () {
if(this.indicating_loading) {
this.content.removeClass("indicate-loading");
this.indicating_loading = false;
}
if(!this.fired) {
var match_loc = window.location.pathname;
var i = this.url_exec_queue.length;
while(i--) {
this.url_exec_queue[i].fire(match_loc);
}
i = this.id_exec_queue.length;
while(i--) {
this.id_exec_queue[i].fire(match_loc);
}
}
this.fired = true;
},
reset: function() {
this.fired = false;
},
loading: function () {
this.content.addClass("indicate-loading");
this.indicating_loading = true;
this.reset();
},
count: function () {
return exec_queue.length;
},
show: function (for_url) {
for (var i=0; i < exec_queue.length; i++) {
if(for_url) {
if(exec_queue[i].url.test(for_url)) {
console.log("" + exec_queue[i].method);
}
} else{
console.log(exec_queue[i].url + " : " + exec_queue[i].method);
}
}
}
};
// before send
$(document).on('pjax:beforeSend', function() {
onLoad.loading();
onUnload.fire();
});
// after pjax complete
$(document).on('pjax:complete', function() {
onLoad.fire();
onUnload.reset();
});

Make plugin to element specific

I have following js plugin to catch show hide events of elements. But i want to make it specific to One dom element only, i.e #div_loading_page
jQuery(function ($) {
$.each(['show','hide'], function (i, ev) {
var el = $.fn[ev];
$.fn[ev] = function () {
this.trigger(ev);
el.apply(this, arguments);
};
});
});
can anyone please help. thanks
jQuery(function ($) {
$.each(['show','hide'], function (i, ev) {
var el = $.fn[ev];
$.fn[ev] = function () {
this.each(function () {
if ( this.id == 'div_loading_page') {
$(this).trigger(ev);
return false; // break out of the loop
}
});
el.apply(this, arguments);
};
});
});

Not work true my function?

I want after click on link show alert box with tow option ok and cancel, if user click on button ok return it function is true and if click on button cancel return it function is false, problem is here that after click on link always return is true. How can fix it?
Example: http://jsfiddle.net/MaGyp/
function myalert() {
var result = true;
var $alertDiv = $('<div class="alert">Do you want to delete this item?<button class="ok">ok</button><button class="cancel">cancel</button></div>');
$('body').append($alertDiv);
$('.ok').click(function () {
$('.alert').fadeOut(100);
$('#appriseOverlay').css('display', 'none');
result = true;
});
$('.cancel').click(function () {
$('.alert').fadeOut(100);
$('#appriseOverlay').css('display', 'none');
result = false;
});
$alertDiv.fadeIn(100);
$('#appriseOverlay').css('display', 'block');
return result;
};
$('.iu').click(function () {
alert(myalert());
if (myalert() == true) {
alert('ok')
} else {
alert('no')
}
});
Update:
...
$('.iu').click(myalert)
function callback(result) {
//
if(result){
alert(result);
$('.image_upbg').each(function(){$(this).removeClass().addClass(unique())});
var get_class = '.'+$(this).closest('div').attr('class');
var get_val = $(this).closest('a').find('input').attr('value');
//alert(get_val);
var val = 'val_upimg1=' + get_val;
$(get_class).fadeOut('slow');
$.ajax({
type: "POST",
dataType: 'json',
url: 'delete_upimg',
data: val,
cache: false,
success: function (data) {
$(get_class).fadeOut('slow');
},
"error": function (x, y, z) {
// callback to run if an error occurs
alert("An error has occured:\n" + x + "\n" + y + "\n" + z);
}
});
}else{
alert('no')
}
}
If you want to keep it structured like this, you could use a callback after the user responds.
http://jsfiddle.net/MaGyp/2/
function myalert() {
...do stuff here
$('.ok').click(function () {
callback(true); // callback when user clicks ok
});
$('.cancel').click(function () {
callback(false); // callback when user clicks cancel
});
}
$('.iu').click(myalert);
function callback(result) {
alert(result);
}
As suggested by Ben you could improve this by making the callback function a parameter to the first function to remove the tight coupling.
myalert() returns before result is set to true or false. To fix it I suggest having myalert() take a callback function as a parameter, and calling it inside the click() handlers within myalert(). The .iu event handler will then need to be split into two functions, one of which is the callback passed into myalert().
you are not waiting for the ok and cancel clicks so would always return true.
Modified the fiddle - http://jsfiddle.net/MaGyp/3/
function myalert() {
var result = true;
//var hide = $('.alert').fadeOut(100);
//var css = $('#appriseOverlay').css('display','none');
var $alertDiv = $('<div class="alert">Do you want to delete this item?<button class="ok">ok</button><button class="cancel">cancel</button></div>');
$('body').append($alertDiv);
$alertDiv.fadeIn(100);
$('#appriseOverlay').css('display','block');
return result;
};
$(document).ready(function(){
$('.ok').live('click',function () {
$('.alert').fadeOut(100);
$('#appriseOverlay').css('display','none');
alert('ok');
});
$('.cancel').live('click',function () {
$('.alert').fadeOut(100);
$('#appriseOverlay').css('display','none');
alert('cancel');
});
$('.iu').click(function() {
myalert();
});
})

Javascript function only works once

I have an inline script on my page as such:
<script type="text/javascript">
var rootPath = '<%= Url.Content("~/") %>';
$(document).ready(function () {
$('#logonStatus').click(function () { loadLoginForm(); });
alert('Document Ready');
});
function loadLoginForm() {
if(!serenity.tools.isStyleSheetLoaded('redmond.css')) {
$('head').append('<%= Url.StyleTag("Redmond/redmond.css", MediaTypes.Screen) %>');
}
if(!serenity.tools.elementExists($('#logonContainer'))) {
$.ajax({
async: false,
cache: false,
datatype: 'html',
success: function (data) { $('body').append(data); },
type: 'GET',
url: '/Membership/LogOn'
});
}
$('#logonContainer').dialog({
modal: true,
hide: 'slide'
});
}
</script>
I also am loading a custom javascript file and the contents of it are as such:
var serenity = new function () {
$(document).ready(function () {
jQuery.ajaxSetup({
beforeSend: function (xhr) {
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
}
});
});
this.tools = new function () {
this.isStyleSheetLoaded = function (fileName) {
$(document.styleSheets).each(function () {
if (this.href.toLowerCase().indexOf(fileName) != -1) {
this.isStyleSheetLoaded = true;
return;
}
});
this.isStyleSheetLoaded = false;
}
this.elementExists = function (element) {
this.elementExists = element.length != 0;
}
}
}
The file that is being loaded by the ajax call is simply a div with an table containing input elements. The file does not contain any javascript in it whatsoever.
My problem is that the first time I call isStyleSheetLoaded it works just fine but after the file is loaded and the dialog is shown and closed I click on the link that fires the loadLoginForm function but this time it says isStyleSheetLoaded is not a function. This is showing up in all browsers, so I am 99% sure it is my problem, but I have no idea what it is. Could someone please point me in the right direction?
Thanks in advance.
I think your problem is the following:
you define a function "this.isStyleSheetLoaded = function (fileName)" but in his body you overwride this property "this.isStyleSheetLoaded = true;".
So after your first call of isStyleSheetLoaded the function is overwride with a boolen.
the right way could be:
this.isStyleSheetLoaded = function (fileName) {
$(document.styleSheets).each(function () {
if (this.href.toLowerCase().indexOf(fileName) != -1) {
return true;
}
});
return false;
}

Categories