eventlistener javascript problems - javascript

I'm trying to learn Javascript and at the moment and I am working on AddEventListener.
What I'm trying to do is to add a new row and so far it works.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<style>
.colorOrange {
background-color: orange;
}
.colorBlue {
background-color: blue;
}
.colorYellow {
background-color: yellow;
}
.colorGray {
background-color: gray;
}
.colorRed {
background-color: red;
}
.colorGreen {
background-color: green;
}
.colorWhite {
background-color: white;
}
#main {
margin: 0 auto;
width: 325px;
text-align: center;
background-color: gray;
}
.row {
width: 300px;
padding: 10px;
border: 1px solid black;
display: block;
}
.hideButton, .mainText, .deleteButton {
margin: 0 auto;
padding: 10px;
border: 1px solid black;
display: inline;
}
.btn {
}
</style>
</head>
<body>
<div id="main">
<div class="AddBtn btn">Add</div>
<input type="text" id="txtBox" name="text till ruta" />
</div>
<script>
var rownr = 0;
function addListeners() {
var addButton = document.getElementsByClassName('AddBtn');
for (var i = 0; i < addButton.length; i++) {
var addBtn = addButton[i];
addBtn.addEventListener('click', function () {
var elBtn = event.srcElement;
var valueBtn = elBtn.textContent;
alert(valueBtn);
hideOrShow();
addRow();
function addRow() {
switch (valueBtn) {
case "Add":
var input = document.getElementById('txtBox').value;
rownr++;
var div = document.createElement('div');
div.className = "row";
document.getElementById("main").appendChild(div);
var div2 = document.createElement('div');
div2.className = "hideButton colorGreen";
var tx = document.createTextNode("<");
div2.appendChild(tx);
div2.addEventListener('click', hideOrShow, false);
div.appendChild(div2);
var div3 = document.createElement("div");
if (input.toLowerCase() == "red") {
div3.className = "mainText colorRed";
}
else if (input.toLowerCase() == "orange") {
div3.className = "mainText colorOrange";
}
else if (input.toLowerCase() == "blue") {
div3.className = "mainText colorBlue";
}
else if (input.toLowerCase() == "yellow") {
div3.className = "mainText colorYellow";
}
else if (input.toLowerCase() == "gray") {
div3.className = "mainText colorGray";
} else {
div3.className = "mainText colorWhite";
}
tx = document.createTextNode(rownr + " " + input);
div3.appendChild(tx);
div.appendChild(div3);
var div4 = document.createElement("div");
div4.className = "deleteButton colorRed";
tx = document.createTextNode("X");
div4.appendChild(tx);
//div4.addEventListener('click', deleBtn, false);
div.appendChild(div4);
var linebreak = document.createElement("br");
div.appendChild(linebreak);
default:
}
}
So far everything works as I want it to do. But when I click on "<" it will go in to this function and find all tags with the hideButton class in it.
The first click it won't find anything, but the second time it will find the "<" value and an alert window will popup and show the value. Here is where I
get lost and can't get it to work. When you click the the third time it will
loop or whatever to call it - anyway it will show the alert window 2 times and
then if you repeat the same click it will do the same thing 3 times and so it goes.
function hideOrShow() {
var hideButton = document.getElementsByClassName('hideButton');
for (var j = 0; j < hideButton.length; j++) {
hideBtn = hideButton[j];
hideBtn.addEventListener('click', function () {
var hideElBtn = event.srcElement;
var valueHideBtn = hideElBtn.textContent;
alert(valueHideBtn);
}, false);
}
}
}, false);
}
}
window.onload = addListeners;
</script>
</body>
</html>
The goal with this exercise is that
when you click add button add the text from the input field and add that text to the new row.
and "<" shall hide the row and change it to ">" to show it again
and "X" shall just delete the row.
But what I need help with is finding the value part that I mentioned above.

Here is my rework of your javascript. I explained my solution in your comment, but it may be a bit more clear if illustrated.
In the addListeners function, I removed the hideOrShow call as it shouldn't be called in the add button.
Next, I removed the for loop in the hideOrShow method as you really are only after the caller. I also removed the addEventListener call in the same method as you already have an event listener on that element, so there's no need to add one again.
var rownr = 0;
function addListeners() {
var addButton = document.getElementsByClassName('AddBtn');
for (var i = 0; i < addButton.length; i++) {
var addBtn = addButton[i];
addBtn.addEventListener('click', function () {
var elBtn = event.srcElement;
var valueBtn = elBtn.textContent;
alert(valueBtn);
//hideOrShow();
addRow();
function addRow() {
switch (valueBtn) {
case "Add":
var input = document.getElementById('txtBox').value;
rownr++;
var div = document.createElement('div');
div.className = "row";
document.getElementById("main").appendChild(div);
var div2 = document.createElement('div');
div2.className = "hideButton colorGreen";
var tx = document.createTextNode("<");
div2.appendChild(tx);
div2.addEventListener('click', hideOrShow, false);
div.appendChild(div2);
var div3 = document.createElement("div");
if (input.toLowerCase() == "red") {
div3.className = "mainText colorRed";
}
else if (input.toLowerCase() == "orange") {
div3.className = "mainText colorOrange";
}
else if (input.toLowerCase() == "blue") {
div3.className = "mainText colorBlue";
}
else if (input.toLowerCase() == "yellow") {
div3.className = "mainText colorYellow";
}
else if (input.toLowerCase() == "gray") {
div3.className = "mainText colorGray";
} else {
div3.className = "mainText colorWhite";
}
tx = document.createTextNode(rownr + " " + input);
div3.appendChild(tx);
div.appendChild(div3);
var div4 = document.createElement("div");
div4.className = "deleteButton colorRed";
tx = document.createTextNode("X");
div4.appendChild(tx);
//div4.addEventListener('click', deleBtn, false);
div.appendChild(div4);
var linebreak = document.createElement("br");
div.appendChild(linebreak);
default:
}
}
function hideOrShow() {
var hideButton = document.getElementsByClassName('hideButton');
var hideElBtn = event.srcElement;
var valueHideBtn = hideElBtn.textContent;
alert(valueHideBtn);
}
}, false);
}
}
window.onload = addListeners;

