Javascript Logic in Extending Search Bar - javascript

I've created an expanding search bar: You click on the magnifying glass the input extends out and to the right, click it again and it closes. (See Fiddle Below).
I'm new to the world of JS and I thought this would be a great opportunity to implement some logic. Here's what I;m trying to do:
If the search bar is open and the inner.html is empty, if you click the "search" magnifying glass, I want to prevent the default submission of the form and simply close the search bar
If there is text, I want the form to be submitted.
Right now I've got the elements layered in such a way as to when you click the "search" button for the first time, the bar extends and the z-index of the button drops to one where the actual submit button is higher, but I want to control the functionality a little more.
What I've tried:
I tried creating a function that added an event listener that said, basically, if the bar has a width of 700px (the extended length) and the inner html is empty, bring the z-index of the extend button up back higher than the submit simply close the form. But I can't seem to work the logic out properly.
I'm wondering how in JS you can control the z-index.
Here is the code I tried and did not work. I tried something simply like just alerting when the task I wanted to watch for was done first but it doesn't seem to be working.
Any help would be wonderful.
Code:
HTML:
<div id="wrap">
<form id="myForm">
<input id="search" name="search" type="text" placeholder="What are we looking for?" />
<input id="search_submit" value="" type="submit">
</form>
</div>
CSS:
#wrap
{
margin: 50px 100px;
display: inline-block;
position: relative;
height: 60px;
float: right;
padding: 0;
}
input[type="text"]
{
height: 40px;
font-size: 35px;
border: none;
outline: none;
color: #555;
padding-right: 60px;
position: absolute;
width: 0px;
top: 0;
right: 0;
background: none;
z-index: 4;
cursor: pointer;
transition: width .4s ease-in-out;
}
input[type="text"]:focus
{
width: 700px;
z-index: 1;
border-bottom: 1px solid #bbb;
cursor: text;
}
input[type="submit"]
{
position: absolute;
height: 60px;
width: 60px;
display: inline-block;
float: right;
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAMAAABg3Am1AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADNQTFRFU1NT9fX1lJSUXl5e1dXVfn5+c3Nz6urqv7+/tLS0iYmJqampn5+fysrK39/faWlp////Vi4ZywAAABF0Uk5T/////////////////////wAlrZliAAABLklEQVR42rSWWRbDIAhFHeOUtN3/ags1zaA4cHrKZ8JFRHwoXkwTvwGP1Qo0bYObAPwiLmbNAHBWFBZlD9j0JxflDViIObNHG/Do8PRHTJk0TezAhv7qloK0JJEBh+F8+U/hopIELOWfiZUCDOZD1RADOQKA75oq4cvVkcT+OdHnqqpQCITWAjnWVgGQUWz12lJuGwGoaWgBKzRVBcCypgUkOAoWgBX/L0CmxN40u6xwcIJ1cOzWYDffp3axsQOyvdkXiH9FKRFwPRHYZUaXMgPLeiW7QhbDRciyLXJaKheCuLbiVoqx1DVRyH26yb0hsuoOFEPsoz+BVE0MRlZNjGZcRQyHYkmMp2hBTIzdkzCTc/pLqOnBrk7/yZdAOq/q5NPBH1f7x7fGP4C3AAMAQrhzX9zhcGsAAAAASUVORK5CYII=) center center no-repeat;
border: none;
outline:none;
top: -15px;
right: 0;
z-index: 2;
cursor: pointer;
transition: all .4s ease;
}
JS
var search = document.getElementById("myForm").search;
var search_submit = document.getElementById("myForm").search_submit;
function showOpen()
{
if(search.style.width=="700px")
{
alert("OPEN!");
}
};
search.addEventListener("click", showOpen);
showOpen();
HERE IS THE FIDDLE: https://jsfiddle.net/theodore_steiner/7begmkf3/37/

