How to display user input as a chat bubble using simple javascript? - javascript

I'm developing a chatbox and I have the chat messages hardcoded for the moment.
<!-- Reciever Message-->
<div class="media w-50 ml-auto mb-3">
<div class="media-body">
<div class="bg-primary rounded py-2 px-3 mb-2">
<p class="text-small mb-0 text-white">Test chat</p>
</div>
</div>
</div>
I have a form with a simple input box.
<form action="#" class="bg-light">
<div class="input-group">
<input type="text" placeholder="Type a message" aria-describedby="button-addon2" class="form-control rounded-0 border-0 py-4" id="message">
<div class="input-group-append">
<button id="button-addon2" type="submit" class="btn btn-link" onclick="addText()"> <i class="fa fa-paper-plane"></i></button>
</div>
</div>
</form>
What I want is a way to display the text entered in the text box as the receive message div when the form is submitted. Any suggestions as to how to do it. Thanks in advance.

This is really a design question, not a technical one. Technically speaking you just do exactly what you are doing ... and then put a "chat bubble graphic" as the background-image style of .bg-light.

Related

Create a dynamic div with JavaScript

I have created a page of feeds in which a new post should be created and shown in the user's feed. Lets say the div will look like this
In the textarea the data is entered and then on click of the post button the lower div is created
I have done this in javascript but the name, image, all data is simply entered by me but it should come from the controller I cant use the simple approach like I have done in HTML page how can it be done in javascript?
<body>
<textarea class="form-control border-0 p-0 fs-xl" rows="4" id="input" placeholder="What's on your mind Codex?..."></textarea>
<button class="btn btn-info shadow-0 ml-auto " id="submit" onclick="addCode()">Post</button>
<div id="add_after_me">
<div class="test " >
</div>
</div>
<script>
$('#submit').click(function () {
var text = $('#input').val();
$('#newDivs').append('<div class="test">' + text + '</div>');
});
function addCode() {
document.getElementById("add_after_me").insertAdjacentHTML("afterend",
'<div class="card mb-g"> < div class= "card-body pb-0 px-4" ><div class="d-flex flex-row pb-3 pt-2 border-top-0 border-left-0 border-right-0"><div class="d-inline-block align-middle status status-success mr-3"> <span class="profile-image rounded-circle d-block" style="background-image:url(); background-size: cover;"></span> </div> <h5 class="mb-0 flex-1 text-dark fw-500"> Dr. John Cook PhD <small class="m-0 l-h-n">Human Resources & Psychiatry Division</small></h5><span class="text-muted fs-xs opacity-70"> 3 hours </span> </div> <div class="pb-3 pt-2 border-top-0 border-left-0 border-right-0 text-muted " id="newDivs"> </div> </div ></div > ');
}
</script>
</body>
here is my code
I'm assuming that you have a Controller that can receive POST data, will handle it, then will respond an JSON with all the processed data that you want your Javascript to display.
We will use simple Ajax with jQuery here. We will start by sending the form via post to your controller when you submit the form, then we will assume that your controller respond a json with the same data once it's done. Then javascript will read the Json responded, and update the DOM.
Here is your code :
<body>
<textarea class="form-control border-0 p-0 fs-xl" rows="4" id="input" placeholder="What's on your mind Codex?..."></textarea>
<button class="btn btn-info shadow-0 ml-auto " id="submit" onclick="addCode()">Post</button>
<div id="add_after_me"></div>
<script>
$('#submit').click(function () {
$.post('/your-controller', {
text: $('#input').val()
}, function(data) {
const json = jQuery.parseJSON(data)
addCode(json)
})
});
function addCode(data) {
const addAfterMe = $("#add_after_me")
const template = `
<div class="card mb-g">
<div class= "card-body pb-0 px-4">
<div class="d-flex flex-row pb-3 pt-2 border-top-0 border-left-0 border-right-0">
<div class="d-inline-block align-middle status status-success mr-3">
<span class="profile-image rounded-circle d-block" style="background-image:url('${data.image}'); background-size: cover;"></span>
</div>
<h5 class="mb-0 flex-1 text-dark fw-500">
${data.fullname}
<small class="m-0 l-h-n">${data.department}</small>
</h5>
<span class="text-muted fs-xs opacity-70">
${data.time}
</span>
</div>
<div class="pb-3 pt-2 border-top-0 border-left-0 border-right-0 text-muted" id="newDivs">${data.text}</div>
</div>
</div>`
addAfterMe.append(template)
}
</script>
</body>
To create your "card", I use "Template Literals" javascript standard. But feel free to use whatever strategy you want.
So, each time that you will submit your form, the text will be sent to the Controller. Assuming that your controller will response this JSON :
{
'text': "Lorem Ipsum",
'image': "https://url-to-your-profile-image.com/image.png",
'fullname': 'Dr. John Cook PhD',
'department': 'Human Resources & Psychiatry Division',
'time': '3 hours'
}
And voila :)
I hope it helps !

