Jquery .load firing twice, but being called once - javascript

I have a problem here, my jquery .load function seems to be running twice even though Im only calling it once. Here is my code:
function updateRowItem(idIn){
if (ready) {
id = idIn
$("#controlPanelResult").css("background-color", "");
var query = {};
var tid = id.replace("#", "\\#");
tid = tid.replace(".", "\\.");
var value = $('#'+tid).text();
//var value = decodeURI(document.getElementById(id).innerHTML);
//if (value == "<br>"){
// value = "NULL"
//}
//value = value.replace(" "," ")
//value = value.replace("&","&")
var split = id.split('#');
var temp = split[0];
var uuid = split[1];
var temp2 = temp.split('.');
var tableName = temp2[0];
var item = temp2[1];
query['table_name'] = tableName;
query['uuid'] = uuid;
query[item] = value;
var tid = id.replace("#", "\\#");
tid = tid.replace(".", "\\.");
$.ajax({
async: false,
type: "POST",
//url: '/admin/updateRow?table_name=' + tableName + "&uuid=" + uuid +"&" + item + "=" + value,
url: '/admin/updateRow',
data: query,
success: function(data) {
if (data == "1"){
alert ("Hellooo!")//This alert only and always pops up once
$('#'+tid).empty().load(showRowsUrl + " #" + tid,function (status) {
alert (status) // This alert pops up first once, then twice, then four times, then eight etc....
$("#"+tid).animate({backgroundColor: '#70DB70'}, 'slow');
$('#controlPanelResult').html("Updated: " + id);
$("#controlPanelResult").animate({ backgroundColor: '#70DB70'}, 'slow');
$("#"+tid).animate({backgroundColor: 'white'}, 'slow');
});
} else {
$('#mainRows').load(showRowsUrl, function() {
$("#"+tid).animate({backgroundColor: 'red'}, 'fast');
$('#controlPanelResult').html(data);
$("#controlPanelResult").animate({backgroundColor: 'red'}, 'fast');
});
}
}
});
}
}
This causes my divs contents to be constantly repeated, I would appreciate any help in figuring this out

Replace the problematic .load() call with this:
$.get(showRowsUrl, function(data) {
$('#'+tid).replaceWith($('#'+tid,'<div>'+data+'</div>'));
$("#"+tid).animate({backgroundColor: '#70DB70'}, 'slow');
$('#controlPanelResult').html("Updated: " + id);
$("#controlPanelResult").animate({ backgroundColor: '#70DB70'}, 'slow');
$("#"+tid).animate({backgroundColor: 'white'}, 'slow');
});
Explanation: .load is loading the element into itself, so there are afterwards two elements with the same ID, nested. Then when you run .load again, it runs on both elements with that ID, and so on.

Related

Can't get each to work after ajax page load changes contents