Your issue can be solved using a few basic JavaScript elements (if you're looking to get into basic logic, these are important to know). The JS uses onsubmit, onclick, and some basic form logic. Basically, when you try to submit the form it checks if the form is empty, and if it is, the program refuses to submit the code. I added the new JavaScript to the HTML file:
<script>
function check(){
value = document.forms["myForm"]["search"].value;
if(value == "" || value == null){
alert("please enter a search term");
return false;
}else{
document.getElementById("myForm").submit();
}
}
</script>
<div id="wrap">
<form id="myForm" onsubmit="return check()">
<input id="searchBar" name="search" type="text" placeholder="What are we looking for?" />
<input id="search_submit" value="" type = "submit">
</form>
</div>
fiddle: https://jsfiddle.net/q1L3Lstx/1/
It might also help in the future to look at the required element: http://www.w3schools.com/tags/att_input_required.asp

I saw a couple of issues with the code.
search and search_submit are pointing to the wrong items they can be like this:
var search = document.getElementById("search");
var search_submit = document.getElementById("search_submit");
You could call a function on submit. like this:
<form id="myForm" onsubmit="myFunction(event)">
finally you can work your code inside that function:
function myFunction(e){
if(search.value.length <= 0){
e.preventDefault();
alert('empty');
}
}

Related

Input field is not focusing when clicked

I have an <input> field inside a div that is giving me trouble.
It is inside a div with position absolute. When I click on it, it does not get the focus, so I cannot type inside it.
The other parts of an input field work as they should: The cursor changes to the text symbol when over it, I can focus on it using the right-click with the mouse or the Tab key and when it DOES get focus I can type on it normally.
I even binded a console log to it when clicked, just to make sure the the correct element being clicked. The log does happen, but it still doesn't get the focus on clicking.
Does anyone have an idea of what may be happening here?
Edit: added more parts of my code, sorry for having such little code before.
Here is my code:
// link that makes the form appear, on another part of the UI
jQuery("#link").on("click", function() {
jQuery(".form").show()
})
jQuery("#close-button").on("click", function() {
jQuery(".form").hide()
})
// This was added to test if the click was happening,
// it does not work with or without this
jQuery("#input-field").on("click", function(e) {
console.log("clicked")
console.log(e.target) // this is returning the "input-field" element
})
.form {
background-color: #EAE8E8;
position: absolute;
width: 99%;
right: 0;
z-index: 100;
bottom: 0;
display: none;
border: 1px solid;
}
#close-button {
float: right;
cursor: pointer;
}
/* input-field doesn't have any CSS defined by code yet */
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="link">Click to show form</button>
<div class="form">
<!-- this has position: absolute -->
<img src="'/close.png" id="close-button">
<!-- Here are some other images that can be clicked... that all works fine -->
<input id="input-field" />
<!-- this is not getting focused when clicked -->
</div>
You might add .focus() to autofocus your desired input. Here is your example:
jQuery("#link").on("click", function() {
jQuery(".form").show()
// Add to auto focus your input
jQuery("#input-field").focus();
})
jQuery("#close-button").on("click", function() {
jQuery(".form").hide()
})
.form {
background-color: #EAE8E8;
position: absolute;
width: 99%;
right: 0;
z-index: 100;
bottom: 0;
display: none;
border: 1px solid;
}
#close-button {
float: right;
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="link">Click to show form</button>
<div class="form">
<img src="'/close.png" id="close-button">
<input id="input-field" />
</div>

Disable part of textarea content