Vue js edit content according to its ID

I’m starting with vue js and I’m listing some data from database. More specifically posts with title, description and images.
I have Edit and Delete buttons. All posts are loaded using v-for. So when I click to edit one post, all the posts are “openning” to be edited.
I need to open the editing only in one post at a time. I mean, the specific post I really want to edit.
I made some progress with title input and with image delete badge but still need to work on Save and Cancel buttons (they open in all posts) and input files (when I choose files in second post for example, they load into first post).
<div id="app" class="row mb-50">
<div v-for="(item, index) in tours" v-bind:key="item.id" id="tours" class="col-md-12 mb-30">
<div class="tour-list">
<div class="tour-list-title">
<p>
<!-- here I can block input title to be disabled on other posts not than the specific one and I intend to do the same with textarea -->
<input class="inputEdit" type="text" ref="item.id" v-model="item.title"
:disabled="editingTour !== item.id" :class="{inputEditOpen: !editingTour}" />
</p>
</div>
<div class="tour-list-description">
<p>
<textarea class="inputEdit" :disabled="!editingTour" v-model="item.description"
:class="{inputEditOpen: !editingTour}">
{{ item.description }}
</textarea>
</p>
</div>
<div class="tour-list-pics">
<div class="row mb-20">
<div class="col-md-12">
<ul class="pics-list">
<li v-for="(image, index) in item.images">
<!-- here I could hide badge -->
<span :hidden="editingTour !== item.id" class="badge"
#click="$delete(item.images, index), deleteImage(image.imageID)">
<i class="fa fa-fw fa-times-circle"></i>
</span>
<div class="pics-list-image-container img-fluid cursor-pointer"
v-bind:style="{'background-image': 'url(http://localhost/tours/'+image.image + ')' }"
#click="openModal = true, showModal(image.image)">
</div>
</li>
<li v-if="urls" v-for="(url, key) in urls" :key="key">
<div id="preview" :ref="'url'" class="pics-list-image-container img-fluid"></div>
</li>
<li v-if="editingTour" class="add-pics-item">
<div :hidden="editingTour !== item.id" class="mt-10">
<label for="file-upload" class="custom-file-upload">
<img class="img-fluid" src="./img/plus-icon.png">
</label>
<input id="file-upload" type="file" #change="onFileChange"
name="files[]" multiple />
</div>
</li>
</ul>
</div>
</div>
</div>
<div class="tour-list-options">
<div class="row">
<div class="col-md-6">
<span>
<button #click="editingTour = item.id" v-if="!editingTour"
class="btn border btn-circle tour-list-edit-btn">Edit</button>
</span>
<span>
<button #click="editTour(item)" v-if="editingTour"
class="btn border btn-circle tour-list-edit-btn">Save</button>
</span>
<span>
<button #click="clearInput" v-if="editingTour"
class="btn border btn-circle tour-list-delete-btn">Cancel</button>
</span>
<span>
<button #click="deleteTour(item.id, index)" v-if="!editingTour"
class="btn border btn-circle tour-list-delete-btn">Delete</buton>
</span>
</div>
</div>
</div>
</div>
</div>
</div>
Update
If I use
<button #click="editTour(item)" v-if="editingTour == item.id" class="btn border btn-circle tour-list-edit-btn">Save</button>
all others Save buttons get hidden.
I think you can use add to each object of list new property isEditing and look for it in each item of the loop to check Save/Edit show.
Now your one prop editingTour can't be used for multiple edit, it can't store array of edited items id.
Template of buttons would look like:
<span>
<button #click="item.isEditing = item.id" v-if="!item.isEditing"
class="btn border btn-circle tour-list-edit-btn">Edit</button>
</span>
<span>
<button #click="editTour(item)" v-if="item.isEditing"
class="btn border btn-circle tour-list-edit-btn">Save</button>
</span>
<span>
<button #click="clearInput(item)" v-if="item.isEditing"
class="btn border btn-circle tour-list-delete-btn">Cancel</button>
</span>
<span>
<button #click="deleteTour(item.id, index)" v-if="!item.isEditing"
class="btn border btn-circle tour-list-delete-btn">Delete</button>
</span>

