How to display document.write in a specific div with specific id? - javascript

I want to display my document.write("something important");
into a specific div with specific id.
Im my HTML, I have a div <div class="col-lg-4" id="print"> ... </div>
In my JavaScript, I have a loop.
for(var i = 0; i < L; i++) {
document.write(
navigator.plugins[i].name +
" | " +
navigator.plugins[i].filename +
" | " +
navigator.plugins[i].description +
" | " +
navigator.plugins[i].version +
"<br><hr><br>"
);
}
What is the most efficient way to display them in my div ?

I would recommend not using document.write, especially after the page has loaded. It can lead to unexpected results. Just use this method:
document.getElementById('print').innerHTML = "something important";
If, however, you did not want to replace the whole innerHTML, you could append something to it:
document.getElementById('print').insertAdjacentHTML('beforeend', "something added");
Update
Here is an example with a loop:
var elem = document.getElementById('print'),
L = navigator.plugins.length;
for(var i = 0; i < L; i++) {
elem.insertAdjacentHTML('beforeend',
navigator.plugins[i].name +
" | " +
navigator.plugins[i].filename +
" | " +
navigator.plugins[i].description +
" | " +
navigator.plugins[i].version +
"<br><hr><br>"
);
}
JS Fiddle Demo

man!
I think that what you want to do is update the content of the element, right? If so:
document.getElementById('print').innerHTML = something important
I hope I have helped you

Related

Unable to display total using append

I am making a food delivery app. I would like that there would be a place whereby it would display the total. Right now, I am unable to display the total amount from multiplying quantity and price. It does not show up on the app.
And, there are no errors on the console too.
Javascript Code:
function _showorderResult(arr) {
var value1 = arr[0].price;
var value2 = arr[0].quantity;
for (var i = 0; i < arr.length; i++) {
result = value1 * value2;
htmlstring = "";
$("#itemimage").html("<img src='" + serverURL() + "/images/" +
arr[i].imagefile + "' width='200'>");
$("#price").html("Price" + ": " + " $" + arr[i].price);
$("#itemname").html("Item" + ":" + arr[i].itemName);
$("#quantity").html("Quanitiy" + ":" + arr[i].quantity);
$("result").append(htmlstring);
$("#requestedDateTime").html("To delivery by" + ":" + arr[i].requestedDateTime);
$("#deliveredDateTime").html("Delivered on" + ":" + arr[i].deliveredDateTime)
}
}
And, there are no errors on the console too.
There were plenty of errors in my console, but there are several mistakes here. The first is that your code is not runnable. Please consider making a minimal, verifiable example.
Next, you are misusing or not properly formatting the append(...) function. That's intended to append HTML elements, not string values.
As the comments suggest, you seem to have confused var result and $("result"). If you're not using the DOM selector, you probably don't want to jQuery-wrap your variables. The proper jQuery-wrap syntax would have been $(result) without the double quotes, but please don't do that either, it doesn't offer any benefit over just var result. htmlstring doesn't contain any actual HTML, so I've renamed it runningTotal instead and add it to the price * quantity. This must be initialized first or you'll get NaN.
Make sure to initialize your variables. To this point, there's some hard-coded indexes such as value1 = arr[0].price which make no sense in this pasted code. We can assume you left these here after troubleshooting. Please clean them up next time.
Finally, this is minor, but be consistent with your object names... e.g. imagefile versus imageFile. It doesn't matter which you choose so as long as you're consistent. This will help find typos down the road.
Here's a working example:
<html>
<img src="" id="itemimage">
<p id="price">Price: $0.00</p>
<p id="itemname">Item: None</p>
<p id="quantity">Quantity: None</p>
<p id="result">Running: None</p>
<p id="requestedDateTime">To delivery by: None</p>
<p id="deliveredDateTime">Delivered on: None</p>
<script>
var order = [{
price: 5,
quantity: 3,
itemName: 'Pizza',
imagefile: 'pizza.png',
requestedDateTime: '12:00',
deliveredDateTime: '12:30'
}];
/** Dummy function to allow code to run **/
var serverURL = function() { return ""; }
function _showorderResult(arr) {
// var value1 = arr[0].price;
// var value2 = arr[0].quantity;
var result;
var runningTotal = 0;
for (var i = 0; i < arr.length; i++) {
result = arr[i].price * arr[i].quantity;
runningTotal += result;
$("#itemimage").html("<img src='" + serverURL() + "/images/" + arr[i].imagefile + "' width='200'>");
$("#price").html("Price" + ": " + " $" + arr[i].price);
$("#itemname").html("Item" + ":" + arr[i].itemName);
$("#quantity").html("Quanitiy" + ":" + arr[i].quantity);
$("#result").html("Running" + ":" + runningTotal);
$("#requestedDateTime").html("To delivery by" + ":" + arr[i].requestedDateTime);
$("#deliveredDateTime").html("Delivered on" + ":" + arr[i].deliveredDateTime);
}
}
_showorderResult(order);
</script>
</html>