I have textarea with a static content. So I disabled the textarea to prevent any modification in the content. But I want to modify some part of this content. How can I do this ?
I have created a select box as follows :
<div class="scroll-inside">
<?php if($transactionalTemplates->num_rows() > 0) {
foreach($transactionalTemplates->result_array() as $template) { ?>
<a href="#" class="transactionalTemplate" data-text="<?php echo $template['TemplateText']?>">
<?php echo $template['TemplateText'];?>
</a>
<?php }
}
?>
</div>
When I select an item, the selected item will pasted to the following textarea
<textarea placeholder="Enter your message here.." maxlength="160" class="messageTransactional" name="messageTransactional" id="messageTransactionalEnglish"></textarea>
here is my script code:
$('.transactionalTemplate').click(function() {
$('.messageTransactional').val($(this).data('text'));
flag = true;
$('.messageTransactional').keypress(function(e) {
e.preventDefault();
});
});
After adding the content to textarea, I prevent typing new content using the above function.
here is an example:
Suppose Dear (123), thanks for registering with us. Please subscribe our new offer to send unlimited SMS. For details please call (123) is my content.
I need to edit this content as Dear John, thanks for registering with us. Please subscribe our new offer to send unlimited SMS. For details please call 91xxxxxxxx
Which means, I need to change the content in paranthesis, keeping the format static.
I would highly suggest not using a textarea. There is no real way to stop that. You would need to do it yourself and try to catch every possibility to change that.
Instead, a simple text-input usually looks the best.
Alternatively, if it has to be seamless, you can use a contenteditable span, like this:
Dear <span contenteditable="true">(please enter your name here)</span>, thanks for registering with us. Please subscribe our new offer to send unlimited SMS. For details please call <span contenteditable="true">(please enter your tel. number here)</span>
I was bored so did a pretty cool solution, it's not perfect though and still needs work for production.
const $editable = $('.editable')
const $inputs = $('.input')
const $save = $('#save')
const popup = function(e) {
const $this = $(this)
$this
.find('input')
.addClass('active')
.focus()
}
const onBlur = function(e) {
const $this = $(this)
const $parent = $this.parent()
const value = $this.val()
$parent.find('input')
.removeClass('active')
if (value) {
$parent
.find('.value')
.text($this.val())
}
}
const onSave = function(e) {
const $pre = $('pre')
console.log('save', $pre.text())
}
$editable.on('click', popup)
$inputs.on('blur', onBlur)
$save.on('click', onSave)
body {
padding: 1em;
}
pre {
white-space: normal;
font-family: sans-serif;
}
.editable {
border-bottom: 1px dotted #3cf;
color: #3cf;
min-width: 1em;
min-height: 1em;
position: relative;
}
.editable input {
position: absolute;
width: 80px;
transform: translate(-70px, 0%);
border: 1px solid #aaa;
padding: .5em;
border-radius: 5px;
text-align: center;
opacity: 0;
visibility: hidden;
transition: .4s opacity ease, .4s transform;
}
.editable input:focus,
.editable input.active {
transform: translate(-70px, -100%);
opacity: 1;
visibility: visible;
outline: none;
}
.editable:focus {
outline: none;
}
.button {
float: right;
padding: .5em 2em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="hidden" name="messageTransactional" />
<pre id=="messageTransactional">
Dear <span class="editable" id="name"><span class="value">name</span><input type="text" class="input" /></span>, thanks for registering with us. Please subscribe our new offer to send unlimited SMS. For details please call <span class="editable" id="phone"><span class="value">phone</span><input type="text" class="input" /></span> is my content.
</pre>
<button id="save" class="button">save</button>

Can you turn a CSS background-image into a submit button using JavaScript? [duplicate]

This question already has answers here:
How do I add a "search" button in a text input field?
(7 answers)
Closed 5 years ago.
Here is the HTML form:
<form method="post" action="search.php">
<input type="text" id="inputSearch"/>
</form>
And some CSS:
#inputSearch {
padding:18px 15px 18px 52px;
font-size:1rem;
color:#1f5350;
border:none;
/*defining background image as a search symbol*/
background: #7accc8 url(search.png) 8px 14px no-repeat;
background-size:25px 26px;
}
The search icon is just a static image. Using JavaScript, how can I grab the CSS background-image and use it to create a clickable submit button without adding further HTML code?
You can wrap your search icon in <a></a> tags, that way your image will be clickable and can take the user to the page you want once he clicks on it: Here's an example:
<div class="maindiv">
<form id="myform" name="myform" method="post" action="schitems.php">
<input type="search" id="itemcd" name="itemcd" class="inputfields" placeholder="Type an Ingredient..." />
<img src="search_icon.jpg" alt="search">
</form>
</div>
What you're trying to achieve can't actually be accomplished with raw CSS; you need to use JavaScript and attach a click event handler to the element.
Unfortunately, considering you're making use of background-image, your image is essentially 'part of' the whole <input> element itself, and as far as I'm aware, you can't separate out the click functionality (without making use of a separate element for the image).
Having said that, you can make it so that the form submits when any part of the <input> is clicked on with the following. This can be improved by double-checking that there is actually content entered into the input before allowing the form submission to fire:
var form = document.getElementById('myform');
var input = document.getElementById('itemcd');
input.onclick = function() {
if (this.value.length > 0) {
form.submit();
}
}
#myform {
width: 260px;
margin: 0 auto;
}
input[type="search"] {
padding: 18px 15px 18px 52px;
font-size: 1rem;
color: #1f5350;
/*removing boder from search box*/
border: none;
/*defining background image as a search symbol*/
background-image: url(http://placehold.it/100);
background-repeat: no-repeat;
/*background-size*/
-webkit-background-size: 25px 26px;
-moz-background-size: 25px 26px;
-o-background-size: 25px 26px;
background-size: 25px 26px;
/*positioning background image*/
background-position: 8px 14px;
/*changing background color form white*/
background-color: #7accc8;
outline: 0;
}
/*now using placeholder property to change color of placholder text and making it consitent accross the browser by use of prefix*/
input[type="search"]::-webkit-input-placeholder {
color: #b1e0de;
}
input[type="search"]:-moz-placeholder {
/* Firefox 18- */
color: #b1e0de;
}
input[type="search"]::-moz-placeholder {
/* Firefox 19+ */
color: #b1e0de;
}
input[type="search"]:-ms-input-placeholder {
/* interner explorer*/
color: #b1e0de;
}
<div class="maindiv">
<form id="myform" name="myform" method="post" action="schitems.php">
<input type="search" id="itemcd" name="itemcd" class="inputfields" placeholder="Type an Ingredient..." />
</form>
</div>
Hope this helps! :)

