How to prevent previous data from going away before new one is fetched? - dom

all,
I have a simple app that fetches data on button click from remote API and fills in text into HTML elements when data is fetched.
The problem is that once I click button, the old data is gone and there is a delay between new data rendering and old data, during which the page looks not good.
How should I modify my code to prevent old data from going away until I am ready to write new one?
document.querySelector('#next-album').addEventListener('click', (e) => {
e.preventDefault();
fetch('http://localhost:3000/random')
.then((response) => response.json())
.then(data => {
displayRandomAlbum(data);
displayAlbums(data.artistAlbums, relatedArtistAlbumsContainer);
displayAlbums(data.onThisYear, relatedYearAlbumsContainer);
});
});

Seems like you are having problem with Postback.
Add stopPropagation to your code, like this:
...
e.preventDefault();
e.stopPropagation();
...
This is to avoid default postback behavior of button

Related

Refreshing dynamic form fields after data has changed

I have a ColdFusion page that has, among other things, forms that are built using DataTables.
This page manages a handful of things (documents, categories, doctypes, etc) and each tab has CRUD functionality going on.
Initially, on each tab, it simply displays the current set of (fill in the blank) but if you click the create/update links/icons, the form to do so pops up. Some of the form fields are actually lists of the others. For example, if I want to upload a new document, one of the form fields is the category for that document.
I get the information for that form field by using cfinvoke to a get function in a cfc, which returns as a query and I loop through, populating the dropdown.
My problem is this: If I go and create a new category on the category tab I need the dropdown of category choices to update over on the new document form. However, it's already been populated and won't recheck that info until I refresh the page and thus won't show my new category in the dropdown.
The way I see it, I need to reinvoke the CFC method, repopulating the query variable and then refresh the form to make it loop through the new data and fully populate the dropdown.
I've tried to call the cfinvoke and reset the form from within the callbacks section of the DTHelper() but that (kind of as expected) didn't work.
How would I force the refreshing of the data, and subsequently, the form when this all takes place using AJAX and the actual page never reloads? Or should I just be forcing a page reload in this situation? (which works, I tried that, but it's a page refresh)
So, my boss figured it out. You have to use drawCallback().
In my example it worked like so. First, give all your major category select boxes a class:
<select name="majorCategoryID" class="major-category-select">
...
</select>
Then modify the DataTable options for major category:
majorcat_dt = $("#majorcat-dt").DataTable({
ajax: "blah"
columns: [{ blah }],
drawCallback: function() {
/* remove all options from select boxes */
$(".major-category-select option").remove();
/* this is the crazy DataTables api call to get rows */
this.api().rows().data().each(function(row) {
$(".major-category-select").append("<option value='"+row.id+"'>"+row.name+"</option>");
});
}
});
This also removed the need for the cfinvoke in the first place since this also populates the dropdowns on page load as well.
Here is how I did something like that once.
javascript:
var minutes = 10;
var refreshInterval = minutes * 60 * 1000; // to get milliseconds
jQuery.fn.populateCensusDiv = function() {
$.ajax({
type:"POST",
url:"censusData.cfc?method=getCensusData",
cache:false,
success: function(msg) {
$("#census").html(msg);
}
});
setTimeout(function() {
$("#census").populateCensusDiv();
}, refreshInterval);
return this;
ColdFusion function
<cffunction name="getCensusData" access="remote" returntype="string"
//deleted code
returnFormat = "plain">
<cfscript>
var returnString = "";
</cfscript>
more code
<cfsavecontent variable="returnString">
more code
</cfsavecontent>
<cfreturn returnString>
</cffunction>
My context was an html table that got refreshed every 10 minutes. You can adapt it for your own needs.

Serializing form exotic behaviour in AJAX response?

I have a page with few tabs. Data in each tab is ajax response once the user clicks tab.
Tab1 Tab2 Tab3
While coming to the page, we load Tabl with ajax response, in that serializing form.
After page loads, Editing form then checking is there any change to save the form data.
* Again serializing form and comparing old and new form.
It is working fine. But if i move to other Tab and come back to Tab1 serializing is not working as expected.
I kept alert and checked it. Orizinal form data serializing and new form also serializing and checking.
Even Data is same but
_sourcePage param is having different value.
I don't know why it is giving this strange behaviour.
Please help me.
Edit:
The code what i'm using is :
$(document).ready(function () {
originalSerializedForm = $("#Tab1").serialize();
});
function saveDataWhenFormChanged()
{
var newSerializedForm = $("#Tab1").serialize();
if(originalSerializedForm && newSerializedForm && newSerializedForm != originalSerializedForm){
alert('Original Form :'+originalSerializedForm+'\n'+'New Form :'+newSerializedForm);
$.ajax({
url : url,
data : newSerializedForm,
dataType: "html",
type : "POST",
beforeSend: function(){
openLoadingPopup();
}});
}
This happened due to zig-zag and not well formated html..
i was using form with in the other form.. which caused this..
i removed that.. it was working as expected..

Prevent TinyMCE prompting onbeforeunload with save from custom button

I couldn't find any post regarding this issue, so this was my last way out. I'd like to somehow tell TinyMCE that I've taken care of the saving process (reset the isdirty I guess), but to keep checking for further changes without reloading the page. Ofcourse, if I do a location.reload it works, but that takes a bit of elegance out of it.
I have a custom save-button with the following method:
$("#saveAbout").click(function(){
tinymce.activeEditor.getBody().setAttribute('contenteditable', false);
$("#outerWrapper").animate({opacity:0.3});
$("#bigloader").fadeIn();
var currentData = tinyMCE.activeEditor.getContent();
var currentLanguage = $("#currentLang").val();
$.post("src/actions/pup_about.php", { text: currentData, lang: currentLanguage })
.done(function(data) {
$("#bigloader").fadeOut();
$("#outerWrapper").animate({opacity:1});
// What to do here?
});
});
This basically gets the contents and saves it through a PHP file. A neat ajax loader shows up and fades out during the process. The #outerWrapper div is a div around the TinyMCE in order to fade it slightly out during the save process.
Is there any smart way to tell TinyMCE that saving is done, but to keep looking for further changes?
You could issue in your function
tinymce.get('your_editor_id').save();
this should then take care of setting everything else.

jQuery live() for removeAttr()?

I need to use removeAttr on elements that may be loaded via ajax. Is there a way to automatically do this, similar to the way you can bind events automatically with live()?
NOTE: I don't have control over the JavaScript libraries that are doing the ajax calls.
this creates a new event for all elements now and in the future that have your 'undesirable attribute', next we'll trigger it to fire and do its work.
$("mySelector").live("myRemoveAttrEvent", function(event){
$(this).removeAttr("myAttr");
});
on the successfull ajax call's function
// quick jQ ajax, the important part is on success
$("div").load("url", function(data, status, xhr){
..do work..
// this is the important part
$("mySelector").trigger("myRemoveAttrEvent");
});
if you do not have control over all the ajax, you have to piggy back on the user events that Cause the ajax to fire ... this is dirty:
//events you think cause the uncontrollable ajax to fire, e.g change
$("*").change()(function(event){
$("mySelector").trigger("myRemoveAttrEvent");
});
You can use complete option of the $.ajax request like this:
$.ajax({
......
complete:function(){
$('selector').removeAttr('attribute here');
}
});
What you're looking for is to handle this at the time those elements are loaded, which would be in the success callback for your AJAX call:
$.ajax({
// your details
success: function(html){
$('a', html).removeAttr('title');
$('body').append(html);
}
});
Update: If you don't have control of whatever is making the AJAX calls and it doesn't provide any hooks or callbacks, you are going to need to find another event to bind to in order to perform this action. Depending on how these elements are being inserted into the page and exactly what you're doing with them, you might be able to use delegate like this (just a guess):
$('body').delegate('p', 'load', function(){ /* remove attr */ });
I don't know of any events that are triggered when the DOM or a single element is modified. You can try load, but I don't think it gets called in the case of AJAX loaded and inserted elements.

jQuery - submit form via AJAX and put results page into a div...?

I'm using jQuery Form (http://jquery.malsup.com/form/) to get send data to a form - is there a way I can then, without refresh, put the results page that's generated by the form into a div on the page?
Any advice appreciated!
I would suggest not using that form plugin - it was made back in the days before there was an easy way to serialize form data using jQuery, and serves no real purpose any more. I would suggest something like this:
$("form").submit(function() {
$.post($(this).attr("action"), $(this).serialize(), function(data) {
$("#someDiv").html(data);
});
return false; // prevent normal submit
});
If you insist on using jQuery Form Plugin - which is NOT recommended -, you can set the target option to a selector of the element(s) you would like to fill up:
// prepare Options Object
var options = {
target: '#divToUpdate',
url: 'comment.php',
success: function(data) {
alert('Thanks for your comment!');
}
};
Take a look at http://jquery.malsup.com/form/#options-object for more info.
To prevent refresh, just make sure the form's onsubmit event returns false:
<form method="post" onsubmit="return false">