Switching position of bootstrap input-group-addon & input when on mobile - javascript

I tried to change the position of bootstrap input-group-addon when on mobile by using two input and playing with their display and visibility.
From a frontend visibility perspective I got what I want, the input is now behind the addons ... but I'm running some javascript on #input-newsearch and when on mobile it's not working. It looks like it's still looking at the first input. What am I missing or how can I solve this?
html:
<div class="input-group">
<input id="input-newsearch" class="form-control input-newsearch-desktop" type="text">
<span class="input-group-addon" id="delete-newsearch">Delete</span>
<span class="input-group-addon" id="remove-newsearch">Remove</span>
<input id="input-newsearch" class="form-control input-newsearch-mobile" type="text">
</div>
css:
.input-newsearch-mobile {
display: none;
visibility: hidden;
}
#media (max-width: 768px){
.input-newsearch-desktop {
display: none;
visibility: hidden;
}
.input-newsearch-mobile {
display: initial;
visibility: initial;
}
}
javascript:
$('#delete-newsearch, #delete-newsearch').on('click', function() {
$('#input-newsearch').val('');
});
$('#input-newsearch').autocomplete({
source:'/source.php',
minLength: 3,
...
});

Instead of using Id's as your selection I would use a class instead.
The reason it is not working as you intended is because Id's are expected to only show up once. It causes problems when you have multiple elements with the same Id and try to reference one of them.
Styles
Added the class input-newsearch
<div class="input-group">
<input id="input-newsearch" class="form-control input-newsearch input-newsearch-desktop" type="text">
<span class="input-group-addon" id="delete-newsearch">Delete</span>
<span class="input-group-addon" id="remove-newsearch">Remove</span>
<input id="input-newsearch" class="form-control input-newsearch input-newsearch-mobile" type="text">
</div>
Javascript
Changed Id selector '#input-newsearch' to the class '.input-newsearch'
$('#delete-newsearch, #delete-newsearch').on('click', function() {
$('.input-newsearch').val('');
});
$('.input-newsearch').autocomplete({
source:'/source.php',
minLength: 3,
...
});

Related

How can i wap the position of the label and the input tag with javascript?

