Clone is duplicating multiple times, when I just want one - javascript

When I click duplicate it duplicates the row fine, but when I click it again I get another 2, then 4 etc, how can I stop this from happening and just clone one div on each click...
Jquery:
<script>
$(".clonable-button").bind('click', function(e){
e.preventDefault();
var section = $(this).data('clone');
var parent = $('[data-id="' + section + '"]');
var sequence = 0;
if(!$(this).data('last')) {
sequence = $(parent).find('.cloneable').last().data('id');
} else {
sequence = $(this).data('last');
}
$(this).data('last', ++sequence);
$(parent).append(parent.html());
});
$('.clone-wrapper').on('click', '.clone-remove',function(){
var parent = $(this).parents('.cloneable');
$(parent).remove();
});
</script>
html:
<div class="clone-wrapper" data-id="skill">
<div class="row cloneable" data-id="0">
<div class="col-md-9">
<div class="form-group">
<label for="skill_name_0">Skills and Qualifications Titles </label>
<input id="skill_name_0" placeholder="ex : PHP, WordPress" name="skill[0][name]" type="text" class="form-control" value="">
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<label for="skill_percentage_0">Job Position </label>
<input id="skill_percentage_0" placeholder="ex : 90" name="skill[0][percentage]" type="text" class="form-control" value="">
</div>
</div>
<div class="col-md-12 text-right clone-remove" data-last="">
<div class="btn btn-danger btn-sm" data-clone="skill">
<i class="fa fa-times"></i> Remove Skill </div>
</div>
</div>
</div>
<div class="white-space-20"></div>
<div class="row text-right">
<div class="col-md-12">
<div class="btn btn-default btn-sm clonable-button" id="skill">
<i class="fa fa-plus"></i> Add Skill </div>
</div>
</div>
I just want the following code duplicated once on each click
<div class="row cloneable" data-id="0">
<div class="col-md-9">
<div class="form-group">
<label for="skill_name_0">Skills and Qualifications Titles </label>
<input id="skill_name_0" placeholder="ex : PHP, WordPress" name="skill[0][name]" type="text" class="form-control" value="">
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<label for="skill_percentage_0">Job Position </label>
<input id="skill_percentage_0" placeholder="ex : 90" name="skill[0][percentage]" type="text" class="form-control" value="">
</div>
</div>
<div class="col-md-12 text-right clone-remove" data-last="">
<div class="btn btn-danger btn-sm" data-clone="skill">
<i class="fa fa-times"></i> Remove Skill </div>
</div>
</div>

The problem is in this line:
var parent = $('[data-id="' + section + '"]');
Each time you append new block with the same data-id number of elements that match this selector increases. So to avoid this you have make the selector more specific. Like:
var parent = $('[data-id="' + section + '"]:last');
Also there is a jQuery method to clone the element. So change your line from:
$(parent).append(parent.html());
to:
parent.append(parent.clone());
That will fix the issue.

