Add/Remove button not working on duplicated form fields - jquery - javascript

I have used the code from the following answer: jquery clone form fields and increment id to created a clone-able area of my form and all is working well except for the "Add another" and "Remove row" button.
Only the original clone-able areas Add / Remove buttons work so the next cloned area's add / remove buttons don't do anything meaning you have use the first row's which is confusing.
I really can't see what is going on. Any help would be greatly appreciated!
The HTML:
<div id="previous-jobs">
<div class="panel-group" id="accordion">
<div id="clonedInput1" class="clonedInput panel panel-default">
<div class="panel-heading clearfix">
<h4 class="panel-title pull-left">
<a class="heading-reference accordion-toggle" data-toggle="collapse" data-parent="#accordion" href="#collapse1">
Entry #1
</a>
</h4>
<div id="action-buttons" class="pull-right">
<button type="button" class="btn btn-success clone">Add another</button>
<button type="button" class="btn btn-danger remove">Delete Row</button>
</div>
</div>
<div id="collapse1" class="input-panel panel-collapse collapse">
<div class="panel-body">
<div class="row">
<div class="form-group col-sm-6">
<label class="p-date-from-title input-title" for="p-date-from">Date From</label>
<input type="text" class="ci-df form-control" id="p-date-from1" name="p-date-from" value="[[+!fi.p-date-from]]" placeholder="Date from">
</div>
<div class="form-group col-sm-6">
<label class="p-date-to-title input-title" for="p-date-to">Date To</label>
<input type="text" class="ci-dt form-control" id="p-date-to1" name="p-date-to" value="[[+!fi.p-date-to]]" placeholder="Date to">
</div>
</div>
<div class="form-group">
<label class="p-employer-title input-title" for="p-employer">Employer</label>
<input type="text" class="ci-em form-control" id="p-employer1" name="p-employer" value="[[+!fi.p-employer]]" placeholder="Employer">
</div>
<div class="form-group">
<label class="p-position-title input-title" for="p-position">Position</label>
<input type="text" class="ci-po form-control" id="p-position1" name="p-position" value="[[+!fi.p-position]]" placeholder="Position">
</div>
<div class="form-group">
<label class="p-salary-title input-title" for="p-salary">Salary</label>
<input type="text" class="ci-sa form-control" id="p-salary1" name="p-salary" value="[[+!fi.p-salary]]" placeholder="Salary">
</div>
<div class="form-group">
<label class="p-full-part-time-title input-title" for="p-full-part-time">Full/Part Time</label>
<select class="ci-fpt form-control" id="p-full-part-time1" name="p-full-part-time" value="[[+!fi.p-full-part-time]]">
<option value="Full Time">Full Time</option>
<option value="Part Time">Part Time</option>
</select>
</div>
<div class="form-group">
<label class="p-leaving-reason-title input-title" for="p-leaving-reason">Reason for Leaving</label>
<input type="text" class="ci-rfl form-control" id="p-leaving-reason1" name="p-leaving-reason" value="[[+!fi.p-leaving-reason]]" placeholder="Reason for leaving">
</div>
</div>
</div>
</div>
</div>
The jQuery:
var regex = /^(.*)(\d)+$/i;
var cloneIndex = $(".clonedInput").length;
$("button.clone").click(function(){
cloneIndex++;
$(this).parents(".clonedInput").clone()
.appendTo("#accordion")
.attr("id", "clonedInput" + cloneIndex)
.find("*").each(function() {
var id = this.id || "";
var match = id.match(regex) || [];
if (match.length == 3) {
this.id = match[1] + (cloneIndex);
this.name = match[1] + (cloneIndex);
}
$(this).find('.heading-reference').attr("href", "#collapse" + cloneIndex).html('Entry #' + cloneIndex);
});
});
$("button.remove").click(function(){
$(this).parents(".clonedInput").remove();
});