Related

How to pass this and addEventListener to pickup item from a list and set it up on input field

I am working on a autocomplete feature and to populate in on a list currently the list is just showing the results but I can't select them to add it to the input element.
Here is a sample of the code:
var search_terms = ['a', 'b', 'c'];
function autocompleteMatch(input) {
if (input == '') {
return [];
}
var reg = new RegExp(input);
return search_terms.filter(function(term) {
if (term.match(reg)) {
return term;
}
});
}
function showResults(val) {
res = document.getElementById("result");
res.innerHTML = '';
let list = '';
let terms = autocompleteMatch(val);
for (i = 0; i < terms.length; i++) {
list += '<li>' + terms[i] + '</li>';
}
res.innerHTML = '<ul>' + list + '</ul>';
}
<input type="text" class="form-control" placeholder="Explain in fewer words with the primary product key word (Eg: OneDrive sync issue, etc.)" name="post" required id="id_post" onKeyUp="showResults(this.value)">
<span class="fas fa-asterisk" style="font-size:12px;color:red;position:absolute; right:20px;top:12px;" id="asterix"></span>
<div id="result"></div>
Any advice to add the elements on list to the input. I've search for similar suggestions but I couldn't apply the answers to my code.
Edit: In my case the solutions posted here were not working because the calling of the script
<script type="text/javascript" src="app.js" charset="utf-8"></script>
was at the top. So it was failing with a Uncaught TypeError: Cannot read property 'addEventListener' of null. After moving <script> section to the end of the <body> suggested answers started to work.
Is this how it should work. I added an event listener to res that tests id a <li> was clicked. If so, the innerHTML of the <li> is inserted as value in the <input>. Using the dispatchEvent() I update the list as if it was a keyup event.
var search_terms = ['abc', 'abcde', 'abde'];
var res = document.getElementById("result");
var id_post = document.getElementById("id_post");
function autocompleteMatch(input) {
if (input == '') {
return [];
}
var reg = new RegExp(input)
return search_terms.filter(function(term) {
if (term.match(reg)) {
return term;
}
});
}
function showResults(val) {
let terms = autocompleteMatch(val);
list = terms.map(term => `<li>${term}</li>`).join('');
res.innerHTML = '<ul>' + list + '</ul>';
}
res.addEventListener('click', e => {
if(e.target.nodeName == "LI"){
id_post.value = e.target.innerHTML;
id_post.dispatchEvent(new Event('keyup'));
}
});
<input type="text" class="form-control" placeholder="Explain in fewer words with the primary product key word (Eg: OneDrive sync issue, etc.)" name="post" required id="id_post" onKeyUp="showResults(this.value)">
<div id="result"></div>
Considering your original code there are some missing details like autocomplete function and keyboard events (up/down/enter).
1) HTML
// form (autocomplete off) disables autocomplete integration with external tools like 1password
<form autocomplete="off">
<div class="autocomplete" id="autocomplete-container">
<input id="autocomplete-input" type="text" placeholder="Type Something...">
</div>
<input type="submit">
</form>
2) List of possible options (to make it dynamic, load the list before binding it to the autocomplete method)
const data = ["Aaa", "Aab", "Aac", "Abc", "Bbc", "Bbd", "Xpto", "Item1", "Item2", "SomethingElse"];
3) Autocomplete Functionality
const autocomplete = (container, inputElement, list) => {
var currentFocus = -1;
inputElement.addEventListener('input', () => {
var autocompleteText = inputElement.value;
hideList();
if (!autocompleteText) {
return false;
}
const autocompleteList = document.createElement('div');
autocompleteList.setAttribute('id', 'autocomplete-list');
autocompleteList.setAttribute('class', 'autocomplete-items');
container.appendChild(autocompleteList);
list.forEach((item, index) => {
if (
item.substr(0, autocompleteText.length).toUpperCase() ===
autocompleteText.toUpperCase()
) {
const tempId = `hiddenInput_${index}`;
const text = item.substr(0, autocompleteText.length);
const autocompleteMatch = document.createElement('div');
autocompleteMatch.innerHTML = `<strong>${text}</strong>`;
autocompleteMatch.innerHTML += item.substr(autocompleteText.length);
autocompleteMatch.innerHTML += `<input type='hidden' id='${tempId}' value='${item}'>`;
autocompleteMatch.addEventListener('click', (event) => {
const clickedElement = event.target.getElementsByTagName('input')[0];
inputElement.value = clickedElement.value;
hideList();
});
autocompleteList.appendChild(autocompleteMatch);
}
});
});
inputElement.addEventListener('keydown', function (e) {
const autoCompleteList = document.getElementById('autocomplete-list');
var autoCompleteDiv;
if (autoCompleteList) {
autoCompleteDiv = autoCompleteList.getElementsByTagName('div');
}
if (e.keyCode === 40) {
// KEY DOWN
currentFocus++;
addActive(autoCompleteDiv);
} else if (e.keyCode === 38) {
// KEY UP
currentFocus--;
addActive(autoCompleteDiv);
} else if (e.keyCode === 13) {
// ENTER
e.preventDefault();
if (currentFocus > -1 && autoCompleteDiv) {
autoCompleteDiv[currentFocus].click();
}
}
});
const addActive = (item) => {
if (!item) {
return false;
}
removeActive(item);
if (currentFocus >= item.length) {
currentFocus = 0;
}
if (currentFocus < 0) {
currentFocus = item.length - 1;
}
item[currentFocus].classList.add('autocomplete-active');
};
const removeActive = (autoCompleteItems) => {
Array.from(autoCompleteItems).forEach((item) => {
item.classList.remove('autocomplete-active');
});
};
const hideList = (element) => {
var autoCompleteItems =
document.getElementsByClassName('autocomplete-items');
if (autoCompleteItems && autoCompleteItems.length > 0) {
Array.from(autoCompleteItems).forEach((item) => {
if (element !== item && element !== inputElement) {
item.parentNode.removeChild(item);
}
});
}
};
document.addEventListener('click', (event) => hideList(event.target));
};
// this part binds the autocomplete with the HTML
window.addEventListener('load', function () {
const container = document.getElementById('autocomplete-container');
const inputElement = document.getElementById('autocomplete-input');
autocomplete(container, inputElement, data);
});
CSS
* { box-sizing: border-box; }
body {
font: 16px Arial;
}
.autocomplete {
display: inline-block;
position: relative;
width: 300px;
}
input {
border: 1px solid transparent;
background-color: #f1f1f1;
padding: 10px;
font-size: 16px;
}
input[type=text] {
background-color: #f1f1f1;
width: 100%;
}
input[type=submit] {
background-color: DodgerBlue;
color: #fff;
}
.autocomplete-items {
position: absolute;
border: 1px solid #d4d4d4;
border-bottom: none;
border-top: none;
z-index: 99;
top: 100%;
left: 0;
right: 0;
}
.autocomplete-items div {
padding: 10px;
cursor: pointer;
background-color: #fff;
border-bottom: 1px solid #d4d4d4;
}
.autocomplete-items div:hover {
background-color: #e9e9e9;
}
.autocomplete-active {
background-color: DodgerBlue !important;
color: #ffffff;
}
Based on W3School - How TO - Autocomplete
Live Version - Codesandbox
Try This Code
var searchTerms = ["OneDrive sync issue", "Abcde", "123456"];
var result = document.getElementById("result");
rul = document.createElement("ul");
result.appendChild(rul);
rul.classList.add("datalist");
for(var x = 0; x < searchTerms.length; x++ ){
rli = document.createElement("li");
rul.appendChild(rli);
rli.innerHTML = searchTerms[x];
rli.classList.add("d-none");
rli.addEventListener("click", function(){
document.getElementById("id_post").value = this.innerHTML;
this.classList.add("d-none");
});
}
function showResults(v){
var ListItems = rul.querySelectorAll("li");
for(var i = 0; i < ListItems.length; i++){
var c = ListItems[i].innerHTML.toLowerCase();
v = v.toLowerCase();
if(c.indexOf(v) > -1 && v !== ""){
ListItems[i].classList.remove("d-none");
}
else{
ListItems[i].classList.add("d-none");
}
}
}
.d-none{ display:none; }
.datalist li{ cursor:pointer; }
<input
type="text"
class="form-control"
placeholder="Explain in fewer words with the primary product key word (Eg: OneDrive sync issue, etc.)"
name="post"
required
id="id_post"
onKeyUp="showResults(this.value)">
<span
class="fas fa-asterisk"
style="font-size:12px;color:red;position:absolute; right:20px;top:12px;"
id="asterix"></span>
<div id="result"></div>

