how to combine append() and replaceWith() in jquery? - javascript

Is ther a Jquery way to combine append() and replaceWith()?
I have a login form in a JQM project, sitting on every site. As multiple pages will be loaded into the DOM, I need to move the long form "along", as the user goes from page to page, to avoid having duplicate form#ids in the DOM.
My question:
I can do like this:
$('.form_in_new_page').replaceWith('.form_in_old_page')
But is there a way to "append and replace", so I can do this with one line of code?
Thanks for help!
EDIT: some more info
Here is my script which I'm running on pagebeforehide:
$('div:jqmData(role="page").basePage').on('pagebeforehide', function(e, data) {
// look for unique elements on the page being left
$(this).find(':jqmData(unique="true")').each(function(){
var uniqueID = $(this).jqmData("unique-id"),
nextPage = data.nextPage,
nextUnique = nextPage.find( ":jqmData(unique-id='"+uniqueID+"')" ),
nextUniqueID = nextUnique.jqmData('unique-id') === uniqueID;
// if a unique element with id=123 is on both from and next page
if ( nextUniqueID == true ) {
// append element from page being left to and replace it on next page
nextUnique.replaceWith( $(this) );
}
});
});
I need to keep my pages inside the DOM in my app. All pages have a login/logout popup, which includes a form and inputs with ids. So if I have 10 pages in my DOM I will have 10 popups with 10 forms and 10x each ID. I'm inserting the popups automatically on every so they are there if the user calls a subpage directly. However as soons as the user goes to the next page I need to make sure the form on the first page appends and replaces the form on the 2nd page.
Hope it's clear now.
The above only replaces the form on the new page, but still leaves it in the old page.

In jquery since functions return this ($) you can chain calls:
$("#selector").replaceWith("<div>Hello</div>").append('<div>test2</div>');
Of corse, that means you need to chain calls in the correct order.

Related

How can I unload/load pages using jQuery?

Here is the things I want to achieve with jQuery.
First of all, I want to save a copy of the entire page as is in a variable.
I then want to replace the currently loaded page with a loading page from another html file or URL without redirecting to that page.
After it has done loading, I want to replace the page back with what it originally was (the variable from step 1).
The question asked
At it's simplest (and this is a gross simplification that will lose state like event handlers, iframe state, shadow DOM etc.) you "save a copy" of the page's HTML by using .html() on the root element (html or body for example).
You can replace the entire top level element with fixed content from another HTML file or URL by providing the data to the same .html(data) function as well.
You can restore the original content by repeating step 2 using the data you saved off in step 1.
// Step 1 - save old page
const oldPage = $('html').html();
// result of fetch() or fixed HTML from file
// const newHTML = ...
// Step 2 - load new page
$('html').html(newHTML);
// Step 3 - restore old page
$('html').html(oldPage);
What you might actually want
If you only care that the user can't see the old page, you may want to wrap all of the UI inside a div that you can set display property to none on. You could also just overlay the new UI elements on top of the old one, possibly wrapped in a container with a solid background (to prevent old UI elements from being shown through transparent background).

jQuery / JavaScript Hide an element based on current page?

lets say im on this page
http://MyWebSite.com/users
and there is a link button on this page lets say
<span class="user">
go to page
</span>
If i click on the link it goes to for example
http://MyWebSite.com/users/jake
So now when im on this page there is same button exists and i want to hide it using javascript or jQuery :)
More info: The {$record->url()} in the link is dynamic goes to a page depending on the user, so i must use {$record->url()} in the script to match the current page link
Is this possible?
(I'm on a phone so this is the best I can do for now)
Maybe something like....
if (window.location.href.replace(location.hash,'') == "http://kodeweave.sourceforge.net/editor/") {
$(".nicole").hide()
} else {
$(".michael").hide()
}
You could use jQuery's equals selector to hide any elements that had an href attribute that pointed to your target page using the following code :
// This assumes that the URL will be populated via your server-side code in
// { ... } braces
$('[href="{$record->url()}"]').hide();
likewise, if you just wanted to hide any elements that pointed to the current URL, you could do the same thing via a bit of string concatenation :
// This would hide any elements that point to the current URL
$('[href="' + window.location.href + '"]').hide();
If you can avoid it though, you may want to consider hiding this using server-side code (i.e. using a conditional to determine when certain elements should / should not be rendered).

Trouble calling function after Infinite Scroll runs

I am using the Infinite Scroll plugin, for Wordpress, to load new posts on to the page when users scroll to the bottom. The problem is this has been loading duplicate posts, as the sorting changes extremely fast (due to popularity) and posts end up on different pages.
When the plugin grabs the next page, sometimes products that were originally on the FIRST page have been sorted to the SECOND page. So I end up with duplicates.
I was planning on waiting for the script to load the next page content, then loop through all of the post titles and locate the duplicates. Then I would remove the second instance of each post.
I noticed Infinite Scroll has a window in the settings labeled "Run after content is loaded/callback" so I thought I could enter a function in that field to be called.
removeDuplicates();
Then I entered something like this in the footer:
function removeDuplicates(){
var titleList = [];
$('.title').each(function(i, obj) {
/* The titles are in <h1> tags, I cycle through them,
if it's the first time seeing the title I add it to titleList.
If it's already in the array I hide the parent. */
});
});
I keep getting "undefined function" related to the .each, and it seems like it has something to do with scope but I'm not sure what's happening.
Is there an easier way to trigger the function to remove the duplicates? Am I at least on the right track?
Thanks for any insight you can provide!
It seems like jquery isn't loaded. Even if you use a selector that returns no elements, it should still have the .each() method.
Try using vanillaJS instead of jquery.
var titleNodeList = document.querySelectorAll('.title'); // get elements
var titleElArray = Array.prototype.slice(titleNodeList); // convert to array
titleElArray.forEach(function(el){...}); // iterate