Selenium - Unable to find the hidden element

I am trying to create an framework where I want to find whether an webelement is hidden or not before performing an action on the web element.
I have a password field which is hidden and is structured as below
<div class=hidepassword>
<input password field >
<div>
When I query the input tag with the following lines
Isvisible1 = (string)js1.ExecuteScript("return (window.getComputedStyle?window.getComputedStyle(arguments[0], null):arguments[0].currentStyle).visibility;", myCurElement);
Isvisible2 = (string)js1.ExecuteScript("return (window.getComputedStyle(arguments[0], null).getPropertyValue('display'));", myCurElement);
Isvisible3 = (bool)js1.ExecuteScript("return !(arguments[0].offsetHeight <= 1);", myCurElement);
I am getting all the values indicating it as visible.
Later , got to know that the class which the preceding div has is making the input invisible.
I tried to get the value of overflow which is made available in the .css file for the class hidepassword
But unfortunately, there are lot of css values for the class hidepassword and when I use the below javascript function, I am able to get only one of its CSS value
public string getStyle(string ClassName)
{
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
return (String)js.ExecuteScript(
"function getStyle(ClassName) {" +
"var styleSheets = window.document.styleSheets;" +
"var styleSheetsLength = styleSheets.length;" +
"for (var i = 0; i < styleSheetsLength; i++)" +
"{" +
" var classes = styleSheets[i].rules || styleSheets[i].cssRules;" +
" if (!classes)" +
" continue;" +
" var classesLength = classes.length;" +
" for (var x = 0; x < classesLength; x++)" +
" {" +
" if (classes[x].selectorText == ClassName)" +
" {" +
" var ret;" +
" if (classes[x].cssText)" +
" {" +
" ret = classes[x].cssText;" +
" }" +
" else" +
" {" +
" ret = classes[x].style.cssText;" +
" }" +
" if (ret.indexOf(classes[x].selectorText) == -1)" +
" {" +
" ret = classes[x].selectorText + ret ;" +
" }" +
" return ret;" +
" }" +
" }" +
"}" +
"}return getStyle(arguments[0]);", ClassName);
}
Is there a way to get all the css values for the particular class name and then based on the css values for the class, we can make a call whether the element is visible or not visible. ?
Thanks in advance for all your help on this.
Selenium had supply api:isDisplayed() to detect element visibility, why you want to implement it as such complex by yourself

How to replace current page content on user input?

I am creating a search engine of sorts, using the Wikipedia API to query content. As it currently stands, the user can make a search input and the page returns the top 10 results with links and snippets. I run into difficulty when the user makes another search, in which case the page simply appends the original search results again. I have tried using replaceWith() and html(), but they either prevent the search results from coming through at all (if I put them within the event handler), or they don't get triggered (if they are outside the event handler). I am hoping to achieve a result where the user can make another input and the page will replace the current content with the new search results.
Here is what I have currently:
JS:
var results = [];
$("#search").on("keydown", "#searchinput", function(event) {
if (event.key === "Enter") {
var searchParameter = encodeURIComponent(this.value);
var link = "https://en.wikipedia.org/w/api.php?action=opensearch&search=" + searchParameter + "&limit=10&namespace=0&format=json&origin=*";
$.getJSON(link, function(data) {
for (var key in data) {
results.push(data[key]);
}
for (var i = 0; i < 10; i++) {
$("#results").append("<div class=\"resultContent\">" + "<h2>" + "" + results[1][i] + "" + "</h2>" + "<p>" + results[2][i] + "<br/>" + "</p>")
}
})
}
})
HTML:
Feeling Bold? Click Here for a Random Article
<div id="search">
<span>Search:</span>
<input type="text" id="searchinput" autocomplete="off"></input>
</div>
<div id="results"></div>
Thanks for the help!
You can remove the current results just before your loop:
$("#results").empty();
for (var i = 0; i < 10; i++) {
$("#results").append("<div class=\"resultContent\">" + "<h2>" + "" + results[1][i] + "" + "</h2>" + "<p>" + results[2][i] + "<br/>" + "</p>")
}

