Removing javascript created content - javascript

I have some java script that work behind a navigation menu, the user clicks the nav button, and some AJAX fires and brings in some HTML, what I want is for if that same link is clicked again then the content that was loaded in by that specific button is removed from the markup.
Does anyone have ideas? My code currently stands at
$("#Blog").click(function (ev) {
ev.preventDefault()
var url = $(this).attr("href");
$.ajax ({
url: "index.php/home/category",
type: "GET",
success : function (html) {
//alert("Success");
$("#accordion").append(html);
}
});
});

Try using .toggle instead of .click:
This would allow you to add a second function which removes the content when the button is clicked again.
$("#Blog").toggle(function (ev) {
ev.preventDefault();
var url = $(this).attr("href");
$.ajax ({
url: "index.php/home/category",
type: "GET",
success : function (html) {
//alert("Success");
$("#accordion").append(html);
}
});
},
function (ev) {
// remove content from accordion here
});

$("#accordion").append(
$("<div class='AJAXContend' />").append(html)
);
And then you can easily do $('.AJAXContend').remove();.
Another option is to do $('#accordion :last-child').remove();, but this is a little hacky.

$("#Blog").click(function (ev) {
ev.preventDefault();
Missing the comma after preventDefault.

So I don't know jQuery enough to answer in that way, but why not use a simple boolean switch?
// Pseudo:
If clicked and the switch is false, show the HTML, and set the Switch to True
If clicked and the switch is true, hide the HTML, and set the Switch to False
That should solve the problem.
The following code is probably horribly wrong, but I will use it to explain my thinking:
//Global Variables
var switch = false;
//Function
if(!switch)
{
$("#Blog").click(function (ev) {
ev.preventDefault()
var url = $(this).attr("href");
$.ajax ({
url: "index.php/home/category",
type: "GET",
success : function (html) {
//alert("Success");
$("#accordion").append(html);
}
});
});
switch = true;
}
else
{
$("#accordion").innerHTML = "";
switch = false;
}

Related

JQuery conditional preventDefault() firing when not called

I have the following script I've written.
<script>
$(document).ready(function(){
$('a').data('loop',true);
$('body').on('click', 'a', function(event){
console.log($(this).data('loop'));
if ($(this).data('loop') == 'true') {
console.log('hit');
event.preventDefault();
caller = $(this);
$(this).data('loop',false);
var linkref = $(this).attr('href');
var linkpos = $(this).offset();
var screenwidth = $(window).width();
var json_data = JSON.stringify({linkref: linkref, linkpos: linkpos, screenwidth: screenwidth});
$.ajax({
url: "content/submitcontenthandler?handler=core/_dashboard&method=tracking_ping",
method: "POST",
data: "json=" + json_data,
complete: function (jqXHR, status) {
console.log(status);
console.log(caller);
$(caller).click();
}
});
} else {
console.log(event.isDefaultPrevented());
console.log('miss');
$(this).data('loop',true);
}
});
});
</script>
It works, sends me the details I want etc etc. BUT!!!
When I click a link, It fires off the details to me via Ajax, then it's meant to "click" the event again, which it does! but the event does not fire it's normal action. So When clicking a link to another page, I would go to that other page... that's not happening.
If I comment out the line event.preventDefault(); Then the event fires as I would expect...
So to me it looks like the event.preventDefault is executing even though it's not meant to be during the second call...
Sorry if this is a bit complicated to understand. I don't quite understand what's happening myself.
Is it possibly a bug, or is there something that I've done that has caused this?
I didn't think I could, but I have successfully made a jsfiddle for this.
https://jsfiddle.net/atg5m6ym/2001/
You can try this and not worry about the "loop" anymore:
$(document).ready(function () {
$('body').on('click', 'a', function (event) {
event.preventDefault();
var caller = $(this);
var linkref = $(this).attr('href');
var linkpos = $(this).offset();
var screenwidth = $(window).width();
var json_data = JSON.stringify({linkref: linkref, linkpos: linkpos, screenwidth: screenwidth});
$.ajax({
url: "content/submitcontenthandler?handler=core/_dashboard&method=tracking_ping",
method: "POST",
data: "json=" + json_data,
complete: function (jqXHR, status) {
console.log(status);
console.log(caller);
window.location.href = linkref; // Redirect happens here
}
});
});
});
UPDATE
There's a few issues to note here:
1) Some links don't require a redirect (as noted, bootstrap model links that control showing/hiding or within document anchors
To correct this it really depends on the case. Usually bootstrap adds specific classes or data attributes to the links so you can do something like.
$('body').on('click', 'a:not(list of things to exclude)'..
Personally I'd instead define the links I wanted to track as :
<a href=<link> data-tracked='true'...
<script>
$('body').on("click","a[data-tracked='true']"...
Or if you want to track most links with a few exceptions you can:
<a href=<link> data-tracked='false'...
<script>
$('body').on("click","a:not([data-tracked='false'])"...
Or more generally:
<script>
$('body').on("click","a", function () {
if ($(this).attr("data-tracked") == "false" || <you can check more things here>){
return true; //Click passes through
}
//Rest of the tracking code here
});
The following if statement will return true whenever the data-loop attribute exists against an element, regardless of it's value:
if ($(this).data('loop')) {
It needs to be changed to check for the value:
if ($(this).data('loop') == 'true') {
When you assign anything to be the value of an element attribute it becomes a string and, as such, requires a string comparison.
Event.preventDefault() is not being executed second time.
Link redirection happens when the method is completed.
So in your case redirection will happen when complete method of ajax call is completed.
lets say, we have event1 and event2 object in the code. event1 is the object in the ajax call method and event2 is the event object in recursive call (second call) method.
so when link is clicked second time , we still have complete method to be executed. as soon as it returns to the complete method of ajax call, it finds the event1 is having preventDefault property true and it does not redirect.
Try this ;)
$(document).ready(function(){
$('body').on('click', 'a', function(event){
event.preventDefault();
var caller = $(this);
var linkref = $(this).attr('href');
var linkpos = $(this).offset();
var screenwidth = $(window).width();
var json_data = JSON.stringify({
linkref: linkref,
linkpos: linkpos,
screenwidth: screenwidth
});
$.ajax({
url: "content/submitcontenthandler?handler=core/_dashboard&method=tracking_ping",
method: "POST",
/* To temprary block browser; */
async: false,
data: "json=" + json_data,
complete: function(jqXHR, status){
/* add class **ignore** to a element you don't want to redirect anywhere(tabs, modals, dropdowns, etc); */
if(!caller.hasClass('ignore')){
/* Redirect happens here */
window.location.href = linkref;
}
}
});
});
});

Using history.pushstate on jquery ajax

I have a heavily ajax based application wherein i only have a login page and the main page.
Most of my links are "ajaxed" and i have them done like this:
//get the href of the link that has been clicked, ajaxify ANY links
$(document).on('click', '.tree a', function () {
var link = $(this).attr('href'); //get the href off the list
$.ajax({ //ajax request to post the partial View
url: link,
type: 'POST',
cache: false,
success: function (result) {
$('#target').html(result);
$.validator.unobtrusive.parse($("form#ValidateForm"));
}
});
return false; //intercept the link
});
I want to implement "pushState" on my application and the first step that i have done so far is to add this code:
$(document).on('click', 'a', function () {
history.pushState({}, '', $(this).attr("href"));
});
Now it updates my address bar whenever i click on any of my links and the ajax content gets successfully loaded.
I am kinda new to this API so i don't know what am i missing but here are my issues so far:
when i press the "back" button, nothing happens. I read about "popstate" and browsed through SO to look for solutions but i can't
seem to make them work.
When i click the link from the history, i get the "raw" view of the child html w/o the layout from the master html. What do i need to do if i want it to be displayed like
it was clicked from my main application?
Most of my child views are either forms or list.
This code should help you :
function openURL(href){
var link = href; //$(this).attr('href');
$.ajax({
url: link,
type: 'POST',
cache: false,
success: function (result) {
$('#target').html(result);
$.validator.unobtrusive.parse($("form#ValidateForm"));
}
});
window.history.pushState({href: href}, '', href);
}
$(document).ready(function() {
$(document).on('click', 'a', function () {
openURL($(this).attr("href"));
return false; //intercept the link
});
window.addEventListener('popstate', function(e){
if(e.state)
openURL(e.state.href);
});
});

jQuery .on not working after ajax delete and div refresh

On a page with a tab control, each tab contains a table, each tr contains a td with a button which has a value assigned to it.
<td>
<button type="button" class="btn" name="deleteEventBtn" value="1">Delete</button>
</td>
This code below works for the first delete. After the AJAX call & the refresh of the div, no further delete buttons can be clicked. The .on is attached to the document. The same happens if I attach it to the body or anything closer to the buttons.
function deleteRecord(url, id, container) {
$.ajax({
type: "POST",
url: url,
data: { id: id },
success: function (data) {
$('#delete-popup').hide();
$(container).trigger('refresh');
}
});
}
$(document).ready(function () {
$(document).on('click', '[name^="delete"]', function (e) {
e.preventDefault();
var id = $(this).val();
$('#current-record-id').val(id);
$('#delete-popup').modal('show');
});
$('#delete-btn-yes').on('click', function (e) {
e.preventDefault();
var recordId = $('#current-record-id').val();
var recordType = location.hash;
switch (recordType) {
case "#personList":
deleteRecord(url, recordId, recordType);
break;
}
});
});
Any ideas? Could it be related to the wildcard for starts with [name^="delete"]? There are no other elements where the name starts with 'delete'.
EDIT
When replacing
$(container).trigger('refresh');
with
location.reload();
it "works", however that refreshes the whole page, loses the users position and defeats the point of using AJAX.
As the button click is firing at first attempt, there is no issue in that code. All you have to do is, put the button click event in a method and call it after the refresh. This way, the events will be attached to the element again. See the code below,
function deleteRecord(url, id, container) {
$.ajax({
type: "POST",
url: url,
data: { id: id },
success: function (data) {
$('#delete-popup').hide();
$(container).trigger('refresh');
BindEvents();
}
});
}
$(document).ready(function () {
BindEvents();
});
function BindEvents()
{
$(document).on('click', '[name^="delete"]', function (e) {
e.preventDefault();
var id = $(this).val();
$('#current-record-id').val(id);
$('#delete-popup').modal('show');
});
$('#delete-btn-yes').on('click', function (e) {
e.preventDefault();
var recordId = $('#current-record-id').val();
var recordType = location.hash;
switch (recordType) {
case "#personList":
deleteRecord(url, recordId, recordType);
break;
});
}
Apologies to all and thanks for your answers. The problem was due to the way the popup was being shown & hidden.
$('#delete-popup').modal('show');
and
$('#delete-popup').hide();
When I changed this line to:
$('#delete-popup').modal('hide');
it worked. Thanks to LShetty, the alert (in the right place) did help!
If you are using Bootstrap Modal
After Ajax Request before Refreshing page add
$('.modal').modal('hide');
This Line will Close your Modal and reload your page. Before that it will complete all Ajax Request things.
But for google chrome there is no issues :) hope this help someone.

Prevent previously requests on click

I have list of tables,
<table id="<%#DataBinder.Eval(Container.DataItem, "Certificate")%>" class="tbl_evenSearchResultRow" onmouseover="this.className='ResultGridRowSeleted'" onmouseout="this.className='tbl_evenSearchResultRow'" onclick="return SynopsisWindowOpen(this)">
onclick of each i use next function:
function SynopsisWindowOpen(obj) {
var title = $(obj).find("strong[name='title']").html();
var isParentools = 0;
if (window.location.href.indexOf('recent_releases.aspx') > -1)
isParentools = 1;
var url = "/ratings/Synopsis.aspx?logoonly=1&Certificate=" + obj.id + "&Title=" + encodeURIComponent(title) + "&parentools=" + isParentools;
$("#ratingModal").on("show.bs.modal", function (e) {
$.ajax({
url: url,
cache: false,
dataType: "html",
success: function (data) {
$("#ratingModal").find(".modal-body").html(data);
}
});
});
$("#ratingModal").on("hide.bs.modal", function (e) {
$(this).find(".modal-body").html('');
});
$("#ratingModal").modal('show');
return false;
}
By url i render body of modal : i get certificate from request.query and according to it render body
LoadSynopsisContent(Request.QueryString["Certificate"], Request.QueryString["parentools"]);
Problem : when i click at first - everything seems to be good, on second click in modal body firstly rendered body of first click and then of second click. And so on.
I don't know where is problem.
Firstly i use jquery load function, but then i change to simple ajax call with disabled caching.
Move the all event bindings to outside of the function and everything should work fine.
Thus, these parts should not be inside the function:
$("#ratingModal").on("show.bs.modal", ....);
$("#ratingModal").on("hide.bs.modal", ....);
Here is one way you could organize your code:
var url; //a global variable ... not a good idea though
function SynopsisWindowOpen(obj) {
....
url = .....
}
$(function() {
$("#ratingModal").on("show.bs.modal", ....);
$("#ratingModal").on("hide.bs.modal", ....);
});
However, the way would be to not use inline JavaScript but to take advantage of the power of jQuery to separate structure from behavior.
UPDATE
Instead of using a global variable url you can store the new url in a data attribute of the modal. Then you can get it from there when the modal opens.
In the function:
//calculate the url
var url = .....
//store the url in the modal
$('#ratingModal").data('table-url', url);
In the modal event handler:
$("#ratingModal").on("show.bs.modal", function(e) {
//retrieve the url from the modal
var url = $(this).data('table-url');
//use the url
$.ajax({ url: url, .... }):
});

optimizing colorbox and adding extra jquery

I have two problems
I am trying to open a jQuery colorbox and it is very slow. The reason is I am trying to get html content from a different page (I cannot use iframe because I just need a part of this page). The following code works but it takes time after the button is clicked:
$(document).ready(function() {
$(".cart-link a").click(function(event) {
$(this).colorbox.close();
});
$(".rest-menuitem a").click(function(event) {
event.preventDefault();
var result = null;
var sURL = $(this).attr("href");
$.colorbox({
html: function() {
$.ajax({
url: sURL,
type: 'get',
dataType: 'html',
async: false,
success: function(data) {
result = data;
}
});
return $(result).find('.product');
},
width: '650px',
height: '10px',
onComplete: function() {
$(this).colorbox.resize();
}
});
});
});
I want to know if there is a alternative way to do it. I dont mind if the colorbox popup and then takes time to load the content. The above version can be fount at this url (http://delivery3.water-7.com/index.php/restaurants/manufacturers/3/Barcelona-Restaurant-&-Winebar/products).
I am also trying to close the colorbox when a user clicks on add to cart. But some reason it is not triggered. $(".cart-link a").click is not triggered when I click on add to cart. Is there a special way to add jquery to colorbox content?
Try this instead:
$(".rest-menuitem a").colorbox({
href: function(){
return $(this).attr('href') + ' .products';
},
width: '650px',
height: '10px',
onComplete: function() {
$(this).colorbox.resize();
}
});
ColorBox uses jQuery's load() method for it's ajax handling, so you just need to add the desired selector to the link's href.
For your question 2 can you try this ?
$(document).ready(function() {
$(".cart-link a").live('click',function(event) {
$(this).colorbox.close();
});
});
For your question 1..it will be slow since you are fetching it from different page.Use a different logic for that
For your question no 1
$('selector').colorbox({onLoad: function() { /*Intially load a empty color box with only <div id="contenttoload"></div> (No other html content */
$.ajax({
url :'Your url',
data : {}, //data to send if any
type : "POST" //or get
success:function(data){ /*data means the stuff you want to show in color box which you must return from the other page*/
$('#contenttoload').html(data); //data should be well formatted i mean add your css,classes etc from the server itself */
}
});
}});

Categories

Resources