I am building a chat and i need to append content from the textarea to an inner div upon clicking send
<div class="inner" id="inner">
<div class="incoming" id="incoming">
<div class="them" id="them">Lorem
</div>
</div>
<div class="outgoing" id="outgoing">
<div class="me" id="me">Lorem ipsum
</div>
</div>
</div>
the button and textarea code is
<textarea class="input" id="input" placeholder="Message.."></textarea>
<a class="waves-effect waves-light" id="send-btn" >Send</a>
Javascript
var sendButton= document.getElementById('send-btn');
var textArea = document.getElementById('input');
var innerDiv= document.getElementById('inner');
var message=textArea.value;
sendButton.addEventListener('click', function(){
innerDiv.innerHTML=meMessage;
});
var meMessage= '<div class="outgoing" id="outgoing">'+
'<div class="me" id="me"></div></div>';
What i am trying to do is show the text value of the text area to the inner div called 'me' when i click send
and also get the value of the textarea to save it to a database. How can i achieve this
First of all you shouldn't create html elements manually since they would be XSS vulnerable and read about escaping mechanics to prevent malicious code being injected.
Try using document.createElement('div'); method to create div with valid innerText.
later use method:
innerDiv.appendChild(createdElement);
To append element.
You could create builder to build html elements you need and you have to htmlEncode text that will be inside of div element.
const sendButton = document.getElementById('send-btn');
const textArea = document.getElementById('input');
const innerDiv = document.getElementById('inner');
var message = textArea.value;
sendButton.addEventListener('click', function () {
const message = new MessageContainerBuilder().BuildMessage(textArea.value);
innerDiv.appendChild(message);
textArea.value = '';
});
function encodeHtmlEntity(input) {
var output = input.replace(/[\u00A0-\u9999<>\&]/gim, function (i) {
return '&#' + i.charCodeAt(0) + ';';
});
return output;
}
function MessageContainerBuilder() {
var createDivElement = function (classTest) {
var div = document.createElement('div');
var classAttr = document.createAttribute('class');
classAttr.value = classTest;
div.setAttributeNode(classAttr);
return div;
};
var createSpanElement = function (value, classTest) {
var span = document.createElement('span');
if (classTest) {
var classAttr = document.createAttribute('class');
classAttr.value = classTest;
span.setAttributeNode(classAttr);
}
span.innerText = encodeHtmlEntity(value);
return span;
};
this.BuildMessage = function (text) {
var divContainer = createDivElement('outgoing');
var messageSpan = createSpanElement(text, 'me');
divContainer.appendChild(messageSpan);
return divContainer;
};
}
<div id="inner">
<div class="incoming">
<div class="them">Lorem
</div>
</div>
<div class="outgoing">
<div class="me">Lorem ipsum
</div>
</div>
</div>
<textarea class="input" id="input" placeholder="Message..."></textarea>
<button class="waves-effect waves-light" id="send-btn">Send</button>
UPDATE: Extended snippet code. Removed Ids since they shouldn't be used there to create multiple message elements with same Id. Changed anchor to button.
You need to get the value of the textarea on click of the link
var sendButton = document.getElementById('send-btn');
var textArea = document.getElementById('input');
var innerDiv = document.getElementById('inner');
var message = textArea.value;
sendButton.addEventListener('click', function() {
innerDiv.innerHTML = `<div class="outgoing" id="outgoing">${textArea.value}
<div class="me" id="me"></div></div>`;
});
<div class="inner" id="inner">
<div class="incoming" id="incoming">
<div class="them" id="them">Lorem
</div>
</div>
<div class="outgoing" id="outgoing">
<div class="me" id="me">Lorem ipsum
</div>
</div>
</div>
<textarea class="input" id="input" placeholder="Message.."></textarea>
<a class="waves-effect waves-light" id="send-btn">Send</a>
You can use this. Youe message variable is not receiving the textarea value
var sendButton= document.getElementById('send-btn');
var innerDiv= document.getElementById('inner');
sendButton.addEventListener('click', function(){
innerDiv.innerHTML=innerDiv.innerHTML+'<div class="outgoing" id="outgoing">'+document.getElementById('input').value+
'<div class="me" id="me"></div></div>';
});
<div class="inner" id="inner">
<div class="incoming" id="incoming">
<div class="them" id="them">Lorem
</div>
</div>
<div class="outgoing" id="outgoing">
<div class="me" id="me">Lorem ipsum
</div>
</div>
</div>
<textarea class="input" id="input" placeholder="Message.."></textarea>
<a class="waves-effect waves-light" id="send-btn" >Send</a>
Maybe be replacing your js with that :
document.getElementById('send-btn').addEventListener('click',
function(){
var userInput = document.getElementById('input').value;
if(userInput) { document.getElementById('me').innerHTML += '<br>' + userInput; }
}
);
That should let you go a step forward... And good luck for saving to DB.
innerDiv.append(message)
instead of
innerDiv.innerHTML=message
Related
I want the button with the id #show-text-area execute the postButton(); function only once so it won't create a second elements whenever clicked (i want it to create it for only one time and won't work again until clicked another button).
Hope my question was clear enough.
HTML
<div id="post-creator" class="creator-container">
<div class="post-type">
<div class="text-post" id="post">
<button onclick="postButton();">Post</button>
</div>
<div class="media-post">Image & Video</div>
<div class="link-post">Link</div>
</div>
<div class="post-title">
<input type="text" class="title-text" name="post-title" placeholder="Title">
</div>
<div class="post-content">
</div>
<div class="post-footer">
<div class="spoiler">Spoiler</div>
<div class="nsfw">NSFW</div>
<button class="post">post</button>
</div>
</div>
Javascript
let postButton = function() {
let textarea = document.createElement('textarea');
textarea.setAttribute('class', 'post-data');
textarea.setAttribute('placeholder', 'Text (optional)');
document.querySelector('.post-content').appendChild(textarea);
}
You could disable the button after activation, this has the benefit of informing the user that further clicks won't do anything.
let postButton = function() {
let textarea = document.createElement('textarea');
textarea.setAttribute('class', 'post-data');
textarea.setAttribute('placeholder', 'Text (optional)');
document.querySelector('.post-content').appendChild(textarea);
document.getElementsByTagName("button")[0].disabled = true;
}
Otherwise you could simply have the function short-circuit if it has already been called.
// alreadyPosted is scoped outside of the function so it will retain its value
// across calls to postButton()
let alreadyPosted = false;
let postButton = function() {
// do nothing if this isn't the first call
if (alreadyPosted) { return; }
// mark the function as called
alreadyPosted = true;
let textarea = document.createElement('textarea');
textarea.setAttribute('class', 'post-data');
textarea.setAttribute('placeholder', 'Text (optional)');
document.querySelector('.post-content').appendChild(textarea);
document.getElementsByTagName("button")[0].disabled = true;
}
The following works.
let postButton = function(event) {
event.target.disabled = true;
let textarea = document.createElement('textarea');
textarea.setAttribute('class', 'post-data');
textarea.setAttribute('placeholder', 'Text (optional)');
document.querySelector('.post-content').appendChild(textarea);
};
document.getElementById('post').addEventListener('click', postButton);
<div id="post-creator" class="creator-container">
<div class="post-type">
<div class="text-post" id="post">
<button>Post</button>
</div>
<div class="media-post">Image & Video</div>
<div class="link-post">Link</div>
</div>
<div class="post-title">
<input type="text" class="title-text" name="post-title" placeholder="Title">
</div>
<div class="post-content">
</div>
<div class="post-footer">
<div class="spoiler">Spoiler</div>
<div class="nsfw">NSFW</div>
<button class="post">post</button>
</div>
</div>
You can also use hide show function on textarea if you do not want to create one.
let postButton = function() {
let d = document.getElementById('post_data').style.display;
if(d=='none'){
document.getElementById('post_data').style.display = 'block';
}
}
document.getElementById('post_data').style.display = 'none';
document.getElementById('post_btn').addEventListener('click', postButton);
<div id="post-creator" class="creator-container">
<div class="post-type">
<div class="text-post">
<button id="post_btn">Post</button>
</div>
<div class="media-post">Image & Video</div>
<div class="link-post">Link</div>
</div>
<div class="post-title">
<input type="text" class="title-text" name="post-title" placeholder="Title">
</div>
<div class="post-content">
<textarea class="post-data" id="post_data" placeholder="Text (optional)"></textarea>
</div>
<div class="post-footer">
<div class="spoiler">Spoiler</div>
<div class="nsfw">NSFW</div>
<button class="post">post</button>
</div>
</div>
I am trying to create a button using array but when i try to write text in text input and try to create a button it doesn't change the value.
function ready() {
var family = ["demo1", "demo2", "demo3", "demo4", "demo5", "demo6"];
function btns() {
var btn = $("<button>" + family[i] + "</button>")
$(btn).attr("data-search", family[i])
$(btn).appendTo("#buttons")
}
var submit = $("<button>Submit</button>");
var text = $("<input type='text' name='text'>");
$(text).appendTo("#submit");
$(submit).appendTo("#submit");
for (i = 0; i < family.length; i++) {
btns();
}
$(submit).on("click", function() {
var textBtn = text.val();
family.push(textBtn);
btns();
})
}
ready();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
<div class="container">
<div class="row">
<div id="buttons"></div>
</div>
<div class="row">
<div class="col-sm-3">
<div id="gif"></div>
</div>
<div class="col-sm-9">
<div id="submit"></div>
</div>
</div>
</div>
</body>
Is this what you are looking for? The code is commented to show you the steps
var family = ["demo1", "demo2", "demo3", "demo4", "demo5", "demo6"];
// for each family add a button
const buttons = family.map(el => $(`<button data-search="${el}">${el}</button>`));
$('#buttons').append(buttons);
function addButton() {
// get the value of the text input
const val = $('#button-text').val();
// if the value is not empty
if (val.trim().length) {
// create the new button and append it
const btn = $(`<button data-search="${val}">${val}</button>`);
$('#buttons').append(btn);
// add the val to the family array
family.push(val);
// add the button to the buttons array
buttons.push(btn);
// reset the input field
$('#button-text').val('');
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="buttons">
</div>
<div>
<input type="text" id="button-text"/>
<button onClick="addButton()">Add Button</button>
</div>
The issue with your existing code is that you have declared the variable i in your for loop, but you are not incrementing the value when you manually add the new button.
If you update your submit button click event as follows, you will accomplish what you are looking for:
$(submit).on("click", function(){
var textBtn = text.val();
family.push(textBtn);
console.log(family);
btns();
i++; // Added the increment of 'i' here.
});
However, I am sure there's a much more eloquent way of solving this problem that doesn't involve keeping track of the array index.
Few things here
You may not need to create the input and the button using js. You can create it using html only
The i in the for loop is global, put a keyword before it and then pass the family[i] to the btns function
var family = ["demo1", "demo2", "demo3", "demo4", "demo5", "demo6"];
function btns(val) {
var btn = $("<button>" + val + "</button>")
$(btn).attr("data-search", val)
$(btn).appendTo("#buttons")
}
for (let i = 0; i < family.length; i++) {
btns(family[i]);
}
$("#submitBtn").on("click", function() {
var textBtn = $("#submitIp").val();
btns(textBtn);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
<div class="container">
<div class="row">
<div id="buttons"></div>
</div>
<div class="row">
<div class="col-sm-3">
<div id="gif"></div>
</div>
<div class="col-sm-9">
<div id="submit">
<input type='text' id='submitIp' name='text'><button id='submitBtn'>Submit</button>
</div>
</div>
</div>
</div>
</body>
here, your loop is the main problem...you need to add element singularly
function ready(){
var family = ["demo1","demo2","demo3","demo4","demo5","demo6"];
function btns(){
var btn = $("<button>" + family[i] + "</button>");
$(btn).attr("data-search", family[i])
$(btn).appendTo("#buttons")
}
var submit = $("<button>Submit</button>");
var text = $("<input type='text' name='text'>");
$(text).appendTo("#submit");
$(submit).appendTo("#submit");
for (i=0; i < family.length; i++){
btns();
}
$(submit).on("click", function(){
var textBtn = text.val();
// family.push(textBtn);
var btn = $("<button>" + textBtn + "</button>");
$(btn).attr("data-search", textBtn)
$(btn).appendTo("#buttons")
})
}
ready();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
<div class="container">
<div class="row">
<div id="buttons"></div>
</div>
<div class="row">
<div class="col-sm-3">
<div id="gif"></div>
</div>
<div class="col-sm-9">
<div id="submit"></div>
</div>
</div>
</div>
</body>
Also, I haven't change your code..just pasted your code on the correct block :)
you are missing selector while getting input val
function ready() {
var family = ["demo1", "demo2", "demo3", "demo4", "demo5", "demo6"];
function btns() {
var btn = $("<button>" + family[i] + "</button>")
$(btn).attr("data-search", family[i])
$(btn).appendTo("#buttons")
}
var submit = $("<button>Submit</button>");
var text = $("<input type='text' name='text'>");
$(text).appendTo("#submit");
$(submit).appendTo("#submit");
for (i = 0; i < family.length; i++) {
btns();
}
$(submit).on("click", function() {
var textBtn = $( "input[name='text']" ).val();
family.push(textBtn);
btns();
})
}
ready();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
<div class="container">
<div class="row">
<div id="buttons"></div>
</div>
<div class="row">
<div class="col-sm-3">
<div id="gif"></div>
</div>
<div class="col-sm-9">
<div id="submit"></div>
</div>
</div>
</div>
</body>
You're referring i in your btns function. The recommended way is to create a scope for any variable. I prefer to use let and const to scope the variables.
You have to move the iteration into the btns function and create another function which is solely responsible to create a button with the text passed as a parameter. And call the create button function from your btns function. And easily you can reuse the create button function even for your click event handler.
The sample code can be found here: https://codesandbox.io/s/pop7vkzpx
I am using form to pass the data from one page to other page.If i click the apply button will go to other page, i want to display the corresponding title of the career(i.e Java Developer) in the next page.I tried to achieve this with the help of javascript.
career.html:
<form action="job portal.html" method="get" target="_blank">
<div class="section-header text-center wow zoomIn">
<h2>Current Oppournities</h2>
</div><br /><br />
<div class="row">
<div class="col-lg-6">
<div class="box wow fadeInLeft">
<h4 class="title" id="career-title" name="career-title"><i class="fa fa-java"></i> <b>Java Developer</b></h4>
<hr />
<div class="carrer-opt">
<h5 name="test">Software Developer</h5>
<p>
Should have join immediate joiner .
</p>
</div>
<div class="col-lg-3 cta-btn-container">
<input type="submit" id="apply" value="Apply Now" onClick="testJS()" />
</div>
</div>
</div>
</form>
js:
<script src="js/main.js"></script>
<script>
function testJS() {
var b = document.getElementById('career-title').value,
url = 'job portal.html?career-title=' + encodeURIComponent(b);
document.location.href = url;
}
</script>
job portal.html:
<h1 id="here" style="color:black"></h1>
js:
<script>
window.onload = function () {
var url = document.location.href,
params = url.split('?')[1].split('&'),
data = {}, tmp;
for (var i = 0, l = params.length; i < l; i++) {
tmp = params[i].split('=');
data[tmp[0]] = tmp[1];
}
document.getElementById('here').innerHTML = data.career-title;
}
</script>
How to acheive this.Anyone please help.
You need to use HTML5 local storage for these kind of problems.
here is solution for your problem.
<script>
function testJS() {
var b = document.getElementById('career-title').value;
var titleText = localStorage.setItem('title', b);
var url = 'job portal.html';
document.location.href = url;
}
</script>
after setting title value get value by referencing id 'title' in your prtal.html script and set value for the element.
<script>
window.onload = function () {
var valueText = localStorage.getItem('title');
document.getElementById('here').innerHTML = valueText;
}
</script>
There is a small hmtml code attached to variable templ. Inside variable templ there is a div with id note-remarks I want to add list of span text something like
<small class="note-tag">tag1</small>
inside it. Where tag1 is dynamic text. These dynamic text is currently alerted as l. Selected tags are the tags selected while making comment.
var tmpl = `<div class="container mb-1">
{{date('m/d/Y')}}
<span class="text-gray pull-right">{{Auth::user()->name}}</span>
<p class="text-gray">
<strong>COMMENT</strong>
</p>
<div id="note-remarks">
</div>
</div>`;
function loadRecentNote(comment,selected_tags){
$('#recent_note').prepend(tmpl.replace("COMMENT", comment));
$.each(selected_tags, function( i, l ) {
alert(l)
});
}
var tmpl = `<div class="container mb-1">
{{date('m/d/Y')}}
<span class="text-gray pull-right">{{Auth::user()->name}}</span>
<p class="text-gray">
<strong>COMMENT</strong>
</p>
<div id="note-remarks"></div>
</div>`;
function loadRecentNote(comment, selected_tags) {
var $tmpl = $(tmpl.replace("COMMENT", comment));
$.each(selected_tags, function(i, l) {
$tmpl.find('#note-remarks').append('<small class="note-tag">' + l + '</small>')
});
$("#recent_note").prepend($tmpl);
}
loadRecentNote('comment', ["tag1", "tag2"]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<div id="recent_note"></div>
Try this: You can append all selected tags in a variable and then replace it with html of noter-remarks
var tmpl = `<div class="container mb-1">
{{date('m/d/Y')}}
<span class="text-gray pull-right">{{Auth::user()->name}}</span>
<p class="text-gray">
<strong>COMMENT</strong>
</p>
<div id="note-remarks">
</div>
</div>`;
function loadRecentNote(comment,selected_tags){
$('#recent_note').prepend(tmpl.replace("COMMENT", comment));
var selectedText = '';
$.each(selected_tags, function( i, l ){
//alert(l);
selectedText += '<small class="note-tag">' + l + '</small>';
});
$('#recent_note #note-remarks').html(selectedText);
}
To achieve this you can use map() on the array of selected_tags to build a HTML string which you can then use to replace() a marker in the template; similar to how your logic is currently working for COMMENT. Try this:
var tmpl = `
<div class="container mb-1">
{{date('m/d/Y')}}
<span class="text-gray pull-right">{{Auth::user()->name}}</span>
<p class="text-gray">
<strong>COMMENT</strong>
</p>
<div id="note-remarks">REMARKS</div>
</div>`;
function loadRecentNote(comment, selected_tags) {
var remarksHtml = selected_tags.map(function(tag) {
return `<small class="note-tag">${tag}</small>`;
}).join('');
var html = tmpl.replace("COMMENT", comment)
html = html.replace("REMARKS", remarksHtml)
$('#recent_note').prepend(html);
}
loadRecentNote('Comment foo bar', ['tag #1', 'tag #2']);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="recent_note"></div>
Select your element, identifying it uniquely and set it to the new value with ".text("arg")"
jQuery method:
$(".note-tag").text("updateText");
Hi how to append div inside button on click this is my JavaScript:
function addLoader() {
var div = document.createElement('div');
div.innerHTML = '<div class="loader"> <div class="loader-ring"> <div class="loader-ring-light"></div> </div> </div>';
var test01 = document.createElement('button');
test01.appendChild(div);
console.log(test01);
}
I want to add innerHTML inside button tags on click
<button onclick="addLoader(this);">testt </button>
It must be like this when function is finish :
<button>testt <div class="loader"> <div class="loader-ring"> <div class="loader-ring-light"></div> </div> </div> </button>
HTML
// Added id attribute
<button onclick="addLoader();" id = "test01">testt </button>
JS
function addLoader() {
var _div = document.createElement('div');
_div.innerHTML = '<div class="loader"> <div class="loader-ring"> <div class="loader-ring-light"></div> </div> </div>';
//append _div to button
document.getElementById("test01").appendChild(_div);
}
Working jsfiddle
EDIT
This will append element to any button call addLoader on click
function addLoader(elem) {
var _div = document.createElement('div');
_div.innerHTML = '<div class="loader"> <div class="loader-ring"> <div class="loader-ring-light"></div> </div> </div>';
elem.appendChild(_div);
}
Updated jsfiddle
var btn = document.getElementById("addLoader");
if (btn) {
btn.addEventListener('click', addLoader, false);
}
function addLoader() {
var div = document.createElement('div');
div.innerHTML = '<div class="loader"> <div class="loader-ring"> <div class="loader-ring-light"></div> </div> </div>';
this.appendChild(div);
}
<button id="addLoader">Test</button>
You just need one more line of code. The variable test01 is created in memory but not added to the DOM. You must append this new element to the DOM (ie. document.appendChild(test01))