Getting different id for 24 buttons, made with a for loop

I have made 24 buttons with a for loop, and want button from number 1 to 24 to give a message like this.
"you clicked on button 1"
"you clicked on button 2" and so on.
I have been able to split the 3 first buttons so they say "button 1" "2" "3", but that is done by 3 if statements, which means i would need 23-24 ish if statements to get them all to do as I want. That's not a very efficient way to do it.
Is there a good way to get the button id to add +1 after "knapp" every time the loop runs ? something like this element.id = "knapp" + 1; < so the id become knapp1, knapp2, knapp3 as the loop keep running 24 times ?
html:
<!DOCTYPE html>
<meta charset="utf-8">
<html>
<head>
<script src="Assignment06.js"></script>
<style>
h1 {
text-align: center;
}
div {
background-color: forestgreen;
border: solid 1px #000;
display: inline-block;
width: 100px;
height: 100px;
padding: 10px
}
#panel {
width: 610px;
margin: 0 auto;
}
</style>
</head>
<body>
<h1>Assignment06</h1>
<p id = "panel"></p>
</body>
</html>
Javascript:
function dag(){
knapp = window.alert("Du trykket knapp 1");
}
function dag2(){
window.alert("Du trykket knapp 2");
}
function dag3(){
window.alert("Du trykket knapp 3");
}
function init(){
knapper();
}
function knapper(){
for (var antall = 1; antall <= 24; antall++){
if(antall == 1){
var element = document.createElement("div");
element.innerHTML = antall;
element.id = "knapp";
knapp = element.addEventListener("click", dag);
element.type = "div";
var panel = document.getElementById("panel");
panel.appendChild(element);
}
else if (antall == 2){
var element = document.createElement("div");
element.innerHTML = antall;
element.id = "knapp2";
knapp2 = element.addEventListener("click", dag2);
element.type = "div";
var panel = document.getElementById("panel");
panel.appendChild(element);
}
else{
var element = document.createElement("div");
element.innerHTML = antall;
element.id = "knapp3";
knapp3 = element.addEventListener("click", dag3);
element.type = "div";
var panel = document.getElementById("panel");
panel.appendChild(element);
}
}
}
window.onload = init;
You can save the id in the dataset of the <div /> element.
function knapper() {
var panel = document.getElementById("panel");
for (var antall = 1; antall <= 10; antall++) {
var element = document.createElement("div");
element.innerHTML = antall;
element.dataset.id = antall;
element.addEventListener("click", dag);
panel.appendChild(element);
}
}
function dag(evt) {
alert(evt.target.dataset.id);
}
window.onload = knapper;
#panel div {
width: 50px;
height: 50px;
border: solid 1px black;
float: left;
}
<div id="panel"></div>
To directly answer your question without suggestions:
You already have a counter in the for loop (antall). You can just use that variable and concatenate it on the end of the string that you're using as an id.
element.id = "knapp" + antall;

