jQuery append DOM - javascript

All the examples of jQuery.append() seem to take an html string and append it to a container. I have a slightly different use case. My server returns me an XML that contains HTML text to be displayed, something like:
<event source="foo">
<contents>
<h1>This is an event</h1>
This is the body of the event
</contents>
</event>
I have a div where this content needs to be displayed.
My JS currently does the following:
Loads up the XML data into jQuery in the $.ajax() success handler:
var jData = $( data );
Find the contents tag and tries to add its children to the div that is supposed to display the event:
var contents = jData.find( "contents" );
if( contents != null )
{
$( contents ).children().each( function( index, value )
{
$( "#eventDiv" ).append( $( value ) );
});
}
The append() call fails with Uncaught Error: WRONG_DOCUMENT_ERR: DOM Exception 4 on Chrome. The debugger shows value to be a DOM Element object and $( value ) to be an Object that contains the Element.
Any help will be appreciated.
Thanks.
-Raj

You can't append nodes that belong to one DOM tree to another document.
Try to clone them:
$("#eventDiv").append( jData.find("contents").children().clone() );
or simply use their textual representation to have them re-created:
$("#eventDiv").append( jData.find("contents").html() );

Related

jQuery: Unable to remove unwanted elements and getting remaining HTML

I am fetching URL content via Ajax. In the text, I have to find the tag containing "See Additional", if found, mark all HTML after it with a certain class, for instance .REMOVE. I am unable to extract the irrelevant DOM but I am unable disassociate with the rest of the HTML. I also tried remove() but I am unable to fetch the remaining HTML. Below is my code:
$( document ).ready(function() {
$.get("http://localhost:8000/read.php", function(data, status){
html = $.parseHTML( data ) // Construct DOM from string
//Check if it exist, remove/isolate it
see_additional = $(html).find("H2:contains('See Additional')");
if(see_additional.length > 0) {
console.log('Found it')
parent = see_additional.parent()
$(parent).addClass('remove')
//parent.remove();
//console.log(parent.html())
$('#view').html($(html).html()) // The HTML here is NOT showing entire HTML without removed parent DOM
}
});
});
End Goal
Basically, I have to count the number of links on a page but it should ignore links that are found in HTML after H1/H2 Tags contain "See Additional.."

javascript - load html content from ajax call

