Initialize Anonymous function after ajax call - javascript

Hi I have a template where the scripts are initialized in this file like this
;(function ($) {
"use strict";
var $body = $('body');
var $head = $('head');
var $header = $('#header');
var transitionSpeed = 300;
var pageLoaded = setTimeout(addClassWhenLoaded, 1000);
var marker = 'img/marker.png';
The problem is i have tried to name the function and call it in my ajax code, with no luck
here is my ajax code, how can i initialize again so tabs and bootstrap progress bar work again. in the loaded code?
$(document).ready(function(){
var form = $('#prevjob_form');
var submit = $('#prevjob_submit');
form.on('submit', function(e) {
// prevent default action
e.preventDefault();
// send ajax request
$.ajax({
url: '<?php echo $this->make_url("user/prevjobs/"); ?>',
type: 'POST',
cache: false,
data: form.serialize(), //form serizlize data
beforeSend: function(){
// change submit button value text and disabled it
submit.val('Añadiendo...').attr('disabled', 'disabled');
},
success: function(data){
// Append with fadeIn see http://stackoverflow.com/a/978731
var item = $(data);
$('.prevjobs').empty().append(item);
//ready();
// progress();
//I try to name it progress and call it here, but this wont work
var objDiv = document.getElementById("prevjobs");
objDiv.scrollTop = objDiv.scrollHeight;
// reset form and button
form.trigger('reset');
submit.val('Añadir Gol').removeAttr('disabled');
},
error: function(e){
console.log(e);
}
});
});
});
I try to wrap the progress bar code just to test, and name a function.
like this
<script>
function progress(){
$('.progress-bar').each(function () {
var $this = $(this),
progress = $this.data('progress');
if (!$this.hasClass('no-animation')) {
$this.one('inview', function () {
$this.children('.progress-bar-inner').children('span').css('width', progress + '%');
});
} else {
$this.children('.progress-bar-inner').children('span').css('width', progress + '%');
}
if ($this.hasClass('toggle')) {
$this.children('.progress-bar-toggle').on('click', function (event) {
event.preventDefault();
if (!$this.hasClass('active')) {
$this.children('.progress-bar-content').slideDown(250, function () {
$this.addClass('active');
});
} else {
$this.children('.progress-bar-content').slideUp(250, function () {
$this.removeClass('active');
});
}
});
}
});
}
</script>
But again after the Ajax call progress bar are not working.

Your issue is that your function and the call to it are in different scopes.
When you define a function or a variable inside an on load function like this $(document).ready(function(){ .... or like this ;(function ($) {... you can only access those function or variables from within the scope of that closure.
Here is an example:
$(document).ready(function(){
function myFunction(msg){
console.log(msg);
}
myFunction('this will work')
});
$(document).ready(function(){
myFunction('but this never will');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
You'll need to move the function to the global scope or move the call to it to the same scope as the function itself
Another solution would be to access the function through the document object like this:
;(function ($) {
$.fn.myFunction = function (msg) {
console.log(msg);
}
})(jQuery);
$(document).ready(function(){
$(document).myFunction('called from outside the original scope');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Related

How can I check if a jQuery loaded PHP file changes and execute function if changed?

I am trying to make a dynamic dashboard that refreshes every x seconds to deliver new data from a PHP file. I want this to issue an Alert whenever there is a change in the data delivered, not whenever the data is refreshed. I am using require.js, watch.js and jQuery. I can`t get it to issue alert on changes on #tfpromo or the variable refreshId. Is there a way to do this in jQuery, JS or Watch.js?
PHP file:
$mainbalance = "foo";
echo $mainbalance;
Index.html:
<div id="tfpromo"></div>
<script>
require(['watch', 'jquery'], function(WatchJS, $) {
var watch = WatchJS.watch;
var unwatch = WatchJS.unwatch;
var callWatchers = WatchJS.callWatchers;
$(document).ready(function () {
$("#tfpromo").load("php/dataload.php");
var refreshId = setInterval(function load2(){
$("#tfpromo").load("php/dataload.php");
}, 4000);
watch(refreshId, function(){
alert("balance changed!");
});
});
});
</script>
watch.js is for monitoring the value of JavaScript objects. So put the balance amount in an object, and update the object in the .load() callback.
var watch = WatchJS.watch;
var unwatch = WatchJS.unwatch;
var callWatchers = WatchJS.callWatchers;
$(document).ready(function () {
var balanceObj = {balance: 0};
$("#tfpromo").load("php/dataload.php", function() {
balanceObj.balance = $(this).text();
watch(balanceObj, "balance", function() {
alert("Balance changed!");
});
});
var refreshId = setInterval(function load2(){
$("#tfpromo").load("php/dataload.php", function() {
balanceObj.balance = $(this).text();
});
}, 4000);
watch(refreshId, function(){
alert("balance changed!");
});
});
});

Why doesn't the setInterval function stop?

I'm trying to clear the time interval which runs every 15 seconds.
Here is the ajax request:
function extras()
{
$x = {
action:'extras'
};
var r;
$.ajax({
type:'POST',
url:'services.php',
data:$x,
beforeSend:function() {
$('input[name="stop_"]').trigger("click");
},
success:function(response) {
r = response;
//console.log(response)
},
complete:function() {
console.log(r);
$('input[name="re_start"]').trigger("click");
}
});
}
So, in my buttons re_start and stop_ i have:
$('input[name="re_start"]').click(function (event) {
event.preventDefault();
clearInterval(check);
var check = setInterval(function() {
extras();
},15000);
console.log('Starting again...');
});
$('input[name="stop_"]').click(function (event) {
event.preventDefault();
clearInterval(check);
console.log('Stop');
});
In my DOM in jQuery I initialize the function extras() and keep it in a variable called "check" where I initialize the time interval as follows:
<input type="button" style="display:none;" name="re_start">
<input type="button" style="display:none;" name="stop_">
<script type="text/javascript">
(function() {
extras();
var check = setInterval(function() {
extras();
},15000);
})();
function extras()
{
$x = {
action:'extras'
};
var r;
$.ajax({
type:'POST',
url:'services.php',
data:$x,
beforeSend:function() {
$('input[name="stop_"]').trigger("click");
},
success:function(response) {
r = response;
//console.log(response)
},
complete:function() {
console.log(r);
//message_smart(r);
$('input[name="re_start"]').trigger("click");
}
});
}
</script>
Then I can not understand how it is possible that the first 30 seconds work and when they pass 60 seconds seem to start doing things twice at once, then three and so on! It seems like if I change the interval every second and will run faster and faster. What is the problem?
The problem is here:
(function() {
extras();
var check = setInterval(function() {
extras();
},15000);
})();
You are creating a variable check in a new function scope that is inaccessible outside of that scope. Microsoft has a good example of scope in javascript. Additionally you can see this question.
Now to solve your problem you need to put the check variable in the global scope so remove the function wrapper.
extras();
var check = setInterval(function() {
extras();
},15000);
You also need to change the restart handler to reassign the variable, like so:
$('input[name="re_start"]').click(function (event) {
event.preventDefault();
clearInterval(check);
check = setInterval(function() {
extras();
},15000);
console.log('Starting again...');
});
Now they should all be using the same check variable and work as expected when clearing the timeout.

2 javascripts are conflicting

I have 2 javascripts that are conflicting with eachother, the newer one (Zeroclipboard) conflicts with the older one (delete row) and won't let the delete row one work. The moment i removed the zeroclipboard one, delete worked.
Tried adding jQuery.noConflict(); but didn't seem to work. By reading few solutions, I decided to remove $ signs, but still no.
I have a files.php file, including the header.php file. I am adding the custom.js file in header.php, which holds many functions for operations across the project, including the delete row function. Whereas, the newer script for ZerClipboard is in files.php itself.
Older one, to delete a table row on delete icon click, which won't work after I add the next:
custom.js
function deleteRow()
{
var current = window.event.srcElement;
while ( (current = current.parentElement) && current.tagName !="TR");
current.parentElement.removeChild(current);
}
$(document).ready(function()
{
$('table#delTable td a.delete').click(function()
{
if (confirm("Are you sure you want to delete?"))
{
var fid = $(this).parent().parent().attr('fid');
var str=$(this).attr('rel');
var data = 'fid=' + $(this).attr('rel') + '&uid=' + $(this).parent().attr('rel');
var deletethis = '#tr' + $(this).attr('rel');
var parent = $(this).parent().parent();
$.ajax(
{
type: "POST",
url: "delete.php",
data: data,
cache: false,
success: function(msg)
{
$(deletethis).fadeOut('slow', function() {$(this).remove();});
}
});
}
});
$('table#delTable tr:odd').css('background',' #FFFFFF');
});
ZeroClipboard's JS and SWF, along with this js to copy some text on clipboard on Share icon click:
files.php
<script type="text/javascript" src="js/ZeroClipboard.js"></script>
<script language="JavaScript">
var clip = null;
function $(id) { return document.getElementById(id); }
function init()
{
clip = new ZeroClipboard.Client();
clip.setHandCursor( true );
}
function move_swf(ee)
{
copything = document.getElementById(ee.id+"_text").value;
clip.setText(copything);
if (clip.div)
{
clip.receiveEvent('mouseout', null);
clip.reposition(ee.id); }
else{ clip.glue(ee.id); }
clip.receiveEvent('mouseover', null);
}
</script>
I used this blog post for implementing multiple zerclipboard - http://blog.aajit.com/easy-multiple-copy-to-clipboard-by-zeroclipboard/
And, here's the HTML source generated by the files.php page - http://jpst.it/tlGU
Remove the follow function definition of your second script:
function $(id) { return document.getElementById(id); }
Because this is redefining your $ object in window context, due when you use $ in your first script you're not using jquery, instead you're using your new function definition.
Hope this helps,
Here is how you should use noConflict() :
function deleteRow()
{
var current = window.event.srcElement;
while ( (current = current.parentElement) && current.tagName !="TR");
current.parentElement.removeChild(current);
}
jQuery.noConflict(); // Reinitiating $ to its previous state
jQuery(document).ready(function($) // "Protected" jQuery code : $ is referencing jQuery inside this function, but not necessarily outside
{
$('table#delTable td a.delete').click(function()
{
if (confirm("Are you sure you want to delete?"))
{
var fid = $(this).parent().parent().attr('fid');
var str=$(this).attr('rel');
var data = 'fid=' + $(this).attr('rel') + '&uid=' + $(this).parent().attr('rel');
var deletethis = '#tr' + $(this).attr('rel');
var parent = $(this).parent().parent();
$.ajax(
{
type: "POST",
url: "delete.php",
data: data,
cache: false,
success: function(msg)
{
$(deletethis).fadeOut('slow', function() {$(this).remove();});
}
});
}
});
$('table#delTable tr:odd').css('background',' #FFFFFF');
});
And in files.php:
<script src="js/ZeroClipboard.js"></script>
<script>
var clip = null;
function $(id) {
return document.getElementById(id);
}
function init() {
clip = new ZeroClipboard.Client();
clip.setHandCursor(true);
}
function move_swf(ee) {
copything = document.getElementById(ee.id + "_text").value;
clip.setText(copything);
if (clip.div) {
clip.receiveEvent('mouseout', null);
clip.reposition(ee.id);
} else {
clip.glue(ee.id);
}
clip.receiveEvent('mouseover', null);
}
</script>

JavaScript timer is not working

I have created a file named ExtremeNotifications.js and added to the _Layout.cshtml master layout.
The ExtremeNotifications.js includes the following JavaScript code:
var extremeNotifications = extremeNotifications || {};
extremeNotifications = (function () {
var baseURL = document.baseURI;
var url = baseURL + 'api/usernotifications';
var isNotificationServiceStarted = false;
var timer;
function getPendingNotifications() {
$.ajax({ url: url, success: dataRetrieved, type: 'GET', dataType: 'json' });
}
function dataRetrieved(data) {
alert(data);
}
function startNotifications() {
if (!isNotificationServiceStarted) {
timer = setInterval(getPendingNotifications, 3000);
isNotificationServiceStarted = true;
}
}
function stopNotifications() {
clearInterval(timer);
isNotificationServiceStarted = false;
}
return {
start: startNotifications(),
getPendingNotifications: getPendingNotifications(),
isNotificationServiceStarted: isNotificationServiceStarted,
stop: stopNotifications()
}
})();
Then in my Home Index.cshtml I start the notifications with the following code and only if User.Identity.IsAuthenticated:
<script>
extremeNotifications.start();
</script>
So now when my page starts and I'm authenticated user I get an alert box in the first time but I never see another alert after 3 seconds.
Any comments?
You're close, but you're creating that returned object incorrectly:
return {
start: startNotifications,
getPendingNotifications: getPendingNotifications,
isNotificationServiceStarted: isNotificationServiceStarted,
stop: stopNotifications
};
By including the () after the function names, your code was calling the functions and returning their return values instead of returning references to the functions themselves.

Add more items from database when scroll

I have a problem, I can not run this script, the problem is that I use mcustomscrollbar
and so I did not read the Scroll event;
the scroll event is not executed.
<script type="text/javascript">
var page = 1;
$("#my_div").scroll(function () {
$('#more').hide();
$('#no-more').hide();
if($("#my_div").scrollTop() + $("#my_div").height() > $("#my_div").height() - 200) {
$('#more').css("top","400");
$('#more').show();
}
if($("#my_div").scrollTop() + $("#my_div").height() == $("#my_div").height()) {
$('#more').hide();
$('#no-more').hide();
page++;
var data = {
page_num: page
};
var actual_count = "<?php echo $actual_row_count; ?>";
if((page-1)* 12 > actual_count){
$('#no-more').css("top","400");
$('#no-more').show();
}else{
$.ajax({
type: "POST",
url: "../data.php",
data:data,
success: function(res) {
$("#result").append(res);
console.log(res);
}
});
}
}
});
</script>
How can I adapt this script to this plugin,
mcustomscrollbar http://manos.malihu.gr/jquery-custom-content-scroller/
The event
$(document).on('scroll',"#my_div",function () {
is not recognized on this plugin mcustomscrollbar manos.malihu.gr/jquery-custom-content-scroller. Help me please!
Maybe because you aren't waiting for DOM ready. Try this:
<script type="text/javascript">
var page = 1;
$(function () { //DOM ready handler
$(document).on('scroll',"#my_div",function () {
//all your code here
});
});
</script>

Categories

Resources