I have two dropdown selections where when you click on the option with value "other", it generates a text area just below the dropdown form.
Both areas work fine but to do so I had to create separate parent wrappers for both and I don't want that because I will be dynamically adding more dropdowns and it will be hard to dynamically make more unique parent wrapper divs.
I want each dropdown to be different from each other with their own textboxes generated.
I have made the entire code available in this pen
Code for your reference
HTML
<section id="alterationForm1">
<div class="card">
<div class="imgCard">
<img src="http://abhisheksuresh.online/alter/assets/uploadImage.svg" alt="upload-image" height="128px" width="128px">
<span class="badge badge-success" style="z-index: 1; position: absolute;" data-toggle="tooltip" data-placement="left" title="Tap on the image to upload picture of your defected garment"><i class="fa fa-question-circle" aria-hidden="true"></i></span>
</div>
<!--Dropdown List-->
<div class="form-group">
<label for="exampleFormControlSelect1"><p class="dropDownLabel">Select alteration type</p></label>
<select class="form-control alterationTypeSelect" name="alterationTypeSelect">
<option value="button">Button</option>
<option value="stitching">Stitching</option>
<option value="cloth">Cloth</option>
<option value="fabrics">Fabrics</option>
<option value="otherClick">Other</option>
</select>
</div>
<div class="hideMe textBoxDiv">
<div class="form-group">
<label for="exampleFormControlTextarea1">Additional alteration details</label>
<textarea class="form-control" id="exampleFormControlTextarea1" rows="3"></textarea>
</div>
</div><!--text box div-->
<div class="submitButton text-center">
Submit
</div><!--submitButton-->
</div><!--card-->
</section><!--alteration form-->
<div data-duplicate="demo" class="demoClass">
<div class="card">
<div class="imgCard">
<img src="http://abhisheksuresh.online/alter/assets/uploadImage.svg" alt="upload-image" height="128px" width="128px">
<span class="badge badge-success" style="z-index: 1; position: absolute;" data-toggle="tooltip" data-placement="left" title="Tap on the image to upload picture of your defected garment"><i class="fa fa-question-circle" aria-hidden="true"></i></span>
</div>
<!--Dropdown List-->
<div class="form-group">
<label for="exampleFormControlSelect1"><p class="dropDownLabel">Select alteration type</p></label>
<select class="form-control alterationTypeSelect" name="alterationTypeSelect">
<option value="button">Button</option>
<option value="stitching">Stitching</option>
<option value="cloth">Cloth</option>
<option value="fabrics">Fabrics</option>
<option value="otherClick">Other</option>
</select>
</div>
<div class="hideMe textBoxDiv">
<div class="form-group">
<label for="exampleFormControlTextarea1">Additional alteration details</label>
<textarea class="form-control" id="exampleFormControlTextarea1" rows="3"></textarea>
</div>
</div><!--text box div-->
<div class="submitButton text-center">
Submit
</div><!--submitButton-->
</div><!--card-->
<div id="addOnButton" class="text-center">
<button class="btn-danger btn-sm" data-duplicate-add="demo">Add More</button>
</div>
</div><!--demo class-->
JS
//When clicked on option with "other" value
$('#alterationForm1 .alterationTypeSelect').on('change', function(){
var val = $(this).val();
if(val === 'otherClick') {
$('#alterationForm1 .textBoxDiv').removeClass('hideMe');
}
else{
$('#alterationForm1 .textBoxDiv').addClass('hideMe');
}
});
$('#alterationSection2 .alterationTypeSelect').on('change', function(){
var val = $(this).val();
if (val === 'otherClick') {
$('#alterationSection2 .textBoxDiv').removeClass('hideMe');
}
else{
$('#alterationSection2 .textBoxDiv').addClass('hideMe');
}
});
$('.demoClass .alterationTypeSelect').on('change',function(){
var val = $(this).val();
if (val === 'otherClick') {
$('.demoClass .textBoxDiv').removeClass('hideMe');
}
else{
$('.demoClass .textBoxDiv').addClass('hideMe');
}
});
//Dynamic Adding
$("#czContainer").czMore();
Thank you so much for the help. I am in a great need for this help. Please find the pen link to better understand the entire problem.
please follow the below pen as I have modified your code as we want elements to be dynamically triggered:
https://codepen.io/anon/pen/NYyvpy?editors=1011
//question mark tooltip
$('[data-toggle="tooltip"]').tooltip()
//When clicked on other button
$('body').on('change','.alterationTypeSelect', function(){
console.log(544);
var val = $(this).val();
if(val === 'otherClick') {
$(this).parent().parent().find('.textBoxDiv').removeClass('hideMe');
}
else{
$(this).parent().parent().find('.textBoxDiv').addClass('hideMe');
}
});
//Dynamic Adding
$("#czContainer").czMore();
Also, follow this link if you want to understand how newly added elements work with events
Event binding on dynamically created elements?
Related
I am very new to event delegation and I'm having trouble selecting the correct div to change. I have a partial view that can be displayed multiple times on a webpage. However, when it is displayed multiple times, the JavaScript only works for the first instance of the partial view. So I tried to use event delegation to solve my problem but it still only works on the first instance. I think it might be anytime I select by Id, since they share ids, it is selecting only the first id it sees and thus only working on the first instance of the partial view. Here is my Partial View's HTML:
<div id="AddMedia">
<form>
<div class="container">
<div class="form-row">
<div class="col-6 dropdown my-2 px-0">
<label class="control-label">Source:<span class="text-danger ml-1">*</span></label>
<select id="SourceFromSelect" asp-for="Medias.SourceFrom" asp-items="Html.GetEnumSelectList(typeof(SourceFromEnum))" style="width:85%;" class="btn border-dark" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<option class="dropdown-item" selected>Select</option>
</select>
<span asp-validation-for="Medias.SourceFrom" class="text-danger"></span>
</div>
</div>
<div class="form-row">
<div class="col-5">
<div id="MediaFile" class="form-group">
<label for="exampleFormControlFile1">Pick a File</label>
<input type="file" class="form-control-file" id="exampleFormControlFile1">
</div>
<div id="MediaLink" class="form-group">
<label for="url">Link the Media</label>
<input type="url" class="form-control" id="exampleFormControlFile1">
</div>
</div>
</div>
</div>
</form>
</div>
And here is the script for it:
document.getElementById("MediaFile").style.display = "none";
const addMedia = document.querySelector("#AddMedia")
addMedia.addEventListener('change', function (e) {
if (e.target.getAttribute('id') === 'SourceFromSelect') {
changeFile(e);
}
});
function changeFile(e) {
// $("#SourceFromSelect").change(function () {
console.log(e.target)
var e = document.getElementById("SourceFromSelect");
var strUser = e.options[e.selectedIndex].text;
if (strUser == "Phone or Computer") {
document.getElementById("MediaFile").style.display = "inline-block";
document.getElementById("MediaLink").style.display = "none";
}
else {
document.getElementById("MediaFile").style.display = "none";
document.getElementById("MediaLink").style.display = "inline-block";
}
// })
}
Finally here is where I call the Partial view:
<div id="MediaList">
#for (i = 0; i < MediaCount; ++i)
{
<partial name="_MediaPartial" />
}
</div>
As #AlwaysHelping said in comment, Id selector MUST be unique for element. since you can not change their id, you can use name or class selector.
I made a demo based on your codes which change the id to name in partial. Also, I use jquery, it is much easier.
Partial view:
<div name="AddMedia">
<form>
<div class="container">
<div class="form-row">
<div class="col-6 dropdown my-2 px-0">
<label class="control-label">Source:<span class="text-danger ml-1">*</span></label>
<select name="SourceFromSelect" style="width:85%;" class="btn border-dark">
<option selected>Select</option>
<option value="1">Phone or Computer</option>
<option value="2">Other Media</option>
</select>
</div>
</div>
<div class="form-row">
<div class="col-5">
<div name="MediaFile" class="form-group">
<label for="exampleFormControlFile1">Pick a File</label>
<input type="file" class="form-control-file" name="exampleFormControlFile1">
</div>
<div name="MediaLink" class="form-group">
<label for="url">Link the Media</label>
<input type="url" class="form-control" name="exampleFormControlFile1">
</div>
</div>
</div>
</div>
</form>
</div>
Scripts:
<script>
$("[name = MediaFile]").css("display", "none")
$("[name = SourceFromSelect]").on('change', function () {
var parent = $(this.parentElement.parentElement.nextElementSibling)
if ($(this).find(":selected").text() == "Phone or Computer") {
parent.find("[name = MediaFile]").css("display", "inline-block");
parent.find("[name = MediaLink]").css("display", "none");
}
else {
parent.find("[name = MediaFile]").css("display", "none");
parent.find("[name = MediaLink]").css("display", "inline-block");
}
});
</script>
Result:
I have multiple div with class rows and in each row there is a dropdown on change of dropdown i want to hide the anchor tag with class "add_marks" which is inside the same row.
I'm using the following code to hide it:
jQuery(document).on('change', '.subject', function(e) {
var nearest_row = $(this).closest('div.row');
var elem = $(nearest_row).closest(".add_marks");
elem.hide();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>
<div class="row clearfix attr_fields">
<div class="col-sm-3">
<div class="form-group">
<h2 class="card-inside-title">Class</h2>
<div class="form-line focused">
<input type="text" name="name" class="form-control" required="">
</div>
</div>
</div>
<div class="col-sm-3">
<div class="form-group">
<h2 class="card-inside-title">Subject</h2>
<select name="subject_name" class="form-control subject" required="" aria-invalid="false">
<option value="">Select</option>
<option value="1">Maths</option>
<option value="2">Science</option>
</select>
</div>
</div>
</div>
<div class="col-sm-1">
<div class="form-group">
<div class="col-xs-1 col-sm-7 col-md-1"><i class="material-icons">add</i>Add Marks</div>
</div>
</div>
You have to get the next div and find the a link, then hide it.
var nearest_row = $(this).closest('div.row');
gets you the div.row.clearfix.attr_fields but the link is present in the next div, so doing next gets you the next div element, then you find the 'a' element.
You can also do next('div') instead of getting the next element to find the next div.
jQuery(document).on('change', '.subject', function(e) {
var nearest_row = $(this).closest('div.row').next().find('.add_marks').hide();
//console.log(nearest_row);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>
<div class="row clearfix attr_fields">
<div class="col-sm-3">
<div class="form-group">
<h2 class="card-inside-title">Class</h2>
<div class="form-line focused">
<input type="text" name="name" class="form-control" required="">
</div>
</div>
</div>
<div class="col-sm-3">
<div class="form-group">
<h2 class="card-inside-title">Subject</h2>
<select name="subject_name" class="form-control subject" required="" aria-invalid="false">
<option value="">Select</option>
<option value="1">Maths</option>
<option value="2">Science</option>
</select>
</div>
</div>
</div>
<div class="col-sm-1">
<div class="form-group">
<div class="col-xs-1 col-sm-7 col-md-1"><i class="material-icons">add</i>Add Marks</div>
</div>
</div>
Here is Working code example run it with js (shortcut: ctrl + enter)
...want to hide the anchor tag with class "add_marks" which is inside the same row.
So I have moved that button inside row.
Using .col* as direct child of .row is proper way of using bootstrap grid.
Used the following jQuery considering your requirement.
jQuery(document).on('change', '.subject', function (e) {
$(this)
.parents('.row')
.find('.add_marks')
.hide();
});
$(".incrementer").click(function(){
var values = $("#layernumber").val();
var item = $("input[type=file]:last").clone(true);
var txt = $(".layer_selector:last").after('<br>').clone(true);
if($("#layernumber").val() < 4){
$("#attach").append(item);
$("#attach").append(txt);
}
if($("#layernumber").val() > 2){
$(".incrementer").hide();
}
});
The above code increments the value of layers
as the layers increments the file upload option will also.
But this works only in Chrome. Not in FireFox or Internet Explorer.
HTML code is:
<div class="tab-pane active" id="tab2">
<h3 class="block">Provide your layer details</h3>
<div class="form-group">
<label class="control-label col-md-3">Number of layer
<span class="required" aria-required="true"> * </span>
</label>
<div class="col-md-4">
<div class="input-group bootstrap-touchspin">
<span class="input-group-addon bootstrap-touchspin-prefix" style="display: none;"></span>
<input id="layernumber" type="text" class="form-control" name="layernumber" style="display: block;">
<span class="input-group-addon bootstrap-touchspin-postfix" style="display: none;"></span>
<span class="input-group-btn-vertical">
<button class="btn btn-default bootstrap-touchspin-up" type="button">
<i class="glyphicon glyphicon-plus incrementer"></i>
</button>
<button class="btn btn-default bootstrap-touchspin-down" type="button">
<i class="glyphicon glyphicon-minus decrementer"></i>
</button>
</span>
</div>
<span class="help-block"> Provide your number of layers </span>
</div>
</div>
<!-- fileupload starts-->
<!-- -->
<div class="form-group">
<label class="control-label col-md-3">Choose Layer
<span class="required" aria-required="true"> * </span>
</label>
<div class="col-md-9">
<div id="attach">
<div id="previewImg"></div>
<div class="col-md-9">
<input type="file" name="layerimages[]" onchange="preview(this);" class="myfile" id="fileid" multiple="">
<select id="layerid" class="layer_selector" name="layer_selector">
<option value="">Please Select</option>
<option value="0">First</option>
<option value="1">Second</option>
<option value="2">Intermediate</option>
<option value="3">Final</option>
</select>
</div>
</div>
<br>
</div>
</div>
<!-- fileupload ends-->
</div>
I have made a fiddle for this.
https://jsfiddle.net/w1gy8ruj/1/
The changes i did to your code is basically initialise the value of the layernumber input to 0 and increment it on every click.
$(document).ready(function() {
$(".incrementer").click(function() {
var values = $("#layernumber").val();
var item = $("input[type=file]:last").clone(true);
var txt = $(".layer_selector:last").after('<br>').clone(true);
if ($("#layernumber").val() < 4) {
$("#attach").append(item);
$("#attach").append(txt);
}
if ($("#layernumber").val() > 2) {
$(".incrementer-button").hide();
}
values++;
$("#layernumber").val(values);
});
});
You do not use
var values = $("#layernumber").val();
anywhere in this scope, so this is unneeded unless you don't want to use it in the if statement below and for incrementing.
And you do not increment the layernumber, so
if($("#layernumber").val() > 2) {
will never execute. You should increment it and set it like
$("#layernumber").val(values)
So im trying to build the front end of a form builder however i've run into a problem when trying to clone collapsible elements. Im an absolute beginner at jquery so sorry for the dirty code.
When an element is cloned and it is nested under itself with a modified sortable jquery plugin, any one of the bottom levels collapsible's will open the collapsible of the top level parent (but not any of the other nested elements).
My jquery is:
var count = 1;
$("#displayUpload").click(function() {
var clonecount = 'Uploadpanel' + count;
var cloneobject = $("#toggleUpload").clone(true).appendTo(".sortable").show();
$("#Uploadpanel", cloneobject).attr('id', clonecount);
$(cloneobject, this.id).on("click", (".edit", ".panel-title"), function() {
$("#" + clonecount, this.id).collapse('toggle');
});
$(cloneobject).on("click", ".remove", function() {
$(cloneobject).remove();
});
count = count + 1;
});
Html:
<li id="toggleUpload" data-role="main" class="js-form-element" style="display: none">
<div>
<div class="panel panel-default" data-role="collapsible" id="panel3">
<div class="panel-heading">
<h4 class="panel-title" data-target="#Uploadpanel"
href="#Uploadpanel">
<a data-target="#Uploadpanel"
href="#Uploadpanel" class="edit">
File upload
</a>
<span class="btn-group pull-right">
<a data-target="#Uploadpanel"
href="#Uploadpanel" class="collapsed">Edit</a>
<span class="padding-line">|</span>
<a class="remove" href="#">Delete</a>
</span>
</h4>
</div>
<div id="Uploadpanel" class="panel-collapse collapse">
<div class="panel-body">
<div class="margin-bottom-20">
<p class="font-italic">Label:</p>
<input type="text" class="form-control" id="exampleInputName2" placeholder="Label">
</div>
<div class="margin-bottom-20">
<p class="font-italic">Placeholder text:</p>
<input type="text" class="form-control" placeholder="Placeholder message">
</div>
<div class="margin-bottom-5">
<div class="checkbox">
<label>
<input id="required" type="checkbox"> Required
</label>
</div>
</div>
<div class="margin-bottom-20">
<p class="font-italic">Validation message:</p>
<input type="text" class="form-control" id="validation" placeholder="Validation message">
</div>
<div>
<div class="row">
<div class="col-sm-6">
<p class="font-italic">Form input size:</p>
<div class="form-group">
<select name="form_select">
<option value="0">100% (1 in a row)</option>
<option value="0">33% (3 in a row)</option>
<option value="0">50% (2 in a row)</option>
</select>
</div>
</div>
<div class="col-sm-6">
<p class="font-italic">Form position:</p>
<div class="form-group">
<select name="form_select">
<option value="0">Left</option>
<option value="0">Middle</option>
<option value="0">Right</option>
</select>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</li>
Any help would be great,
Thanks
There can be some issues using clone on objects that already has event handlers. I had this issue for a while, and I just resolved it by creating a function that generates a new jQuery object, instead of cloning an existing one.
After seeing my questions replied here and with success, the problems appeared when transposing to my script:
I have a dropdown that is being cloned which shows it's value on a side div. The problem is that when I clone it, the dropdown below don't work and the first updates all the remaining. Code:
Add
<div class="row">
<div class="products-row">
<div class="col-xs-12 nopadding">
<div class="col-xs-2">
<input type="text" id="number1" class="form-control" value="1" />
</div>
<!-- if i remove the div below and leave only the select, it works -->
<div class="col-xs-6" >
<select name="total-checkout" id="name" class="form-control product-name select" >
<option value="25" >A</option>
<option value="50" >B</option>
<option value="75" >C</option>
</select>
</div>
<div class="col-xs-2">
<div class="tags">25</div>
</div>
</div>
</div>
</div>
jQuery:
var count = 0;
$('#add-more').click(function(){
var id = $(".row:last").attr('id');
var appendDiv = $($(".products-row:last")[0].outerHTML);
appendDiv.attr('id', ++id).insertAfter(".products-row:last");
});
$('#name').change(function(event) {
$('.tags').html($('#name').val());
});
$(document).on('change', '.select', function() {
$(this).next(this).html($(this).val());
});
Working jsFiddle:
http://jsfiddle.net/QuadDamage/p843nc9j/
If I remove the <div class="col-xs-6"> from around the <select> the output will appear not formatted but correctly updating the div.
Thanks in advance.
It seems to me that you're targeting .col-xs-2 .tags if this is the case you need this code
$(this).parent().next().find('.tags').html($(this).val());