Replace text on VisualForce page using JavaScript - javascript

I'm working with a VisualForce page (SalesForce related) and I need to write a piece of JavaScript that will replace some text on the page after everything is loaded.
I've tried the following (I'm using jQuery on other parts of the page so I've used jQuery for this also):
var j$ = jQuery.noConflict();
j$(document).ready(function()
{
var replaced = $find("body").html().replace('Test', '1234');
$("body").html(replaced);
});
Unfortunately it doesn't seem to do anything. It's like I can't get the page HTML code. I'm assuming it's because this is a VisualForce page running on the Force platform, so if anyone can offer any help with this that would be much appreciated.
Thanks.
P.S. In case anyone is wondering why I'm doing this is because I can't do this through VisualForce or Apex since I'm trying to unescape some HTML characters provided by a variable and being used in a dataTable header. Unfortunately everything in a dataTable header is automatically escaped.

First of all, it should be $.find() but hum.. also not necessary: simply $("body") for a selector.
Then in one line you can write:
$("body").html($("body").html().replace(/test/g, '1234'));
Notice /g in the regex, it should allow it to replace all instance of test, not only the first one.
You might also need to be precise with your j$ and use it everywhere, not only for document ready event. The line above uses $ shortcut.

Related

Javascript for replacing $ with $$ or $latex

I do know good HTML and some PHP, but not at all javascript, so I need some help with this question please. I have a wordpress site the uses math equations together with Simple Matjax plugin for rendering the math from latex. There are many worpress plugins for latex some of them faster, some of them slower.
I tried to find a faster plugin to replace Simple Mathjax, but every other plugin use a different math "quotation" than that I am using $...$
So I need a javascript that either replaces the $...$ with $$...$$ or first $ with $latex (or whatever start and end sequence I might need for a specific plugin). I guess this is simple, but as I was saying, I do not know javascript at all. Thank you.
PS. There is one replacement WP Quick Latex but when I install it it block the access to my homepage (all other pages are rendered and displayed, except my homepage, page 2, page 3,...that contain excertpts). Any suggestions? Edit: Quicklatex uses shortcodes [latexpage]. If one enables it sitewide on the homepage it has to work on all equations, Thus the wating time for loading the homepage increases significantly.
The javascript function for string replacement is
replace("string to replace", "new string")
I think you should do something like this:
var string = "$"; // <-- this is where you enter the string you want to replace
var new_replaced_string = string.replace("$", "$latex");
Hope this helps.

Tags Get Removed When Using Codesample Plugin with TinyMCE

Since 4.3.0 TinyMCE includes Codesample plugin that lets you enter code snippets.
This works very well for languages like Java, PHP, C# etc. that are not directly running in the browser. You save your code snippet to the server, load it back into the browser, edit it, and save it back to the server again - no hassle.
If you want to do it with HTML, JavaScript, or XML, then it seems not to be possible to load the code snippet back into the browser after saving it to the server.
Most of the tags will be removed, despite being already encoded before.
See TinyMCE Fiddle 1 and TinyMCE Fiddle 2 that try to illustrate the problem.
Any ideas? Many thanks in advance!
If you want to reload content into TinyMCE that was previously stored in your database I would use TinyMCE's JavaScript APIs to load the data after the editor is initialized. I have created a fiddle to show how you would do this.
http://fiddle.tinymce.com/50faab/3
In this example the content that would have come out of TinyMCE from a prior edit is in the theContent variable:
var theContent = '<pre class="language-markup"><code><ul><li>one</li><li>two</li></ul></code></pre>';
(In a real application you would of course grab this from the database and inject it into the web page instead of hard coding the value)
I then use the TinyMCE API for setContent to add the content to TinyMCE once its loaded:
setup: function (editor) {
editor.on('init', function () {
var theContent = '<pre class="language-markup"><code><ul><li>one</li><li>two</li></ul></code></pre>';
this.setContent(theContent);
});
}
When you do it this way the editor will properly syntax highlight the code sample content (as seen in the Fiddle).
<textarea> tags and HTML are a difficult combination if you have anything beyond the simplest of HTML so I would avoid dropping HTML directly into the <textarea>.
Expanding on Michael's answer, putting your content into a hidden DIV, then grabbing it's html works better for me:
<div class="theDiv">
<pre class="language-markup">
<code><ul><li>one</li><li>two</li></ul></code>
</pre>
</div>
var theContent = $('.theDiv').html();
The answer of Felix Riesterer in the forum of TinyMCE might be of help as well:
Yes, in the way I pointed out: < > and " need to be properly encoded as < > and " because these characters have a special meaning in HTML context. So if you want to comply with the specs (and TinyMCE expects you to do so!) you need to convert these characters accordingly. There is no way around that.
And yes, I forgot to mention that & (ampersand) needs to be encoded as & as well.
You might have to double-encode stuff: If you want to see "" you need to code <h1> so the HTML code renders as plain text. The logic behind it is like this:
1. content gets decoded into raw text (< gets translated to <, & becomes &)
2.raw text gets treated as original HTML code for the editor contents (<h1> renders as <h1>, <h1> renders as a first-level heading)

