Invalid characters in HTML preventing my menu from toggling? - javascript

I'm creating a button that makes a table and a drop down menu. But the drop down menu doesn't work when it's clicked, like it should.
I keep receiving this error: 'Uncaught InvalidCharacterError: Failed to execute 'toggle' on 'DOMTokenList': The token provided ('[object HTMLCollection]') contains HTML space characters, which are not valid in tokens.' This error occurs near the last line here where I use toggle.
I've checked the HTML generated with JS and it seems fine. I just can't figure out what exactly this error is referring to. I've gone through the code at least a half dozen times and don't see any spaces within the html. This makes me question whether this is where the problem actually is. If anyone has a solution or insight into how to correct this, that would be much appreciated.
Here is the code:
//**HTML**
<div class = 'insertsGrid buttonStyle'>Grid</div>
//**CSS**
.buttonStyle{
width: 12vh;
height: 12vh;
border: 1px solid;
position: fixed;
display:flex;
justify-content:center;
align-items: center;
font-weight: 900;
font-size: 4vh;
color: #b8860b;
cursor:pointer;
background-color:white;
user-select: none;
}
th, td, tr {
border: 1px solid black;
}
//**Javascript**
const insertsGrid = document.getElementsByClassName('insertsGrid');
insertsGrid[0].addEventListener('mousedown', createGrid);
let z =0;
function createGrid (){
z++;
document.execCommand('insertHTML', true,/*this is the bar */'<div class=bar'+z.toString()+'></div>'+/*this is the menu options that show when bar is clicked */ '<div class =dropDownContent'+z.toString()+'><div class =dropDownContentX'+z.toString()+'><p>Add Row</p><p class=addColumn'+z.toString()+'>Add Column</p></div></div>'+/*this is the table */ '<table><tr><td>Head1</td><td>Head2</td></tr><tr><td></td><td></td></tr></table><br>');
let bar = document.getElementsByClassName('bar'+z.toString());
let dropDownContent = document.getElementsByClassName('dropDownContent'+z.toString());
let dropDownContentX = document.getElementsByClassName('dropDownContentX'+z.toString());
let addColumn = document.getElementsByClassName('addColumn'+z.toString());
//dom css for the html created in the dom
bar[0].style.width = '10%';
bar[0].style.height = '1%';
bar[0].style.border = '1px solid black';
bar[0].style.cursor = 'pointer';
bar[0].style.marginBottom = '50px';
dropDownContent[0].style.display = 'none';
dropDownContentX[0].style.display = 'inline';
dropDownContentX[0].style.backgroundColor = 'white';
dropDownContentX[0].style.width = '100%';
dropDownContentX[0].style.fontSize = '80%';
//action executed when the nav button is pressed
bar[0].addEventListener('mousedown' , tog);
function tog (){
dropDownContent[0].classList.toggle('dropDownContentX');
}

You are passing dropDownContentX into the toggle() method. This is a collection of DOM nodes, not a string. The toggle() method expects a CSS class name without spaces. You are passing the wrong data type to this method.
Source: https://developer.mozilla.org/en-US/docs/Web/API/DOMTokenList/toggle

Related

remove Highlighted Text SectionWise in Iframe

I am following this plugin https://github.com/mir3z/texthighlighter for text Highlighitng in IFrame. Upon Selection Text if i want to remove perticular section of the Selected{colored} text it is not happening. even though this plugin provides removing of highlighted text line by line ... but i need it differently as below
(function() {
var iframe = document.getElementById('iframeDiv'), colors = new ColorPicker(
document.querySelector('.color-picker')), hltr;
var i = 0;
highlights = 1;
iframe.onload = function() {
var hltr = new TextHighlighter(
iframe.contentDocument.body,
{
onAfterHighlight : function(range, highlights) {
i++;
var xColor = $('.selected').css(
'border-right-color');
highlights[highlights.length - 1].parentNode.innerHTML += '<div class="clored_div'+i+'" style="position: absolute;right: 13px;width: 40px;border-right: 14px solid '+xColor+';height: 40px;background:none;border-bottom: 14px solid transparent;border-top: 10px solid transparent;box-shadow: none;height: 0;margin: 0 auto 20px;width: 0;"><img id="removeHighLight" onClick="removeColor();"; title="<fmt:message key="colorRemove"/>" src="<fmt:message key="images"/>/close_rm.png" alt="Close" style="height: 15px;position: absolute;right: -21px;top: -23px;width: 15px;z-index: 9999;"/></div><div id=section' + i +'></div>'
function removeColor(){
$('.clored_div"'+i+'"').remove();
}
},
colors.onColorChange(function(color) {
hltr.setColor(color);
});
};
//for the src HTML please keep any HTML under same application and access like this
iframe.src = 'http://localhost:8080/html/example.htm';
})();
i want to call this function of this section of colored text in order to remove the color.
function removeColor(){$('.clored_div"'+i+'"').remove();}
anyOne help me out with this problem.. if you need more code or understanding for this problem please ask
Thank you so much in Advance.
parent.removeColor();
Iframe is having this function declared, but it is defined in mainPage.

Force browser to immediately repaint a dom element

I need to insert a huge html markup to some dom element which will take awhile. It is a reason why I want to display some preloader indicator. I have two blocks: #preloader and #container. Some code displays the preloader firstly and then starts to paste a big html markup.
The problem - preloader hasn't really displayed until browser will not finish render html markup. I've tried a lot of solutions (a lot of them are described here) but still haven't success.
An example is avalable below:
https://jsfiddle.net/f9f5atzu/
<div id='preloader'>Preloader...</div>
<div id='container'>Container...</div>
#preloader {
display: none;
background-color: #f00;
color: #fff;
hight: 100px;
text-align: center;
padding: 10px 20px;
}
#container {
background-color: #ccc;
}
setTimeout(function() {
// Define variables
let domPreloader = document.getElementById('preloader');
let domContainer = document.getElementById('container');
const html = Array(100000).fill("<div>1</div>");
// Display preloader
domPreloader.style.display = 'hide';
domPreloader.offsetHeight;
domPreloader.style.webkitTransform = 'scale(1)';
domPreloader.style.display = 'block';
// Render a big html
domContainer.innerHTML = html;
}, 1000);
Is there any solutions for the problem?
The way you did it, you're not releasing control to the browser between the display of the preloader and the display of the 'big html'.
Rather than encapsulating this whole block inside a setTimeout(), you should just differ the rendering part.
Please try something along those lines:
// Define variables
let domPreloader = document.getElementById('preloader');
let domContainer = document.getElementById('container');
// Display preloader
domPreloader.style.webkitTransform = 'scale(1)';
domPreloader.style.display = 'block';
// Render a big html
setTimeout(render, 100);
function render() {
const html = Array(100000).fill("<div>1</div>");
domContainer.innerHTML = html;
// Hide preloader
domPreloader.style.display = 'none';
}
JSFiddle

Message DIV Issues

I have the following javascript it pops up a message on the screen, but always over the top of the previous messageDiv if it hasn't been removed yet.
I am trying to figure out how to get the messageDiv to either push the previous div down until it disappears and then takes the previous MessageDiv's place, or show up just below the current one on the page moving down just below the previous one as new ones appear.
function pushDev(){
$.post( "#cgi.SCRIPT_NAME#", {fileId: "#fileIdIn#", action: "migrateFileDev"}, function(data){
$("body").prepend("<div class='pageMessage' id='messageDiv'>" + data + "</div>");
setTimeout(function(){$('#messageDiv').remove()}, 6000);
});
}
function savePage(){
var code = editor.getValue();
$.post( "#cgi.SCRIPT_NAME#", {fileIdIn: "#fileIdIn#", filePath: "#path#", action: "savePage", editText: code }, function(data){
$("body").prepend("<div class='pageMessage' id='messageDiv'>Saved</div>");
setTimeout(function(){$('#messageDiv').remove()}, 6000);
});
}
.pageMessage{
/*position:fixed;*/
/*top: 15%;*/
/*right: 8%;*/
background-color: #f5f5f5;
opacity: 0.9;
color: #FFF;
font-size: 18px;
text-align:center;
padding: 8px;
width: auto;
height:auto;
border:solid;
border-color: #00A3DD;
border-width: 3px;
z-index: 1000;
border-radius: 8px;
}
I think you are running into a problem because you have multiple elements with the same ID and when your setTimeout callback executes, it removes the newest message rather than the oldest one. Only one element with a given ID is allowed in HTML. You need to figure out a different way of finding the div that should be deleted for the particular timeout, for example (I got rid of the irrelevant AJAX code):
function pushDev(){
var messageDiv = $("<div class='pageMessage'>Data</div>")
$("body").prepend(messageDiv);
setTimeout(function(){messageDiv.remove()}, 6000);
}
function savePage(){
var messageDiv = $("<div class='pageMessage'>Saved</div>")
$("body").prepend(messageDiv);
setTimeout(function(){messageDiv.remove()}, 6000);
}
JSFiddle here.

Dynamically created divs not showing next to each other

I am dynamically creating divs and I want them to appear next to each other. I have the following code and after applying style to it (line 5) they keep showing one of top of the other. Please help.
rmc.onstream = function (e) {
if (e.isVideo) {
var uibox = document.createElement("div");
uibox.appendChild(document.createTextNode(e.userid));
uibox.className = "userid";
uibox.id = "uibox-" + e.userid;
uibox.style.cssText = 'display: inline-block; float: left';
document.getElementById('video-container').appendChild(e.mediaElement);
document.getElementById('video-container').appendChild(uibox);
} else if (e.isAudio) {
document.getElementById('video-container').appendChild(e.mediaElement);
}
else if (e.isScreen) {
$('#cotools-panel iframe').hide();
$('#cotools-panel video').remove();
document.getElementById('cotools-panel').appendChild(e.mediaElement);
}
};
Your styles are only being applied to uibox, and you need to apply them to emediaElement too:
if (e.isVideo) {
var uibox = document.createElement("div");
uibox.appendChild(document.createTextNode(e.userid));
uibox.className = "userid";
uibox.id = "uibox-" + e.userid;
uibox.style.cssText = 'float: left; width: 50%';
e.mediaElement.style.cssText = 'float: left; width: 50%';
document.getElementById('video-container').appendChild(e.mediaElement);
document.getElementById('video-container').appendChild(uibox);
}
Here is a working pen - I had to modify your code since I can't see where e.mediaElement is coming from, but you can get the idea: http://jsbin.com/woluneyixa/1/edit?html,css,js,output
If you're still having issues, please create a working codepen so we can see the problem you're having.
Also, using display: inline-block and float: left; is unnecessary; inline-block will have no effect whatsoever when using float.

How do you get the height of a form div + error messages after hitting the submit button in javascript?

So, I've been trying to get this form to work (css and javascript), but I'm stuck on something: i have the form, and everything's basically working, excpet that i have a container for the form div: formbody, and a container for the submit, clear, etc.
The top div is set to height:auto; position:absolute; and the bottom is set to, nothing. it just had a width.
When the user clicks on the submit button, the formbody will need to resize, but i don't know how to get the new size of the form in order to set the position of the bottom div.
I just added more of the css - there's a background div that just holds the template open for the form -- I had that set to relative -- but formbody has a position absolute because the height needs to be auto in order to resize for the errors (and when i set it to auto without position:absolute, formbody shrank to 20px).
.background {
width: 0px;
height: 700px;
position: relative;
z-index:999;
}
.formbody {
background-image: url('');
background-repeat: no-repeat;
background-position: left bottom;
position:absolute;
left:0px;
top:50px;
width:700px;
height:auto;
padding-bottom:20px;
border:1px solid #d2d2d2;
}
.bottom {
width:700px;
}
Would this work? (Here's a live preview: http://jsfiddle.net/rcMGn/1/)
Basically what I'm doing here is getting the first node with class formwidth (as per your css) and using the DOM model to acquire its style properties.
The function getElementsByClass will return an array of all elements in the document with class formwidth (and I'm supposing there's going to be only one) and getting the first element from the array (which is supposed to be 1) and then styling it.
You don't need to care about the function...
To get the width just the first line of the code below...
formWidth = getElementsByClass('formbody',null,'form')[0].offsetWidth;
To get the height, use this one:
formHeight = getElementsByClass('formbody',null,'form')[0].offsetHeight;
and copy the function from the files of Dustin Diaz, the function below...
function getElementsByClass(searchClass,node,tag) {
var classElements = new Array();
if ( node == null )
node = document;
if ( tag == null )
tag = '*';
var els = node.getElementsByTagName(tag);
var elsLen = els.length;
var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
for (i = 0, j = 0; i < elsLen; i++) {
if ( pattern.test(els[i].className) ) {
classElements[j] = els[i];
j++;
}
}
return classElements;
}
something like this
<script>
var formbody_width= $(".formbody").width();
$(".submit").live("click", function) {
$(".formbody").css("height", formbody_width + 300 + "px");
}
</script>

Categories