Button's message pop up without click

This is a screenshot of a normal google search
I'm trying to get the tiny message box when you go to the mic icon on Google search engine. I want to incorporate that to my bootstrap buttons. Following is the code where i want to add a similar message box on Connect and Disconnect button.
<div class="container">
<div class="row">
<div class="col-12 col-sm-6 col-md-6">
<br>
<img style="width:30%" src="icon1.jpg">
<br>
<br>
<button type="button" class="btn btn-success" >
<a style="color:white;" href= "options.html" >
Connect
</a>
</button>
</div>
<div class = "col-12 col-sm-6 col-md-6 ">
<br>
<img style="width:30%" class="float-right" src="icon1.jpg" >
<br>
<br>
<br>
<br>
<br>
<div class ="text-right">
<button type="button" class="btn btn-danger ">
<a style="color:white;" href= "options.html" >
Disconnect
</a>
</button>
</div>
</div>
</div>
</div>
What you're looking for are tooltips. Check out bootstrap's documentation about them here.
You can follow this code with bootstrap. use data-toggle="tooltip" to your button from where you want hover, title is the tooltip/popup and add below script to the footer. For more follow the link https://www.w3schools.com/bootstrap/bootstrap_tooltip.asp
Hover over me
<script>
$(document).ready(function(){
$('[data-toggle="tooltip"]').tooltip();
});
</script>

Searching and filtering through list elements JS

In todolist i try to search my values so that i use indexOf!=-1 property ,when i console log everything works but i dont see that on screen strangely, i want to see only what i search.
html
<div class="container">
<div class="row">
<div class="col-md-5 mx-auto mt-5">
<div class="card p-4">
<h3 class="result-title">My Program</h3>
<input type="text" placeholder="Search" class="search"/>
<div class="card-body ">
<ul class="result-list">
<li class="result-item">Go to the Shop</li>
</ul>
</div>
</div>
<div class="card mt-5 p-5">
<h3> Add Here </h3>
<form>
<input type="text" class="addtext" placeholder="SOME "/>
<button class="addbutton">Add </button>
</form>
</div>
</div>
</div>
</div>
JS file
// ADDING ITEM //
document.querySelector(".addbutton").addEventListener("click",(event)=>{ event.preventDefault()
const text=document.querySelector(".addtext").value
const asd=document.createElement("li")
asd.classList.add("result-item") ;
asd.innerHTML=text
document.querySelector(".result-list").appendChild(asd)
document.querySelector(".addtext").value=""
} )
//SEARCH ITEM//
const search=document.querySelector(".search")
search.addEventListener("change",()=>{
const list=document.querySelectorAll(".result-item")
search.value.toLowerCase()
list.forEach(item=>{
if(item.innerHTML.toLowerCase().indexOf(search.value)!=-1) {item.style.display==="block"}else{;item.style.display==="none"}}) })
You need use =, not ===.
item.style.display="block"}else{;item.style.display="none"}
One equal sign changes the value, while two or three compare the value.

JS: Expand position:absolute parent when dynamically adding relative divs

