Merge HTML String - javascript

I am trying to find the best way to merge two HTML String in Javascript (JQuery/AngularJS) such as :
var context = '<html>
<head>
</head>
<body>
<ul id="list">
<li>itemA</li>
<li>itemB</li>
</ul>
</body>
</html>';
merged with :
var additionnalInfo = '<ul id="list">
<li>itemC</li>
<li>itemD</li>
</ul>';
should modify context variable to :
'<html>
<head>
</head>
<body>
<ul id="list">
<li>itemA</li>
<li>itemB</li>
<li>itemC</li>
<li>itemD</li>
</ul>
</body>
</html>';
Any idea ?

Should be able to do something like this, as long as your additional info contains only the elements you want to add (which you can easily strip down to).
var additionnalInfo = '<li>itemC</li>
<li>itemD</li>';
var list = getElementById('list');
list.innerHTML += additionalInfo;
Edit
If you must be able to match on several ids, then its possible you could use jQuery to iterate through all elements of a type (all lists for example), and just check the ids for equality, then append as above. Ex:
var additionalInfo = $.parseHTML('<ul id="list"><li>itemC</li><li>itemD</li></ul>');
var elements = additionalInfo.find($('ul'));
var lists = $('ul').get();
elements.each(function(){
var el = this;
lists.each(function(){
if($(this).attr('id') == el.attr('id')){
el.innerHTML += $(this).innerHTML;
}
});
There are more efficient ways of doing this, but it should be a good basis for what you need. Essentially just loop through all of the "parent" list elements in the additional html. Compare those ids against the list ids within your existing html, and if they are the same, then append the new innerHTML to the existing list.
You can also make it more generic so that once you parse your html string, get the type of any element with an id, and do a find for that type. A lot of ways to do this, its just a matter of applying the proper method of iterating through your data without wasting a ton of cycles. Hope this helps a bit more.

Related

How to filter/parse string of html templates with plain javascript?

I have a string of html templates, each wrapped in script tag with id-s.
Example templates string:
<script id="id1"> some html </script>
<script id="id2"> some other html </script>
I want to find template in this string with specified id and get html template without wrapper script tag.
Here is jquery approach to this problem that works:
var template = $(templates).filter("#id1").html();
Unfortunately I need to do the same thing in plain javascript, but I can't find a simple solution to this problem. How can I do this without jquery?
var template = `<script id='id1' src="" /><script id='id2' src="" / >`;
var div = document.createElement('div');
div.innerHTML = template;
var filterElement = div.querySelectorAll("#id1");
console.log(filterElement[0]);
With javascript, you can get a a DOM node by id using
document.getElementById("ID_GOES_HERE")
So, in your case, I would try something like
let tmplt = document.getElementById("id1").innerHTML;
or
let tmplt = document.getElementById("id1").innerText;
Read more about dom elements here.
Also, on a side note, let is probably better to use then var, as it has better scoping, but in the above code I wrote, let could be substituted with var
I suppose you can do this by using Regular Expressions.
This website may help you to find the right one.

Editing and Updating a HTML list with JavaScript

I'm trying to create a list which I can edit/update. I'll need to be able to store the list information in a variable of some sort and display the information on a HTML page.
My attempt is in the jsbin below.
JSBIN
https://jsbin.com/luxobineze/edit?html,js,console,output
So with that code, I'd like to:
Add names by filling in the form and clicking "Add Name"
Click [Edit] which will fill the form with the name that is to be edited
Click Update to update the global variable "names" (If I can do this, then I should be able to update the HTML's "List of Names" as well)
I'm not sure what to do in the updateName function since I'm not sure how to pass the relevant arguments into it in order to update the correct list item. Do I need to use more global variables to keep track of the list item that's being edited? Or is there a better, more standard way of coding this?
The code in the jsbin is here:
HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
Name: <input type="text" id="name-input"><br>
<button id="add-name" class="button">Add Name</button>
<button id="update" class="button">Update</button>
<div id="list">List of Names</div>
</body>
</html>
JavaScript
// global variable storing the list of names
var names = [];
function addName() {
var name = document.getElementById("name-input").value;
var list = document.getElementById("list");
if(name) {
names.push("name");
var wrapper = document.createElement("div")
wrapper.setAttribute("id", name)
var div_name = document.createElement("div");
div_name.appendChild(document.createTextNode(name))
var div_edit = document.createElement("div")
div_edit.appendChild(document.createTextNode("[edit]"))
div_edit.addEventListener("click", editName)
wrapper.appendChild(div_name)
wrapper.appendChild(div_edit)
list.appendChild(wrapper)
}
}
function editName() {
// Fill the input box with the name that you want to edit
var name = this.parentElement.getAttribute("id")
document.getElementById("name-input").value = name;
}
function updateName() {
var new_name = document.getElementById("name-input").value
// How do I update the global variable "names"?
}
document.getElementById("add-name").addEventListener("click", addName)
document.getElementById("update").addEventListener("click", updateName)
Edit
I ended up using some global variables to keep track of which item was currently selected: https://jsbin.com/zupawesifu/1/edit?html,js,console,output
What it sounds like you're doing is building the most basic of applications, a CRUD app. (Create, Read, Update, Delete)
Storing your values in a local variable is not the most desirable way of doing this, unless of course that is your desired functionality.
You ask "is there a more standard way". A more common way would be to store your values in a database, or, in an even simpler scenario, you could store these values in a local .JSON file. This will allow you to use your application at any time, close the application, refresh, or any other number of things without losing your stored or edited values.
I won't code a full CRUD app for you here, but there are many tutorials and templates out there for your learning pleasure. Here is very basic one.
I hope this helps!
http://mrbool.com/creating-a-crud-form-with-html5-local-storage-and-json/26719

object HTMLLlElement popup

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');

Can a JavaScript variable be used in plain HTML?

What I mean is, can a variable/array declared and initialized be used in HTML, outside the <script>-tags? Fx.
<script type="text/javascript">
var foo = array('placeholder1', 'placeholder2');
</script>
<body>
<p><!--access the variable here-->foo[0]</p>
</body>
How do you access the variable/array in this case? like this:
<p><script type="text/javascript">document.print(foo[0])</script></p>
??
Two ways to do this. This is the better one:
<script type="text/javascript">
// make sure to do this onLoad, for example jQuery's $()
var foo = array('placeholder1', 'placeholder2');
document.getElementById("fooHolder").innerHTML = foo.toString();
</script>
...
<p id="fooHolder"></p>
Or you could do it this way (which, as Marcel points out, doesn't work in XHTML and really shouldn't be used anyway):
<p><script type="text/javascript">document.write(foo)</script></p>
You can do something like this:
<script>
var str = 'hello there';
document.getElementById('para').innerHTML = str;
</script>
where an element has the specified id:
<p id="para"></p>
you simply cannot access javascript variable outside of the script tag, it is because,
Html does not recognise any variable it just renders the supported HTML elements
variables are used to store the temporary variables, that is for dynamic data, if you want something more dynamic then you can use PHP for that.
Unnecessarily verbose, but using standard DOM methods.
<script>
window.onload = function(){
// you do not need to initialize like this, but I like to
var bar1 = new String('placeholder1');
var bar2 = new String('placeholder2');
var foo = new Array();
// populate the Array with our Strings
foo.push(bar1);
foo.push(bar2);
// create an array containing all the p tags on the page
// (which is this case is only one, would be better to assign an id)
pArray = document.getElementsByTagName('p');
// create a text node in the document, this is the proper DOM method
bar1TextNode = document.createTextNode(foo[0].toString());
// append our new text node to the element in question
pArray[0].appendChild(bar1TextNode);
};
</script>
<body>
<p></p>
</body>
That's the only direct way you'll access it elsewhere in your page. By opening another script tag and printing it.
You can also use methods such as innerHTML to put the value somewhere.
I don't think you can access the javascript from html but you can set the innerhtml of a dom object through javascript so you may want to go the other way around. First google search I found so I cant promise its good but it has a quick sample.
http://www.tizag.com/javascriptT/javascript-innerHTML.php
You can even you AngularJS expression.
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.framework= "AngularJS";
});
</script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<p>I want to use variables directly in HTML using: {{ framework }}</p>
</div>
</body>
</html>
The above code will print out "I want to use variables directly in HTML using: AngularJS".You can use braces to write AngularJS expression. For example: {{ expression }}.

Can you getElementsByName if you only have partial name on javascript?

I have a repeating table where the name of the elements would be (e.g. 'tdName_1' 'tdName_2'), and I was wondering if it would be possible to getElementsByName('tdName_').
PS: I can not use Jquery.
Thanks In advance.
Cesar.
This is not possible. I'm assuming for the rest of this answer that the elements you're interested in are <td>s. If so, then you should be aware that the name attribute is not valid for <td> elements.
You will have to create a list of matching elements manually. If you decide to use the name attribute anyway (instead of, say, adding a class in the class attribute), something like the following will work:
var table = document.getElementById("your_table_id");
var tds = table.getElementsByTagName("td");
var matchingTds = [];
for (var i = 0, len = tds.length, td, tdName; i < len; ++i) {
td = tds[i];
tdName = td.getAttribute("name");
if (tdName && tdName.indexOf("tdName_") == 0) {
matchingTds.push(td);
}
}
With vanilla javascript you can use the querySelectorAll method:
document.querySelectorAll('[name^=tdName]')
This should work in all modern browsers, including IE9 or later (though I haven't tested it yet).
Not easy or probably possible with getElementsByClassName but you can put JQuery at rescue:
$('td[name=tdName_1]') // matches exactly 'tdName_1'
$('td[name^=tdName]') // matches those that begin with 'tdName'
Obviously, not. But you can use getElementsByTagName() and then filter by name:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head><title></title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<script type="text/javascript"><!--
function find(){
var inputs = document.getElementById("foo").getElementsByTagName("input");
var found = [];
for(var i=0, len=inputs.length; i<len; i++){
if(inputs[i].name.match(/^tdName_\d+$/)){
found.push(inputs[i]);
}
}
alert(found.length + " elements found");
}
//--></script>
</head>
<body>
<form action="" method="post" id="foo">
<input type="text" name="tdName_1">
<input type="text" name="tdName_2">
<input type="text" name="tdName_3">
<input type="text" name="not_me">
<input type="text" name="tdName_4">
<input type="text" name="neither_me">
<input type="text" name="tdName_5">
<input type="button" onclick="find()" value="Find">
</form>
</body>
</html>
AFAIK, getElementsByName requires a static string as an argument.
I don't know if you have any control over the elements, but you should probably give them the same name and use getElementsByName.
Another solution would be to loop through names and use getElementByName('tdName_' + i).
No, you would have to fetch all relevant elements - e.g. using getElementsByTagName - and loop through them until you find one or more elements that fit your criteria.
Maybe you can work around using getElementsByClassName and give every element you want to match a certain class? (Update, the native version is not availalable on SO, thanks Andy E. This is a very popular workaround implementation.)
You say you can't use JQuery and I'm sure you have a good reason for that, but stuff like this is what Frameworks are there for. Would Prototype or MooTools be an option?
As Tim Down said, the name attribute is not valid for <td> elements. It should still work if you decide to use it though. One option is to use a while loop, like this:
function getAllNamedTDs ()
{
var cTD, i=1, elArr = [];
// If an element with "tdName_"+i is not found, exit the loop
while (cTD = document.getElementByName("tdName_"+(i++)))
elArr.push(cTD);
// return the array of elements or null if no elements were found.
return elArr.length ? elArr : null;
}
Instead of using the name attribute, you should use the id attribute and then replace getElementByName with getElementById
put TWO (2) names on each element you want to find... make the first class name the same on every element and the second class name 'tdName_1' or 'tdName_2' (or whatever). Run document.getElementsByClassName on the class name common to all your elements... then loop through the array, do className.split(' ') to get an array where array[0] is the common name and array[1] is the differentiated name, and... do what you need to ...

Categories

Resources