Character counter showing within the input field - javascript

I have an input field and I want to be able to show the length of characters being typed in but I want it to be within the input box all the way to the end of the input box. I'm not even sure where to start to do this.
Not really sure where to start.
<label class="label is-capitalized">Description One </label>
<div class="field">
<div class="control is-expanded">
<input type="text" class="input size19" placeholder="description one" v-model="keyword">
</div>
<div>
var app = new Vue ({
el: '#app',
data: {
keyword: 'hello'
}
})
A counter within the input field pulled to the right edge

this can be handled in CSS in many ways
// Instantiating a new Vue instance which has preinitialized text
var app1 = new Vue({
el: '#app1',
data: {
keyword: 'hello'
}
});
.field {
margin: 1em;
}
.input {
padding-right: 30px;
}
.input-count {
margin: -30px;
opacity: 0.8;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<!-- App 2 -->
<div id="app1">
<div class="field">
<div class="control is-expanded">
<input type="text" class="input size19" placeholder="description one" v-model="keyword" />
<span v-if="keyword.length" class="input-count">{{keyword.length}}</span>
</div>
<div>

You'll have to use CSS to achieve this. Because you cannot get something like this within the input box:
some text in input 18
There has to another div overlapping your input box. See this:
var counter = document.getElementById ('counter'),
input = document.getElementById ('inp');
counter.innerHTML = input.value.length;
input.addEventListener ('keyup', function (e) {
counter.innerHTML = input.value.length;
});
.inline-block {
display: inline-block;
}
.relative {
position: relative;
}
.absolute {
position: absolute;
}
#counter {
top: 0;
right: 0
}
<div class='container'>
<label class="label is-capitalized">Description One </label>
<div class="field">
<div class="control is-expanded relative inline-block">
<input type="text" class='input' id="inp" placeholder="description one" />
<div id='counter' class='absolute'>
</div>
</div>
<div>
</div>
You can add additional styling if needed.

Try this
<div id="app1">
<br>
<div class="holder">
<label>
{{keyword.length}}
</label>
<input type="text" class="input size19" placeholder="description one" v-model="keyword">
</div>
CSS
holder {
position: relative;
}
.holder label {
position: absolute;
left: 200px;
top: 26px;
width: 20px;
height: 20px;
}
.holder input {
padding: 2px 2px 2px 25px;
}
Check the below fiddle for the solution
https://jsfiddle.net/zr968xy2/4/

Related

How can I change between a Login/Sign up Form?

