This is the base of a table that I have.
It could have many more rows and the last number in the name attribute indicates the row number. I want get the name attribute of any of the inputs inside the last row. It does not matter which input is because then I will split the string and only keep the last number.
How can I achieve this?
Thanks!
<table id="tableNames">
<tbody>
<tr>
<td>
<input type="text" name="contact1_1"/>
<input type="text" name="contact2_1"/>
<input type="text" name="contact3_1"/>
</td>
<td>
<input type="text" name="phone1_1"/>
<input type="text" name="phone2_1"/>
<input type="text" name="phone3_1"/>
</td>
</tr>
</tbody>
</table>
:last selector with split() and pop()
console.log( $("#tableNames tbody tr:last input:last").attr("name").split("_").pop())
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="tableNames">
<tbody>
<tr>
<td>
<input type="text" name="contact1_1"/>
<input type="text" name="contact2_1"/>
<input type="text" name="contact3_1"/>
</td>
<td>
<input type="text" name="phone1_1"/>
<input type="text" name="phone2_1"/>
<input type="text" name="phone3_1"/>
</td>
</tr>
</tbody>
</table>
$(document).ready(function() {
alert($("#tableNames").find("tr:last").find("input").attr("name"));
})
Or a shorter version:
$(document).ready(function() {
alert($("#tableNames tr:last input").attr("name"));
})
Here is a fiddle of this getting the name of the input on the last row:
https://jsfiddle.net/L7k2w6Ls/2/
$('#tableNames tr:last input').map(function(){return $(this).attr('name');}).get();
The other answers will do exactly what you are asking. In an attempt to be more generally helpful, I want to make sure this isn't an XY problem.
It sounds like you are effectively encoding some application data in the name of your input elements. It may be worth asking if that is what you actually want to do. Often times I have data related to an element, and the best place to put that for jQuery to find is in the elements data array. Even if the server actually needs that same piece of information in the name, putting the data somewhere more easily accessible to javascript can help minimize bugs in the future and simplify your application. So I might suggest a completely different solution like this:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="tableNames">
<tbody>
<tr>
<td>
<input type="text" name="contact1" data-more="1"/>
<input type="text" name="contact2" data-more="1"/>
<input type="text" name="contact3" data-more="1"/>
</td>
<td>
<input type="text" name="phone1" data-more="1"/>
<input type="text" name="phone2" data-more="1"/>
<input type="text" name="phone3" data-more="1"/>
</td>
</tr>
</tbody>
</table>
$( function(){
$("#tableNames tr:last input").each( function(){
var input = $(this);
console.log( input.attr( 'name' ) + ' has data ' + input.data( 'more' ) );
});
} );
Related
Following is the code to generate a table with input fields and buttons.
<table id="myTable">
<tr>
<td><input type="text" class="text1"></td>
<td><input type="text" class="text2"></td>
<td><input type="text" class="text3"></td>
<td class="up"><button type="button" class="append_up">Up</button></td>
<td class="down"><button type="button" class="append_down">Down</button></td>
</tr>
<tr>
<td><input type="text" class="text1"></td>
<td><input type="text" class="text2"></td>
<td><input type="text" class="text3"></td>
<td class="up"><button type="button" class="append_up">Up</button></td>
<td class="down"><button type="button" class="append_down">Down</button></td>
</tr>
<tr>
<td><input type="text" class="text1"></td>
<td><input type="text" class="text2"></td>
<td><input type="text" class="text3"></td>
<td class="up"><button type="button" class="append_up">Up</button></td>
<td class="down"><button type="button" class="append_down">Down</button></td>
</tr>
</table>
I want to be able to append a similar row anywhere in the table using JavaScript. If I click the Up button I want a similar row to be appended just above that row, and if clicked down, just below that row. And finally I want to be able to get all the data from the table in the order as created by clicking the buttons. Please help.
After receiving few answers this is what i did.
$(document).ready(function(){
var html = '<tr><td><input type="text" class="text1"></td><td><input type="text" class="text2"></td><td><input type="text" class="text3"></td><td><button type="button" class="append_up">Up</button></td><td><button type="button" class="append_down">Down</button></td></tr>';
$('.append_up').click(function(e) {
e.preventDefault();
$(this).closest('tr').before(html);
});
$('.append_down').click(function(e) {
e.preventDefault();
$(this).closest('tr').after(html);
});
});
I was able to append rows but clicking on the button from the new row does nothing.
As I failed to find a duplicate containing an answer to my liking (as in... works even in IE6... and doesn't need a trunk-load of work-arounds like copying events etc..) I'll post mine in pure javascript here (explained in comments):
<table id="tst_table"><tbody>
<tr>
<td><input type="text" class="text1"></td>
<td><input type="text" class="text2"></td>
<td><input type="text" class="text3"></td>
<td><button type="button" class="append_up">Up</button></td>
<td><button type="button" class="append_down">Down</button></td>
</tr>
<tr>
<td><input type="text" class="text1"></td>
<td><input type="text" class="text2"></td>
<td><input type="text" class="text3"></td>
<td><button type="button" class="append_up">Up</button></td>
<td><button type="button" class="append_down">Down</button></td>
</tr>
<tr>
<td><input type="text" class="text1"></td>
<td><input type="text" class="text2"></td>
<td><input type="text" class="text3"></td>
<td><button type="button" class="append_up">Up</button></td>
<td><button type="button" class="append_down">Down</button></td>
</tr>
</tbody></table>
<script> //hook it any way you like, this is just for focussing on the example..
document.getElementById('tst_table').onclick=(function(){
function _addRow(trg, dir){ //private function to add row in any direction
var row= trg.parentNode.parentNode //get correct row
, clone= row.cloneNode(true) //deep-clone that row
, inpts= clone.getElementsByTagName('input') //get inputs in clone
, L= inpts.length //total no of inputs in clone
; //end var
for(;L--; inpts[L].value=inpts[L].defaultValue); //reset inputs to defaultValue
row.parentNode.insertBefore(clone, dir ? row.nextSibling : row); //add row
row=clone=inpts=L=null; //cleanup
}
return function(e){ //return uniform click-handler for the whole table
var trg=e ? e.target : window.event.srcElement; // get source element
if(trg.nodeType === 3) trg = trg.parentNode; // fix Safari bug
var clsnam=' '+trg.className+' '; // get className, allow multiple classnames
if(~clsnam.indexOf( ' append_up ' )) return _addRow(trg, 0);
if(~clsnam.indexOf(' append_down ')) return _addRow(trg, 1);
};
})();
</script>
One of the nice things is that this sets just one eventhandler for the table instead of a (new) function for every button.
In the table's onclick-handler (the returned function) you can handle any click-event that originated in the table: in this example it handles buttons whose class contains 'append_up' or 'append_down' (so you can also set other styling classes like <button class="red_rounded_button append_up">).
In some way's this is simpler/unobtrusive because it deep-copies a row (instead of needing some html-string, which (without jQuery) has some problems with tables in older browsers, notably IE).
Also note that this technique does not touch javascript's global name-space.
EDIT: improved class-name cache so we don't get a misfire on (for example): alt_append_up and added early return.
Finally, to answer your last request: since this uses proper DOM-methods, every time you get the table's rows (and containing elements like inputs) you'll get them in order they are in the DOM (just what you wanted). Nice!
$('.append_up').click(function(){
var str='<tr><td><input type="text" class="text1" value="vikram"></td><td><input type="text" class="text2"></td><td><input type="text" class="text3"></td><td><button type="button" class="append_up">Up</button></td><td><button type="button" class="append_down">Down</button></td></tr>';
$(this).parent().parent().before(str);
});
$('.append_down').click(function(){
var str='<tr><td><input type="text" class="text1" value="sharma"></td><td><input type="text" class="text2"></td><td><input type="text" class="text3"></td><td><button type="button" class="append_up">Up</button></td><td><button type="button" class="append_down">Down</button></td></tr>';
$(this).parent().parent().after(str);
});
var html = '<tr><td><input type="text" class="text1"></td><td><input type="text" class="text2"></td><td><input type="text" class="text3"></td><td><button type="button" class="append_up">Up</button></td><td><button type="button" class="append_down">Down</button></td></tr>';
$(document).ready(function(){
$(document.body).on('click','.append_up',addAbove);
$(document.body).on('click','.append_down',addBelow);
});
function addAbove()
{
$(this).closest('tr').before(html);
}
function addBelow()
{
$(this).closest('tr').after(html);
}
you are dynamically appending the elements and hence you should use and on method to bind the click. hope this helps.
Try something like this:
$(document).ready(function(){
var html = '<tr><td><input type="text" class="text1"></td><td><input type="text" class="text2"></td><td><input type="text" class="text3"></td><td><button type="button" class="append_up">Up</button></td><td><button type="button" class="append_down">Down</button></td></tr>';
$('.append_up').click(function(e) {
e.preventDefault();
$(this).closest('tr').before(html);
});
$('.append_down').click(function(e) {
e.preventDefault();
$(this).closest('tr').after(html);
});
});
There is a fiddle here: http://jsfiddle.net/vyfhrfvf/
I have a tag system implemented into my website for three different categories. I set it up for a twitter account so I have "Keywords", "Mentions" and "Hashtags". What I need is that when a user inserts a tag in the text input for Mentions for it to prepend a "#" symbol before the text entered. The same goes for Hashtags except for the "#" symbol. I have put together a demo of what I have so far. Any help will be greatly appreciated.
JSFIDDLE
<div id="wrapper">
<table>
<tr>
<th></th>
<td id="keyword-filter">
<h5>Keywords</h5>
<input type="text" id="keywordInput">
<br>
Include:
<input type="radio" name="keywordInclude" checked="true">Any
<input type="radio" name="keywordInclude">All
<b>Keywords</b>
</td>
</tr>
<tr>
<th></th>
<td id="mention-filter">
<h5>Mentions</h5>
<input type="text" id="mentionInput">
<br>
Include:
<input type="radio" name="mentionInclude" checked="true">Any
<input type="radio" name="mentionInclude">All
<b>Mentions</b>
</td>
</tr>
<tr>
<th></th>
<td id="tag-filter">
<h5>Hashtags</h5>
<input type="text" id="hashtagInput">
<br>
Include:
<input type="radio" name="tagsInclude" checked="true">Any
<input type="radio" name="tagsInclude">All
<b>Hashtags</b>
</td>
</tr>
</table>
According to the documentation and source code of the tagsInput plugin you can use the onAddTag callback to fire whenever a tag is added. You can grab the tag element which is just created in the DOM and prepend the text with a #.
See the updated jsfiddle for a working example. You also need to check if the user didn't enter a # already.
$('#mentionInput').tagsInput({
'defaultText':'add name',
'onAddTag':function(tag) {
var span = $('#mentionInput_tagsinput .tag span').last();
if (span.text().substring(0, 1) != '#') {
span.text('#' + span.text());
}
}
});
I have a table insite form where I want to be able to duplicate a group of fields as many times as I want. And I also want to have field id, name, and label's for attributes of those new group of fields increase by 1. I've tried this so far with jQuery, and got it to at least duplicate the group of fields, but remove doesn't work. And I'm not sure how to do +1 for each of those 3 attributes. I appreciate any help I can get.
<tr>
<td>name<span class="description"></span>
</td>
<td>
<input type="text" name="type_1" id="type_11" class="regular-text" />
</td>
</tr>
<tr>
<td>pic<span class="description"></span>
</td>
<td>
<input type="file" name="logo_1" id="logo_1" />
</td>
</tr>
<div class="formRowRepeatingSection">Add New
</div>
<div class="repeatingSection"></div>
JS - Jquery
$(function(){
$('#addPro').click(function() {
$('#repeatingSection').append('<tr><td>name<span class="description"></span></td><td><input type="text" name="pro_1'+i+'[]" id="pro_1'+i+'[] class="regular-text" /></td></tr><tr><td>pic<span class="description"></span></td><td><input type="file" name="pro_pic_1'+i+'[]" id="pro_pic_1'+i+'[]" /></td></tr>');
});
});
i need repate in '#repeatingSection' this code html when click '#addPro'
edit:-
$(function(){
$('#addPro').click(function() {
$('#repeatingSection').append('<tr><td>name<span class="description"></span></td><td><input type="text" name="pro_1'+i+'[]" id="pro_1'+i+'[]" class="regular-text" /></td></tr><tr><td>pic<span class="description"></span></td><td><input type="file" name="pro_pic_1'+i+'[]" id="pro_pic_1'+i+'[]" /></td></tr>');
});
});
i will edit now .... but i need when click in #addPro insert new row
HTML
<table>
<tr>
<td>name<span class="description"></span>
</td>
<td>
<input type="text" name="type_1" id="type_11" class="regular-text" />
</td>
</tr>
<tr>
<td>pic<span class="description"></span>
</td>
<td>
<input type="file" name="logo_1" id="logo_1" />
</td>
</tr>
</table>
<div class="formRowRepeatingSection">Add New
</div>
<div id="repeatingSection"></div>
jQuery
$(document).ready(function () {
var i = 0;
$('#addPro').click(function () {
console.log(i);
i++;
$('#repeatingSection').append('<tr><td>name<span class="description"></span></td><td><input type="text" name="pro_1' + i + '[]" id="pro_1' + i + '[]" class="regular-text" /></td></tr><tr><td>pic<span class="description"></span></td><td><input type="file" name="pro_pic_1' + i + '[]" id="pro_pic_1' + i + '[]" /></td></tr>');
});
});
Demo here
What I changed:
replaced in html: class to ID in the <a> element and in the div to append to #repeatingSection
added " closing the ID here id="pro_1'+i+'[] class="regular-text"
added var i = 0; outside the click function and i++; inside it.
I added also opening and closing tags for <table>,maybe you have them somewhere else in the code you didn't posted. I added just to have correct html markup.
hi i have a table records which looks like this:
<form>
<table>
<tr>
<td>
<input type="text" name="txtTitle" class="txtTitle" value="Title 1" />
<input type="button" name="btnSaveTitle" class="btnSaveTitle" value="Save />
</td>
</tr>
<tr>
<td>
<input type="text" name="txtTitle" class="txtTitle" value="Title 2" />
<input type="button" name="btnSaveTitle" class="btnSaveTitle" value="Save />
</td>
</tr>
.....
</table>
</form>
i like to save the records for the particular row in ajax POST. my current method is to get selected button clicked, and traverse backwards to get txtTitle value. for example:
$(".btnSaveTitle").click(function(){
var selected = $(this);
var txtTitle = selected.prev().val();
});
but if i were to have additional html tags around txtTitle, i would have to modify my javascript just to get txtTitle value. for example, if my html becomes this:
<tr>
<td>
<div class="textboxStyle">
<input type="text" name="txtTitle" class="txtTitle" value="Title 2" />
</div>
<div class="btnStyle">
<input type="button" name="btnSaveTitle" class="btnSaveTitle" value="Save />
</div>
</td>
</tr>
then i have to modify my javascript to be this:
$(".btnSaveTitle").click(function(){
var selected = $(this);
var txtTitle = selected.parent().prev().children("input:first").val();
});
this is very hard to debug and error prone. how can i overcome this?
var txtTitle = selected.closest("td").find(".txtTitle");
Jsfiddle: http://jsfiddle.net/8JRmk/
Well you know that they will always be in the same td (or possibly tr), so you can use
selected.closest("td").find("[type=text]")
If that's still no good for you, you can give the button and input the same attribute like data-id or something
<input type="text" data-id="1"
<input type="button" data-id="1"
txtTitle = $("[type=text][data-id=" + selected.data('id') + "]");
I am trying to create a dynamic table with each row containing two date fields. I am using Jquery datepicker. For some reason only the first row is showing in the date picker calendar. Other dynamically created fields are not showing the calendar. I should mention that the first row is by default in place when this page is loaded. Only from the second line it's dynamically created. All solutions say I should reinitialize the .datepicker(). I did and it's not working. I tried changing names and Ids still no solution. Is there something I am missing here. Below is the code used for this purpose.
Yes I know there are several questions related to this here in this site. But some how I couldn't find a solution to this as they aren't working for me.
Javascript:
$("#addurl").click(function(){
var idValue = "input[id='breachCount']";
var counter = $(idValue).val();
var trValue = $("#rowPH"+counter).html();
var countNew = parseInt(counter)+1;
$(idValue).val(countNew);
var newFile = "<tr id='rowPH"+countNew+"'>"+trValue+"</tr>";
$(newFile).insertBefore("#addLink");
var nameTemp, actNm;
var dcounter=0;
$('#rowPH'+countNew+' input').each(function(){
nameTemp = $(this).attr("name");
if(nameTemp){
actNm = nameTemp.substring(nameTemp.indexOf("."));
$(this).attr("name","breachList["+countNew+"]"+actNm+countNew);
}
});
$('.datepicker').each(function(i) {
this.id = 'datepicker' + i;
}).datepicker();
});
Html:
<table>.....
<tr id="rowPH0">
<td>
<input type="checkbox" checked="checked">
</td>
<td>
<input class="text_box_2 div_center" type="text" value="" name="breachList[0].breachText">
</td>
<td>
<input id="datepicker0" class="datepicker date_txt hasDatepicker" type="text" value="" name="breachList[0].activationDt"><img class="calendar" src="assets/images/calendar_icon.png">
</td>
<td>
<input id="datepicker1" class="datepicker date_txt hasDatepicker" type="text" value="" name="breachList[0].deactivationDt">
<input type="checkbox" name="breachList[0].deactiveNa" checked="checked">
</td>
<td>
<input class="text_box_2" type="text" value="" name="breachList[0].note">
</td>
</tr>
</tbody>
<tbody>
<tr id="rowPH1">
<td>
<input type="checkbox" checked="checked">
</td>
<td>
<input class="text_box_2 div_center" type="text" value="" name="breachList[1].breachText1">
</td>
<td>
<input id="datepicker2" class="datepicker date_txt hasDatepicker" type="text" value="" name="breachList[1].activationDt1">
<img class="calendar" src="assets/images/calendar_icon.png">
</td>
<td>
<input id="datepicker3" class="datepicker date_txt hasDatepicker" type="text" value="" name="breachList[1].deactivationDt1">
<input type="checkbox" name="breachList[1].deactiveNa1" checked="checked">
</td>
<td>
</tr>
<tr id="addLink">
<td colspan="5" >+ Add another row
<input type="hidden" id="breachCount" value="${fn:length(auditStandardBreachsForm.breachList)-1}"/>
</td></tr>
...</table>
Not necessary to assign unique ids to each field. Datepicker can identify each uniquely. Try putting following code in your js.
$('.datepicker').each(function(){
$(this).datepicker();
});
I've used it for multiple fields.
*Update*
I read your js code and it's messed up. All you want to do is (from what you've stated) is when user clicks on Add Another Link , you want to add a new row in table and want them to be able to work with jQuery datepicker. Right?
The reason above code is not working is, in this case, text fields are being added dynamically . While datepciker gets initialized on onDocumentReady. So datepicker can not attach itself to these newly created form fields. A solution is to attach datepicker while creating new fields itself.
Here's a working model I prepared for what you want to achieve. See demo on http://jsfiddle.net/phazorrise/bRE6q/
here is my updated code
Javascript
Modified at the bottom of the above javascript
var nameTemp, actNm;
$('#rowPH'+countNew+' input').each(function(){
nameTemp = $(this).attr("name");
if(nameTemp){
actNm = nameTemp.substring(nameTemp.indexOf("."));
$(this).attr("name","breachList["+countNew+"]"+actNm);
$(this).attr("id","breachList["+countNew+"]"+actNm+countNew); //added
}
});
$('.datepicker').each(function(i) {
$(this).removeClass('hasDatepicker').datepicker(); //changed ref: phazor comment
});