Get variable and page fragment using Jquery .load() function

I am currently using Jquery's .load() function to insert a page fragment asynchronously. In the URL that I am loading the page fragment from, I also set a Javascript global variable value (in the script tag).
var loaded_variable = 'value1'
Is there a way I can use the .load() function to insert the page fragment AND retrieve the value of loaded_variable, something like the following code:
function loadProducts(url) {
$('#mainplace').load(url + ' #submain', function() {
current_variable = loaded_variable;
});
}
I am aware that script blocks are used when a selector expression is appended to the URL, so if the .load() function won't work, I'm open to other Jquery functions that can accomplish this.
Extra Info: The URL that I am loading from is written in HTML and Python (Web2py); the same Python variables are used to render the page fragment and set the loaded_variable value.
If you want to both fetch a fragment from a page and execute a script on it, you'll need a different approach. This is a bit hacky, but works.
$.ajax({url: 'fetch_page.html', dataType: 'text'}).done(function(html) {
var dom = $('<html />').prop('innerHTML', html);
$('body').append(dom.find('body p'));
$('head').append(dom.find('script'));
});
That fetches a p tag from our fetched pages and inserts it into the body of the parent page. It also executes any scripts in the fetched page.
If you're wondering about the prop('innerHTML... bit, that's because if I'd used jQuery's .html() method, it sanitises the input string and so we don't get the result we want.
My first thought was a document fragment, but you can't insert an HTML string into a doc frag - you have to append via DOM methods. Even then in this case it wouldn't really offer any saving over simply using an element to parse the dom (dom) as I have.
Bit hacky, as I say, but works.
I think I have a similar question. I have create a page that will hold a newsletter sign up. I want to load this page at the bottom of every blog post on my site. I don't want it in the footer because it is specific to my blog page and I want the ability to edit it without having to edit every blog post.
I created this page with the url /blog-newsletter-form which includes some code from an Email CRM.
I then added a div with a "blog-newsletter-form" class at the end of my blog posts and put the following in the page header to load the content from the first page section inside my blog posts.
$( document ).ready(function() {
$('.blog-newsletter-form').load("/blog-newsletter-signup #page .page-section:nth-of-type(1) .content");
});
This worked great except.. the load function is stripping the script from the newsletter page which is required for my newsletter form to work.
How do I load a page fragment but also keep the script for the newsletter. I tried using your sample code above and couldn't get it to work.

How to dynamically delete a div and clear the memory so I could add a new div with the same ID but different content using jQuery?

I am using the Picasa Web Integrator (PWI) code, that allows me to present a picture gallery using a picasa account. Using a form the user writes a keyword and then a code creates a div and calls for the PWI.
It works perfectly, but I'm trying to add a "back" button in order to let the user select a different keyword without refreshing.
But the code doesn't seem to clear the memory and the result is the same as the first time.
Here is the code:
//The button that the user presses when he has written the keyword.
$("#boton2").click(function() {
//Creates a new div
$(".shop3").append("<div></div>");
$('.shop3 > div').attr('id', 'container3');
//gets the keyword and creates a variable called "competidor"
competidor = $('#competidor_txt').val();
//calls for the PWI code...
$("#container3").pwi({
username: 'davidagnino',
mode: 'keyword',
...
//This part works perfectly.
//The "back" button that should delete the div called #container3
$('#back3').click(function() {
event.preventDefault();
competidor=null;
delete competidor;
$("#container3").empty(); //should make my div empty
$("#container3").remove(); //deletes the div...
});
I think the best approach here would be to change the Div's ID on the fly, and thus set it up as a whole new div each time.
I'd set up a counter variable (ideally static, but global if that's over your head):
var divCounter=0;
$("#container"+divCounter).pwi({/*...*/});
when it's time to destroy that, increment divCounter and generate a whole new div. Should get the job done!
Obviously, in all your event handlers you'd refer to it generically:
$("#container"+divCounter);
A quick note, removing something completely removes it from the DOM, thus emptying it in the same operation. It's also good jQuery practice to chain your functions together, like this:
$("#container3").append(/*whatever*/).attr(/*whatever*/);

Categories