Inserting CSS for an Element from a input field - javascript

Is there any easy way to take in a block of CSS from the user from an textarea and add this styling to the styling for a specific div?
See I'm creating a simple code preview tool like codePen, so far I have two textarea inputs, one for Html and one for CSS, as the user types in the Html input this updates the preview pane, this works, now I want to do it for CSS.
CSS textarea could contain a few blocks like:
h1 {
font-size:23px;
}
.myClass {
//Somestyle
}
Now I want this CSS to be contained in the
<div id="preview"></div>
So it doesnt effect the rest of the page, so a manual example would be
$('preview h1').css('font-size','23px');
Anyway to automate this?

Do it like this. Hope it works.
Add a style block for dynamic styling.
<style id="dynamicCss">
</style>
on the apply button click handler, set the style
$('#btnApplyStyle').click(function(){
$('#dynamicCss').html('').html($('#txtaCustomCss').val());
});
See the Fiddle here.
Please use developer tools to see the new style tag added to head section.
This script simply adds rule to the document. If you don't want that behavior, you can use this plugin in combination with my logic to set scope for rule. You will need to place the style tag inside of the container and add a scoped attribute to style for it to work. Please see the documentation.

If you want to use the iframe approach instead, you'll first need an HTML document to host inside of the iframe. The iframe document should be loaded for the same origin (protocol + domain) as the host document (cross-document cross-domain stuff is tricky otherwise). With your application, this is probably not an issue.
Host page:
<iframe id="preview" src="preview.html"></iframe>
To make things easier on yourself, this iframe document could load a script with convenience functions for injecting the HTML and CSS from the host.
preview.html:
<html>
<head>
<script src="preview.js"></script>
<style type="text/css" id="page-css"></style>
</head>
<body></body>
</html>
preview.js:
function setHTML(html) {
document.querySelector('body').innerHTML = html;
}
function setCSS(css) {
var stylesheet = document.querySelector('#page-css');
// Empty the stylesheet
while (stylesheet.firstChild) {
stylesheet.removeChild(stylesheet.firstChild);
}
// Inject new CSS
stylesheet.appendChild(document.createTextNode(css));
}
Now, from the host page, you can call these functions whenever your text inputs change:
document.querySelector('#preview').contentWindow.setCSS(someCSS);

This plugin may come in handy: https://github.com/websanova/wJSNova/downloads .

Edited
Insert the text of the rules in one of the existing cssStyleSheets you have.
It will be something like
window.document.styleSheets[0].insertRule("a{color:red;}",window.document.styleSheets[0].cssRules.length)
The first parameter is the rule to insert and the second is the index.
Fiddle
The only problem here is that this will affect all the DOM on the page maybe looking for a way to add the #preview before each css rule to get something like
#preview h1{}

Related

Customizing external embed widget

