Targeting events in multiple similar groups of items - javascript

I need your help please.
I'm creating that component that regroups multiple selects and inputs from which I get the values to concatenate them in a string in a preview zone. This string is updated each time a change occurs in those inputs/selects.
It worked fine when I was working on one element, experimenting, styling it and stuff. Now I have to replicate it into possibly an infinite amount, so the script must work accordingly. The problem is that I'm useless when it comes to targeted selectorsn "this", "closest" and stuff. And I'm sure my logic is flawed when it comes to getting the values as you will see in the code I written.
I will share the JSFiddle, it will be easier to understand I think. If not, I will edit this post and share it directly.
Maybe I should declare a variable containing the targeting like [ var route = $(this).parent().closest() ] and use it all the other variables too ?
https://jsfiddle.net/HiD3f/8Lnowqvp/65/
<div class="container" id="settings-fr">
<div class="group">
<select class="day">
<option value="1">Monday</option>
<option value="2">Mon</option>
<option value="3"> </option>
</select>
</div>
<div class="group small-group">
<input type="text" class="separator1">
</div>
<div class="group">
<select class="date">
<option value="1">October 29</option>
<option value="2">Oct 29</option>
<option value="3">10 29</option>
<option value="1">29 October</option>
<option value="2">29 Oct</option>
<option value="3">29 10</option>
</select>
</div>
<div class="group small-group">
<input type="text" class="separator2">
</div>
<div class="group">
<select class="year">
<option value="1">2018</option>
<option value="2">18</option>
<option value="3"> </option>
</select>
</div>
<div class="preview"> preview </div>
</div>
<div class="container" id="settings-us">
<div class="group">
<select class="day">
<option value="1">Monday</option>
<option value="2">Mon</option>
<option value="3"> </option>
</select>
</div>
<div class="group small-group">
<input type="text" class="separator1">
</div>
<div class="group">
<select class="date">
<option value="1">October 29</option>
<option value="2">Oct 29</option>
<option value="3">10 29</option>
<option value="1">29 October</option>
<option value="2">29 Oct</option>
<option value="3">29 10</option>
</select>
</div>
<div class="group small-group">
<input type="text" class="separator2">
</div>
<div class="group">
<select class="year">
<option value="1">2018</option>
<option value="2">18</option>
<option value="3"> </option>
</select>
</div>
<div class="preview"> preview </div>
</div>
and the script :
$('select, input').change(function() {
let day = $(".day option:selected").text();
let sep1 = $(".separator1").val();
let date = $(".date option:selected").text();
let sep2 = $(".separator2").val();
let year = $(".year option:selected").text();
let preview = day + sep1 + date + sep2 + year;
let parent = $(".container");
$(this).parent('.group').closest(".preview").empty().append(preview);
});
Please help me, I'm stuck. Thank you.

Change your logic to find children based off of the section they are in.
$('select, input').change(function() {
//find the container the changed element belongs to
let $container = $(this).closest('.container');
let day = $container.find('.day option:selected').text();
let sept = $container.find('.separator1').val();
//...
});

Change your line
$(this).parent('.group').closest(".preview").empty().append(preview);
to
$(this).parents()
.filter(function() {
return (this.getAttribute('class') === 'container');
}).find('.preview').text(preview);

Related

Getting a value from a dropdown data attribute and passing it to a input field

