Change JS alert to DOM error message div - javascript

I need to convert my error messaging to a positioned div (hidden initially) instead of the standard js alert. I realize I need to push the alert message to the DOM, but I'm new to javascript. Any help would be appreciated.
Additionally, I need to do it without a confirm (so error message removes on field focus)
if(el != null) {
switch(el.name) {
case "firstName":
//First Name Field Validation, Return false if field is empty
if( f.firstName.value == "" )
{
alert( bnadd_msg_002 );
if ((typeof TeaLeaf != "undefined") && (typeof TeaLeaf.Client != "undefined") && (typeof TeaLeaf.Client.tlAddEvent != "undefined") ) {
var nVO = { ErrorMessage : bnadd_msg_002}
var subtype="CustomErrorMsg";
TeaLeaf.Event.tlAddCustomEvent(subtype, nVO);
}
return false;
}
break;

Simple approach using jQuery
function customAlert(msg){
var div = $("#AlertMessage");
if (div.length == 0) {
div = $("<div id='AlertMessage' onclick='$(this).hide();'></div>");
$("body").prepend(div);
}
div.html(msg)
}
CSS
#WriteProperties {
background-color: #FFF;
border: 1px solid #000;
height: 300px;
position: fixed;
right: 10px; /* position as desired */
top: 90px; /* position as desired */
width: 300px;
z-index: 1000;
}
JS for clearing message on focus of a text input field. You can always be more selective about which fields to attach the event to.
$("input[type='text']").live("focus", function(){
$("#AlertMessage").hide();
})

very basic but sshould give you a good direction to go.
Basically your creating a div that is hidden, and then you'll fill the span inside wiht your text and show the div.
<Div id="myalertbox" style='display:none'>
<span>put message here</span>
</div>
I always use jquery to change the DOM around. Makes thing alot simpler.
jquery("#myalertbox span").text(bnadd_msg_002);
jquery("#myalertbox").show();
Then just use CSS to position the DIV.
probably have to set the DIV to position Absolute, then use top and left to place it in the middle of the screen.
You may need to surround the DIV with another DIV.
<div id="grayout">
<Div id="myalertbox" style='display:none'>
<span>put message here</span>
</div>
</div>
Show the gray out div full screen, but set its transpancy.
Basically will block people from clicking the screen while your error message shows.
Or just get jquery and it has a built in error message box.
http://api.jquery.com/jQuery.error/

Related

JS to dynamically add a list to select on input if user type {

I am creating a text editable div box in which user can add text and personalize it by adding fields like First_Name, Last_Name etc. I want the options to show when a user press { key.
I did the js which get fired when the user types {, and added a list with the options, but when the scripts run the whole list get added on the input box instead of providing option to select from.
Here is the text div I have and the Js code
<div contenteditable class="text_im" name="text_im" placeholder="Enter Text" maxlength="640"></div>
script:
$(document).keyup(function (e) {
if ($(".text_im:focus") && (e.keyCode === 219)) {
var options = '<ul><li>{First_Name}</li><li>{Last_Name}</li> <li>{Email}</li><li>{Phone}</li></ul>';
$(".text_im").append(options);
}
});
I tried searching for any tips or tutorial , but can't find any. If you could suggest me some tutorial.
You would need to use a library for that to get a cross-browser, modern-looking result, but the basics could work like this:
Create the options element from a template, and give it the CSS rendering it needs to show correctly at the caret position when needed.
Show it on keypress, when character is already in the div element.
Capture mouse clicks on the options
Hide it whenever a key is pressed or user clicks on an option
When option selected, insert corresponding text, except for the opening { which is already there.
Here is some code, but please note that to make this cross-browser and good-looking (with additional features), you would need a lot more. This is just to show a basic set-up:
// Create element (not in DOM yet) for tooltip
var tooltip = $('#template').clone().attr('id', 'tooltip').get(0);
function insertAtCaret(node, caretBefore = false) {
var range = window.getSelection().getRangeAt(0);
range.insertNode(node);
range.collapse(caretBefore);
}
$(document).keypress(function (e) {
$(tooltip).remove(); // Hide tooltip (detach it from the DOM)
var $div = $(".text_im"),
ch = String.fromCharCode(e.which); // Get typed character
if (!$div.is(":focus") || ch !== '{') return;
setTimeout(function () { // Delay a bit, to ensure correct caret position
insertAtCaret(tooltip, true); // Insert the tooltip at the caret
}, 100);
});
$(document).on('click', '#tooltip li', function () {
var text = $(this).text().substr(1); // The text to insert
$(tooltip).remove(); // Hide tooltip (detach it from the DOM)
$(".text_im").focus(); // Make sure the div has focus
insertAtCaret(document.createTextNode(text)); // Insert the text
});
.text_im {
border : 1px solid;
min-height: 40px
}
#template {
display: none;
}
#tooltip {
position: fixed;
margin-top: -0.2em;
background: #eee;
display: inline-block;
cursor: pointer;
}
#tooltip li:hover {
background: #ccc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div contenteditable class="text_im inputor" name="text_im" placeholder="Enter Text" maxlength="640"></div>
<ul id="template"><li>{First_Name}</li><li>{Last_Name}</li> <li>{Email}</li><li>{Phone}</li></ul>

How to add an element between 2 flex-styled rows and make the row below move down based on new element height?

Please take a look at this basic example:
http://tympanus.net/Blueprints/ResponsiveFullWidthGrid/
Now imagine that by clicking a cat box, I would need (especially on small to medium screens) to add a 100%-width text box (say a description of the clicked cat) below the clicked cat's row. That text box should push down the rest of the rows.
I am full css/js/frontend developer but I never faced a problem like this. It's also the first time I'm going to use a flexbox layout. With a fixed layout would be quite trivial, but in this case I cannot figure out a good way of doing it. One of the things to solve for example is: where should I put the box (relative to the clicked box?), and should I change position via javascript based on current items-per-row or maybe there a smarter css way?
Any idea is appreciated.
That was an interesting challenge :)
The only way to know where to place the expanded area (I called it infoBox), is to identify the 1st node of the next line, and then insert it before it. If there is no node on the last line, we can append it to the end of the ul.
I've also added a window.resize event handler that will close the infoBox, so it won't break the responsive layout, and a close button.
Working example - fiddle.
HTML was copy paste from the codrop article.
JS
var rfgrid = document.querySelector('.cbp-rfgrid');
var items = Array.from(document.querySelectorAll('.cbp-rfgrid > li'));
/** Create infoBox **/
var infoBox = document.createElement('div');
infoBox.classList.add('infoBox');
infoBox.innerHTML = '<div class="close">X</div><div class="content"></div>';
infoBoxClose = infoBox.querySelector('.close');
infoBoxContent = infoBox.querySelector('.content');
/** add close button functionality **/
infoBoxClose.addEventListener('click', function() {
rfgrid.removeChild(infoBox);
});
/** remove infoBox on resize to maintain layout flow **/
window.addEventListener('resize', function() {
rfgrid.removeChild(infoBox);
});
items.forEach(function (item) {
item.addEventListener('click', function (event) {
event.preventDefault();
var insertReference = findReference(this); // get refence to next line 1st node
infoBoxContent.innerHTML = items.indexOf(this); // example of changing infoBox content
if(insertReference) {
rfgrid.insertBefore(infoBox, insertReference); // insert infoBox before the reference
} else {
rfgrid.appendChild(infoBox); // insert infoBox as last child
};
});
});
/** find reference to 1st item of next line or null if last line **/
function findReference(currentNode) {
var originalTop = currentNode.offsetTop; // get the clicked item offsetTop
do {
currentNode = currentNode.nextSibling; // get next sibling
} while (currentNode !== null && (currentNode.nodeType !== 1 || currentNode.offsetTop === originalTop)); // keep iterating until null (last line) or a node with a different offsetTop (next line)
return currentNode;
}
CSS (in addition to the original)
.infoBox {
position: relative;
width: 100%;
height: 200px;
padding: 20px 0 0 0;
clear: both;
background: paleturquoise;
}
.infoBox > .close {
position: absolute;
top: 5px;
right: 5px;
cursor: pointer;
}

How to use javascript to hide and let divs reappear

I am trying to make webpage where there is a div in the center which is being changed, instead of going to different pages.
Ultimately, I would like to have the new div, when clicking on an arrow, to flow from right or left in to the center. But first I would like to make the divs appear and disappear when clicking on the arrows but unfortunately this doesn't work.
This is my javascript:
<script>
function changeToHome() {
document.getElementById("mainmain").style.display="block";
document.getElementById("mainmain2").style.display="none";
document.getElementById("mainmain3").style.display="none";
document.getElementById("mainmain4").style.display="none";
}
function changeToStudy() {
document.getElementById("mainmain").style.display="none";
document.getElementById("mainmain2").style.display="block";
document.getElementById("mainmain3").style.display="none";
document.getElementById("mainmain4").style.display="none";
}
function changeToJob() {
document.getElementById("mainmain").style.display="none";
document.getElementById("mainmain2").style.display="none";
document.getElementById("mainmain3").style.display="block";
document.getElementById("mainmain4").style.display="none";
}
function changeToContact() {
document.getElementById("mainmain").style.display="none";
document.getElementById("mainmain2").style.display="none";
document.getElementById("mainmain3").style.display="none";
document.getElementById("mainmain4").style.display="block";
}
function changePageRight() {
var displayValue5 = document.getElementById('mainmain').style.display;
var displayValue5 = document.getElementById('mainmain2').style.display;
var displayValue6 = document.getElementById('mainmain3').style.display;
var displayValue7 = document.getElementById('mainmain4').style.display;
if (document.getElementById('mainmain').style.display == "block") {
document.getElementById("mainmain").style.display="none";
document.getElementById("mainmain2").style.display="block";
}
else if (document.getElementById('mainmain2').style.display == "block") {
document.getElementById("mainmain2").style.display="none";
document.getElementById("mainmain3").style.display="block";
}
else if (document.getElementById('mainmain3').style.display == "block") {
document.getElementById("mainmain3").style.display="none";
document.getElementById("mainmain4").style.display="block";
}
else if (displayValue8 == block) {}
}
function changePageLeft() {
var displayValue = document.getElementById('mainmain').style.display;
var displayValue2 = document.getElementById('mainmain2').style.display;
var displayValue3 = document.getElementById('mainmain3').style.display;
var displayValue4 = document.getElementById('mainmain4').style.display;
if (displayValue == "block") { }
else if (displayValue2 == "block") {
document.getElementById("mainmain").style.display="block";
document.getElementById("mainmain2").style.display="none";
}
else if (displayValue3 == "block") {
document.getElementById("mainmain2").style.display="block";
document.getElementById("mainmain3").style.display="none";
}
else if (displayValue4 === "block") {
document.getElementById("mainmain3").style.display="block";
document.getElementById("mainmain4").style.display="none";
}
}
</script>
Now I have a few divs that look like this:
<div id="mainmain4">
<img style="width:400px;height:327px;margin-left:auto;margin-right:auto;display:block;" src="Untitled-22.png" />
<h2> My name </h2>
<p>Hi,</p>
<p>Some text</p>
</div>
With these css atributes:
#mainmain {
float: left;
width: 575px;
display: block;
position: relative;
}
And all other divs with display: none; so I can change this to block and the one that was block to none.
For some reason, after when I click on one button of the menu, which activates a changeToX() function, the arrows work great. But before that, when you first go to the website, it doesn't.
Can someone explain me what I do wrong?
You don't tell the browser which divs shall be displayed on load. You can use theonloadevent for this:
<body onload="changeToHome()">
One additional hint: you maybe don't want to use inline JavaScript and CSS.
jQuery is as this simple:
<script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
toggle!
<div id="mainmain">test text</div>
<script>
// you need this, only apply javascript when all html (dom) is loaded:
$(document).ready(function() {
$('.toggle-container').on('click', function(e) {
e.preventDefault(); // this prevents the real href to '#'
// .toggle() is like "on / off" switch for hiding and showing a container
$($(this).data('container')).toggle();
});
});
</script>
This function can be reused, because it is based on classes instead of id's.
Check this JSFiddle: http://jsfiddle.net/r8L6xg15/
Maybe this is of some use. I've tried to make a page control-like behaviour. You can select any container div and put elements in there that have the class 'page'. The JavaScript code will let you navigate those with buttons.
You can make it more fancy by adding the buttons through JavaScript. What you then have is basically a list of pages which are normally displayed as regular divs, but when the script kicks in, it changes them to a page control.
You can call this for any parent element, and in that sense it behaves a bit like a jQuery plugin. It is all native JavaScript, though. And not too much code, I hope. Like you said, I think it's good to learn JavaScript at first. It is very powerful by itself, and it's becoming increasingly powerful. jQuery adds a lot of convenience functions and provides fallbacks in case browser don't support certain features, or when implementations differ. But for many tasks, bare JavaScript will do just fine, and it certainly can't hurt to know your way around it.
Press the 'Run this snippet' button at the bottom to see it in action.
function Pages(element)
{
// Some initialization
var activePage;
// Find all pages within this element.
var pages = document.querySelectorAll('.page');
var maxPage = pages.length - 1;
// Function to toggle the active page.
var setPage = function(index)
{
activePage = index;
for (p = 0; p <= maxPage; p++)
{
if (p == activePage)
pages[p].className = 'page active';
else
pages[p].className = 'page inactive';
}
}
// Select the first page by default.
setPage(0);
// Handler for 'previous'
element.querySelector('.prev').onclick = function()
{
if (activePage == 0)
return;
setPage(activePage - 1);
}
// Handler for 'next'
element.querySelector('.next').onclick = function()
{
if (activePage == maxPage)
return;
setPage(activePage + 1);
}
// Add a class to the element itself. This way, you can already change CSS styling
// depending on whether this code is loaded or not. So in case of an error, the
// divs are just all show underneath each other, and the nav buttons are hidden.
element.className = element.className + ' js';
}
Pages(document.querySelector('.pages'));
.pages .page {
display: block;
padding: 40px;
border: 1px solid blue;
}
.pages .page.inactive {
display: none;
}
.pages .nav {
display: none;
}
.pages.js .nav {
display: inline-block;
}
<div class="pages">
<button class="nav prev">Last</button>
<button class="nav next">Next</button>
<div class="page">Page 1 - Introduction and other blah</div>
<div class="page">Page 2 - Who am I? Who are you? Who is Dr Who?</div>
<div class="page">Page 3 - Overview of our products
<ul><li>Foo</li><li>Bar</li><li>Bar Pro</li></ul>
</div>
<div class="page">Page 4 - FAQ</div>
<div class="page">Page 5 - Contact information</div>
</div>
To dos to make this a little more professional:
Add the navigation through JavaScript
Disable the buttons when first/last page has been reached
Support navigation by keys too (or even swipe!)
Some CSS transform (fade or moving) when toggling between pages
Smarter adding and removing of classes. Now I just set className, which sucks if someone would like to add classes themselves. jQuery has addClass and removeClass for this, which is helpful. there are also stand-alone libraries that help you with this.
Visible indication of pages, maybe with tabs at the top?

How do I move the DOM elements down when I insert a new one so they don't overlap?

So I have a javascript function that inserts a span on clicking a button. But the problem is when I insert it, it overlaps the other elements. How can I move the other elements down when the button is clicked to make room for the inserted element? And then move them back up when the element is removed? Here is my code:
$(".top-button").on("click", function() {
if (this.nextElementSibling) {
$(this.nextElementSibling).slideToggle(600);
};
});
$(".bottom-button").on("click", function() {
$(this.nextElementSibling).slideToggle(600);
});
And a working demo here http://codepen.io/andrewcockerham/pen/xjgkL/
Basically, when I click on the yellow and green 'buttons' on Entry 1, the MP and IP boxes toggle, but they overlap the other elements (When Entry 1 is collapsed, {click on it}). How can I make the other elements move out to make room when the MP and IP appear, then return to their normal place when the MP or IP disappear?
I've tried appendChild(), insertAfter(), insertBefore(), all without success.
Please forgive the ugly demo and ugly code - its a WIP! Thanks!
So I figured out how to do it, so I'll answer my own question.
Basically I just inserted a blank or empty div 'behind' the inserted span, thus moving the DOM down or up. Here's the JS code:
$(".top-button").on("click", function() {
if (this.nextElementSibling) {
if ($(this.nextElementSibling).css('display') == "none") {
// insert blank element to move the DOM down
$("<div class='top-blank'><span></span></div>").insertBefore($(this).parent());
} else {
// remove blank element when collapse dropdown
$(this).parent().siblings('.top-blank').slideUp(600);
}
$(this.nextElementSibling).slideToggle(600);
};
});
$(".bottom-button").on("click", function() {
if ($(this.nextElementSibling).css('display') == "none") {
$("<div class='blank'><span></span></div>").insertAfter($(this).parent());
} else {
// remove inserted stuff
$('.blank').slideUp(500);
}
$(this.nextElementSibling).slideToggle(600);
});
and the CSS:
.blank {
position: relative;
min-height: 60px;
border-left: 2px solid white;
left: -50px;
}
.top-blank {
position: relative;
min-height: 60px;
}
updated Codepen working example: http://codepen.io/andrewcockerham/pen/xjgkL/
Not sure if this is the best or most proper way, but it works in my case. Interested to hear if there are other better solutions for this.

Highlight the sub text depending on the number of characters

Basic idea is to highlight the characters after a specified length value in input, and also show a notice message.
Here we go:
<div id="test_box">
<input type="text" id="text_text">
</div>
css:
#notice {
width: 140px;
height: 40px;
background-color: black;
}
#test_box {
width: 400px;
height: 400px;
}
and jQuery code:
$(document).ready(function() {
var length = $('#text_text').val().length;
var char_limit = 5;
$('#text_text').bind('keyup', function() {
new_length = $('#text_text').val().length;
if (new_length > char_limit) {
$('#text_text').css('color','red');
$('#test_box').append('<div id="notice"> There are limit of character for home page title of this field </div>'); // wrong too much divs :/
} else {
$('#text_text').css('color', 'black');
$('#notice').hide(); //wrong
}
});
});
At the moment characters highlighted after char_limit is exceeded, what i need is to highlight only those who go after char_limit. And also notice block is adding every time if i input character, i think i should create that div manually or maybe not and appear it somehow when char_limit is exceeded.
It is not really impossible highlight some part of the text as you can highlight it by selection.
Check this out: http://jsfiddle.net/9BrpD/3/
$(document).ready(function(){
var input = $('#text_text');
var warning = $('#warning');
input.on('keyup', function(){
var val = $(this).val();
if ( val.length > 3 ) {
warning.html('hello').css('display', 'block');
l = val.length
var input = document.getElementById("text_text");
input.setSelectionRange(l-3, l);
input.focus();
}
else {
warning.css('display', 'none');
}
});
});​
It also solves the issue you had with your repeated divs. However, I don't find this solution very user-friendly. You could try to move the focus outside of the input field but still, not entirely satisfactory.
I am not sure what you mean by "highlighting" the characters exceeding char_limit. If you want to apply a style to a part of the input text, then it is impossible: styles will apply to the whole input. You can try to simulate an input field with spans and some javascript to listen to the keyboard events. This is explained in this answer to a similar question as yours.
For the notice, indeed, you should not add it every time. it should be in your HTML with css "display:none" and shown and hidden when appropriate.
<div id="test_box">
<input type="text" id="text_text">
<div id="notice"> There are limit of character for home page title of this field </div>
</div>
--
#notice {
width: 140px;
height: 40px;
background-color: black;
display:none;
}
--
$(document).ready(function() {
var length = $('#text_text').val().length;
var char_limit = 5;
$('#text_text').bind('keyup', function() {
new_length = $('#text_text').val().length;
if (new_length > char_limit) {
$('#text_text').css('color','red');
$('#notice').show();
} else {
$('#text_text').css('color', 'black');
$('#notice').hide();
}
});
});
Here is a JSFiddle with that code.

Categories