Hello I want to remove the cloned html when I click this, what is the best way? how to detect that it's what I've clicked on X
and this is the HTML
<div class="col-md-12">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">Fields</h4>
</div>
<div class="panel-body">
<div class="field">
<div class="col-md-6">
<div class="panel panel-default">
<div class="panel-heading clearfix">
<a id="close" class="pull-right" href="#">
<i class="fa fa-times"></i>
</a>
</div>
<div class="panel-body">
<select class="form-control" name="custom_form[type]" required>
<option value="">Type</option>
<option>text</option>
<option>textarea</option>
<option>radio</option>
<option>checkbox</option>
</select>
<input class="form-control" type="text" name="customform[label]" placeholder="Label" />
</div>
</div>
</div>
</div>
+ Add attribute
</div>
</div>
</div>
and this is what I've used to clone the fields when I click the button + Add Attribute
<div class="clone-field hide">
<div class="col-md-6">
<div class="panel panel-default">
<div class="panel-heading clearfix">
<a id="close" class="pull-right" href="#">
<i class="fa fa-times"></i>
</a>
</div>
<div class="panel-body">
<select class="form-control" name="custom_form[type]" required>
<option value="">Type</option>
<option>text</option>
<option>textarea</option>
<option>radio</option>
<option>checkbox</option>
</select>
<input class="form-control" type="text" name="customform[question]" placeholder="Question" />
</div>
</div>
</div>
</div>
<script type="text/javascript">
$(".container").on("click", "#add_attribute", function(e){
e.stopPropagation();
e.preventDefault();
alert("ok");
var append_att = $(".clone-field").html();
$(".field").append(append_att);
});
</script>
EDIT1
the close is already done, so I added one more since it's still same concept,
How to add <input type="text" name="customform[option]" placeholder="Ex. Male,Female" /> when I select Type = radio,select,checkbox and remove if it's not, then put it under on the Label input?
currently I have
$(".container").on("click", "#add_attribute", function(e){
e.stopPropagation();
e.preventDefault();
var append_att = $(".clone-field").html();
$(".fields").append(append_att);
}).on('click', '.remove', function() {
$(this).closest('.field').remove();
}).on('change', '.field-type', function(){
var input_option = '<input class="form-control" type="text" name="customform[option]" placeholder="Ex. Male,Female" /> ';
var valueSelected = this.value;
if(valueSelected == 'radio' || valueSelected == 'select')
//append
else
//remove
});
EDIT2
I've added this hidden input text
how to find closest into removeClass('hide')/addClass('hide') of my base on Type = radio,select
EDIT3 - MY TOTAL ANSWER
$(".container").on("click", "#add_attribute", function(e){
e.stopPropagation();
e.preventDefault();
var append_att = $(".clone-field").html();
$(".fields").append(append_att);
}).on('click', '.remove', function() {
$(this).closest('.field').remove();
}).on('change', '.field-type', function(){
var inputType = this.value;
var panel = $(this).closest('.panel-body');
var inputs = panel.find('input');
inputs.last().val("");
if(inputType=='radio' || inputType=='select') {
inputs.last().removeClass('hide');
} else {
inputs.last().addClass('hide');
}
});
Your are using duplicate id=close. Use class=close instead like following.
<a class="close" class="pull-right" href="#">
<i class="fa fa-times"></i>
</a>
And your js for removing item should be like this.
$('.container').on('click', '.close', function(){
$(this).closest('.col-md-6').remove();
});
Update
$('.container').on('click', 'select.form-control', function () {
var input_type = this.value;
var panel = $(this).closest('.panel-body');
var inputs = panel.find('input');
if (input_type == 'radio' || input_type == 'select') {
if (inputs.length > 1) {
inputs.last().removeClass('hide');
}
else {
var input_option = '<input class="form-control" type="text" name="customform[option]" placeholder="Ex. Male,Female" /> ';
panel.append(input_option);
}
} else {
if (inputs.length > 1)
inputs.last().addClass('hide');
}
});
Two simple steps:
change #close to class .close. You should not duplicate ids.
add some class to col-md-6 container to be able to select it later. You could use col-md-6 too but you don't want to tie JS code to layout specific classes
HTML becomes:
<div class="clone-field hide">
<div class="block col-md-6">
<div class="panel panel-default">
<div class="panel-heading clearfix">
<a class="close" class="pull-right" href="#">
<i class="fa fa-times"></i>
</a>
</div>
<div class="panel-body">
<select class="form-control" name="custom_form[type]" required>
<option value="">Type</option>
<option>text</option>
<option>textarea</option>
<option>radio</option>
<option>checkbox</option>
</select>
<input class="form-control" type="text" name="customform[question]" placeholder="Question" />
</div>
</div>
</div>
</div>
Then you also need to add once more click handler similar to what you already have:
$(".container").on("click", "#add_attribute", function(e){
e.stopPropagation();
e.preventDefault();
alert("ok");
var append_att = $(".clone-field").html();
$(".field").append(append_att);
})
.on('click', 'close', function() {
$(this).closest('.block').remove();
});
You should use jQuery.closest() https://api.jquery.com/closest/ to travel from the button you clicked back to the parent container that holds all the panel
$('#close').on('click', function(){
$(this).closest('.clone-field').remove();
});
.clone-field is the top most DIV of the panel to delete
Edit:
Also, Difference between id and class in CSS and when to use it
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:
On click event, I'm cloning the section which is working fine. I'm having while duplicating the section i want to change the name attribute like increase by 1 every time when add the new section.
This is my code
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<div class="name-field row" id="taskForm">
<div class="form--group">
<div class="col-xs-12 col-sm-6 childname">
<div class="field text-left">
<label class="text-left">First Name</label> <input class="“first" name="first" placeholder="“Firstname”" type="text">
</div>
</div>
<div style="height:0;"><a class="delete removeButton" href="javascript:;"><i class="fa fa-times"></i></a></div>
<div class="col-xs-12 col-sm-6 dateofbirth">
<div class="field text-left">
<label class="text-left">Date of birth</label> <input class="date" name="date" type="text">
</div>
</div>
</div>
<div class="form--group hide" id="taskTemplate">
<div class="col-xs-12 col-sm-6 childname">
<div class="field text-left">
<label class="text-left">First Name</label> <input class="firstname character" name="first" type="text">
</div>
</div>
<div style="height:0;"><a class="delete removeButton" href="javascript:;"><i class="fa fa-times"></i></a></div>
<div class="col-xs-12 col-sm-6 dateofbirth">
<div class="field text-left">
<label class="text-left">Date of birth</label> <input class="date" name="date" type="text">
</div>
</div>
</div>
<div class="col-lg-12 col-sm-12 col-xs-12">
<a class="btn-success addButton" href="javascript:;" id="addChild" name="addchild">Add Child</a>
</div>
</div>
.hide { display: none }
.field { margin-left: 20px }
$(document).ready(function() {
$('#taskForm')
// Add button click handler
.on('click', '.addButton', function() {
var $template = $('#taskTemplate'),
$clone = $template
.clone(true,true)
.removeClass('hide')
.removeAttr('id')
.insertBefore($template)
.attr("name", "first[" + i + "]")
$(".removeButton").toggle($(".removeButton").length > 2);
})
// Remove button click handler
.on('click', '.removeButton', function() {
var $row = $(this).closest('.form--group');
$row.remove();
$(".removeButton").toggle($(".removeButton").length > 2);
});
$(".removeButton").toggle($(".removeButton").length > 2);
});
.attr("name", "first[" + i + "]")
I'm using this line of code to increase name attribute like name="first", name="first1" and so on when add the new section. But it's not working.
Can anyone help me with this.
Thanks in advance.
i is not defined. Make a count variable that holds the number.
$(document).ready(function() {
var count = 0;
$('#taskForm')
//Add button click handler
.on('click', '.addButton', function() {
var $template = $('#taskTemplate'),
$clone = $template
.clone(true, true)
.removeClass('hide')
.removeAttr('id')
.insertBefore($template)
.attr("name", "first" + count++)
$(".removeButton").toggle($(".removeButton").length > 2);
})
});
I am trying to create a dynamic form that adds another field when choosing Verification select, the problem is that when I add fields of options in Verification at the time of adding another form, the options that I previously added appear, as I do to add a new form and don't show added options? I appreciate your help thanks!
$(document).ready(function() {
$('.verificar-free').hide();
$('.duplicate-free').hide();
$('.optionRow').hide();
var count = 2;
//duplicate
$('a.add-free').on('click', function() {
//clone
var row = $('.duplicate-free').clone();
$(row).insertAfter('.aditional-box-free');
$(row).show();
//add new ids
$(row).find('select').attr('id', 'select-free_' + count);
//remove duplicate class
$(row).removeClass('duplicate-free');
//onchange of select
$('select').on('change', function() {
var value = $(this).val();
var select = $(this).parent();
if (value == 1) {
$(select).siblings('.input-free').show();
$(select).siblings('.ocultar-free').hide();
} else {
$(select).siblings('.input-free').hide();
}
if (value == 2) {
$(select).siblings('.ocultar-free').show();
$(select).siblings('.verificar-free').show();
} else {
$(select).siblings('.verificar-free').hide();
}
});
//add option
$(".addRow-free").click(function() {
var html = "<div class='option-free' id='" + count + "'><div class='form-group'><div class='input-group select'><input type='text' class='form-control' placeholder='Añade opción' /><span class='input-group-btn'><button class='btn btn-primary remove-option' type='button'><a class='remove-tipe' href='javascript: void(0)'><span class='glyphicon glyphicon-trash' style='color:white'></span></a></button></span></div></div></div>";
var form = $(html);
$(this).closest(".verificar-free").find(".optionRow-free").append(form);
});
count++;
});
});
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<div class="aditional-questions text">
<div class="aditional-box-free">
<p class="aditional-text" for=""><b>Add Question</b>
<a class="btn btn-primary agregar add-free" href="javascript: void(0)" type="button"><span></span>Add</a>
</p>
</div>
<div class="duplicate-free all-free" style="text-align: center">
<div class="box-question">
<div class="row">
<label class="type-question-text" for="">Question Type</label>
<div class="col-md-12">
<select class="form-control select">
<option value="1">Text</option>
<option value="2">Verification</option>
</select>
</div>
<div class="row ocultar-free">
<div class="col-md-12">
<label class="type-question-text" for="">Title</label>
<div class="form-group">
<input type="text" id="" class="form-control text general" placeholder="Question">
</div>
</div>
</div>
<!--aditional option-->
<div class="row verificar-free">
<div class="text">
<div class="col-md-6">
</div>
</div>
<div class="text option text" style="margin-top:10px;">
<a class="btn btn-primary addRow-free" href="javascript: void(0)" type="button"><span></span>Add Option</a>
</div>
<br>
<div class="form-group optionRow-free">
</div>
</div>
</div>
<br>
</div>
</div>
</div>
If I'm not wrong with your question.
The problem is you got same(duplicate) added input right? (If more than 1 question)
Change this line
$(".optionRow-free").append(form);
To
$(this).closest(".verificar-free").find(".optionRow-free").append(form);
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?
Having the following HTML/jQuery code:
$(function() {
"use strict";
var manage_form_listing_grid = $("#manage_form_listing"),
forms_search = $("#forms_search"),
btn_search_forms = $("#btn_search_forms"),
chk_show_archived = $("#show_archived"),
inp_search_form_by_name = $("#search_form_by_name");
forms_search.keypress(function(ev) {
var key = ev.which;
if (key === 13) {
btn_search_forms.trigger("click");
return false;
}
});
forms_search.on("click", btn_search_forms, function(ev) {
ev.preventDefault();
var archive = !!chk_show_archived.is(":checked");
alert("You click me");
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row">
<div class="col-md-12">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Search form</h3>
</div>
<div class="panel-body">
<form class="form-inline" id="forms_search">
<div class="form-group col-md-5">
<input type="text" name="search_form_by_name" id="search_form_by_name" class="form-control input-full-width">
</div>
<div class="checkbox">
<label>
<input type="checkbox" id="show_archived" name="show_archived" value="1"> Show archived?
</label>
</div>
<button type="button" class="btn btn-default" id="btn_search_forms">
<i class="fa fa-search" aria-hidden="true"></i> Search
</button>
<button type="button" class="btn btn-default" id="btn_new_form">
<i class="fa fa-plus-circle" aria-hidden="true"></i> New Form
</button>
</form>
</div>
</div>
</div>
</div>
Why the click event is triggered as soon as I click on the input#search_form_by_name? What I am missing here? I would expect that clicking the button will trigger the event but not the click event on the input. Here is the jsFiddle
A delegated target of on() needs to be a selector string, not jQuery object
Change
forms_search.on("click", btn_search_forms, function(ev) {
To
forms_search.on("click", '#btn_search_forms', function(ev) {
Since you've created separate variables for the elements you can call on() this way:
btn_search_forms.on('click', function(ev){...})
Or as it is mentioned above, change the second param to a string
forms_search.on('click', '#btn_search_forms', function(ev) {...})
$(function() {
"use strict";
var manage_form_listing_grid = $("#manage_form_listing"),
forms_search = $("#forms_search"),
btn_search_forms = $("#btn_search_forms"),
chk_show_archived = $("#show_archived"),
inp_search_form_by_name = $("#search_form_by_name");
var new_form = $("#btn_new_form");
forms_search.keypress(function(ev) {
debugger
var key = ev.which;
if (key === 13) {
btn_search_forms.trigger("click");
return false;
}
});
forms_search.on("click", btn_search_forms, function(ev) {
console.log(btn_search_forms);
console.log("#btn_search_forms");
ev.preventDefault();
var archive = !!chk_show_archived.is(":checked");
alert("You click me");
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row">
<div class="col-md-12">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Search form</h3>
</div>
<div class="panel-body">
<form class="form-inline" id="forms_search">
<div class="form-group col-md-5">
<input type="text" name="search_form_by_name" id="search_form_by_name" class="form-control input-full-width">
</div>
<div class="checkbox">
<label>
<input type="checkbox" id="show_archived" name="show_archived" value="1"> Show archived?
</label>
</div>
<button type="button" class="btn btn-default" id="btn_search_forms">
<i class="fa fa-search" aria-hidden="true"></i> Search
</button>
<button type="button" class="btn btn-default" id="btn_new_form">
<i class="fa fa-plus-circle" aria-hidden="true"></i> New Form
</button>
</form>
</div>
</div>
</div>
</div>
Issue is the .on( events [, selector ] [, data ], handler ) the issue is selector here is a string to filter the descendants of the selected elements that trigger the event. If the selector is null or omitted, the event is always triggered when it reaches the selected element.
So in your case selected elements is complete forms_search. So click is attach to complete as will matching selector it didn't anything.
I have added console to check what is the value btn_search_form holding when click event trigger. See the difference. You are passing object but it need string.