I am trying to write to my iframe on keyup but it does not update. I will run through the code I am using to try to achieve this.
First, I am grabbing the original HTML that I would like on the iframe (through AJAX) and writing that to the iframe as so:
var base_tpl = base_html; //get base template html.
var iframe = document.querySelector('#output iframe'),
iframe_doc = iframe.contentDocument;
iframe_doc.open();
iframe_doc.write(base_tpl);
iframe_doc.close();
After that I am attaching document.querySelector to the relevant text areas that will serve as inputs for the changes that I want to show up on the corresponding elements within the iframe. Here is how I am doing that:
var the_title = document.querySelector('#the_title2 textarea'),
the_subheading = document.querySelector('#the_subheading2 textarea'),
the_image_url = document.querySelector('#the_image_url2 textarea'),
the_description = document.querySelector('#the_description2 textarea'),
the_signup_button_text = document.querySelector('#the_signup_button_text2 textarea'),
the_email_capture_text = document.querySelector('#the_email_capture_text2 textarea'),
the_email_capture_button_text = document.querySelector('#the_email_capture_button_text2 textarea');
the_css = document.querySelector('#the_css2 textarea');
var editors = [the_title, the_subheading, the_image_url, the_description, the_signup_button_text, the_email_capture_text, the_email_capture_button_text];
I then attach these to on keyup listeners as such:
// Attaching the onkeyup Event
editors.forEach(function(editor, i, arr) {
editor.addEventListener('keyup', function() {
// The function that'll prepare the code and inject
// into the iframe.
//alert(the_title.value);
render();
}, false);
});
Notice the render function, it works like this:
var render = function() {
var source = prepareSource();
var iframe = document.querySelector('#output iframe'),
iframe_doc = iframe.contentDocument;
console.log(source);
iframe_doc.open();
iframe_doc.write(source);
iframe_doc.close();
};
Prepared source is the function that puts together the newly inputted elements. The methodology behind it can be seen here:
var prepareSource = function() {
var title = the_title.value,
subheading = the_subheading.value,
image_url = the_image_url.value,
description = the_subheading.value,
signup_button_text = the_image_url.value,
email_capture_text = the_subheading.value,
email_capture_button_text = the_image_url.value,
css = the_css.value,
src = '';
src = base_tpl;
// Title
src = src.replace("<div id='the_title'><h3><?php echo $page->title; ?></h3></div>", "<div id='the_title'><h3>" + title + "</h3></div>");
// Subheading
src = src.replace("<div id='the_subheading'><h3><?php echo $page->subheading; ?></h3></div>", "<div id='the_subheading'><h3>" + subheading + "</h3></div>");
// Image URL
src = src.replace("<div id='the_image_url'><h3>", image_url + "</h3></div>");
// Description
src = src.replace("<div id='the_description'><h3>", description + "</h3></div>");
// Signup Button Text
src = src.replace("<div id='the_signup_button_text'><h3>", signup_button_text + "</h3></div>");
// Email Capture Text
src = src.replace("<div id='the_email_capture_text'><h3>", email_capture_text + "</h3></div>");
// Email Capture Button Text
src = src.replace("<div id='the_email_capture_button_text'><h3>", email_capture_button_text + "</h3></div>");
// CSS
css = '<style>' + css + '</style>';
src = src.replace('</head>', css + '</head>');
return src;
};
My question is of whether i am doing something wrong here. The main issue is that the prepared source does not seem to be working at all. Nothing changes on the iframe on keyup. I have tested this with console.log. It does not seem to be affected at all.
I would appreciate any help here.
Cheers!
Tapha.
EDIT: Please ignore the elements after subheading in the 'prepared source' section - i have only done the title and subheading portions for testing purposes.
Related
I am using TypeForm and need to autofill utm fields from javascript, everything works except I cant get the html created from the script to show on the page. I am embedding the below code in a html/js module in a clickfunnels page. Any help is very much appreciated.
<div id="typeform"></div>
<script>
//<div id="typeform"></div> <div id="row--27712"></div>
window.onload = function(){
var source = "utm_source=1";
var medium = "utm_medium=2";
var campaign = "utm_campaign=3";
var content = "utm_content=4";
var keyword = "utm_term=5"
var HTMLA = '<div data-tf-widget="mYH43Dz4" data-tf-iframe-props="title=TFS - ANALYTICSDEV V1.1" data-tf-medium="snippet" data-tf-hidden=';
var HTMLquote = '"';
var HTMLcomma = ',';
var HTMLB = '" style="width:100%;height:600px;"></div><script src="//embed.typeform.com/next/embed.js">';
var HTMLC = '</'
var HTMLD = 'script>'
var form = HTMLA.concat(HTMLquote).concat(source).concat(HTMLcomma).concat(medium).concat(HTMLcomma).concat(campaign).concat(HTMLcomma).concat(content).concat(HTMLcomma).concat(keyword).concat(HTMLB);
var form2 = form.replaceAll("undefined","");
document.getEIementById('typeform').innerHTML = form2;
};
</script>
You can pass custom values to hidden fields like this:
<div id="typeform"></div>
<link rel="stylesheet" href="//embed.typeform.com/next/css/widget.css" />
<script src="//embed.typeform.com/next/embed.js"></script>
<script>
var source = '1';
var medium = '2';
var campaign = '3';
var content = '4';
var keyword = '5';
window.tf.createWidget('mYH43Dz4', {
container: document.getElementById('typeform'),
hidden: {
utm_source: source,
utm_medium: medium,
utm_campaign: campaign,
utm_content: content,
utm_term: keyword
}
});
</script>
In case you already have those values in your host page URL, you could use transitive search params feature:
<div
data-tf-widget="mYH43Dz4"
data-tf-transitive-search-params="utm_source,utm_medium,utm_campaign,utm_content,utm_term"
></div>
<script src="//embed.typeform.com/next/embed.js"></script>
Your code does not work because you are adding script tag via innerHTML. This script tag will not execute for security purposes:
https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML#security_considerations
https://www.w3.org/TR/2008/WD-html5-20080610/dom.html#innerhtml0
I have a PHP function that loops through image results in a database, formats them with HTML, then returns the variable containing the HTML layout to my page.php. This is all working okay, but in the loop I have some script tags that call a function in my script.js file. It takes two parameters (url and count). I am trying to pass the url of the result from the database to the function, create a new img element, and append the passed url to the src attribute of the newly created img tag.
This appears to be working so far - when I console.log the result, I get a load of <img> tags, all with corresponding src attached to them.
I am having trouble with actually getting these back to the front end, though.
My code below shows the part of the php that gets looped through, followed be the Javascript function it calls on each loop.
public function getResultsHtml($page, $pageSize, $term) {
$fromLimit = ($page - 1) * $pageSize;
$query = $this->con->prepare("SELECT * FROM images
WHERE (title LIKE :term
OR alt LIKE :term) AND broken=0
ORDER BY clicks DESC
LIMIT :fromLimit, :pageSize");
$searchTerm = "%" . $term . "%";
$query->bindParam(":term", $searchTerm);
$query->bindParam(":fromLimit", $fromLimit, PDO::PARAM_INT);
$query->bindParam(":pageSize", $pageSize, PDO::PARAM_INT);
$query->execute();
$resultsHtml = "<div class='image-results'>";
$count = 0;
while($row = $query->fetch(PDO::FETCH_ASSOC)) {
$count++;
$id = $row["id"];
$imgUrl = $row["imgUrl"];
$siteUrl = $row["siteUrl"];
$title = $row["title"];
$alt = $row["alt"];
if($title){
$displayText = $title;
} else if ($alt) {
$displayText = $alt;
} else {
$displayText = $imgUrl;
}
$resultsHtml .= "<div class='grid-item image$count'>
<a href='$imgUrl'>
<script>
document.addEventListener('DOMContentLoaded', function() {
loadImage(\"$imgUrl\", \"image$count\");
});
</script>
<span class='details'>$displayText</span>
</a>
</div>";
}
$resultsHtml .= "</div>";
return $resultsHtml;
}
var loadImage = function(src, className){
var image = document.createElement("img");
var aTag = document.querySelectorAll("." + className + " a");
image.onload = function(){
aTag.innerHTML = image;
};
image.onerror = function(){
};
image.setAttribute("src", src);
}
At the moment I'm not geting any results at the front end. In the page source, I can see that inside each anchor tag are script tags, which show the function preloaded with the parameters (loadImage(http://www.com, image22)), but it isn't actually getting a return from the function.
The solution for this with jQuery is below, but I really don't want to use jQuery!
function loadImage(src, className) {
var image = $("<img>");
image.on("load", function() {
$("." + className + " a").append(image);
});
image.on("error", function() {
});
image.attr("src", src);
}
I know that there is some trouble with dynamically writing <script> tags with .innerHTML, but I don't think this is the problem as the script tags are written before the function is called.
I think I have something firing in the wrong order, or I'm missing something that jQuery handles automatically with the .append function.
I have also tried aTag.appendChild(image);, which also gives no results.
I have been using jQuery for a few months, but I am trying to learn Vanilla JS thoroughly - I'm trying to grasp how the jQuery functions actually work, rather than just relying on them blindly.
Any help is massively appreciated!
Beware of that querySelectorAll() returns an array-like NodeList (https://developer.mozilla.org/en-US/docs/Web/API/NodeList), so it should be like this:
(If you only want one element returned user querySelector(), then you don't need the loop)
function loadImage(src, className) {
var image = document.createElement("img");
image.src = src;
image.onload = function() {
var tags = document.querySelectorAll("." + className + " a");
for (var i = 0; i < tags.length; i++) {
tags[i].appendChild(image);
}
}
}
<div class='grid-item image2'>
<a href='https://cdn.pixabay.com/photo/2015/08/21/21/55/star-wars-899693_960_720.jpg'>
<script>
document.addEventListener('DOMContentLoaded', function() { loadImage("https://cdn.pixabay.com/photo/2015/08/21/21/55/star-wars-899693_960_720.jpg", "image2");
});
</script>
<span class='details'>Star Wars 1</span>
</a>
</div>
The problem is that you are using querySelectorAll, which returns a NodeList instead of a single DOM node. This means, you have to iterate over the NodeList and append the image to all the nodes within. For this, you have can either create new copies for each place you want to insert the image, or use cloneNode multiple times.
var each = function (xs, func) {
for (var i = 0; i < xs.length; i += 1) {
func(xs[i]);
}
return xs;
}
var loadImage = function(src, className){
var image = document.createElement("img");
var aTag = document.querySelectorAll("." + className + " a");
image.onload = function(){
each(aTag, function (a) {
a.appendChild(image.cloneNode());
});
};
image.onerror = function(){};
image.alt = '';
image.src = src;
}
loadImage('http://www.fillmurray.com/500/300', 'wrap')
<div class="wrap">
</div>
i'm using the following code to insert new script with content to HTML file,
Currently the following code is working and the new script is inserted after the first existing script, the problem is the content is not indent
e.g. this is the output of the new added script(as you can see its in one line)
<script> var keyOfFilesArray = Object.keys(data)[0]; var filesArray = data[keyOfFilesArray]; </script>
I want to change it to be indented like following:
the second added open script tag will be inserted line after the closing tag of the first script
the vars should be inserted one after other to be like this
<script>
var keyOfFilesArray = Object.keys(data)[0];
var filesArray = data[keyOfFilesArray];
</script>
How I can do that ? I belive I need to add the /n but not sure where is the best way to insert it...
https://jsfiddle.net/k32ntkr8/
This is the JS code
btn.onclick = function(e){
debugger;
var innerhtml = [
' var keyOfFilesArray = Object.keys(data)[0];',
' var filesArray = data[keyOfFilesArray]; '
].join('');
var html = process(input.defaultValue,innerhtml);
output.value = html;
}
function process(html,innerhtml) {
var escapedHTML = html
.replace(/body/g, 'body$')
.replace(/head/g, 'head$');
sandbox.innerHTML = escapedHTML;
var script = sandbox.querySelectorAll('#app-ux-bootstrap')[0];
var newScript = document.createElement('script');
newScript.innerText = innerhtml;
script.parentNode.insertBefore(newScript, script.nextSibling);
var unescapedHTML = sandbox.innerHTML
.replace(/body\$/g, 'body')
.replace(/head\$/g, 'head')
.replace(/"/g, "'");
return (
'<!DOCTYPE HTML>\n<html>' +
unescapedHTML +
'</html>'
);
};
How it can be done? please suggest ,the answer below doesn't help much...
if I can improve this question somehow please let me know.
Something like this?
var innerhtml = [
'\tvar keyOfFilesArray = Object.keys(data)[0];',
'\tvar filesArray = data[keyOfFilesArray];'
].join("\n");
var script_code = '<script>\n' + innerhtml + '\n<\/script>';
Then just insert the script_code variable wherever you want it to appear on the page.
https://jsfiddle.net/e72c17zg/1/
Ok, if you change your onclick handler to this
btn.onclick = function(e){
debugger;
var innerhtml = [
'',
' <script>',
' var keyOfFilesArray = Object.keys(data)[0];',
' var filesArray = data[keyOfFilesArray]; ',
' <\/script>'
].join('\n');
var html = process(input.defaultValue,innerhtml);
output.value = html;
}
And change the lines of process that populate the script to this
var script = sandbox.querySelectorAll('#app-ux-bootstrap')[0];
script.parentNode.insertAdjacentHTML('afterBegin', innerhtml);
You should get this output
<head>
<script>
var keyOfFilesArray = Object.keys(data)[0];
var filesArray = data[keyOfFilesArray];
</script>
...
</head>
I am trying to do similar thing as YouTube has when you are embeding a video and you want to get a code. You can click on checkboxes or select size and it dynamically changes the value of input field.
Does somebody have idea how to do it?
I managed to write a code that is replacing the width correctly, but I dont know how to make a code that would add &scheme=XXX at the end of the link or remove it if user selects no color scheme.
This is the code for width,I dont think its best one, but works:
$("#width").on("change keyup", function(){
var width = $(this).val();
if (width){
$("#embed-text").val($("#embed-text").val().replace(/ (width\s*=\s*["'])[0-9]+(["'])/ig, ' width=\''+width+'\''));
}
});
Here is textarea which I am trying to change and inputs I'm using for it:
The ID is taken from PHP, in actual textarea that jQuery sees the ".$id." is actual number
<textarea class='clean' id='embed-text'><iframe src='http://my.url/embed/?r=".$id."' width='600' height='".$height."' frameborder='0' marginwidth='0' marginheight='0' allowtransparency='true'></iframe></textarea>
<div style='padding-right: 10px; display: inline-block;'>
Color scheme:
<select id='schemes' class='clean'>
<option value='-'>None</option>
<option value='xxx'>Xxx</option>
</select>
</div>
<div style='padding-right: 10px; display: inline-block;'>
Width: <input type='number' min='250' max='725' value='600' id='width' class='clean'>
</div>
When user does not select any scheme (or changes from XXX to None), I want link in textarea (iframes src) to be like this:
http://my.url/embed/?r=X
But when he selects any scheme, i would like it to look like this:
http://my.url/embed/?r=X&scheme=XXX
I actually have no idea how to do this. Tried googling for more than hour, but I don't know what the ID will be (to identify position where to add the string), thats PHP value and I cant pass it to external script file, so I tried to find if I can insert something at specific position (ie.: 15th character from start) with JS, but could not find anything.
Thanks.
I separate some functions in order to keep the code clean check this I think that is what you were looking for JsFiddle
var generateUrl = function(id,colorScheme) {
var baseUrl = "http://my.url/embed/?";
var url = baseUrl.concat("r="+id);
if (colorScheme != null && colorScheme != '')
url = url.concat("&scheme="+colorScheme);
return url;
};
var changeUrl = function(id, colorScheme) {
var url = generateUrl(id, colorScheme);
var srcPattern = "src='(.*?)'";
var embedText = $("#embed-text").val();
var newEmbedText = embedText.replace(new RegExp(srcPattern),"src='"+url+"'");
$("#embed-text").val(newEmbedText);
};
var changeWidth = function(newWidth) {
var widthPattern = "width='([0-9]*)'";
var embedText = $("#embed-text").val();
var newEmbedText = embedText.replace(new RegExp(widthPattern),"width='"+newWidth+"'");
$("#embed-text").val(newEmbedText);
};
var getURLParameter = function(url,parameterName) {
return decodeURIComponent((new RegExp('[?|&]' + parameterName + '=' + '([^&;]+?)(&|#|;|$)').exec(url)||[,""])[1].replace(/\+/g, '%20'))||null
};
var getId = function() {
var urlPattern = "src='(.*?)'";
var embedText = $("#embed-text").val();
var url = embedText.match(new RegExp(urlPattern))[1];
var id = getURLParameter(url, 'r');
return id;
};
$("#width").on("change keyup", function(){
var width = $(this).val();
var colorScheme = $(schemes).val();
changeWidth(width);
changeUrl(getId(),colorScheme);
});
And i removed the value '-' for the first option just leave it in blank.
convert onclick new window to onclick fancy box?
got this free code for displaying facebook photos and its great but it opens a new window that doesnt really do it justice, would like to convert it to opening a fancybox instead any help appreciated."code below"
full url = http://www.footfalldigital.co.uk/fbalbum.html
thanks in advance lee "i will buy you a pint someday"
<script language="javascript" type="text/javascript">
function popitup(url) {
newwindow=window.open(url,'name','height=450,width=600,location=1,toolbar=1,status=1,resizable=1')
if (window.focus) {newwindow.focus()}
return false;
}
</script>
<script type="text/javascript"src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript">
<!-------ENTER YOUR FACEBOOK ALBUM IDS HERE------->
var id1 = "444691594416";
var id2 = "";
var id3 = "";
var id4 = "";
var id5 = "";
<!----------------------------------------------->
function fbFetch1(){
var url = "https://graph.facebook.com/" + id1 + "/photos&callback=?&limit=0";
$.getJSON(url,function(json){
var html = "";
$.each(json.data,function(i,fb){
var name = "";
if (fb.name !== undefined){
var name = fb.name;}
html += "<a onclick=\"return popitup('" + fb.source + "')\"><img style='margin:5px;padding:0px;cursor:pointer;vertical-align:middle;' src=" + fb.picture + " title=\"" + name + "\"></a>"; });
html += "";
$('.facebookfeed1').animate({opacity:0}, 500, function(){
$('.facebookfeed1').html(html);});
$('.facebookfeed1').animate({opacity:1}, 500);}
);
};
function fbFetch2(){
If you already have all of the images on the page why not look at: http://lokeshdhakar.com/projects/lightbox/
It will automatically look at the images within a selector and add the photo album for you.
Taken from their site:
How to Use:
Include lightbox.js in your header.
<script type="text/javascript" src="lightbox.js"></script>
Add rel="lightbox" attribute to any link tag to activate the lightbox. For example:
image #1
Optional: Use the title attribute if you want to show a caption.
update
http://lokeshdhakar.com/projects/lightbox2/ - Updated version
Replace:
$('.facebookfeed5').animate({opacity:0}, 500, function(){
$('.facebookfeed5').html(html);});
$('.facebookfeed5').animate({opacity:1}, 500);});};
With:
$('.facebookfeed5').animate({opacity:0}, 500, function(){
$('.facebookfeed5').html(html);});
$('.facebookfeed5').animate({opacity:1}, 500);})
$('img').attr('rel','lightbox')
;};