I have HTML page that has Ajax call to load table content
<html>
....
<script sec:haspermission="VIEW_NOTE" th:inline='javascript'>
require(['app/agent/viewGlobalAgent'], function (){
var individualId= [[${model.agent.individual.id}]];
var agentId= [[${model.agent.id}]];
$.get("/notes/referenceTable.html?individualId="+individualId+"&agentId="+agentId, function(data){
console.log("theData " , data);
var noteList = $("#note-list-container2").value;
var fileList = $("#file-list-container2").value;
// document.getElementById("note-list-container").innerHTML = noteList;
// document.getElementById("note-file-form").innerHTML = fileList;
$("#note-list-container").html(noteList);
$("#note-file-form").html(fileList);
});
</script>
....
</html>
the html that Ajax call load
<div>
<div id="note-list-container2">
....
</div>
<div id="file-list-container2">
....
</div>
</div>
I need to access these two div on callback of Ajax call
$.get("/notes/referenceTable.html?individualId="+individualId+"&agentId="+agentId, function(data){
I tried to access them but its not working
$("#note-list-container2").value
is any way to access div in loaded html
Since you want content from within the new html returned as data you want to wrap that data in $() and query within that object
Then use text() or html() since value is only for form controls, not content elements
$.get(url, function(data) {
var $data = $(data);
var noteList = $data.find("#note-list-container2").text();// or html()
var fileList = $data.find("#file-list-container2").text();
$("#note-list-container").html(noteList);
$("#note-file-form").html(fileList);
});
jQuery.text(): Get the combined text contents of each element in
the set of matched elements, including their descendants, or set the
text contents of the matched elements
jQuery.val(): Get the current value of the first element in the
set of matched elements or set the value of every matched element.
The .val() method is primarily used to get the values of form elements
such as input, select and textarea. When called on an empty
collection, it returns undefined.
A div element does not have a value....
An example:
console.log('text(): ' + $("#note-list-container2").text());
console.log('val(): ' + $("#note-list-container2").val());
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="note-list-container2">
....
</div>
I’m guessing you’re using jQuery. The HTML contents can be accessed with .html() not with value. There is no value attribute on a div element. More importantly, you should attempt to get the contents of the element AFTER updating it, not before. Also, the selectors should match. From your example, it seems that you're attempting to get the contents for a #note-list-container2 but you're updating a #note-list-container element. One of those IDs is wrong, given your sample AJAX call output.

Loop through an object in a page, if page contains key, append value

I have a page full of links. I want to put a little jquery at the bottom that looks for particular URL's or and for each one, append a little tag at the bottom of the page if it finds that URL in the content or if the current page's canonical link (which is included in the meta) matches. So far I have this:
<script type="text/javascript">
var obj = {
"apple.php":"apple_pixel_url",
"banana.php":"banana_pixel_url",
"carrot.php":"carrot_pixel_url"
};
$.each( obj, function( key, value ) {
$( "html:contains(key)" ).append('<img src="'+value+'">');
});
</script>
This always appends all three values, so I'm obviously doing something wrong. I guess Ideally I would look at only "a" links plus any tags that matched
<link rel="canonical" href="CANONICAL_URL" />
What is the best way to do this?
You can also append to the individual links using this syntax:
$("a[href$='"+key+"']").append('<img src="'+value+'">');
You are passing a static string as selector where as 'key' is a variable.
$( "html:contains("+key+")" ).append('<img src="'+value+'">');
It always appends the three links because it's finding the values in your javascript! Check only in the href attribute of <a> and <link> elements.
var obj = {
"apple.php":"apple_pixel_url",
"banana.php":"banana_pixel_url",
"carrot.php":"carrot_pixel_url"
};
function load(){
$.each( obj, function( key, value ) {
if($("a[href='"+key+"'],link[href='"+key+"']").length > 0){
$("body").append('<img src="'+value+'">');
}
});
}
<body onload="load()">
Apple
<link href="carrot.php" />
</body>
Here's a fiddle: https://jsfiddle.net/wjdo23kr/1/

Getting element by tag name after getting a page using jQuery $.get

I am requesting a full page using $.get in jQuery and would like to get the content of a specific element. Separately, here is how things look:
$.get( "/page.html").done(function( data ) {
// get textArea.
});
and I want to get:
document.getElementByTagName("textArea")[0].value;
but I can't do getElementByTagName on data so what is the best way to do this?
I tried using find but that did not work so I ended up using filter and that returned the value of textArea that I needed:
$.get( "/page.html").done(function( data ) {
var textArea = $(data).filter("textarea")[0].innerText;
});
It's slightly different of what you are doing but i think it can help. You can call .load instead of get and add the whole page to a div say <div id="mydiv"></div>
var value;
$('#mydiv').load('xyz.html',function(){value=$('#mydiv').find('#mytextarea').val()})
however if you do not want mydiv to show you can hide at the beginning once the main page gets loaded and if you also don't want this div on your page you can remove it after the above task is performed.
$(document).ready(function(){
$('#mydiv').hide();
var value;
$('#mydiv').load('xyz.html',function(){value=$('#mydiv').find('#mytextarea').val()});
$('#mydiv').remove();
})
//str represents page.html
var str = 'gibberish gibberish <textarea class="test">hello world</textarea>gibberish';
$.each( $.parseHTML(str), function( i, el ) {
if(el.firstChild) console.log(el.firstChild);
});
Fiddle: http://jsfiddle.net/ez666/7DKDk/
You could try jquery load() function.
It will load from remote server and insert document into selected element.
It also allow us to specify a portion of remote document to be inserted.
Assume your remote textarea's id is "remote" and you want to fetch the remote content into a textarea which id is "local"
var result="";
$("#local").load("/page.html #remote", function(response, status, xhr){
result=$(this).find("#remote").val();
});
I'm not sure if you want to get the remote textarea and insert into the element of the current document.
If you just want to get the value of the remote textarea, you could just hide the load function invoking element
Hope this is helpful for you.
Since you're using jQuery anyway… have you tried $(data).find('textarea').first().val() yet?
This is assuming that data is a fragment. If it is not you will want to wrap it in a div or something first.

IE doesn't apply dynamically loaded CSS

It appears as though IE (older versions at least) does not apply CSS that is loaded dynamically. This can be a pain point if you load a page containing CSS via ajax into a "lightbox" or "colorbox".
For example, say your HTML page has a div named "taco":
<style>#taco {color:green;}</style>
<div id="taco">Hola Mundo!</div>
"Hola Mundo!" will be green since the CSS was included in the original HTML page. Then some Javascript happens and appends this to "taco":
<style>#taco {color:green;}</style>
<div id="taco">
Hola Mundo!
<style>#burrito {color:red;}</style>
<span id="burrito">mmmm burrito</span>
</div>
In all browsers except IE, burrito's font will be red.
So is there a way to do this in IE? It seems as though there is not.
The style tag is only allowed in the head section. Placing it somewhere else is simply invalid and that has nothing to do with IE.
More information.
By the way, to solve your problem if you can´t put the styles in a global style-sheet, you can use the 'style' attribute to modify elements:
<p style="...">
Or you can use an iframe but then you'd have to serve a whole page instead of just a few tags.
You might want to start using jQuery's .CSS methed for dynamic style changes like that.
$("#jane").css('color', '#0F0');
Or just plain jane Javascript:
document.getElementById['sally'].style.color = '#0F0';
EDIT:
Have your ajax inject this:
<div id="jane">
<div id="sally">Hi, I'm Sally!</div>
<script>document.getElementById['sally'].style.color = '#0F0';</script>
</div>
Or Why not just inject elements with inline styles computed server side?:
<div id="jane">
<div id="sally" style="color:#0F0">Hi, I'm Sally!</div>
</div>
If there is no way to do this, and you don't want to change your server-side code, here is a way for very simple style elements:
// In the callback function, let's assume you're using jQuery
success: function( data ) {
// Create a dummy DOM element
var el = document.createElement( 'div' );
// Add the html received to this dummy element
el.innerHTML = data;
// so that you can select its html:
var s = $( 'style', el ).text();
// Delegate to another function, it's going to get messy otherwise
addRules( s );
}
function addRules( s ) {
// First, separate your strings for each line
var lines = s.split( '\n' ),
// Declare some temporary variables
id,
rule,
rules;
// Then, loop through each line to handle it
$.each( lines, function() {
id = $( this ).split( ' ' )[ 0 ];
// Get the rules inside the brackets, thanks #Esailija
rules = /\{\s*([^}]*?)\s*\}/.exec( $( this ) )[ 1 ];
// Split the rules
rules = rules.split( ';' );
$.each( rules, function() {
rule = $( this ).split( ':' );
// Apply each rule to the id
$( id ).css( $.trim( rule[ 0 ] ), $.trim( rule[ 1 ] ) );
} );
} );
}
So, yeah, basically I'm making a CSS parser.
This is a very basic parser however.
It will parse the following rules only:
#some-id { some: rule; another: rule; }
#other-id { some: rule; yet: another; rule: baby; }
If you load a linked stylesheet dynamically (via AJAX) into a webpage, IE < 8 does not even recognize the LINK tag.
If you load a SCRIPT tag dynamically IE < 8 will not parse it.
Jeron is correct, the only way to dynamically load HTML and have it styled is via iframe, but I am testing the idea of reflowing the container.

Categories