When using CasperJS, is it possible to interact with the DOM of a loaded page before any inline or external Javascript is executed?

The situation I have is that I'm opening a page using CasperJS.
The page in question has some Javascript (a combination of both inline and external) that removes several HTML elements from the document.
However, I want to be able to retrieve those elements using something like getElementsByXPath() within CasperJS before they are removed. Is this possible?
When I dump out the value of getPageContent(), the elements are not in there. However, if I set casper.page.settings.javascriptEnabled = false; before calling the page, getPageContent() now shows the raw HTML before any Javascript is executed, and the missing HTML tags are there. The problem now, though, is that disabling Javascript prevents any usage of evaluate(), so I still can't retrieve the elements. I could probably do it using a regex of some sort on the raw content, but I was hoping there could be a cleaner method of doing it.
Any suggestions welcome!
I've never heard of anyone doing this. I wouldn't say using regex is a bad idea. I usually scrape with a combination of casperjs xpath and python regex it works extremely well and I personally don't think it's any messier than trying to intercept JavaScript before the page is loaded.
That being said, casperjs allows you to inject JavaScript which you could use jquery if it's available on the page you're requesting. The below code fires before anything is loaded. You actually have to go out of your way to add code to prevent this from firing before the page loads.
<script type='text/javascript'>
alert("Stop that parsing!");
</script>

how to retrieve dynamic scripts from javascript

In my project i have to retrieve the content in all script tags. I am able to do this by simply including
var scrpt=document.getElementsByTagName('script');
script_txt=scrpt[i].innerHTML;
but by using the above code i am not getting dynamic scripts which are created by
var s=document.createElement('script');
s.src="http://somefile.js";
not only this there are many other ways of creating dynamic scripts like
document.write('<script src="">');
and
document.body.innerHTML='<script src="">';
and many more. I tried to retrieve it by using regular expressions like this
var pattern=/([a-zA-Z0-9_\.].*?)=(document.createElement\((.*)\));
/g;
but this may not match all.
Can anyone suggest a better method for achieving this property.
The first method you mentioned, using document.getElementsByTagName('script'), is fine.
I wrote up a fiddle where I'm counting script tags before and after inserting a tag dynamically. It works fine. http://jsfiddle.net/crGx9/
Could you show us an example of when it doesn't work?

JavaScript - controlling the insertion point for document.write