I am using absolutely positioned containers to slide screens left and right on "Next" and "Back". You can see this here: http://opencdesign.herokuapp.com/offer
Click "Got it" to move to 2nd screen, which is where the problem lies. If you click "Add item or category" enough times, the inputs will expand past the footer.
What is the simplest way to expand the height of the window as I add inputs? I'm also open to an alternative method of sliding screens left and right than using absolute positioning.
HTML
<div id="offer-2">
<div class="row one-margin-bottom">
<div class="small-12 medium-11 small-centered columns">
<h5 class="">What share of purchases will you accept in Currents?</h5>
<!-- <a class="offer-info-popup_open"><i class="half-margin-right fa fa-lg fa-question-circle"></i>How it works</a> -->
</div>
</div>
<div class="row left">
<div class="small-12 medium-6 small-centered columns">
<div class="row">
<div class="input-left small-3 columns">
<p><strong><img class="" src="{% static 'img/symbol-navy.svg' %}"/> share</strong></p>
</div>
<div class="input-right small-9 columns">
<p id="item-title"><strong>Item or category</strong></p>
</div>
</div>
</div>
</div>
<div class="row">
<div class="small-12 medium-6 small-centered columns">
<div id="item-1" class="row collapse">
<div class="input-left small-3 columns">
<div class="relative">
<input name="discount-amount-1" type="number" class="fit-left qtr-margin-right" placeholder="20" value="20"/>
<span class="input-icon-right">%</span>
</div>
<!-- <span class="input-sizer"><select name="discount-type-1">
<option selected>% of</option>
<option>$ of</option>
</select></span> -->
</div>
<div class="input-right small-9 columns">
<div class="fit-left half-margin-top one-margin-right one-margin-left">of</div>
<div class="relative input-sizer">
<input name="item-name-1" type="text" placeholder="Item or category name" value="All products" class="good-cat" />
<i class="remove-input alert fa fa-times"></i>
</div>
</div>
</div>
<div id="item-2" class="row collapse">
<div class="input-left small-3 columns">
<div class="relative">
<input name="discount-amount-2" type="number" class="fit-left qtr-margin-right" placeholder="20" value="20"/>
<span class="input-icon-right">%</span>
</div>
<!-- <span class="input-sizer"><select name="discount-type-1">
<option selected>% of</option>
<option>$ of</option>
</select></span> -->
</div>
<div class="input-right small-9 columns">
<div class="fit-left half-margin-top one-margin-right one-margin-left">of</div>
<div class="relative input-sizer">
<input name="item-name-2" type="text" placeholder="Item or category name" value="All services" class="good-cat" />
<i class="remove-input alert fa fa-times"></i>
</div>
</div>
</div>
<a id="add-item" class=""><i class="half-margin-top fa fa-plus-circle half-margin-right"></i>Add item or category</a>
<div class="row one-margin-top">
<a class="prev-offer button round secondary">Back</a>
<a class="next-offer button round">Next</a>
</div>
</div>
</div>
</div>
JS
var id = 3
$('#add-item').click(function(){
$(this).before('<div id="item-'+id+'" class="row collapse hidden"><div class="input-left small-3 columns"><div class="relative"><input name="discount-amount-'+id+'" type="number" class="fit-left qtr-margin-right" placeholder="20" value="20"/><span class="input-icon-right">%</span></div></div><div class="input-right small-9 columns"><div class="fit-left half-margin-top one-margin-right one-margin-left">of</div><div class="relative input-sizer"><input name="item-name-'+id+'" type="text" placeholder="Item or category name" /><i class="remove-input alert fa fa-times"></i></div></div></div>');
$('#item-'+id+'').slideDown();
id ++
});
I think you could potentially target the div with a CSS rule and handle its overflow-y with scroll (or increase its size, if you want to expand it). For a quick example, using jQuery, you could have a condition followed by $('#mydiv').css("overflow-y", "scroll"); (though it doesn't look like that div currently has an ID or custom Classname, so feel free to change that to whatever works best).
Alternatively, you could use a second, hidden div which is a parent to this one, and expand the hidden div. By using a relative size, you'd be able to fill into the invisible parent =)
It looks good, though!

Categories