Toggle like button to create and remove input box - javascript

Am creating an HTML page with some buttons to create the input boxes. The buttons should behave like toggle one. ie, on first click input box should appear and if the same button in clicked again that particular input box need to disappear. Button toggle i have managed. But div is not creating
This is my toggle button
<button class="btn" id="button_rd" onclick="setColor('button_rd', '#101010')";>one</button>
Following is the javascript
var count = 1;
function setColor(btn, color) {
var property = document.getElementById(btn);
if (count == 0) {
property.style.backgroundColor = "#f4543c"//red
property.style.borderColor = "#f4543c"
count = 1;
}
else {
property.style.backgroundColor = "#00a65a"//green
property.style.borderColor = "#008d4c"
count = 0;
var newdiv = '<div class="form-group"><label for="exampleInputEmail1">email</label>'
+'<input type="email" class="form-control" id="exampleInputEmail1" placeholder="Enter email"></div>'
document.getElementById("create").append(newdiv);
}
}
And below is the place where I need the input box to display(inside this div)
<div class="box-body" id="create">
</div>

If you're happy to use Jquery, Something like this may be what you're looking for.
it's not so much as 'creating' an element, more actually 'toggling' its visibility
$(document).ready(function() {
$('[id^=bool]').click(function() {
var id = $(this).attr("id").substr($(this).attr("id").length - 1);
$('[id^=bool' + id + '] .switcher').toggleClass("switched");
var x = $('[id=input' + id + ']').length;
if (x > 0) //there is one there
{
$('[id=input' + id + ']').remove();
} else {
$('body').append('<input type="text" id="input' + id + '" placeholder="input ' + id + '" />');
}
});
});
.bool {
height: 40px;
width: 100px;
background: darkgray;
position: relative;
border-radius: 5px;
overflow: hidden;
box-shadow: inset 5px 0 6px gray;
border: 1px solid black;
}
.bool:before {
content: "On";
left: 10%;
position: absolute;
top: 25%;
}
.bool:after {
content: "Off";
right: 10%;
position: absolute;
top: 25%;
}
.switcher {
height: 100%;
width: 50%;
position: absolute;
background: lightgray;
top: 0;
left: 0;
z-index: 5;
transform: translateX(0px);
transition: all 0.5s;
border-radius: 5px;
box-shadow: inset 0 0 6px black;
}
.switched {
transform: translateX(50px);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="bool" id="bool1">
<div class="switcher"></div>
</div>
<div class="bool" id="bool2">
<div class="switcher"></div>
</div>
Edit History
Altered snippet to include 2 toggles, as per comments
refactored jquery method with help from Tambo
altered markup to 'append' and 'remove' instead

OnClick write following code to hide:
document.getElementById('create').style.display = 'none';
And following code to show:
document.getElementById('create').style.display = 'block';
Like:
JavaScript:
<script type="text/javascript">
var count = 1;
function hidShow()
{
if(count == 1)
{
document.getElementById('create').style.display = 'none';
count = 0;
}
else
{
document.getElementById('create').style.display = 'block';
count = 1;
}
}
</script>
HTML:
<button id="button_rd" onClick="hidShow()">one</button>
<div class="box-body" id="create">
<input type="text" id="txt"/>
</div>

instead of
document.getElementById("create").append(newdiv);
'innerHTML' works for me, like below:
document.getElementById("create").innerHTML = '<div class="form-group"><label for="exampleInputEmail1">email</label>'
+'<input type="email" class="form-control" id="exampleInputEmail1" placeholder="Enter email"></div>'
to remove the div on toggle i used
$('div_id').remove();

Related

HTML 5 Validation Customization

I would like to have a form that:
Display validation messages in a custom format instead of the default style.
Display all invalid field bubbles at once instead of one at a time.
Right now, I am stuck with the boring browser-specific message appearance and I don't see the next error until I correct the last one. This is a really bad user experience, so looking for a few pointers on how to address this.
This is my current JavaScript code:
const contactUsForm = document.querySelector('#Form');
if (contactUsForm) {
function Validate() {
validatedFields = contactUsForm.querySelectorAll('[data-validation-required],[data-validation-format]');
validatedFields.forEach(field => {
/* RegEx patterns */
const emailPattern = /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))#((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i;
if (field.getAttribute('type') === 'email')
{
field.setAttribute('pattern', emailPattern);
}
if (field.validity.valueMissing) {
field.setCustomValidity(field.dataset.validationRequired);
}
else if (field.validity.patternMismatch) {
field.setCustomValidity(field.dataset.validationFormat);
}
else {
field.setCustomValidity('');
}
field.reportValidity();
contactUsForm.checkValidity();
/* Recheck on field value change */
field.addEventListener('change', function() {
field.setCustomValidity('');
Validate();
});
});
}
Validate();
contactUsForm.addEventListener('submit', function(e) {
e.preventDefault;
if (e.checkValidity() == false) {
return false;
}
else {
// form.submit()
}
});
}
Styling validation bubbles/tooltips used to be feature but only exclusive to Chrome, however it got removed.
More information about it here:
How do you style the HTML5 form validation messages?
However, you can create your own tooltips or bubbles to display validation messages. With use of a div container and a span and a little bit of CSS, you can create a bubble with almost any kind of look you can image.
.ttCont {
position: relative;
display: inline-block;
}
.ttCont .ttText {
display: inline-block;
visibility: hidden;
min-width: 200px;
background-color: darkblue;
color: #fff;
text-align: center;
border-radius: 6px;
padding: 5px;
opacity: 0;
transition: opacity 0.5s;
/* Place bubble to the right of container */
position: absolute;
z-index: 1;
top: 5px;
left: 105%;
}
.ttCont .ttText::after {
content: " ";
position: absolute;
top: 50%;
right: 100%; /* To the left of the bubble */
margin-top: -5px;
border-width: 5px;
border-style: solid;
border-color: transparent darkblue transparent transparent;
}
.ttCont .ttText.active{
visibility: visible;
opacity: 1;
}
Use of custom bubbles now means that you might need to use less of the ValidityState API, however you can still validate your fields using the same approach. Instead of using field.reportValidity(), you can create a custom function that shows a bubble whenever each field validates
function customReportValidatity(elem, type) {
let msg = "";
///check if validity is based on required or mismatch///
switch (type) {
case 'required':
msg = $(elem).attr('data-validation-required');
///without jQuery
// msg = elem.dataset.validationRequired;
break;
case 'format':
msg = $(elem).attr('data-validation-format');
///without jQuery
// msg = elem.dataset.validationFormat;
break;
default:
break;
}
///make popup appear///
let ttText = $(elem).parent().children('.ttText');
$(ttText).text(msg);
$(ttText).addClass('active');
///without jQuery
// let ttText = elem.parentElement.querySelector('.ttText');
// ttText.innerText = msg;
// ttText.classList.add('active');
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
With that styling and custom function, you can apply it to your existing code for any form you are willing to apply to. In this case, I made an example form that takes in a name and email that are required, while the description is not required.
const contactUsForm = document.querySelector('#Form');
const submitBtn = document.querySelector('#submitBtn');
if (contactUsForm) {
function customReportValidatity(elem, type) {
let msg = "";
///check if validity is based on required or mismatch///
switch (type) {
case 'required':
msg = $(elem).attr('data-validation-required');
///without jQuery
// msg = elem.dataset.validationRequired;
break;
case 'format':
msg = $(elem).attr('data-validation-format');
///without jQuery
// msg = elem.dataset.validationFormat;
break;
default:
break;
}
///make popup appear///
let ttText = $(elem).parent().children('.ttText');
$(ttText).text(msg);
$(ttText).addClass('active');
///without jQuery
// let ttText = elem.parentElement.querySelector('.ttText');
// ttText.innerText = msg;
// ttText.classList.add('active');
}
function Validate() {
let isValid = true;
/* RegEx patterns */
const emailPattern = /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))#((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i;
let validatedFields = contactUsForm.querySelectorAll('[data-validation-required],[data-validation-format]');
validatedFields.forEach(field => {
if (field.getAttribute('type') === 'email') {
field.setAttribute('pattern', emailPattern);
}
if (field.validity.valueMissing) {
field.setCustomValidity(field.dataset.validationRequired);
customReportValidatity(field, 'required');
isValid = false;
} else if (field.validity.typeMismatch) {
//using typeMismatch instead of patternMismatch because the regex is not working for emails
field.setCustomValidity(field.dataset.validationFormat);
customReportValidatity(field, 'format');
isValid = false;
}
contactUsForm.checkValidity();
/// Recheck on field value change ///
field.addEventListener('change', function() {
$('.ttText').removeClass('active');
///without jquery
/*document.querySelectorAll('.ttText').forEach((tt)=>{
tt.classList.remove('active');
});*/
Validate();
});
});
return isValid;
}
submitBtn.addEventListener('click', function(e) {
e.preventDefault();
e.stopPropagation();
if (Validate()) {
// contactUsForm.submit();
//you can use this output to check if the form will submit
console.log("Form Submitted!");
} else {
return false;
}
});
}
.ttCont {
position: relative;
display: inline-block;
}
.ttCont .ttText {
display: inline-block;
visibility: hidden;
min-width: 200px;
background-color: darkblue;
color: #fff;
text-align: center;
border-radius: 6px;
padding: 5px;
opacity: 0;
transition: opacity 0.5s;
position: absolute;
z-index: 1;
top: 5px;
left: 105%;
}
.ttCont .ttText::after {
content: " ";
position: absolute;
top: 50%;
right: 100%;
margin-top: -5px;
border-width: 5px;
border-style: solid;
border-color: transparent darkblue transparent transparent;
}
.ttCont .ttText.active {
visibility: visible;
opacity: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<form id="Form">
<div class="ttCont">
<label for="name">Name</label><br/>
<input type="text" name="name" required data-validation-required="Name is required!" /><br/>
<span class="ttText"></span>
</div>
<br/><br/>
<div class="ttCont">
<label for="email">Email</label><br/>
<input type="email" name="email" required data-validation-required="Email is required" data-validation-format="Email must have the format similar to example#email.com!" /><br/>
<span class="ttText"></span>
</div>
<br/><br/>
<div class="ttCont">
<label for="desc">Description</label><br/>
<input type="text" name="desc" data-validation-required="Description is required!" /><br/>
<span class="ttText"></span>
</div>
<br/><br/>
<button type="button" id="submitBtn">Submit</button>
</form>
You can read more about how to create and handle custom tooltips here:
W3Schools Tooltips
LogRocket Tutorial

Function to count number of line breaks acts differently on $(window).on('resize') and $(document).ready

I have a function which counts the number of line breaks in a div, depending on the width of the window. While the functions works fine when placed in the $(window).on('resize') function, it does not work when put in $(document).ready() function. I want it to work right on page load, and also window resize, how do I support both?
JSFiddle
Javascript/jQuery:
// functions called in both document.ready() and window.resize
$(document).ready(function(){
var lineCount = getLineCount();
postItems(lineCount);
$('.answer').text("Ready");
});
$(window).on('resize', function(){
var lineCount = getLineCount();
postItems(lineCount);
$('.answer').text("Number of lines: " + lineCount);
});
// calculates the amount of lines required to hold the items
function getLineCount() {
var lineWidth = $('.line').width();
var itemWidthSum = 0;
var lineCount=1;
$('.item').each(function(index, element) {
if((lineWidth - itemWidthSum) > ($(element).outerWidth())) {
itemWidthSum = itemWidthSum + $(element).outerWidth();
} else {
lineCount++;
itemWidthSum = $(element).outerWidth();
}
});
return lineCount;
}
// overlays rows for the amount of linebreaks
function postItems(lineCount){
var container = $('<div />');;
for(var i = 1; i <= lineCount; i++) {
container.append('<div class="line">' + i + '</div>');
}
$('.line-wrap').html(container);
}
You'll see at the start of the page, it incorrectly shows 17 lines, and then once you resize it will show the correct amount.
The issue lies in the first line of getLineCount(). Originally you had
var lineWidth = $('.line').width();
but no elements with the class "line" exist yet on your page (since they get added in your postItems() method. I changed it to
var lineWidth = $(".container").width();
instead, and now your code should be working. Snippet posted below:
$(document).ready(function(){
var lineCount = getLineCount();
postItems(lineCount);
$('.answer').text("Ready");
});
$(window).on('resize', function(){
var lineCount = getLineCount();
postItems(lineCount);
$('.answer').text("Number of lines: " + lineCount);
});
// calculates the amount of lines required to hold the items
function getLineCount() {
var lineWidth = $('.container').width();
var itemWidthSum = 0;
var lineCount=1;
$('.item').each(function(index, element) {
if((lineWidth - itemWidthSum) > ($(element).outerWidth())) {
itemWidthSum = itemWidthSum + $(element).outerWidth();
} else {
lineCount++;
itemWidthSum = $(element).outerWidth();
}
});
return lineCount;
}
// overlays rows for the amount of linebreaks
function postItems(lineCount){
var container = $('<div />');;
for(var i = 1; i <= lineCount; i++) {
container.append('<div class="line">' + i + '</div>');
}
$('.line-wrap').html(container);
}
body {
text-align:center;
}
.answer {
position: fixed;
left: 0;
bottom: 0;
}
.container {
position: relative;
width: 50%;
margin: 0 auto;
border: 1px solid #e8e8e8;
display: inline-block;
}
.item {
height: 50px;
padding:0 10px;
background-color: #aef2bd;
float: left;
opacity:0.2;
white-space: nowrap;
}
.line-wrap {
position: absolute;
border: 1px solid red;
width: 100%;
height: 100%;
top:0; left: 0;
}
.line {
height: 50px;
width: 100%;
background-color: blue;
opacity:0.5;
color: white;
transition: all 0.5s ease;
}
.line:hover {
background-color: yellow;
color: #000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="item-wrap">
<div class="item">Computer Science</div>
<div class="item">Language</div>
<div class="item">Marketing</div>
<div class="item">Biology</div>
<div class="item">Computer Science</div>
<div class="item">Language</div>
<div class="item">Marketing</div>
<div class="item">Biology</div>
<div class="item">Computer Science</div>
<div class="item">Language</div>
<div class="item">Marketing</div>
<div class="item">Biology</div>
<div class="item">Computer Science</div>
<div class="item">Language</div>
<div class="item">Marketing</div>
<div class="item">Biology</div>
</div>
<div class="line-wrap">
</div>
</div>
<h1 class="answer"></h1>

Jquery functions continue to apply even the CSS is changed. How do I stop this?

The fiddle first.
I have nameCards which expand and contract when clicked by adding/removing classes. Additionally, they move to different sections in the page when buttons are clicked (again by adding/removing classes). The problem: Despite them no longer having the classes needed to trigger the functions, the function still applies to them.
In the code, they move from .unmatched to .matched, so the function selector $('.matched.nameCard') should no longer work, but it does, as shown by the fact that the alert from the .click() still shows after it got moved.
I've tried event.stopProgation() basically everywhere in the functions, tried using a local variable instead of the global variable currentCard, and have double checked that the classes are changing by inspecting using .html. By my reasoning, the second they change from .unmatched to .matched the original function should stop working. Can anybody help me figure out why it's not?
Final note, the formatting got screwed up a little in the switch to fiddle, please forgive the funkyness. I tried to get rid of as much extra stuff as possible.
Edit: Changed from #matched in my question to .matched
Full code:
HTML
<div class="col-xs-3 col-sm-4 col-md-2">
<h2>Unmatched:</h2>
<div class="container-fluid matchBoxes" id="unmatched">
<div class="namesAndModals">
<div class="nameCard preClick unmatched" id="unmatchedFunctionalityShell">
<h2 class="memberName"></h2>
<div class="nameCardContents">
<button type="button" class="btn checkmark" id="yesBtn" href="#" data-toggle="modal" data-target="#pairModal">
<div class="checkmark_circle"></div>
<div class="checkmark_stem"></div>
<div class="checkmark_kick"></div>
</button>
<input type="text" placeholder="PNM ID#" class="IDnum ansField" autofocus/>
<input type="text" placeholder="Last Name" class="lastName ansField" id="lastName"/>
<input type="text" placeholder="First Name" class="firstName ansField" id="firstName"/>
</div>
</div>
<div class="nameCard preClick unmatched">
<h2 class="memberName">Jane Doe</h2>
</div>
<div class="nameCard preClick unmatched">
<h2 class="memberName">Jane Doe</h2>
</div>
<!-- Pairing Modal -->
<div id="pairModal" class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Ready to Pair?</h4>
</div>
<div class="modal-body">
<p id="pairDialog"></p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" id="pairButton" data-dismiss="modal">Pair</button>
<button type="button" class="btn btn-default" id="dismissButton" data-dismiss="modal">Never Mind</button>
</div>
</div>
</div>
</div>
</div>
</div>
<h2>Matched:</h2>
<div class="container-fluid matchBoxes" id="matched">
<div class="nameCard preClick matched">
<h2 class="memberName">Jane Doe</h2>
<div class="matchedNameCardContents">
<p class="pnmName">Jaime Doe</p>
</div>
</div>
</div>
CSS
* {
font-family: 'Gill Sans MT', 'Microsoft YaHai UI', sans-serif;
font-weight: 200;
}
#unmatched {
width: auto;
height: 300px;
background-color: rgba(211, 211, 211, .55);
border-radius: 10px;
margin: 10px 0;
overflow-y:scroll;
min-width: 270px;
}
#matched {
width: 110%;
height: 200px;
background-color: rgba(211, 211, 211, .55);
border-radius: 10px;
margin: 10px 0;
overflow-y:scroll;
min-width: 270px;
}
.nameCard {
width: 100%;
height: 70px;
background-color: rgba(255,100,171,.5);
border-radius: 10px;
display: block;
margin: 2px 1px;
overflow:auto;
}
.nameCard.preClick {
height: 30px;
}
.nameCard .nameCardContents {
display:none;
}
.nameCard h2 {
display:inline-block;
font-size: 20px;
font-weight: 500;
padding: 5px 0 3px 10px;
text-align: left;
width: 75%;
float:left;
}
.nameCard .IDnum {
display:inline-block;
margin: 5px 2px 3px 10px;
padding: 3px 0px 3px 2px;
width: 25%;
}
.nameCard .lastName {
display:inline-block;
margin: 5px 2px 3px 2px;
padding: 3px 0px 3px 2px;
width: 30%;
}
.nameCard .firstName {
display:inline-block;
margin: 5px 2px 3px 2px;
padding: 3px 0px 3px 2px;
width: 30%;
}
#unmatchedFunctionalityShell {
display:none;
}
.checkmark {
display:inline-block;
margin:auto;
margin-right:2px;
padding-right:0px;
-ms-transform: rotate(45deg); /* IE 9 */
-webkit-transform: rotate(45deg); /* Chrome, Safari, Opera */
transform: rotate(45deg);
}
.checkmark_circle {
position: absolute;
width:22px;
height:22px;
background-color: rgba(46,195,1,.8);
border-radius:11px;
left:0;
top:0;
}
.checkmark_stem {
position: absolute;
width:3px;
height:9px;
background-color:#fff;
left:11px;
top:6px;
}
.checkmark_kick {
position: absolute;
width:3px;
height:3px;
background-color:#fff;
left:8px;
top:12px;
}
#yesBtn{
display:inline-block;
background-color: rgba(46,195,1,0);
width:20px;
height:20px;
border-radius:11px;
}
/* Matched Members */
.matched.nameCard {
background-color: rgba(50, 205, 50, .5);
}
.matched p {
display: inline-block;
text-align: left;
margin-left: 10px;
padding-top: 5px;
}
.matched .btn {
display: inline-block;
background-color: rgba(255,37,37,.7);
padding: 4px;
float:right;
}
/*I had to use important here to get rid of the nameCardContents. Try and remove it later */
#matched .nameCardContents {
display:none !important;
}
#matched .preClick .matchedNameCardContents {
display:none;
}
Javascript
$(document).ready(function(){
$('.unmatched.nameCard').hover(function() {
var currentCard = $(this);
var memberName = $(this).children(".memberName").text();
currentCard.off('click').on("click", function(event) {
// alert("hello");
//switches between "active" and "inactive (preClick)" card
$("#unmatched .nameCard").addClass('nameCard preClick');
currentCard.toggleClass('nameCard');
currentCard.toggleClass('nameCard preClick');
var cardContents = $('.nameCardContents');
cardContents.appendTo(currentCard);
if (currentCard.is(".nameCard.preClick") ) {
cardContents.hide();
alert("this shouldn't happen after being moved to #matched");
} else {
cardContents.show();
alert("this shouldn't happen after being moved to #matched");
}
});
//stops card from closing if you click on buttons/input and carries out button events
currentCard.off('click', ".btn").on("click", ".btn", function(event) {
var pnmLastName = $("#lastName").val();
var pnmFirstName = $('#firstName').val();
$("#pairDialog").text("Are you sure you want to pair " + memberName + " with " + pnmFirstName + " " + pnmLastName + "?");
});
currentCard.off('click', ".ansField").on("click", ".ansField", function(event) {
event.stopPropagation();
});
//Unmatched to Matched
$('#pairModal #pairButton').off('click').on("click", function(event) {
var pnmLastName = $("#lastName").val();
var pnmFirstName = $('#firstName').val();
currentCard.removeClass('unmatched');
currentCard.addClass('matched');
currentCard.children(".nameCardContents").hide();
currentCard.append("<div class='matchedNameCardContents'><p class='pnmName'>" + pnmFirstName + " " + pnmLastName + "</p><button type='button' class='btn btn-default' data-toggle='modal' data-target='#unpairModal'>Unpair</button></div>");
currentCard.addClass('preClick');
currentCard.prependTo("#matched");
$("#lastName").val("");
$("#firstName").val("");
});
//Move from Unmatched to Unavailible
//Remove for one party
$('#discardModal #onePartyButton').off('click').on("click", function(event) {
currentCard.removeClass('unmatched');
currentCard.addClass('unavailable');
currentCard.prependTo("#unavailable");
var newDiv = $("<div><p>Removed for one party</p></div>")
newDiv.appendTo(currentCard);
});
//Remove for one round
$('#discardModal #oneRoundButton').off('click').on("click", function(event) {
currentCard.removeClass('unmatched');
currentCard.addClass('unavailable');
currentCard.prependTo("#unavailable");
var newDiv = $("<div><p>Removed for one round</p></div>")
newDiv.appendTo(currentCard);
});
//Remove for all recruitment
$('#discardModal #allRecruitmentButton').off('click').on("click", function(event) {
currentCard.removeClass('unmatched');
currentCard.addClass('unavailable');
currentCard.prependTo("#unavailable");
var newDiv = $("<div><p>Removed from recruitment</p></div>")
newDiv.appendTo(currentCard);
});
});
});
//Matched Name cards
$(document).ready(function(){
$('.matched.nameCard').off().hover(function() {
var currentCard = $(this);
var memberName = $(this).children(".memberName").text();
var pnmName = $(this).children(".pnmName").text();
currentCard.on("click", function(event) {
//switches between "active" and "inactive (preClick)" card
//$("#matched .nameCard").addClass('nameCard preClick');
currentCard.toggleClass('nameCard');
currentCard.toggleClass('nameCard preClick');
var cardContents = $('.matchedNameCardContents');
if (currentCard.is(".nameCard.preClick") ) {
cardContents.hide();
} else {
cardContents.show();
}
});
//stops card from closing if you click on buttons/input and carries out button events
currentCard.on("click", ".btn", function(event) {
$("#unpairButton").text("Are you sure you want to unpair " + memberName + " and " + pnmName + "?");
});
currentCard.on("click", ".ansField", function(event) {
event.stopPropagation();
});
//.unbind() is the best thing to happen to me
//Unmatched to Matched
$('#pairModal #pairButton').unbind('click').on("click", function(event) {
var pnmLastName = $("#lastName").val();
var pnmFirstName = $('#firstName').val();
currentCard.removeClass('unmatched');
currentCard.addClass('matched');
currentCard.children(".nameCardContents").hide();
var addPNM = $("<div class='matchedNameCardContents'><p class='pnmName'>" + pnmFirstName + " " + pnmLastName + "</p><button type='button' class='btn btn-default' data-toggle='modal' data-target='#unpairModal'>Unpair</button></div>");
currentCard.append("<div><p class='pnmName'>" + pnmFirstName + " " + pnmLastName + "</p><button type='button' class='btn btn-default' data-toggle='modal' data-target='#unpairModal'>Unpair</button></div>");
currentCard.prependTo("#matched");
});
});
});
I figured it out! I looked into event delegation based on the comments and changed everything to take that into account. Here's a preview of what my new functions look like:
$(document).ready(function(){
$('#unmatched').off().on("mouseover", ".unmatched.nameCard", function() {
var currentCard = $(this);
var memberName = $(this).children(".memberName").text();
currentCard.off('click').on("click", function() {
//switches between "active" and "inactive (preClick)" card
$("#unmatched .nameCard").addClass('nameCard preClick');
currentCard.toggleClass('nameCard');
currentCard.toggleClass('nameCard preClick');
var cardContents = $('.nameCardContents');
cardContents.appendTo(currentCard);
if (currentCard.is(".nameCard.preClick") ) {
cardContents.hide();
} else {
cardContents.show();
}
});
//stops card from closing if you click on buttons/input and carries out button events
currentCard.off('click', ".btn").on("click", ".btn", function(event) {
var pnmLastName = $("#lastName").val();
var pnmFirstName = $('#firstName').val();
$("#pairDialog").text("Are you sure you want to pair " + memberName + " with " + pnmFirstName + " " + pnmLastName + "?");
$("#removeMember").text("How long do you want to remove " + memberName + " from recruitment?");
});
});
});