What are the drawbacks in my form design logic?

$('.login_links_register').click(
function () {
$("body").addClass("removeScroll");
$(".login_form_container").show();
$("#registerForm").show();
$(".login_form_container").css('top', '0px');
/*$('.overlay').addClass('visible');*/
});
$(document).on('click', ".close_button",
function (event) {
var negativeHeight = -1 * ($('.login_form_container').offset().top + $(this).parents('.login_form_container').height());
$(".login_form_container").css('top', negativeHeight);
//$(".login_form_container").slideUp();
/*$('.overlay').removeClass('visible');*/
setTimeout(function () {
$('.overlay').addClass('displayNone');
$(".login_links").removeClass("popup_opened");
$("#loginForm").hide();
$("#registerForm").hide();
$("body").removeClass("removeScroll");
}, 500); /*Execute a set of statements after a statement completion. To make it faster reduce the milliseconds*/
});
input[type="text"], input[type="password"] {
border: 1px solid #aaa;
}
.header2 {
background-color:#E1E3E5;
/*have to change */
/*padding: 15px 0;*/
}
.right {
float: right;
clear:both;
/*To avoid problems caused by float - but check it may cause some problems check for it*/
}
/*Instead overflow:auto(or) hidden*/
.clearboth::after {
clear: both;
content:"";
display: block;
visibility: hidden;
}
.displayNone {
display: none;
}
.emailField, .passwordField {
width: 200px;
padding: 5px;
}
/*to remove unnecessary margin caused by ul element */
.login_links_list {
/*margin:10px 0;*/
padding: 0px;
margin: 0;
}
.login_links.right {
margin-right: 70px;
/*Same as Login container*/
}
/*login_link ul li element*/
.login_links_list_ele, .login_links_list_label
/*can apply al these properties to anchor tag instead li */
{
float: left;
list-style: outside none none;
transition: all 0.5s ease 0s;
}
.login_links_list_label {
padding: 15px;
}
.login_links_register, .login_links_login {
/*border-right:1px solid #ccc;
border-left: 1px solid #ccc;*/
float:left;
padding:15px;
}
.login_form_container.right {
border: 1px solid #aaa;
margin-right: 70px;
/* For better alignment. Instead kissing the edge of the screen*/
transition: all 1s ease 0s;
position: relative;
top: -173px;
/* For Styling. instead displayNone*/
z-index: 2;
}
/*positioning close button*/
.close_button {
cursor: pointer;
float: right;
position: relative;
top: -15px;
right: -15px;
width: 17px;
}
.loginDiv.right {
padding: 15px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="headers header2 clearboth" id="header2">
<nav class="login_links right">
<ul class="login_links_list right">
<li class="login_links_list_label">Are you a member?</li>
<li id="login_links_register" class="login_links_list_ele login_links_register">Register</li>
<li id="login_links_login" class="login_links_list_ele login_links_login">login</li>
</ul>
</nav>
</div>
<div class="login_form_container right displayNone">
<form class="right registerForm" id="registerForm" method="POST" action="lib/registration_validate.php">
<img class="close_button close_popup close_register_form" src="image/close_icon.png"></img>
<div class="register_input">
<input autocomplete="off" class="register_links emailID" type="text" placeholder="Email ID" name="email"/>
</div>
<div class="register_input">
<input type="password" autocomplete="off" class="register_links password" placeholder="Password" name="password"/>
</div>
<div class="register_input">
<input autocomplete="off" class="register_links conf_password" type="password" placeholder="Confirm Password" name="confirmPassword"/>
</div>
<div class="register_submission">
<input type="submit" value="Register" name="submit" class="register_button"></input>
<div class="custom_checkbox_div">
<input id="custom_checkbox" class="custom_checkbox_input" type="checkbox" value="Remember Me" name="remMeCheckbox"/>
<label for="custom_checkbox" class="custom_checkbox_label"></label>
<label class="custom_checkbox_string" for="custom_checkbox">Remember Me</label>
</div>
</div>
This is in my HTML page. I have negative top to show and hide forms for better views.
Please clear me the following doubts
1) I have to send the data to server when user submits form. I do client-side and server-side validation. If client-side validation fails, I 'll show the errors in the form itself. If there is any server-side error, how do i show this in the form?
My ideas:
I have to insert some php error tags in the html page and change my filetype to php from html so that if there is any server side error i ll insert the error in those tags.
<span class="error">* <?php echo $emailErr;?></span>
Something like the above.
(or)
Take the user to another php page where user re-enter the details. and handles all the error in the same page.
2) What are the problems with this type of negative top form design?
Please let me know the problems and suitable solutions so that i get clean design. I don't want the code only the idea.
There are couple of ways to do it but I am gonna stay low here by giving more of a hint to what you can do.
Using AJAX to submit form?
If the validation fails in PHP...
Create an associative array containing all the error messages and a key like submitError set to TRUE.
json_encode the array and die or return it.
In your JavaScript AJAX success callback, check for the existence of submitError key in the response.
If true, parse and display all messages from the JSON response you received. Done!
NOT using AJAX?
You can utilize $_SESSION to store the errors and related messages & set a flag for error.
When the page loads/submits, check if $_SESSION contains that flag.
If it does, pull the messages from session and display to the user.
Once displayed, clear those things from $_SESSION
These things can be done for small applications. If you are using some kind of framework like CodeIgniter or Laravel, you may want to check their session flash methods.
About Negative Top Form Design
I don't see much of a problem there unless it's covering up something vital beneath it when opened. Specially on mobile version( if you plan to do that).

