I am trying to insert a form when a button is clicked but cannot find a way that does not make me put all of the HTML on one line with back slashes or many ugly lines of code. Something that does not include adding on something line jQuery or php.
In essence: How can I make this...(that is all on one line)
<script>
function newMsg() {
document.getElementById("add_message").innerHTML = "<div class=\"message\">Add Message<br>Title: <input type=\"text\" id=\"title\"><br>Text: <input type=\"text\" id=\"message\"><br><br></div>";
}
</script>
Look a little more something like this (that has good formatting and on multiple lines)
<script>function newMsg() {function newMsg() {
document.getElementById("add_message").innerHTML =
"<div class="message">Add Message<br>
Title: <input type="text" id="title"><br>
Text: <input type="text" id="message"><br><br>
</div>";
}
</script>
Simply replace the first and last " of the right hand side with ' and remove all \
like this :
document.getElementById("add_message").innerHTML = '<div class="message">Add Message<br>Title: <input type="text" id="title"><br>Text: <input type="text" id="message"><br><br></div>';
.innerHTML = '<div class="message">Add Message<br>'
+ 'Title: <input type="text" id="title"><br/>'
+ 'Text: <input type="text" id="message"><br/><br/></div>';
You can do what hamism suggested as well as concatenate if one line is too long, this way you can make your code look slightly cleaner.
You may check this fiddle:
http://jsfiddle.net/7sqha4ks/
function myFunction(){
document.getElementById("add_message").innerHTML =
'<div class="message">Add Message<br>Title: <input type="text" id="title">
<br>Text: <input type="text" id="message"><br><br></div>';
};
If you're issue is just with formatting, you can use an array of lines and the join array method like this:
var html = [
'<div class="message">Add Message<br>',
'Title: <input type="text" id="title"><br>',
'Text: <input type="text" id="message"><br><br>',
'</div>'
].join("\n");
Alternatively, you could use a templating language such as Handlebars or Jade and precompile your templates.
Alternatively, you could use a multiline string hack like this:
https://github.com/sindresorhus/multiline
If you wanna get it on separate lines like that for easier readability create your html as a variable and concatenate with the "+" symbol. Also use single quotes for any quotes inside of the main html. Something like:
var html = "<div class='message'>Add Message<br>"
+ "Title: <input type='text' id='title'><br>"
+ "Text: <input type='text' id='message'><br><br>"
+ "</div>";
document.getElementById("add_message").innerHTML = html
Related
I am working on javascript and html. I have table data. On the click of each td value I run a javascript function which get the text value of td and put as value in input tag generated dynamically. When I click the td text why I don't get the full string in my value?
I tried using inner Html and tried setting value.
<tr class="success">
<td id="name" ><a style="cursor: pointer;">Ravi Sharma</a></td>
</tr>
$('#name a').click(function() {
var name = $(this).text();
var html = '<input type="text" name="memberlist" value='+ name +'/> ';
});
Expecting:
<input type="text" name="memberlist" value="Ravi Sharma" >
Actual:
<input type="text" name="memberlist" value="Ravi" sharma>
Other answers will tell you why you got the result you did. It is tempting to try to solve the problem by just adding quotes, e.g.,
var html = '<input type="text" name="memberlist" value="'+ name +'"/> ';
This will work great if name is Ravi Sharma. But if you are constructing a chunk of HTML and trying to put the resulting string into an element's innerHTML you will have trouble if the variable name has double quotes in it!
name = 'Ravi O"Brien'
document.body.innerHTML = '<input type="text" name="memberlist" value="'+ name +'"/> '
This will expand into
value="Ravi O"Brien"
and your input box will contain only "Ravi O".
Sure you can use backticks and interpolation to solve this, or you can even try escaping the double quote characters with backslashes. Doing so is error prone. innerHTML is problematic anyway, and a big security concern. It is preferable to create the HTML elements yourself. You are using jQuery so the proper way to create your input element is:
$("<input/>", {
type: 'text',
value: name,
name: 'memberList',
})
There are ways to be safe with innerHTML but IMHO it should (always) be avoided.
HTML element attributes need to have quotes around their values. When you are doing your concatenating the single quotes get interpolated. So it assumes the first word is the only value.
Instead of:
var html = '<input type="text" name="memberlist" value='+ name +'/> ';
Try:
var html = '<input type="text" name="memberlist" value="'+ name +'"/> ';
#ray-toal brings up many good points about sanitization of your inputs and defending against XSS.
You are getting confused between the single and double quotes paring. I suggest using backticks as below:
var name = 'Ravi Sharma';
var html = `<input type="text" name="memberlist" value="${name}"/> `;
console.log(html);
When ever you need to insert a variable just encapsulate it within ${}. No more quotes pairing problems.
Just added an ID to the <a> tag (as it's the parent of the content text) and changed a bit of the JavaScript logic, hope it helps :
var text = document.getElementById("aName").innerHTML;
var output = '<p>The name below is the result of the event, not the original state !</p>';
document.getElementById("aName").addEventListener("click", function() {
document.body.innerHTML = output + text;
});
<tr class="success">
<td id="name" ><a id="aName" style="cursor: pointer;">Ravi Sharma</a></td>
</tr>
ALSO, reading again what you're needing, to achieve what you want, you pretty much just have to apply the same logic to the tag inside the var, then call the var name on the innerHTML event :
var text = document.getElementById("aName").innerHTML;
var input_txt = '<input type="text" name="memberlist" value="'+ text +'"/> ';
document.getElementById("aName").addEventListener("click", function() {
document.body.innerHTML = input_txt;
});
<tr class="success">
<td id="name" ><a id="aName" style="cursor: pointer;">Ravi Sharma</a></td>
</tr>
Reproduced your code and got answer.
1. Change string initialization from '' to `` to be able to interpolate variables.
2. In your expectations, you ask for '>', but code contains '/>' change that if needed.
3. Here your solution!
$('#name a').click(function() {
var name = $(this).text();
var html = `<input type="text" name="memberlist" value="${name}"/> `;
"use strcit";
$('#name a').click(function() {
var name = $(this).text();
var html = `<input type="text" name="memberlist" value="${name}"/> `;
console.log(html);
});
table, th, td {
border: 1px solid black;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie-edge">
<title>Stack Overflow</title>
<link rel="stylesheet" href="css/index.css">
<link rel="stylesheet" href="styles.css">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<table class="table">
<tr class="success">
<td id="name" ><a style="cursor: pointer;">Ravi Sharma</a></td>
</tr>
</table>
<script src="scripts/so.js"></script>
</body>
</html>
});
Browsers ignore the <tbody>, <tr>, and <td> tags and the corresponding end tags. This has not been specified in HTML specifications, since they do not define the parsing of syntactically erroneous documents. In the HTML5 draft, however, there is a description that defines the browser behavior in a manner that corresponds to the what browsers actually do: Tree construction.
This means that you cannot write an HTML document that contains, say, a element outside a table element. The HTML parser in a browser simply does not construct such document trees. (You can, however, construct such a document dynamically with client-side scription.)
$('#name').click(function() {
alert("asdfsdf");
var name = $(this).text();
var html = '<input type="text" name="memberlist" value='+ name +'/> ';
$("#test").text(html);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<tr class="success">
<td><a id="name" style="cursor: pointer;">Ravi Sharma</a></td>
</tr>
<div id="test"></div>
$('button').click(function(){
$('#inputs').children().first().clone().appendTo('#inputs');
$('#inputs').children().last().clone().appendTo('#inputs');
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='inputs'>
<input type='text' name="input['name'][1]">
<input type='text' name="input['name'][2]">
<input type='text' name="input['name'][3]">
<br>
<input type='text' name="input['age'][1]">
<input type='text' name="input['age'][2]">
<input type='text' name="input['age'][3]">
</div>
<button>Add</button>
The Script works properly, but the only problem is copying the name of the input. I want when I clone it to change the [1] into its sequence number with the ['name'] changes to ['age'] in the second clone. I also want the ['name'] to be appended to the end of the list of ['name'].
I thought about copying the name then removing last two letters and replace it by the '+index+]' But I wonder if that the proper way to do it.
You can just do a normal string operation on it. Since you know the pattern, you just need the number of inputs for the number and to stick in here there. Something like this:
$('#inputs').children().last().attr('name', `input['name'][${$('#inputs').children().length}`);
Since there are now 4 (including the new one), length will give you 4 so you'll end up setting the name to input['name'][4]. Subsequent will give you 5, 6, and so on.
If you need to dynamically grab the name and just need to update the number, you can just find and replace the number part (since you know it'll always be [1]):
const $last = $('#inputs').children().last();
$last.attr('name', $last.attr('name').replace('[1]', `[${$('#inputs').children().length}]`));
With this approach, it'll use the current name, and just replace the [1] bit with the new number, so you'll get [4] in there first (so input['name'][4] and input['age'][4], then [5] and so on.
Yes you can simply change the string. To add the name name to the end of the name list before the <br>, you need to select each group separately and then use after() instead of appendTo():
$('button').click(function(){
var names = $('#inputs').children('[name^="input[\'name"]');
var clone = names.first().clone();
clone.attr("name", "input['name'][" + (names.length + 1) + "]");
names.last().after(clone);
var ages = $('#inputs').children('[name^="input[\'age"]');
clone = ages.first().clone();
clone.attr("name", "input['age'][" + (ages.length + 1) + "]");
ages.last().after(clone);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='inputs'>
<input type='text' name="input['name'][1]">
<input type='text' name="input['name'][2]">
<input type='text' name="input['name'][3]">
<hr>
<input type='text' name="input['age'][1]">
<input type='text' name="input['age'][2]">
<input type='text' name="input['age'][3]">
</div>
<button>Add</button>
Note: I changed your <br> to <hr> only for demo so we can see it.
say I have the following code:
var rightPane = $("#right");
// Draw the right pane
rightPane.html('<h2>' + task.task + '<h2> <hr />' +
'data1: <input type="text" id="data1" value="' + task.data1 + '" /> <br />' +
'data2: <input type="text" id="data2" value="' + task.data2 + '" /> <br />' +
'data1: <input type="text" id="data3" value="' + task.data3 + '" /> <br />' +
'<input type="button" id="subUpdated" value="Save">');
I there any way to write the HTML code like a simple HTML code , and without the qoutes and the plus signs?
In the current version of JavaScript, you can do this by escaping the newlines at the ends of lines, which is a bit better but note that leading whitespace will be included in the string, and you still have to use concatenation to swap in your values:
var rightPane = $("#right");
// Draw the right pane
rightPane.html('<h2>' + task.task + '<h2> <hr />\
data1: <input type="text" id="data1" value="' + task.data1 + '" /> <br />\
data2: <input type="text" id="data2" value="' + task.data2 + '" /> <br />\
data1: <input type="text" id="data3" value="' + task.data3 + '" /> <br />\
<input type="button" id="subUpdated" value="Save">');
In the next version of JavaScript, "ES6", we'll have template strings which can be multi-line and which let you easily swap in text using ${...}:
// REQUIRES ES6
var rightPane = $("#right");
// Draw the right pane
rightPane.html(`
<h2>${task.task}<h2> <hr />
data1: <input type="text" id="data1" value="${task.data1}" /> <br />
data2: <input type="text" id="data2" value="${task.data2}" /> <br />
data1: <input type="text" id="data3" value="${task.data3}" /> <br />
<input type="button" id="subUpdated" value="Save">
`);
(Again leading whitespace is included in the string.)
To do that before ES6, you can use any of several templating libraries (Handlebars, Mustache, RivetsJS).
For a really simple version, you could use the function I wrote for another question.
You could create your own super-simple 'template engine'.
Write your template in the markup of your page as you would a usual element.
Give the template container element an attribute to denote its role as a template, for example a data attribute of data-template.
Clone and detach all data-template elements when the DOM is ready.
On some event, insert your values as you like, then re-insert the compiled template into the page.
For example:
$(document).ready(function() {
var template = $('[data-template]').detach().clone();
var values = { foo: 'bar', yipee: 'yahoo' };
$('button').click(function() {
for(var prop in values) {
template.find('[data-value="' + prop + '"]').html(values[prop]);
$('#container').append(template);
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>Insert</button>
<div id="container"></div>
<div data-template>
<div data-value="foo"></div>
<div>
<div data-value="yipee"></div>
</div>
</div>
Not currently, other than templates as others have mentioned. What you could do, however, is to include the initial HTML code in your main document, and then set the values with rightPane.val(task.data1);, etc.
You can try to do something like this: Format a string using placeholders and an object of substitutions?
but as Hacketo suggests it would be better to learn to use templates. Take for instance look at underscore.js (http://underscorejs.org/#template)
One alternative way of approaching this would be :
var $h2 = $("<h2>", {text : task.task});
var $data1 = $("<input>", {type : 'text', value : task.data1});
var $data2 = $("<input>", {type : 'text', value : task.data2});
var $data3 = $("<input>", {type : 'text', value : task.data3});
var $button = $("<input>", {type : 'button', value : 'Save'});
rightPane.append($h2, $data1, $data2, $data3, $button);
This might be a little easier to follow when scanning over the code, rather than shifting through the .html() function.
You could take a look at a JavaScript templating engine. Such as Handlebars, Mustache etc. You can see some of the popular ones here: You can kind of view these as user controls similar to what you get in ASP.NET
This is an example of Handlebars for your code:
<h2>{{task}}<h2> <hr />
data1: <input type="text" id="data1" value="{{data1}}" /> <br />
data2: <input type="text" id="data2" value="{{data2}}" /> <br />
data1: <input type="text" id="data3" value="{{data3}}" /> <br />
<input type="button" id="subUpdated" value="Save">
<div id="file">
<input type="file" name="txtImage" multiple="multiple" class="upload" />
<input type="text" name="txtImageDesc" class="desc" />
</div>
<input type="button" value="Add" name="addButton" onclick="javascript: add_more();" />
<input type="button" value="Remove" name="removeButton" onclick="javascript: remove();" />
The above is two button which add or remove div on its calls.I have a java script function which is adding a div in html on call which works perfect
function add_more()
{
var txt = " <p><label>Upload Image</label><input type=\"file\" name=\"txtImage[]\"></p> <p>
<label>Image Description</label><input type=\"text\" name=\"txtImageDesc[]\"> </p>";
document.getElementById("file").innerHTML += txt;
}
However i am using the same script(with modification) to remove the last inserted div in it but its removing the whole html in the div.Here is the code:
function remove() {
var txt = " <p><label>Upload Image</label><input type=\"file\" name=\"txtImage[]\"></p>
<p><label>Image Description</label><input type=\"text\" name=\"txtImageDesc[]\"> </p>";
document.getElementById("file").innerHTML -= txt;
}
The output it generate is.I want the last div inserted to be remove on button click
NaN
As already said in comments, you are adding p elements here, not div.
If you don’t want to use jQuery, you can do it in “pure JS” as well, like this:
function lastParagraphBeGone() { // brilliant function name :-)
var paragraphs = document.getElementById("file").getElementsByTagName("p");
var lastParagraph = paragraphs[paragraphs.length-1];
lastParagraph.parentNode.removeChild(lastParagraph);
}
$('#file p').slice(-2).remove(); will remove the last 2 P elements from your #file element:
LIVE DEMO
HTML:
<input type="button" value="Add" name="addButton" />
<input type="button" value="Remove" name="removeButton" />
<div id="file"></div>
jQ:
var html = " <p><label>Upload Image</label><input type=\"file\" name=\"txtImage[]\"></p><p><label>Image Description</label><input type=\"text\" name=\"txtImageDesc[]\"></p>";
$('[name=addButton]').click(function(){
$('#file').append( html );
});
$('[name=removeButton]').click(function(){
$('#file p').slice(-2).remove();
});
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/slice
Javascript uses the same operator for concatenation and for addition; so adding works.
But the minus operator is only for subtraction. So you try to subtract text from text which aren't numbers, so it's a NaN.
You cannot remove by this way: Use some function to search the beginning of this string and extract it so or simply add an id attribute to your <p> tag, so you can simply hide it when not needed anymore.
This works for me. One thing that seems to break this kind of function is when the adding text is on separate lines. So, always put that kind of "txt" addition on a single line in javascript.
<script type="text/javascript" >
function add_more()
{
var txt = " <p><label>Upload Image</label><input type=\"file\" name=\"txtImage[]\"></p><p><label>Image Description</label><input type=\"text\" name=\"txtImageDesc[]\"> </p>";
document.getElementById("extra-text").innerHTML = txt;
}
function remove() {
document.getElementById("extra-text").innerHTML = '';
}
</script>
<input type="button" value="Add" name="addButton" onclick="javascript: add_more();" />
<input type="button" value="Remove" name="removeButton" onclick="javascript: remove();" />
<div id="file"><h1>Existing text</h1>
<div id="extra-text"></div>
</div>
I'm working on a tagging system and I want users to be able to add and remove tags on the page. for each one thats added I am displaying a small div with the tag and an x to remove the tag. I have the adding functionality working, but I'm not sure how to go about making it so I can remove them. I also have a hidden input which should hold all the values so that when the information is submitted I can use it.
Heres my attempt that doesn't work:
function tagsremove(tag) {
$('#hiddentags').val().replace('/'+tag+'\,\s/', '');
$("#tagdiv-"+tag.replace(" ","_")).fadeOut('normal', function(){
$(this).remove();
});
}
$(document).ready(function(){
$('#tagbutton').click(function(){
var tags = $('#tagsbox').val().split(", ");
for (var i in tags) {
$('#hiddentags').val($('#hiddentags').val() + tags[i] +", ");
$('#curtags').append("<div class='tag'>" + tags[i] + " <a href='#' id='#tagdiv-"+tags[i].replace(" ", "_")+"' onclick='tagsremove(\""+tags[i]+"\");' >x</a></div>");
}
$('#tagsbox').val('');
});
});
heres the html to go with it:
<div class='statbox'>
<form method='post' action='post.php' id='writeform'>
<p class='subtitle'>Title</p>
<input type='text' name='title' id='titlebox' /><br />
<p class='subtitle'>Body</p>
<textarea id='postbox' name='body' rows='10'></textarea><br />
<p class='subtitle'>Tags</p>
<input type='text' id='tagsbox' /><input type='button' id='tagbutton' value='Add' />
<p class='subsubtitle'>Seperate by commas (eg. "programming, work, job")</p>
<div class='subsubtitle' id='curtags'>Current Tags:</div>
<input type='hidden' value='' name='tags' id='hiddentags' />
</form>
</div>
Make each of your tag divs have a relevant ID. For, say, the "play pen balls" tag, your ID could be "tagdiv-play_pen_balls". Now you can just do
function removeTag(tag) {
$("#tagdiv-"+tag.replace(" ","_")).remove();
}
to remove the visible div.
(I'm not sure if that's what you were asking for, though...)
Instead of using .val('') you should be using .html('');
http://docs.jquery.com/Manipulation