I have the following table
<table id="customFields" class="table table-bordered table-hover additionalMargin alignment">
<thead>
<tr>
<th colspan="2"></th>
<th>Some Title</th>
</tr>
</thead>
<tbody>
<tr>
<td><label class="subjectline" for="User1">User NOC M1</label></td>
<td id="slLabel">SLA</td>
<td id="slInput"><input type="text" name="slOptions[User][NOC M1]" class="form-control" id="User1"></td>
<td><a class="addCF" href="javascript:void(0);">+ additional user</a></td>
</tr>
</tbody>
</table>
I then have the following javascript to add additional rows
$(function() {
$(".addCF").click(function(){
$("#customFields").append('<tr><td></td><td>SL_B</td> <td><input type="text" name="slOptions[User][NOC M1]" class="form-control" id="User1"></td> <td> Remove</td></tr>');
});
$("#customFields").on('click','.remCF',function(){
$(this).parent().parent().remove();
});
});
This currently works how I want it to. However, there are a couple of things I am having issues with.
Firstly, when you first view it, you will see the label SL_A. In the cloned version, I manually set it to SL_B. All other clones then have SL_B. What I am trying to do is have SL_ followed by the next letter in the alphabet. So the third row should be SL_C. I am not too sure how I can achieve this.
My second issue relates to the name of the cloned input. At the moment, they all have the same name e.g. slOptions[User][NOC M1]
When a new row is added, the name should change to something unique, maybe using the additional letter of the alphabet above e.g. slOptions[User][NOC M1B]
Would it be possible to achieve these things?
I have set up a Fiddle for demonstration
Thanks
You could store a reference to the possible letters as well as your current letter and then within your function determine the appropriate one to use :
// Store the possible letters
var possibleLetters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
// Store the current letter
var currentLetter = 'A';
$(function() {
$(".addCF").click(function(){
// Resolve the next letter to add
var nextIndex = possibleLetters.indexOf(currentLetter) + 1;
// Update your reference
currentLetter = possibleLetters[nextIndex];
// Append it
$("#customFields").append('<tr><td></td><td>SL_' + currentLetter + '</td> <td><input type="text" name="slOptions[User][NOC M1' + currentLetter + ']"...');
// More code omitted for brevity
});
// Still more code omitted for brevity
});
You can see an example of this in action here and demonstrated below :
Here is your solution for both the issues:
See: https://jsfiddle.net/pdxgrpqz/
$(function() {
alp = "A";
$(".addCF").click(function(){
alp = (alp.substring(0,alp.length-1)+String.fromCharCode(alp.charCodeAt(alp.length-1)+1));
$("#customFields").append('<tr><td></td><td>SL_'+alp+'</td> <td><input type="text" name="slOptions[User][NOC M1'+alp+']" class="form-control" id="User1"></td> <td> Remove</td></tr>');
});
$("#customFields").on('click','.remCF',function(){
$(this).parent().parent().remove();
});
});
Related
I am trying to delete a row in html via jquery or javascript. I'm reading from a directory, but if there's no information within a row, I don't want it to be visible. Let's just assume I have two rows, and a user within the directory doesn't have a mobile number, how to remove it for them?
I have genuinely tried so many things but I must be missing something.
<tr>
<td>email: %%email%%</td>
</tr>
<tr>
<td>mobile: %%MobileNumber%%</td>
</tr>
I would assume the row would delete just for the user without a mobile number.
You need to set the text as a variable, then find the substring after the ":" which will return the %%MobileNumber%%.
If the substring is empty, then we hide it.
As you can see the third td does not have the required text, so it is hidden.
$(function() {
$('td').each(function() {
var str = $(this).text();
var sub = str.substring(
str.indexOf(':', 1) + 1
);
if (sub == '') {
// or .remove()
$(this).hide();
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<td>email: %%email%%</td>
</tr>
<tr>
<td>mobile: %%MobileNumber%%</td>
</tr>
<tr>
<td>mobile:</td>
</tr>
</tbody>
</table>
And if you only want it for the td containing "mobile:"
// find if a td starts with "mobile:" and if the substring after is empty
if ( str.match("^mobile:") && sub == '' ) {
$(this).hide();
}
Add a id to the row you want to hide, put the mobile: outside <td> then use JQuery to achieve the same
<tr id="hideIfNoData">
mobile:<td> %%MobileNumber%%</td>
</tr>
$('#hideIfNoData > tr td:empty').parent().hide()
I came across a problem whose solution has led me to post it here so others may make use of it or improvise better than me.
My Problem: I have a table of results with check boxes to select rows. The requirement was to know if I was selecting(using the checkboxes) the same set of one particular column value, if so I had to do something.
HTML code
Considering the below being my html code for the dynamic table(CFML). The tag has to be inside a loop to dynamically create the table content.
<table class="fixedTable">
<thead class="containerbg">
<tr class="listingheader">
<td>StagingID</td>
<td>BatchID</td>
<td>AuditID</td>
<td>Action</td>
<td>File Name</td>
<td>Card No</td>
<td>Card No</td>
</tr>
</thead>
<tbody>
<tr class="cur_row" >
<td>#staging_id#</td>
<td>#batch_import_job_id#</td>
<td>#audit_Id#</td>
<td>#code#</td>
<td class="file_name">#source_filename#</td>
<td>#card_number#</td>
<td class="tblResolve">
<input type="checkbox" class="checkBoxClass cb" name="resolveErrorsCheck" value="#row_no#">
</td>
</tr>
JS Code
//register the click event
$(document).ready(function() {
$(document).on('click', '.cb',enableDisableActions);
});
function enableDisableActions() {
var values = new Array();
$.each($("input[name='resolveErrorsCheck']:checked").closest('td').siblings('.file_name'),
function (){
values.push($(this).text());
});
const initial = values[0];
const result = values.filter(src => src != initial);
if(result.length){
//no duplicate file_name selected
//do something
}else{
//duplicate file_name selected
//do something
}
}
I want to add a row in the table on click of "Add" button.I am trying to accomplish this using "ng-show" directive but that row is displaying even without clicking "Add" button. Please help me with this. Here is the code -
home.html -
<table class="table">
<thead>
<tr>
<th>SNo.</th>
<th>UserId</th>
<th>Name</th>
<th>Share</th>
<th>Paid</th>
</tr>
</thead>
<tbody ng-repeat="member in members">
<tr>
<td>{{member.sNo}}</td>
<td>{{member.id}}</td>
<td>{{member.name}}</td>
<td>{{member.share}}</td>
<td>{{member.paid}}</td>
</tr>
<tr ng-show="show" class="ng-hide"> //the row which is to be added
<td><span>{{counter}}</span></td>
<td><input type="text" required ng-model="new.id"></td>
<td><input type="text" required ng-model="new.name"></td>
<td><input type="text" required ng-model="new.share"></td>
<td><input type="text" required ng-model="new.paid"></td>
</tr>
</tbody>
</table>
<div><input type="button" value="Add" ng-click="addMember()"/></div>
controller.js -
expmodule.controller('expenseForm', function($scope, sharedProperties) {
var id, expenses = {};
$scope.show = false;
$scope.members = [{
sNo: "1",
id: "abc#gmail.com",
name: "Neha",
share: 200,
paid: 400,
}, {
sNo: "2",
id: "xyz#gmail.com",
name: "Sneha",
share: 200,
paid: 400,
}];
$scope.counter = $scope.members.length++;
$scope.addMember = function () {
$scope.show = true;
return $scope.newRow = true;
}
});
Are you looking for something like this? http://plnkr.co/edit/jxXX5sWhgmYrANV7ieKM?p=preview
There are few things which are not correct in the code provided in the question.
The add row is inside ng-repeat. So a new add row will be added for each member.
Also as the show variable is inside ng-repeat it will be a child of parent scope and will be always false as per the current logic.
$scope.counter = $scope.members.length++ This will increase the array length by 1 and the new object in the array will be undefined. I guess you wanted to display the counter in the new add row. It can be simple done like this - {{members.length + 1}} in the add row rather than creating a new scope variable for this. Also this will always have the latest value when ever a new member is added.
The return statement in the addMember function has a assignment operation.
It seems to work fine (see demo below).
Of course, you should place the ng-repeat="member in members" to the <tr> not <tbody> (unless you want to have multiple tbodies).
And you should change $scope.counter = $scope.members.length++; to $scope.counter = $scope.members.length + 1;
See, also, this short demo.
I have one HTML table and I don't want the value of second column to repeat in the grid.
Here is my JavaScript:
var $addedProductCodes = [];
function getProductData(value){
$td_productCode=$("#sales-product-code").val();
var index = $.inArray($td_productCode, $addedProductCodes);
if (index >= 0) {
alert("You already added this Product");
} else {
$('#test').append("<tr><td>"+ value +"</td></tr>");
$addedProductCodes.push($td_productCode);
}
}
and Html
<tbody id="test">
<tr>
<td><input type="text" id="sales-product-code" name="cm_code[]" value="" class="sales-product-code"/> </td>
</tr>
</tbody>
Please help me out. Help is highly appreciated.
The call to
$('#test').append("<tr><td>"+ value +"</td></tr>")
should be replaced with
$('#test tr:last').after("<tr><td>" + value + "</td></tr>").
I created a JSFiddle example.
Try to use a boolean variable and use it in your conditional if. If the column is added, change the value for that variable.
I have a table with a template to insert rows, I would like to make those rows clickable so that I can edit them. How do I append an href value to the template?
My Template
<tr class="template" style="display:none;">
<td><span class="item_num"> Num </span></td>
<td><span class="item_desc"> Description </span></td>
<td><span class="item_price"> Price </span></td>
<td><span class="item_ref">ref</span></td>
</tr>
My Javascript
var newRow = $('#quote .template').clone().removeClass('template');
var quoteItem = {
number: 1,
description: myDescriptionVariable,
price: myPriceVariable,
};
template(newRow, quoteItem)
.insertAfter('#quote tr.template')
.fadeIn()
function template(row, quoteItem) {
row.find('.item_num').text(quoteItem.number);
row.find('.item_desc').text(quoteItem.description);
row.find('.item_price').text(quoteItem.price);
row.find('.item_ref').attr('href','hello');
return row;
}
You can use .data()
row.find('.item_ref').data('ref','hello');
with
<span class="item_ref" data-ref="" > Edit</span>
Then you can use it like --
console.log($('.item-ref').data('ref'));
If you just wish to store data somehow then this might be useful. Let me know if there's something more you want to do. Or what kind of data href holds and how you want to use it further.
UPDATE
From what I understand up till now is, you want to add rows dynamically that needs to editable after insertion. Each row contain some fields with certain values. And you want to save ref in item_ref class.
So here's how you can do it -
var num = 1;
var myDescriptionVariable = 111;
var myPriceVariable = 999;
// You may have some other element triggers cloning
$("button").click(function(){
var newRow = $('#quote .template').clone().removeClass('template');
var quoteItem = {
number: num,
description: 'Description ' + myDescriptionVariable, // added to distinguish items
price: myPriceVariable + ' USD', // added to distinguish items
linkToPopup: myDescriptionVariable + '_link_goes_here' // added to distinguish items
};
template(newRow, quoteItem)
.insertAfter('#quote tr.template')
.show();
});
function template(row, quoteItem) {
row.find('.item_num').text(quoteItem.number);
row.find('.item_desc').text(quoteItem.description);
row.find('.item_price').text(quoteItem.price);
// here 'href' will hold desired link_to_popup
row.find('.item_ref').data('href',quoteItem.linkToPopup);
myDescriptionVariable+= 1; // added to distinguish items
myPriceVariable+=2; // added to distinguish items
num+=1; // added to distinguish items
return row;
}
$("#quote").on("click", ".item_ref",function(){
// this will give to desired link_to_pop_val
alert($(this).data('href'));
});
I've added a button to give demonstration. This approach definitely avoid unnecessary DOM elements like hidden inputs to be added for each row. With .data() you same multiple kind of information for every field like -
$("span").data('key_1', value_1);
$("span").data('key_2', value_2);
$("span").data('key_2', value_3);
fiddle for demonstration
I think that's what you want to do and should serve the purpose. :)
There are actually a few ways to do this, one of them being:
Add some inputs to your template that are hidden
Bind a click event to the row that will hide the spans and show the input
You would of course need a save button and do something with the values, but I didn't do that part.
A condensed not fully working demo: http://plnkr.co/edit/GGM0d9wfNcoZBd5kKCwA
<tr class="template" style="display:none;">
<td><span class="item_num"> Num </span><input type="text" style="display:none" /></td>
<td><span class="item_desc"> Description </span> <input type="text" style="display:none" /></td>
<td><span class="item_price"> Price </span><input type="text" style='display:none' /></td>
<td><span class="item_ref">ref</span><input type="text" style='display:none' /></td>
</tr>
jquery:
$(document).on('click', '#quote tr', function(e) {
$('span', this).hide();
$('input', this).show();
});
$('#add').on('click', function(e) {
var newRow = $('#quote .template').clone().removeClass('template');
var quoteItem = {
number: 1,
description: 'myDescriptionVariable',
price: 100,
};
template(newRow, quoteItem)
.insertAfter('#quote tr.template')
.fadeIn()
});
function template(row, quoteItem) {
row.find('.item_num').text(quoteItem.number).next().val(quoteItem.number);
row.find('.item_desc').text(quoteItem.description).next().val(quoteItem.description);
row.find('.item_price').text(quoteItem.price).next().val(quoteItem.price);
row.find('.item_ref').attr('href','hello').next().val('hello');
return row;
}