Hi I'm working on a custom text editor, on a linux 64 machine (if it can help).
Since the javascript "document.execCommand" has been deprecated, I'm working with "selection" and "range" and other javascript objects and functions.
I'm using an external div (as textarea) with the attribute contenteditable = true.
Everything seems fine until the text editor generate, inside the main editable div, tags like: span, ol, li ...
In Firefox (Chrome, and Opera work fine) the editor let the user write inside the tag until he press enter to go to a new line.
At this point if the user try to get back (to correct something for example) these tags are not editable anymore.
I tried to give to those tags the same attribute contenteditable = true, but no luck;
The only way I can get back and edit them is by clicking with the mouse right button.
Any idea on how I can keep all the tags "contenteditable" inside the main div?
The file I'm working on is thousands of lines long so I simplified the problem in the snipped below.
/**
the text editor object
*/
function TextEditor( args ){
this.editorId = args.editorId;
this.container = document.querySelector('#' + this.editorId );
var self = this;
this.setOrderList = function(){
document.execCommand('insertorderedlist');
}
this.initialize = function(){
if( self.textArea.innerHTML === '' ){
var div = document.createElement('div');
self.textArea.appendChild(div);
}
}
if ( this.container ) {
this.textArea = this.container.querySelector('.text-area');
this.orderedList = this.container.querySelector('#orederd-list');
this.orderedList.addEventListener('click', this.setOrderList);
this.textArea.addEventListener('focus', this.initialize);
}
}
var args = {
editorId : 'container'
}
var editor = new TextEditor( args );
<div id="container">
<div id="buttons-container">
<ul id="buttons">
<li id="orederd-list" class="button"><i class="fas fa-list-ol"></i></li>
</ul>
</div>
<div class="text-area" contenteditable="true">
</div>
</div>
I found What's the problem is.
In the main style sheet I have the following instruction:
a, li, span, h1, h2, h3, h4, h5, h6, p{
-webkit-touch-callout: none; /* iOS Safari */
-webkit-user-select: none; /* Safari */
-khtml-user-select: none; /* Konqueror HTML */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
user-select: none; /* Non-prefixed version, currently supported by Chrome and Opera */}
this instruction prevent users to select text from the website.
In Browsers like Chrome, Edge, Opera... this css instruction does not work inside "contenteditable" elements, while for some reason in Firefox it does.
For those interested, the I changed for the text editor main div the instruction:
-moz-user-select: none;
into:
-moz-user-select: text;
and now everything is fine.
Related
I'm getting started working with Electron to build a desktop app. How can I customize the window title bar (which contains the close, minimize, and full screen buttons) to add custom views? Safari is an example that I am thinking of:
Your only option in Electron would be to create a frameless (aka borderless) window, and then create a "fake" title bar with CSS, including any UI elements you need.
Electron/webkit provides CSS properties that allows you to make any element draggable, like a titlebar:
.titlebar {
-webkit-user-select: none;
-webkit-app-region: drag;
}
The first, and cross-platform option is to create a frameless window. The second is macOS only, and allows you to hide the title bar, but retain the window controls, allowing for the addition of custom buttons.
Example:
const { BrowserWindow } = require('electron')
// This will create a window without titlebar, allowing for customization
let win = new BrowserWindow({ titleBarStyle: 'hidden' })
win.show()
Then you could use the css properties -webkit-user-select and -webkit-app-region to specify the drag zone.
Hide the default titlebar by creating a frameless window:
// main.js
window = new BrowserWindow({
titlebarStyle: 'hidden',
trafficLightPosition: {
x: 15,
y: 13, // macOS traffic lights seem to be 14px in diameter. If you want them vertically centered, set this to `titlebar_height / 2 - 7`.
},
})
Then create your own makeshift titlebar using HTML + CSS:
<!-- index.html -->
<body>
<header class="titlebar"></header>
...
</body>
/* styles.css */
.titlebar {
background-color: #f0f0f0;
height: 40px;
border-bottom: 1px solid #d0d0d0;
-webkit-app-region: drag; /* Allow user to drag the window using this titlebar */
-webkit-user-select: none; /* Prevent user from selecting things */
user-select: none;
}
The result so far:
Notice that the titlebar appears under the scrollbar. It even moves when the user scrolls. We need to separate it from the scrollable content by wrapping everything below the titlebar in a <div class="main-content"> and then adding these styles:
.main-content {
height: calc(100vh - 40px); /* Force the content to take up the viewport height minus the titlebar height */
overflow: auto; /* Allow the main content to be scrollable */
}
body {
overflow: hidden; /* Make the HTML body be non-scrollable */
}
Final result:
Now you can add whatever HTML content you want up there.
Hope my Question is enough clear. I own a website.
http://khchan.byethost18.com
My problem is in the tab "Calendar", it run properly in chrome, ie. but not in fixfox.
my design is that when I hover the calendar tab. the page of calendar will show.
but in firefox, when I do that, it don't show properly. developer tool show $bookblock.bookblock is not a function. If I reload the frame, such error message will not show.
If I directly load "http://khchan.byethost18.com/cal.php
It can show properly and such error message don't appear.
so I guess may be something is not load properly. I already try add $(top.document,document).ready({function(){}); or replace the jquery library to the head or body. the problem still exist.
since the coding is very long. I only write the iframe tag.Please try to use developer tool to view my code.
I tried document.getElementById('CalF').contentWindow.location.reload();
if I already hover the calendar tab, the tab can be reload properly.
but if not, the developer tool display the same error message.
so, I think the major key to the problem is that the jquery tab affect something so that the tab "CalF" can't work properly.
.boxoff{
display: none;
}
<article class='boxoff'> //this article will be hidden until I delete the class.
<iframe id=CalF src="cal.php" style="top: 0;"></iframe>
</article>
Thanks.
iframeLoaded()
Update 2
OP explained that the iframe must be invisible initially. While this may seem an impossibility since iframes do not load when it or one of it's ancestor elements are display: none;. The key word is invisible which is a state in which the iframe is not visible.... There are three CSS properties that come to mind and one of them is actually shouldn't be used in this situation.
display: none; This is the property being used by OP and this property actually hinders the iframe's loading. The reason why is when in that state of invisibility, the iframe is not in the DOM according to Firefox's behavior.
opacity: 0; This property renders the iframe invisible as well and Firefox seems to recognize the invisible iframe just fine.
visibility: hidden; This seems to be an acceptable as well....
So try this code that I use to suppress the FOUC:
Child Page
function init(sec) {
var ms = parseFloat(sec * 1000);
setTimeout('initFadeIn()', ms);
}
function initFadeIn() {
$("body").css("visibility","visible");
$("body").fadeIn(500);
}
HTML
<body style="visibility: hidden;" onload="init(2);">
Update 1
I made an alternative solution because I hate leaving a demo that doesn't completely work★.
Ok this relies on cal.php window.onload event which is basically the slowest but the most stablest phase of loading there is.
Initially, #overlay will block any user interaction while calF is loading.
Once calF is completely loaded, it will call iframeLoaded function that's located on the parent page.
iframeLoaded will remove #overlay (I added a setTimeout for good measure but it's probably not necessary.)
I'm not that familiar with PHP syntax, so you'll have to modify the following code✶ and place it in cal.php
window.onload = function() {
parent.iframeLoaded();
}
Then on the parent page:
function iframeLoaded() {
setTimeout(function() {
$('#overlay').hide(750);
}, 1500);
}
The code above as well as the required HTML and CSS is in the snippet below.
★ Note: The code in the snippet should work, but this snippet won't of course because there's some code that needs to be on the child page. That's just a shoutout to all the downvoters out there ;-)
Snippet 1
// iframeLoaded will remove the overlay when cal.php has completely loaded
function iframeLoaded() {
setTimeout(function() {
$('#overlay').hide(750);
}, 1500); //<========[1 to 2 (1000 - 2000ms) seconds should give you plenty of time]
}
/*~~~~~~~~~~~~~~~~~~~~~~~~[Code in cal.php]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
// When everything (DOM, script, images. etc...) is loaded on cal.php, call iframeLoaded function that is on the parent's page.
window.onload = function() {
parent.iframeLoaded();
}
#overlay {
background: rgba(0, 0, 0, .3);
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
pointer-events: none;
}
#CalF {
position: absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="overlay"></div>
<iframe id="CalF" src="http://khchan.byethost18.com/cal.php" height="100%" width="100%" frameborder="0" style="top: 0;"></iframe>
✶ Function loadedIframe() inspired by SO5788723
Snippet 2
document.getElementById('CalF').onload = function(e) {
var over = document.getElementById('overlay');
over.classList.add('hide');
}
#overlay {
background: rgba(0, 0, 0, .3);
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
pointer-events: none;
}
.hide {
display: none;
}
#CalF {
position: absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="overlay"></div>
<iframe id="CalF" src="http://khchan.byethost18.com/cal.php" height="100%" width="100%" frameborder="0" style="top: 0;"></iframe>
$(document).ready seems to be called too soon, based on parent page instead of iframe content.
here you have solution to a similar problem:
jQuery .ready in a dynamically inserted iframe
I have written some javascript under a text item html and it is working perfectly when in eclipse birt designer. When I deploy the report to Birt viewer in apache, it does not seem to work. I am not sure if the click is not working or the javascript behind it is not working but something is wrong the I am not getting the desired result on clicking the text item
Basically, I am hiding few charts when I click on the text item (I wrote an html script to make it a button and then called a javascript function to hide a chart). It is working in birt designer but not working in birt viewer on apache
below is the button html script
<button type="button"
style="width: 120px; height: 30px; color: #5a698b; font: bold 12px Arial;
padding-top: 1px; padding-bottom: 1px; background: #ddddff; text-align: center;"
onclick=" showhidetab(1,'Population','2.5in')";">Overview
</button>
here is the javascript function that the button is calling
<script>
function showhidetab(showflag,bookmark, heightval)
{
if (showflag == 1)
{
document.getElementById(bookmark).style.visibility="visible";
document.getElementById(bookmark).style.display = "block"
document.getElementById(bookmark).style.height= heightval;
}
else
{
document.getElementById(bookmark).style.visibility="hidden";
document.getElementById(bookmark).setAttribute("style","display:inline;height:1px");
document.getElementById(bookmark).style.height='1px';
}
}
</script>
Can someone please suggest what could be wrong here
Regards
Syed
Some quick fixes:
Your line document.getElementById(bookmark).style.display = "block" is missing a semicolon.
I think the id should be js3_Population... check in your browser.
The brackets closing the else statement is missing a semicolon.
When I made those changes it worked for me. Your code is only resizing the item and not hiding it since the state of the bookmarked object is already visible. You might consider using style.display="none" to avoid holding space for hidden items.
I'm having trouble with CK4 and getting the styles for headers reflected in the styles-dropdown.
The .css should be shared of both back- and frontend and uses #page as css-id
Is there any way to tell the dropdown to parse headers with the #page-prefix.
I'm using
CKEDITOR.config.bodyId = 'page';
and css
.cke_editable {
}
#page {
/* works - editor area goes black..
font-family:Arial;
margin:10px;
font-family:Arial;
background-color:#000;
font-size: 10px;
color:#fff;
}
#page h1 {
/* works in editor-area, but not dropdown */
font-family: Verdana;
color:#999;
}
.cke_editable h2 {
/* same as h1.. */
font-family:Arial;
color:#f00;
font-size:16px;
background-color:#999;
}
h3 {
/* work BOTH in editor and style shows in dropdown. */
color:#0f0;
}
I guess that you're about to use stylesheetparser plugin to parse additional selectors. This issue has already been answered here: CKEditor - Stylesheet Parser - Valid Selectors
It's not straightforward but I believe you'll manage to do this. Good luck!
The problem is that CKEditor doesn't apply the bodyId and/or bodyClass to the styles combo: http://dev.ckeditor.com/ticket/7452
As you can see that bug was reported almost two years ago and it has been without activity from the developers most of that time.
I achived a working solution by parsing the css e.g.
#page h1 {...}
when attaching to CK like:
['config']['css'] = 'parseMyCss.php?theFile=style.css
and in parseMyCss (simplified):
$s = file_get_contents($theFile);
$s = str_replace('#page ','', $s);
header('content-type:text/css');
echo $s;
Hey frenz In my mvc 3 project i need a pop up box. Actually when the user click the edit button, I need to show the Edit View page as pop up box and save the edited data in database.
Simply, I need to replace the edit view page with edit pop up box.
I know that i need to use ajax and jquery. But confuse how to implement it.
So, Any idea about this will be greatly appreciated
I have also faced such type of situation and I preferred some style sheet instead of using any 3rd party control. I am writing sample code here.
<!DOCTYPE html PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”>
<html>
<head>
<title>LIGHTBOX EXAMPLE</title>
<style>
.black_overlay{
display: none;
position: absolute;
top: 0%;
left: 0%;
width: 100%;
height: 100%;
background-color: black;
z-index:1001;
-moz-opacity: 0.8;
opacity:.80;
filter: alpha(opacity=80);
}
.white_content {
display: none;
position: absolute;
top: 25%;
left: 25%;
width: 50%;
height: 50%;
padding: 16px;
border: 16px solid orange;
background-color: white;
z-index:1002;
overflow: auto;
}
</style>
</head>
<body>
<p>This is the main content. To display a lightbox click <a href = “javascript:void(0)” onclick = “document.getElementById(‘light’).style.display=’block’;document.getElementById(‘fade’).style.display=’block’”>here</a></p>
<div id=”light” class=”white_content”>This is the lightbox content. <a href = “javascript:void(0)” onclick = “document.getElementById(‘light’).style.display=’none’;document.getElementById(‘fade’).style.display=’none’”>Close</a></div>
<div id=”fade” class=”black_overlay”></div>
</body>
</html>
Onclick event you need to display user control in that div. I have used json object for that. Javascript code is like this.
function ShowPopups(cntrlId, controllerName, actionName, className, id) {
var url = controllerName + "/" + cntrlId;
elementId = id;
$.ajax(
{
type: "POST",
url: "/" + controllerName + "/" + actionName,
data: "Display=" + cntrlId,
dataType: "html",
success: function (result) {
removeClass('light1');
changeClass('light1', className);
document.getElementById('light1').style.display = 'block';
document.getElementById('fade1').style.display = 'block'
$("#light1").html(result);
}
});
}
function HidePopup() {
var url = document.location.hash;
document.getElementById('fade1').style.display = 'none';
document.getElementById('light1').style.display = 'none';
document.location.hash = url;
}
// To Add and Remove class using javascript
function removeClass(elementID) {
var element = document.getElementById(elementID);
element.className = '';
}
function changeClass(elementID, newClass) {
var element = document.getElementById(elementID);
element.className += newClass;
}
you can use JQuery model dialog box(use model form) it is really simple, Here is the documentation with examples. http://jqueryui.com/demos/dialog/#modal-form
I also recommend Jquery UI model dialog still you want to try out something else here is the list of Jquery Model PopUp Samples
So many of the other tutorials don't cover how to actually edit data, only how to show the dialog. When you try to post your form, the entire window will post and change.
jQuery ui's dialog method has some funny behavior at times, and validation won't work by default unless you parse newly loaded content.
With that said, the best overall code I've found recently is this solution here to handle the ajax loading and posting.
http://nickstips.wordpress.com/2011/08/11/asp-net-mvc-ajax-dialog-form-using-jquery-ui/