on page load I run this function to hide long quoted posts into a clickable link to prevent huge comments on my site:
function hide_long_quotes()
{
$('.comments .comment_quote').each(function(i)
{
var actual_text = $(this).text();
var content = $(this).outerHTML();
if(actual_text.length > showChar)
{
var cite = $(this).find('cite span.username').first().text();
var cite_link = '';
if (cite.length > 0)
{
cite_link = 'from ' + cite;
}
var html = '<span class="morecontent">' + content + '</span>' + moretext + cite_link + '<br />';
$(this).replaceWith(html);
}
if (i+1 === quote_count) // this will be executed at the end of the loop
{
// deal with being linked to a comment, so we can put the window to the correct scroll position, since it will be different due to hidden quotes making the page smaller
if(window.location.hash)
{
var hash = window.location.hash.substring(1); //Puts hash in variable, and removes the # character
if (hash.indexOf("r") >= 0)
{
$('#'+hash)[0].scrollIntoView();
}
}
}
});
}
The problem is that when I reload ".comments" through ajax/load the above function no longer works:
function paginate_comments(page, article_id)
{
var url = "/includes/ajax/post_comment.php";
var current_url = window.location.href;
var host = window.location.host;
if(current_url.indexOf(host + '/admin.php?module=reviewqueue') != -1 || current_url.indexOf(host + '/admin.php?module=articles&view=Submitted') != -1 || current_url.indexOf(host + '/admin.php?module=articles&view=Submitted') != -1)
{
var area = 'admin';
}
else
{
var area = 'normal';
}
$('.comments').load(url, {'type':'reload', 'article_id': article_id, 'page': page, 'area': area}, function()
{
$(".lb-container").show();
$('.box.comments').get(0).scrollIntoView();
hide_long_quotes();
});
}
Not sure why it doesn't work, as the function is being called in the completed callback part of the load function?
What about giving the element collection to that function:
function hide_long_quotes(var comments = false)
{ /* for the case that you don't pass a collection to the function, maybe in the first call when the page is loaded */
comments = comments ? comments : $('.comments .comment_quote');
comments.each(function(i)
{
...
}
function paginate_comments(page, article_id)
{
...
$('.comments').load(
url,
{
'type':'reload',
'article_id': article_id,
'page': page,
'area': area
},
function()
{
$(".lb-container").show();
$('.box.comments').get(0).scrollIntoView();
hide_long_quotes($('.comments .comment_quote'));
}
);
}

Change a JS function based on resolution

Currently I am working on a webapplication for my company, and recently started learning JS/Jquery. I have set up content in a Tabs plugin/libary from the github link below:
https://github.com/samsono/Easy-Responsive-Tabs-to-Accordion
The JS file
// Easy Responsive Tabs Plugin
// Author: Samson.Onna <Email : samson3d#gmail.com>
(function ($) {
$.fn.extend({
easyResponsiveTabs: function (options) {
//Set the default values, use comma to separate the settings, example:
var defaults = {
type: 'default', //default, vertical, accordion;
width: 'auto',
fit: true,
closed: false,
tabidentify: '',
activate: function () {
}
}
//Variables
var options = $.extend(defaults, options);
var opt = options, jtype = opt.type, jfit = opt.fit, jwidth = opt.width, vtabs = 'vertical', accord = 'accordion';
var hash = window.location.hash;
var historyApi = !!(window.history && history.replaceState );
//Events
$(this).bind('tabactivate', function (e, currentTab) {
if (typeof options.activate === 'function') {
options.activate.call(currentTab, e)
}
});
//Main function
this.each(function () {
var $respTabs = $(this);
var $respTabsList = $respTabs.find('ul.resp-tabs-list.' + options.tabidentify);
var respTabsId = $respTabs.attr('id');
$respTabs.find('ul.resp-tabs-list.' + options.tabidentify + ' li').addClass('resp-tab-item').addClass(options.tabidentify);
$respTabs.css({
'display': 'block',
'width': jwidth
});
if (options.type == 'vertical')
$respTabsList.css('margin-top', '0px');
$respTabs.find('.resp-tabs-container.' + options.tabidentify).css('border-color', options.active_content_border_color);
$respTabs.find('.resp-tabs-container.' + options.tabidentify + ' > div').addClass('resp-tab-content').addClass(options.tabidentify);
jtab_options();
//Properties Function
function jtab_options() {
if (jtype == vtabs) {
$respTabs.addClass('resp-vtabs').addClass(options.tabidentify);
}
if (jfit == true) {
$respTabs.css({ width: '100%', margin: '0px' });
}
if (jtype == accord) {
$respTabs.addClass('resp-easy-accordion').addClass(options.tabidentify);
$respTabs.find('.resp-tabs-list').css('display', 'none');
}
}
//Assigning the h2 markup to accordion title
var $tabItemh2;
$respTabs.find('.resp-tab-content.' + options.tabidentify).before("<h2 class='resp-accordion " + options.tabidentify + "' role='tab'><span class='resp-arrow'></span></h2>");
$respTabs.find('.resp-tab-content.' + options.tabidentify).prev("h2").css({
'background-color': options.inactive_bg,
'border-color': options.active_border_color
});
var itemCount = 0;
$respTabs.find('.resp-accordion').each(function () {
$tabItemh2 = $(this);
var $tabItem = $respTabs.find('.resp-tab-item:eq(' + itemCount + ')');
var $accItem = $respTabs.find('.resp-accordion:eq(' + itemCount + ')');
$accItem.append($tabItem.html());
$accItem.data($tabItem.data());
$tabItemh2.attr('aria-controls', options.tabidentify + '_tab_item-' + (itemCount));
itemCount++;
});
//Assigning the 'aria-controls' to Tab items
var count = 0,
$tabContent;
$respTabs.find('.resp-tab-item').each(function () {
$tabItem = $(this);
$tabItem.attr('aria-controls', options.tabidentify + '_tab_item-' + (count));
$tabItem.attr('role', 'tab');
$tabItem.css({
'background-color': options.inactive_bg,
'border-color': 'none'
});
//Assigning the 'aria-labelledby' attr to tab-content
var tabcount = 0;
$respTabs.find('.resp-tab-content.' + options.tabidentify).each(function () {
$tabContent = $(this);
$tabContent.attr('aria-labelledby', options.tabidentify + '_tab_item-' + (tabcount)).css({
'border-color': options.active_border_color
});
tabcount++;
});
count++;
});
// Show correct content area
var tabNum = 0;
if (hash != '') {
var matches = hash.match(new RegExp(respTabsId + "([0-9]+)"));
if (matches !== null && matches.length === 2) {
tabNum = parseInt(matches[1], 10) - 1;
if (tabNum > count) {
tabNum = 0;
}
}
}
//Active correct tab
$($respTabs.find('.resp-tab-item.' + options.tabidentify)[tabNum]).addClass('resp-tab-active').css({
'background-color': options.activetab_bg,
'border-color': options.active_border_color
});
//keep closed if option = 'closed' or option is 'accordion' and the element is in accordion mode
if (options.closed !== true && !(options.closed === 'accordion' && !$respTabsList.is(':visible')) && !(options.closed === 'tabs' && $respTabsList.is(':visible'))) {
$($respTabs.find('.resp-accordion.' + options.tabidentify)[tabNum]).addClass('resp-tab-active').css({
'background-color': options.activetab_bg + ' !important',
'border-color': options.active_border_color,
'background': 'none'
});
$($respTabs.find('.resp-tab-content.' + options.tabidentify)[tabNum]).addClass('resp-tab-content-active').addClass(options.tabidentify).attr('style', 'display:block');
}
//assign proper classes for when tabs mode is activated before making a selection in accordion mode
else {
// $($respTabs.find('.resp-tab-content.' + options.tabidentify)[tabNum]).addClass('resp-accordion-closed'); //removed resp-tab-content-active
}
//Tab Click action function
$respTabs.find("[role=tab]").each(function () {
var $currentTab = $(this);
$currentTab.hover(function () {
var $currentTab = $(this);
var $tabAria = $currentTab.attr('aria-controls');
if ($currentTab.hasClass('resp-accordion') && $currentTab.hasClass('resp-tab-active')) {
$respTabs.find('.resp-tab-content-active.' + options.tabidentify).slideUp('', function () {
$(this).addClass('resp-accordion-closed');
});
$currentTab.removeClass('resp-tab-active').css({
'background-color': options.inactive_bg,
'border-color': 'none'
});
return false;
}
if (!$currentTab.hasClass('resp-tab-active') && $currentTab.hasClass('resp-accordion')) {
$respTabs.find('.resp-tab-active.' + options.tabidentify).removeClass('resp-tab-active').css({
'background-color': options.inactive_bg,
'border-color': 'none'
});
$respTabs.find('.resp-tab-content-active.' + options.tabidentify).slideUp().removeClass('resp-tab-content-active resp-accordion-closed');
$respTabs.find("[aria-controls=" + $tabAria + "]").addClass('resp-tab-active').css({
'background-color': options.activetab_bg,
'border-color': options.active_border_color
});
$respTabs.find('.resp-tab-content[aria-labelledby = ' + $tabAria + '].' + options.tabidentify).slideDown().addClass('resp-tab-content-active');
} else {
console.log('here');
$respTabs.find('.resp-tab-active.' + options.tabidentify).removeClass('resp-tab-active').css({
'background-color': options.inactive_bg,
'border-color': 'none'
});
$respTabs.find('.resp-tab-content-active.' + options.tabidentify).removeAttr('style').removeClass('resp-tab-content-active').removeClass('resp-accordion-closed');
$respTabs.find("[aria-controls=" + $tabAria + "]").addClass('resp-tab-active').css({
'background-color': options.activetab_bg,
'border-color': options.active_border_color
});
$respTabs.find('.resp-tab-content[aria-labelledby = ' + $tabAria + '].' + options.tabidentify).addClass('resp-tab-content-active').attr('style', 'display:block');
}
//Trigger tab activation event
$currentTab.trigger('tabactivate', $currentTab);
//Update Browser History
if (historyApi) {
var currentHash = window.location.hash;
var tabAriaParts = $tabAria.split('tab_item-');
// var newHash = respTabsId + (parseInt($tabAria.substring(9), 10) + 1).toString();
var newHash = respTabsId + (parseInt(tabAriaParts[1], 10) + 1).toString();
if (currentHash != "") {
var re = new RegExp(respTabsId + "[0-9]+");
if (currentHash.match(re) != null) {
newHash = currentHash.replace(re, newHash);
}
else {
newHash = currentHash + "|" + newHash;
}
}
else {
newHash = '#' + newHash;
}
history.replaceState(null, null, newHash);
}
});
});
//Window resize function
$(window).resize(function () {
$respTabs.find('.resp-accordion-closed').removeAttr('style');
});
});
}
});
})(jQuery);
Orginally the tabs are set to a onclick like this on line number 142:
$currentTab.click(function () {
I've changed the tabs to a hover because I like that more for my application, like so:
$currentTab.hover(function () {
It works fine on my desktop but when I resize my browser to a smaller resolution the tabs will change in a accordion. Normally it works totally fine, but because I've changed it to a hover system it's not the best option to have now. Is there any way to detect smaller resolutions in javascript/jquery so when its like under 800px the function changes back to $currentTab.click(function () {? Or any other solution for my problem?
What I want: Change a jquery hover event function based on resolution OR change a JS script based on resolution (So I create 2 js files, one for mobile and one for desktop and then decide which script I would load).
Make a named function and do
if (window.screen.width < whatever ) $currentTab.click(doIt);
else $currentTab.hover(doIt);

What about variable scopes inside a callback function

If I have a callback function within a callback function I can't reach the variables declared inside the first callback.
See example (Uses some jquery):
my fiddle
Why is this?
Or
What am I doing wrong!?
I am using this in the following:
$('<div/>').html(data).find('load').each(function(id, deze) {
var method = $(deze).attr("method");
var animate = $(deze).attr("animate");
var locatie = $(deze).attr("id");
var html = $(deze).html();
if(!method){
method = 'overide';
}
if(!locatie){
error('A002','No loadloc');
}
if(!html){
html = '';
}
if(!animate){
animate = false;
}
else if(animate == 'fade'){
var effectout = 'fade';
var timeout = 100;
var optionsout = {
easing: 'swing'
};
var effectin = 'fade';
var timein = 600;
var optionsin = {
easing: 'swing'
};
}
else{
animate = false;
error('A006','Animation: "' + animate + '" does not exist');
}
//here I make callback or direct function call
if(animate){
$('#' + locatie).hide(effectout, optionsout, timeout, load());
}
else{
load();
}
function load(){
console.log('hallo');
console.log(html);
if(method == 'overide'){
$('#' + locatie).html(html);
}
else if(method == 'tablerow'){
var html = $('tr', deze).html();
$('#' + locatie).html(html);
}
else if(method == 'append'){
$('#' + locatie).append(html);
}
else if(method == 'prepend'){
$('#' + locatie).prepend(html);
}
else{
error('A007','load method: "' + method + '" does not exist');
}
if(animate){
$('#' + locatie).show(effectin, optionsin, timein);
}
}
});
Why is this?
It is not. You can simply access something, it is in the scope of the load function that you posted.
What am I doing wrong!?
You're not passing the load function itself as the callback, but it's result - you're immediately calling it (without arguments). You want
$('#' + locatie).hide(effectout, optionsout, timeout, load);
// ^^
//It seems I can't reach html and other variables here
console.log(this.html);
That's not a variable, that's a property of this (and the this keyword points to different things in the different calls). What you want is a simple variable:
console.log(html);
Same story for this.locatie and the others.
I changed your code a bit and I believe this is what you were trying to do:
http://jsfiddle.net/smerny/2M6k3/
var anothercallbackfunctiontriggerthing = function(cb) {
cb();
}
$('.something').each(function(id, value) {
var something = 'something';
var load = function(){
// can't reach something here
console.log(something);
}
anothercallbackfunctiontriggerthing(load);
});
As load() didn't return anything, I assume you were wanting to pass it as a callback (load) and then call it from within anothercallbackfunctiontriggerthing. The above code will print "something" for each .something.
The reason it doesn't work is because the keyword this changes meanings within the context of load() since you're defining a function using function load(). There are several ways of getting around this; here's one:
Before:
if(animate){
$('#' + locatie).hide(effectout, optionsout, timeout, load());
}
else{
load();
}
use
var load = (function(el) {
return function() {
console.log('hallo');
//It seems I can't reach html and other variables here
console.log(el.html);
if(method == 'overide'){
$('#' + el.locatie).html(el.html);
}
else if(method == 'tablerow'){
var html = $('tr', deze).html();
$('#' + el.locatie).html(el.html);
}
else if(method == 'append'){
$('#' + el.locatie).append(el.html);
}
else if(method == 'prepend'){
$('#' + el.locatie).prepend(el.html);
}
else{
error('A007','load method: "' + el.method + '" does not exist');
}
if(el.animate){
$('#' + el.locatie).show(el.effectin, el.optionsin, el.timein);
}
};
})(this);
What I did there was to change all references to this with el. And then I injected this as el by using the following format:
load = ( function(el) { return yourFunction() {...}; })(this);
Let me know if that makes sense and if it works for you :)

Accessing and modifing a variable in and out of functions

Hello i am trying to modify the variable popText but failing on the ajax function, i cant get the output on popText :(
What am i doing wrong?
function nariTooltip(){
var popTime;
var fading;
var popboxIsActive = false;
var mouseIsHoverPopbox = false;
var popText;
//Using Event Delegation to cover late AJAX inserted DOM elements
//no need to recall function after each AJAX run
//Mouseenter / Mouseout
$("body").on(
{
mouseenter: function(e){
$hoverElem = $(this);
//Define Variables
var popDelay = 250;
if ($hoverElem.attr("popdelay")){
var popDelay = $hoverElem.attr("popdelay");
}
popTime = setTimeout(function() {
popText = $hoverElem.attr("poptext");
if ($hoverElem.next().hasClass("poptext")) {
popText = $hoverElem.next(".poptext").html();
}
var popAjax = $hoverElem.attr("popajax");
if (popAjax){
var popAjax = popAjax.split(':');
popAjaxType = popAjax[0];
if (popAjaxType == 'general')
{
popAjaxUrl = 'tooltip_gen.php';
}
else if (popAjaxType == 'item')
{
popAjaxUrl = 'tooltip_items.php';
}
if (popAjaxUrl){
$.ajax({ url: 'ajax/'+popAjaxUrl,
data: {id: popAjax[1]},
type: 'get',
success: function(output)
{
popText = output;
},
error:function (xhr, ajaxOptions, thrownError){
popText = html(xhr.statusText);
},
});
}
//alert(outputs);
}
//Create Popup
$hoverElem.append('<div class="popbox">' + popText + '</div>');
popText always end up with the value assigned on popText = $hoverElem.next(".poptext").html();
It seems that you create the div with the text before ajax has returned. Make function that sets the popText and call it when you've got it from ajax
function setPopText( elem, txt ) {
$(elem).append('<div class="popbox">' + txt + '</div>')
}
And in your ajax
success: function ( output ) {
setPopText( $hoverElem, output );
}

ajax() call in javascript function

i have a jquery .click() function that executes an .ajax() method call
$(".btn-play").live("click", function () {
//set globalSortNumber
globalSortNumber = $(this).parents("[sortnumber]").attr("sortnumber");//.attr("value") ; //change should be some type of input like mediaid //see if its possible to add the sortID to the handle span
// alert(globalSortNumber);
//set title
//set mediaID
var mediaID = $(this).parents("[mediaid]").attr("mediaid");
// alert(mediaID);
//ajax query to get link and excute code to launch music
$.ajax({
type:"POST",
url:"ajax/AB3Ajax.asmx/GenerateLink",
data:"{'mediaId':" + mediaId + ",'userId':" + "0" + "}",
contentType:"application/json; charset=utf-8",
dataType:"json",
success:function (msg) {
if (msg.d != "") {
playsong(msg.d,null);
}
else {
soundManager.stopAll();
//look at what is already in place in mystudio
}
},
error: function (err) {
//add code later look at what is already in place in mystudio
}
})
when the .ajax() method executes succesfully it calls a javascript function
function playsong(sortNumber,url) {
if (soundManager.supported()) {
globalSortNumber = sortNumber;
var aSoundObject = soundManager.createSound({
id: 'mySound' + sortNumber,
url: url,//'/Music/mafiamusicpt2rickross.mp3',
whileplaying: function () {
if (count == 0) {
if (this.position > 1000) {
this.pause();
pos = this.position;
count++;
this.resume();
}
} else if (count == 1) {
soundManager._writeDebug('old position: ' + pos);
soundManager._writeDebug('new position: ' + this.position);
// See that this.position is less than pos!
count++;
}
},
onfinish: function () {
//find the next song in the list
//var nextSongPosition=
this.destruct();
$.ajax({
type:"POST",
url:"ajax/AB3Ajax.asmx/GenerateLink",
data:"{'mediaId':" + mediaId + ",'userId':" + "0" + "}",
contentType:"application/json; charset=utf-8",
dataType:"json",
success:function (msg) {
if (msg.d != "") {
playsong(msg.d,null);
}
else {
soundManager.stopAll();
//look at what is already in place in mystudio
}
},
error: function (err) {
//add code later look at what is already in place in mystudio
}
})
playsong(sortNumber++,url)
}
});
aSoundObject.play();
}
}
as you can see i have an .ajax() method inside my javascript function, is this possible?
I am creating loop that starts on the finish listener of the soundmanager object. So when I need to make the ajax call to get he next url I need. If my way isnt correct can you please tell me what is the best way to accomplish what i am trying to do.
Think it's fine but i would make a separate function for the ajax call so you dont need to duplicate the code twice. Easier to maintain.
$(".btn-play").live("click", function () {
//set globalSortNumber
globalSortNumber = $(this).parents("[sortnumber]").attr("sortnumber");//.attr("value"); //change should be some type of input like mediaid //see if its possible to add the sortID to the handle span
//alert(globalSortNumber);
//set title
//set mediaID
var mediaID = $(this).parents("[mediaid]").attr("mediaid");
//alert(mediaID);
//ajax query to get link and excute code to launch music
getAudio(mediaID);
}
function playsong(sortNumber,url) {
if (soundManager.supported()) {
globalSortNumber = sortNumber;
var aSoundObject = soundManager.createSound({
id: 'mySound' + sortNumber,
url: url,//'/Music/mafiamusicpt2rickross.mp3',
whileplaying: function () {
if (count == 0) {
if (this.position > 1000) {
this.pause();
pos = this.position;
count++;
this.resume();
}
} else if (count == 1) {
soundManager._writeDebug('old position: ' + pos);
soundManager._writeDebug('new position: ' + this.position);
// See that this.position is less than pos!
count++;
}
},
onfinish: function () {
//find the next song in the list
//var nextSongPosition=
this.destruct();
getAudio(mediaId);
playsong(sortNumber++,url)
}
});
aSoundObject.play();
}
}
function getAudio(mediaID) {
$.ajax({
type:"POST",
url:"ajax/AB3Ajax.asmx/GenerateLink",
data:"{'mediaId':" + mediaId + ",'userId':" + "0" + "}",
contentType:"application/json; charset=utf-8",
dataType:"json",
success:function (msg) {
if (msg.d != "") {
playsong(msg.d,null);
}
else {
soundManager.stopAll();
//look at what is already in place in mystudio
}
},
error: function (err) {
//add code later look at what is already in place in mystudio
}
});
}

Categories

Resources