I'm trying to create an upload form. It's working well so far and i'm trying to sort out a couple of bugs that I dislike.
The line that I seem to be having trouble with is
$(element).find(">:first-child").attr("value", "");
When cloning the form, it clones the div and replaces the value with nothing leaving a blank form, this works well, if I were to delete that line I would get the previous form's value, so it would be nice for a blank form to show.
The issue i'm having is when you delete a form all the forms values delete, What I want is when you delete a form, leave the value alone for the other forms.
Here's a fiddle http://jsfiddle.net/d77pd/1/ or see code below
HTML
<button class="clone">Add an Image</button>
<div id="upload_image_sets">
<div id="clonedInput1" class="clonedInput">
<input type="text" id="upload_image_link_1" class="image" size="36" name="hero_options[upload_image_link_1]" value="' . $hero_options['upload_image_link_1'] . '" />
<input id="show_upload_image_link_button_1" class="button upload_images" type="button" value="Upload Image" />
<button class="remove">Remove</button>
</div>
</div>
JavaScript
function updateClonedInput(index, element) {
$(element).appendTo("#upload_image_sets").attr("id", "clonedInput" + index);
$(element).find(">:first-child").attr("id", "cs_product_menu_img_src_" + index);
$(element).find(">:first-child").attr("name", "hero_options[upload_image_link_" + index + "]");
$(element).find(">:first-child").attr("value", "");
$(element).find(">:first-child").next().attr("id", "cs_product_menu_img_src_" + index + "_button");
displayRemove();
}
function displayRemove() {
if ($('.clonedInput').length === 1) {
$('.remove').hide();
} else {
$('.remove').show();
}
}
displayRemove();
$(document).on("click", ".clone", function (e) {
e.preventDefault();
var cloneIndex = $(".clonedInput").length + 1;
var new_Input = $(this).closest('.clonedInput').length ? $(this).closest('.clonedInput').clone() : $(".clonedInput:last").clone();
updateClonedInput(cloneIndex, new_Input);
});
$(document).on("click", ".remove", function (e) {
e.preventDefault();
$(this).parents(".clonedInput").remove();
$(".clonedInput").each(function (cloneIndex, clonedElement) {
updateClonedInput(cloneIndex + 1, clonedElement);
})
});
Clone the form a few times, if you delete any form apart form the 1st one with the content, you'll notice the first form's content deletes, I want this left alone.
First approach:
call $(element).find(">:first-child").attr("value", ""); after calling updateClonedInput(cloneIndex, new_Input); from add function.
Working Demo First approach:
Second Approach:
I have modified some code. pass one more bool argument in function updateClonedInput.which will be set true when added and set false when dom is removed.This will prevent the value getting replaced on remove function:
function updateClonedInput(index, element,param) {
$(element).appendTo("#upload_image_sets").attr("id", "clonedInput" + index);
$(element).find(">:first-child").attr("id", "cs_product_menu_img_src_" + index);
$(element).find(">:first-child").attr("name", "hero_options[upload_image_link_" + index + "]");
if(param)
$(element).find(">:first-child").attr("value", "");
$(element).find(">:first-child").next().attr("id", "cs_product_menu_img_src_" + index + "_button");
displayRemove();
}
function displayRemove() {
if($('.clonedInput').length === 1) {
$('.remove').hide();
} else {
$('.remove').show();
}
}
displayRemove();
$(document).on("click", ".clone", function(e){
e.preventDefault();
var cloneIndex = $(".clonedInput").length + 1;
var new_Input = $(this).closest('.clonedInput').length ? $(this).closest('.clonedInput').clone() : $(".clonedInput:last").clone();
updateClonedInput(cloneIndex, new_Input,true);
});
$(document).on("click", ".remove", function(e){
e.preventDefault();
$(this).parents(".clonedInput").remove();
$(".clonedInput").each( function (cloneIndex, clonedElement) {
updateClonedInput(cloneIndex + 1, clonedElement,false);
})
});
Working Demo Second Approach
An alternate solution that creates a blank clone from the first element once, then uses this every time a new row is required. It also uses CSS to hide/show the Remove button based on the fact that you only need Remove buttons on all rows unless it's the only child.
Disclaimer: I have removed the id manipulation as I am unsure if you really need it. I can update if necessary.
Demo
HTML
<button class="clone">Add an Image</button>
<div id="upload_image_sets">
<div class="clonedInput">
<input type="text" class="image" size="36" name="hero_options[upload_image_link_1]" value="an initial value" />
<input class="button upload_images" type="button" value="Upload Image" />
<button class="remove">Remove</button>
</div>
</div>
CSS
.clonedInput .remove {
display:inline-block;
}
.clonedInput:only-child .remove {
display:none;
}
JavaScript
function resetForm($form) {
$form.find('input:text, input:password, input:file, select, textarea').val('');
$form.find('input:radio, input:checkbox').removeAttr('checked').removeAttr('selected');
}
var $blankClone = $('.clonedInput').clone();
resetForm($blankClone);
$(document).on('click', '.clone', function(e) {
e.preventDefault();
$blankClone.clone().appendTo('#upload_image_sets');
});
$('#upload_image_sets').on('click', '.remove', function(e) {
e.preventDefault();
$(this).closest('.clonedInput').remove();
});
resetForm() borrowed from Resetting a multi-stage form with jQuery
Related
Is there a way to change my button to "remove" if i clicked the "add to stay button"
Like when i click the add button it will load the data then it will be changed to remove button because it is already added.
and if i press the remove button how can it go back to "add to your stay" button? Here is my js code and My button code
$(document).ready(function() {
$(".addons").on("click", function(event) {
event.preventDefault();
var id = $(this).data('addon-id');
console.log(id);
if (id != '') {
$.ajax({
type: "POST",
url: "Pages/addonajax",
data: {
id: id
},
success: function(data) {
console.dir(data);
if (data) {
result = JSON.parse(data);
$("#test4>span").html(result[0]['name']);
$("#test5>span").html(result[0]['price']);
$("#test2>span").append(result[0]['price']);
} else {
$('#test1').append('no records found');
}
}
});
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h3 class="bookingroom">Total: PHP 2,750.00</h3>
<h5 class="addon-taxes2">Including Taxes & Fees</h5>
<button class="addons addon-btn trans_200">ADD TO MY STAY</button>
here's the example fiddle
https://jsfiddle.net/j501fwb8/1/
It's much harder to maintain a single element that has to do multiple things based on some criteria. Instead I highly suggest using multiple elements with a Single Responsibility.
I'd also HIGHLY recommend reading Decoupling Your HTML, CSS, and JavaScript - Philip Walton (Engineer # Google)
My example would be something like:
$(document).ready(function() {
$('.js-btn-addon').on('click', function() {
var $this = $(this);
/// do whatever
var addonId = $this.data('addon-id');
$this.addClass('is-hidden');
$('.js-btn-remove[data-addon-id="' + addonId + '"]').removeClass('is-hidden');
});
$('.js-btn-remove').on('click', function() {
var $this = $(this);
/// do whatever
var addonId = $this.data('addon-id');
$this.addClass('is-hidden');
$('.js-btn-addon[data-addon-id="' + addonId + '"]').removeClass('is-hidden');
});
});
.is-hidden {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="addons addon-btn js-btn-addon trans_200" data-addon-id = "1">ADD TO MY STAY</button>
<button class="addons addon-btn js-btn-remove is-hidden trans_200" data-addon-id = "1">Remove</button>
<br/>
<button class="addons addon-btn js-btn-addon trans_200" data-addon-id = "2">ADD TO MY STAY</button>
<button class="addons addon-btn js-btn-remove is-hidden trans_200" data-addon-id = "2">Remove</button>
<br/>
<button class="addons addon-btn js-btn-addon trans_200" data-addon-id = "3">ADD TO MY STAY</button>
<button class="addons addon-btn js-btn-remove is-hidden trans_200" data-addon-id = "3">Remove</button>
<br/>
You can change the HTML of the element to say Remove by using:
$(".addons").html('Remove');
You will have to handle the onClick method functionality accordingly though. Or you can remove the button altogether and show a different one.
You can change text after ajax call and load data, also you can add class for remove process etc.
Note: here i remove your ajax call, just put .text() on ajax success when load data
$(document).ready(function(){
$(".addons").on("click", function(event) {
var _t = $(this);
if(_t.hasClass('remove')){
_t.removeClass('remove').text('ADD TO MY STAY');
} else {
_t.addClass('remove').text('Remove');
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h3 class = "bookingroom">Total: PHP 2,750.00</h3>
<h5 class = "addon-taxes2">Including Taxes & Fees</h5>
<button class="addons addon-btn trans_200">ADD TO MY STAY</button>
You can use a class to mark the button once it has been used to add the item. Wrapping the execution code inside an if/else block lets you check whether the class exists so you can act accordingly.
See the comments in this suggested code:
$(document).ready(function() {
$(".addons").on("click", function(event) {
event.preventDefault();
var id = $(this).data('addon-id');
console.log(id);
if (id != ''){
// Tests which type of button this is (see below)
if(!this.classList.contains("isRemoveButton")){
/* Your ajax call for adding goes here */
// Changes the button text
$(this).text("REMOVE");
// Adds a class indicating which type of button this is
this.classList.add("isRemoveButton");
} else {
/* Different ajax call for removing goes here */
// Restores original button text
$(this).text("ADD TO MY STAY");
// Restores original classList state
this.classList.remove("isRemoveButton");
}
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h3 class="bookingroom">Total: PHP 2,750.00</h3>
<h5 class="addon-taxes2">Including Taxes & Fees</h5>
<button class="addons addon-btn trans_200" data-addon-id="1">ADD TO MY STAY</button>
$(document).ready(function(){
$(".addons").on("click", function(event) {
event.preventDefault();
var id = $(this).data('addon-id');
console.log(id);
if(id != '')
{
$.ajax(
{
type:"POST",
url : "Pages/addonajax",
data:{id:id},
success:function(data)
{
console.dir(data);
if (data) {
result = JSON.parse(data);
$("#test4>span").html(result[0]['name']);
$("#test5>span").html(result[0]['price']);
$("#test2>span").append(result[0]['price']);
}
else {
$('#test1').append('no records found');
}
}
});
}
$(this).hide();
$('.remove').show();
//and write a remove property which you want.
});
$('.remove').on("click", function(){
//write your property here for remove once.
$(".addons").show();
$(this).hide();
})
});
Is there a way to detect if the open button in an upload dialog is clicked using javascript or query?
UPDATE :
I will show you my sample code:
<input type = "file" name = "imgUpload" id = "trngImgUpload" style = "display : none;" multiple>
<button class="btnTools" onclick = "trngOpenVidUploadDialog()" ><img src ="#Url.Content("~/Images/video_icon.jpg")" class ="img3"/></button>
<script>
function trngOpenVidUploadDialog() {
//$('#modalMatchingTypePairType').modal('hide');
//console.log(123);
$('#trngImgUpload').trigger("click");
};
$('input[type=file]').change(function () {
if (this.files) {
alert('changed');
var path = sendVidFile($('#trngImgUpload')[0].files[0], 1);
$('#page' + currId).append('<div class = "vidDR" id = "tTool' + (toolIdCounter) + '"><div class = "del"></div><embed autostart="false" class = "vid" src="' + path + '"></embed></div>');
$('.vidDR').resizable({
containment: '#page' + currId
}).draggable({
containment: '#page' + currId
});
$(".vidDR").click(function () {
alert(1);
});
$('#trngImgUpload').val("");
$('#tTool' + toolIdCounter).contextmenu(function () {
$(this).remove();
});
toolIdCounter++;
}
});
</script>
I already tried using change event but nothing happens. I don't know whats wrong in my code.
You cannot capture the action on the 'Open' button, however you can capture the action upon changes on the file input. E.g. when the user has selected a new file using the file input.
Example as follows:
// input on change event listener
$('#file-upload').on('change', function() {
alert('File Attached: ' + $('#file-upload').val());
});
<!-- jQuery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<!-- file upload input -->
<input type="file" id="file-upload">
Hope this helps.
No! That is not possible.
But if you want to have an eye on your input type=file then you might like to use change() event on the input.
Check the snippet:
$('input[type=file]').change(function() {
if (this.files) {
$('pre').html('Files selected. (open clicked.)');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="file" name="imgUpload" id="trngImgUpload" style="display : none;" multiple>
<button class="btnTools" onclick="trngOpenVidUploadDialog()">
<img src="https://cdn3.iconfinder.com/data/icons/ilb/Perspective%20Button%20-%20Windows.png" class="img3" />
</button>
<script>
function trngOpenVidUploadDialog() {
//$('#modalMatchingTypePairType').modal('hide');
//console.log(123);
$('#trngImgUpload').trigger("click");
};
$('input[type=file]').change(function() {
if (this.files) {
alert('changed');
}
});
</script>
<script type="text/javascript">
$(document).ready(function () {
$("#submit").on("click", function () {
$(this).attr('disabled', true);
var taskid = num;
var loadnew = 1;
var guessnum = $("input[name=guessnum]:checked").val();
if (guessnum != 1 && guessnum != 2) {
alert("You could not submit an empty answer");
loadnew = 0;
location.href = "/minions/peerprediction1.php";
}
else if (loadnew == 1) {
finishedTask += 1;
}
var starttime = $("#timestart").val();
var timecost = starttime;
$.ajax({
type: "post",
url: "GameMysql.php",
data: "taskid=" + taskid + "&guessnum=" + guessnum + "&effort=" + effort + "&finishedTask=" + finishedTask + "&time=" + timecost,
success: function (data) {
}
});
});
});
</script>
<form>
<a class="button" id="submit"><span>✓</span>Submit report</a>
</form>
I want to make sure the form with same answers do not submit twice, and disable the button, but it does not truly work. For I click it twice the finished task number increased by 2
I already see the answer here Prevent double submission of forms in jQuery
and tried, but still could not make it work
Use the button element, it will provide the functionality you are after. It can be styled to look like an anchor. Less issues trying to get it working as intended across all browsers.
$("#submit").on("click",function(){
$(this).attr('disabled', true);
console.log('disabled');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="button" id="submit"> <span>✓</span> Submit report</button>
You should use a button instead of an anchor, anchors dont support the disabled attribute
<button id="submit">Submit Report</button>
I've got a table with multiple tr under tbody under a table with #attribute.
function searchEnter() {
var content = $('#search').val();
$('#search').change(function() {
if ($('#search').text() != content) {
content = $('#search').val();
$('tbody', '#attribute').each(function() {
$(this).find('tr').each(function() {
if ($('tbody>tr>h4:contains(' + content + ')')) {
$(this).show();
} else {
$(this).hide();
}
})
})
}
});
}
I wanted to change the contents of the table according to what is typed into the search box. Though I'm also not sure about how to structure the html for the search box (also using Twitter Bootstrap) or if the jquery/javascript is right. Also not sure what the action should be but I wanted it to refer to the function and not a PHP file.
<form class="well form-search fill pull-right" action="">
<input id="search" type="text" class="input-medium search-query" />
<button type="submit" class="btn" onclick="searchEnter">Search</button>
</form>
Try the following code...
$(document).ready(function () {
var search$ = $('#search')
, table$ = $('#mytable')
, content = search$.val().toLowerCase();
search$.change(function() {
if (search$.val() === content) { return; }
content = search$.val().toLowerCase();
table$.find('tr').show();
table$
.find('h4')
.filter(function (index, element) {
return $(this).text().toLowerCase().indexOf(content) === -1; })
.closest('tr')
.hide();
});
});
I also created a JSFiddle to demonstrate and a JSFiddle that works on a key up event which is even nicer.
You can use a selector just for the row, which is probably a cleaner way to start. So in your code, after you determine new text has been entered, start a block with something like:
$('tr').each(function(index){
Which will select all your rows. If you have TR elements in more than just this table, you could either specify each with a class, such as 'table_row' or specify the table itself with an id, such as 'data_table'
$('.table_row').each(function(index){ //Class based selector
$('#data_table tr').each(function(index){ //Id based selector
I have the following html code:
<h3 id="headerid"><span onclick="expandCollapse('headerid')">⇑</span>Header title</h3>
I would like to toggle between up arrow and down arrow each time the user clicks the span tag.
function expandCollapse(id) {
var arrow = $("#"+id+" span").html(); // I have tried with .text() too
if(arrow == "⇓") {
$("#"+id+" span").html("⇑");
} else {
$("#"+id+" span").html("⇓");
}
}
My function is going always the else path. If I make a javacript:alert of arrow variable I am getting the html entity represented as an arrow. How can I tell jQuery to interpret the arrow variable as a string and not as html.
When the HTML is parsed, what JQuery sees in the DOM is a UPWARDS DOUBLE ARROW ("⇑"), not the entity reference. Thus, in your Javascript code you should test for "⇑" or "\u21d1". Also, you need to change what you're switching to:
function expandCollapse(id) {
var arrow = $("#"+id+" span").html();
if(arrow == "\u21d1") {
$("#"+id+" span").html("\u21d3");
} else {
$("#"+id+" span").html("\u21d1");
}
}
If you do an alert of arrow what does it return? Does it return the exact string that you're matching against? If you are getting the actual characters '⇓' and '⇑' you may have to match it against "\u21D1" and "\u21D3".
Also, you may want to try ⇑ and ⇓ since not all browsers support those entities.
Update: here's a fully working example:
http://jsbin.com/edogop/3/edit#html,live
window.expandCollapse = function (id) {
var $arrowSpan = $("#" + id + " span"),
arrowCharCode = $arrowSpan.text().charCodeAt(0);
// 8659 is the unicode value of the html entity
if (arrowCharCode === 8659) {
$arrowSpan.html("⇑");
} else {
$arrowSpan.html("⇓");
}
// one liner:
//$("#" + id + " span").html( ($("#" + id + " span").text().charCodeAt(0) === 8659) ? "⇑" : "⇓" );
};
Use a class to signal the current state of the span.
The html could look like this
<h3 id="headerId"><span class="upArrow">⇑</span>Header title</h3>
Then in the javascript you do
$( '.upArrow, .downArrow' ).click( function( span ) {
if ( span.hasClass( 'upArrow' ) )
span.text( "⇓" );
else
span.text( "⇑" );
span.toggleClass( 'upArrow' );
span.toggleClass( 'downArrow' );
} );
This may not be the best way, but it should work. Didnt test it tough
Check out the .toggle() effect.
Here is something similar i was playing with earlier.
HTML:
<div id="inplace">
<div id="myStatic">Hello World!</div>
<div id="myEdit" style="display: none">
<input id="myNewTxt" type="text" />
<input id="myOk" type="button" value="OK" />
<input id="myX" type="button" value="X" />
</div></div>
SCRIPT:
$("#myStatic").bind("click", function(){
$("#myNewTxt").val($("#myStatic").text());
$("#myStatic,#myEdit").toggle();
});
$("#myOk").click(function(){
$("#myStatic").text($("#myNewTxt").val());
$("#myStatic,#myEdit").toggle();
});
$("#myX").click(function(){
$("#myStatic,#myEdit").toggle();
});
Maybe you're not getting an exact match because the browser is lower-casing the entity or something. Try using a carat (^) and lower-case "v" just for testing.
Edited - My first theory was plain wrong.