I've been playing with making an html editor with javascript functions:
So I have a very basic editor with a "bold" button which with I can make whatever text is selected bold, this is fine (I also have a number of other buttons too, but for simplicity and shortness of code I've missed them all out)
<head>
<script>
var editorDoc;
function InitEditable () {
var editor = document.getElementById ("editor");
editorDoc = editor.contentWindow.document;
var editorBody = editorDoc.body;
if ('contentEditable' in editorBody) {
editorBody.contentEditable = true;
}
else {
if ('designMode' in editorDoc) {
editorDoc.designMode = "on";
}
}
}
function ToggleBold () {
editorDoc.execCommand ('bold', false, null);
}
</script>
</head>
<body onload="InitEditable ();">
<button type="button" onclick="ToggleBold ();">Bold</button>
<iframe contenteditable="true" id="editor"></iframe>
</body>
However, something I was really interested in being able to implement would be adding a button which could insert, say, an accordion when pressed
This would then have to add other bits of script (I imagine) to be able to run each accordion (if you had more than one)
Although I haven't had much of a go at doing this myself yet, I was hoping to get a little insight into whether or not it's possible before starting
Related
Is there a built in way of keeping a button active when it execute a execCommand on a content editable div ?
example :
<input type="button" onclick="doRichEditCommand('bold');" value="B"/>
function doRichEditCommand(command){
document.execCommand(command, null, false);
}
I'd like my button to remain active when the carret is within something where document.execCommand(command, null, false); has been applied. I suppose it's doable by checking the parent elements but if there is a built in way it would be better.
In other words I'd like my bold button to be orange when the carret is somewhere which should be bold.
It's doable, but it's really annoying.
Every time the contenteditable changes you call document.queryCommandState() to find the state of the text where the caret is, and then update the button class to match. So something like:
let div = document.getElementById("myContentEditable");
div.oninput = () => {
if (document.queryCommandState('bold')) {
console.log("bold!");
} else {
console.log("not bold.");
}
return false;
};
From there you can apply or remove a style from your bold button to indicate whether the cursor's in a bold section or not. Repeat for the other styles.
The annoying part is that you need to update the button state on several different events. This seems fairly exhaustive to me:
div.oninput = div.onselect = div.onchange = div.onkeyup = eventhandler;
...but I could be wrong.
<head>
<script type="text/javascript">
var editorDoc;
function InitEditable () {
var editor = document.getElementById ("editor");
editorDoc = editor.contentWindow.document;
var editorBody = editorDoc.body;
// turn off spellcheck
if ('spellcheck' in editorBody) { // Firefox
editorBody.spellcheck = false;
}
if ('contentEditable' in editorBody) {
// allow contentEditable
editorBody.contentEditable = true;
}
else { // Firefox earlier than version 3
if ('designMode' in editorDoc) {
// turn on designMode
editorDoc.designMode = "on";
}
}
}
function ToggleBold () {
editorDoc.execCommand ('bold', false, null);
}
</script>
</head>
<body onload="InitEditable ();">
First, write and select some text in the editor.
<br />
<iframe id="editor" src="editable.htm"></iframe>
<br /><br />
You can toggle the bold/normal state of the selected text with this button:
<br />
<button onclick="ToggleBold ();">Bold</button>
</body>
editable.html:
<!DOCTYPE html>
<html>
<head>
<title>Editable content example</title>
<meta charset="utf-8" />
</head>
<body>
Some text in the editor.
</body>
</html>
some possible solution here: execCommand method examples
This is what I achieved:
JS
function format(command) {
document.execCommand(command, false);
const button = document.getElementById(command);
button.classList.toggle("button--active");
}
HTML
<button id="bold" onclick="format(this.id)">Bold</button>
SCSS
button {
//Whatever you want
&--active {
//Whatever you want
}
}
However, it works for general writing. If you select text and apply an effect, the button will be kept active.
I'm trying to figure out how to pull attributes from CSS to be used in Javascript. I've googled what I'm looking for so many times and in so many ways my fingers are about to fall off.
I'm looking to change font size to three different font sizes: 15px, 28px, and 40px. This would be toggled using three buttons. However, when you choose a font size, some of the other CSS attributes need to change in order to resize the text and padding to align with the element "behind" it, so that it doesn't push off the side and look ugly. I'm planning on doing the resizing automatically with Javascript, but for the life of me I can't figure out how to pull the "text size in pixels" attribute from the page in order to apply an "if/else" argument. This would need to be done in browser and I've found a .getComputedStyle command. But as I can't get it to work I'm not sure if that's what I need or not.
<body>
<p id="spaz">Text to be resized.</p>
<button type="button" onclick="txtszl()">large</button>
<button type="button" onclick="txtszm()">medium</button>
<script>
function txtszl(){
document.getElementById("spaz").style.fontSize="40px";
}
function txtszm(){
document.getElementById("spaz").style.fontSize="28px";
}
var $txtelement = document.getElementById("spaz");
var $txtsize = $txtelement.getComputedStyle("fontSize");
if ($txtsize == 40px){
alert("It's forty!");
}else{
alert("Nope!");
}
</script>
</body>
That's what I have come up with. Any help/links would be greatly appreciated!
The getComputedStyle function returns a CSSStyleDeclaration.
var txtElementStyles = getComputedStyle($txtelement, null),
fontSize = txtElementStyles.getPropertyValue('font-size');
Working fiddle: http://jsfiddle.net/wrathchild77/6LJaM/
function txtszl() {
document.getElementById("spaz").style.fontSize = "40px";
check();
}
function txtszm() {
document.getElementById("spaz").style.fontSize = "28px";
check();
}
function check() {
var $txtsize = document.getElementById("spaz").style.fontSize;
if ($txtsize == "40px") {
alert("It's forty!");
} else {
alert("Nope!");
}
}
I've been working on an ASP.NET page containing a ListView. When the user clicks a row, the content of the last (visible) column of this (once parsed) HTML table is replaced with a textbox (by means of jQuery), making the value editable.
So far, this works like a charm in Chrome but no joy in IE10.
In this jsfiddle, the value becomes editable but then the Save button doesn't work as expected.
In IE the textbox doesn't appear. Funny detail: if I comment out the four vars (invNr, newInvNr, oldHtml and spanWidth), the input element DOES appear in IE10 but of course I have no data to work with. Really REALLY weird.
The jQuery:
$(document).ready(function () {
$('tr[id*="itemRow"]').click(function () {
$clickedRow = $(this);
//this makes sure the input field isn't emptied when clicked again
if ($clickedRow.find('input[id$="editInvNr"]').length > 0) {
return;
}
var invNr = $clickedRow.find('span[id$="InvoiceNumber"]').text(),
newInvNr = '',
oldHtml = $clickedRow.find('span[id$="InvoiceNumber"]').html(),
spanWidth = $clickedRow.find('span[id$="InvoiceNumber"]').width();
$clickedRow.find('span[id$="InvoiceNumber"]').parent('td').html('<input type="text" ID="editInvNr"></input>');
$clickedRow.find('input[id="editInvNr"]').val(invNr).focus().on('input propertychange', function () {
$clickedRow.find('span[id$="SaveResultMsg"]').hide();
$clickedRow.find('td[id$="SaveOption"]').show();
$clickedRow.find('input[id*="btnSaveInvNrFormat"]').show();
newInvNr = $(this).val();
if (newInvNr == $clickedRow.find('span[id$="InvoiceNumber"]').text()) {
$clickedRow.find('td[id$="SaveOption"]').hide();
}
});
});
$('tr[id*="itemRow"]').focusout(function () {
$rowLosingFocus = $(this);
var previousValue = $rowLosingFocus.find('input[id$="editInvNr"]').val();
$rowLosingFocus.find('input[id$="editInvNr"]').closest('td').html('<asp:Label ID="lblInvoiceNumber" runat="server" />');
$rowLosingFocus.find('span[id$="InvoiceNumber"]').text(previousValue);
});
});
function UpdateInvoiceNrFormat(leButton) {
$buttonClicked = $(leButton);
$buttonClicked.focus();
var companyName = $buttonClicked.closest('tr').find('span[id$="lblCompanyName"]').text(),
invoiceType = $buttonClicked.closest('tr').find('span[id$="lblInvoiceType"]').text(),
invNrFormat = $buttonClicked.closest('tr').find('span[id$="lblInvoiceNumber"]').text();
PageMethods.UpdateInvoiceNumberFormat(companyName, invoiceType, invNrFormat, onSuccess, onError);
function onSuccess(result) {
$buttonClicked.hide();
$buttonClicked.siblings('span[id$="SaveResultMsg"]').text(result).show();
}
function onError(result) {
$buttonClicked.hide();
$buttonClicked.siblings('span[id$="SaveResultMsg"]').text('Error:' + result).show();
}
}
I've tried various combinations of jQuery statements, chaining and avoiding chaining, placing it at the bottom of the page as someone suggested, commenting out various parts of the code out of sheer desperation. Still nada.
There was no way to make the html() method replace the html correctly in IE10, although I never did find out exactly why. I ended up writing both elements into the table cell, set style="display:none" for one of them and use show() / hide() and that's good enough for me (and apparently for IE10 as well).
For anyone encountering the same issue: this is a workaround, not a solution in the strictest sense.
How can I simulate user-selection of some style from the styles-box, through JS? I want to put some shortcut buttons that assign some of the popular styles with one click.
EDIT:
I don't care if it'll be in-editor button or outer button.
I don't want css-style assignment; I want CKEditor-style assignment (those of the styles-box).
I haven't used CKEditor, but, I saw your question and thought "That would be fun to figure out." Well, here is what I figured out:
(yes, I found terrible documentation, but, that's not the point...I will give them props for commenting their code, though.)
///
// function to add buttons that trigger styles to be applied.
//
// editor - CKEDITOR - instance of editor you want command attached to.
// buttonName - String - name of the button
// buttonLabel - String - humane readable name of the button
// commandName - String - name of command, the way to call this command from CKEDITOR.execCommand()
// styleDefinition - StyleDefinition - obj defining the style you would like to apply when this command is called.
///
var addButtonCommand = function( editor, buttonName, buttonLabel, commandName, styleDefiniton )
{
var style = new CKEDITOR.style( styleDefiniton );
editor.attachStyleStateChange( style, function( state )
{
!editor.readOnly && editor.getCommand( commandName ).setState( state );
});
editor.addCommand( commandName, new CKEDITOR.styleCommand( style ) );
editor.ui.addButton( buttonName,
{
label : buttonLabel,
command : commandName
//adding an icon here should display the button on the toolbar.
//icon : "path to img",
});
};
//Get the editor instance you want to use. Normally the same as the ID of the textarea CKEditor binds to.
var editor1 = CKEDITOR.instances.editor1;
//If you look at ckeditor/_source/plugins/styles/default.js you will see that this selects the first element. That list is read into the array 'default'.
var blueTitleStyle = CKEDITOR.stylesSet.registered.default[0];
//Or, you can define the style like this: See http://dev.ckeditor.com/wiki/Components/Styles for more info on style definitions.
var blueTitleStyle = {
name : 'Blue Title',
element : 'h3',
styles : { 'color' : 'Blue' }
};
addButtonCommand(editor1, 'BlueTitle', 'BlueTitle', 'bluetitle', blueTitleStyle);
Here is a Javascript function to aid your click events:
//function used to execute the command. Only used for calling the command when not calling from a button. (Like an A with an onClick bound to it.)
//pulled this function right out of the api.html example in the ckeditor/_samples dir.
function ExecuteCommand( commandName )
{
// Get the editor instance that we want to interact with.
var oEditor = CKEDITOR.instances.editor1;
// Check the active editing mode.
if ( oEditor.mode == 'wysiwyg' )
{
// Execute the command.
// http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.editor.html#execCommand
oEditor.execCommand( commandName );
}
else
{
alert( 'You must be in WYSIWYG mode!' );
}
}
Now, you can create a link like this:
<a href='#' class='setBlueTitle'>Set Blue Title</a>
and use a bit of jQuery to spice it up:
<script type="text/javascript">
$(document).ready(function(){
$(".setBlueTitle").onClick(function(e){
//stops the click from changing the page and whatever other default action would happen.
e.preventDefault();
ExecuteCommand('bluetitle');
});
});
</script>
I am not 100% sure about the button icon part. I didn't have an icon to try it with. But, according to a few posts, it should work fine. Regardless, the jQuery click binding works.
That should be pretty much it! I had to do quite a bit of digging around to figure this out, but it certainly is satisfying to see it work!
Here's one option
First, you can setup the desired styles you want to try out in a CSS class. Then, you can set the className for the test div when you click that button. Here's a simple example:
test.css:
.bold {
font-weight: bold;
}
.italic {
font-style: italic;
}
test.html
<html>
<head>
<link rel="stylesheet" type="text/css" href="test.css" />
</head>
<body>
<input type="button" onclick="document.getElementById('testStyleDiv').className='bold'" value="bold"/>
<input type="button" onclick="document.getElementById('testStyleDiv').className='italic'" value="italic"/>
<div id="testStyleDiv">foo</div>
</body>
</html>
I know blinking is not a nice thing. However...
I have a long complex HTML form with a number of compulsory fields. As well as highlighting the empty text boxes I want to draw attention to them by flashing the text of the question for maybe three seconds.
All the javascript/css methods I can find all seem to fall over when there is more than one such item to blink or are designed for leaving the item blinking all the time.
Any suggestions for how to achieve this?
The method at What is the replacement for a blinking text in a web page? seems like overkill.
thanks
Derek
I've tried this (to blink each designated span just over three seconds) but it only works on the first item it's called for:
function blinkOn(span){
span.counter=0;
span.defColor=span.style.color;
span.alertTimerId =setInterval("blinkOnce('"+span.id+"')", 400 );
}
function blinkOnce(spanID){
var span=document.getElementById(spanID)
span.counter++;
if(span.style.color==span.defColor){
span.style.color='transparent'}
else{
span.style.color=span.defColor;
}
if(span.counter>8){
blinkOff(span);
}
}
function blinkOff(span){
clearInterval(span.alertTimerId);
span.style.color=span.defColor;
}
I use jQuery for this kind of thing, personally:
$('#element_id')
.fadeOut(300)
.fadeIn(300)
.fadeOut(300)
.fadeIn(300)
.fadeOut(300)
.fadeIn(300)
.fadeOut(300)
.fadeIn(300)
.fadeOut(300)
.fadeIn(300);
Quite inelegant I know but it does the job. jQuery UI does have some more concise effects.
The only place I use it is for when a user adds something to a shopping basket without redirecting to the basket page, just to make sure they know that it's been added.
See:
http://api.jquery.com/fadeIn/, http://api.jquery.com/fadeOut/ and http://jqueryui.com/docs/show/ (pulsate, in particular)
I'm not exactly clear about the behavior you desire, but it sounds like you might be able to flash the question (or take some kind of action) using a Javascript timer. You can create unique timers for each element that you want to flash. And you can flash them once or set them up to repeat infinitely or up to a limit. Here's one example:
http://www.elated.com/articles/javascript-timers-with-settimeout-and-setinterval/
I took some time to work this out this morning. If you haven't gotten yours to work yet, I hope you can adapt this to help.
<html>
<head>
<script type="text/javascript">
var idArray = [];
var defaultColor = '#000000';
function makeItemsBlink(blinkTime) {
blinkForTime('q1', blinkTime, '#ff0000');
blinkForTime('q2', blinkTime, '#00ff00');
blinkForTime('q3', blinkTime, '#0000ff');
}
function blinkForTime(id, blinkTime, blinkColor) {
idArray[id] = setInterval('toggleColor("' + id + '", "' + blinkColor + '")', 400);
setTimeout('stopBlinking("' + id + '")', blinkTime);
}
function stopBlinking(id) {
clearInterval(idArray[id]);
document.getElementById(id).style.color = defaultColor;
}
function toggleColor(id, blinkColor) {
var e = document.getElementById(id);
var currentColor = e.style.color;
if (currentColor == defaultColor) {
e.style.color = blinkColor;
}
else {
e.style.color = defaultColor;
}
}
</script>
</head>
<body onload="makeItemsBlink(3000);">
<div id="q1">Test question 1</div>
<div id="q2">Test question 2</div>
<div id="q3">Test question 3</div>
</body>
</html>