I'm doing a project where I have to create a website. Currently I am making the Login/Sign up Form, however I don't know how to change between them using a link.
This is my html code for it:
<div class="container">
<form class="form--unhidden" id="Login">
[...some code is meant to be here to input username/password input + continue button]
<p class="form__text" id="ToCreateAccount">
<a class="form__link" href="#ChangeCreateAccount" id="linkCreateAccount">Don't have an account? Create account</a>
</p>
</form>
<form class="form--hidden" id="CreateAccount">
[...some code is meant to be here to create username/password input + continue button]
<p class="form__text" id="ToLogin">
<a class="form__link" href="#ChangeLogin" id="linkLogin">Already have an account? Sign in</a>
</p>
</form>
</div>
This is my JavaScript for the code:
document.addEventListener("DOMContentLoaded", () => {
const loginForm = document.querySelector("#Login");
const createAccountForm = document.querySelector("#CreateAccount");
,
e.preventDefault();
loginForm.classList.remove("form--hidden");
createAccountForm.classList.add("form--hidden");
});
document.querySelector("#ToLogin").addEventListener("click", e => {
e.preventDefault();
loginForm.classList.add("form--hidden");
createAccountForm.classList.remove("form--hidden");
});
I've tried to solve this by adding an id to the class="form__text" line and then connect it to the javascript, and also add # or/and "link" to inside the brackets (e.g. #ToCreateAccount).
document.querySelector("#ToCreateAccount").addEventListener("click", e => {
I believe that the problem is that the JavaScript doesn't fully know what's meant to chance, but I can't figure out how to make it understand it.
Hope this is understandable.
Thank you so much for your help.
You were close. I'm guessing your original code should have had this part:
document.querySelector("#ToCreateAccount").addEventListener("click", e => {
right after this part:
const createAccountForm = document.querySelector("#CreateAccount");
Please take a look at the following example. I've added some of the missing elements, and some simple CSS.
document.addEventListener("DOMContentLoaded", function() {
var create = document.getElementById("linkCreateAccount");
var haveAcc = document.getElementById("linkLogin");
var formLogin = document.getElementById("Login");
var formCreateAcc = document.getElementById("CreateAccount");
create.addEventListener("click", function(e) {
e.preventDefault();
hide(formLogin);
show(formCreateAcc);
});
haveAcc.addEventListener("click", function(e) {
e.preventDefault();
show(formLogin);
hide(formCreateAcc);
});
});
function hide(elem) {
elem.classList.add("form--hidden");
elem.classList.remove("form--unhidden");
}
function show(elem) {
elem.classList.add("form--unhidden");
elem.classList.remove("form--hidden");
}
.container {
padding: 15px;
background-color: #ccc;
font-family: 'Arial','Calibri',sans-serif;
}
.form--unhidden {
display: block;
}
.form--hidden {
display: none;
}
label, input {
display: block;
}
input {
border-radius: 5px;
border: 1px solid #ccc;
margin-top: 3px;
margin-bottom: 3px;
padding: 4px;
}
a.form__link {
text-decoration: none;
transition: 0.5s;
}
button {
margin-top: 5px;
padding: 4px 8px;
border-radius: 3px;
border: 1px solid transparent;
background-color: rgb(9, 100, 170);
color: rgb(255, 255, 255);
cursor: pointer;
display: inline-block;
outline-style: none;
outline-width: 0px;
overflow-wrap: break-word;
position: relative;
text-align: center;
}
a.form__link:hover {
color: #aa5810;
}
<div class="container">
<form class="form--unhidden" id="Login" action="loginPage" method="POST">
<div class="form-inputs">
<label for="username">Username:</label>
<input type="text" id="username" name="username">
</div>
<div class="form-inputs">
<label for="pass">Password:</label>
<input type="password" id="pass" name="pass">
</div>
<div class="form-inputs">
<button type="submit">Login</button>
</div>
<p class="form__text" id="ToCreateAccount">
<a class="form__link" href="#CreateAccount" id="linkCreateAccount">Don't have an account? Create account</a>
</p>
</form>
<form class="form--hidden" id="CreateAccount" action="registerPage" method="POST">
<div class="form-inputs">
<label for="newUsername">Username:</label>
<input type="text" id="newUsername" name="newUsername">
</div>
<div class="form-inputs">
<label for="newPass">Password:</label>
<input type="text" id="newPass" name="newPass">
</div>
<div class="form-inputs">
<label for="againPass">Retype password:</label>
<input type="text" id="againPass" name="againPass">
</div>
<div class="form-inputs">
<label for="newEmail">Username:</label>
<input type="text" id="newEmail" name="newEmail">
</div>
<div class="form-inputs">
<button type="submit">Register</button>
</div>
<p class="form__text" id="ToLogin">
<a class="form__link" href="#ChangeLogin" id="linkLogin">Already have an account? Sign in</a>
</p>
</form>
</div>
The hiding / showing is handled similar to what you were trying to do, I just placed it in a function.

JavaScript get multiple element's text values

I want to make that when the user clicks onto the bordered container, the 'Name' text should show the container's name only and the 'Subject' text should show the container's subject only, but this code shows all the elements inside the container for the 'Name' and the 'Subject' too.
I mean there are two elements inside one container. One with class 'name' and one with the class 'subject'. When I click onto the bordered container I want to get the 'name' text's and write it into the element with the class resname. And the same thing with the subject. Any idea how to solve it?
var name = document.querySelectorAll('.name');
var gname = $('.resname');
var gsub = $('.ressubject');
$('.container').click(function() {
gname.text($(this).text());
gsub.text($(this).text());
});
.container {
border: 1px solid red;
cursor: pointer;
padding: 5px;
}
.resname, .ressubject {
color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="header">
<span class="name">firstname</span>
</div>
<div class="body">
<span class="subject">firstsubject</span>
</div>
</div>
<br>
<div class="container">
<div class="header">
<span class="name">secondname</span>
</div>
<div class="body">
<span class="subject">secondsubject</span>
</div>
</div>
<hr><br>
<div class="result">
<span>Name: <span class="resname"></span></span><br>
<span>Subject: <span class="ressubject"></span></span>
</div>
is that what you want?
const container = document.querySelector('.container');
const output = document.querySelector('.output');
const outputItemName = output.querySelector('.output-item > span[data-name]');
const outputItemSubject = output.querySelector('.output-item > span[data-subject]');
container.addEventListener('click', (e) => {
const containerItem = e.target.closest('.container-item');
if (!containerItem) return;
const { name, subject } = containerItem.dataset;
outputItemName.innerText = name;
outputItemSubject.innerText = subject;
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container-inner>* {
margin-bottom: 16px;
}
.container-inner>*:last-of-type {
margin-bottom: 0;
}
.container-item {
padding: 8px;
border: 1px solid black;
cursor: pointer;
}
.output {
margin-top: 16px;
}
<div class="container">
<div class="container-inner">
<div class="container-item" data-name="First name" data-subject="First subject">
<div class="container-item-name">First name</div>
<div class="container-item-subject">First subject</div>
</div>
<div class="container-item" data-name="Second name" data-subject="Second subject">
<div class="container-item-name">Second name</div>
<div class="container-item-subject">Second subject</div>
</div>
</div>
</div>
<div class="output">
<div class="output-inner">
<div class="output-item">
<span>Name:</span>
<span data-name></span>
</div>
<div class="output-item">
<span>Subject:</span>
<span data-subject></span>
</div>
</div>
</div>

Javascript not creating spans as supposed to

I have a hardcoded span group to which I would like to add more spans from user input, I have tried to do this with a template and without but neither option works out for me
CSS:
.item { /*This is the style I want my new spans to inherit*/
display: flex;
align-items: center;
height: 48px;
line-height: 48px;
cursor: pointer;
padding-left: 24px;
}
.item:hover {
background-color: rgba(0, 0, 0, 0.04);
}
I'm trying to collect a user input from my modal to append it into my other spans which I hardcoded to see what it looks like for now
HTML:
<!------------------------------------------------------------- The modal from which i will be taking the input---------------------------------->
<div id="myModal" class="modal">
<!-- Modal content -->
<div class="modal-content">
<form name="newLayerForm" onsubmit="return validateNewLayerName()" method="post" required>
<span class="close">×</span>
<p>Name your new Layer: </p>
<input placeholder="Type your desired layer name" type="text" name="newLayerName" id="newLayerName">
<button type="submit" value="submit" id="submitNewLayer" class="miro-btn miro-btn--primary miro-btn--small"
style="border: none; background-color: rgb(46,139,87); font-size: 15px; padding: 0px">Create</button>
</form>
</div>
</div>
<!----------------------------------------------------------------End of modal ------------------------------------------------------------------>
</div>
<template>
<div class="item item-layer"><span id="displayLayer"></span></div>
<span>sample layer 1</span>
<span>sample layer 2</span>
<!------------------------------------ template for the first function to add spans into ----------------->
</template>
<div class="miro-p-medium" style="font-size: 20px;">
<div class="item item-layer"><span id="displayLayer">sample layer 1</span></div>
<div class="item item-layer"><span>sample layer 2</span></div>
<div class="item item-layer"><span>sample layer 3</span></div>
<div class="item item-layer"><span>sample layer 4</span></div>
</div>
I have tried 2 ways to achieve this in my javascript code, 1 way with doing all of this inside a template and the other way to just use a div, at some point the input was being added when i appended it to body for about 1 second before disappearing, but I would also like the input from modal to inherit the same style and place in html as the 4 hardcoded spans I have right now
Javascript:
let template = document.querySelector('template').content
let layerTemplate = template.querySelector(".item-layer")
//modals
let modal = document.getElementById("myModal")
let btn = document.getElementById("btnCreate")
let span = document.getElementsByClassName("close")[0]
//function layerCreator(userInput) { // attempt with template
//let layerEl = layerTemplate.clondeNode(true)
//layerEl.querySelector("span").innerText = userInput
//document.getElementById("displayLayer").innerHTML = userInput
//return layerEl
//}
function layerCreatorX(input) { //attempt to directly insert into body
let x = document.createElement("span")
let t = document.createTextNode(input)
x.appendChild(t)
document.body.appendChild(x)
}
function validateNewLayerName() { // validates for empty input from input field
let input = document.forms["newLayerForm"]["newLayerName"].value
if (input == "" || input == null) {
alert("Cannot submit empty field, please try again!")
return false
}
else {
//this appends layer list with new layer
layerCreatorX(input)
}
}
I'm not too experienced in JS so I will be thankful for any suggestions or articles to look into
added just the most essential parts of the code, can add more if needed
Update: Forgot to include the function where i validate input from modal and use the function, it is now added in JS part
You are missing some key things:
You didn't post your validateNewLayerName function. This should return false, to avoid submitting the form.
You are not calling layerCreatorX and passing the value of newLayerName in the newLayerForm form.
You did not apply the class names item item-layer to the new span you created.
You are not adding the span to the .miro-p-medium container.
const template = document.querySelector('template').content
const layerTemplate = template.querySelector(".item-layer")
const modal = document.getElementById("myModal")
const btn = document.getElementById("btnCreate")
const span = document.getElementsByClassName("close")[0]
function validateNewLayerName() {
let input = document.forms["newLayerForm"]["newLayerName"].value
if (input == "" || input == null) {
alert("Cannot submit empty field, please try again!");
} else {
layerCreatorX(input);
}
return false; // Avoid submitting the form...
}
function layerCreatorX(input) {
const x = document.createElement("span");
const t = document.createTextNode(input);
x.className = 'item item-layer'; // Add the appropriate class.
x.appendChild(t);
document.querySelector('.miro-p-medium').appendChild(x);
// Let the modal window know that is can be closed now...
}
.item {
display: flex;
align-items: center;
height: 48px;
line-height: 48px;
cursor: pointer;
padding-left: 24px;
}
.item:hover {
background-color: rgba(0, 0, 0, 0.04);
}
.modal {
position: absolute;
border: thin solid grey;
background: #FFF;
padding: 0.5em;
right: 4em;
}
<div id="myModal" class="modal">
<div class="modal-content">
<form name="newLayerForm"
onsubmit="return validateNewLayerName()"
method="post" required>
<span class="close">×</span>
<p>Name your new Layer: </p>
<input type="text" id="newLayerName" name="newLayerName"
placeholder="Type your desired layer name">
<button type="submit" id="submitNewLayer" value="submit"
class="miro-btn miro-btn--primary miro-btn--small"
style="border: none; background-color: rgb(46,139,87); font-size: 15px; padding: 0px">Create</button>
</form>
</div>
</div>
<template>
<div class="item item-layer">
<span id="displayLayer"></span>
</div>
<span>sample layer 1</span>
<span>sample layer 2</span>
</template>
<div class="miro-p-medium" style="font-size: 20px;">
<div class="item item-layer"><span id="displayLayer">sample layer 1</span></div>
<div class="item item-layer"><span>sample layer 2</span></div>
<div class="item item-layer"><span>sample layer 3</span></div>
<div class="item item-layer"><span>sample layer 4</span></div>
</div>

javascript/jquery onChange function for div.text to update form hidden field value

My Classic ASP cart page uses divs for a quantity selector within a form:
<form action="/update-cart/" method="post">
<div class="quantity-selector detail-info-entry">
<div class="detail-info-entry-title">Quantity</div>
<div class="entry number-minus"> </div>
<div class="entry number">1</div>
<div class="entry number-plus"> </div>
</div>
</div>
</form>
when - or + is clicked the 1 will update as expected. the code to do this is this:
$('.number-plus').on('click', function(){
var divUpd = $(this).parent().find('.number'), newVal = parseInt(divUpd.text(), 10)+1;
divUpd.text(newVal);
});
$('.number-minus').on('click', function(){
var divUpd = $(this).parent().find('.number'), newVal = parseInt(divUpd.text(), 10)-1;
if(newVal>=1) divUpd.text(newVal);
});
What is the easiest way to post the content of the div with class "number" above when a form is submitted. Do i use:
<input type="hidden" id="Num" name="Num" value="" />
Or another way. Either way, how can this be done easily as I cannot get the variable "newVal" to populate the hidden field.
Thanks
This demo has 2 features of note.
The following are done with HTML and inline JS (e.g. onchange='...)
<input>s .number-minus and number-plus
<output> .number displays the sum of .number-minus and .number-plus
As requested, the sum of .number-minus and .number-plus is stored in a <input [hidden]> named .secret. This value was derived from <output> value by using jQuery (overkill IMO). `
$(function() {
$('#pos, #neg').on('change', function(event) {
var cnt = $('#counter').val();
$('#secret').val(cnt);
console.log('Secret: ' + secret.value);
});
});
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>javascript/jquery onChange function for div.text to update form hidden field value</title>
<meta name="description" content="SO33312004">
<style>
.detail-info-entry-title,
#pos,
#neg {
font-variant: small-caps;
}
.entry {
padding: 3px;
margin: 0 5px;
width: 48px;
line-height: 1.6;
border: 2px solid #00E;
border-radius: 8px;
display: table-cell;
}
#counter {
font-weight: 900;
margin: auto;
display: table-cell;
height: 24px;
}
#form33312004 {
color: #0CF;
background: hsla(180, 100%, 10%, 1);
width: 33%;
height: 30%;
text-align: center;
vertical-align: middle;
display: table-row;
}
.field {
width: 50px;
display: table-cell;
}
footer {
font-size: .75em;
text-align: center;
}
</style>
</head>
<!--http://stackoverflow.com/questions/33312004/javascript-jquery-onchange-function-for-div-text-to-update-form-hidden-field-val-->
<body>
<form id="form33312004" submit="return false" oninput="counter.value = parseInt(pos.value, 10) - parseInt(neg.value, 10)">
<fieldset class="quantity-selector detail-info-entry">
<legend class="detail-info-entry-title">Quantity</legend>
<div class="field">
<input type="number" id="pos" min="0" max="999" step="any" value="0" class="entry number-plus">
<label for="pos">Positive</label>
</div>
<output for='pos neg' id="counter" name="counter" class="entry number">0</output>
<div class="field">
<input type="number" id="neg" min="0" max="999" step="any" value="0" class="entry number-minus">
<label for="neg">Negative</label>
</div>
</fieldset>
<input id="secret" type="hidden">
</form>
<div class="field">
<footer>Observe the hidden input's value thru
<br/>the console. (<b>F12</b> then the <b>Console</b> tab).</footer>
<script sr="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.1.4.min.js"></script>
</body>
</html>
With pure JS:
document.getElementById("Num").value = < variable name >
With jQuery(not 100% sure)
$("Num").value(< variable name>)
So I solved the problem myself.
I added the following line:
$("#Num").val(newVal);
To both the jquery functions for the + and - divs as follows:
$('.number-plus').on('click', function(){
var divUpd = $(this).parent().find('.number'), newVal = parseInt(divUpd.text(), 10)+1;
divUpd.text(newVal);
$("#Num").val(newVal);
});
$('.number-minus').on('click', function(){
var divUpd = $(this).parent().find('.number'), newVal = parseInt(divUpd.text(), 10)-1;
if(newVal>=1) divUpd.text(newVal);
$("#Num").val(newVal);
});
I am sure I had tried this but after thought I may have omitted the $ at the beginning. Always something simple in the end

Travel to particular HTML element of active elements

I need help with jQuery (or JavaScript). I have a form with three checkbox alike elements. Want to get description text and input value for sending the data via AJAX form. Ajax is working quite good but I can not travel to the DOM to bring my desired data.
$('.select-item').on('click', function() {
$(this).toggleClass('active');
})
var activeItems = $('.select-item.active');
for( var i = 0, l = activeItems.length; i < l; i++ ) {
console.log( activeItems[i].children[1] );
console.log( activeItems[i].children[2] );
}
.select-item {
background-color: #f7f7f7;
margin-bottom: 20px;
padding: 15px;
}
.selector {
height: 20px;
width: 20px;
border: 1px solid blue;
position: relative;
}
.selector .circle {
height: 10px;
width: 10px;
background-color: blue;
position: absolute;
top: 5px;
left: 5px;
opacity: 0;
}
.active .selector .circle {
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form id="ticket-booking-form-1">
<div class="select-item active">
<!-- SELECTION ITEM -->
<div class="selector">
<div class="circle"></div>
</div>
<div class="description">
<h4 class="title-text">Day 1 Full Day Ticket <span class="text-color">$129</span></h4>
</div>
<div class="select-input">
<label for="qty-1">QTY</label>
<input type="text" id="qty-1" name="qty-1" value="1" class="form-control">
</div>
</div>
<div class="select-item">
<!-- SELECTION ITEM -->
<div class="selector">
<div class="circle"></div>
</div>
<div class="description">
<h4 class="title-text">Day 1 Full Day Ticket <span class="text-color">$129</span></h4>
</div>
<div class="select-input">
<label for="qty-1">QTY</label>
<input type="text" id="qty-1" name="qty-1" value="1" class="form-control">
</div>
</div>
<div class="select-item">
<!-- SELECTION ITEM -->
<div class="selector">
<div class="circle"></div>
</div>
<div class="description">
<h4 class="title-text">Day 1 Full Day Ticket <span class="text-color">$129</span></h4>
</div>
<div class="select-input">
<label for="qty-1">QTY</label>
<input type="text" id="qty-1" name="qty-1" value="1" class="form-control">
</div>
</div>
<!-- /END SELECTION ITEM -->
<button type="submit" class="btn btn-base btn-lg"><span>Proceed to Checkout</span>
</button>
</form>
The scenario is, Description text and input value of selected (checked) elements should be added into an array or object then I can send single/both/all data of selected (active) elements. Actually I am not good at JS so if you think without adding into array or object solution could be achieved, Perfect!
http://jsfiddle.net/getanwar/t2d3sjmq/
Once you see the fiddle will understand my question.
To get the value of the active inputs use
for( var i = 0, l = activeItems.length; i < l; i++ ) {
console.log( activeItems[i].children[2].children[1].value );
}
With JQuery you can use something like
$('.select-item.active > .select-input').each( function(index,element){
console.log( $(this).find('input').attr('value') );
});

Categories