Javascript multi-selection - javascript

I currently have the following functionality (see link: http://jsfiddle.net/eUDRV/3/) and instead of appending the selected values back to the original list, I'd like to return them to the spot that they were previously in. My values are in alphabetical order. I know that I need to index the spot of each value but I'm not quite sure how to accomplish this. Any help would be appreciated, thanks.
Here's my HTML code:
<section class="container">
<div>
<select id="leftValues" size="5" multiple></select>
</div>
<div>
<input type="button" id="btnLeft" value="<<" />
<input type="button" id="btnRight" value=">>" />
</div>
<div>
<select id="rightValues" size="4" multiple>
<option>1</option>
<option>2</option>
<option>3</option>
</select>
<div>
<input type="text" id="txtRight" />
</div>
</div>
Javascript code:
$("#btnLeft").click(function () {
var selectedItem = $("#rightValues option:selected");
$("#leftValues").append(selectedItem);
});
$("#btnRight").click(function () {
var selectedItem = $("#leftValues option:selected");
$("#rightValues").append(selectedItem);
});
$("#rightValues").change(function () {
var selectedItem = $("#rightValues option:selected");
$("#txtRight").val(selectedItem.text());
});
CSS code:
SELECT, INPUT[type="text"] {
width: 160px;
box-sizing: border-box;
}
SECTION {
padding: 8px;
background-color: #f0f0f0;
overflow: auto;
}
SECTION > DIV {
float: left;
padding: 4px;
}
SECTION > DIV + DIV {
width: 40px;
text-align: center;
}

You could assign each option within your select a value attribute that corresponds to the text and then in your code:
$("#btnLeft").click(function () {
var selectedItem = $("#rightValues option:selected");
$("#leftValues").append(selectedItem);
});
You could have it look up the value of the selected item, compare it with anything in the list and place it in the appropriate index in that list and do the same for the code which moves it back into the right hand list.
You could also strip the innerHTML value of the option instead if you didn't want to add the value attribute.

Related

Add fileupload input fields inside multiple div at a same time according to radiobox selection

I have a input field that takes numeric inputs. Then i have a button which display the number of divs as per that input. after displaying div there is two radio-box buttons (paired end and single end) if I select paired end then i want two file upload fields in each divs. and if i select single end then i want only one file upload fields in each div.
I have tried but fileupload fields working on only first div.
function CreateText() {
var text = `<div class="row border-top py-3">
<div class="col-md-3">
<label">sample name *</label></br>
<input type="sample" id="sample" name="sample[]">
</div>
<div class="col-md-3" style="display:none" id="showsingle">
<div class="form-group">
<label for="form_upload">Upload file *</label></br>
<input type="file" id="myFile" name="filename1[]">
</div>
</div>
<div class="col-md-3" style="display:none" id="showpair">
<div class="form-group">
<label for="form_upload">Upload file *</label></br>
<input type="file" id="myFile" name="filename2[]">
<label for="form_upload">Upload file *</label></br>
<input type="file" id="myFile" name="filename2[]">
</div>
</div>
<div class="col-md-3 d-grid">
<div class="form-group">
<button class="btn btn-danger remove_add_btn">Remove</button>
</div>
</div>
</div>`;
var textCount = document.getElementById('textInput').value;
var html = '';
for (var i = 0; i < $('#textInput').val(); i++) {
html = document.getElementById('divDynamicTexts').innerHTML;
document.getElementById('divDynamicTexts').innerHTML = html + text.replace('', i);
}
}
function onlyOne() {
let SradioBox = document.getElementById("singleradio"),
Sfileupload = document.getElementById("showsingle"),
PradioBox = document.getElementById("pairedradio"),
Pfileupload = document.getElementById("showpair");
if (SradioBox.checked == true) {
Sfileupload.style.display = "block",
Pfileupload.style.display = "none";
} else if (PradioBox.checked == true) {
Pfileupload.style.display = "block",
Sfileupload.style.display = "none";
} else {
Pfileupload.style.display = "none",
Sfileupload.style.display = "none";
}
};
$(document).ready(function() {
$(document).on('click', '.remove_add_btn', function(e) {
e.preventDefault();
let row_item = $(this).parent().parent().parent();
$(row_item).remove();
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="text-center">
<input type="text" id="textInput" value="" />
<input type="button" id="" value="Create upload fields" onclick="CreateText();" />
<div class="col-md-4" id="filebutton">
<div class="form-group ">
<label for="form_need">Library Type *</label>
</br>
<div class="px-2">
<label for="myradio">Single end:</label>
<input type="radio" id="singleradio" name="check" onclick="onlyOne();">
<label for="myradio">Paired end:</label>
<input type="radio" id="pairedradio" name="check" onclick="onlyOne();">
</div>
</div>
</div>
</div>
<div id="divDynamicTexts"></div>
ID attributes must be unique. It would be better to remove the IDs altogether ( or change to dataset attributes perhaps ) and use a delegated event listener to process the various clicks related to the task of adding/removing dynamic elements.
In the code below all ID attributes were either removed entirely or changed to data-id type values.
To avoid the need to process different form file input fields at the server the file-input fields are named the same but have an index so can be identified more readily in PHP ( or whatever backend you have )
The delegated listener, because it is bound to the document, will work for all elements whether or not they are static or added dynamically and makes heavy use of the event.target property to help identify the element that invoked the event.
The label element was being used incorrectly previously. If the form-input is within the label then there is no need for the for="ID" syntax ( note that the ID should be the ID of the input element to which the label belongs! ) - as it was the label's appeared to have a for attribute which did not related to an element in the form!
Using querySelector and querySelectorAll you can easily identify nodes of interest within the DOM so button clicks or radio button selection can fire a query to find nodes that are relevant - thus simplifying the hiding/showing of the file input elements.
const strhtml = `
<div data-id="dynrow" class="row border-top py-3">
<div class="col-md-3">
<label>sample name *<input type="text" name="sample[]"></label>
</div>
<div class="col-md-3" style="display:none" data-id="single" data-role="file-field">
<div class="form-group">
<label>Upload file *<input type="file" name="filename[1]" /></label>
</div>
</div>
<div class="col-md-3" style="display:none" data-id="pair" data-role="file-field">
<div class="form-group ">
<label>Upload file *<input type="file" name="filename[1]" /></label>
<label>Upload file *<input type="file" name="filename[2]" /></label>
</div>
</div>
<div class="col-md-3 d-grid">
<div class="form-group">
<button class="btn btn-danger remove_add_btn" data-id='remove'>Remove</button>
</div>
</div>
</div>`;
const _radio = document.querySelectorAll('[type="radio"][data-id]');
const _bttn = document.querySelector('[type="button"][data-id="add"]');
const _div = document.querySelector('#divDynamicTexts');
const _input = document.querySelector('input[type="number"][data-id="textInput"]');
let choice = false;
let qty = false;
/*
Disable radio buttons and the "Create" button initially
and enable when changes are made in the correct sequence.
1: select quantity -> enable radio bttns
2: select single or double -> enable "create" bttn
3: click bttn, create as per radio selection
*/
_input.addEventListener('change', e => {
_radio.forEach(n => {
n.disabled = e.target.value > 0 ? false : true;
});
qty=e.target.value;
});
document.addEventListener('click', e => {
if (e.target instanceof HTMLInputElement && e.target.dataset.id != null) {
/*
set global "choice" variable
and enable "Create" bttn.
*/
if (e.target.type == 'radio') {
choice = e.target.dataset.id;
_bttn.disabled = false;
}
}
/*
If the "choice" has been made the radio
buttons will be enabled. Based on radio
button selected create new HTML and then
unhide the appropriate single/pair DIV
element
*/
if (choice && qty > 0 && e.target.type == 'button') {
_div.innerHTML = '';
for (let i = 0; i < qty; i++) _div.insertAdjacentHTML('afterbegin', strhtml);
let expr = `div[data-id="${choice}"]`;
document.querySelectorAll(expr).forEach(n => n.style.display = 'block');
}
/*
unchanged: delete DIV & contents when "Remove" bttn is clicked.
*/
if (e.target instanceof HTMLButtonElement && e.target.dataset.id != null) {
if (e.target.dataset.id == 'remove') {
_div.removeChild(e.target.closest('[data-id="dynrow"]'));
}
}
});
body {
font-family: arial;
}
label {
display: block;
}
.px-2 {
display: inline-block;
}
.px-2 label {
display: inline-block;
margin: 0.5rem;
}
h2 {
font-size: 1.1rem;
margin: 1rem 0 0 0;
display: inline-block;
width: auto;
}
.inline {
display: inline;
margin: 0 1rem 0 0;
}
#divDynamicTexts {
min-height: 1rem;
margin: 2rem auto
}
div.row {
padding: 0.5rem;
border: 1px dotted grey;
margin: 0.5rem;
}
div[data-id='single'] .form-group label {
background: aliceblue
}
div[data-id='pair'] .form-group label {
background: lightsteelblue
}
div[data-id] .form-group label {
outline: 1px solid grey;
padding: 0.5rem;
margin: 0.5rem 0
}
.bold {
font-weight: bold
}
[disabled]{
border:1px solid red;
outline:2px solid red;
background:rgba(255,0,0,0.25);
}
<div class='text-center'>
<label class='inline bold'>Quantity:<input type='number' data-id='textInput' /></label>
<div class='col-md-4'>
<div class='form-group'>
<h2>Library Type</h2>
<div class='px-2'>
<label>Single end: <input type='radio' data-id='single' name='check' disabled /></label>
<label>Paired end: <input type='radio' data-id='pair' name='check' disabled /></label>
</div>
</div>
</div>
<input type='button' data-id='add' value='Create upload fields' disabled />
</div>
<div id='divDynamicTexts'></div>

How to reset an input type=number element when the user clicks it using JavaScript

I'm experimenting with the <input type="number" ...> list option to create a numeric input field that displays a set of predefined 'favorite' values, but still allow other values to be typed in by the user.
Here is what I have, so far:
<label>
Zoom(%)
<input type="number"
min="50" step="50" value="100"
list="favorites"
title="Please enter or choose a zoom value." />
<datalist id="favorites">
<option value="100" />
<option value="150" />
<option value="200" />
<option value="250" />
<option value="300" />
</datalist>
</label>
Problems:
There are two problems:
After the first time selecting/entering a value and exiting the field, the next time the field had the focus, the drop-down list only shows some of options that sort of match the current input value, and
The input element must be cleared and clicked twice in order to display the full list of options.
Goal:
How do I get the full list of options to show everytime the drop-down list shows?
I tried adding an inline onclick="this.value = '';" code segment to the input element in order to reset the input element each time the user clicks the input element, but while sometimes this seems to work, it doesn't always work, even in the same browser, so this isn't a cross-browser issue.
Is there a way to reset an input element, like a form reset does, without actually using an enclosing form element?
My issue about using a form is that when I'm using a form element to enclose the input field and reset the parent form, I can't nest forms to isolate just the one input element and resetting the parent form resets all of the input elements, which I don't want.
Here is a CodePen examples showing my test case and others.
The last example in the CodePen example shows an alternate to the input type number, but without the list attribute. This separates the list feature from the input element so that the drop-down-list doesn't show until the user presses the down-triangle list button, next to the input element. When before the list actually displays, the options in the list are filters with anything that the user may have typed into the input field and supports partial matches. The initial/default value of the input field is not used as a filter, so that the whole list is displayed until something is typed into the field or after the clear button is clicked.
Here is an example that combines a number input and a down-list to achieve a better solution than using the number input with its data list option.
div {
display: inline-block;
vertical-align: top;
padding-right: 10px;
}
span.h {
font-weight: 900;
font-size: x-large;
}
button.blacktriangledown {
position: relative;
top: -1px;
margin-left: -5px;
padding: 0;
height: 21px;
width: 20px;
outline: none;
}
button.blacktriangledown > div {
position: relative;
top: -7px;
left: -3px;
font-size: 26px;
}
button.times {
outline: none;
padding: 0;
height: 20px;
width: 20px;
}
button.times > div {
position: relative;
top: -8px;
font-size: 26px;
}
datalist {
display: none;
position: absolute;
top: 20px;
left: 0px;
border: thin solid black;
background-color: white;
cursor: pointer;
}
datalist > option:hover {
border: thin solid black;
background-color: lightskyblue;
}
<div>
<p>
<span class="h">Input-7</span><br />
<b><u>with</u> an inline reset inline code segment and list and clear buttons</b>
</p>
<label>
Zoom(%)
<div style="position: relative;">
<input type="number" id="input7" min="50" step="50" filter="" value="100"
datalist="favorites7"
title="Please enter or choose a zoom value."
oninput="this.setAttribute( 'filter', this.value );" />
<button class="blacktriangledown" onclick="listButton( this );">
<div>&blacktriangledown;</div>
</button>
<button class="times" onclick="clearButton( this );">
<div>×</div>
</button>
<script>
function listButton( This ) {
var input = This.parentElement.querySelector( 'input' );
var filter = input.getAttribute( 'filter' );
var value = input.value;
var list = This.parentElement.querySelector( 'datalist' );
var options = list.options;
var option;
for( var i = 0, l = options.length; i < l; ++i ) {
option = options[ i ];
option.style.backgroundColor = ( ( option.value === value )
? 'lightblue'
: 'inherit' );
if( filter !== '' )
option.hidden = ( option.value.indexOf( filter ) === -1 );
}
list.style.display = ( ( list.style.display === 'inline' )
? 'none'
: 'inline' );
}
function clearButton( This ) {
var input = This.parentElement.querySelector( 'input' );
var list = This.parentElement.querySelector( 'datalist' );
var options = list.options;
list.style.display = 'none';
for( var i = 0, l = options.length; i < l; ++i )
options[ i ].hidden = false;
input.setAttribute( 'filter', '' );
input.value = input.defaultValue;
input.focus();
}
</script>
<datalist id="favorites7">
<option value="50">50% (half-size)</option>
<option value="100">100% (full-size)</option>
<option value="150">150%</option>
<option value="200">200%</option>
<option value="250">250%</option>
<option value="300">300%</option>
</datalist>
<script>
( function() {
var lists = document.querySelectorAll( 'datalist' );
var list = lists[ lists.length - 1 ];
var options = list.options;
list.value =
list.selectedOption = null;
list.selectedIndex = -1;
list.length = list.length;
for( var i = 0, l = options.length; i < l; ++i ) {
options[ i ].index = i;
options[ i ]
.addEventListener( 'click',
function() {
var list = this.parentElement;
list.style.display = 'none';
list.value = this.value;
list.selectedOption = this;
list.selectedIndex = this.index;
list.parentElement
.querySelector( 'input' )
.value = this.value ;
} );
}
} )();
</script>
</div>
</label><br />
<span id="span7"></span>
</div>

Is it possible to take more than one input from a textbox in a php form?

I am trying to make a calculator program in php code.
I made it using html and javascript, but I've been told to use php code for the logical part.
Is there any way we can take more than one input from a textbox, in a php form ?
Yes, you can easily use multiple inputs in a form, by giving them different names and accessing them through $_REQUEST['input_name'].
In this example, what I am doing is taking the selected checkboxes from the popup and putting them into the text input field in the main form as a comma-separated list.
HTML
<input type="text" id="entry-r1" placeholder="place" tabindex="1">
<a class="show-lookup button" href="#" id="popup-r1" tabindex="2"><i class="fa fa-search"></i></a>
<div class="overlay"> </div>
<div class="lookup-multiselect" id="lookup-r1">
<a class="button close-button right">x</a>
<form action="" id="form-r1" name="form-r1" method="post">
<input class="checkall" id="checkall" type="checkbox">
<label for="checkall" class="narrow">Select all</label>
<p class="category" id="checkboxes-r1"><strong>Select...</strong><br>
<input class="js-popup-focus" type="checkbox" name="place" id="antwerp" value="Antwerp" tabindex="3"> <label for="antwerp">Antwerp</label><br>
<input type="checkbox" name="place" id="berlin" value="Berlin" tabindex="3"> <label for="berlin">Berlin</label><br>
<input type="checkbox" name="place" id="cairo" value="Cairo" tabindex="3"> <label for="cairo">Cairo</label><br>
<input type="checkbox" name="place" id="duss" value="Düsseldorf" tabindex="3"> <label for="duss">Düsseldorf</label><br>
</p>
</form>
Use selected
</div>
CSS
.overlay {
display: none;
position: fixed;
text-align: center;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
opacity: 0.7;
background: #333;
}
.lookup-popup, .lookup-multiselect {
padding: 0.5em;
display: none;
z-index: 99999;
background-color: #fff;
position: absolute;
top: 5em;
left: 25%;
width: 20%;
}
jQuery
$(document).ready(function ()
{
/* get id of form to work with */
$('.show-lookup').click(function()
{
var pairedId = $(this).attr('id').split('-');
var lookupToDisplay = '#lookup-' + pairedId[1];
$('.overlay').show();
$(lookupToDisplay).show();
$('.js-popup-focus').focus();
});
/* put value selected in lookup into field in main form */
$('.lookup-popup input').on('change', function()
{
var fieldname = $(this).attr('name');
var pairedId = $(this).parent().attr('id').split('-');
var selOption = $('input[name='+fieldname+']:checked').val();
$("#entry-"+pairedId[1]).val(selOption);
});
/* for checkbox version, append selected values to field in main form */
$('.lookup-multiselect input').on('change', function()
{
var pairedId = $(this).parent().attr('id').split('-');
//event.preventDefault();
var selOptions = $(".category input:checkbox:checked").map(function(){
return $(this).val();
}).get(); // <----
//console.log(selOptions);
var selectedString = selOptions.toString();
$("#entry-"+pairedId[1]).val(selOptions);
});
$('.close-button').click(function()
{
$(this).parent().hide();
var pairedId = $(this).parent().attr('id').split('-');
$('.overlay').hide();
$("#entry-"+pairedId[1]).focus();
});
});

Multiple plus and minus buttons

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>

Dynamically Created Div is getting invisible

I am trying to create a div dynamically by clicking a button and add it to the parent name "option_selection". But the div get 'vanished' (I don't know what else could I say because saying 'invisible' may mean something else!).
Here is my JS code:
function addMoreOptions(div){
var counter_div = document.getElementById("hidden");
var counter = counter_div.value;
counter_div.setAttribute("id","not_hidden");
counter_div.setAttribute("name","not_hidden");
counter++;
var addString="";
addString = addString+"<div style="\"width:" 250px;="" float:="" left;="" \"="">";
addString = addString+"<p>Choose option type to display :</p></div>";
addString = addString+"<div style="\"float:" left;\"=""><select id="\"option_type\"" name="\"option_type_";" addstring="addString+counter;"><option value="\"1\"">Single Option (radio button)</option>";
addString = addString+"<option value="\"2\"">Multiple Option (check boxes)</option>";
addString = addString+"<option value="\"3\"">Text Entry (text input box)</option>";
addString = addString+"<option value="\"4\"">Menu(Drop Down)</option></select></div>";
addString = addString+"<div style="\"float:" none;="" clear:="" both;="" width:="" 0px;\"=""></div>";
addString = addString+"<div style="\"width:" 250px;="" float:="" left;="" \"="">";
addString = addString+"<p>Enter option text:</p></div><div style="\"float:" left;\"="">";
addString = addString+"<input type="\"text\"" id="\"option_text_1\"" name="\"option_text_";" addstring="addString+counter;"><input id="\"hidden\"" type="\"hidden\"" name="\"hidden\"" value="";
addString = addString+counter;
addString = addString+""></div><div style="\"float:" none;="" clear:="" both;="" width:="" 0px;\"=""></div>";
var element = document.createElement("div");
element.innerHTML= addString;
document.getElementById(div).appendChild(element);
alert(document.getElementById(div).innerHTML);
}
here is the HTML Code
<div id="option_selection">
<div>
<div style="width: 250px; float: left; "><p>Choose option type to display :</p></div>
<div style="float: left;">
<select id="option_type" name="option_type_1">
<option value="1">Single Option (radio button)</option>
<option value="2">Multiple Option (check boxes)</option>
<option value="3">Text Entry (text input box)</option>
<option value="4">Menu(Drop Down)</option>
</select>
</div>
<div style="float: none; clear: both; width: 0px;"></div>
<div style="width: 250px; float: left; "><p>Enter option text:</p></div>
<div style="float: left;">
<input type="text" id="option_text_1" name="option_text_1">
<input id="hidden" name="hidden" type="hidden" value="1">
</div>
<div style="float: none; clear: both; width: 0px;"></div>
</div>
</div>
<div align="right" style="width: 800px;">
<button id="add" onclick="addMoreOptions('option_selection')">Add More Option</button>
Any help would be highly appreciated.
Thanks in Advance.
Your button has no type-attribute. The default type of buttons is submit (also see here).
type
The type of the button. Possible values are:
- submit: The button submits the form data to the server. This is the default if the attribute is not specified, or if the attribute is dynamically changed to an empty or invalid value.
- reset: The button resets all the controls to their initial values.
- button: The button has no default behavior. It can have client-side scripts associated with the element's events, which are triggered when the events occur.
Add type="button" and on click the form won't be submitted.
<button type="button" id="add" onclick="addMoreOptions('option_selection')">Add More Option</button>
Use
document.getElementById(div).innerHTML = element;
Instead of
document.getElementById(div).appendChild(element);

Categories