jquery AJAX call only works once? - javascript

I'm setting up some sort of small form to determine whenether my users want to submit a form anonymously or not, and whenether the content they're submitting is original or not.
The first AJAX call seems to work fine, but then when the new content is loaded from a PHP file through AJAX, then the jQuery function doesn't seem to work.
It is supposed to work like this.
They are presented with 2 options, submit with username, or submit anonymously (clicking either of these calls an AJAX request to the specified PHP file)
The PHP file contains another 2 options (see example below) called Original and Existing. (Clicking any of these doesn't seem to do anything!)
Finally, they should be presented with the specific submission form for their choices.
Here is my code:
jQuery
// User
$('#user-submission').on( "click", function() {
$.ajax({url:'<?php echo get_template_directory_uri(); ?>/submission/user-submission.php',success:function(result) {
$("#submit-section").html(result).fadeIn('slow');
}});
});
// Anonymous
$('#anonymous-submission').on( "click", function() {
$.ajax({url:'<?php echo get_template_directory_uri(); ?>/submission/anonymous-submission.php',success:function(result) {
$("#submit-section").html(result).fadeIn('slow');
}});
});
// User -> Original
$('#original-submission-user').on( "click", function() {
$.ajax({url:'<?php echo get_template_directory_uri(); ?>/submission/original-user-submission.php',success:function(result) {
$("#submit-section").html(result).fadeIn('slow');
}});
});
// User -> Existing
$('#original-submission-anonymous').on( "click", function() {
$.ajax({url:'<?php echo get_template_directory_uri(); ?>/submission/original-anonymous-submission.php',success:function(result) {
$("#submit-section").html(result).fadeIn('slow');
}});
});
// Anonymous -> Original
$('#existing-submission-user').on( "click", function() {
$.ajax({url:'<?php echo get_template_directory_uri(); ?>/submission/existing-user-submission.php',success:function(result) {
$("#submit-section").html(result).fadeIn('slow');
}});
});
// Anonymous -> Existing
$('#existing-submission-anonymous').on( "click", function() {
$.ajax({url:'<?php echo get_template_directory_uri(); ?>/submission/existing-anonymous-submission.php',success:function(result) {
$("#submit-section").html(result).fadeIn('slow');
}});
});
Main HTML
<section id="submit-section">
<div class="anonymous-or-credited">
<a href="#" id="user-submission" class="submit-url">
<div class="transition">
<h2><?php echo $current_user->display_name; ?></h2>
<h3>Submit a as <?php echo $current_user->display_name; ?></h3>
</div>
</a>
<a href="#" id="anonymous-submission" class="submit-url">
<div class="transition">
<h2>Anonymous</h2>
<h3>Submit a Creepypasta Anonymously</h3>
</div>
</a>
</div>
</section>
PHP file containments
<div class="anonymous-or-credited">
<a href="#" id="original-submission-user" class="submit-url">
<div class="transition">
<h2>Original</h2>
<h3>I wrote this myself</h3>
</div>
</a>
<a href="#" id="exisiting-submission-user" class="submit-url">
<div class="transition">
<h2>Existing</h2>
<h3>I found this elsewhere</h3>
</div>
</a>
</div>

If the elements are added dynamically, selecting for the ID of the dynamically-added element will not work. You will have to instead listen for event to bubble up in a location higher up (in terms of hierarchy) on the DOM tree, like document.
I assume that both #user-submission and #anonymous-submission are already present on the page when it is initially loaded, but the rest are not. Therefore, you need to listen to the click event bubbling up to document (or any parent that is already present on the page when JS is executed):
$(document).on('click', '#original-submission-user', function() {
$.ajax({url:'<?php echo get_template_directory_uri(); ?>/submission/original-user-submission.php',success:function(result) {
$("#submit-section").html(result).fadeIn('slow');
}});
});
Remember to repeat this for all dynamically-added elements which you want to bind events to.

If I'm understanding correctly, you have JS bindings to HTML that exists on page load -- but when you dynamically load more HTML, your existing JS isn't bound to it. One solution would be to add your click bindings to the ajax callback, after the HTML is loaded.

You need to enter the second parameter of the .on() function (delegated event):
$('#submit-section').on('click','#original-submission-user', function() {
});

Related

Javascript add class active when click a link after load another page?

I have a list a.href to many URL contain film.
When I click a.href, it will reload my page. I don't know how to add the class .active to the a.href current selected.
In Ajax call, it simple like this code, it's working because the page is not reloaded. But I write on PHP and using $_GET and $_POST method. So the page must be reloaded.
Have any method to add the class .active on a.href link was clicked?
<div class="btn-group listEp col-md-12">
$i = 0;
Episode:
<?php foreach($data['episodes'] as $epList) { ?>
<a class="btn btn-default" href="<?php echo $epList['href']); ?>"> <?php echo $i++; ?> </a>
<?php } ?>
</div>
$(function() {
$('#listEp').on("click", "a", function() {
$( "#listEp a:first-child" ).css("cssText", "background: #4CAF50 !important;");
$(this).addClass('active').siblings().removeClass('active');
});
});
If you don't want to reload page after click and create a custom action on this just do this:
$('#listEp').on("click", "a", function(e) {
e.preventDefault() // this will disable default action which is redirect in case of a element
e.stopPropagation() // this will stop element beeing propagated by other functions
$( "#listEp a:first-child" ).css("cssText", "background: #4CAF50 !important;");
$(this).addClass('active').siblings().removeClass('active');
});
Looks like you're targeting an ID which doesn't exist, the element has a class listEp. Try $('.listEp') instead
You can do simply like this,
$('a.btn[href]').click(function(){
$('a.btn[href]').removeClass('active');
$(this).addClass('active');
});
above code removes active class from other same elements and adds class in this element.
Add below code to that page which is rendering on reload,
$(document).ready(function(){
$('a.active.btn[href]').removeClass('active');
});

Opening a window in Javascript with the value of a PHP variable

I would like to open a window with a 5 second delay when a button is clicked. I'm trying:
<script type="text/javascript">
function sample() {
setTimeout(function() {
window.open('<?php echo esc_attr(wpcoupon_coupon()->get_go_out_url()); ?>', '_self');
}, 5000);
}
</script>
which I call in the onclick attribute of the <button>:
<button class="ui right labeled icon button btn btn_secondary" onClick="sample();">
<i class="copy icon"></i>
<span><?php esc_html_e('Copy', 'wp-coupon'); ?></span>
</button>
The problem is that <?php echo esc_attr(wpcoupon_coupon()->get_go_out_url()); ?> doesn't return the correct value, and correct URL doesn't open.
What could be going wrong?
You need ajax to read that php variable asynchronously from javascript. Otherwise i think your question is better answered here:
Get variable from PHP file using JQuery/AJAX
Is the page address correct?
esc_attr(wpcoupon_coupon()->get_go_out_url())
For test your script in php file use construction:
<?php
//php code
?>
<script>
function sample() {
setTimeout(function() {
window.open('<?php echo('https://google.com'); ?>', '_self');
}, 5000);
}
</script>
<button class="ui right labeled icon button btn btn_secondary" onClick="sample();">test</button>
<?php
//php code
?>

hiding divs using javascript that don't match the clicked div and pushing correct div up the page

I have a web page in PHP that shows blog posts/ articles that were posted from 2015-2008. basically at the top of the page I have buttons that have the year on it, and below all the blog posts and articles correlatin to the years. I want to have a feature so that if the user clicks 2013, all other posts with years not matching 2013 will dissapear and the correct year posts/articles will move up to the top of the page, so the user doesn't have to scroll.
Here is my code, the content is loaded through a controller so the page is basically created by grabbing data from an array.
<div class="calendar-key">
<div class="cd-timeline2-img cd-2015" id="btn" >'15</div>
<div class="cd-timeline2-img cd-2014" >'14</div>
<div class="cd-timeline2-img cd-2013" >'13</div>
<div class="cd-timeline2-img cd-2012">'12</div>
<div class="cd-timeline2-img cd-2011" >'11</div>
<div class="cd-timeline2-img cd-2010" >'10</div>
<div class="cd-timeline2-img cd-2009" >'09</div>
<div class="cd-timeline2-img cd-2008" >'08</div>
<div class="cd-timeline2-img cd-2007" >'07</div>
<?php foreach ($article as $slug => $article): ?>
<div class="cd-timeline-block">
<div class="cd-timeline-img cd-<?php echo $article['year'] ?>">
<span class="timelinedate"><?php echo $article['month'] ?><?php echo $article['day'] ?></span>
</div>
<div class="cd-timeline-content">
<a href="<?php echo $article['link'] ?>">
<h3 class="press_title" id="<?php echo $article['year'] ?>-<?php echo $article['first'] ?>"><?php echo $article['title'] ?></h3>
<img src="<?php echo $article['image'] ?>" width="100%" height="auto" />
</a>
<p><?php echo $article['description'] ?> </p>
<div class="social-share-buttons article-share-buttons pull-left">
<a class='social-email' href='<?php echo SocialShareLink::email("", "Check out this article, ".$article['title']." \n\n" .$article['link']); ?>'</a>
<a class='social-facebook' href='<?php echo SocialShareLink::facebook($article['link']); ?>' target='_blank'></a>
<a class='social-twitter' href='<?php echo SocialShareLink::twitter("", $article['link']); ?>' target='_blank'></a>
<a class='social-google' href='<?php echo SocialShareLink::googleplus($article['link']); ?>' target='_blank'></a>
</div>
Read more
</div>
</div>
<?php endforeach; ?>
the for each basically takes an array I have in a config file with data, and populates the articles on the page for however many there are in the array.
'articles' => [
'article#1 example' => [
'description' => "exampletextblablabla",
'title' => 'article title',
'link' => '//www.google.com',
'year' => '2015',
'month' => 'Jul ',
'day' => '25',
'first' => '1', //first article of that year
'image' => '../../images/example.jpg'
],
//more articles in this format
and then my failed attempt at js
<script type="javascript">
$('.cd-timeline2-img a').on('click',function(){
var eq = $(this).index();
$('cd-timeline-img cd-<?php echo $article['year'] ?>').removeClass('show');
$('cd-timeline-img cd-<?php echo $article['year'] ?>').eq(eq).addClass('show');
});
</script>
I am not very good at javascript, so I tried something like this but nothing works. I feel like this is an easy little script to right, any help would be great! thanks.
Woohoo! Finally, I got it working and 100% where I want it. So I used your code and threw it into a Fiddle: https://jsfiddle.net/rockmandew/4Lyofmkh/44/
You will see that I went with my approach - by default, the articles are display none and have a class of 'show' on them to begin with - you will also notice I changed where you had your 'cd-(year)' - I did this because you needed to identify the entire article container since that is what you would be hiding/showing.
I also added a 'Show All' button, so the user can view all if desired.
So like I said I changed your HTML markup right here:
<div class="cd-timeline-block cd-2015 show">
<!-- Article Year in Div Class below -->
<div class="cd-timeline-img">
It was "cd-timeline-img cd-2015" previously. That is the only change you need to make to your markup, besides adding the "show all" button (if you want it):
<div class="show-all">Show All</div>
Furthermore, I applied the display:none css property to the ".cd-timeline-block"
.cd-timeline-block {
margin-top:35px;
display:none;
}
Which is why we initialize the page with the "show" class on there:
<div class="cd-timeline-block cd-2015 show">
Which has the following styles:
.show {
display:block;
}
Finally, we get to the meat of it all, the jQuery. I will post the working code that I used and then explain it. The following code is to toggle articles based on the year clicked:
$('.calendar-key a').each(function() {
$(this).on('click', function() {
var x = 'cd-' + $(this).attr('rel');
$('.cd-timeline-block').each(function() {
if($(this).hasClass(x)) {
$('.cd-timeline-block').not(this).each(function() {
if($(this).hasClass('show')) {
$(this).toggleClass('show');
}
});
$(this).each(function() {
if(!$(this).hasClass('show')) {
$(this).toggleClass('show');
}
});
}
});
})
});
As you will see, when a ".calendar-key" link is clicked, the clicked link will produce a variable based on the links "rel" - the variable adds the "cd-" prefix onto the "rel" value. Then for each ".cd-timeline-block" if it has the class that was created from clicking (the variable just discussed), it will cycle through all of the ".cd-timeline-block" elements that isn't "this" (meaning all elements that don't match the selected year.) - for all of those elements, if it has the "show" class, it will be toggled. Then the last part, it takes the "this" and cycles through each of them, if it doesn't have the class "show", then it toggles the class "show", thus displaying the desired elements.
Finally, the show all button is controlled with the following function:
$('.show-all a').on('click', function() {
$('.cd-timeline-block').each(function() {
if(!$(this).hasClass('show')) {
$(this).toggleClass('show');
}
});
});
Its a fairly simple function. When the ".show-all" link is clicked, it cycles through all of the ".cd-timeline-block" elements, again, if they don't have the "show" class, the function will toggle the "show" class.
I know that was a lot but hopefully it all made sense. Again, here is the associated Fiddle I made to help you.
https://jsfiddle.net/rockmandew/4Lyofmkh/44/
Let me know if you need any further help.
Latest Update:
https://jsfiddle.net/rockmandew/4Lyofmkh/46/
Fiddle now contains new mark-up for easiest solution to updated issue marked in comments below.
It finally dawned on me that I was filtering your list of years not your posts. For future reference post a snippet of actual code, now bits with php all over them. Now the script looks for the rel attribute in your year list for the year, matches that year to the class "cd-year" in each post and filters as necessary. I stripped out all of the superfluous parts of the post like the social links as they're not needed for this exercise.
http://jsfiddle.net/1dyocexe/2/
//this is where you'd have your <?php echo $article['year'] ?> set the current year
var year = 2014;
getPosts(year);
function getPosts(year) {
$(".cd-timeline-block").find("div").each(function (i) {
var elm = $(this);
var cdYear = "cd-" + year;
var use = elm.hasClass(cdYear);
if (use === true) {
elm.show();
} else {
elm.hide();
}
});
}
$(".calendar-key div a").on("click", function () {
var year = $(this).attr("rel");
getPosts(year);
});

JQuery's .on() not working correctly

I'm setting things up very simply and i just can't wrap my brain why this won't work. I know this is correct, yet it doesn't work.
.navigate-button is being ajax'd into .overlay-content so .overlay-content isn't in the dom on page load, hence using .on
When i click the link it just takes me to the page as normal. I know that the even tisn't being bound to .navigate-button
Mark Up:
<div class="overlay" id="overlay">
<div class="overlay-content--bg">
<div class="overlay-content">
<a class="navigate-button left" href="/question.php?id=<?php echo $json->id-1;$json->id+1; ?>">
<
</a>
<a class="navigate-button right" href="/question.php?id=<?php echo $json->id+1; ?>">
>
</a>
</div>
</div>
</div>
JS: if i run this code in console it works as expected
$('#overlay').on('click','.navigate-button', function(){
var id = $(this).attr('href');
id = id.split('=');
console.info(id[1]);
callPage(id[1]);
return false;
});
function callPage (id) {
$.ajax({
url:'/question.php?id='+id,
success: function(data){
$('.overlay-content').html(data);
FB.XFBML.parse(document.getElementById('overlay'));
$('.overlay').fadeIn();
}
});
}
We solved this in chat. Jamie's problem was that the click event on the .navigate-button div wasn't bubbling up to the #overlay div because it was being caught and handled in between by a handler that called .stopPropagation on it. The solution was to remove that intermediate handler.
Have you tried this?
$(document).on('click', '.navigate-button', function() {
YOUR FUNCTION
});

drop down is not hidden when I click outside

This is my script. The script works when i click but it is not hidden when i click outside.
$(document).ready(function() {
//Translate(); //caling Language Translater function
$("#translate_image").attr('href', base_url)
$("#select_lang").click(function() {
$("#lang_visible").attr('style', 'visibility: visible');
})
})
Here's my HTML:
<li>
<div class="clsCurrent_Lan ">
<a class="clsHead_Link_Bg" href="#" id="select_lang">
<span>Select Language</span>
</a>
</div>
<ul id="lang_visible" >
<?php foreach($language_drops as $lang){?>
<li>
<a href="<?php echo admin_url('home/ch_language/' .
$lang->language_code)?>"
id="<?php echo $lang->language_code?>">
<?php echo ucfirst($lang->language_name);?></a>
</li>
<?php }?>
</ul>
</li>
$(document).mouseup(function(e) {
if ($(e.target).parents('#select_lang').length === 0) {
$("#lang_visible").attr('style', 'visibility: hidden');
}
});
Try that. Add it within your document ready call. Basically clicking anywhere besides in the #select_lang selector will cause the visibility of #lang_visible to be hidden.
I think you are going about this the wrong way, sort of like reinventing the wheel. So the behavior you want is to have a control where the user can select a language from a number of different languages? Rather than trying to roll your own, why not just use the "Select" element? You can use php to set up the "Select" initially, and then use javascript/jQuery to respond to state changes.
So, something like this then?
$(document).ready(function () {
//Translate(); //calling Language Translater function
$("#translate_image").attr('href',base_url);
$("#select_lang").click(function () {
$("#lang_visible").attr('style','visibility: visible').click(function (e) {
$(this).hide(); //hides the #lang_visible element
//$(this).parent().hide(); //to hide the <li> containing the #lang_visible element
e.preventDefault();
return false;
});
});
});

Categories

Resources