Ok, so I have a filterable search form that returns certain images in a grid, which works great, it resets when I delete the text in the search input, but when I click the "Clear" button, which should do the same thing as deleting the text, it doesn't work. Here is the HTML and JQuery used:
<form id="live-search" action="" class="styled" method="post" style="margin: 2em 0;">
<div class="form-group">
<input type="text" class="form-control" id="filter" value="" style="width: 80%; float: left;" placeholder="Type to search"/>
<span id="filter-count"></span>
<input type="button" class="clear-btn" value="Clear" style="background: transparent; border: 2px solid #af2332; color: #af2332; padding: 5px 15px; border-radius: 3px; font-size: 18px; height: 34px;">
</div>
</form>
This is the JQuery for the clearing text:
jQuery(document).ready(function(){
jQuery("#filter").keyup(function(){
// Retrieve the input field text and reset the count to zero
var filter = jQuery(this).val(), count = 0;
// Loop through the comment list
jQuery(".watcheroo").each(function(){
jQuery(this).removeClass('active');
// If the list item does not contain the text phrase fade it out
if (jQuery(this).text().search(new RegExp(filter, "i")) < 0) {
jQuery(this).fadeOut();
// Show the list item if the phrase matches and increase the count by 1
} else {
jQuery(this).show();
count++;
}
});
// Update the count
var numberItems = count;
});
//clear button remove text
jQuery(".clear-btn").click( function() {
jQuery("#filter").value = "";
});
});
Any help would greatly be appreciated.
value is a property on a DOMElement, not a jQuery object. Use val('') instead:
jQuery(document).ready(function($) {
$("#filter").keyup(function() {
var filter = $(this).val(),
count = 0;
$(".watcheroo").each(function(){
var $watcheroo = $(this);
$watcheroo.removeClass('active');
if ($watcheroo.text().search(new RegExp(filter, "i")) < 0) {
$watcheroo.fadeOut();
} else {
$watcheroo.show();
count++;
}
});
var numberItems = count;
});
$(".clear-btn").click(function() {
$("#filter").val(''); // <-- note val() here
});
});
Note that I amended your code to alias the instance of jQuery passed in to the document.ready handler. This way you can still use the $ variable safely within the scope of that function.
As the accepted answer doesn't solve the problem.
Try input event instead of keyup
$("#filter").on("input", function() {.....
& then clear the filter input field on which event you want.
$(".clear-btn").on("click", function() {
$("#filter").val("").trigger("input");
});
Add this to your CSS:
input[type="search"]::-webkit-search-cancel-button {
-webkit-appearance: searchfield-cancel-button;
}
<form>
<input type="search" name="search" placeholder="Search...">
</form>
Related
I tried to change the background color of the input field with an if statement. I dont know why it isnt working. What can I do to get it working?
function increment() {
var textbox = document.
getElementById("inc");
textbox.value++;
}
var inputfield = document.getElementById("inc")
// trying to change bg color of inputfield if number higher or lower -- doesnt work yet
if (inputfield.value > 3) {
inputfield.style.backgroundColor = "#AA0000";
}
<div class = wrapper>
<button onclick="increment()">Click to + 1!</button>
<input class="inputfield" id="inc" type="text" value="0" />
</div>
While your javascript function increment() gets executed each click of the button, the rest of your javascript code gets only executed once after the document has been loaded. Initially input field #inc value is 0 and will not change color as it never becomes > 3 this way.
In your Javascript:
you only have to get the reference to input element #inc once (const textBox) and use that in your increment function. In the snippet I defined the constant textBox as global because the reference does not change, just its .value. Consequently method .getElementById does not have to be executed each click of the button.
After the button has been clicked, increment textBox.value and change the color when the value > 3.
Snippet
// Get a reference to the textbox
const textbox = document.getElementById("inc");
function increment() {
textbox.value++; // increment its value
if (textbox.value > 3) {
// change its color
textbox.style.backgroundColor = "#AA0000";
}
}
<div class=wrapper>
<button onclick="increment()">Click to + 1!</button>
<input class="inputfield" id="inc" type="text" value="0" />
</div>
Check this out.
const inputfield = document.getElementById("change_color_example")
inputfield.addEventListener("keyup", function() {
if (this.value > 3) {
this.classList.add("active-math")
} else {
this.classList.remove("active-math")
}
if (this.value.length > 3) {
this.classList.add("active-length")
} else {
this.classList.remove("active-length")
}
})
.example-input {
color: #333333;
background-color: #ffffff;
border: 1px solid #000000;
transition: all 300ms linear;
}
.example-input.active-math {
color: #f8f8f8;
background-color: #AA0000;
}
.example-input.active-length {
color: blue;
background-color: bisque;
}
<input type="text" id="change_color_example" class="example-input" />
We can start of by grabbing the input element from the DOM.
const input = document.querySelector('input');
Once we have the element to work with we can, we can add an event listener (blur) so whenever a user moves out of the box the action in the code will be performed.
JS:
const input = document.getElementById("input");
input.addEventListener("blur", () => {
if (input.value.length > 3) {
input.style.backgroundColor = "red";
}
});
HTML:
<input type="text" id="input" />
A javascript program to concate the first name and last name, but the concated string gets displayed as the cursor moves out from the last name text box
`
<!DOCTYPE html>
<html lang="en">
<head>
<title>Practical 3</title>
<style>
#concatenator {
background-color: white;
height: 150px;
width: 330px;
border-width: 4px;
border-color: black;
border-style: solid;
padding: 5px;
}
</style>
<script>
function concat() {
fst = String(myform.fst.value);
snd = String(myform.snd.value);
result = fst.concat(" ", snd);
myform.result.value = result;
}
function refresh() {
location.reload();
}
</script>
</head>
<body id="concatenator">
<form name="myform">
Enter first name: <input type="text" name="fst"><br><br>
Enter second name: <input type="text" name="snd"><br><br>
<input type="Button" name="" value="Refresh" onclick="refresh()">
<input type="Button" name="" value="Full Name" onclick="concat()"><br><br>
Full Name: <input type="text" name="result">
</form>
</body>
</html>
`
I have to makes changes in this so that the full name button is gone and the two name are concatenated instantly
To achieve that result you may use a keyup event handler on your input elements so that a given logic will be executed every time the user type something.
Such logic just fetches the values of those input elements, concatenates the two string and sets the value of the return input element.
I used a general approach as far as possible so that the conditions to fetch those two input elements are defined as css selectors in the targetSelectors array.
//selectors relative to the root document for the input element to concat
const targetSelectors = ['#myform [name=fst]', '#myform [name=snd]'];
//adds a keyup event handler to all the elements in targetSelectors
targetSelectors.forEach( (targetSelector) => {
document.querySelector(targetSelector)
.addEventListener('keyup', (event) => {
//concats the fields value
const concatenated = concatFields(' ');
//refreshes the result input field value with the new one
refreshField('input[name=result]', concatenated);
});
});
//sets the value of the input element found with targetSelector
function refreshField(targetSelector, value){
document.querySelector(targetSelector).value = value;
}
//returns the concatenated values from the input elements in targetSelectors (separated by spacer)
function concatFields(spacer = ''){
return targetSelectors.map( targetSelector => document.querySelector(targetSelector).value ).join(spacer);
}
<!DOCTYPE html>
<html lang="en">
<head>
<title>Practical 3</title>
<style>
#concatenator {
background-color: white;
height: 150px;
width: 330px;
border-width: 4px;
border-color: black;
border-style: solid;
padding: 5px;
}
</style>
<script>
function concat() {
fst = String(myform.fst.value);
snd = String(myform.snd.value);
result = fst.concat(" ", snd);
myform.result.value = result;
}
function refresh() {
location.reload();
}
</script>
</head>
<body id="concatenator">
<form id="myform">
Enter first name: <input type="text" name="fst"><br><br>
Enter second name: <input type="text" name="snd"><br><br>
Full Name: <input type="text" name="result">
</form>
</body>
</html>
And this an attempt went too far with the generalization able to keep an arbitrary number of inputs bound to each other in the aim of concatenating their values inside an output element when the change event occurs on any of those inputs.
*the answer was accepted already.. it was for the sake of making sense of the generalized approach and nothing else
const c = new Concatenator(
retrieveClassSelectors('#showingMaxPotential input.concat'),
'#showingMaxPotential input[name=result]');
//returns an array of selector (sorted) based on the class attribute belonging to all the elements grabbed by the matchingSelector
function retrieveClassSelectors(matchingSelector){
const specificSelectors =
[...document.querySelectorAll(matchingSelector)]
.map(target => {
const classesSelector =
target.getAttribute('class')
.replace(/[^\s]+/g, '.$&')
.replace(/\s/g, '');
return classesSelector;
}).sort();
return specificSelectors;
}
function Concatenator(targetSelectors, outputSelector) {
this.init = () => {
//adds a keyup event handler to all the elements in targetSelectors
this.targetSelectors.forEach((targetSelector) => {
document.querySelector(targetSelector)
.addEventListener('keyup', (event) => {
//refreshes the result input field value with the new one
this.refreshField(this.outputSelector, this.concatFields(' '));
});
});
}
//sets the value of the input element found with targetSelector
this.refreshField = (targetSelector, value) => {
document.querySelector(targetSelector).value = value;
}
//returns the concatenated values from the input elements in targetSelectors (separated by spacer)
this.concatFields = (spacer = '') => {
return this.targetSelectors.map(targetSelector => document.querySelector(targetSelector).value).join(spacer);
}
this.targetSelectors = targetSelectors;
this.outputSelector = outputSelector;
this.init();
}
form#showingMaxPotential{
border: solid 1px darkgray;
padding: 1em;
}
form#showingMaxPotential > label,
form#showingMaxPotential > input{
display: block;
}
form#showingMaxPotential > input{
margin-bottom: 1em;
}
<form id="showingMaxPotential">
<label>Enter <b>first</b> item name:</label>
<input type="text" name="i1" class="concat item-1">
<label>Enter <b>last</b> item name:</label>
<input type="text" name="i3" class="concat item-3">
<label>Enter <b>middle</b> item name:</label>
<input type="text" name="i2" class="concat item-2">
<label>Full Name:</label>
<input type="text" name="result" disabled>
</form>
I have a series of forms on a page which each have a simple text counter on the input element (to illustrate the length of a title as it is being typed). When I was working out how to do the counter it was on a singular instance of the form.
How do I have it so the counter works in relation to the nextElementSibling when there are multiple instances of the form? I would've thought it would be done with e.target property, but I can't work out how to store the input element as a target so to speak? I thought e.target = item in the code below would work but this doesn't.
Codepen: https://codepen.io/thechewy/pen/powZppR
var title = document.querySelectorAll(".image-title-upload"),
charsRemaining = document.querySelectorAll(".image-title-upload").nextElementSibling,
maxValue = 125;
title.forEach((item) => {
item.addEventListener("input", (e) => {
//e.target = item; thought this might work but it doesn't
remaining = maxValue - item.value.length; // work out how many characters are left
charsRemaining.textContent = remaining;
});
});
form {
margin-bottom: 2rem;
}
span {
display: block;
margin-top: 4px;
}
<form>
<input class="image-title-upload" type="text" name="image-title" placeholder="Title">
<span class="tl characters-remaining">125</span>
</form>
<form>
<input class="image-title-upload" type="text" name="image-title" placeholder="Title">
<span class="tl characters-remaining">125</span>
</form>
this way
const
titleInput = document.querySelectorAll(".image-title-upload")
, maxValue = 125;
titleInput.forEach( item =>
{
item.oninput = e =>
{
item.nextElementSibling.textContent = maxValue - item.value.length
}
})
form {
margin-bottom: 2rem;
}
span {
display: block;
margin-top: 4px;
}
<form>
<input class="image-title-upload" type="text" name="image-title" placeholder="Title">
<span class="tl characters-remaining">125</span>
</form>
<form>
<input class="image-title-upload" type="text" name="image-title" placeholder="Title">
<span class="tl characters-remaining">125</span>
</form>
you can also use
e.target.closest('form').querySelector('.characters-remaining').textContent = ....
I am using - and + buttons to change the number of the text box, I am having troubles dealing with different text fields, here is my code:
var unit = 0;
var total;
// if user changes value in field
$('.field').change(function() {
unit = this.value;
});
$('.add').click(function() {
unit++;
var $input = $(this).prevUntil('.sub');
$input.val(unit);
unit = unit;
});
$('.sub').click(function() {
if (unit > 0) {
unit--;
var $input = $(this).nextUntil('.add');
$input.val(unit);
}
});
button {
margin: 4px;
cursor: pointer;
}
input {
text-align: center;
width: 40px;
margin: 4px;
color: salmon;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id=field1>
field 1
<button type="button" id="sub" class=sub>-</button>
<input type="text" id="1" value=0 class=field>
<button type="button" id="add" class=add>+</button>
</div>
<div id=field2>
field 2
<button type="button" id="sub2" class=sub>-</button>
<input type="text" id="2" value=0 class=field>
<button type="button" id="add2" class=add>+</button>
</div>
And here's the DEMO
You can see in the demo that the values change correctly only if you click buttons on the same field, but if you alternate between fields the values don't change properly.
This should be all you need:
$('.add').click(function () {
$(this).prev().val(+$(this).prev().val() + 1);
});
$('.sub').click(function () {
if ($(this).next().val() > 0) $(this).next().val(+$(this).next().val() - 1);
});
By using the unit variable you were tying both inputs together. And the plus in +$(this) is a shorthand way to take the string value from the input and convert it to a number.
jsFiddle example
You're using the same variable to hold the values of your two inputs. One simple option would be to use two variables instead of one:
var unit_1 = 0;
$('#add1').click(function() {
unit_1++;
var $input = $(this).prev();
$input.val(unit_1);
});
/* Same idea for sub1 */
var unit_2 = 0;
$('#add2').click(function() {
unit_2++;
var $input = $(this).prev();
$input.val(unit_2);
});
/* Same idea for sub2 */
and unit = unit just assigns the value of unit to itself, so that's no very useful and you can certainly leave it out.
An alternative approach is to use data attributes and have each element store its own value. Edit: it already stores its own value. Just access it.
var total;
// if user changes value in field
$('.field').change(function() {
// maybe update the total here?
}).trigger('change');
$('.add').click(function() {
var target = $('.field', this.parentNode)[0];
target.value = +target.value + 1;
});
$('.sub').click(function() {
var target = $('.field', this.parentNode)[0];
if (target.value > 0) {
target.value = +target.value - 1;
}
});
button {
margin: 4px;
cursor: pointer;
}
input {
text-align: center;
width: 40px;
margin: 4px;
color: salmon;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id=field1>
field 1
<button type="button" id="sub" class=sub>-</button>
<input type="text" id="1" value=0 class=field>
<button type="button" id="add" class=add>+</button>
</div>
<div id=field2>
field 2
<button type="button" id="sub2" class=sub>-</button>
<input type="text" id="2" value=0 class=field>
<button type="button" id="add2" class=add>+</button>
</div>
This code is functioning correctly. However, I need help getting the "input" tag to display like a combobox. I have tried to styled the inputbox as a combobox without success. I am also looking for a way to make the code work with a combobox by building the options dynamically. Any and all help is appreciated.
$(function () {
var availableTags = new Array(1000000);
var j = 0;
for (var i = 1; i < availableTags.length; i++) {
availableTags[j++] = i.toString();
}
$("#tags").autocomplete({
source: function (req, responseFn) {
var re = req.term;
var matcher = new RegExp("^" + re, "i");
var a = $.grep(availableTags, function (item) {
return matcher.test(item);
});
responseFn(a.slice(0, 5));
},
select: function (event, ui) {
if (ui.item && ui.item.value) {
var titleinput = ui.item.value;
ui.item.value = $.trim(titleinput);
alert(ui.item.value);
}
},
change: function (event, ui) {
if (!valid) {
// remove invalid value, as it didn't match anything
$(this).val("");
select.val("");
return false;
}
}
});
});
.custom-combobox {
position: relative;
display: inline-block;
border-style: solid;
border-width: 1px;
}
.custom-combobox-toggle {
position: absolute;
top: 0;
bottom: 0;
margin-left: -1px;
padding: 0;
}
.custom-combobox-input {
margin: 0;
padding: 5px 10px;
}
/*
.custom-combobox-list-item {
color: blue;
font-weight: bold;
}
.custom-combobox-input , .custom-combobox-list-item.ui-state-focus {
color: black;
font-weight: bold;
font-style: italic;
}
*/
#tags {
width: 40px;
}
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
<script type="text/javascript" src="https://code.jquery.com/ui/1.11.1/jquery-ui.min.js"></script>
<link rel="stylesheet" href="https://code.jquery.com/ui/1.11.1/themes/smoothness/jquery-ui.css">
<label for="tags">Tags: </label>
<input id="tags" type="text" class="custom-combobox" value="">
You could use a datalist to transfer the options to the text input which will then turn it into a combobox
I slimmed your code write down to the very basics to make a simple example.
<label for="tags">Tags: </label>
<input id="tags" name="tags" type="text" list="options" class="custom-combobox" value="">
<datalist id="options">
<!-- it puts the options here then the input type text gets them as select options -->
</datalist>
$(function () {
var availableTags = new Array(10);
var j = 0;
for (var i = 1; i < availableTags.length; i++) {
$('#options').append("<option value='" + i + "'>");
}
});
here is a JSFIDDLE showing the basic functionality
After a research I found Combo-Box-jQuery-Plugin written by dellsala.
What is it ?
Turns a <input type="text"> into a combo box.
autocomplete
keyboard controls
most styles can be customized via css
list of values can be changed dynamically
How it looks like ?
Why I suggest that ?
This is not intended for extending <select> elements. Many other jquery "combo box" plugins out there behave more like searchable select elements with disctinct labels and values for each option. This plugin simply allows the user to choose from existing text values or supply their own.
How to use ? http://jsfiddle.net/csdtesting/eh0gse2f/
<div class="inputCombox">
<label for="input1">Field1:</label>
<input id="input1" type="text" value="" />
</div>
<div class="inputCombox">
<label for="input2">Field2:</label>
<input id="input2" type="text" value="" />
</div>
jQuery(function () {
var varValue = 12;
var aval = [
'Yo',
'1',
'Jo',
varValue.toString()];
//#Example 1
jQuery('#input1').combobox(aval);
//#Example 2
jQuery('#input2').combobox([
'Yo',
'1',
'Jo']);
});
Please Check this it might be helpful
http://jqueryui.com/autocomplete/#combobox
http://demos.telerik.com/kendo-ui/combobox/cascadingcombobox
Do you need this? http://jqueryui.com/autocomplete/#combobox
It's pretty simple, just look that is an input, with an anchor at the end.
Just click on "view source" to see how it's implemented.
Good luck!
Try the bootstrap tags
$("#tags").tagsinput("Amsterdam,Washington,Los Angeles");
Bootstrap Tags Input
Try to use select2.
To populate the Select2 with an ajax call, try this:
PHP:
<?php
$result = array();
//Do something with the search string ($searchfor), eg. find the desired results
$result[] = array('id' => '1', 'text' => '101');
$result[] = array('id' => '2', 'text' => '102');
$result[] = array('id' => '3', 'text' => '103');
$result[] = array('id' => '4', 'text' => '104');
$result[] = array('id' => '5', 'text' => '105');
//Send the ajax results formatted as JSON
print(json_encode($result));
?>
HTML:
<input type="hidden" id="tags" value="" style="width: 300px;">
<script>
$('#tags').select2({
minimumInputLength: 2,
ajax: {
url: 'http://yourdomain.com/ajax.php',
dataType: 'json',
type: "GET",
quietMillis: 100,
data: function (term) {
return {
searchfor: term
};
},
results: function (data) {
return {
results: data
};
}
}
});
</script>
Here's a quick workaround to make your inout look like a select. No code changes needed, just some HTML/CSS. I made your input transparent, and layered a select behind it. The functionality is still handled by your input, but now it looks exactly like the select.
Demo - http://jsfiddle.net/sifriday/xy0mxst4/1/
Trick - Do this with the HTML:
<div id="wrapper">
<select id="fake-tags"></select>
<input id="tags" type="text" class="custom-combobox" value="" />
</div>
and add this CSS to make the input appear above the select to handle the functionality:
#tags {
width: 40px;
border: 0;
background: none;
margin-left: -50px;
}
#tags:focus {
outline: 0
}
#fake-tags {
width: 50px;
}
It's a hack, but it's a super-simple one and it sounds like it might be just what you need - you already have working code, you just need it to look a bit different.
This is inspired by the 'good old day's, when people used to layer a nice looking but fake file upload control on top of the nasty default browser one. The default did the real work, and the fake one just provided the nice UI. People don't do this so much now that we have the FileAPI.
I will place the image of a clickable down arrow next to the textbox. I will display 1 to 10 in the list box if the user clicks the image instead of entering data into the text box.