jQuery/Javascript foreach If/Else | If empty (do nothing) else (show foreach)

THIS QUESTION IS SOLVED VIA COMMENTS. WORKING SOLUTION IS POSTED BELOW
So I got this piece of code that I am trying to adapt as it ain't showing the way I wish.
function writeRow(row) {
var spans = '';
for (var i = 0; i < num_of_fields; ++i) {
// to do: append for select type field -> if select write: name, value, title
// to do: add class "debug" to name, and for select tag value
spans += '<div><span class="name"><b>' + field[i].name + ':</b></span> <span class="value">' + row[field[i].name] + '</span></div> ';
}
spans += ' ×';
$('#outer-list').append($('<li id="row_' + row_id++ +'">').append(spans));
}
The issue is with this line:
spans += '<div><span class="name"><b>' + field[i].name + ':</b></span> <span class="value">' + row[field[i].name] + '</span></div> ';
The problem is that when the row[field[i].name] inside the .value <span> is empty it still shows the name and a empty value field.
So I thought to replace that line with a if/else like if .value <span> is empty then //do nothing else CODE FROM ABOVE.
As I am not going to ask a question without trying to fix it by myself first here are the attempts I made so far, please keep in mind that I placed all these if else at the same place as the single line of code above!
Attempt 1
if $(row[field[i].name]).length == 0) {
// Do nothing
} else {
spans += '<div><span class="name"><b>' + field[i].name + ':</b></span> <span class="value">' + row[field[i].name] + '</span></div> ';
}
Attempt 2
if $(row[field[i].name]).val().trim().length == 0) {
// Do nothing
} else {
spans += '<div><span class="name"><b>' + field[i].name + ':</b></span> <span class="value">' + row[field[i].name] + '</span></div> ';
}
The attempts are not in the right order but those 2 where left in the document as comments I tried a couple of other things as well including :empty but I already deleted them from the comments section.
Thanks in advance for any help. And if something is not clear please let me know.
Attempt 3 with help from Mike C
var row_id = 0; // row counter
function writeRow(row) {
var spans = '';
for (var i = 0; i < num_of_fields; ++i) {
// to do: append for select type field -> if select write: name, value, title
// to do: add class "debug" to name, and for select tag value
if row[field[i].name].length == 0) {
// Do nothing
} else {
spans += '<div><span class="name"><b>' + field[i].name + ':</b></span> <span class="value">' + row[field[i].name] + '</span></div> ';
}
}
spans += ' ×';
$('#outer-list').append($('<li id="row_' + row_id++ +'">').append(spans));
}
I am answering it myself as I don't want to have too many questions with no answers as it could get me blocked! Can't have that. Too be clear this answers credits should go to MikeC. But he never posted the answer as answer but as comment. I asked him together with some others to please post a answer so we could accept it. He never did so therefore I post his answer myself.
Working solution by Mike C
var row_id = 0; // row counter
function writeRow(row) {
var spans = '';
for (var i = 0; i < num_of_fields; ++i) {
// to do: append for select type field -> if select write: name, value, title
// to do: add class "debug" to name, and for select tag value
if (row[field[i].name].length == 0) {
// Do nothing
} else {
spans += '<div><span class="name"><b>' + field[i].name + ':</b></span> <span class="value">' + row[field[i].name] + '</span></div> ';
}
}
spans += ' ×';
$('#outer-list').append($('<li id="row_' + row_id++ +'">').append(spans));
}

Creating and deleting divs using javascript