display a div below a selected input field? No JQuery

how to display a div everytime a user focus on a input field. there is already a div and it is hidden. the position of the div will change depending on the position of the selected field and it will be display below
this is my code
formFieldListWrapper.style.top = ((((formSelectedFieldInput.offsetTop > (formWrapper.offsetHeight/2))?((formSelectedFieldInput.offsetTop-(formWrapper.offsetHeight/2))-(formSelectedFieldInput.offsetHeight+formWrapper.offsetHeight*0.02)):(formSelectedFieldInput.offsetTop))/formWrapper.offsetHeight)*100) + "%";
formFieldListWrapper.style.left = ((formSelectedFieldInput.offsetLeft/formWrapper.offsetWidth)*100) + "%";
Why use javascript? This could be chieved by using CSS only
HTML
<div class="holder">
<input type="text" />
<div class="dropdown">
<p>Testing</p>
<p>Css ONLY</p>
<p>Dropdown</p>
</div>
</div>
CSS
.holder {
position: relative;
}
.dropdown {
position: absolute;
border: 1px solid red;
display: none;
}
input:focus + .dropdown {
display: block;
}
UPDATE
little bit misred the question, if You need to position div dynamically like in this fiddle, You cloud use:
HTML
<div class="holder">
<input type="text" />
</div>
<div class="holder" style="margin-top: 30px;">
<input type="text" />
</div>
<div class="dropdown">
<p>Testing</p>
<p>Css ONLY</p>
<p>Dropdown</p>
</div>
CSS
.holder {
position: relative;
}
.dropdown {
position: absolute;
border: 1px solid red;
display: none;
z-index: 1;
background: white;
}
input:focus + .dropdown {
display: block;
}
Javascript to position dropdown div
var inputs = document.querySelectorAll('input');
for (var i = 0; i < inputs.length; i++) {
inputs[i].addEventListener('focus', function(){
this.parentNode.appendChild(document.querySelector('.dropdown'));
});
}
Try the following:
formSelectedFieldInput.addEventListener("focus", setDivToInput, false);
function setDivToInput(e)
{
var inputElement = e.target; //e.target refers to the element that fired the event.
formFieldListWrapper.style.top = inputElement.offsetTop + formFieldListWrapper.offsetHeight + "px";
formFieldListWrapper.style.left= inputElement.offsetLeft + "px";
formFieldListWrapper.style.display = "block";
}
The first line adds a focus event to the input. This sets the div to the input based upon it's position on the page. This is very basic and doesn't behave well when the div runs of the screen. You need to add logic for that.
Now for multiple inputs in a form
var nodes = form.querySelectorAll("input"); //replace with your form element
for (var i = 0; i < nodes.length; ++i)
{
nodes[i].addEventListener("focus", setDivToInput, false);
}
function setDivToInput(e)
{
var node = e.target;
formFieldListWrapper.style.top = node.offsetTop + formFieldListWrapper.offsetHeight + "px";
formFieldListWrapper.style.left= node.offsetLeft + "px";
formFieldListWrapper.style.display = "block";
}
This code sets the focus event to all inputs in the form.