I'm trying to pass values that i have stored in a multiple dropdown list to relevant input fields on select. I have gotten it to work to a certain extent but i can't get it to work when the input field and the select drop down is not under the parent div.
Current working code
$(document).ready(function() {
$('.select2').select2();
});
$(document).ready(function() {
$('select.material-price').change(function() {
var materialValue = $(this).select2().find(":selected").data("price");
$(this).parent('.row').find('.material-total').val(materialValue);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="row">
<select class="material-price select2">
<option value="100" value="10">Material A</option>
<option data-price="400" value="20>">Material B</option>
<option data-price="500" value="30">Material C</option>
</select>
<input type="text" class="material-total" readonly />
</div>
</div>
Code i'm trying to fix
<div class="row">
<div class='col-md-2 nopadding'>
<div class='form-group nomarg'>
<select class="material-pricex select2">
<option data-price="100" value="10">Material A</option>
<option data-price="400" value="20>">Material B</option>
<option data-price="500" value="30">Material C</option>
</select>
</div>
</div>
<div class='col-md-1 nopadding'>
<div class='form-group nomarg'>
<input type='number' id="total" name="total" min='0' class='form-control'>
</div>
</div>
</div>
How can I get data-price value selected on material-pricex to pass it to the "total" input field?
Problem with your implantation was usage of .parent() which only tragets the direct parent element of the selected element, thus your code didn't worked.
You can use .closest()/.parents() to traverse up-to common ancestor then use .find() to target the desired element.
$(this).closest('.row').find('.material-total').val(materialValue);

Having some issue with show and hide. How to solve this?

My Form:
<form name="test" action="" method="post">
Day And Time Available:<br/>
<input type="checkbox" name="day[]" id="day1" value="monday" onclick="show();"/>Monday<br/>
<input type="checkbox" name="day[]" id="day2" value="Tuesday" onclick="show();"/>Tuesday<br/>
<input type="checkbox" name="day[]" id="day3" value="Wednesday" onclick="show();"/>Wednesday<br/>
<input type="checkbox" name="day[]" id="day4" value="Thursday" onclick="show();"/>Thursday<br/>
</form>
<p style="visibility:hidden" id="timing">Here I am maintain the form</p>
<input type="submit" name="submit" onclick="return valid();"/>
</form>
If user have have selected Monday, tuesday I want output like this:
Monday
From Time
<select name="Fromtime" id="Fromtime">
<option value="6Am">6Am</option>
<option value="7Am">7Am</option>
<option value="8Am">8Am</option>
</select>
To Time
<select name="Totime" id="Totime">
<option value="6Am">6Am</option>
<option value="7Am">7Am</option>
<option value="8Am">8Am</option>
</select>
Tuesday:
From Time
<select name="Fromtime" id="Fromtime">
<option value="6Am">6Am</option>
<option value="7Am">7Am</option>
<option value="8Am">8Am</option>
</select>
To Time
<select name="Totime" id="Totime">
<option value="6Am">6Am</option>
<option value="7Am">7Am</option>
<option value="8Am">8Am</option>
</select>
How do I solve this in jQuery. Based on user Selection I want to show the day and timing form.
Likewise if the user selects Monday, Tuesday and Wednesday how do I show the day and timing form
My JavaScript:
<script type="text/javascript">
function show()
{
var flag = 0;
for (var i = 1; i< 7; i++)
{
if(document.getElementById("day"+i).checked)
{
document.getElementById('Fromtime').style.visibility='visible';
document.getElementById('Totime').style.visibility='visible';
}
}
return true;
}
</script>
As #Jai mentions, there are a couple of issues with your HTML. First, you cannot have multiple elements with the same ID, e.g: your 'Fromtime' and 'Totime' select boxes.
All the data you wish to submit needs to be wrapped in <form> tags. It looks like you've got one too many closing tags here which will cause problems.
That being said, you can achieve the show/hide effect with something like the following (I've stayed away from jQuery for something this simple):
function show(element) {
var day = element.value; // gets the value of checkbox, e.g: 'monday'
var timeElement = document.querySelector('.times-' + day); // finds correct times- element for day
if (element.checked) {
timeElement.style.display = 'block';
} else {
timeElement.style.display = 'none';
}
}
.hidden {
display: none;
}
input[type=submit] {
margin-top: 10px;
}
<form name="test" action="" method="post">
<fieldset>
<legend>Day And Time Available:</legend>
<input type="checkbox" class="day" value="monday" onclick="show(this);"/>Monday<br/>
<input type="checkbox" class="day" value="tuesday" onclick="show(this);"/>Tuesday<br/>
</fieldset>
<div class="times-monday hidden">
<p>Monday</p>
<label for="FromtimeMonday">From Time</label>
<select name="FromtimeMonday" id="FromtimeMonday">
<option value="6Am">6Am</option>
<option value="7Am">7Am</option>
<option value="8Am">8Am</option>
</select>
<label for="TotimeMonday">To Time</label>
<select name="TotimeMonday" id="TotimeMonday">
<option value="6Am">6Am</option>
<option value="7Am">7Am</option>
<option value="8Am">8Am</option>
</select>
</div>
<div class="times-tuesday hidden">
<p>Tuesday</p>
<label for="FromtimeTueday">From Time</label>
<select name="FromtimeTueday" id="FromtimeTueday">
<option value="6Am">6Am</option>
<option value="7Am">7Am</option>
<option value="8Am">8Am</option>
</select>
<label for="TotimeTueday">To Time</label>
<select name="TotimeTueday" id="TotimeTueday">
<option value="6Am">6Am</option>
<option value="7Am">7Am</option>
<option value="8Am">8Am</option>
</select>
</div>
<input type="submit" name="submit" text="submit" />
</form>

Trying to put list data into another list

In the program below I am using fee head id and trying to access dynamic data but when I select or click on any element of the first list it does not go to the next list.
After clicking on any element in first list, the element should disappear from first list and display in the second list. I am using a theme which has built-in classes in JS and JSP.
<div class="panel-body">
<div class="form-group">
<div class="col-lg-12">
<div class="leftBox">
<select id="feesHeads" multiple="multiple" class="multiple nostyle form-control" style="height:300px;">
<!-- <option value="1">Spain</option>
<option value="2">Germany</option>
<option value="3">Uruguay</option>
<option value="4" selected="selected">Brazil</option>
<option value="5" selected="selected">England</option>
<option value="6" selected="selected">Portugal</option>
<option value="7">Argentina</option>
<option value="8">Italy</option>
<option value="9">Croatia</option>
<option value="10">Denmark</option>
<option value="11">Russia</option>
<option value="12">Greece</option>
<option value="13">Chile</option>
<option value="14">Côte d'Ivoire</option>
<option value="15" selected="selected">France</option>
<option value="16">Sweden</option>
<option value="17">Switzerland</option>
<option value="18">Republic of Ireland</option>
<option value="19">Australia</option>
</select> -->
<br/>
<span id="box1Counter" class="count"></span>
<div class="dn"><select id="box1Storage" name="box1Storage" class="nostyle"></select></div>
</div>
<div class="dualBtn">
<button id="to2" type="button" class="btn" ><span class="icon12 minia-icon-arrow-right-3"></span></button>
<button id="allTo2" type="button" class="btn" ><span class="icon12 iconic-icon-last"></span></button>
<button id="to1" type="button" class="btn marginT5"><span class="icon12 minia-icon-arrow-left-3"></span></button>
<button id="allTo1" type="button"class="btn marginT5" ><span class="icon12 iconic-icon-first"></span></button>
</div>
<div class="rightBox">
<select id="box2View" multiple="multiple" class="multiple nostyle form-control" style="height:300px;"></select>
<br/>
<span id="box2Counter" class="count"></span>
<div class="dn"><select id="box2Storage" class="nostyle"></select></div>
</div>
</div>
</div><!-- End .form-group -->
</div>
</div><!-- End .panel -->
</div><!-- End .span6 -->
</div><!-- End .row -->
When you click on the firstList's option remove it from there and append it to the secondList. I've created a simple demo that might go with your scenario.
HTML :
First :
<select id="firstList">
<option>Mango</option>
<option>Banana</option>
<option>Apple</option>
</select>
<br />
Second
<select id="secondList"></select>
jQuery :
$("#firstList").on("change", function(){
var selectedItem = $(this).children("option:selected").val();
$(this).children("option:selected").remove();
$("#secondList").append($("<option> </option>").text(selectedItem));
});
jsFiddle
Note : It's just an overview of how you can implement it. But what you want is entirely upto you.

How to put option value into another input

When the user selects an option from the list, i want to put the option values into the space - however again every time i try, it goes wrong. Can anyone help or point me in the right direct with this please - thanks.
This is the form code.
<form>
<div class="form-group">
<div class="col-xs-6">
<div class="input-group">
<span class="input-group-addon"><i class="gi gi-user"></i></span>
<select class="form-control input-md" id="subscription" name="subscription">
<option value="1">Choose Plan</option>
<option value="Solo">Solo - 1</option>
<option value="Double">Double - 2</option>
<option value="Triple">Triple - 3</option>
</select>
</div>
</div>
<div class="col-xs-3">
<input id="plan" type="text" name="plan" class="form-control input-md" value="">
</div>
</div>
</form>
Assuming you're using JQuery, try this code:
// JQuery
$("#subscription").on('change', function(){
$('#plan').val($(this).val());
});
// Vanilla JS
var subscription = document.getElementById('subscription');
var plan = document.getElementById('plan');
subscription.onclick = function(){
plan.value = this.value;
}

Better way to change id's of controls using jquery

I have the following form that renders from a django model_formset. It starts with one form and some static controls (like date etc).The form set fields are inside the 'form-wrapper' div
<form action="/customer/images/1/upload_xray" method="post" id="xrayform" enctype="multipart/form-data">
<input id="id_form-TOTAL_FORMS" name="form-TOTAL_FORMS" type="hidden" value="1"><input id="id_form-INITIAL_FORMS" name="form-INITIAL_FORMS" type="hidden" value="0"><input id="id_form-MAX_NUM_FORMS" name="form-MAX_NUM_FORMS" type="hidden" value="1000">
<input type="hidden" name="csrfmiddlewaretoken" value="LI1L39J1C7P4tQeqfJhL5CBuW283FmOI">
<div class="form-group">
<label for="date">Date</label>
<input id="date" type="text" name="date" class="form-control input-sm datepicker input-append date" readonly="">
</div>
<div class="form-group">
<label for="id_title">Title</label>
<select class="form-control input-sm" id="id_title" name="title">
<option value="" selected="selected">---------</option>
<option value="Observation">Observation</option>
<option value="Initial">Initial</option>
<option value="Progress">Progress</option>
<option value="Final">Final</option>
<option value="Post Treatment">Post Treatment</option>
</select>
</div>
<hr class="divider">
<div class="form-wrapper">
<div class="form-group">
<label for="id_form-0-image">Image</label>
<input id="id_form-0-image" name="form-0-image" type="file">
</div>
<div class="form-group">
<label for="id_form-0-type">Type</label>
<select class="form-control input-sm" id="id_form-0-type" name="type">
<option value="" selected="selected">---------</option>
<option value="xray">X-ray Image</option>
<option value="internal">Intraoral Image</option>
<option value="external">Extra-oral Image</option>
<option value="model">Model</option>
</select>
</div>
<div class="form-group">
<label for="id_form-0-desc">Desc</label>
<select class="form-control input-sm" id="id_form-0-desc" name="form-0-desc">
<option value="" selected="selected">---------</option>
<optgroup label="Xray" />
<option value="PA Ceph">PA Ceph</option>
<option value="Lateral Ceph">Lateral Ceph</option>
<option value="Panoramic">Panoramic</option>
<optgroup label="Interior oral">
<option value="Anterior Occlution">Anterior Occlution</option>
<option value="Anterior Occlusion Relaxed">Anterior Occlusion Relaxed</option>
<option value="Overjet Right">Overjet Right</option>
<option value="Overjet Left">Overjet Left</option>
<option value="Right Occlusion">Right Occlusion</option>
<option value="Left Occlusion">Left Occlusion</option>
<option value="Upper Occlusal">Upper Occlusal</option>
<option value="Lower Occlusal">Lower Occlusal</option>
<optgroup label="External oral" />
<option value="Frontal">Frontal</option>
<option value="Lateral Right">Lateral Right</option>
<option value="Lateral Left">Lateral Left</option>
<option value="Oblique smile Right">Oblique smile Right</option>
<option value="Oblique smile Left">Oblique smile Left</option>
<option value="Frontal smile">Frontal smile</option>
<option value="Oblique Right">Oblique Right</option>
<option value="Oblique Left">Oblique Left</option>
<optgroup label="Model"/>
<option value="Model Upper Occlusal">Model Upper Occlusal</option>
<option value="Model Lower Occlusal">Model Lower Occlusal</option>
<option value="Model Right Buccal">Model Right Buccal</option>
<option value="Model Left Buccal">Model Left Buccal</option>
<option value="Model Anterior Dental">Model Anterior Dental</option>
</select>
</div>
</div>
</form>
<div class="row">
<button class="btn btn-sm btn-success pull-right" id="add-form">+</button>
</div>
The add button adds a new form-wrapper element and increments by one the proper input fields so the model_formset of django to function correctly. Each new form-wrapper element consists of a delete button to delete it. On deletion javascript corrects the id's and values again for the formset to function correctly. I have made it work, but uses to much .each methods. Do u think is a better way to do that?
javascript
$(document).on('click','.delete', function (e){
e.preventDefault();
var forms;
var index = parseInt($(this).prop('id')) - 1;
var formWrapper = $(".form-wrapper")[index];
formWrapper.remove();
forms = $(".form-wrapper");
$("#id_form-TOTAL_FORMS").val(parseInt($("#id_form-TOTAL_FORMS").val()) - 1);
forms = $('.form-wrapper');
forms.each(function (index, item){
var form_groups = $(item).children('.form-group');
form_groups.each(function (index2, item2){
controls = $(item2).children();
controls.each(function(index3, item3){
var id = $(item3).prop('id');
parts = id.split('-');
parts[1] = String(index);
id = parts.join('-');
});
});
});
$('button.delete').each(function(index, item){
var id = parseInt($(item).prop('id'));
id = index + 2; //First start button starts with id=2 as in "delete 2nd form"
console.log('id after '+id);
$(item).prop('id', id);
});
});
Basicaly take the formwrappers to know how many forms are there, take each children (form-group) and then each children(control elements) and change their id's. Not having any trouble in speed yet, it works great, but don't like it's cleanness.
You can use .attr() like
$('button.delete').attr('id', function (index, item) {
return index + 2;
});
Demo: Fiddle

Categories

Resources