I've been trying to customize an embedded widget from Zendesk on my website. Since they don't give any option to customize the look of its form, I would like to enforce my css rules.
I added this piece of code from Zendesk to have their form on my page.
<script type="text/javascript" src="https://leads-capturer.futuresimple.com/embed.js?token=ca98908sdgfgds9834234jlkjsdb">
This script places a form within an <iframe> and all nodes inside this <iframe> cannot be customized/changed.
I tried JS to set an inline style to form elements inside the <iframe>. Tried create a new stylesheet to override their original stylesheet but nothing seems to work.
Even something as simple as this code below, fails (#iframe-main-container is a child from <iframe>):
<script>
let p = document.querySelector('#iframe-main-container');
p.style.background = 'red';
</script>
If I change the code above and target <iframe>, it works.
My first question would be, is it possible to override an existing CSS rule from an embedded widget?
If this is possible, am I doing something wrong to change its looks?
Give this a try.
<script>
let iframe = document.getElementsByTagName("iframe");
let p = iframe[0].contentWindow.document.getElementById('#iframe-main-container');
p.style.background = 'red';
</script>

Can I create an HTML pop up that do not use Javascript? or can I put the Javascript into the <body> section?

I have to create a pop up that will be show when the user click on a link.
I think that I can not use Javascript because I have no access to the full template so I can't put the javascript into the <head></head> section of the page (I can't modify it)
Can I create a pure HTML pop up withous use Javascript or alternatively can I declare my Javascript into the <body></body> of my html code and not into the <head></head> section?
Tnx
Andrea
Yes, you can do this in pure html and css. The trick is to use the :target pseudo selector. Rules with :target will match when the url anchor matches a particular id. You can update the url anchor by creating a plain anchor link. This does have a slight jumping effect because we're using anchors, but it is possible.
So for example: http://jsfiddle.net/X49zJ/1/
Click to Trigger The Modal
<div id="modal"> I am a Hidden Modal</div>
And CSS:
#modal {
display: none;
width: 300px;
height: 100px;
border:1px solid #CCC;
background:#EEE;
}
#modal:target {
display: block;
}
See https://developer.mozilla.org/en-US/docs/Web/CSS/:target for more information on the :target and also this demo for a much prettier lightbox.
For more flexibility you can always add javascript. If your javascript is non-essential, it's generally best practice to put javascript at the bottom of the body, or add the script tag with the async attribute so it doesn't pause rendering of content when it loads.
You can do this with HTML and CSS, like so.
To answer your second question, generally it's possible to put Javascript in the <body> section of your page as well.
You cannot do this without javascript, however you can put script tags literally anywhere in your page and it should work, so try this.
<div>
<h1 id="test">New Content</h1>
<script>
var test = document.getElementById('test');
test.addEventListener('click', function() {
alert('clicked');
});
</script>
</div>
It's permittable to use target="_blank" in the <a> tag if you're using HTML5, which will generally make the link open in a new tab in modern browsers. This is preferred by quite a lot of users so you may want to consider this.
Putting JavaScript into the body of the page should be perfectly fine if you have complete control over the HTML. It is put within simple <script> tags, after all — there's no need for it to be in the <head>.
If whatever CMS you're using filters out <script> tags but you still have control over HTML attributes, you might be able to get away with putting JavaScript in an onclick attribute:
Link
Here you can find a walk-through http://dsheiko.com/weblog/fancy-modal-windows-without-javascript/
It opens pop-up and blurs the modal underlay. Here how it looks codepen.io/dsheiko/pen/jCcld
It also describes how you can enhance it with such goodies as closing on Esc press and by clicking outside modal content and provides JavaScript fallback for IE8.

constrain image width in javascript link

How to constrain image width in javascript link? (As you would easily do in HTML.) The following code is not working. The image sources at 250px, so can't a width attribute be put in the script tag to constrain it to 191px? Thank you.
(I am using single quote marks here because the whole script tag code is contained within double quotes.)
<script type='text/javascript' language='javascript' src='http://www.dpbolvw.net/29102g73tvx-63wx9IOQJRNJM?target=_blank&mouseover=Y' width='191'></script>
The script you're including is programmatically adding an <img> to your document:
document.write("<a href=\"javascript:submitCJ10909759X391\
(\'CJ10909759X391\',null);\"><img src=\"http://www.yceml.net\
/0063/10909759-1.jpg\" width=\"250\" height=\"250\"\
alt=\"Travel related banner\" border=\"0\"/></a>");
You can modify the width of the image in one of two ways:
Modify the script that you're loading, or, if that's not possible;
Run your own script afterwards and use it to locate the <img> that was appended.
Unfortunately, the script doesn't give the <img> an id whereby you could easily find it in the DOM. If this is the way you want to go, I leave it up to you to find an alternative to locate the <img> in your DOM tree.
Per the conversation we had, it looks like this JS is loading an image.
The only way to set a width attribute on this image would be for the script to support that feature, where you could perhaps pass it in as a querystring. Alas, it looks like this script does not do that.
My suggestion is to wrap the script tag (which renders an IMG tag) and then use CSS to handle the width:
<div id="myImage"><script.../></div>
#myImage img {width: 191px;}

Create new (not change) stylesheets using jQuery