.hover() seems to overwrite .click()

A little background of my problem:
I'm making a board-based game when the user is going to be able to make a path from a square to another one, the thing is that when a square is clicked it should stay highlighted no matter if pointer is over of it and then leaves it. It seems when the square is clicked and then the pointer leaves it the handlerIn of .hover() changes the state of the square's path-type attribute making possible to the square to be unhighlited when the pointer enter and leaves the square.
this is what I've got so far:
$(function() {
$('td.soccer-field').click(function(){
if ($('#dice1').text() != '' && $('#dice2').text() != '') {
if ($("[path-type='begin-path']").length == 0) {
$(this).attr('path-type','begin-path');
} else if ($("[path-type='begin-path']").length && $(this).attr('path-type') != 'end-path'){
$(this).attr('path-type','end-path');
$('[path-type="selecting-actual-path"]').attr('path-type','actual-path');
} else if ($(this).attr('path-type') == 'end-path'){
$(this).attr('path-type','');
};
}
});
$('td.soccer-field').hover(
function () {
if ($('#dice1').text() != '' && $('#dice2').text() != '') {
if ($("[path-type='begin-path']").length == 0) {
$(this).attr('path-type','select-begin-path');
} else if ($(this).attr('path-type') == ''){
var actualCell = $(this).attr('id') + $(this).parent().attr('id');
var cell, distance,dicesResult = parseInt($('#dice1').text())+ parseInt($('#dice2').text());
$("[path-type*='path']").each(function () {
cell = $(this).attr('id') + $(this).parent().attr('id');
distance = new Board().calculateDistanceSquares(actualCell,cell);
if (distance == 1 && $("[path-type='selecting-actual-path']").length < (dicesResult -2))
{
$(this).attr('path-type','selecting-actual-path');
return false;
}
});
}
};
},function () {
if ($(this).attr('path-type') == 'selecting-actual-path' || $(this).attr('path-type') == 'select-begin-path') {
$(this).attr('path-type','');
}
});
$('#diceRoller').click(function() {
$('#dice1').text(Math.floor(Math.random()*6)+1);
$('#dice2').text(Math.floor(Math.random()*6)+1);
$(this).attr('disabled',true);
});
});
//function Board(playerTurn, piecesPosition, gamePhase, gameBegginingType, container)
function Board(){
this.buildBoard = function (container) {
var board = $('<table></table>').attr('id','board');
var row, cell,containerHeight,containerWidth;
for (var i=0; i<10; i++){
row = $('<tr></tr>').attr('id',i+1);
for (var j=0; j<20; j++){
cell = $('<td></td>');
cell.attr('path-type','');
if ((j == 0 || j == 19) && (i >= 3) && (i <= 6)) {
cell.addClass('behind-goal');
}
else if ((j > 0) && (j < 19)){
cell.attr('id',String.fromCharCode(j+96));
cell.addClass("soccer-field");
};
row.append(cell);
}
board.append(row);
}
$('#'+container).append(board);
};
this.calculateHorizontalDistance = function (sq1,sq2) {
var column1 = sq1.substring(0,1).charCodeAt(0);
var column2 = sq2.substring(0,1).charCodeAt(0);
return ( Math.abs(column1-column2) );
};
this.calculateVerticalDistance = function (sq1, sq2) {
var row1 = parseInt(sq1.substring(1));
var row2 = parseInt(sq1.substring(1));
return ( Math.abs(row1-row2) );
};
this.calculateDistanceSquares = function(sq1, sq2){
return(this.calculateVerticalDistance(sq1,sq2)+this.calculateHorizontalDistance(sq1,sq2));
}
}
var board = new Board();
board.buildBoard('left');
#left table{
width: 60em;
height: 25em;
border:0.2em solid black;
border-collapse:collapse;
}
#left table tr{
height: 2.5em;
}
#left table tr td{
width: 3.33em;
}
td.soccer-field{
border: 0.1em solid black;
}
td.behind-goal{
background-color: #F8FAB4;
}
td[path-type*="path"]{
border: 0.15em solid #F8FAB4;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="boardContainer">
<div id="right">
<p id="dice1"></p><p id="dice2"></p>
<button id="diceRoller">Lanzar Dados</button>
</div>
<div id="left"></div>
</div>
A little help will be really appreciate
To prevent that you can add an attribute on the element whenever it is clicked and remove it later on second click. Now in the hover handler check for this attribute on the element, if it is present(or set) then don't do anything just return from the handler.
Something like this
$('td.soccer-field').click(function(){
$(this).data('clicked', !!$(this).data('clicked'));
...
...
});
$('td.soccer-field').hover(
function () {
if ($(this).data('clicked')) return;
...
...
},
function () {
if ($(this).data('clicked')) return;
...
...
});

Dynamically create buttons based on input values from XML response

Alright, so I have been killing myself over this for a while now. I simply want to take an XML response containing names from my arduino and then dynamically create buttons. Each button needs to say the name and have the name as its id for the GetDrink function to use to send back to the arduino. If anyone can give me some help, maybe some code to work off of it would be appreciated.
I am able to have a button call the CreateButton function to create more buttons which all work. But I need to dynamically create the buttons off of the XML response. Also, this has to be done strictly using JavaScript and HTML.
<!DOCTYPE html>
<html>
<head>
<title>The AutoBar</title>
<script>
// Drinks
strDRINK1 = "";
function GetArduinoIO()
{
nocache = "&nocache=" + Math.random() * 1000000;
var request = new XMLHttpRequest();
request.onreadystatechange = function()
{
if (this.readyState == 4) {
if (this.status == 200) {
if (this.responseXML != null) {
var count;
var num_an = this.responseXML.getElementsByTagName('alcohol').length;
for (count = 0; count < num_an; count++) {
document.getElementsByClassName("AlcStatus")[count].innerHTML =
this.responseXML.getElementsByTagName('alcohol')[count].childNodes[0].nodeValue;
}
}
}
}
}
request.open("GET", "ajax_inputs" + strDRINK1 + nocache, true);
request.send(null);
setTimeout('GetArduinoIO()', 1000);**strong text**
strDRINK1 = "";
}
function GetDrink(clicked_id)
{
strDRINK1 = "&" + clicked_id;
document.getElementById("AlcStatus").innerHTML = "Your " + clicked_id + " is being made";
}
function CreateButton(Drink_Name)
{
myButton = document.createElement("input");
myButton.type = "button";
myButton.value = Drink_Name;
placeHolder = document.getElementById("button");
placeHolder.appendChild(myButton);
myButton.id = Drink_Name;
myButton.onclick = function()
{
strDRINK1 = "&" + myButton.id;
document.getElementById("AlcStatus").innerHTML = "Your " + myButton.id + " is being made";
}
}
</script>
<style>
.IO_box {
float: left;
margin: 0 20px 20px 0;
border: 1px solid blue;
padding: 0 5px 0 5px;
width: 320px;
}
h1 {
font-size: 320%;
color: blue;
margin: 0 0 10px 0;
}
h2 {
font-size: 200%;
color: #5734E6;
margin: 5px 0 5px 0;
}
p, form, button {
font-size: 180%;
color: #252525;
}
.small_text {
font-size: 70%;
color: #737373;
}
</style>
</head>
<body onload="GetArduinoIO()" BGCOLOR="#F5F6CE">
<p> <center><img src="pic.jpg" /></center><p>
<div class="IO_box">
<div id="button"></div>
</div>
<div class="IO_box">
<h2><span class="AlcStatus">...</span></h2>
</div>
<div>
<button onclick="location.href='Edit_Bar.htm'">Edit Bar Menu</button>
<div>
</body>
</html>
Something like this?
var xml = "<items><alcohol>Bourbon</alcohol><alcohol>Gin</alcohol><alcohol>Whiskey</alcohol></items>";
var parser = new DOMParser();
var dom = parser.parseFromString(xml, "text/xml");
var alcohol = dom.querySelectorAll('alcohol');
function getDrink(event) {
alert(event.target.value);
}
function makeButton(value) {
var b = document.createElement('button');
b.innerHTML = value;
b.value = value;
b.id = value;
b.addEventListener('click', getDrink);
return b;
}
var list = document.getElementById('buttons');
for(var i = 0; i < alcohol.length; i++ ) {
var b = makeButton(alcohol[i].firstChild.nodeValue);
var li = document.createElement('li');
li.appendChild(b);
list.appendChild(li);
}
<ul id="buttons"></ul>

how to generate tinymce to ajax generated textarea

I have an image multi-uploader script which also each item uploaded was preview 1st before it submitted and each images has its following textarea which are also generated by JavaScript. I want to use the tinymce editor to each textarea generated by the ajax.
Here is my script:
function fileQueueError(file, errorCode, message) {
try {
var imageName = "error.gif";
var errorName = "";
if (errorCode === SWFUpload.errorCode_QUEUE_LIMIT_EXCEEDED) {
errorName = "You have attempted to queue too many files.";
}
if (errorName !== "") {
alert(errorName);
return;
}
switch (errorCode) {
case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE:
imageName = "zerobyte.gif";
break;
case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT:
imageName = "toobig.gif";
break;
case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE:
case SWFUpload.QUEUE_ERROR.INVALID_FILETYPE:
default:
alert(message);
break;
}
addImage("images/" + imageName);
} catch (ex) {
this.debug(ex);
}
}
function fileDialogComplete(numFilesSelected, numFilesQueued) {
try {
if (numFilesQueued > 0) {
this.startUpload();
}
} catch (ex) {
this.debug(ex);
}
}
function uploadProgress(file, bytesLoaded) {
try {
var percent = Math.ceil((bytesLoaded / file.size) * 100);
var progress = new FileProgress(file, this.customSettings.upload_target);
progress.setProgress(percent);
if (percent === 100) {
progress.setStatus("Creating thumbnail...");
progress.toggleCancel(false, this);
} else {
progress.setStatus("Uploading...");
progress.toggleCancel(true, this);
}
} catch (ex) {
this.debug(ex);
}
}
function uploadSuccess(file, serverData) {
try {
var progress = new FileProgress(file, this.customSettings.upload_target);
if (serverData.substring(0, 7) === "FILEID:") {
addRow("tableID","thumbnail.php?id=" + serverData.substring(7),file.name);
//setup();
//generateTinyMCE('itemdescription[]');
progress.setStatus("Thumbnail Created.");
progress.toggleCancel(false);
} else {
addImage("images/error.gif");
progress.setStatus("Error.");
progress.toggleCancel(false);
alert(serverData);
}
} catch (ex) {
this.debug(ex);
}
}
function uploadComplete(file) {
try {
/* I want the next upload to continue automatically so I'll call startUpload here */
if (this.getStats().files_queued > 0) {
this.startUpload();
} else {
var progress = new FileProgress(file, this.customSettings.upload_target);
progress.setComplete();
progress.setStatus("All images received.");
progress.toggleCancel(false);
}
} catch (ex) {
this.debug(ex);
}
}
function uploadError(file, errorCode, message) {
var imageName = "error.gif";
var progress;
try {
switch (errorCode) {
case SWFUpload.UPLOAD_ERROR.FILE_CANCELLED:
try {
progress = new FileProgress(file, this.customSettings.upload_target);
progress.setCancelled();
progress.setStatus("Cancelled");
progress.toggleCancel(false);
}
catch (ex1) {
this.debug(ex1);
}
break;
case SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED:
try {
progress = new FileProgress(file, this.customSettings.upload_target);
progress.setCancelled();
progress.setStatus("Stopped");
progress.toggleCancel(true);
}
catch (ex2) {
this.debug(ex2);
}
case SWFUpload.UPLOAD_ERROR.UPLOAD_LIMIT_EXCEEDED:
imageName = "uploadlimit.gif";
break;
default:
alert(message);
break;
}
addImage("images/" + imageName);
} catch (ex3) {
this.debug(ex3);
}
}
function addRow(tableID,src,filename)
{
var table = document.getElementById(tableID);
var rowCount = table.rows.length;
var row = table.insertRow(rowCount);
rowCount + 1;
row.id = "row"+rowCount;
var cell0 = row.insertCell(0);
cell0.innerHTML = rowCount;
cell0.style.background = "#FFFFFF";
var cell1 = row.insertCell(1);
cell1.align = "center";
cell1.style.background = "#FFFFFF";
var imahe = document.createElement("img");
imahe.setAttribute("src",src);
var hidden = document.createElement("input");
hidden.setAttribute("type","hidden");
hidden.setAttribute("name","filename[]");
hidden.setAttribute("value",filename);
/*var hidden2 = document.createElement("input");
hidden2.setAttribute("type","hidden");
hidden2.setAttribute("name","filename[]");
hidden2.setAttribute("value",filename);
cell1.appendChild(hidden2);*/
cell1.appendChild(hidden);
cell1.appendChild(imahe);
var cell2 = row.insertCell(2);
cell2.align = "left";
cell2.valign = "top";
cell2.style.background = "#FFFFFF";
//tr1.appendChild(td1);
var div2 = document.createElement("div");
div2.style.padding ="0 0 0 10px";
div2.style.width = "400px";
var alink = document.createElement("a");
//alink.style.margin="40px 0 0 0";
alink.href ="#";
alink.innerHTML ="Cancel";
alink.onclick= function () {
document.getElementById(row.id).style.display='none';
document.getElementById(textfield.id).disabled='disabled';
};
var div = document.createElement("div");
div.style.margin="10px 0";
div.appendChild(alink);
var textfield = document.createElement("input");
textfield.id = "file"+rowCount;
textfield.type = "text";
textfield.name = "itemname[]";
textfield.style.margin = "10px 0";
textfield.style.width = "400px";
textfield.value = "Item Name";
textfield.onclick= function(){
//textfield.value="";
if(textfield.value=="Item Name")
textfield.value="";
if(desc.innerHTML=="")
desc.innerHTML ="Item Description";
if(price.value=="")
price.value="Item Price";
}
var desc = document.createElement("textarea");
desc.name = "itemdescription[]";
desc.cols = "80";
desc.rows = "4";
desc.innerHTML = "Item Description";
desc.onclick = function(){
if(desc.innerHTML== "Item Description")
desc.innerHTML = "";
if(textfield.value=="Item name" || textfield.value=="")
textfield.value="Item Name";
if(price.value=="")
price.value="Item Price";
}
var price = document.createElement("input");
price.id = "file"+rowCount;
price.type = "text";
price.name = "itemprice[]";
price.style.margin = "10px 0";
price.style.width = "400px";
price.value = "Item Price";
price.onclick= function(){
if(price.value=="Item Price")
price.value="";
if(desc.innerHTML=="")
desc.innerHTML ="Item Description";
if(textfield.value=="")
textfield.value="Item Name";
}
var span = document.createElement("span");
span.innerHTML = "View";
span.style.width = "auto";
span.style.padding = "10px 0";
var view = document.createElement("input");
view.id = "file"+rowCount;
view.type = "checkbox";
view.name = "publicview[]";
view.value = "y";
view.checked = "checked";
var div3 = document.createElement("div");
div3.appendChild(span);
div3.appendChild(view);
var div4 = document.createElement("div");
div4.style.padding = "10px 0";
var span2 = document.createElement("span");
span2.innerHTML = "Default Display";
span2.style.width = "auto";
span2.style.padding = "10px 0";
var radio = document.createElement("input");
radio.type = "radio";
radio.name = "setdefault";
radio.value = "y";
div4.appendChild(span2);
div4.appendChild(radio);
div2.appendChild(div);
//div2.appendChild(label);
//div2.appendChild(table);
div2.appendChild(textfield);
div2.appendChild(desc);
div2.appendChild(price);
div2.appendChild(div3);
div2.appendChild(div4);
cell2.appendChild(div2);
}
function addImage(src,val_id) {
var newImg = document.createElement("img");
newImg.style.margin = "5px 50px 5px 5px";
newImg.style.display= "inline";
newImg.id=val_id;
document.getElementById("thumbnails").appendChild(newImg);
if (newImg.filters) {
try {
newImg.filters.item("DXImageTransform.Microsoft.Alpha").opacity = 0;
} catch (e) {
// If it is not set initially, the browser will throw an error. This will set it if it is not set yet.
newImg.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity=' + 0 + ')';
}
} else {
newImg.style.opacity = 0;
}
newImg.onload = function () {
fadeIn(newImg, 0);
};
newImg.src = src;
}
function fadeIn(element, opacity) {
var reduceOpacityBy = 5;
var rate = 30; // 15 fps
if (opacity < 100) {
opacity += reduceOpacityBy;
if (opacity > 100) {
opacity = 100;
}
if (element.filters) {
try {
element.filters.item("DXImageTransform.Microsoft.Alpha").opacity = opacity;
} catch (e) {
// If it is not set initially, the browser will throw an error. This will set it if it is not set yet.
element.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity=' + opacity + ')';
}
} else {
element.style.opacity = opacity / 100;
}
}
if (opacity < 100) {
setTimeout(function () {
fadeIn(element, opacity);
}, rate);
}
}
/* ******************************************
* FileProgress Object
* Control object for displaying file info
* ****************************************** */
function FileProgress(file, targetID) {
this.fileProgressID = "divFileProgress";
this.fileProgressWrapper = document.getElementById(this.fileProgressID);
if (!this.fileProgressWrapper) {
this.fileProgressWrapper = document.createElement("div");
this.fileProgressWrapper.className = "progressWrapper";
this.fileProgressWrapper.id = this.fileProgressID;
this.fileProgressElement = document.createElement("div");
this.fileProgressElement.className = "progressContainer";
var progressCancel = document.createElement("a");
progressCancel.className = "progressCancel";
progressCancel.href = "#";
progressCancel.style.visibility = "hidden";
progressCancel.appendChild(document.createTextNode(" "));
var progressText = document.createElement("div");
progressText.className = "progressName";
progressText.appendChild(document.createTextNode(file.name));
var progressBar = document.createElement("div");
progressBar.className = "progressBarInProgress";
var progressStatus = document.createElement("div");
progressStatus.className = "progressBarStatus";
progressStatus.innerHTML = " ";
this.fileProgressElement.appendChild(progressCancel);
this.fileProgressElement.appendChild(progressText);
this.fileProgressElement.appendChild(progressStatus);
this.fileProgressElement.appendChild(progressBar);
this.fileProgressWrapper.appendChild(this.fileProgressElement);
document.getElementById(targetID).appendChild(this.fileProgressWrapper);
fadeIn(this.fileProgressWrapper, 0);
} else {
this.fileProgressElement = this.fileProgressWrapper.firstChild;
this.fileProgressElement.childNodes[1].firstChild.nodeValue = file.name;
}
this.height = this.fileProgressWrapper.offsetHeight;
}
FileProgress.prototype.setProgress = function (percentage) {
this.fileProgressElement.className = "progressContainer green";
this.fileProgressElement.childNodes[3].className = "progressBarInProgress";
this.fileProgressElement.childNodes[3].style.width = percentage + "%";
};
FileProgress.prototype.setComplete = function () {
this.fileProgressElement.className = "progressContainer blue";
this.fileProgressElement.childNodes[3].className = "progressBarComplete";
this.fileProgressElement.childNodes[3].style.width = "";
};
FileProgress.prototype.setError = function () {
this.fileProgressElement.className = "progressContainer red";
this.fileProgressElement.childNodes[3].className = "progressBarError";
this.fileProgressElement.childNodes[3].style.width = "";
};
FileProgress.prototype.setCancelled = function () {
this.fileProgressElement.className = "progressContainer";
this.fileProgressElement.childNodes[3].className = "progressBarError";
this.fileProgressElement.childNodes[3].style.width = "";
};
FileProgress.prototype.setStatus = function (status) {
this.fileProgressElement.childNodes[2].innerHTML = status;
};
FileProgress.prototype.toggleCancel = function (show, swfuploadInstance) {
this.fileProgressElement.childNodes[0].style.visibility = show ? "visible" : "hidden";
if (swfuploadInstance) {
var fileID = this.fileProgressID;
this.fileProgressElement.childNodes[0].onclick = function () {
swfuploadInstance.cancelUpload(fileID);
return false;
};
}
};
I am using a swfuploader and I just added a input fields and a textarea when it preview the images which ready to be uploaded.
And from my HTML I have this script:
<script type="text/javascript">
var swfu;
window.onload = function () {
swfu = new SWFUpload({
// Backend Settings
upload_url: "../we_modules/upload.php", // Relative to the SWF file or absolute
post_params: {"PHPSESSID": "<?php echo session_id(); ?>"},
// File Upload Settings
file_size_limit : "20 MB", // 2MB
file_types : "*.*",
//file_types : "",
file_types_description : "jpg",
file_upload_limit : "0",
file_queue_limit : "0",
// Event Handler Settings - these functions as defined in Handlers.js
// The handlers are not part of SWFUpload but are part of my website and control how
// my website reacts to the SWFUpload events.
//file_queued_handler : fileQueued,
file_queue_error_handler : fileQueueError,
file_dialog_complete_handler : fileDialogComplete,
upload_progress_handler : uploadProgress,
upload_error_handler : uploadError,
upload_success_handler : uploadSuccess,
upload_complete_handler : uploadComplete,
// Button Settings
button_image_url : "../we_modules/images/SmallSpyGlassWithTransperancy_17x18.png", // Relative to the SWF file
button_placeholder_id : "spanButtonPlaceholder",
button_width: 180,
button_height: 18,
button_text : '<span class="button">Select Files<span class="buttonSmall">(2 MB Max)</span></span>',
button_text_style : '.button { font-family: Helvetica, Arial, sans-serif; font-size: 12pt;cursor:pointer } .buttonSmall { font-size: 10pt; }',
button_text_top_padding: 0,
button_text_left_padding: 18,
button_window_mode: SWFUpload.WINDOW_MODE.TRANSPARENT,
button_cursor: SWFUpload.CURSOR.HAND,
// Flash Settings
flash_url : "../swfupload/swfupload.swf",
custom_settings : {
upload_target : "divFileProgressContainer"
},
// Debug Settings
debug: false
});
};
</script>
Where should I put on the tinymce function as you mention below?
Taken directly from the TinyMCE documentation:
<script type="text/javascript" src="<your installation path>/tiny_mce/tiny_mce.js"></script>
<script type="text/javascript">
tinyMCE.init({
mode : "textareas",
theme : "simple"
});
</script>
<form method="post" action="somepage">
<textarea name="content" style="width:100%">
</textarea>
</form>
Please read the documentation for basic questions like this.
If you get stuck or need help after you've done that, provide a clear explanation of your problem (and sample code if possible) so that we can help you.
Edit:
Alright, I've attempted a solution to the problem. The following code loads 20 images and textareas dynamically and then turns the textareas into TinyMCE editors (I hope you don't mind the jQuery):
<html>
<head>
<script src="TinyMCE/jscripts/tiny_mce/tiny_mce.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<style>
img { height: 100px; display: block;}
li { border: 1px solid black; margin: 1em; padding: 1em; }
#message { position: fixed; top: 0; left: 50%; margin-left: -100px; width: 200px; text-align: center; background-color: white; border: 1px solid black;}
</style>
</head>
<body>
<ul>
</ul>
<div id="message">Loading...</div>
<script>
$(function(){
var numImages = 20;
for (var i = 0; i < numImages; i++) {
// Create an img element with a random image
var img = $('<img />').attr('src', randomXKCD);
// Attach a callback to the image's load event
img.load(function(){
numImages--;
if (numImages === 0) {
// When all the images have loaded,
// turn the textareas into tinyMCE editors
tinyMCE.init({
mode: 'textareas',
theme: 'simple',
oninit: function(){$('#message').hide()}
});
}
});
// Add the image and a textarea to the document.
$('ul').append(
$('<li />')
.append(img)
.append('<textarea />')
);
}
// helper function to get a random image.
function randomXKCD() {
var xkcds = [
'http://imgs.xkcd.com/comics/barrel_mommies.jpg',
'http://imgs.xkcd.com/comics/su_doku.jpg',
'http://imgs.xkcd.com/comics/linux_user_at_best_buy.png',
'http://imgs.xkcd.com/comics/commented.png',
'http://imgs.xkcd.com/comics/typewriter.png',
'http://imgs.xkcd.com/comics/pirate_bay.png',
'http://imgs.xkcd.com/comics/quirky_girls.png',
'http://imgs.xkcd.com/comics/firefly.jpg',
'http://imgs.xkcd.com/comics/kepler.jpg',
'http://imgs.xkcd.com/comics/centrifugal_force.png',
'http://imgs.xkcd.com/comics/trebuchet.png',
'http://imgs.xkcd.com/comics/egg_drop_failure.png',
'http://imgs.xkcd.com/comics/too_old_for_this_shit.png',
'http://imgs.xkcd.com/comics/2008_christmas_special.png',
'http://imgs.xkcd.com/comics/braille.png',
'http://imgs.xkcd.com/comics/impostor.png',
'http://imgs.xkcd.com/comics/not_enough_work.png'
];
return xkcds[Math.floor(Math.random() * xkcds.length)];
}
});
</script>
</body>
</html>

Categories

Resources