object HTMLLlElement popup - javascript

I'm Roberto and I'm just a beginner of Javascript. I'm learning on a site and I'm going to get a book of Javascript very soon.
I came across an example: I want to read the elements of the list and tweak the own class of each element( in this case, I want to delete the classes).
As you all can see, for reading all the elements I wrote
var elementi = document.getElementsByTagName('li');
and to verify that everything is gone well I put an alert( elementi[0] ); after the "var elementi..........", then i wrote the rest of the code.
When I open the Window of the browser, It runs a pop-up that contains object HTMLLlElement text.
How can I get rid of this mistake? And what does it mean?
var elementi = document.getElementsByTagName('li');
alert ( elementi[1] );
for ( var i = 0 ; i< elementi.lenght; i++){
elementi[i].className = " ";
}
<!DOCTYPE html>
<HTML>
<head>
<link rel="stylesheet" type="text/css" href="mycss.css">
<title> Javascript </title>
</head>
<body>
<h1><p>Javascript</p></h1>
<p class="subtitle">Shopping list:<p>
<ul id="lista">
<li>Pasta</li>
<li >Crocchette</li>
<li >Lotamma</li>
</ul>
<script type="text/javascript" src="corso01.js"></script>
</body>
</HTML>

You simply need to remove this line:
alert ( elementi[1] );
To no longer get the message. But, the message itself it just showing what type of object you have (element[1] is a list item HTML element). You could modify the alert to be more specific by changing it to:
alert ( elementi[1].textContent);
Which would show "Crocchette" because that is the text that is stored in the list item.
It's coming up because the JavaScript code you've shown is automatically running as soon as the page is loaded. In practice, you'll most likely want to move that code into a function that is called at a particular time, called an event. This could be when the user interacts with the page in some way (a click, a mouseover, etc.).
Also, you should change this:
elementi[i].className = " "
to this:
elementi[i].className = "";
The second one removes the space between the quotes so that instead of setting a class name to an actual space character, you are setting the class name to an empty string (no space).

to remove a class from an element, you want to use the remove method on the classList property, like this:
elementi[i].classList.remove('lined');

Related

Why does the Awesomplete JavaScript object fail to be created when new'ed?

I found the Awesomplete JavaScript/jQuery plug-In here. It's a combobox/drop-down list widget that displays a list of case-less matches while the user types characters into a input text element. The provided link shows the section of the widget's web-page that shows how multiple entries can be entered into the input element, which is exactly what I need. A live-demo in this section shows that the widget works.
Unfortunately, the examples shown at the Awesomplete web-page don't provide a complete example of how to properly use the widget, so I cobbled the following together in order to begin integrating it into my own web-page, but my attempt gets an error when the script tries to create the Awesomplete object, saying:
awesomplete.html: 61 Uncaught ReferenceError: Awesomplete is not defined
at awesomplete.html: 61
(anonymous) # awesomplete.html: 61
Here is my code:
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title>Awesomplete: Multiple values</title>
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js'></script>
<script src="awesomplete.js" async></script>
<link rel="stylesheet" href="awesomplete.css" />
<style>
.visually-hidden { display: none; }
</style>
</head>
<body translate="no" >
<h2>Awesomplete: Multiple values</h2>
<label for="browserInput">browser List: </label>
<input type="text" id="browserInput"
style="width: 245px;"
maxlength="100"
autocomplete="off"
autofocus
required
placeholder="Enter browser name(s)."
title="Enter the name of one or more browsers
or press space to see all choices."
multiple
data-multiple
data-list="#browsersList"
data-minchars="1"
data-maxitems="100"
data-autofirst
aria-expanded="false"
aria-owns="awesomplete_list_2"
role="combobox" />
<ul id="browsersList" hidden>
<li>Zebra</li>
<li>Safari</li>
<li>Opera</li>
<li>Microsoft Internet Explorer</li>
<li>Microsoft Edge</li>
<li>Google Chrome</li>
<li>Firefox</li>
</ul>
<ul id="awesomplete_list_2" hidden
role="listbox"
aria-label="Results List">
</ul>
<span class="visually-hidden"
role="status"
aria-live="assertive"
aria-atomic="true">
Type one or more characters for results.
</span>
<script>
// Show label and insert label into the input:
// ***** The error occurs when the next line executes ***** //
new Awesomplete( 'input[data-multiple]',
{
filter: function( text, input ) {
return Awesomplete.FILTER_CONTAINS(
text, input.match( /[^,]*$/ )[ 0 ] );
},
item: function( text, input ) {
return Awesomplete.ITEM(
text, input.match( /[^,]*$/ )[ 0 ] );
},
replace: function( suggestion ) {
var before = this.input.value
.match( /^.+,\s*|/ )[ 0 ];
this.input.value = before + suggestion.label + ", ";
}
} );
</script>
</body>
</html>
I downloaded the files needed for the <script src="awesomplete.js" async></script> and <link rel="stylesheet" href="awesomplete.css" /> lines to my computer before trying to run my web-page. You may do the same using this link to show the top section of the Awesomplete web-page and then clicking on the Download button.
In my initial test web-page using this widget, I used class="awesomplete" setting in the input element as suggested near the top of the Awesomplete web-page, and it worked, but it only let me enter one value. However, I need to enter multiple matches, but simply adding the multiple and data-multiple attributes to the input element isn't enough to make it work. I then added the script that crates the Awesomplete object and took the class out of the input element, but that's when I started getting the error I showed, above.
Incidentally, having the class in the element didn't work.
After the above works, I'm wondering if the Awesomplete settings in the input element will be used when the Awesomplete object is created in the script or do I need to take then out of the input element and instead explicitly put them in the Awesomplete new call.
Thanks
While putting the above web-page content into codepen.io I found that the javascript file can be found using the codepen's setting js search tool, but the corresponding css file can't when using the css search tool. However, using the URL for the js file, I was able to find the css file. When both of these URLs are added to codepen, my test version worked and did allow multiple choices to be selected in the input element. Finally, was able to copy the script and link statements into my local version of the test web-page, and it also worked. Note, the script statement uses the min.js version, not the full version. I don't know if this is a factor, but for my production site, I want the min.js version anyway.
Here are to two lines needed to make the code I posted here work:
<script src="https://cdnjs.cloudflare.com/ajax/libs/awesomplete/1.1.5/awesomplete.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/awesomplete/1.1.5/awesomplete.css">
Hope this helps others, too.
I read on the GitHub page about it and successfully tried removing async in line 7.