I would like to create a page that runs a 3rd party script that includes document.write after the DOM was already fully loaded.
My page is not XHTML. My problem is that the document.write is overwriting my own page. (which is what it does once the DOM was loaded).
I tried overriding the document.write function (in a way similiar to http://ejohn.org/blog/xhtml-documentwrite-and-adsense/) but that doesn't cover cases where the document.write contains partial tags.
An example that would break the above code is:
document.write("<"+"div");
document.write(">"+"Done here<"+"/");
document.write("div>");
Is there some way to modify the document.write insertion point through JavaScript? Does anyone have a better idea how to do this?
If you're dealing with 3rd party scripts, simply replacing document.write to capture the output and stick it in the right place isn't good enough, since they could change the script and then your site would break.
writeCapture.js does what you need (full disclosure: I'm the author). It basically rewrites the script tags so that each one captures it's own document.write output and puts it in the correct place. The usage (using jQuery) would be something like:
$(document.body).writeCapture().append('<script type="text/javascript" src="http://3rdparty.com/foo.js"></script>');
Here I'm assuming that you want to append to the end of the body. All jQuery selectors and manipulation methods will work with the plugin, so you can inject it anywhere and however you want. It can also be used without jQuery, if that is a problem.
It is possible to override the document.write method. So you can buffer the strings sent to document.write and output the buffer wherever you like. However changing a script from synchronous to asynchronous can cause errors if not handled correctly. Here's an example:
Simplified document.write replacement
(function() {
// WARNING: This is just a simplified example
// to illustrate a problem.
// Do NOT use this code!
var buffer = [];
document.write = function(str) {
// Every time document.write is called push
// the data into buffer. document.write can
// be called from anywhere, so we also need
// a mechanism for multiple positions if
// that's needed.
buffer.push(str);
};
function flushBuffer() {
// Join everything in the buffer to one string and put
// inside the element we want the output.
var output = buffer.join('');
document.getElementById("ad-position-1").innerHTML = output;
}
// Inject the thid-party script dynamically and
// call flushBuffer when the script is loaded
// (and executed).
var script = document.createElement("script");
script.onload = flushBuffer;
script.src = "http://someadserver.com/example.js";
})();
Content of http://someadserver.com/example.js
var flashAdObject = "<object>...</object>";
document.write("<div id='example'></div>");
// Since we buffer the data the getElementById will fail
var example = document.getElementById("example");
example.innerHTML = flashAdObject; // ReferenceError: example is not defined
I've documented the different problems I've encountered when writing and using my document.write replacement: https://github.com/gregersrygg/crapLoader/wiki/What-to-think-about-when-replacing-document.write
But the danger of using a document.write replacement are all the unknown problems that may arise. Some are not even possible to get around.
document.write("<scr"+"ipt src='http://someadserver.com/adLib.js'></scr"+"ipt>");
adLib.doSomething(); // ReferenceError: adLib is not defined
Luckily I haven't come across the above problem in the wild, but that doesn't guarantee it won't happen ;)
Still want to try it out? Try out crapLoader (mine) or writeCapture:
You should also check out friendly iframes. Basically it creates a same-domain iframe and loads everything there instead of in your document. Unfortunately I haven't found any good libraries for handling this yet.
Original Answer before the edit:
Basically the problem of document.write is that it does not work in XHTML documents. The most broad solution then (as harsh as it may seem) is to not use XHTML/xml for your page. Due to IE+XHTML and the mimetype problem, Google Adsense breaking (may be a good thing :), and the general shift towards HTML5 I don't think it's as bad as it seems.
However if you'd really like to use XHTML for your page, then John's script that you linked to is the best you've got at this point. Just sniff for IE on the server. If the request is from IE, don't do anything (and don't serve the application/xhtml+xml mimetype!). Otherwise drop it into the <head> of your page and you're off to the races.
Re-reading your question, is there a specific problem you have with John's script? It is known to fail in Safari 2.0 but that's about it.
You may be interested in the Javascript library I developed which allows to load 3rd party scripts using document.write after window.onload. Internally, the library overrides document.write, appending DOM elements dynamically, running any included scripts which may use document.write as well.
Unlike John Resig's solution (which was part of the inspiration for my own code), the module I developed supports partial writes such as the example you give with the div:
document.write("<"+"div");
document.write(">"+"Done here<"+"/");
document.write("div>");
My library will wait for the end of the script before parsing and rendering the markup. In the above example, it would run once with the full string "<div>Done here</div>" instead of 3 times with partial markup.
I have set up a demo, in which I load 3 Google Ads, an Amazon widget as well as Google Analytics dynamically.
FWIW, I found postscribe to be the best option out there these days - it handles wrapping a pesky ad rendering module like a charm allowing our page to load without being blocked.
In order to alter the content of the page after the DOM has rendered you need to either use a javascript library to append HTML or text at certain points (jQuery, mootools, prototype, ...) or just use the innerHTML property of each DOM element to alter/append text to it. This works crossbrowser and doesn't require any libraries.
There are better ways to do this.
2 ways
1) Append
<html><head>
<script>
window.onload = function () {
var el = document.createTextNode('hello world');
document.body.appendChild(el);
}
</script></head><body></body></html>
2) InnerHTML
<html><head><script>
window.onload = function () {
document.body.innerHTML = 'hello world';
}
</script></head><body></body></html>

Categories

Resources