2 javascripts are conflicting - javascript

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>

Related

Remove dynamically created button's history - jQuery

this is my first entry on StackOverFlow.
I'm working on a project and it needs jQuery to perform a master/detail table layout.
I have to work in asp.net C#, master and detail table generate dynamically.
So what is my problem:
I generate the master table with ajax:
function refreshMasterTable() {
xhr = $.ajax({
type: "GET",
url: "tablefunctions.aspx?mode=showmastertable",
success: function (html) {
$("#tbl_master").html(html);
prevAjaxReturned = true;
$('input[type=button]').click(function () {
var bid, trid;
bid = (this.id);
trid = $(this).closest('tr').attr('id');
if ($("#detail_" + trid).length == 0) {
detailShow = true;
pointer = $(this).closest('tr');
pointer.after("<tr><td colspan=5><div id=detail_" + trid + "></div></td></tr>");
$.get("tablefunctions.aspx?mode=showdetailtable&id=" + trid, function (response) {
$('#detail_' + trid).html(response);
});
$(document).on('click', '#submitMasterData', function () {
value = $('#name').val();
$.get("tablefunctions.aspx?mode=mastertableupdate&id=" + trid + "&name=" + value);
refreshMasterTable();
});
} else {
detailShow = false;
$(this).closest('tr').next("tr").remove();
}
});
}
});
};
In tablefunctions.aspx there is an entry, what generates the submit button:
html.Append("<tr><td colspan=\"2\" align=\"right\"><input type=\"submit\" id=\"submitMasterData\" /></td></tr>");
So the problem begins here. Each time when I ask a new detail row in the master table, a new submitMasterData instance of button creates and the $(document).on('click', '#submitMasterData', function () event triggers on every previous values. If I reload the page, the first detail request is OK, but the "collection" begins again.
$("#submitMasterData").remove(); didn't solve the problem. Sorry for my bad English, if something is not clear, please ask me...
The problem is the $(document).on() function is binding a new event each time a button is clicked without removing any of the previous events. You can use the off() function to remove the old ones in queue.
function refreshMasterTable() {
xhr = $.ajax({
type: "GET",
url: "tablefunctions.aspx?mode=showmastertable",
success: function (html) {
$("#tbl_master").html(html);
prevAjaxReturned = true;
$('input[type=button]').click(function () {
var bid, trid;
bid = (this.id);
trid = $(this).closest('tr').attr('id');
if ($("#detail_" + trid).length == 0) {
detailShow = true;
pointer = $(this).closest('tr');
pointer.after("<tr><td colspan=5><div id=detail_" + trid + "></div></td></tr>");
$.get("tablefunctions.aspx?mode=showdetailtable&id=" + trid, function (response) {
$('#detail_' + trid).html(response);
});
//need to unbind all the previously attached events
$(document).off('click', '#submitMasterData');
$(document).on('click', '#submitMasterData', function () {
value = $('#name').val();
$.get("tablefunctions.aspx?mode=mastertableupdate&id=" + trid + "&name=" + value);
refreshMasterTable();
});
} else {
detailShow = false;
$(this).closest('tr').next("tr").remove();
}
});
}
});
};
You can view a proof of concept in this JS fiddle: https://jsfiddle.net/bfc6wzt8/
Hope that helps :-)

Initialize Anonymous function after ajax call

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>

Adding event handler to non-existent class?