Issue with tabbing between form fields when using jQuery custom scrollbars

I'm working on project to provide a bolt-on tool for websites, which makes heavy use of jQuery. Presentation / design is crucial, and I want to replace the standard (ugly) scrollbar applied by the browser to html elements with overflowing content, with something better looking.
There are numerous jQuery plug-ins around that apply custom scrollbars and allow styling via CSS which is great, but all the ones I've tried seem to suffer from the same problem which is this: if the scrollable content contains a form with text fields etc, tabbing between fields does not activate the scrollbar, and in some cases can screw up the custom scrollbar layout altogether.
Two examples of plug-ins I've tried:
http://manos.malihu.gr/jquery-custom-content-scroller
http://baijs.nl/tinyscrollbar/
I've tried others also, but in all demos / examples the content is plain text. I've done a lot of searching on this already, but it seems no-one has tried using these plug-ins with form-based content.
All these plug-ins seem to work in more or less the same way, and I can see exactly what happens and why, but just wondered if anyone else has had this problem and / or found a solution?
This issue can be easily replicated as follows (using the tinyscrollbar plug-in):
Add this to a standard html test page -
CSS:
<style>
#tinyscrollbartest { width: 520px; height: 250px; padding-right: 20px; background-color: #eee; }
#tinyscrollbartest .viewport { width: 500px; height: 200px; overflow: hidden; position: relative; }
#tinyscrollbartest .overview { list-style: none; position: absolute; left: 0; top: 0; }
#tinyscrollbartest .scrollbar { position: relative; float: right; width: 15px; }
#tinyscrollbartest .track { background: #d8eefd; height: 100%; width: 13px; position: relative; padding: 0 1px; }
#tinyscrollbartest .thumb { height: 20px; width: 13px; cursor: pointer; overflow: hidden; position: absolute; top: 0; }
#tinyscrollbartest .thumb .end { overflow: hidden; height: 5px; width: 13px; }
#tinyscrollbartest .thumb, #tinyscrollbartest .thumb .end { background-color: #003d5d; }
#tinyscrollbartest .disable { display: none; }
</style>
Html:
<div id="tinyscrollbartest">
<div class="scrollbar">
<div class="track">
<div class="thumb">
<div class="end"></div>
</div>
</div>
</div>
<div class="viewport">
<div class="overview">
</p>Here's a text field: <input type="text"/><p>
...
// lots of content to force scrollbar to appear,
// and to push the next field out of sight ..
...
<p>Here's another field: <input type="text"/></p>
</div>
</div>
</div>
Plug-in reference (assuming jquery libraries etc are referenced also):
<script type="text/javascript" src="scripts/jquery.tinyscrollbar.min.js"></script>
Jquery code:
<script type="text/javascript">
$(document).ready(function () {
$('#tinyscrollbartest').tinyscrollbar();
});
</script>
Now click in the first text field so it has focus, hit the tab key to move to the next one and see what happens.
I understand your problem.. But is hard to find a good solution to this. You could try to set a focus event on your form elements. And let this event trigger the scrollbar_update function of tinyscrollbar. You can set the offsetTop of the form element that currently has focus as the methods parameter. I think that would work.
$('formelements').focus(function(){
YourScrollbar.tinyscrollbar_update(this.offsetTop);
});
I had to overwrite the standard tabbing functionality with my own:
$(".scrollable").each(function() {
if (!$(this).data("scrollbar"))
{
$(this).data("scrollbar", new Scrollbar({
holder:$(this)
}));
$(this).find("input").bind("keydown", function(e)
{
var keyCode = e.keyCode || e.which;
if (keyCode == 9)
{
e.preventDefault();
var scrollTo = $(this);
if (e.shiftKey)
{
var nextInput = $(this).prevAll("input:not([type=hidden])").first();
scrollTo = nextInput.prevAll("input:not([type=hidden]), label").first();
}
else
{
var nextInput = $(this).nextAll("input:not([type=hidden])").first();
}
if (nextInput.length)
{
console.log(scrollTo);
$(this).closest(".scrollable").data("scrollbar").scrollTo(scrollTo, function()
{
nextInput.focus().select();
});
}
}
});
}
});
It's a bit annoying to have to wait for the scroll but I don't see any other option.

Categories

Resources