For dynamically added elements, use .on() jQuery documentation .on() (For jQuery 1.7 and above)
In the example you posted, they used .live() which is for jQuery 1.7 and below.
Add this outside of any $(document).ready() function:
$(document).on('click', 'button.clone', function(){
...
});
By doing this, the event handler gets added to the document so any time an event bubbles up to it that originated from a button.clone element, it will trigger that function. So when buttons get added after the page is loaded, they will still trigger the click event, even when they weren't available when the page initially loaded.
If you just use $('button.clone').click(...) only the buttons that are on the page when it is first loaded will trigger the click event.

Related

Trying to find this on click and then toggle class?

I'm trying to toggle the class of this on click, I tried this but it doesn't seem to work. Any ideas? I have included some HTML now so that it is more easily understood what is going on.
$('.play-with-friends').on('click', function(){
$('.flipper', this).toggleClass('flipped');
});
HTML:
<div class="flipper">
<div class="row game-cards">
<div class="container col-lg-6">
<canvas id="game-circles"></canvas>
</div>
<div class="col-lg-6 game-info">
<h6 class="text-center">{{AwayTeam}} # {{HomeTeam}}</h6>
<p class="text-center">{{MatchTime}}</p>
<form>
<div class="form-group text-center">
<label for="home-team">{{HomeTeam}} -2.5</label>
<input type="number" class="form-control text-center" placeholder="Home Team Bet">
</div>
<div class="form-group text-center">
<label for="away-team">{{AwayTeam}}</label>
<input type="number" class="form-control text-center" placeholder="Away Team Bet">
</div>
<button type="submit" class="btn btn-primary btn-block">Submit</button>
<button type="button" class="btn btn-secondary btn-block play-with-friends">Play With Friends</button>
</form>
</div>
</div>
</div>
So please change your code to select .flipper:
$('.play-with-friends').on('click', function(){
$('.flipper').toggleClass('flipped');
});
When you do $('.some-class', elem) you're saying you want to target .some-class that's a child of elem. That's not what your HTML is showing – you actually have .flipper way above at the top level. How about using a different method, like closest, which will find an ancestor with the selector you specify:
$('.play-with-friends').on('click', function() {
$(this).closest('.flipper').toggleClass('flipped');
});

How to add dynamic data attribute value to a button and a div generated by repeater.js