Making a javascript popup draggable

I am creating a JavaScript popup. The code is as below.
The HTML:
<div id="ac-wrapper" style='display:none' onClick="hideNow(event)">
<div id="popup">
<center>
<h2>Popup Content Here</h2>
<input type="submit" name="submit" value="Submit" onClick="PopUp('hide')" />
</center>
</div>
</div>
The CSS:
#ac-wrapper {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: url("images/pop-bg.png") repeat top left transparent;
z-index: 1001;
}
#popup {
background: none repeat scroll 0 0 #FFFFFF;
border-radius: 18px;
-moz-border-radius: 18px;
-webkit-border-radius: 18px;
height: 361px;
margin: 5% auto;
position: relative;
width: 597px;
}
The Script:
function PopUp(hideOrshow) {
if (hideOrshow == 'hide') document.getElementById('ac-wrapper').style.display = "none";
else document.getElementById('ac-wrapper').removeAttribute('style');
}
window.onload = function () {
setTimeout(function () {
PopUp('show');
}, 0);
}
function hideNow(e) {
if (e.target.id == 'ac-wrapper') document.getElementById('ac-wrapper').style.display = 'none';
}
The jsFiddle Link:
http://jsfiddle.net/K9qL4/2/
The Issue:
The above script works fine, but I need to make the popUp draggable.
Here's some code that will do what you want. It relies only on an object called drag to store all its values, but you can easily alter that. The example relies on there being a div with the id of mydiv (a document.write() is used in this instance to supply that) that has a position attribute of absolute or fixed. You can see it in action at Jamie
document.write("<" + "div id='mydiv' style='background:blue; width:100px;"
"height:100px; position:fixed;'>" + "<" + "/div>");
var drag = new Object();
drag.obj = document.getElementById('mydiv');
drag.obj.addEventListener('mousedown', function(e)
{
drag.top = parseInt(drag.obj.offsetTop);
drag.left = parseInt(drag.obj.offsetLeft);
drag.oldx = drag.x;
drag.oldy = drag.y;
drag.drag = true;
});
window.addEventListener('mouseup', function()
{
drag.drag = false;
});
window.addEventListener('mousemove', function(e)
{
drag.x = e.clientX;
drag.y = e.clientY;
var diffw = drag.x - drag.oldx;
var diffh = drag.y - drag.oldy;
if (drag.drag)
{
drag.obj.style.left = drag.left + diffw + 'px';
drag.obj.style.top = drag.top + diffh + 'px';
e.preventDefault();
}
});
Use the
.draggable();
jquery function, here is your updated fiddle:
http://jsfiddle.net/N9rQK/
If you don't want to use jQuery, you should read this subject: Draggable div without jQuery UI

Categories