I'm using elementor in wordpress, i'cant modify the html directly, so i need to swap both tags with javascript (or css if that's possible) in the form.
The code i'm using in CSS:
input:focus > .elementor-field-label {
border: 1px solid black !important;
border-radius: 5px;
transform: translate(0px, -20px);
font-size: 14px;
}
Won't work because of the position of the tags.
Then i tried this code in javascript to do the job:
$('label').each(function() {
$(this).insertAfter($(this).nextAll('input:first'));
});
But don't work.
So, how can i make this possible?
FIY:
The structure of this specific part of the form is this:
<div class="elementor-field-type-text elementor-field-group elementor-column elementor-field-group-name elementor-col-100 elementor-field-required"> /*Using just the elementor-field-group*/
<label for="form-field-name" class="elementor-field-label"> Texto </label>
<input size="1" type="text" name="form_fields[name]" id="form-field-name" class="elementor-field elementor-size-sm elementor-field-textual" required="required" aria-required="true">
</div>
With CSS you could do something like this:
.elementor-field-group {
display: flex;
flex-flow: column;
}
.elementor-field-group input {
order: -1;
}
This wouldn't change the HTML structure but visually they would swap position.
With Javascript you can do it like this:
document.querySelectorAll('.elementor-field-group label').forEach((e) => {
e.parentNode.appendChild(e)
})
This script just takes the label and appends it to the parent again, so it will be the last child of the wrapper.
Or this, to add the input element before the label. This would be the better solution, if there are more than those two elements inside of the wrapper.
document.querySelectorAll('.elementor-field-group input').forEach((e) => {
e.parentNode.insertBefore(e, e.previousElementSibling);
})

How can I toggle image source only during input focus?

Summary: I've created a search bar with three inputs: name, date of birth, and social security number. The functionality is all there, but I am attempting to elevate the design and am running into an issue on input focus.
When the user selects the inputs, there are focus effects in my CSS. What I am trying to do is toggle the images on input focus. Currently they are written like this:
<div class="adv-searchbar__wrapper__search-box">
<span class="column-1"><img src="/img/person-name.png" class="input-ico"/><input type="text" class="input" id="adv-input-1" placeholder="John Adam Smith"></span>
<span class="column-2"><input type="date" class="input" id="adv-input-2" placeholder="MM / DD / YY"></span>
<span class="column-3"><img src="/img/person-ssn.png" class="input-ico"/><input type="text" class="input" id="adv-input-3" placeholder="### - ## - ####"></span>
<button type="submit" class="advSearchBtn"><img src="/img/search_white.png"/></button>
</div>
The user can either click the button to execute the next function, or use the Enter key.
Effort: I've tried using if-else statements in jQuery when the user Clicks an input. The issue with that that I've found is that I am not sure how to 'measure' when the user leaves the input. So while the image will change correctly, it will not change back once the user moves on.
$('.input').click(function() {
let currIco = $(this)[0].previousSibling.src.slice(0, -4);
if ($(this).is(':focus')) {
console.log('input is focused');
currIco = currIco + '__focus.png';
$(this)[0].previousSibling.src = currIco;
} else {
console.log('input is blurred');
}
});
I've found several tutorials for changing images on click or on hover, but I haven't been able to implement those solutions to my needs.
You say in a comment that the only reason you didn't use CSS is because the images are not in the input.
As CSS is still an option for you and it is much easier to achieve in CSS (plus you haven't got a JS answer yet), take a look at the solution below.
FYI CSS-only is also a more efficient option - the more client-side processing you add, the slower the page load and the worse for SEO and user experience.
.column-1 input, .column-3 input {
background-repeat: no-repeat;
background-position: top left;
padding-left: 40px;
}
.column-1 input {
background-image: url(https://lorempixel.com/output/abstract-q-c-30-30-1.jpg);
}
.column-1 input:focus {
background-image: url(https://lorempixel.com/output/abstract-q-c-30-30-2.jpg);
}
.column-3 input {
background-image: url(https://lorempixel.com/output/abstract-q-c-30-30-3.jpg);
}
.column-3 input:focus {
background-image: url(https://lorempixel.com/output/abstract-q-c-30-30-4.jpg);
}
<div class="adv-searchbar__wrapper__search-box">
<span class="column-1">
<input type="text" class="input" id="adv-input-1" placeholder="John Adam Smith">
</span>
<span class="column-2"><input type="date" class="input" id="adv-input-2" placeholder="MM / DD / YY"></span>
<span class="column-3"><input type="text" class="input" id="adv-input-3" placeholder="### - ## - ####"></span>
<button type="submit" class="advSearchBtn"><img src="/img/search_white.png"/></button>
</div>
Obviously I haven't applied your styling to the inputs because you hadn't included it, but you can apply that the same way excluding the image.
You could, alternatively to the existing answer (provided by FluffyKitten), create a <label> element and place it after the <input>.
I too, don't recommend using JavaScript over CSS if you are indeed able to get it done in CSS.
In this case, you can separate the icon (and therefore the styling) from the rest of the input field if you so desire.
.adv-searchbar__wrapper__search-box span {
position: relative;
}
.input {
box-sizing: border-box;
padding: 2px 2px 2px 20px;
max-height: 20px;
border: 1px solid #888;
}
.input~.icon {
position: absolute;
left: 2px;
top: 0px;
height: 16px;
width: 16px;
background-image: url('https://via.placeholder.com/16?text=icon');
background-repeat: no-repeat;
}
.input:focus~.icon {
filter: blur(1px);
background-image: url('https://via.placeholder.com/16/FF9900');
}
<div class="adv-searchbar__wrapper__search-box">
<span class="column-1">
<input type="text" class="input" id="adv-input-1" placeholder="John Adam Smith">
<label class="icon" for="adv-input-1"></label>
</span>
<span class="column-2">
<input type="date" class="input" id="adv-input-2" placeholder="MM / DD / YY">
</span>
<span class="column-3">
<input type="text" class="input" id="adv-input-3" placeholder="### - ## - ####">
<label class="icon" for="adv-input-3"></label>
</span>
<button type="submit" class="advSearchBtn">
<img src="https://via.placeholder.com/16?text= "/>
</button>
</div>
Here is an other way, using focus on parent element.
span:focus-within .input-ico-focus {
display: inline-block;
}
span:focus-within .input-ico {
display: none
}
span .input-ico-focus {
display: none
}
span .input-ico {
display: inline-block;
}
.input-ico, .input-ico-focus {
width: 16px;
}
<div>
<span class="column-1">
<img src="https://i.stack.imgur.com/pd8J3.png" class="input-ico">
<img src="https://i.stack.imgur.com/XdkNO.png" class="input-ico-focus">
<input type="text" class="input" id="adv-input-1" placeholder="John Adam Smith">
</span>
</div>

Bootstrap 4 + Intl-Tel-Input Workaround

I am trying to use the intl-tel-input with bootstrap 4. However, I am not able to see the placeholder for the input at all. I tried almost all the solution available on the net on this matter but unfortunately, none worked.
This is my HTML
<div class="form-row">
<div class="form-group col-sm-12">
<label for="quote-phone" class="sr-only">Mobile Number</label>
<div class="input-group input-group-lg">
<input id="phone" type="tel" class="form-control" placeholder="Phone Number">
<div class="invalid-feedback">
Please provide a phone number.
</div>
</div>
</div>
</div>
This is my CSS
.iti-flag {
background-image: url("https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/12.0.3/img/flags.png");
}
#media only screen and (-webkit-min-device-pixel-ratio: 2),
only screen and (min--moz-device-pixel-ratio: 2),
only screen and (-o-min-device-pixel-ratio: 2 / 1),
only screen and (min-device-pixel-ratio: 2),
only screen and (min-resolution: 192dpi),
only screen and (min-resolution: 2dppx) {
.iti-flag {
background-image: url("https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/12.0.3/img/flags#2x.png");
}
}
And my JS to initialize the plugin:
$("#phone").intlTelInput({
utilsScript: "https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/12.0.3/js/utils.js",
allowDropdown: true
});
The only time I get to see the placeholder is when I do this:
#phone{
width:100%;
}
But it still doesn't cover the whole row obviously.
Here is the JSFiddle link.
Any workarounds to this problem?
It's because this class is making your input at 1% width:
.input-group .form-control, .intl-tel-input { width: 100%; }
If you overwrite that file, then you can see it.
.iti{ width: 100%;}
this works for me
if you are not using input-group or form-control just add below property
.intl-tel-input { width: 100%; }

Bootstrap datetimepicker strange positioning on a different div altogether

I am using bootstrap datetimepicker with formatting to enable only editing time in my code, I do it like this:
function setTimepicker(object){
object.datetimepicker({
format: 'HH:mm'
});
}
I call this function in document.ready like so:
$(document).ready(function(){
setTimepicker(starttimefield);
setTimepicker(endtimefield);
});
The html I am using is like this:
<div class="panel-body">
<form id="myform">
<p> <b>Create a New Event:</b></p>
<br>
<p>Description for main page: <br>
<textarea id="summary" name="summary" maxlength="100"></textarea>
</p>
<p> Full description: <br>
<textarea id="description" name="description" maxlength="500"></textarea>
</p>
<div class="wrapper">
<div class="titles">
<p> Event date:
</p>
<p> Start time:
</p>
<p> End time:
</p>
</div>
<div class="values">
<input type="text" id="eventdate" readonly/><br>
<div id="starttimepicker">
<input type="text" id="starttime" onkeydown="return false"/><br>
</div>
<div id="endttimepicker">
<input type="text" id="endtime" onkeydown="return false"/>
</div>
</div>
</div>
<p> Location: <input type="text" id="location"/> </p>
<p><input type="hidden" id="userid" value="<?php echo Auth::id();?>"/></p>
<p><input id="saveevent" type="button" value="Save Event" />
</p>
</form>
</div>
Except for the standard css files (jquery-ui.css, bootstrap-datetimepicker.css) I added 1 extra css file that contains:
.wrapper {
display: inline-block;
width: auto;
overflow: hidden;
}
.titles {
width: 100px;
float:left;
}
.values {
overflow: hidden;
margin-left: 100px;
}
Now for the issue at hand, the fields endtime and starttime should have a timepicker when clicked (this works) but look at where it renders the timepicker in this image:
Can anyone help me to get that timepicker element next to (or above or close by, anything) the field that it belongs to
You are missing an .input-group wrapper which has a position value of "relative". Since the datepicker is absolutely positioned it's container needs to be relatively positioned for the datepicker to be positioned correctly.
So I believe something like this would work:
.values {
position: relative;
overflow: hidden;
margin-left: 100px;
}
Better yet, let's set position relative on the divs that actually hold our inputs like so:
#starttimepicker {
position: relative;
}
#endtimepicker {
position: relative;
}
If you want my opinion though that is not very DRY. If you have control over the html you might try to add a class of "values__datepicker" (or whatever class) to #starttimepicker and #endtimepicker and set just one CSS rule like so:
.values__datepicker {
position: relative;
}

Forcing a tab stop on a hidden element? Possible?

The site is here
I have opt to using the radiobutton's labels as customized buttons for them. This means the radio inputs themselves are display:none. Because of this, the browsers don't tab stop at the radio labels, but I want them to.
I tried forcing a tabindex to them, but no cigar.
I have came up with just putting a pointless checkbox right before the labels, and set it to width: 1px; and height 1px; which seems to only really work on chrome & safari.
So do you have any other ideas for forcing a tab stop at those locations without showing an element?
Edit:
Just incase someone else comes by this, this is how I was able to insert small checkboxes into chrome & safari using JQuery:
if ($.browser.safari) {
$("label[for='Unlimited']").parent().after('<input style="height:1px; width:1px;" type="checkbox">');
$("label[for='cash']").parent().after('<input style="height:1px; width:1px;" type="checkbox">');
$("label[for='Length12']").parent().after('<input style="height:1px; width:1px;" type="checkbox">');
}
Note: $.browser.webkit was not becoming true...so I had to use safari
a working solution in my case to enable tab selection / arrow navigation was to set the opacity to zero rather than a "display: none"
.styled-selection input {
opacity: 0; // hide it visually
z-index: -1; // avoid unintended clicks
position: absolute; // don't affect other elements positioning
}
Keep the radio input hidden, but set tabindex="0" on the <label> element of reach radio input.
(A tab index of 0 keeps the element in tab flow with other elements with an unspecified tab index which are still tabbable.)
If you separate the label from any field and set a tabIndex you can tab to it and capture mouse and key events. It seems more sensible to use buttons or inputs with type="button",
but suit yourself.
<form>
<fieldset>
<input value="today">
<label tabIndex="0" onfocus="alert('label');">Label 1</label>
</fieldset>
</form>
I have an alternative answer that I think has not been mentioned yet. For recent work I've been reading the Mozilla Developer Docs MDN Docs, Forms, especially the Accessibility Section MDN Docs, Accessible HTML(5), for information related to keyboard accessibility and form structure.
One of the specific mentions in the Accessibility section is to use HTML5 elements when and where possible -- they often have cross-browser and more accessible support by default (not always true, but clear content structure and proper elements also help screen reading along with keyboard accessibility).
Anyway, here's a JSFiddle: JSFiddle::Keyboard Accessible Forms
Essentially, what I did was:
shamelessly copy over some of the source code from a Mozilla source code to a JSFiddle (source in the comments of the fiddle)
create a TEXT-type and assign it the "readonly" HTML5 attribute
add attribute tabindex="0" to the readonly
Modify the "readonly" CSS for that input element so it looks "blank" or hidden"
HTML
<title>Native keyboard accessibility</title>
<body>
<h1>Native keyboard accessibility</h1>
<hr>
<h2>Links</h2>
<p>This is a link to Mozilla.</p>
<p>Another link, to the Mozilla Developer Network.</p>
<h2>Buttons</h2>
<p>
<button data-message="This is from the first button">Click me!</button>
<button data-message="This is from the second button">Click me too!
</button>
<button data-message="This is from the third button">And me!</button>
</p>
<!-- "Invisible" HTML(5) element -->
<!-- * a READONLY text-input with modified CSS... -->
<hr>
<label for="hidden-anchor">Hidden Anchor Point</label>
<input type="text" class="hidden-anchor" id="hidden-anchor" tabindex="0" readonly />
<hr>
<h2>Form</h2>
<form name="personal-info">
<fieldset>
<legend>Personal Info</legend>
<div>
<label for="name">Fill in your name:</label>
<input type="text" id="name" name="name">
</div>
<div>
<label for="age">Enter your age:</label>
<input type="text" id="age" name="age">
</div>
<div>
<label for="mood">Choose your mood:</label>
<select id="mood" name="mood">
<option>Happy</option>
<option>Sad</option>
<option>Angry</option>
<option>Worried</option>
</select>
</div>
</fieldset>
</form>
<script>
var buttons = document.querySelectorAll('button');
for(var i = 0; i < buttons.length; i++) {
addHandler(buttons[i]);
}
function addHandler(button) {
button.addEventListener('click', function(e) {
var message = e.target.getAttribute('data-message');
alert(message);
})
}
</script>
</body>
CSS Styling
input {
margin-bottom: 10px;
}
button {
margin-right: 10px;
}
a:hover, input:hover, button:hover, select:hover,
a:focus, input:focus, button:focus, select:focus {
font-weight: bold;
}
.hidden-anchor {
border: none;
background: transparent!important;
}
.hidden-anchor:focus {
border: 1px solid #f6b73c;
}
BTW, you can edit the CSS rule for .hidden-anchor:focus to remove the highlight for the hidden anchor if you want. I added it just to "prove" the concept here, but it still works invisibly as requested.
I hope this helps!
My preference:
.tab-only:not(:focus) {
position: fixed;
left: -999999px;
}
<button class="tab-only">Jump to main</button>
Another great option would be to nest your input + div in a label and hide the input by setting width and height to 0px instead of display: none
This method even allows you to use pseudo-classes like :focus or :checked by using input:pseudo + styleDiv
<label>
<input type="radio">
<div class="styleDiv">Display text</div>
</label>
input
{
width: 0px;
height: 0px;
}
input + .styleDiv
{
//Radiobutton style here
display: inline-block
}
input:checked + .styleDiv
{
//Checked style here
}
Discard the radio-buttons and instead; keep some hidden fields in your code, in which you store the selected value of your UI components.

Categories

Resources