I am using repeater.js to repeat a div with some input fields and button, but the problem is that i want to give each and every div a unique id so that i can extract data from all the fields of that particular div input elements.
this is the HTML Code:
<div class="form-group mt-repeater">
<a href="javascript:;" data-repeater-create class="btn btn-circle purple mt-repeater-add">
<i class="fa fa-edit"></i> Repeat Field
</a>
<div data-repeater-list="group-b">
<div data-repeater-item class="mt-repeater-item">
<div class="mt-repeater-cell">
<div class="row">
<div class="col-md-2">
<div class="form-group">
<div class="input-group">
<input type="text" id="dosage_form" class="form-control typeahead-findings circle-input" placeholder="Dosage Form">
<label for="dosage_form">e.g. Tablet / Syrup / Capsule etc.</label>
</div>
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<div class="input-group">
<input type="text" id="brand_name" class="form-control typeahead-findings circle-input" placeholder="Brand / Generic Name">
<label for="brand_name">e.g. Dytor</label>
</div>
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<input class="form-control circle-input" id="contents" type="text" placeholder="Contents" />
<span class="help-block"> e.g Paracetamol </span>
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<div class="input-group">
<input type="text" id="dose" class="form-control typeahead-findings circle-input" placeholder="Dose">
<label for="dose">e.g. 20 mg / 20 ml</label>
</div>
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<input class="form-control circle-input" id="dose_regimen" type="text" placeholder="Dose Regimen" />
<span class="help-block"> e.g 1-1-1-1 </span>
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<div class="input-group">
<input type="text" id="therapy_duration" class="form-control typeahead-findings circle-input" placeholder="Therapy Duration">
<label for="therapy_duration">e.g. 1 Day / 1 Month etc.</label>
</div>
</div>
</div>
<div class="col-md-1 col-sm-6 col-xs-6">
<i class="fa fa-plus"></i>
</div>
<div class="col-md-1 col-sm-6 col-xs-6">
<i class="fa fa-minus"></i>
</div>
</div>
</div>
</div>
every time i click on the add repater button this div gets replicated but what i also want is that the new div generated should have a unique div id also the curresponding elemnts inside it should have a class or id starting with that id so that data extraction can be easy for that particular div
I was using this Jquery code:
$(".addData").on('click' ,function()
{
alert("hi");
});
This is the repeater i am using: https://pastebin.com/n7g7tdTH
but this code only runs for the very first div on the later generated dynamic divs it doesn't run. I also tried editing the repeater.js but no success because its all dynamic and i am not able to understand where i should edit that code to add a dynamic data-counter value for the div and the corresponding elements.
Can anyone help with this logic?
Another option, to retrieve field values would be to rename all input field id with name (example below) and use repeater.js repeaterVal() to get all the field values .
$(".mt-repeater").repeater();
$("#getVal").click(function () {
$('.mt-repeater').repeaterVal()["group-b"].map(function(fields){
//fields contain the collection of input fields per row
console.log(fields["dosage_form"]);
console.log(fields["brand_name"]);
//....
})
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.repeater/1.2.1/jquery.repeater.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" />
<div class="form-group mt-repeater">
<a href="javascript:;" data-repeater-create class="btn btn-circle purple mt-repeater-add">
<i class="fa fa-edit"></i> Repeat Field
</a>
<div data-repeater-list="group-b">
<div data-repeater-item class="mt-repeater-item">
<div class="mt-repeater-cell">
<div class="row">
<div class="col-md-2">
<div class="form-group">
<div class="input-group">
<input type="text" name="dosage_form" class="form-control typeahead-findings circle-input" placeholder="Dosage Form">
<label for="dosage_form">e.g. Tablet / Syrup / Capsule etc.</label>
</div>
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<div class="input-group">
<input type="text" name="brand_name" class="form-control typeahead-findings circle-input" placeholder="Brand / Generic Name">
<label for="brand_name">e.g. Dytor</label>
</div>
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<input class="form-control circle-input" nam="contents" type="text" placeholder="Contents" />
<span class="help-block"> e.g Paracetamol </span>
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<div class="input-group">
<input type="text" name="dose" class="form-control typeahead-findings circle-input" placeholder="Dose">
<label for="dose">e.g. 20 mg / 20 ml</label>
</div>
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<input class="form-control circle-input" name="dose_regimen" type="text" placeholder="Dose Regimen" />
<span class="help-block"> e.g 1-1-1-1 </span>
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<div class="input-group">
<input type="text" name="therapy_duration" class="form-control typeahead-findings circle-input" placeholder="Therapy Duration">
<label for="therapy_duration">e.g. 1 Day / 1 Month etc.</label>
</div>
</div>
</div>
<div class="col-md-1 col-sm-6 col-xs-6">
<i class="fa fa-plus"></i>
</div>
<div class="col-md-1 col-sm-6 col-xs-6">
<i class="fa fa-minus"></i>
</div>
</div>
</div>
</div>
<button id="getVal">Get Value</button>
For the first problem..
but this code only runs for the very first div on the later generated
dynamic divs it doesn't run
You can convert your jquery events into delegated events.. These allow you to catch events on DOM elements based on a selector, so when newer DOM elements are added these are caught too.
So -> $(".addData").on('click' ,function()
As a delegated event becomes -> $(document.body).on("click",".addData" ,function()
The second problem.
but how to get the values from the input field that are present near that button
This can be achieved by traversing up the DOM tree to a parent that surrounds the elements you want,. eg. .row or maybe mt-repeater-cell, as long as it's a DOM element that contains the elements you want to find. Here you can use jquery's closest selector, that will traverse up the tree until it finds the element your after.
So -> $(this).closest('.row').find('#dose_regimen').val()
The above will traverse up the DOM tree until it finds a .row class, we then find element with id dose_regimen etc,.. #dose_regimen and then finally get it's value with .val()

javascript - how to fade in div class

I want to fade in a div class when a click action is made. But it's not working.
the picture above is produced by function gotData.
function gotData(data) {
var jobs = data.val();
var keys = Object.keys(jobs);
var container = document.getElementById('Jobcontainer');
var container2 = document.getElementById('jobpackage');
for (var i = 0; i<keys.length; i++) {
var k = keys[i];
var newCard = `
<li class="pos-card" id="Jobcontainer">
<div class="content">
<div class="title">`+jobs[k].JobTitle+`</div>
<div class="date">April 21</div>
<div class="refer">Refer</div>
</div>
<ul class="desc">
<li>`+ jobs[k].JobSummary + `</li>
</ul>
</li>`;
container.innerHTML += newCard;
}
}
in the same file html tag I have this html code
<div class="return">Return to listings </div>
<div class="container refer-card">
<div class="modal confirmed"><span class="close-modal"></span>
<h2>Thank you!</h2>
<p><span id="refer_name" class="focus"></span> has been submitted for the <span id="refer_pos" class="focus"></span> position.</p>
</div>
<div class="sign-up card">
<div class="card__header">
<h1>Employee Referral</h1>
<div class="description">For more information, please consult the employee handbook.</div>
</div>
<div class="card__content">
<form class="referral" method="post">
<div class="field line">
<input class="req" maxlength="240" type="text" name="name" value="" required="required" id="name"/>
<label class="placeholder" for="name">Full Name</label>
</div>
<div class="field line">
<input class="req" maxlength="240" type="email" name="email" value="" required="required" id="email"/>
<label class="placeholder" for="email">Email</label>
</div>
<div class="field line inline">
<input class="req" maxlength="240" type="text" name="position" value="" required="required" id="position"/>
<label class="placeholder" for="position">Position</label>
</div>
<!-- <div class="field inline right"><span class="dropdown-wrapper">
<select class="empty" name="department" id="choice">
<option value="" selected="selected">Department</option>
<option value="1">Development</option>
<option value="2">Sales</option>
<option value="3">QA</option>
<option value="4">Design</option>
<option value="5">HR</option>
<option value="6">Research </option>
</select></span></div> -->
<div>
<input type="submit" value="Submit" disabled="disabled" id="btn"/>
</div><a class="reset" href="#">Reset </a>
</form>
</div>
</div>
</div>
I am attempting to use the JS function below to fade in refer-card in the html tag when "refer" in picture above is clicked but for some unknown reasons nothing is happening and no error is displayed. Can you help figure out what I'm doing wrong or missing?
$('.refer').click(function(e){
e.stopPropagation();
$('.positions').addClass('fadeOut');
$('.refer-card').addClass('show');
$('.return').fadeIn('fast');
});
Try this codepen (http://codepen.io/anon/pen/gmdgmv)
Perhaps you have not defined jQuery, as it seems to work with a sample job block I put in place, and the basic CSS to hide the element you are trying to fade in. Also, bear in mind that if you've hidden it with '!important' in your CSS then the fade in will not work.
I added a console.log('clicked'); to your click handler verify that the block is executing.
It might be because you've called the [gotData] method that would append the html tag with the 'refer' class in play thus by that time, (refer) class didnt register or bind the [click] event handler after loading the DOM
In this case, you need to attach / bind them beforehand using (on) or (delegate) method (If you want to apply this in jQuery)
Using (on) method:
$('.refer').on('click', function(event) {
$('.positions').addClass('fadeOut');
// rest of code
});
Using (delegate) method:
$(document).delegate('.refer', 'click', function(event) {
$('.positions').addClass('fadeOut');
// rest of code
});
Hope this helps for your case.

Jquery - Cloning collapsible divs

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.

Closing Dynamically created DIV

So I have a section to add a color and I got it to dynamically create a copy of the div with a new ID for each dynamic div.
The problem is that once the div is created, I don't know how to close it (i.e. remove it from DOM via a "close" action). I know it's because it's dynamic content. You cant bind event likes the static content, it's will not bind to the elements because they don't appear at the time you bind. I just don't know how to go about getting it to close.
The div I want to close starts with "Color" + incremented number. I hope I explained this correctly and any help would be appreciated. Thanks.
<div class="col-xs-12" style="max-width: 800px">
<div class="col-md-12">
<h3>COLOR ROTATION</h3>
<!--Begin color rotation well-->
<div id="color">
<div class="well well-sm">
<div class="row">
<div class="col-md-6">
<div class="form-group"><a><span class="glyphicon glyphicon-remove-sign" aria-hidden="true" style="padding-right: 2px;"></span></a>
<label class="control-label">Color 1</label>
<input class="form-control" maxlength="100" placeholder="Enter Color" required="required" type="text" />
</div>
</div>
<div class="col-md-6">
<label class="control-label">DROPDOWNS REQUIRED?</label>
<div class="form-inline">
<div class="radio">
<label>
<input name="optradio" type="radio" />Yes</label>
</div>
<div class="radio">
<label>
<input name="optradio" type="radio" />No</label>
</div>
</div>
</div>
</div>
</div>
</div>
<!--End color rotation well-->
</div>
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span><a id="addcolor">Add Color</a>
<button class="btn btn-primary nextBtn btn-lg pull-right" type="button">Next</button>
Here's the link to the working example:
jsfiddle
Sure, see this updated fiddle;
Essentially you want to bind an event to the document using .on(), like:
$(document).on('click', '.remove', function(e){
$(this).closest('.color-wap').remove();
});
I added the .color-wrap class to the #color div to avoid working with duplicated ID's via cloning, and added the .remove class to the remove button
1)Use the .on() to bind events on dynamically created elements
2)jquery selector ^ can help in selecting the div with id of color-number.
3).animate() to toggle height of the div or .remove if you want to completly remove the element.
$(function() {
var count = 0;
$('#addcolor').click(function() {
count++;
var clonediv = $('#color');
$(clonediv).clone().insertBefore('#color');
$(clonediv).attr("id", "color" + count);
});
$(document).on("click", ".glyphicon-remove-sign", function() {
$(this).closest("div[id^='color']").animate({"height":"toggle"});
//$(this).closest("div[id^='color']").remove();
})
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div class="col-xs-12" style="max-width: 800px">
<div class="col-md-12" id="test">
<h3>COLOR ROTATION</h3>
<!--Begin color rotation well-->
<div id="color">
<div class="well well-sm">
<div class="row">
<div class="col-md-6">
<div class="form-group"><a><span class="glyphicon glyphicon-remove-sign" aria-hidden="true" style="padding-right: 2px;"></span></a>
<label class="control-label">Color 1</label>
<input class="form-control" maxlength="100" placeholder="Enter Color" required="required" type="text" />
</div>
</div>
<div class="col-md-6">
<label class="control-label">DROPDOWNS REQUIRED?</label>
<div class="form-inline">
<div class="radio">
<label>
<input name="optradio" type="radio" />Yes</label>
</div>
<div class="radio">
<label>
<input name="optradio" type="radio" />No</label>
</div>
</div>
</div>
</div>
</div>
</div>
<!--End color rotation well-->
</div>
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span><a id="addcolor">Add Color</a>
<button class="btn btn-primary nextBtn btn-lg pull-right" type="button">Next</button>
</div>

Categories