I've seen questions that relate to non-existent elements, but not non-existent classes. Here's what I want to do. When a button of class "see_answer" is clicked, I want to remove the class and replace it with "see_question". However, my click function for a button, once its class is "see_question", is not running. I have tried $(document).on("click", ".see_question", function(event ) and I have tried $(".see_question").on("click", function(event) {etc.... Thanks for the help! My code is below:
$(document).ready(function() {
// initialize variables
var lang = "javascript";
var qno = 1;
var prevText; // holds question/answer
var language = lang + ".html";
// set up tabs, and keep track of which one is clicked
$("#myTabs").tabs({
activate: function (event, ui) {
var active = $("#myTabs").tabs("option", "active");
lang = $("#myTabs ul > li a").eq(active).attr("href");
lang = lang.replace("#", "");
}
});
/* REMINDERS
actual qa part: blah_language
*/
// set up question
$.ajax({
url: language,
dataType: "html",
success: function(data) {
$("#blah_"+lang)
.text($(data).find("#1").text());
},
error: function(r) {
alert("whoops, error in initialization");
}
});
$(".next_question").on("click", function(event) {
event.preventDefault();
var id = $(this).attr("id").replace("next_question_", "");
var language = id + ".html";
var doc = "#blah_" + id;
$.ajax({
url: language,
dataType: "html",
success: function(data) {
var num = "#" + qno;
$(doc)
.text($(data).find(num).text());
qno = qno + 1;
},
error: function(r) {
alert("whoops");
}
});
prevText = "";
});
// SHOW ANSWER
$(".see_answer").on("click", function(event) {
event.preventDefault();
var id = $(this).attr("id").replace("see_answer_", "");
var prev = "#blah_" + id;
var answers = id + "_answers.html";
// Save the question
prevText = $(prev).text();
var obj = $(this);
$.ajax({
url: answers,
dataType: "html",
success: function(data) {
var num = "#" + 3;
$(prev)
.text($(data).find(num).text());
},
error: function(r) {
alert("whoops");
}
});
obj.val("See Question");
obj.removeClass("see_answer");
obj.addClass("see_question");
event.stopPropagation();
});
$(document).on("click",".see_question", function(event) {
event.preventDefault();
obj = $(this);
event.preventDefault();
var id = $(this).attr("id").replace("see_answer_", "");
var prev = "#blah_" + id;
$(prev).text(prevText);
obj.val("See Answer");
obj.removeClass("see_question");
obj.addClass("see_answer");
});
})
Click handling for .see_question elements is delegated to document. For .see_answer elements, a click handler is attached directly. Therefore, swapping the class names will have an undesirable effect.
when see_answer is in force, a click will trigger the "see_answer" handler.
when see_question is in force, a click will trigger the "see_question" handler AND the "see_answer" handler, which is still attached.
There's a number of ways to do this properly. From where you currently are, the simplest solution is to delegate click handling of .see_question and .see_answer elements to document.
$(document).on("click", ".see_answer", function(event) {
...
});
$(document).on("click", ".see_question", function(event) {
...
});
Combine the 2 handlers and figure out which version it is by hasClass() before you change the classes around
$(document).on("click", ".see_question, .see-answer", function(event ){
var $btn =$(this), isAnswer = $btn.hasClass('see_answer');
// we know which one it is so can switch classes now
$btn.toggleClass('see_answer see_question');
if(isAnswer){
/* run code for answer version */
}else{
/* run code for question version */
}
});

Append more content when scroll to end of page

Hi I only started working on JQuery Mobile a month ago and my starting project was to build an app to load my blog posts. After spending days and night researching and support from SO, I did manage to get my blog posts loaded and also added a Load More link to append new contents.
My intention no is rather than use a link, I want the new contents appended when I scroll to end of page. I do not plan to use a plugin for now but was hoping I could write a simple code to do that for me. This is my current code (First function to load initial contenst while the 2nd function is to append more contents. Not sure if this is the best approach but like I said, I am still in learning process)
$(document).on('pagebeforeshow', '#blogposts', function () {
$.ajax({
url: "http://howtodeployit.com/?json=recentstories",
dataType: "json",
beforeSend: function () {
$('#loader').show();
},
complete: function () {
$('#loader').hide();
},
success: function (data) {
$('#postlist').empty();
$.each(data.posts, function (key, val) {
//Output data collected into page content
var rtitle = $('<p/>', {
'class': 'vtitle',
html: val.title
}),
var rappend = $('<li/>').append(rtitle);
$('#postlist').append(rappend);
return (key !== 5);
});
$("#postlist").listview().listview('refresh');
},
error: function (data) {
alert("Service currently not available, please try again later...");
}
});
});
$(document).on("click", ".load-more", function () {
$.getJSON("http://howtodeployit.com/?json=recentstories", function (data) {
var currentPost = $('#postlist');
console.log(currentPost);
loadMore = currentPost.parent().find('.load-more');
var currentPostcount = $('#postlist li').length;
console.log(currentPostcount);
var desiredPosts = 3;
newposts = data.posts.slice(currentPostcount, currentPostcount + desiredPosts);
$.each(newposts, function (key, val) {
var rtitle = $('<p/>', {
'class': 'vtitle',
html: val.title
}),
var rappend = $('<li/>').append(rtitle);
$('#postlist').append(rappend);
$("#postlist").listview('refresh');
});
});
});
Sorry if this type of question had been answered else where. Please post link
This is a typical approach with jquery,
$(window).scroll(function () {
if ($(window).scrollTop() == $(document).height() - $(window).height()) {
/*end reached*/
$('.content').html($('.content').html()+"more</br></br></br></br>");
}
});
example with jqm,
http://jsfiddle.net/F5McF/
Try this example it works.
function loaddata()
{
var el = $("outer");
if( (el.scrollTop + el.clientHeight) >= el.scrollHeight )
{
el.setStyles( { "background-color": "green"} );
}
else
{
el.setStyles( { "background-color": "red"} );
}
}
window.addEvent( "domready", function()
{
$("outer").addEvent( "scroll", loaddata );
} );
Fiddle is
http://jsfiddle.net/wWmqr/1/

jQuery on or live?

I recently deployed an infinite scroll to an app that I have build and found that sometimes I need to click twice for something to happen.
My app has likes, and once the dom had loaded, i need to click on the like button twice before it changes, then once i click on the other ones it's okay but I always have to click once for the app to almost "wake up"
Is there a better solution?
$(document).ready(function() {
function runUpdate(url, item) {
$.ajax({
type: "GET",
url: url,
cache: false,
success: function(data){
if (data == '200') {
removeAddColor(item);
}
}
});
}
$('.mini-like').live('click', function(){
$('.mini-like').toggle(
function() {
var item = $(this);
var href = item.attr('href');
runUpdate(href, item);
},
function() {
var item = $(this);
var rel = item.attr('rel');
runUpdate(rel, item);
}
);
});
function removeAddColorFollow(item) {
var href = $(this).attr('href');
var rel = $(this).attr('rel');
if (item.hasClass('btn-success')) {
$(item).removeClass('btn-success').attr('href', href).attr('rel', rel);
$(item).find('i').removeClass('icon-white');
} else {
$(item).addClass('btn-success').attr('href', rel).attr('rel', href);
$(item).find('i').addClass('icon-white');
};
}
});
Well unless I'm completely wrong, you only attach the toggle event to .mini-like after it has been clicked once. Try to just replace
$('.mini-like').live('click', function() {...
With
$(function() {...
To attach the toggle event handler on document ready instead of on click
The code $('.mini-like').live('click',... should be placed inside $(document).ready()
You can use .on in place of .live. As .on is a new method and .live is deprecated now you should use .on
UPDATE
The re-written version will be
$(document).ready(function(){
$('.mini-like').on('click', function(){
$('.mini-like').toggle(
function() {
var item = $(this);
var href = item.attr('href');
runUpdate(href, item);
},
function() {
var item = $(this);
var rel = item.attr('rel');
runUpdate(rel, item);
}
);
});
});
function runUpdate(url, item) {
$.ajax({
type: "GET",
url: url,
cache: false,
success: function(data){
if (data == '200') {
removeAddColor(item);
}
}
});
}
function removeAddColorFollow(item) {
var href = $(this).attr('href');
var rel = $(this).attr('rel');
if (item.hasClass('btn-success')) {
$(item).removeClass('btn-success').attr('href', href).attr('rel', rel);
$(item).find('i').removeClass('icon-white');
} else {
$(item).addClass('btn-success').attr('href', rel).attr('rel', href);
$(item).find('i').addClass('icon-white');
};
}

Categories

Resources