how to add a variable inside a string with jquery - javascript

I'm appending some html into a list, but having trouble passing the selected_files.name value into the function. Please see the onclick below
for (var i = 0; i < selected_files.length; ++i) {
children += '<div class="del" onclick="javascript:removeImageFromList(selected_files[i].name)">X</div>' + selected_files[i].name + '<br>';
}
What is the proper way to pass this in? When I log from inside the removeImageFromList function it is receiving a selected_files[i].name as a string rather than the value.

You can use template string. It would be easy to read and You can get rid to remember where to add + and "".
Just for example I've simulated selected_files as an array with name property.
const selected_files = [{ name: "first"}, {name: "second"}];
let children = "";
for (var i = 0; i < selected_files.length; ++i) {
children += `<div class="del" onclick="javascript:removeImageFromList(${selected_files[i].name})">X</div>${selected_files[i].name}<br>`;
}
console.log( children );

To pass the value contained in the object, you need to do what you did later in the string:
children += '<div class="del" onclick="javascript:removeImageFromList(' + selected_files[i].name + ')">X</div>' + selected_files[i].name + '<br>';

please try the below code snippet
var selected_files=[{name:'abc'}, {name:'xyz'}]
var children='';
for (var i = 0; i < selected_files.length; ++i) {
children += '<div class="del" onclick="javascript:removeImageFromList(\''+selected_files[i].name+'\')">X</div>' + selected_files[i].name + '<br>';
}
console.log('children--->',children);

You just need to move your function-call-variable outside the string like you already did at the end.
Like this:
for (var i = 0; i < selected_files.length; ++i) {
children += '<div class="del" onclick="javascript:+removeImageFromList('+selected_files[i].name)+'">X</div>' + selected_files[i].name + '<br>';
}

Your code has two problems:
you are appending html (a div) as a string, which is prone to spelling errors. your editor won't correct strings but it will correct javascript.
you are actually adding javascript inside that string. I would say that is a definite no-no in code land....
You can solve this problem by creating DOM elements the javascript way. Then you can add an eventListener to respond to mouse clicks.
let selected_files = [{name:"henk"},{name:"wim"}]
for (let i = 0; i < selected_files.length; i++) {
let div = document.createElement("div")
div.classList.add("del")
div.innerText = selected_files[i].name
div.addEventListener("click", ()=>{
removeImageFromList(selected_files[i].name)
})
document.body.appendChild(div)
}
function removeImageFromList(str){
console.log(str)
}

Related

Bad html formatting with jQuery.html()

I have something that I can't understand and i'm struggling with that for 2 days.
For the story, I'm using VICOPO api to get zipcode/city (France only I think).
The thing is that the code I'm generating is not really good interpreted by jQuery (or maybe I'm doing it wrong)
Here is the code:
$('#postcode').val($('#postcode').val().toUpperCase());
if ($('#postcode').val().length == 5)
{
var $ville = $('#postcode');
$.vicopo($ville.val(), function (input, cities) {
if(input == $ville.val() && cities[0]) {
if (cities.length == 1)
$('#city').val(cities[0].city);
else
{
var html = '';
html += '<div style=\'text-align:center\'>';
for (var i=0; i<cities.length; i++)
{
var v = cities[i].city;
// --- HERE IS MY PROBLEM ---
html += '<p onclick=\'alert(\'' + v + '\');\'>' + v + '</p>';
}
html += '</div>';
console.log(html);
$('#multi_ville').html(html);
}
}
});
When I inspect the elements in the multi_div this is what I get:
<p onclick="alert(" billey');'>BILLEY</p>
<p onclick="alert(" flagey-les-auxonne');'>FLAGEY-LES-AUXONNE</p>
etc ....
And when I inspect the console log, all looks correct:
<p onclick='alert('BILLEY');'>BILLEY</p>
<p onclick='alert('FLAGEY-LES-AUXONNE');'>FLAGEY-LES-AUXONNE</p>
<p onclick='alert('VILLERS-LES-POTS');'>VILLERS-LES-POTS</p>
etc ....
If someone have an idea or what I'm doing wrong, it would cool.
(may I mention, this code is in a smarty tpl file surrounded with the {literal} tag)
Try to create self closed tags via jquery and then append them to #multi_ville, here is an example:
// create div element
var div = $('<div/>', {
'style' : 'text-align:center'
});
for (var i=0; i<cities.length; i++)
{
var v = cities[i].city;
// create p element with click event and then append it to div
$('<p/>').on('click', function() {
alert(v);
}).text(v).appendTo(div);
}
$('#multi_ville').append(div);
EDIT It seems that my code above always alert the last city when we click on a element, that's because alert takes the value that v variable has at the time it runs, to solve this we can use let statement:
let v = cities[i].city;
Or a function:
for (var i=0; i<cities.length; i++) {
var v = cities[i];
createPTag(v, div);
}
function createPTag(v, div) {
$('<p/>').on('click', function() {
alert(v);
}).text(v).appendTo(div);
}
Instead of
html += '<p onclick=\'alert(\'' + v + '\');\'>' + v + '</p>';
try this:
html += '<p onclick="alert(\'' + v + '\');">' + v + '</p>';
Here's some info on when and how to use double/single quotes.
EDIT:
Also, check the else on this if statement:
if (cities.length == 1)
You need a closing curly bracket (}) to close in the else. It should be added directly after this line:
$('#multi_ville').html(html);