store the 'this' object in an onclick attribute

What I ultimately want is to retrieve the innerHTML of the example script below (the html is to be put in a database). It must include the onclick events also. However in the generated HTML there is no onclick event available.
<html>
</head>
<script>
function test() {
this.goodbye="goodbye!";
this.elem=document.createElement('div');
this.elem.style.border='1px solid #888888';
this.elem.textContent="hello";
this.elem.style.cursor='pointer';
var that=this;
this.elem.onclick=function(){that.say_goodbye();}
document.getElementsByTagName('body')[0].appendChild(this.elem);
}
test.prototype.say_goodbye=function(blockid) {
this.elem.textContent=this.goodbye;
}
</script>
</head>
<body>
<script>var obj = new test();</script>
get html
</body>
</html>
the line of importance is thus:
this.elem.onclick=function(){that.say_goodbye();}
I tried to add it as attribute like:
this.elem.setAttribute('onclick',that.say_goodbye.bind(that));
But is doesn't work. When I click the link in the given code the browser alerts:
<div> onclick="function(){[native code]}" ..... </div>
In this case the HTML now has an 'onclick' event but contains '[native code]' as action.
Anyone an idea on how to make the code work?
The reason you get this is that attribute value is text always and you are trying to put object into it (functions are objects). This case you should rather use this.elem = that.say_goodbye.bind(that).

Call javascript from XForms action

I am experimenting with XForms and trying to dynamically load javascript, but cannot figure it out.
I am presenting a simple example - that is just an input field and button that loads the javascript:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:xf="http://www.w3.org/2002/xforms"
xmlns:ev="http://www.w3.org/2001/xml-events" >
<head>
<title>Hello World in XForms</title>
<xf:model>
<xf:instance xmlns="">
<data>
<firstName/>
</data>
</xf:instance>
</xf:model>
<script type="text/javascript">
var myFunction = function(){
var name = document.getElementById("firstName").value;
alert("Hello " + name + "!");
}
</script>
</head>
<body>
<xf:label>Please enter your first name: </xf:label>
<xf:input ref="firstName" id="firstName">
</xf:input>
<br />
<xf:trigger>
<xf:label>Click me!</xf:label>
<xf:action ev:event="DOMActivate">
<xf:load resource="javascript:myFunction()" />
</xf:action>
</xf:trigger>
</body>
</html>
So in my script I am trying to get the value from the input box and then show an alert box with concatenated string. Currently, I get "Hello undefined!"
Do you have an idea how to get the value from the firstName xf:input with Javascript?
I know how to do it with XForms only, but this is sort of a proof of concept.
On a side note - I am using XSLTForms, so the XForms runs on the client.
Another hint might be in the fact that XSLTForms transforms the xf:input into several nested span elements with a <input type="text"> element, but that input element does not have a name or id.
With XSLTForms, there are different possibilities...
If you want to access the value of the corresponding HTML input, I would suggest document.getElementById("firstName").xfElement.input.value.
You could also use the node property to get the value stored in the bound node.
Don't hesitate to browse DOM with a debugger to find how to get things from XSLTForms!
--Alain