I have a few JavaScript functions designed to add and remove HTML divs to a larger div. The function init is the body's onload. New lines are added when an outside button calls NewLine(). Divs are removed when buttons inside said divs call DeleteLine(). There are a few problems with the code though: when I add a new line, the color values of all the other lines are cleared, and when deleting lines, the ids of the buttons, titles, and line boxes go out of sync. I've gone through it with the Chrome debugger a few times, but each time I fix something it seems to cause a new problem. I would greatly appreciate some input on what I'm doing wrong.
function init()
{
numOfLines = 0; //Keeps track of the number of lines the Artulator is displaying
}
function NewLine()
{
var LineBoxHolder = document.getElementById("LineBoxHolder");
numOfLines += 1;
LineBoxCode += "<div class = 'Line Box' id = 'LineBox" + numOfLines + "'>" //The code is only split onto multiple lines to look better
+ " <h6 id = 'Title " + numOfLines + "' class = 'Line Box Title'>Line " + numOfLines + "</h6>";
+ " <p>Color: <input type = 'color' value = '#000000'></p>"
+ " <input type = 'button' value = 'Delete Line' id = 'DeleteLine" + numOfLines + "' onclick = 'DeleteLine(" + numOfLines + ")'/>"
+ "</div>";
LineBoxHolder.innerHTML += LineBoxCode;
}
function DeleteLine(num)
{
deletedLineName = "LineBox" + num;
deletedLine = document.getElementById(deletedLineName);
deletedLine.parentNode.removeChild(deletedLine);
num++;
for ( ; num < numOfLines + 1 ; )
{
num++;
var newNum = num - 1;
var changedLineName = "LineBox" + num;
var changedHeaderName = "Title" + num;
var changedButtonName = "DeleteLine" + num;
var changedButtonOC = "DeleteLine(" + newNum + ")";
var changedLine = document.getElementById(changedLineName);
var changedHeader = document.getElementById(changedHeaderName);
var changedButton = document.getElementById(changedButtonName);
var changedLine.id = "LineBox" + newNum;
var changedHeader.innerHTML = "Line" + newNum;
var changedHeader.id = "Title" + newNum;
var changedButton.setAttribute("onclick",changedButtonOC);
var changedButton.id = "DeleteLine" + newNum;
}
num--;
numOfLines = num;
}
You are having a hard time debugging your code because of your approach. You are "marking" various elements with the IDs you construct, and using the IDs to find and address elements. That means that when things change, such as line being deleted, you have to go back and fix up the markings. Almost by definition, the complicated code you wrote to do something like that is going to have bugs. Even if you had great debugging skills, you'd spend some time working through those bugs.
Do not over-use IDs as a poor-man's way to identify DOM elements. Doing it that way requires constructing the ID when you create the element and constructing more IDs for the sub-elements. Then to find the element again, you have to construct another ID string and do getElementById. Instead, use JavaScript to manage the DOM. Instead of passing around IDs and parts of IDs like numbers, pass around the DOM elements themselves. In your case, you don't need IDs at all.
Let's start off with DeleteLine. Instead of passing it a number, pass it the element itself, which you can do my fixing the code inside your big DOM string to be as follows:
<input type='button' value='Delete Line' onclick="DeleteLine(this.parentNode)"/>
So we have no ID for the line element, no ID for the element, and no ID within the onclick handler. DeleteLine itself can now simply be
function DeleteLine(line) {
{
line.parentNode.removeChild(line);
renumberLines();
}
We'll show renumberLines later. There is no need to adjust IDs, rewrite existing elements, or anything else.
Since we no longer need the ID on each line or its sub-elements, the code to create each element becomes much simpler:
function NewLine()
{
var LineBoxHolder = document.getElementById("LineBoxHolder");
numOfLines += 1;
var LineBoxCode = "<div class='LineBox'>" +
+ " <h6 class='LineBoxTitle'>Line " + "numOfLines + "</h6>"
+ " <p>Color: <input type='color' value='#000000'></p>"
+ " <input type='button' value='Delete Line' onclick= 'DeleteLine(this.parentNode)'/>"
+ "</div>";
LineBoxHolder.innerHTML += LineBoxCode;
}
The only remaining work is to fix up the titles to show the correct numbers. You can do this by just looping through the lines, as in
function renumberLines() {
var LineBoxHolder = document.getElementById("LineBoxHolder");
var lines = LineBoxHolder.childElements;
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
var h6 = line.querySelector('h6');
h6.textContent= "Line " + (i+1);
}
}
I voted to close because the question is too broad, but will answer anyway on a few points to... well, point in the right direction.
var changedButton.setAttribute("onclick",changedButtonOC); This is not a variable declaration. Omit the var.
for ( ; num < numOfLines + 1 ; ) { num++; ... The correct form here would be simply for (; num < numOfLines + 1; num++) { ....
Instead of incrementing (num++) then decrementing (num--) around the loop, why not just use the right math?
See:
for (; num < numOfLines; num++) {
...
}

Categories