print array of object in javascript and print in html tags

i am using storelocater.js for multiple location in google map and show the information according to the location with image. i can show only one image but i want to show multiple images inside the information panel. link this
Here is my code
var panelDiv = document.getElementById('panel');
storeLocator.Panel.NO_STORES_IN_VIEW_HTML_ = '<li class="no-stores">The nearest outlet:</li>';
var Store = storeLocator.Store;
Store.prototype.generateFieldsHTML_ = function(fields) {
var html = '';
html += '<div class="store-data">';
if(this.props_['title']){
html += '<div class="title"><div class="img-list clearfix">' +
for (var i = 0; i <= this.props_[images].length; i++) {
console.log(this.props_[images[i]]);
// <img src=' + this.props_['images'] + '>
}
+ '</div></div>'
}
html += '</div>';
return html;
}
var data = new storeLocator.StaticDataFeed;
data.setStores([
new storeLocator.Store('store02', new google.maps.LatLng(27.67663,85.31093), null, {images: ["img/thapathalil.jpg","img/thapathalil.jpg","img/thapathalil.jpg"]})
]);
and it shows:
Uncaught SyntaxError: Unexpected token for...
how can i solve this?? how can i fetch location inside of "images"
THANKS in advance
Actually you got Uncaught SyntaxError: Unexpected token for... because you used the for..loop in the string concatenation statement, directly after the + sign.
Change this code :
html += '<div class="title"><div class="img-list clearfix">' +
for (var i = 0; i <= this.props_[images].length; i++) {
console.log(this.props_[images[i]]);
// <img src=' + this.props_['images'] + '>
}
+ '</div></div>'
To the following:
html += '<div class="title"><div class="img-list clearfix">';
for (var i = 0; i <= this.props_['images'].length; i++) {
console.log(this.props_['images'][i]);
html += '<img src=' + this.props_['images'][i] + '>';
}
html += '</div></div>'
Note:
You should separate the concatenation of strings to the html
variable and the for loop logic, using html += instead of just using concatenation with + sign on multiple lines.
Make sure to wrap the properties names between two '' while accessing your objects, like in this.props_[images] where it should be this.props_['images'] and in this.props_[images[i]] where it should be this.props_['images'][i].
And the first 2 lines of your html variable decalaration and the concatenation, var html = ''; html += '<div class="store-data">'; can be shortened to just var html = '<div class="store-data">';.
I think there is a typo. Change this:
console.log(this.props_[images[i]])
to
console.log(this.props_['images'][i])
And you should use
i < this.props_['images'].length
So try this:
for (var i = 0; i < this.props_['images'].length; i++) {
console.log(this.props_['images'][i]);
}

Javascript attach new property to element

