I have a mediawiki where I would like to get the content from into another page. So I have:
http://bourlo.net/wiki/index.php/Lunet
And would like to display parts of this in a bootstrap modal on another page:
http://bourlo.net/stack/
The heading of the wiki page is retrieved by:
$("#wikiModal h4.modal-title")
.load( "http://bourlo.net/wiki/index.php/Lunet .firstHeading");
That works, yeah! But I don't want the complete
<h1 id="firstHeading" class="firstHeading" lang="nl-informal">Lunet</h1>
In the <h4> from the modal, but only the content >>> Lunet
How can I do this?
You need to use other ajax method instead. For the example:
$.get("http://bourlo.net/wiki/index.php/Lunet", function(html){
var txt = $(html).find('.firstHeading').text();
$("#wikiModal h4.modal-title").text(txt);
});
So you want to extract the text only from your ajax returned text:
$.get( "http://bourlo.net/wiki/index.php/Lunet", function(html){
$("#wikiModal h4.modal-title").text( $(html).find('.firstHeading').text() );
});
That's because you with .load(), you cannot manipulate the responseText before inserting into the DOM. Let's acknowledge that you can actually do something like this:
$h4 = $("#wikiModal h4.modal-title")
$h4
.load( "http://bourlo.net/wiki/index.php/Lunet #firstHeading", function(){
$h4.find('#firstHeading').replaceWith(function(){
return $(this).text();
});
});
This is definitely more clumsy. But I bothered to put this out because, once in a while, you're constrained to use the .load version instead of the .get version by factors beyond your control.
Related
In Javascript, to add text to an already existing div I would use
document.getElementById("container").innerHTML = document.getElementById("container").innerHTML + "Text";
So that the text that is already present in the div wouldn't be deleted and to be able to reset what is written in the div by just using:
document.getElementById("container").innerHTML = "Text";
But, since I'm using jquery to load the text from a txt file with
$( "#container" ).load( "text.txt" );
That doesn't seem possible.
I'm not a big expert on neither JS or Jquery, but is there a way to mix the two to still be able to reset the text in a div or add text to it, while still fetching that text from an external file?
Hope I've been clear enough in explaining what I'm trying to do
Try using AJAX to fetch your data but not populate it:
$.ajax({
url: 'text.txt',
success: function(text){
document.getElementById("container").innerHTML += text;
}
});
Ajax is a lot more full featured - it's the 'harder' cousin of load(), so you can also add an error catcher (as well as a raft of other things):
$.ajax({
url: 'text.txt',
success: function(text){
document.getElementById("container").innerHTML += text;
},
error: function(e){
document.getElementById("container").innerHTML += 'Data could not be loaded! (' + e.statusText + ')';
}
});
You can learn more about AJAX at jQuery docs: http://api.jquery.com/jquery.ajax/
First of all:
You run the risk of loading a file, which may or may not be available. Meaning you could get a file load error. In order to stick with jQuery I would leverage AJAX to load the file like so:
JQuery code:
$(document).ready(function() {
$.ajax({
url : "text.txt",
dataType: "text",
success: function (data) {
data.appendTo("#container")
},
error: function(e){
// Show some error, for example:
alert("Data failed to load from text.txt file")
}
});
});
I believe that appendTo will be a much simpler version of what you've tried to accomplish via document.getElementById("container").innerHTML in order to replace the text. Give it a try and modify this to work exactly as you like. Let me know if you have any questions about it.
To make it clear to you, JQuery is an extension of the existing JavaScript language. Meaning, you can always use your JavaScript within your perceived JQuery code. You can learn how to use the strengths of JQuery to support your JavaScript code with added functionality, a great example of one is the AJAX implementation of file loading you see here. To learn more visit: Learn JQuery.
Ok. I am making a website on github using html and javascript. Earlier, I was using a template to make simple, formatted webpages. I got it to work, but it has an annoying bug: the unformatted webpage shows up before the formatted one. I am using the latest version of jquery (2.1.4) hosted from google and the javascript below:
var heading = document.getElementById("heading").innerHTML;
var pghead = document.getElementById("pghead").innerHTML;
var pgtext = document.getElementById("pgtext").innerHTML;
var template = function () {
var tmp = null;
$.ajax({
'async': false,
'dataType': 'html',
'url': "https://jediguy13.github.io/template.html",
'success': function (data) {
tmp = data;
}
});
return tmp.split("derp");
}();
document.write(template[0] + heading + template[1] + pghead + template[2] + pgtext + template[3]);
document.getElementById("heading").innerHTML = "";
document.getElementById("pghead").innerHTML = "";
document.getElementById("pgtext").innerHTML = "";
And here's a sample webpage:
<div id="heading">Test</div>
<div id="pghead">Test</div>
<div id="pgtext">This is some text in the main body of the webpage</div>
As you can see from the 'async': false. line, Jquery is requesting the template webpage at the same time as the main thread. However, there is always a slight delay in the formatting. I'm betting it is because the document.write is called near the end. What is a better way to get the browser to display just the formatted page?
Example page: website
Don't use document.write(). Ever. If you have an HTML snippet, just attach it to the desired node like this:
$("body").html(template[0] + ...);
If the page is originally empty and all the content is loaded with AJAX, then you'll see a white page that then is filled with your code.
In your case it will NOT be empty as I can guess, so you have to clear the HTML immediately after you fetch it:
heading = $("#heading").html();
$("#heading").html("");
This will minimize the original exposure of the HTML.
At this point you may want to fade it in slowly, like this:
$("body").hide();
// ... make AJAX call and attach it as shown above
$("body").fadeIn();
The fadeIn() is a touch of class you might as well replace with show().
Make the AJAX call asynchronous and put all of this into the AJAX success() method.
This is all together in a complete rewrite. Just copy+paste and tell me if it's working:
var heading, pghead, pgtext;
$("body").hide();
heading = $("#heading").html();
pghead = $("#pghead").html();
pgtext = $("#pgtext").html();
$("#heading").html("");
$("#pghead").html("");
$("#pgtext").html("");
$.ajax({
'async': true,
'dataType': 'html',
'url': "https://jediguy13.github.io/template.html",
'success': function (data) {
template = data.split("derp");
$("body").html(template[0] + heading + template[1] + pghead + template[2] + pgtext + template[3]);
$("body").fadeIn();
}
});
Okay, so first off I'm going to say you shouldn't rely on JS to format your entire page unless you're hosting a single-page application, and even then... probably not the entire page.
To answer your question, the only way to not show the unformatted page is to hide your content until the page loads. Give your body tag or container style='display:none;' and then when your JS has finished executing, show the content with by calling something like $('body').show().
one of my favourite tricks is to place a loader div and keep the content hidden and the loader visible until all JS based layout changes are completed. provided you have the luxury of using Jquery (or CSS3) you can use an easing effect on the opacity to give it a much better feel.
I want load a html part with ajax in the page. I have a html page. With ajax, i want load from a other page a part html.
I make this code:
$.get(/vision.html/, function(data){
$(data).find(".container-helper").appendTo(".wrapper");
});
From the vision.html page. I want load the container-helper div. And i want append that html to the .wrapper div in the page. But this code is not working.
what am I doing wrong?
Thanks!
I think you need to use filter rather than find. Like so:
$(data).filter('.container-helper').appendTo('.wrapper')
You have to replace your code with following:
$.get("vision.html", function(data){
$response = $(data);
$response.filter('.container-helper').appendTo('.wrapper');
});
vision.html should only return the .container-helper content.
<div class="container-helper">some content</div>
$.get('vision.html', function(data){
$(data).appendTo('.wrapper');
});
I would like to refire the styling and processing.js scripts that i linked to in the head so that they display correctly when brought in through an ajax-request. I see where in the ajax request this code needs to be, but i don't know how to tell the code to simply reapply the script. I've seen people using getScript() to do this, but from what i can tell this reloads the script, rather than simply telling it repeat or refire. Do all of the scripts need their own reinitialization? I found the syntax highlighters .highlight() method, but i am yet to get the processing script to load. currently, Processing.loadSketchFromSources($('#processing'), ['mysketch.pde']); does not work. I am using current versions of all libraries. Surprised i haven't been able to find the answer yet, as a lot of people seem to have the same problem. Thanks for your help!
index page:
$(document).ready(function () {
// put all your jQuery here.
//Check if url hash value exists (for bookmark)
$.history.init(pageload);
//highlight the selected link
$('a[href=' + document.location.hash + ']').addClass('selected');
//Search for link with REL set to ajax
$('a[rel=ajax]').live("click",function(){
//grab the full url
var hash = this.href;
//remove the # value
hash = hash.replace(/^.*#/, '');
//for back button
$.history.load(hash);
//clear the selected class and add the class class to the selected link
$('a[rel=ajax]').removeClass('selected');
$(this).addClass('selected');
//hide the content and show the progress bar
//$('#content').hide();
$('#loading').show();
//run the ajax
getPage();
//cancel the anchor tag behaviour
return false;
});
});
function pageload(hash) {
//if hash value exists, run the ajax
if (hash) getPage();
}
function getPage() {
//generate the parameter for the php script
var data = 'page=' + encodeURIComponent(document.location.hash);
$.ajax({
url: "loader.php",
type: "GET",
data: data,
cache: false,
success: function (html) {
//hide the progress bar
$('#loading').hide();
//add the content retrieved from ajax and put it in the #content div
$('#content').html(html);
//display the body with fadeIn transition
$('#content').fadeIn('fast');
//reapply styles?
//apply syntax highlighting. this works
SyntaxHighlighter.highlight();
//relaod processing sketch, currently displays nothing
Processing.loadSketchFromSources($('#processing'), ['mysketch.pde']);
}
});
}
This the ajax-loaded content:
<!--ajax'd content-->
<??>
<h2>code</h2>
<pre class="brush: php">
$last_modified = filemtime("header.php");
echo("last modified: ");
echo(date("m.j.y h:ia", $last_modified));
</pre>
<script type="application/processing">
</script>
<canvas data-processing-sources="mysketch.pde" id="processing">
</canvas>
</div>
</body>
</html>
<??>
So, let's analyze what usually happens when you include an (external or internal) Javascript code: It will automatically execute only the code that is available in the global scope. "Good" scripts will only add one command to the global scope which will then execute the initialization code somewhere in a function/method.
All you need to do is view the external Javascript file and find out what is being executed from the global scope. There is no general answer to that ... some scripts use an object and call its init() method ... but that is totally subject to the imagination of the developer.
If you have javascript that needs to trigger, you MUST add this to the head element:
var head = document.head || document.getElementsByTagName("head")[0];
var script = document.createElement("script");
script.innerHTML = "your AJAX-obtained js code";
head.appendChild(script);
The same trick goes for CSS. Add a element to the head with your CSS declarations as innerHTML. So: make sure to preprocess your AJAX response and split out the JavaScript and CSS elements, then add those to the document header. It's probably easier to make your response a JSON object along the lines of:
{
html: "<html>string<goes>here</goes></html>",
scripts: ["url1","url2","url2",...],
style: ...
}
and then parsing that JSON for the html (which you use as innerHTML for a new document.createElement("div") or something, and then append wherever it needs appending), the scripts (which you turn into elements for HEAD insertion) and the style declarations (which you turn into elements for HEAD insertion).
(On a functional note, your example AJAX response looks like it has PHP code in it. I have no idea what you're using it for, but that looks like a bad response)
Just incase anyone stumbles upon this:
If you have processing.js already loaded, simply call Processing.reload() in your AJAX success/complete function.
Perhaps you already have an element with id="processing" on your page. In that case $("#processing") will only return the first one. If that is the case, change the id or use a class instead.
The other option, which I don't recommend, is to use $("[id=processing]"). That will return every element on the page with id="processing". But, don't use it. Use unique ids in your page, or switch to using classes, whichever works best for you.
Imagine a normal page calling javscript in head. The trouble is some of the content isnt loaded untill i click on a link. Subsequently when this link loads the content it wont work. This is because i guess the javascript has already been run and therefor doesnt attach itself to those elements called later on. There is only standard html being called.
So for example this is the code which calls my external html.
$.get('content.inc.php', {id:id}, function(data){
$('#feature').children().fadeTo('fast', 0).parent().slideUp('slow', function(){
$(this).html(data).slideDown('slow');
});
});
If the html i was calling for example and H1 tag was already in the page the cufon would work. However because i am loading the content via the above method H1 tags will not be changed with my chosen font.This is only an example. The same will apply for any javascript.
I was wonering whether there is a way around this without calling the the javascript as well the html when its received from the above function
If you want to attach events to elements on the page that are dynamically created take a look at the "live" keyword.
$('H1').live("click", function() { alert('it works!'); });
Hope this is what you were looking for.
Does Cufon.refresh() do what you want?
As you said Cufon was just an example, I'd also suggest a more general:
$.get(url, options, function(html, status) {
var dom = $(html);
// call your function to manipulate the new elements and attach
// event handlers etc:
enhance(dom);
// insert DOM into page and animate:
dom.hide();
$target_element.append(dom); // <-- append/prepend/replace whatever.
dom.show(); // <-- replace with custom animation
});
You can attach event handlers to the data that you get via the get() inside of the callback function. For example
$.get('content.inc.php', {id:id}, function(data){
$('#feature').children().fadeTo('fast', 0).parent().slideUp('slow', function(){
$(this).html(data).find('a').click(function(e) {
// specify an event handler for <a> elements in returned data
}).end().slideDown('slow');
});
});
live() may also be an option for you, depending on what events you want to bind to (since live() uses event delegation, not all events are supported).
Andy try this. It will call the Cufon code after each AJAX request is complete and before the html is actually added to the page.
$.get('content.inc.php', {id:id}, function(data){
$('#feature').children().fadeTo('fast', 0).parent().slideUp('slow', function(){
$(this).html(data);
Cufon.replace('h1');
$(this).slideDown('slow');
});
});
JavaScript is not executed because of a security reason OR beccause jQuery is just setting this element's innerHTML to some text (which is not interpreted as a JavScript) if it's contained. So the security is the beside effect.
How to solve it?
try to find all SCRIPT tags in Your response and execute them as fallows:
var scripts = myelement.getElementsByTagName("SCRIPT");
var i = 0;
for (i = 0; i < scripts.length; i++)
eval(scripts[i].innerHTML);