Override existing HTML Element attribute and property with Javascript

I was wondering if its possible to override existing HTML Element attribute and property accessors (getters and setters) with Javascript so that when html is rendered by browser all the assignments to certain attributes in the html code are preprocessed with custom functionality.
Here is an example :
<html>
<head>
<script>
// JS code would go here which would override default behavior
// for example if I wanted to reformat id="name" so its actually
// registered as id="pre_name" once browser renders the html
</script>
</head>
<body>
<!-- here we are assigning the 'name' to id , but behind the scene we really want it to be 'pre_name' -->
<div id="name"></div>
<script>
// when we try to access the id it would actually match the overwritten one
console.log(document.body.children[0].id) // would output pre_name
</script>
</body>
</html>
Is something like that possible and how?
I know that I can traverse the dom after it's rendered and change all of the ids, but I am wondering if its possible to intercept the assignment of properties and attributes and do it at that level before browser even renders the html.
Example I presented is just made up one to present the problem and make is simple to understand.
Thanks
Unfortunately this is not possible, you can only modify the name element after it is loaded.
So it would be something like this:
<body>
<!-- here we are assigning the 'name' to id , but behind the scene we really want it to be 'pre_name' -->
<div id="name"></div>
<script>
// right after
document.getElementById('name').id = 'pre_name';
</script>
<script>
// when we try to access the id it would actually match the overwritten one
console.log(document.body.children[0].id) // would output pre_name
</script>
</body>
or even
<body>
<!-- here we are assigning the 'name' to id , but behind the scene we really want it to be 'pre_name' -->
<div id="name"></div>
<script>
// or here
document.getElementById('name').id = 'pre_name';
// when we try to access the id it would actually match the overwritten one
console.log(document.body.children[0].id) // would output pre_name
</script>
</body>
You can use html data-* attributes for second value like;
<div id="name" data-second="pre_name"></div>
And then you can use,
var div = document.getElementById('name');
div.getAttribute("data-second");

html assigning value to input text using javascript does not work

I am new to programming and I have a small problem
I have a form named "fr" with an input text box named "in" and a variable "n" with the value of "my text"
this is my code what I have:
<html>
<head>
<script LANGUAGE="JavaScript">
var n = "my text";
document.fr.in.value = n;
</script>
</head>
<body>
<form name="fr">
<input name="in" size="3">
</form>
</body>
</html>
but somehow input "in" does not show the text "my text"
I have been browsing the internet but I couldn't find any solution which works..
everything what I try does not work.
I think I am doing something very simple wrong.
please help me.
document.fr does not exist yet at time of invocation; hence, everything following it doesn't exist either, so it throws a TypeError
TypeError: Cannot read property 'in' of undefined
To fix this, move your code to be invoked after the nodes exist, using your favourite method
window.addEventListener('load', function () {
var n = "my text";
document.fr.in.value = n;
});
I'll further note that;
The preferred way to look up an Element is to give it an id attribute and use document.getElementById. An id must be unique.
Using the language attribute of <script> is depreciated, if you want to specify the language, use the type attribute type="text/javascript" or type="application/javascript"
Opening the Console when a script is not working as expected will often show you the cause immediately. This is usually done with F12.
You should init the script after the form is defined, as explained by Paul S. in his answer. So you may do,
<html>
<head>
</head>
<body>
<form name="fr">
<input name="in" size="3">
</form>
<script type="text/javascript">
var n = "my text";
document.forms.fr.in.value = n;
</script>
</body>
</html>
This would run the script after the form is defined. Or put this code in some function, and instantiate the function after the form is defined(i.e. loaded).
As Paul pointed out you should only try to get a hold of page elements when you are certain that the element you are interested has already been loaded. So in this case you can set the value of the input field by running your code when the page has fully loaded and by getting a reference to the input like this:
window.addEventListener("load", function () {
var n = "my text";
var myInput = document.getElementsByName("in");
myInput[0].value = n;
});
Note, because getElementsByName() returns an array, you will have to use [0], to get the first element.

Categories

Resources