You are binding the click event multiple times somehow, You should either use a delegated event handler or use the off method like below.
$(".clonable-button").off('click').on('click', function(e){

Related

Form repeater send wrong data with last element in Laravel

My form sends multiple forms of (name and image). However, the last element sends a name only with the wrong 'name.' Do I need to simultaneously make multiple inserts in the database to solve this problem?
Form View
Dump of the request with wrong last element of array
Script of repeat the form
<div class="row">
<div class="col-12">
<form class="form repeater-default" method="POST"
action="{{ route('admin.cat.doCreate2') }}"
enctype="multipart/form-data">
#csrf
<input type="hidden" name="admin_id"
value="{{ auth()->guard('admin')->user()->id }}">
<div data-repeater-list="group_a">
<div data-repeater-item>
<div class="row justify-content-between">
<div class="col-md-4 col-sm-12 form-group">
<label for="Name">Name </label>
<input type="text" class="form-control" name="name[]" required
placeholder="Enter Name of Category">
</div>
<div class="col-md-4 col-sm-12 form-group">
<label for="Image">Image </label>
<input type="file" class="form-control" name="image[]">
</div>
{{-- Delete Button --}}
<div class="col-md-2 col-sm-12 form-group d-flex align-items-center pt-2">
<button class="btn btn-danger" data-repeater-delete type="button"><i
class="mdi mdi-x"></i>
Delete
</button>
</div>
</div>
<hr>
</div>
</div>
<div class="form-group">
<div class="col p-0">
<button class="btn btn-primary" data-repeater-create type="button"><i class="mdi mdi-plus"></i>
Add
</button>
</div>
<div class="col p-0">
<button class="btn btn-success" type="submit"><i class="mdi mdi-account"></i>
Done
</button>
</div>
</div>
</form>
</div>
</div>
Script
<script>
$(document).ready(function(){
$("#myInput").on("keyup", function() {
var value = $(this).val().toLowerCase();
$("#tableData tr").filter(function() {
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
});
});
});
</script>
first solution : inputs and their labels must be on table tag and th tag and td tag
to send right data
second solution : dont use array for inputs names like name[ ] or image[ ] :
<div class="col-md-4 col-sm-12 form-group">
<label for="Image">Image </label>
<input type="file" class="form-control"
name="image">
</div>
and receive datas like this :
$data=$request->group_a
group_a is your data-repeater-list name :
<div data-repeater-list="group_a">
and now you can put $data in foreach and use data arrays for create ...insert and anything

How to copy full form on click add button(+ plus)

I am trying to copy full form on click add button,
copying only label name.
below JS code: below is js code trying to add form dynamically.
how to add same form below last div onclick '+' button.
using js code below, only adding panel, but it's not working.
document.getElementById('add').onclick = duplicate;
var i = 0;
var original = document.getElementById('add-form');
function duplicate() {
var clone = original.cloneNode(true); // "deep" clone
clone.id = "add-form" + ++i; // there can only be one element with an ID
original.parentNode.appendChild(clone);
}
<div class="row mt-4">
<div class="row">
<div class="col-md-3 text-center mt-3 ml-3">
<button type="button" class="btn btn-light" id="add"><i class="fas fa-plus fa-xs"></i></button>
</div>
<div class="col-md-3 text-center mt-3 ml-4">
<button type="button" class="btn btn-light" id="minus"><i class="ri-delete-bin-line mr-0"></i></button>
</div>
</div>
<div class="col-md mt-1" id="add-form" style="width: 100%;">
<button class="accordion btn btn-primary">Product screen</button>
<div class="panel">
<div class="col-sm-12">
<div class="card mt-3">
<div class="col-md-12">
<!-- first row -->
<div class="row" style="margin-top: 9px;">
<div class="col-sm">
<label for="fname">product_name
</label>
<input type="text" id="fname" class="form-control" placeholder="product_name">
</div>
<div class="col-sm">
<label for="fname">price
</label>
<input type="text" id="fname" class="form-control" placeholder="price">
</div>
<div class="col-sm">
<label for="fname">pur_id
</label>
<input type="text" id="fname" class="form-control" placeholder="pur_id">
</div>
<div class="col-sm">
<label for="field2">type
</label>
<select name="field2" id="field2" class="selectpicker form-control" data-style="py-0" width="50">
<option selected>select one</option>
<option>type1</option>
<option>type2</option>
<option>type3</option>
</select>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
after click add button displayed only this panel.

Change the multi select option text, when the option text is changed jquery

I'm creating a form where the user is allowed to add the options manually to the multiple select box. I've provided a preview field(for showing the preview) and a default value field(to select the default values if the user needs). There is a field for the user to enter the options. Once the user clicks the Add button after entering an option, it will be displayed in div provided. Each option can also be edited.
When the option is Added, that option will be added to the default value field as dropdown and to the preview field as dropdown. This is done simultaneouly, whenever an option is added.
When the option is edited, (according to my logic) the option in the div should be edited and the option in the default value and preview option should be edited as well. This is how I tried:
<div class="modal fade" id="MultiSelect_Modal" tabindex="-1" role="dialog" aria-hidden="true" data-backdrop="static">
<div class="modal-dialog" style="min-width: 75% !important;">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">
<span aria-hidden="true">×</span><span class="sr-only">Close</span>
</button>
<h4 class="modal-title" id="FieldType">Multi Select</h4>
</div>
<div class="modal-body form-horizontal">
<div class="row">
<div class="col-sm-6">
<div class="form-group required">
<label for="MultiSelect_Label" class="col-sm-4 control-label">Label Name</label>
<div class="col-sm-6">
<input type="text" class="form-control" id="MultiSelect_Label" name="MultiSelect_Label" value=''>
</div>
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label for="MultiSelect_DefaultValues" class="col-sm-4 control-label">Default Value</label>
<div class="col-sm-6">
<select id="MultiSelect_DefaultValues" name="MultiSelect_DefaultValues[]" class="form-control" multiple="multiple" style="width: 160px;">
<option value="0">---Select---</option>
</select>
</div>
</div>
</div>
</div>
<div class="row" id="manualEntryDiv">
<div class="col-sm-6">
<div class="form-group required">
<label for="MultiSelect_Options" class="col-sm-4 control-label">Options</label>
<div class="col-sm-6">
<div class="input-group">
<input type="text" class="form-control" id="MultiSelect_Options" name="MultiSelect_Options" value=''>
<span class="input-group-btn">
<input type="button" class="btn btn-primary" id="MultiSelect_optionAdd" name="MultiSelect_optionAdd">
</span>
</div>
</div>
</div>
</div>
<div class="col-sm-6">
<div class="result" id="MultiSelect_mydiv"></div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="form-group" style="margin-left: -20px;">
<label for="MultiSelect_Description" class="col-sm-4 control-label">Description</label>
<div class="col-sm-6">
<textarea type="text" class="form-control" id="MultiSelect_Description" name="MultiSelect_Description" row='3'></textarea>
</div>
</div>
</div>
<div class="col-sm-6">
<div class="form-group required">
<label for="MultiSelect_Status" class="col-sm-4 control-label">Status</label>
<div class="col-sm-6">
<select class="form-control" name="MultiSelect_Status" id="MultiSelect_Status">
<option value="1">Active</option>
<option value="0">In-Active</option>
</select>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label for="MultiSelect_Preview" id="MultiSelect_PreviewID" class="col-sm-4 control-label">Preview</label>
<div class="col-sm-6">
<select id="MultiSelect_Preview" name="MultiSelect_Preview[]" class="form-control" multiple="multiple" style="width: 160px;">
<option value="0">---Select---</option>
</select>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer clearfix">
<button type="button" class="btn btn-default" onclick="clearcontrols();" data-dismiss="modal">Close</button>
<input type="submit" id="MultiSelect_Save" name="MultiSelect_Save" value="Save" class="btn btn-primary">
</div>
</div>
</div>
</div>
$("#MultiSelect_optionAdd").click(function(){
if($("#MultiSelect_Options").val() == ""){
MyNotif.Show("Please enter an option","warning");
} else {
if($("#MultiSelect_optionAdd").val() == "Add"){
var optionvalue = $("#MultiSelect_Options").val();
$("#MultiSelect_mydiv").append("<span id='span" + a + "' class='editbutton'>" + optionvalue + "&nbsp&nbsp&nbsp&nbsp<a href='javascript:void(0)' ><i class='fa fa-close btn btn-danger btn-xs btn-remove btn-icon remove' id='remove" + a + "' style='display: none;'></i></a><a href='javascript:void(0)'><i class='fa fa-pencil btn btn-warning btn-xs btn-edit btn-icon edit' id='edit" + a + "' style='display: none; margin-right:10px;'></i></a></span><br/>");
$("#MultiSelect_Preview").append('<option value="value-'+ optionvalue +'" id="options'+ a +'">' + optionvalue + '</option>');
$("#MultiSelect_DefaultValues").append('<option value="value-'+ optionvalue +'" id="defaultOptions'+ a +'">' + optionvalue + '</option>');
a = a + 1;
$("#MultiSelect_Options").val("");
} else if ($("#MultiSelect_optionAdd").val() == "Update") {
$("#"+spanid).text($("#MultiSelect_Options").val()).append("&nbsp&nbsp&nbsp&nbsp<a href='javascript:void(0)' ><i class='fa fa-close btn btn-danger btn-xs btn-remove btn-icon remove' id='" + removebuttonid + "' style='display: none;'></i></a><a href='javascript:void(0)'><i class='fa fa-pencil btn btn-warning btn-xs btn-edit btn-icon edit' id='" + editbuttonid + "' style='display: none; margin-right:10px;'></i></a>");
$("#MultiSelect_optionAdd").val("Add");
$("#"+optionsid).text($("#MultiSelect_Options").val());
$("#"+defaultOptionsid).text($("#MultiSelect_Options").val());
$("#"+defaultOptionsid).val("value-"+$("#MultiSelect_Options").val());
$("#MultiSelect_Options").val("");
}
$('.remove').click(function(){
removebuttonid = $(this).attr("id");
spanid = removebuttonid.replace('remove', 'span');
optionsid = removebuttonid.replace('remove', 'options');
defaultOptionsid = removebuttonid.replace('remove', 'defaultOptions');
$("#"+spanid).next("br").remove();
$("#"+spanid).remove();
$("#"+optionsid).remove();
$("#"+defaultOptionsid).remove();
});
$(".edit").click(function(){
addButtonValue = "Update"
$("#MultiSelect_optionAdd").val(addButtonValue);
editbuttonid = $(this).attr("id");
spanid = editbuttonid.replace('edit', 'span');
optionsid = editbuttonid.replace('edit', 'options');
defaultOptionsid = editbuttonid.replace('edit', 'defaultOptions');
removebuttonid = editbuttonid.replace('edit', 'remove');
var value = ($("#"+spanid).text()).trim();
$("#MultiSelect_Options").val(value);
});
}
});
Here, whenever I add an option, that option gets added to the div, default value and preview fields. Whatever I add as an option, it gets added.
But, the problem is, when I edit the option I provide, the option inside the div gets changed. But, the option in the default value and preview displays the same text which was provided previously. But, when I inspect the element, I can see the edited text as well as edited value. But, the previously provided option is only shown. The edited text is not shown.
I don't know what's wrong with the above code. What should I change in this?

Setting focus inside textarea doesn't work

I have the following code:
<div class="modal-body">
<div class="form-group" id="checkDiv_0">
<div class="col-md-2 control-label">
#Translations.ReportCopy
</div>
<div class="col-md-10">
<div class="col-md-1">
<button class="btn btn-primary pull-right"><span class="glyphicon glyphicon-remove"></span></button>
</div>
<div class="col-md-11">
<textarea id="textarea_0" name="Copies" class="form-control textarea-resize"></textarea>
</div>
</div>
</div>
<div class="form-group" id="checkDiv_1">
<div class="col-md-2 control-label">
#Translations.ReportCopy
</div>
<div class="col-md-10">
<div class="col-md-1">
<button class="btn btn-primary pull-right"><span class="glyphicon glyphicon-remove"></span></button>
</div>
<div class="col-md-11">
<textarea id="textarea_1" name="Copies" class="form-control textarea-resize"></textarea>
</div>
</div>
</div>
I want to set focus on textare with the id textarea_1. Without the focus the user must left-click insisde the textarea and than can start writting inside it.
I tried with $('#textarea_1').focus(), but without success.
SOLUTION:
I solved the problem this way:
$(document).ready(function () {
$('#modal').on('shown.bs.modal',
function () {
var element = document.getElementById("textarea_0");
element.focus();
});
});
You need to wrap your jQuery code inside the .ready() function:
$(document).ready(function(){
$("#textarea_1").focus();
});
You do not need javascript for this question, since you can just do:
<textarea id="textarea_1" name="Copies" class="form-control textarea-resize" autofocus></textarea>
The autofocus attribute focuses the text area as default on the DOM.
You can use this page as reference:
http://www.w3schools.com/tags/att_textarea_autofocus.asp
Two examples without jQuery:
window.onload = function() { document.getElementById('textarea_1').focus(); };
or
window.addEventListener('load', function() { document.getElementById('textarea_1').focus(); }, false);
The second one allows you to assign multiple 'onload' events to single DOM element.
The code necessary really depends on when you need to give it focus. If you need to give it focus when the page loads, you should do what #David Li suggested.
Otherwise, you can do something like this.
document.getElementById('focusButton').onclick = function(){
document.getElementById('textarea_1').focus();
};
<div class="modal-body">
<div class="form-group" id="checkDiv_0">
<div class="col-md-2 control-label">
#Translations.ReportCopy
</div>
<div class="col-md-10">
<div class="col-md-1">
<button class="btn btn-primary pull-right"><span class="glyphicon glyphicon-remove"></span></button>
</div>
<div class="col-md-11">
<textarea id="textarea_0" name="Copies" class="form-control textarea-resize"></textarea>
</div>
</div>
</div>
<div class="form-group" id="checkDiv_1">
<div class="col-md-2 control-label">
#Translations.ReportCopy
</div>
<div class="col-md-10">
<div class="col-md-1">
<button class="btn btn-primary pull-right"><span class="glyphicon glyphicon-remove"></span></button>
</div>
<div class="col-md-11">
<textarea id="textarea_1" name="Copies" class="form-control textarea-resize"></textarea>
</div>
</div>
</div>
<input type="button" id="focusButton" value="give element focus">

jQuery .on() issue, console.log() works but element interaction doesn't

I am using this code inside $(document).ready(function(){ ... }):
$('#flavours').on('click', '.toggle-quantity', function(e){
e.preventDefault();
var $quantity_percent = $(this).parent().find('.quantity_percent');
if($quantity_percent.is(':hidden')){
console.log("is hidden");
$quantity_percent.show();
}else{
console.log("is not hidden");
$quantity_percent.hide();
}
});
What's happening is the console.log() is working, but the $quantity_percent is not showing/hiding.
Additionally, if I add an alert('test') to the beginning of the function (just after e.preventDefault) this also doesn't work, but the console.log() continues to work (it correctly logs 'is not hidden').
EDIT: Relevant HTML markup:
<div id="flavours">
<div class="row flavour" id="flavour_1" style="display: block;">
<div class="form-group">
<div class="col-xs-12">
<fieldset>
<legend>Flavour 1</legend>
<div class="col-sm-4">
<label>Flavour Name</label>
<input type="text" value="" name="flavour_name[]" data-flavour-id="1" id="flavour_name_1" class="form-control autocomp" placeholder="Flavour name">
<input type="hidden" value="" name="flavour_id[]" id="flavour_id_1" class="form-control flavour_id">
<p class="flavour_info"></p>
</div>
<div class="col-sm-6">
<label>Flavour Quantity <span class="fa fa-filter"></span> <span class="hidden-sm">Switch to </span>drops per ml</label>
<div class="input-group" id="quantity_percent">
<input type="text" class="form-control" id="flavour_percentage_1" name="flavour_percentage[]" placeholder="Flavour Quantity">
<span class="input-group-addon">%</span>
</div>
<div class="input-group" id="quantity_drops" style="display: none;">
<input type="text" class="form-control" id="flavour_drops_1" name="flavour_drops[]" placeholder="Flavour Quantity">
<span class="input-group-addon">drops/ml</span>
</div>
<p class="flavour_recommended_percentage"></p>
</div>
<div class="col-sm-2">
<label> </label>
<button class="btn btn-danger btn-block remove-flavour"><span class="glyphicon glyphicon-remove"></span> Remove</button>
</div>
</fieldset>
</div>
</div>
</div>
$(this).parent() is a label element which doesn't have a child with .quantity_percent
Also quantity_percent is an id and not a class. Use the ID selector
So use
var $quantity_percent = $('#quantity_percent');
instead of
var $quantity_percent = $(this).parent().find('.quantity_percent');
Note: IDs must be unique in HTML
EDIT: as per OPs comments
I updated it to a class rather than ID (as it's on a dynamically growing list)
Usage
var $quantity_percent = $(this).closest('.col-sm-6').find('.quantity_percent');
The .parent() targets the <label> therefore it can't find .quantity_percent

Categories

Resources