I am using Krajee's Bootstrap file upload plugin for file input & I am trying to clone the file input so that users can add multiple files from different folders rather than selecting it at once. The issue I am facing is after the file input gets cloned, it behaves weirdly. I have setup a fiddle for this.
When I am trying to reset or clear the file input, it always clears the first input. Have been trying a lot of options & after spending so many hours decided to post here.
JS Fiddle: https://jsfiddle.net/asfg9mna/
Any ideas as to how to make it work fine? Issue is whenever i click on delete icon, it always deletes the first input's file & not the current one.
HTML code:
<form role="form" id="upload-form" class="form-horizontal">
<div class="addFiles text-nowrap">
<div class="appendClass form-group" style="margin-bottom: 1.5%;">
<label class="col-md-2 control-label" for="input-2">Select Files</label>
<div class="col-md-9 col-9-input uploadFile">
<input placeholder="Select Files" id="input-2" name="input2[]" type="file" class="file input-upload" data-show-upload="false" data-show-preview="false">
</div>
<button type="button" class="btn btn-box-tool addFilesBtn" data-toggle="tooltip" title="Click to add more files">
<i class="fa fa-plus"> </i>
</button>
<button type="button" class="btn btn-box-tool closeFilesBtn" data-toggle="tooltip" title="Click to remove this block">
<i class="fa fa-times"> </i>
</button>
</div>
</div>
</form>
JS Code:
//Clone Upload File Div
$(document).on('click', ".addFilesBtn", function(e) {
e.preventDefault();
$(this).tooltip('hide');
$(".appendClass:first").clone(true).appendTo(".addFiles");
$('.closeFilesBtn').show();
$('.closeFilesBtn:first').hide();
//$fileInput = $('.input-upload');
//$fileInput.replaceWith( $fileInput = $fileInput.clone( true ) );
//$('.input-upload').fileinput('clear').fileinput();
$('.uploadFile').next().trigger('reset');
});
Here is jsfiddle
Update your js code like this,
$(document).on('click', ".addFilesBtn", function(e) {
e.preventDefault();
$(this).tooltip('hide');
parent_element = $(".appendClass:first");
$(".input-upload").fileinput('destroy');
element = parent_element.clone();
element.appendTo(".addFiles");
$(".input-upload").fileinput();
$('.closeFilesBtn').show();
$('.closeFilesBtn:first').hide();
//$fileInput = $('.input-upload');
//$fileInput.replaceWith( $fileInput = $fileInput.clone( true ) );
//$('.input-upload').fileinput('clear').fileinput();
//$('.uploadFile').next().trigger('reset');
});
And please write your code to update ids of every elements which will be cloned.
EDIT
$(document).on('click', ".addFilesBtn", function(e) {
e.preventDefault();
$(this).tooltip('hide');
$(".has_clone").each(function() {
$this = $(this);
var parent_element = $(this).closest(".appendClass");
var $element = parent_element.clone();
$element.find(".file-input").remove();
var counter = parseInt($("#counter").val()) + 1;
$element.find(".col-md-9").append('<input placeholder="Select Files" id="input-' + counter + '" name="input2[]" type="file" class="file dynamic_clone input-upload " data-show-upload="false" data-show-preview="false">');
$("#counter").val(counter);
$element.appendTo(".addFiles");
$(".input-upload").fileinput({
'showPreview': true
});
});
$('.closeFilesBtn').show();
$('.closeFilesBtn:first').hide();
});
//Close addFile div - Upload files
$(document).on('click', ".closeFilesBtn", function(e) {
e.preventDefault();
$(this).closest(".appendClass").hide();
});
Thanks
Related
I have a page that has multiple range sliders with matching submit buttons so i can submit each slider value after the user changes it and send it to a server where a program is running a function that returns the square of this value and return it back to me. This is the code i'm using :
$(window).on("load", function(){
var slider = $(".slider");
slider.change(function(){
var output= this.value;
$(".formoid").submit(function(event) {
posting= $.get( "http://192.168.4.49:8002/data", { n:output });
posting.done(function(data){
console.log(data)
});
});
});
});
(Html)
<div id='Services' style="display:none;">
<span class="Content_Title"> Demand <i class="fa fa-chevron-right" aria-hidden="true"></i> Tertiary <i class="fa fa-chevron-right" aria-hidden="true"></i> Services </span>
<div id="svg_Services"></div>
<div id="slider_box">
<div class="Slider"><input type="range" class="slider" min="0" max="100" name="output10"></div>
<b><div class="output" id="output10">value: %</div></b>
</div>
<form class="formoid" title="" method="get">
<div>
<input type="submit" class="btn-info" id="submitButton" name="submitButton" value="Submit Value">
</div>
</form>
</div>
<div id='Agriculture' style="display:none;">
<span class="Content_Title"> Demand <i class="fa fa-chevron-right" aria-hidden="true"></i> Tertiary <i class="fa fa-chevron-right" aria-hidden="true"></i> Agriculture </span>
<div id="svg_Agriculture"></div>
<div id="slider_box">
<div class="Slider"><input type="range" class="slider" min="0" max="100" name="output11"></div>
<b><div class="output" id="output11">value: %</div></b>
</div>
<form class="formoid" title="" method="get">
<div>
<input type="submit" class="btn-info" id="submitButton" name="submitButton" value="Submit Value">
</div>
</form>
</div>
The problem is that each time i submit another slider's value i get the previous one as well.For example if i move the first slider to a value of 3 i get 9 in my console.If after this i move another slider to a value of 2 i get 9 and 4. Does anybody know how to fix this?
You don't really want the form to submit, therefore you don't need a 'submit' handler, let alone an accumulation of 'submit' handlers that grows every time one of the sliders is changed.
Instead, attach a 'click' handler that :
inhibits form submission
finds the button's corresponding slider element
executes $.get(...)...
$(window).on("load", function() {
$(".formoid").on('click', 'button', function(e) { // guess; adjust as necessary to delegate button click handling to the form.
e.preventDefault(); // prevent buttons submitting the form
var $slider = $(this).prev('input'); // guess; adjust as necessary to select the appropriate slider relative to the clicked button
$.get( "http://192.168.4.49:8002/data", { n: $slider.val() }).then(function(data) {
console.log(data);
});
});
});
Without sight of the HTML, there's a couple of guesses in there so be prepared to do some debugging.
EDIT:
With sight of the HTML, the javascript becomes :
$(window).on("load", function() {
$(".btn-info").on('click', function(e) {
e.preventDefault(); // prevent form submission.
var $slider = $(this.form).closest('div').find("input.slider");
$.get( "http://192.168.4.49:8002/data", { n: $slider.val() }).then(function(data) {
console.log(data);
});
});
});
I have a script that disables links with a class "disabled"
//disabled links
$(document).ready(function() {
$(".disabled a").click(function() {
return false;
});
});
Additionally, I have a script that when the ".edit" button is clicked toggles the disabled state of the inputs in it's own form. It also does a removeClass('disabled') on any matching links in the form.
//toggle form edit
$("#edit").click(function(e) {
e.preventDefault();
$(this).closest("form").find("input").prop('disabled',false);
$(this).closest("form").find(".input-group-addon").removeClass('disabled');
$("#save").prop('disabled',false);
$("#edit").prop('disabled',true);
$(".alert").hide(400, "swing");
});
Then there is a script for adding and deleting input fields
//add input fields
$(".form-group").on('click', 'a.addInput', function() {
var original = $(this).closest(".input-group");
original.clone().insertAfter(original);
});
//remove input fields
$(".form-group").on('click', 'a.deleteInput', function() {
var original = $(this).closest(".input-group");
if($(this).closest(".form-group").children(".input-group").length > 1) {
original.remove();
}
});
HTML:
<form class="edit">
<div class="panel">
<div class="panel-heading">
<span><i class="fa fa-user" aria-hidden="true"></i> Basic Information</span>
<span class="pull-right"><input id="save" class="btn btn-success" type="submit" value="Save" disabled></span>
<span class="pull-right"><button id="edit" class="btn btn-default">Edit</button></span>
</div>
<div class="panel-body">
<div class="form-group">
<label for="email">Email</label>
<div class="input-group">
<input type="email" class="form-control" placeholder="Email" name="email" value="engelo#dingosoft.us" disabled required>
<div class="input-group-addon disabled"><span class="fa fa-plus"></span></div>
<div class="input-group-addon disabled"><span class="fa fa-minus"></span></div>
</div>
</div>
<div class="form-group">
<label for="phone">Phone</label>
<div class="input-group">
<input type="tel" class="form-control" pattern="\d{3}[\-]\d{3}[\-]\d{4}" placeholder="Format: 555-555-5555" name="phone" value="419-555-1212" disabled required>
<div class="input-group-addon disabled"><span class="fa fa-plus"></span></div>
<div class="input-group-addon disabled"><span class="fa fa-minus"></span></div>
</div>
</div>
</div>
</div>
</form>
The problem I am having is that when the class "disabled" is removed from the links, the links ('a.addInput') & ('a.deleteInput') do not function. What am I missing here?
Click handlers are attached to elements, not to selectors. So when you do this:
$(".disabled a").click(function() {
return false;
});
You are assigning that behavior to all elements which match at that moment (in this case, when the document loads). No matter what changes you make to the DOM after the fact, any elements which were matched when you invoked the above code will still have the above click handler.
One approach here could be to assign the click handler to a common unchanging parent, instead of to the elements themselves. By using .on() in this way, you can evaluate the selector dynamically when the click event happens instead of just once when the page loads. Something like this:
$(document).on("click", ".disabled a", function() {
return false;
});
Then the second selector (".disabled a") will be evaluated with each click. So if the DOM has changed such that an element no longer matches that selector, this click handler won't be used.
You need to add prevent the event.
$(".form-group").on('click', 'a.addInput', function(e) {
e.preventDefault();
var original = $(this).closest(".input-group");
original.clone().insertAfter(original);
});
//remove input fields
$(".form-group").on('click', 'a.deleteInput', function(e) {
e.preventDefault();
var original = $(this).closest(".input-group");
if($(this).closest(".form-group").children(".input-group").length > 1) {
original.remove();
}
});
or you can add a href="javascript:void(0);" to addInput and deleteInput.
I hope it will be help to achieve your goal...
I am using Net mvc4 in this project. I got a problem in my javascript where the
modal.find('modal-body input:radio[name=require_attachment][id=' + attachment+ ']').prop('checked', true);
It does not function properly. I also tried the jquery filter function:
modal.find('modal-body input:radio[name=require_attachment]').filter(['value=' + attachment+ '']).prop('checked', true);
Which has the same result, not working.
In my modal button that has data-* on with.e.g. data-attachment, I want to display it as a radio checked whether what value it return to the content of my modal.
<button type="button" class="btn btn-primary"
data-toggle="modal"
data-target="#Update_COA_Codes"
data-code="#item.code"
data-attachment="#item.require_attachment"
data-status="#item.status"
data-description="#item.description">Edit</button>
Inside my jquery script:
$('#Update_COA_Codes').on('show.bs.modal', function (event) {
var button = $(event.relatedTarget)
var attachment = button.data('attachment');
//... other code here
var modal = $(this);
modal.find('modal-body input:radio[name= require_attachment]')
.filter(['value=' + attachment + ''])
.prop('checked', true);
});
HTML modal-body
<div class="row top-buffer">
<div class="col-md-4">
<label><span class="red">*</span>Needs Attachments?</label>
</div>
<div class="col-md-4">
<input type="radio" name="require_attachment" value="true"> Yes
<input type="radio" name="require_attachment" value="false"> No
</div>
</div>
I'm not sure if this is the correct way of doing it. I'm open for any suggestions, thank you.
This is what I have right now. I'm trying to add fields to the form dynamically using jQuery add() and append() method. But I want to remove the particular added field when the remove button is clicked.
<div class="col-md-12">
<h3>Added Description Fields</h3>
<div class="col-md-12" id="descFields">
</div>
</div>
JS
$(document).ready(function() {
console.log(descFields);
$('#addDesc').click(function(e) {
var descFields = $('#descFields');
var descLabel = $('#descLabel').val();
var large = '<div class="form-group" id="descField"><div class="input-group"><input type="text" class="form-control" placeholder="Enter Value For ' + descLabel + '" /><span class="input-group-btn"><button class="btn btn-danger" id="removeDesc" type="button">Remove</button></span></div>';
descFields.add(large).appendTo(descFields);
e.preventDefault();
});
$('#removeDesc').click(function(e) {
$(this).remove();
});
});
When the user click on the #removeDesc button , the the field that is added should be removed. I cannot figure out how to achieve this.
There are many ways of doing this, but the simpler for your problem is this one:
$(document).ready(function() {
console.log(descFields);
$('#addDesc').click(function(e) {
var descFields = $('#descFields');
var descLabel = $('#descLabel').val();
var large = '<div class="form-group" id="descField"><div class="input-group"><input type="text" class="form-control" placeholder="Enter Value For ' + descLabel + '" /><span class="input-group-btn"><button class="btn btn-danger" id="removeDesc" type="button">Remove</button></span></div>';
descFields.add(large).appendTo(descFields);
e.preventDefault();
});
$('#descFields').on('click', '#removeDesc', function(e) {
$(this).parents('.form-group').remove();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="descLabel"/>
<button id="addDesc">Add Desc</button>
<div class="col-md-12">
<h3>Added Description Fields</h3>
<div class="col-md-12" id="descFields">
</div>
</div>
Your problem is in the callback to delete the rows. When the document has finished loading you are trying to attach a click event to an object #removeDesc that is still not present in the DOM because it's created on the fly when the user clicks the #addDesc.
That's why you should use:
$('#descFields').on('click', '#removeDesc', function(e) {
$(this).parents('.form-group').remove();
});
As #vijayP suggested before you can use the on() to attach an event handler to the container where you'll be adding the object that is still not present in the DOM. Then you pass in the query selector as the second parameter to filter in execution time which of its children will trigger the event and execute the callback.
My additional trick is that I'm using .parents('.form-group') to select the div containing the group and remove all of the fields that were added instead of removing only the button.
Happy coding!
Add click event for remove button like follows:
$(document).on("click","#removeDesc",function(e) {
$(this).remove();
});
I have a file upload button with auto upload enabled as follows:
<form id="fileupload" action="home/uploadprofilepic" method="POST" enctype="multipart/form-data">
<span class="btn btn-success fileinput-button">
<i class="icon-plus icon-white"></i>
<span>Add files...</span>
<input type="file" name="files">
</span>
</form>
$(document).ready(function()
{
$("input[name=files]").change(function() {
$(this).closest("form").submit();
});
});
However, I want to dynamically insert this as html. I need to add the autoupload javascript too. This is what I have so far :
$('#uploadPicId').popover({
title : 'Edit Profile Picture', //this is the top title bar of the popover. add some basic css
html: 'true', //needed to show html of course
content : '<form id="fileupload" action="home/uploadprofilepicmeta" method="POST" enctype="multipart/form-data">'+
'<span class="btn btn-success fileinput-button">'+
' <i class="icon-plus icon-white"></i>'+
' <span>Add files...</span>'+
' <input type="file" name="files">'+
'</span>'+
'</form>'
});
I need to add javascript to make the autoupload work. Is there any way to do this? I am pretty lost.
Thanks.
Change your above js to be like this instead:
$(document).ready(function()
{
$("body").on("change", "input[name=files]", function() {
$(this).closest("form").submit();
});
});
The key difference is your setting up the event listener on the entire body and if the event was launched from the given input, fire your function no matter if the html was added dynamically or not.