I have a simple table with a Select button for each row that when clicked calls a PHP script to update a Session Variable with the ID of the selected Item. Here's the table:
<tr class="" id="PR9215">
<td>CODE A</td>
<td>Fresh Frust</td>
<td class="text-center"><button type="button" class="btn btn-success btn-sm">Select</button></td>
</tr>
<tr class="" id="PR9594">
<td>Oranges</td>
<td>Fresh Oranges</td>
<td class="text-center"><button type="button" class="btn btn-success btn-sm">Select</button></td>
</tr>
<tr class="" id="PR9588">
<td>MANGO</td>
<td>Fresh Mango</td>
<td class="text-center"><button type="button" class="btn btn-success btn-sm">Select</button></td>
</tr>
and here's the script that it calls:
$(document).ready(function() {
$('button.btn-success').click(function() {
var itemID = $(this).closest('tr').attr('id');
// Create a reference to $(this) here:
$this = $(this);
$.post('updateSelections.php', {
itemID: itemID,
selectionType: 'yes'
}, function(data) {
data = JSON.parse(data);
if (data.error) {
var ajaxError = (data.text);
var errorAlert = 'There was an error updating your selections - ' + ajaxError + '. Please contact Support';
$this.closest('tr').addClass("warning");
$('#alert_ajax_error').html(errorAlert);
$("#alert_ajax_error").show();
return; // stop executing this function any further
} else {
console.log('update successful - success add class to table row');
$this.closest('tr').addClass("success");
$this.closest('tr').removeClass("danger");
//$(this).closest('tr').attr('class','success');
}
}).fail(function(xhr) {
var httpStatus = (xhr.status);
var ajaxError = 'There was an error updating your selections - AJAX request error. HTTP Status: ' + httpStatus + '. Please contact Support';
console.log('ajaxError: ' + ajaxError);
$this.closest('tr').addClass("warning");
$('#alert_ajax_error').html(ajaxError);
$("#alert_ajax_error").show();
});
});
});
This is working when it comes to making the initial selection - the table row is coloured green to indicate it has been selected. I now need to extend this so that when the Select button is clicked a 2nd time it then removes the green table row highlighting and returns it to it's original state.
Now sure how to go about extending the script to achieve this.
Check below logic for that:
$('button.btn-success').click(function() {
if ($this.closest('tr').hasClass("first_click")) {
$this.closest('tr').removeClass();
//$( "tr" ).removeClass();
return false;
}else{
$this.closest('tr').addClass("first_click");
}
You chould achieve that by using a boolean to track the state of the button. Then check the state of the button before taking action.
Ps. You can chain your addClass() and removeClass() methods.
var buttonSelected = false;
if(buttonSelected){
$this.closest('tr').addClass("success").removeClass("danger");
buttonSelected = true;
} else {
$this.closest('tr').removeClass("success").addClass("danger");
buttonSelected = false;
}
Related
function getAnnoDetailsForTeacher(){
var tcounter = 1;
$.ajax({
url:'<%=contextPath%>/show/announcementsForTeacher',
headers: {
'Authorization':'${sessionScope.token}'
},
type:'GET',
data: {
'loginId' : '${loginId}'
},
success:function(data){
$('#annoTable tbody').empty();
for(var i=0; i<data.length;i++)
{
var aid = data[i].id;
var date = data[i].date;
var subject = data[i].subject;
var details = data[i].details;
var status = data[i].status;
$('#annoTable tbody').append('<tr data-toggle="modal" data-target="#viewTAnnoModal"><td id="tCounter'+aid+'"><strong>'+tcounter+
'</strong></td><td id="tDate'+aid+'"><strong>'+date+
'</strong></td><td id="tSubject'+aid+'"><strong>'+ subject +
'</strong></td><td id="tDetails'+aid+'" class="cell expand-small-on-hover"><strong>'+ details +
'</strong></td><td><button type="button" id="tAnnoBtn'+aid+'" onclick="viewTAnno()" class="viewbtn" data-toggle="modal" data-target="#" style="display:block;">View</button>'+
'</td>'+
......+
'</tr>');
tcounter += 1;
}
$('#tnoti').empty();
$('#tnoti').css('display','block');
$('#tnoti').append(tcounter-1);
},
error:function(e){
console.log(e)
}
});
return tcounter;
}
my goal is to unbold a row when clicked on view btn (where id is dynamic:i d="tAnnoBtn'+aid+'") inside the jQuery.
Here is the unbold jQuery
$('#tAnnoForm').on('click', '.viewbtn', function() {
const fooTCounter = document.getElementById("tCounter");
fooTCounter.innerHTML = fooTCounter
.innerHTML
.replace(/<strong>/g, "")
.replace(/<\/strong>/g, "");
const fooTDate = document.getElementById("tDate");
fooTDate.innerHTML = fooTDate
.innerHTML
.replace(/<strong>/g, "")
.replace(/<\/strong>/g, "");
const fooTSubject = document.getElementById("tSubject");
fooTSubject.innerHTML = fooTSubject
.innerHTML
.replace(/<strong>/g, "")
.replace(/<\/strong>/g, "");
const fooTDetails = document.getElementById("tDetails");
fooTDetails.innerHTML = fooTDetails
.innerHTML
.replace(/<strong>/g, "")
.replace(/<\/strong>/g, "");
});
problem is every element is created dynamically with dynamic id (td cells and buttons)
so how can i input the dynamic ids inside the unbold jQuery??
like in jQuery it should go like document.getElementById("tCounter1") where 1 is concatenated with tCounter.
also in '.viewbtn', it should go like '#tAnnoBtn1' where 1 is dynamically concatenated with tAnnoBtn.
check this viewTAnno(aid) function
function viewTAnno(aid)
{
var viewed;
$.ajax({
url:'<%=contextPath%>/show/annoViewedForTeacher',
headers: {
'Authorization':'${sessionScope.token}'
},
type:'GET',
data: {
'loginId' : '${loginId}',
'anno_id' : aid
},
success:function(data){
//alert("New Announcement Added Successsfully");
console.log(data);
viewed =data;
$('#tAnnoTable').on('click', '.viewbtn', function() {
if(viewed==0){
//get closest tr > loop through tds
$(this).closest("tr").find("td:not(:last)").each(function() {
//replace text
$(this).text($(this).text().replace(/<strong>/g, "")
.replace(/<\/strong>/g, ""))
//tcounter=tcounter-1;
$.ajax({
url:'<%=contextPath%>/show/annoViewedForTeacher',
headers: {
'Authorization':'${sessionScope.token}'
},
type:'POST',
data: {
'loginId' : '${loginId}',
'anno_id' : aid
},
success:function(data){
console.log(data);
},
error:function(e){
console.log(e)
}
});
})
}
})
},
error:function(e){
console.log(e)
}
});
return viewed;
}
i want to unbold a particular row upon clicking on view so that it also changes in db just like gmail inbox. how can i do that?
You can simply iterate through your tds where view button has been clicked then using $(this).text(..) replace <strong> tag with ''
Demo Code :
$('#annoTable').on('click', '.viewbtn', function() {
//get closest tr > loop through tds
$(this).closest("tr").find("td:not(:last)").each(function() {
//replace text
$(this).text($(this).text().replace(/<strong>/g, "")
.replace(/<\/strong>/g, ""))
})
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="annoTable">
<tbody>
<tr data-toggle="modal" data-target="#viewTAnnoModal">
<td id="tCounter1"><strong>1</strong></td>
<td id="tDate1"><strong>0.005997001499250375</strong></td>
<td id="tSubject1"><strong>Abc</strong></td>
<td id="tDetails1" class="cell expand-small-on-hover"><strong>Somwthing..</strong></td>
<td><button type="button" id="tAnnoBtn1" onclick="viewTAnno()" class="viewbtn" data-toggle="modal" data-target="#" style="display:block;">View</button></td>
</tr>
<tr data-toggle="modal" data-target="#viewTAnnoModal">
<td id="tCounter2"><strong>2</strong></td>
<td id="tDate2"><strong>0.005997001499250375</strong></td>
<td id="tSubject2"><strong>Abc</strong></td>
<td id="tDetails2" class="cell expand-small-on-hover"><strong>Somwthing..</strong></td>
<td><button type="button" id="tAnnoBtn2" onclick="viewTAnno()" class="viewbtn" data-toggle="modal" data-target="#" style="display:block;">View</button></td>
</tr>
</tbody>
</table>
On table row Edit button click, a form modal is opened.
I am picking that row current values so they can be default values of that form fields when modal is opened.
As I am new in jQuery I can not figure out how to pass that values in other method.
My func:
var $fruitForm = $('#edit-form')
$('.fruit_edit').on('click', function(event) {
// Get the data-id value of the modal link.
var id = $(this).data('fruit_id');
// Set the hidden input field with the id.
$('#fruit_id').val(id);
var $row = $(this).closest('tr');
// Here I am finding row value on click
var tableFruitName = $("a[data-fruit_id="+id+"]").closest("tr").find('.tableFruitName').text()
event.preventDefault();
});
// Listen for submit instead of click.
$fruitForm.on('submit', function(event) {
event.preventDefault();
// Get the values from the form.
var $form = $(this);
var id = $form.find('input[name="fruit_id"]').val();
I want for the value from upper 'onclick' to be defined in from input here
var fruitName = $('#fruitName').val(tableFruitName);
$.ajax({
type: 'PATCH',
url: '/fruit/edit',
data: JSON.stringify({
'id' : id,
'fruitName' : fruitName
}),
processData: false,
contentType: 'application/json-patch+json',
success: function () {
$("#fruit-table").load(location.href + " #fruit-table");
$('#editFruit').modal('hide');
},
error: function (xhr, status, error) {
var ErrorMessage = JSON.parse(xhr.responseText);
}
});
});
Explanation of my workflow is within comments. I don't know how to pass catched value in other method where the input is defined.
<tr>
<td class="text-center"> {{ fruit.id }} </td>
<td class="text-center tableFruitName"> {{fruit.fruitName is empty ? "N/A" : fruit.startDate }}</td>
<td class="td-actions text-center">
<a href data-toggle="modal" data-target="#editFruit" data-fruit_id="{{ fruit.id }}" class="btn btn-warning fruit_edit">
<i class="fa fa-fw fa-pencil"></i>
</a>
</td>
</tr>
The code below has a select with three options. When you choose one of the options and click add the option is added to the table. If the user were try to choose the same option I need an alert or modal window to appear saying "Duplicates not allowed."
Anyone have an idea how to accomplish that?
$("select#keys").change(function(){
$("#add-user-code").click(function(){
var selectedKey = $("#keys").val();
$("#3rd-row").show();
$('#example').html('<span class="lbl">' + selectedKey + ' </span>');
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
<body>
<select class="select-duc" id="keys">
<option></option>
<option>Allergies</option>
<option>Animals</option>
<option>Coughing</option>
</select>
<button type="button" id="add-user-code" class="btn btn-default pull-right" data-dismiss="modal">Add User Code</button>
<div class="col-sm-6 reset">
<div class="details-page-container two">
<h5>User Codes</h5>
<div class="table-container">
<table>
<tbody><tr>
<th><strong>Code</strong></th>
<th><strong>Description</strong></th>
<th><strong>Domain</strong></th>
<th><strong>Start Date</strong></th>
<th><strong>End Date</strong></th>
<th><strong>Delete</strong></th>
</tr>
<tr>
<td>01</td>
<td>MINNEAPOLIS</td>
<td>MN</td>
<td>11/01/2019</td>
<td></td>
<td>Delete</td>
</tr>
<tr>
<td>02</td>
<td>MINNEAPOLIS</td>
<td>MN</td>
<td>11/01/2019</td>
<td></td>
<td>Delete</td>
</tr>
<tr id="3rd-row" class="hideIT">
<td id="example"></td>
<td>MINNEAPOLIS</td>
<td>MN</td>
<td>11/01/2019</td>
<td>12/01/2019</td>
<td><a data-toggle="modal" data-target="#myModal2" href="#">Delete</a></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>
Define an array, and
In your $("#add-user-code").click function:
Check if the value(which user selected) is already present in the array or not(To show the alert),
push the index/value to the array after adding it to your table(So that next time the condition fails and alert would show up).
Also, don't forget to remove items from the array whenever needed(User Starts again or item is removed from the table)/
I'd better just hide the duplicate option when the one is selected and show them back when/if its unselected, for better user experience.
Otherwise, you can make an array of selected values and loop through it when an option selected, something like this:
var selectedOptions = [];
$("select#keys").change(function(){
$("#add-user-code").click(function(){
var selectedKey = $("#keys").val();
if($.inArray(selectedKey, selectedOptions)) {
alert ("Duplicate values are not allowed");
} else {
selectedOptions.push(selectedKey);
}
$("#3rd-row").show();
$('#example').html('<span class="lbl">' + selectedKey + ' </span>');
});
});
Still, it has to be reset when options are unselected, I don't see multiple options in your snippet, though
You can create a function to return all the values to check whether the value the user wants to insert does not exits already
function getTableValues() {
return $('tr').find('td:first-child').map(function() {
return $( this ).text();
}).get();
}
$("select#keys").change(function(){
$("#add-user-code").click(function(){
var selectedKey = $("#keys").val();
if(!getTableValues().includes(selectedKey)) {
$("#3rd-row").show();
$('#example').html('<span class="lbl">' + selectedKey + ' </span>');
}
else {
alert('Duplicate not allowed');
}
});
I don't think you need the .click() bind inside of the .change() bind. Also, rather than using an alert, you could just make that option not available.
$("#add-user-code").click(function(){
$('#example').html('<span class="lbl">' + $('#keys option:selected').hide().text() + ' </span>');
$("#3rd-row").show();
$('#keys option:eq(0)').prop('selected', 'selected'); //set the select back to the blank option
});
Then if you click delete:
$('a').click(function() {
let example = $('#example .lbl').text().trim();
$('#keys option').filter(function() {return this.textContent === example; }).show();
$("#3rd-row").hide();
});
You shouldn't need an array or function to achieve what you're after.
https://jsfiddle.net/g9523ysz/
If you really need an alert:
$("#add-user-code").click(function(){
let option = $('#keys option:selected').text();
if (option) {
if ($('td').filter(function() { return $(this).find('.lbl').text().trim() === option; }).length){
alert('Duplicates not allowed.');
} else {
$("#3rd-row").show();
$('#example').html('<span class="lbl">' + option + ' </span>');
}
}
});
I would suggest that if you can, use a more specific class for the span, like lbl-user-code. Then rather than having to check every single td you could:
if ($('.lbl-user-code').filter(function() { return this.textContent === option; }).length) { ... }
https://jsfiddle.net/9us4d08j/
I want to be able to email content such as a div that is in my webpage using the php mail function and possible putting it on the so called "Thank Your, Your Email Sent" page. However, I'm running into some issues. I am following this Email Div Content, Email div text content using PHP mail function, and GET entire div with its elements and send it with php mail function questions that has already been posted as a guide but it doesn't seem to be working for me. I want to send via email and show up on the "Thank Your, Your Email Sent" page within the message. Anything I'm doing wrong?
HTML Table that I want to send over is:
<div id="add_items_content" style="width:100%;">
<center>
<table id="add_item_here" style="width:98%;">
<tbody>
<tr><td>Item</td><td>Years</td><td>Quantity</td><td>Training Hours</td><td>Total Item Cost</td></tr>
</tbody>
</table>
</center>
<center>
<table id="add_totals_here" style="width:98%;">
<tbody>
<tr><td cospan="3"> </td><td> </td><td> </td></tr>
</tbody>
</table>
</center>
</div>
<script>
$(document).ready(function(){
$('table[id^=add_item_here]').hide();
$('table[id^=add_totals_here]').hide();
$('div[id^=office_submit]').hide();
$('div[id^=show_form]').hide();
//First obtaining indexes for each checkbox that is checked
$('input[name=item_chk]').change(function(){
var index = this.id.replace('item_chk','');
if($(this).is(':checked')){
AddNewItem(index);
}else{
RemoveItem(index);
}
CalculateTotals();
});
function AddNewItem(index){
// Get hidden variables to use for calculation and tables.
var item = $('#item_chk'+index).parent().text().trim();
var itemdescr = $('#itemdescr'+index).val();
var traininghrs = parseInt($('#traininghrs'+index).val());
var qty = parseInt($('#qty'+index).val());
var yrs = parseInt($('#yrs'+index).val());
var item_cost = 0;
// Calculating item cost for just that one checkbox
item_cost+=parseInt($('#servicefee'+index).val());
item_cost*=parseInt($('#yrs'+index).val());
item_cost+=parseInt($('#licensefee'+index).val());
item_cost*=parseInt($('#qty'+index).val());
var traininghrs = parseInt($('#traininghrs'+index).val());
//Display each item that is checked into a table
$('#add_item_here tr:last').after('<tr id="row_id'+index + '"><td style=\"width:35%;\">' + itemdescr +'</td><td style=\"width:15%;\" >' + yrs +'</td><td style=\"width:16%;\">' + qty +'</td><td style=\"width:18%;\">' + traininghrs + '</td><td style=\"width:16%;\">$'+ item_cost + '</td></tr>');
}
function RemoveItem(index){
$('table#add_item_here tr#row_id'+index).remove();
}
function CalculateTotals(){
var total_cost = 0;
var total_training = 0;
$('input:checkbox:checked').each(function(){
var index = this.id.replace('item_chk','');
var item_cost = 0;
// Calculating item cost for just that one checkbox
item_cost+=parseInt($('#servicefee'+index).val());
item_cost*=parseInt($('#yrs'+index).val());
item_cost+=parseInt($('#licensefee'+index).val());
item_cost*=parseInt($('#qty'+index).val());
var traininghrs = parseInt($('#traininghrs'+index).val());
total_cost +=item_cost;
total_training +=traininghrs;
});
if(total_cost > 0 || total_training > 0) {
$('#add_totals_here tr:last').children().remove();
$('#add_totals_here tr:last').after('<tr ><td colspan="3" style=\"width:66%;\">TOTALS:</td><td style=\"width:18%;\">' + total_training + '</td><td style=\"width:16%;\">$'+ total_cost + '</td></tr>');
$('#add_item_here').show();
$('#add_totals_here').show();
$('#office_submit').show();
}else{
$('table[id^=add_item_here]').hide();
$('table[id^=add_totals_here]').hide();
$('div[id^=office_submit]').hide();
}
}
$("input[name='office_submit']").click(function () {
$('#show_form').css('display', ($(this).val() === 'Yes') ? 'block':'none');
});
// Quantity change, if someone changes the quantity
$('select[name=qty]').change(function(){
var index = this.id.replace('qty','');
if($("#item_chk"+index).is(':checked')){
RemoveItem(index);
AddNewItem(index);
CalculateTotals();
}
});
// Years change, if someone changes the years
$('select[name=yrs]').change(function(){
var index = this.id.replace('yrs','');
if($("#item_chk"+index).is(':checked')){
RemoveItem(index);
AddNewItem(index);
CalculateTotals();
}
});
})
</script>
Trial Number 1; So far I have tried:
<script>
function mail_content() {
var tablesContent = document.getElementById("add_items_content").innerHTML;
$.post('send_form.email.php',{content:tablecontent},function(data) {
});
}
</script>
Using script I have added to the send_form_email.php:
<?php
$txt = $_POST['content'];
mail($to,$subject,$message,$txt,$headers);
mail($from,$subject2,$message2,$txt,$headers2);
?>
Trial Number 2: I even tried storing it into a hidden field:
<input name="data" id="data" type="hidden" value=""></input>
<script type="text/javascript">
$(document).ready(function(){
$("#price_quote").submit(function() { //notice submit event
$("#my_hidden_field").val($("#add_items_content").html()); //notice html function instead of text();
});
});
</script>
And then the send_form_email.php I put it in that message see if it even shows up.
$txt = $_POST['data'];
$message = "Content: ".$txt."\n";
mail($to,$subject,$message,$txt,$headers);
mail($from,$subject2,$message2,$txt,$headers2);
Trial Number 3: Even tried Ajax
<script>
function mail_content(){
var html = $('#add_items_content').html();
$.ajax(function{
type="POST",
url:"send_form_email.php",
data:"data="+html,
success:function(response){
$('#add_items_content').show().html("email sent");
}
});
}
</script>
What am I missing or doing wrong? Why doesn't the div / tables show up or display?
You really should check your JS console for errors:
var tablesContent = document.getElementById("add_items_content").innerHTML;
^---note the "sC"
$.post('send_form.email.php',{content:tablecontent},function(data) {
^--note the c
JS vars are case sensitive, and will NOT magically correct typos for you.
And then there's this:
<input name="data" id="data" type="hidden" value=""></input>
^---id 'data'
$("#my_hidden_field").val($("#add_items_content").html());
^--- completely DIFFERENT ID
I have a page with a list of items. Items have several actions assigned to them. (see screenshot).
One may choose to directly click on an icon next to each row or check a checkbox on the left hand side.
The issue is that after clicking an item OR checking a checkbox of several items and then clicking an action there is a lag (a second or so). Imagine having 100 rows or more.
How can I improve the performance of my javascript code?
sample HTML of one row:
<tr id="1960AGIMMGMRTB20314" class="">
<td class="checkbox">
<input type="checkbox" value="1960" class="checkbox">
</td>
<td class="">
<p>GD009000246</p>
</td>
<td class="platform">PCGames</td>
<td class="cat">Up</td>
<td class="platform">
<div class="pbar"><span class="progresslabel"></span></div>
</td>
<td class="date">10.48.1.236</td>
<td class="options clearfix">
<a title="" class="iconMagnifier tip" href="/Packages/View/AGI-MM-GM-RTB-2.0.3.1.4">View</a>
<a title="" href="/Packages/PackageActionAsyncDeletePackage" data-ajax-type="DeletePackage" data-ajax-packageid="AGI-MM-GM-RTB-2.0.3.1.4" data-ajax-machineid="1960" class="iconDelete action tip">Remove</a>
</td>
</tr>
javascript:
// action invoker
$("a.action:not(.remove)").click(function (e) { // .remove => do not execute on download tasks page
var obj = $(this);
e.preventDefault();
if (!$(this).hasClass('disablelink')) {
var machineIds = getSelection(obj);
if (machineIds.length > 0) {
packageAction(obj.attr("data-ajax-packageid"), machineIds, obj.attr("data-ajax-type"));
};
}
$(".checkall").attr("checked", false);
});
function getSelection(obj) {
var selected = new Array();
if (obj.attr('data-ajax-machineId')) {
selected.push(obj.attr('data-ajax-machineId'));
} else {
$("input.checkbox:checkbox:checked:not(.checkall)").each(function () {
var machineId = $(this).val();
var packageId = obj.attr("data-ajax-packageid");
var operation = obj.attr("data-ajax-type");
if ($("#" + machineId + packageId.removeSpecialChars().toUpperCase() + "").size() != 0) {
var row = $("#" + machineId + packageId.removeSpecialChars().toUpperCase() + "");
row.has("a[data-ajax-type=" + operation + "]:not(.hide)").length ? selected.push(machineId) : $(this).attr('checked', false);
}
});
}
return selected;
}
// download, install, uninstall, remove, activate, deactivate package
function packageAction(packageId, machineIds, operationType) {
.....// to implement - not needed
Querying objects out of the DOM is slow. The best thing to do is hold all of your data in javascript objects, do all the calculations and stuff you want, THEN update the DOM all at once. Ember.js and some other javascript libraries/tools have bound data which is cool, meaning you change an attribute in the javascript object and it automatically updates the DOM!