this is my code
html :
<input type="text" class="js-input">
<div class="js-autofill"></div>
jquery :
var myarray = ['apple' , 'orange'];
myarray.forEach(element => {
$('.js-autofill').append(
`<div class="js-item" data-value="`+element+`">` +element+ `</div>`
)
})
$(document).on('click','.js-item',function(){
$('.js-input').val($(this).attr('data-value'))
})
problem is .js-item onclick not working at firsttime - it's work when i doubleclick
i can't find why
You need to change .val() to .text() for the div click.
From Docs
The .val() method is primarily used to get the values of form elements such as input, select and textarea. When called on an empty collection, it returns undefined.
$('.js-input').val($(this).text())
2 - Your div string in append has mismatch quotes, the correct order should be as below.
`<div class='js-item' data-value='` + element + `'>` + element + `</div>`
Also its helpful for you to read: When should I use double or single quotes in JavaScript?
Working code below
var myarray = ['apple', 'orange'];
myarray.forEach(element => {
$('.js-autofill').append(
`<div class='js-item' data-value='` + element + `'>` + element + `</div>`
)
})
$(document).on('click', '.js-item', function() {
$('.js-input').val($(this).text())
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" class="js-input">
<div class="js-autofill"></div>
Related
I am wanting to try and pass record.ItemID to my onclick = buy() function. But I am getting errors like "Uncaught SyntaxError: Unexpected end of input"
I have tried \"record.ItemID \" but that of course just passes the literal string of result.name
I have also tried (\'' + record.ItemID + '\') but get the same Syntax error
function showShop(items) {
let tableContent = "<tr class='orderTitle'><td =imgTable></td><td id = contentTable ></td></tr>\n";
let odd = true;
const addRecord = (record) => {
tableContent += odd ? "<tr class='orderOdd'>" : "<tr class='orderEven'>";
odd = !odd;
tableContent += "<td>" + "<img id = image src="+ "http://redsox.uoa.auckland.ac.nz/ms/MuseumService.svc/shopimg?id=" + record.ItemId + " />" + "</td><td id = content>" + record.Description + "<td><button onclick='buy("+ record.ItemId +")'/> Buy </button></td>";
}
items.forEach(addRecord)
document.getElementById("shop").innerHTML = tableContent;
}
function buy(item){
window.open('http://redsox.uoa.auckland.ac.nz/mss/Service.svc/buy?id='+ item,'_self');
}
I'm not sure if this will solve your problem but it looks like you're mixing up 's and "s.
onclick='buy('record.ItemId')'
You are terminating the onclick attribute right after buy(.
You may need to do something like:
onclick='buy(" + record.ItemId + ")'
Generally speaking though, if you have to build up HTML in strings, you are better off string interpolation. It makes it easier to read and is less prone to these types of issues.
Example:
const html = `<button onclick="buy(${record.ItemId})">Click</button>`;
It looks like you're trying to build up some HTML content to put into a table, and you want some behaviour attached to a button inside the table so that it opens a new window when you click on it.
There are a number of different approaches to what you're trying to do which would be safer in production code, so while you've got some answers to your specific question, please consider these alternative approaches which are more idiomatic:
You could use a link (<a>) instead of a button, and use CSS to make the link look like a button. This avoids needing a click handler at all.
You could use data attributes to store the record in a safe way, then access it from the click event, e.g. e.target.dataset.recordId.
You could use jQuery or a similar toolkit to create the button, then attach a function to the button as a click handler.
When you create HTML directly like you are doing in your question, you're opening your code up to code injection, where someone malicious could craft data that could steal private information from users of your site. It's much safer to use a library to construct your HTML directly rather than building it up in strings.
Really you're much better off separating out your inline JS and using event listeners to target classes on your elements.
Here's a quick example to show you how you might achieve that:
const records = [{ itemId: 1 }, { itemId: 2 }, { itemId: 3 }];
const imgRoot = 'https://dummyimage.com/30x30/676767/fff.png?id=';
// `map` iterates over the array and produces one element of HTML per record
// We use a class on the button to identify it, and a data attribute
// button to hold the itemId
const html = records.map(({ itemId }) => {
return `
<div class="itemWrapper">
<img class="item" src="${imgRoot}${itemId}" />
<button data-itemid="${itemId}" class="buyRecord">Buy record</button>
</div>
`;
});
document.querySelector('.root').innerHTML = html.join('');
// We grab the buttons and iterate over them attaching
// event listeners that call `handleBuy` when the button is clicked
const buyButtons = document.querySelectorAll('.buyRecord');
buyButtons.forEach(button => button.addEventListener('click', handleBuy, false));
function handleBuy(e) {
// Destructure the itemid from the dataset of the button
// click event
const { target: { dataset: { itemid } } } = e;
console.log(itemid);
}
<div class="root" />
Documentation
map
Data attributes
Template literals
Destructuring assignment
The General format of onclick is
onclick="function_name(variable)"
For this case you can do something like this:
tableContent += '<td>' + '<img id = image src="http://redsox.uoa.auckland.ac.nz/ms/MuseumService.svc/shopimg?id=' + record.ItemId + '" /></td><td id="content">' + record.Description + '<td><button onclick="buy('+record.ItemId+')"> Buy </button></td>';
I have many span element with many ids such as these:
<span id="spn1" class="span-text">hello</span>
<span id="spn2" class="span-text">world</span>
<span id="spn3" class="span-text">12345</span>
It could be 1 or 100 span element. If 100 span was created so the id will be spn100. No problem with that. Now I have problem with javascript code because I hardcoded the ids when the span such as these:
var text = $("#spn1").text() + "\r\n" + $("#spn2").text() + "\r\n" + $("#spn3").text();
The javascript code above was hardcoded so if 100 span was created; my copy function will not worked. How do I solve this problem?
Full code : http://jsfiddle.net/p3h7j4eb/
Thanks in advance
You can use the CSS class as selector and just iterate over that with $.map. Then there's no more need for all those id properties:
var text = $.map($(".span-text"), function(span) {
return $(span).text();
}).join("\r\n");
console.log(text);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="span-text">hello</span>
<span class="span-text">world</span>
<span class="span-text">12345</span>
You can iterate over all elements with you classname, using the 'each' function like this:
var text = '';
$('.span-text').each(function ()
{
text += $(this).text() + '\r\n';
}
I am trying to add and remove file uploading using javascript.
I am able to add the Element but when I try to remove the same element, it gives the error:
SyntaxError: expected expression, got '}
Below is my HTML code:
<form enctype="multipart/form-data" action="" method="post">
<p>Upload file(s)</p>
<div id="files">
<p><input type="file" name="uploaded_file[]" /></p>
</div>
<p><input type="button" value="Add File" onclick="addFile();" /></p>
</form>
JS :
function addElement(parentId, elementTag, elementId, html) {
// Adds an element to the document
var p = document.getElementById(parentId);
var newElement = document.createElement(elementTag);
newElement.setAttribute('id', elementId);
newElement.innerHTML = html;
p.appendChild(newElement);
}
function removeElement(elementId) {
// Removes an element from the document
var element = document.getElementById(elementId);
element.parentNode.removeChild(element);
}
var fileId = 0; // used by the addFile() function to keep track of IDs
window.addFile = function() {
fileId++; // increment fileId to get a unique ID for the new element
var html = '<input type="file" name="uploaded_files[]" /> ' +
'Remove';
addElement('files', 'p', 'file-' + fileId, html);
}
the error seems to be in this line, bu I am not sure
var html = '<input type="file" name="uploaded_files[]" /> ' +
'Remove';
jsFiddle here
Change "file-' + fileId + '" with \'file-' + fileId + '\'.
You're setting a string in html var using '' chars, so you can use freely "" in it: var html = '<a href="myhref">'
But when you need to also declare a string inside an already opened double quote, you need to use single quote and escape it so JS knows you're not actually closing the initial single quote at the beginning.
var html = '<a href="myhref" onclick="functionToCall(\'myStringInsideAnotherString\')">'
And you can still add dynamic thing using regular (not escaped) single quotes:
var html = '<a href="myhref" onclick="functionToCall(\'myStringInside' +
myOtherStringDeclaredSomewhereElse + 'AnotherString\')">'
Also, in order to make your fiddle to work, you'll need to change the load type to "No wrap" instead of onLoad.
I am trying to edit the div's text, but when i use my function to update the rowcount, everytime the text vanihes completely. Would by nice if you could also explain why.
Thanks in advance.
My update function:
var rowCountF = $('#tablef tr').length;
var rowCountV = $('#tablev tr').length;
var ftext = "Teilnehmer (" + String(rowCountF) + ")";
var vtext = "Teilnehmer (" + String(rowCountV) + ")";
$("#divf").html(ftext);
$("#divv").html(vtext);
My div layer:
<div id="divf"class="tableheader"> <h2>Teilnehmer</h2> </div>
Code for divf:
<div id="divf"class="tableheader"> <h2>Teilnehmer</h2> </div>
You are actually replacing the contents of the div itself with your text. This means the heading disappears and there is only plain text.
Probably you wanted to replace the heading contents:
$("#divf h2").html(ftext);
$("#divv h2").html(vtext);
This will select the h2 elements inside the divs and hence will update only the text inside the headings.
The result will look like the following:
<div id="divf"class="tableheader"> <h2>Teilnehmer (987)</h2> </div>
<div id="divf"class="tableheader"> <h2>Teilnehmer (123)</h2> </div>
.html() sets the HTML, meaning it replaces anything that's currently there. If you want to add to the HTML, you'll need to set the HTML to what's already there plus what you're adding, like so:
var rowCountF = $('#tablef tr').length;
var rowCountV = $('#tablev tr').length;
var ftext = "Teilnehmer (" + rowCountF + ")";
var vtext = "Teilnehmer (" + rowCountV + ")";
//Get already-existing HTML
var divfHtml = $("#divf").html();
var divvHtml = $("#divv").html();
//Set the new HTML to the existing + the new text
$("#divf").html(divfHtml + ftext);
$("#divv").html(divvHtml + vtext);
If you only want to replace the heading, then just target the <h2> as Martin Zikmund suggested in his answer.
You need to reference the h2 for the div. using .html() will replace ALL of the html inside the #divf which in this case means it will replace the h2
$("#divf h2").html(ftext);
$("#divv h2").html(vtext);
Example: https://jsfiddle.net/qhef0toc/3/
Can you group those into one line, I know how to do this without concatenation but with, not working.
$('#vda'+event.target.id).remove();
$('#a'+event.target.id).remove();
$('#'+event.target.id).remove();
$('#da'+event.target.id).remove();
here is your one liner.
$(
'#vda' + event.target.id +
', #a' + event.target.id +
', #' + event.target.id +
', #da' + event.target.id
).remove();
it seems more, but I divided to better readability.
https://api.jquery.com/multiple-selector/ here is the documentation for multiple selector of jQuery
Try this
var str = ['#vda', '#a', '#', '#da'].join(event.target.id + ',') + event.target.id;
$(str).remove();
The join() method joins all elements of an array into a string.
str = arr.join([separator = ','])
or you can use reduce function
var str = ['#vda', '#a', '#', '#da'].reduce(function(p,c, i,arr){
if(i !== arr.length - 1)
return p + event.target.id + ',' + c
else
return p + event.target.id+ ',' + c + event.target.id
});
$(str).remove();
jQuery allows you to select as you do in CSS
So for the sake of an example, if you want to make a selector that matches all divs with test class, and all the p elements as well, in CSS you would select them using:
div.test, p { property:value }
In jQuery, do the same thing:
$("div.test, p").remove()
So you can just replace the div.test, p with whatever you selector you like
Here's a nice reference for CSS selectors
['vda','a','',da].forEach(function(val,key){
$('#'+event.target.id).remove();
})
If you do not have any extra elements with similar IDs, you can try ends with pattern selector:
$("[id$='pattern']")
$("#btn").on("click", function() {
var target = "test"; // e.target.id
$('[id$="test"]').remove();
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div>
<div id="test">test</div>
<div id="atest">atest</div>
<div id="datest">datest</div>
<div id="vdatest">vdatest</div>
</div>
<button id="btn">Test</button>
You can try to make an array of all possible combinations and use map + join to get string
$("#btn").on("click", function() {
var target = "test"; // e.target.id
var selector_list = ["#", "#a", "#da", "#vda"];
var el_str = selector_list.map(function(item) {
return item + target;
}).join();
console.log(el_str);
$(el_str).remove();
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div>
<div id="test">test</div>
<div id="atest">atest</div>
<div id="datest">datest</div>
<div id="vdatest">vdatest</div>
</div>
<button id="btn">Test</button>
Just for a record, you can do with pure JS selector API in ES6 style as follows;
[...document.querySelectorAll(['#vda','#a','#','#da'].join(",")].forEach(e => e.parentElement.removeChild(e));