We've got a little tool that I built where you can edit a jQuery template in one field and JSON data in another and then hit a button to see the results immediately within the browser.
I really need to expand this though so the designer can edit a full CSS stylesheet within another field and when we render the template, it will have the CSS applied to it. The idea being that once we've got good results we can take the contents of these three fields, put them in files and use them in our project.
I found the jQuery.cssRule plugin but it looks like it's basically abandoned (all the links go nowhere and there's been no development in three years). Is there something better or is it the only game in town?
Note: We're looking for something where someone types traditional CSS stylesheet data in here and that is used immediately for rendering within the page and that can be edited and changed at will with the old rules going away and new ones used in their stead. I'm not looking for something where the designer has to learn jQuery syntax and enter in individual .css("attribute", "value") type calls to jQuery.
Sure, just append a style tag to the head:
$("head").append("<style>p { color: blue; }</style>");
See it in action here.
You can replace the text in a dynamically added style tag using something like this:
$("head").append("<style id='dynamicStylesheet'></style>");
$("#dynamicStylesheet").text(newStyleTextGoesHere);
See this in action here.
The cleanest way to achieve this is by sandboxing your user-generated content into an <iframe>. This way, changes to the CSS won't affect the editor. (For example, input { display:none; } can't break your page.)
Just render out your HTML (including the CSS in the document's <head>, and write it into the <iframe>.
Example:
<iframe id="preview" src="about:blank">
var i = $('#preview')[0];
var doc = i.contentWindow || i.contentDocument;
if (doc.document) doc = doc.document;
doc.open('text/html',true);
doc.write('<!DOCTYPE html><html>...</html>');
doc.close();
If the user should be able to edit a whole stylesheet, not only single style attributes, then you can store the entered stylesheet in a temporary file and load it into your html document using
$('head').append('<link rel="stylesheet" href="temp.css" type="text/css" />');
sounds like you want to write an interpreter for the css? if it is entered by hand in text, then using it later would be as simple as copy and pasting it into a css file.
so if you have a textarea on your page to type in css and want to apply those rules when you press the button, you could use something like this (only pseudocode, needs work):
//for each css id in the text area
$.each($('textarea[name=cssTextArea]').html().split('#'), function({
//now get each property
$.each($(this).split(';'), function(){
$(elem).css({property:value});
});
});
then you could write something to go through each element that your designer typed in, and get the current css rules for it (including those that you applied using some code like the snippet above) and create a css string from that which could then be output or saved in a db. It's a pain and much faffing around with substrings but unfortunately I don't know of a faster or more efficient way.
Hope this atleast gives you some ideas

BODY tag disappear when using Jquery.Load()

Im trying to make a pop-up like window using jquery and its modal box. First I load the content from a html file:
$("#test").load("test.htm");
Then I load the popup:
$("#test").dialog("open");
This works like it should, the content of test.html is injectet into the modal pop-up. There is only one think that is wrong, and that is the BODY tags are gone from the source of the pop-up. I need the BODY tag to be there because I do some formatting based on the BODY tag.
Does anyone know why jQuery.Load() removes the BODY tag? And are there any workarounds?
A page can only have one body tag. If you already have one on the page, the second will be ignored.
In your case, it sounds like the browser is ignoring the duplicate body (nothing specific to jquery). Rather than use the body for styling, use a containing <div> with an id or class which will be retained.
It probably removes the body tag because it's not allowed! Each document can only have one body. Rather than force everyone to redo all their HTML pages, jQuery probably just grabs the contents of the body to use when you call load().
Have you thought about perhaps wrapping everything in a containing element? eg: <div class="body"> You can then apply the exact same styles to that element.
/* change this: */
body { color: #f0f; etc }
/* to this: */
body, div.body { color: #f0f; }
You are loading the HTML into an existing document that already has a body tag. A document can only have one so it automatically filters anything and extracts only the HTML inside the body tag when using load. You should wrap your HTML in a div with a specific class and do your formatting based on that class.
From the load docs (emphasis mine):
In jQuery 1.2 you can now specify a
jQuery selector in the URL. Doing so
will filter the incoming HTML
document, only injecting the elements
that match the selector. The syntax
looks something like "url #some >
selector". Default selector "body>*"
always applies. If the URL contains a
space it should be escape()d. See the
examples for more information.
You might dynamically create the body tag using document.write of js as an alternative.
I had the same issue, and solved it more or less as the following:
instead of using load(), you can use get(), and do some smart string replacement:
var content = get("test.htm")
.replace("<body>", "<body><div class='body'>")
.replace("</body>", "</body>");
$("#test").replace($(content).filter(".body"));

Categories