I have an object, X, and some code that creates a div and assigns id = X.ID. After the html is created, I assign the object to the div, like this:
document.getElementById(X.ID).XValue = X;
If I set a break after that statement, I can evaulate document.getElementById(X.ID).XValue and see all the properties of X.
While I was creating the html, I added onmouseup="MOUSE_UP(event)".
var aProp = {};
aProp.ThisValue = "This";
aProp.ThatValue = "That";
aProp.Id = 5;
var html = '<div id="' + aProp.Id + '"';
var func = 'MOUSE_UP';
html += ' onmouseup="' + func + '(event) ">';
html += '</div>';
document.getElementById("test").innerHTML += html;
document.getElementById(aProp.Id).XVALUE = aProp;
function MOUSE_UP(event) {
alert(event.currentTarget.XValue.ThisValue);
}
Now, when I set a break at MOUSE_UP, event.currentTarget is my div (event.currentTarget.id == X.ID), but event.currentTarget.XValue is undefined.
Why is XValue undefined here when it was defined earlier?
Looks like setting innerHTML of #test would wipe out all custom properties from its children. You can check this in the jsFiddle. When you'll run the fiddle as it is, you'll notice NewProp of #1 will become undefined after adding more content with test.innerHTML += ... If you log tabIndex instead of NewProp, you'll get the correct values.
This happens because += operator is just a shortcut for a statement like a = a + b, which can also be written a += b.
Basicly you create a string from the inner HTML of #test, then add another string to it, and finally replace the original innerHTML of #test with this new string. All previous elements in #test are replaced with new ones, which don't have the custom properties set.
When setting id property for an element, also id attribute is added to the HTML, hence they are a part of innerHTML of #test, and are added to the newly created HTML too.
If you use proper DOM manipulation instead of setting innerHTML, you'll get the results you want. The code below uses createElement() and appendChild() methods instead of setting innerHTML.
function myMouseUp(e) {
alert("at MouseUp " + e.currentTarget.NewProp.ThisValue);
}
function buildOneDiv(aProp) {
var html = document.createElement('div');
aProp.ThisValue = 'This is ' + aProp.id;
aProp.ThatValue = 'That is ' + aProp.id;
html.id = aProp.id;
html.addEventListener('mouseup', myMouseUp, false);
html.innerHTML = 'Test ' + aProp.id;
return html;
}
function buildDivs(x) {
var html = buildOneDiv(x);
document.getElementById("test").appendChild(html);
document.getElementById(x.id).NewProp = x;
}
window.onload = function () {
var aProp, i;
for (i = 1; i < 4; i++) {
aProp = {};
aProp.id = i;
buildDivs(aProp);
}
};
A live demo at jsFiddle.
This is not so much an answer as it is a clarification and a work-around.
Given this html
<div id="test"></div>
and this code
function myMouseUp(e) {
alert("at MouseUp " + e.currentTarget.NewProp.ThisValue);
}
function buildOneDiv(aProp) {
aProp.ThisValue = "This";
aProp.ThatValue = "That";
var html = '<div id="' + aProp.id + '"';
var func = 'myMouseUp';
html += ' onmouseup="' + func + '(event) ">';
html += 'Test ' + aProp.id + '</div>';
return html;
}
function buildDivs(x) {
var html = buildOneDiv(x);
document.getElementById("test").innerHTML += html;
document.getElementById( x.id ).NewProp = x;
}
window.onload = function () {
for (var i = 1; i < 4; i++) {
var aProp = {};
aProp.id = i;
buildDivs(aProp);
}
};
The end result is that only the LAST div whose onmouseup is defined will have a legitimate value for NewProp at myMouseUp. For each other div, this property is undefined. This is why I got some comments indicating that "It does work." It works for ONE, which is all I had in my example. (This is the clarification.)
My workaround is to add a global object to be an associative array and change two statements:
var myDivs = {}; // global
Replace
document.getElementById( x.id ).NewProp = x;
in buildDivs with
myDivs[x.id] = x;
and replace
alert("at MouseUp " + e.currentTarget.NewProp.ThisValue);
in myMouseUp with
alert(myDivs[e.currentTarget.id].ThisValue );.
I'd still like to know why the original approach doesn't work.

Changing the content of all <pre> tags using JavaScript

I want to know how I change all the pre tags inside a document...
I'm using this:
var preContent = document.getElementById('code').innerHTML;
but this only changes the content of 1 pre tag... the one with the ID 'code'.
If you can show me how i can change all the pre tags using JavaScript I appreciate
Here's all the code:
window.onload = function () {
var preContent = document.getElementById('code').innerHTML;
var codeLine = new Array();
var newContent = '<table width="100%" border="1" '
+ 'cellpadding="0" cellspacing="0" >';
codeLine = preContent.split('\n');
for (var i = 0; i < codeLine.length; i++) {
newContent = newContent + '<tr><td class="codeTab1" >'
+ i.toString() + '</td><td class="codeTab2">'
+ codeLine[i] + '</td></tr>';
}
newContent = newContent + '</table>';
document.getElementById('code').innerHTML = newContent;
}
PS: This is to make a look like a normal compiler with numbers before the line
PPS: Each pre tag will have a different content and I want the same script to change it (if possible).
You can use getElementsByTagName:
var preElements = document.getElementsByTagName('pre');
for(var i = 0; i < preElements.length; ++ i)
{
var element = preElements[i];
/* modify element.innerHTML here */
}
First problem in you code . No two elements in a document can have same id .
So you can change it easily with jquery . look at the code .
$('pre').html("what ever text you want to show ");
Or with javascript you can do like this :
var x = document.getElementsByTagName('pre');
for(var i = 0; i < x.length; ++ i)
{
x.innerHTML = "what ever text you want to show";
}

How to get an element's full start tag in javascript (not only tagName)?

Is there simple any way to get an element's starting tag in javascript as string?
Suppose I have a DOM node which is a html element in a variable, I would like write something similar:
var tagName = element.tagName; //Works
var startingTag = element.startingTag; // Is there any way?
var startingTag = getStartingTag(element); // Or do I have to write my own function?
Thx for answers
For example this is a starting tag I would like to get into a string:
<Table class="anyClass" width="100" ... >
where the tagName only gives this: "Table"
Well, you could do:
var elStr = element.outerHTML
,startTag = elStr.substr(0,elStr.indexOf('>')+1);
Or use the element.attributes if you need information about attributes
You can loop through the attributes and append them to some string.
function getStartingTag(elem)
var str = '',
attr = elem.attributes,
value;
// Beginning of tag. toLowerCase() for a cleaner string.
str += '<' + elem.nodeName.toLowerCase() + ' ';
for (var i = 0, l = attr.length; i < l; i++) {
// Safety check.
value = attr[i].nodeValue.replace('"', '\\"');
// Append the name + value of the attribute.
str += attr[i].nodeName + '="' + attr[i].nodeValue + '" ';
}
str += '>';
return str;
}

Categories