I am putting a modal alert on the screen when a user clicks a choice of a dropdown like this:
$(document).ready(function(){
$('#id_state').change(function(e){
var selection = $("#id_state").val();
if(selection == 1){
event.preventDefault();
var entryType = 'diabetes';
var data = new Object();
data.entryType = entryType;
programAlertModal(programAlertModalCallback, data);
return false;
}
});
$('#id_state').trigger('change');
});
Program alert modal is then called here:
programAlertModal:function(callback, data){
var entryType = data.entryType;
var url = '/shared/enrollment/'+entryType+'/';
$.get(url, function(result) {
callback(result, entryType);
return false;
});
},
programAlertModalCallback:function(result, entryType){
$( "body" ).append(result);
},
The result is some html that looks like this:
<div class="takeover">
<div class="takeover-bg"></div>
<div class="takeover-body">
{% if entry_type == 'diabetes' %}
<h1>My awesome title</h1>
Dismiss
</div>
</div>
How can I dismiss what is loaded without reloading the page (and clearing the dropdown selection)?
Add a class to the Dismiss link so we can reference it:
Dismiss
Then bind a handler that removes the modal in the callback:
programAlertModalCallback: function(result, entryType) {
var $result = $(result).appendTo("body");
$result.find("a.dismiss").on("click", function(e) {
e.preventDefault();
$result.remove();
});
},
Pass an e parameter to your function and add e.preventDefault(); to prevent the default behaviour of the a tag that reloads the page. You should also include href="#" in your a since leaving it blank causes some trouble in some cases.
Related
I am trying to generate history states so I can click backwards and forwards on my AJAX-powered pages. It largely works, but on one page my AJAX call doesn’t update page content when I click a button after loading a previous/later page state. Why?
The issue happens with the #filtered_posts div. On my home page, I display posts inside #filtered_posts with a category filter above it. When I click a button on the category filter, it updates the content inside #filtered_posts. If I click back or forward on the homepage without pressing a category filter button, it successfully retrieves the page with the correct state of #filtered_posts. But if I then click on a category filter button, my website URL updates but #filtered_posts doesn't, and clicking back/forward only changes the URL. How can I fix this?
Also, is there a way for me to only update the state of #filtered_posts when clicking back or forwards on the home page, and update content in the .main div for all other pages?
Here is my simplified code:
$(document).ready(function () {
var $mainContent = $(".main");
var mainContentHTML;
var value;
var title;
var filtered_posts = $("#filtered_posts");
$(document).on("click", "nav li a", function (e) {
e.preventDefault();
value = $(this).attr("href");
$mainContent.load(value + " .main", function (data) {
console.log("this function works properly");
})
});
$(document).on("click", "#category-filter li.filter-button", function (e) {
e.preventDefault();
value = $(this).find("a").attr("href");
var category = $(this).data("category");
$.post(wp_ajax.ajax_url, {
action: "filter",
category: category
},
function (data, status, xhr) {
if (status == "success") {
filtered_posts.html(data);
}
if (status == "error") {
console.warn(data);
}
});
});
//Create history to enable back button functionality
$(document).ajaxComplete(function (event, jqXHR, settings) {
mainContentHTML = $(".main").html();
title = $(document).find("h1.entry-title").text();
var stateObj = {
content: mainContentHTML
};
window.history.pushState(stateObj, title, value);
});
window.addEventListener('popstate', function (event) {
var state = event.state == null ? mainContentHTML : event.state.content;
$mainContent.html(state);
});
});
I've managed to fix this by replacing the filtered_posts variable with $("#filtered_posts") in the code.
I am doing one feature about showing alert on external link(apart from current domain) click. For that, I have written below code. All is working fine except below scenario.
$('a').each(function() {
var $a = jQuery(this);
if ($a.get(0).hostname && getDomain($a.get(0).hostname) != currentDomain) {
$a.click(function(event) {
//console.log($a.get(0));
//var myClasses = this.classList;
//console.log(myClasses.length + " " + myClasses['0']);
$("#redirectconfirm-modal").removeClass('hide');
if (!confirmed) {
event.preventDefault();
event.stopPropagation();
$modal.on('show', function() {
$modal.find('.btn-continue').click(function() {
confirmed = true;
$a.get(0).click();
$modal.modal('hide');
location.reload();
});
});
$modal.on('hide', function() {
$a.get(0).removeClass("selected");
confirmed = false;
});
$modal.modal('show');
}
});
}
});
Scenario which produces this issue:
Click on any external link from the site, it open a modal popup for redirection confirmation with continue & return button.
If I click on "Return" button it closes the modal popup.
Now, I am clicking on external link from my site, it open the modal again but this time I am clicking on "Continue" button & guess what, it open that external link in 3 different tabs
Actually on each anchor tag click, it saves whole anchor tag value. I think, if remove all these anchor tag values on modal close code i.e. $modal.on('hide', function() { }) it will resolve problem. I had tried with many different ways but still facing this issue.
Can you please provide solution/suggestion on that?
Problem is when you have 3 external links (as you probably have), than you set 3 times this part of code:
$modal.on('show', function() { ... });
$modal.on('hide', function() { ... });
which is wrong. Those events listeners should be set only once.
Some simplified code would look like this:
var $modal = $("#redirectconfirm-modal");
var currentDomain = 'blabla';
$modal.on('click', '.btn-continue', function(e) {
window.location = $modal.data('redirectTo');
});
$('a').each(function() {
var $a = jQuery(this);
if( $a.get(0).hostname && getDomain($a.get(0).hostname)!=currentDomain ) {
$a.click(function(e) {
$modal.data('redirectTo', $a.attr('href'));
$modal.modal('show');
});
};
});
Don't inline your events, you may try something like this:
$('a').each(function() { //add a class to all external links
var $a = jQuery(this);
if ($a.get(0).hostname && getDomain($a.get(0).hostname) != currentDomain) {
$a.addClass('modalOpen');
}
});
$('.modalOpen').not(".selected").click(function(event) { //open the modal if you click on a external link
event.preventDefault();
$('.modalOpen').addClass('selected'); //add class selected to it
$modal.modal('show');
});
$modal.on('hide', function() {
$('.selected').removeClass("selected");//remove the class if you close the modal
});
$('.btn-continue').click(function() {
$('.selected').click();//if the users clicks on continue open the external link and hide the modal
$modal.modal('hide');
});
Following OctoberCMS guidelines I need to redirect users when they attempt to reach a certain path (ex: www.foo.com/bar) to the home page with php variables (ex: www.foo.com/?bar=1) and have a modal open if the variable is found.
I've created bar.htm which redirects with the proper variable:
title = "bar"
url = "/bar"
layout = "default"
meta_title = ""
meta_description = ""
is_hidden = 0
==
<?php
function onStart() {
header('Location:/?bar=1');
}
?>
==
and then in my JS (with #submitBtn being the button on the modal to send the form)
$(document).ready(function(){
if(window.location.href.indexOf('1') > -1) {
$('#myModal').modal('show');
$('#submitBtn').click(function() {
window.location.href='/';
})
}
});
So this is not working, it is just showing the modal in a constant loop and never moving to the success modal or changing the href. This form is working properly in all other situations, so I do not believe the issue lies there.
Shortened example modal code:
$('#myModal').on('show.bs.modal', function (event) {
var newForm = $('#newFakeForm');
var config = {
submitBtn: $('#submitBtn'),
contactModal: $('#myModal'),
successModal: $('#successModal'),
};
initContactForm(newFakeForm, config);
});
and my HTML button to dismiss the modal:
Thank you
What if you do the redirect on JS?
Just listen for the hidden.bs.modal event and do the redirect there.
Here is my HTML
$html .= " <td><div class='edit_course' data-id='{$id}' data-type='_title' contenteditable='true'>{$obj->title}</div></td>";
Here is my jQuery:
var selector = 'div[contenteditable="true"]';
// initialize the "save" function
$(selector).focus(function(e) {
content_holder = $(this);
content = content_holder.html();
var id = $(this).data('id');
var type = $(this).data('type');
alert( id + type)
// one click outside the editable area saves the content
$('body').one('click', function(e) {
// but not if the content didn't change
if ($(e.target).is(selector) || content == content_holder.html()) {
return;
}
// Edited out AJAX call
});
});
The problem is, when I click on the div, the alert below triggers. When I click outside of the div (after the edit has been made), nothing happens. Can anyone see what is happening?
First click let's user edit content in div. The first click outside, should make ajax call to save.
EDIT: From recommendation below.
Here is new code this works perfectly except it calls the DB every time, all I need is a check to do that only if data is different and I think I got it from there.
Edit2: Final Code
var original_value = '';
$(".edit_course").focus(function(e) {
original_value = $(this).html();
});
// initialize the "save" function
$(".edit_course").blur(function(e) {
var content = $(this).html();
var id = $(this).data('id');
var type = $(this).data('type');
if (content !== original_value) {
// Ajax edited out
}
});
You're not using one() correctly. What you should do is run the AJAX when focus is taken away from the div. Using blur() would probably be your best bet here.
$('body').blur(function(e) {
// your code here...
});
The following code goes on pushing a new URL to the state object, while dynamically changinf the page's content as well. However, when I start pressing the Back button and return to the original page, the original content is not shown, instead the next page's content is retained. How do I achieve it?
<!DOCTYPE html>
<html>
<head>
<script src="jquery.js"></script>
<script>
$(document).ready(function(){
a = 0;
$("p").click(function(){
var stateObj = { note : ++a };
history.pushState(stateObj, "page 2", "http://localhost/foo/"+a);
$(this).text(a);
});
window.addEventListener('popstate', function(e){
if (history.state){
$("p").text(e.state.note);
if (location.href == 'http://localhost/hist.php') { $('p').text('If you click on me, I will disappear.'); }
}
}, false);
$("div").click(function() { alert(e.state.note); });
});
</script>
</head>
<body>
<p>If you click on me, I will disappear.</p>
<div>Hi</div>
</body>
</html>
It is your responsability to update the page content on popstate. The browser only handles the state.
I had an application, where I replace the main content of a page while navigation through an menu tree. I also updated the page title according to the new content.
When I just go back an forth in AJAX loaded pages, I can save the url to load in the StateObj. But on going back to the initial page, there is no state, and no saved title to restore.
I decided to reload the whole page, when I go back to the initial history state:
var doc_state={'title': ''};
var popped = ('state' in window.history && window.history.state !== null), initialURL = location.href;
function loadDocument(path,title){
$('#document_area').html('<img src="spinner.gif" />');
$('#document_area').load(path+'?ajax=true');
document.title = title;
}
$(document).ready(function(){
$('a.ajax_link').click(function(event){
var path=$(this).attr('href');
var title=$(this).text();
doc_state['title']=title;
event.preventDefault();
loadDocument(path,title);
window.history.pushState(doc_state,document.title,path);
});
$(window).bind('popstate', function(event){
// Ignore inital popstate that some browsers fire on page load
var initialPop = !popped && location.href == initialURL;
popped = true;
if ( initialPop ) return;
var state = event.state;
if (!state){
state=history.state; // FF
}
if (state){
var title= state.title;
loadDocument(location.pathname, title);
}
else window.location.reload();
});
}