Trying to achieve functionality in the linked picture.
The table grows as users click on the add button. I'm trying to replace the text inside the first column of the newly added td with the length of the table. I'm new to jQuery and not sure how to do that. Any help would be great.
It will be easier to answer you with your code but you can know the added row number with $('#yourTBodyID > tr').length
Have a look to this code :
HTML
<table>
<thead>
<tr>
<th>Zone ID</th>
<th>Zone Description</th>
<th><button onclick="addRow();">Add Row</button></th>
</tr>
</thead>
<tbody id="tableBody">
</tbody>
</table>
JS :
function addRow() {
var rowNum = $('#tableBody > tr').length + 1;
$('#tableBody').append('<tr>'
+ '<td>' + rowNum + '</td>'
+ '<td><input type="text"/></td>'
+ '<td><button>Disable</button></td>'
);
}
jsFiddle
Hope it helps ;)
You'll face a few more problems, more than just showing the number on the recently created tr. As you don't write down any code, I'm note sure at which point of the development you are, or which functionalities have you created already. I'll briefly try to explain how to achieve it, just showing you the path.
Add button should find in the DOM a valid <tr>to .clone(). It could be a "seen tr" or a template one. In the first situation you should clean the information in the input.
Once you have saved that cloned node into a variable, you should prepare it for insertion.
Counting the <tr> lines (it'd help if you have a classname on them) and assign the .length() to the first <td> using .text()
Changing name attribute on the input inside the second <td>tag. Otherwise when the form is sent to the server, you will loose every input with the same name which prior the last one.
On the last <td> tag you have a disabled button. It won't have any attached event on your brand new element. You can attach it here, or if you prefer, you can add the event on the very beginning using something like $('table').on('click','.disable-button',function(e){}). Doing that instead of $(.disable-button).click() will assure you that elements with this class created after DOM .ready()fires up will get this event.
I hope it helped you
Related
The answer to the following question,
var counter = 0;
$("button").click(function() {
$("h2").append("<p class='test'>click me " + (++counter) + "</p>")
});
$("h2").on("click", "p.test", function(){
alert($(this).text());
});
I have a dynamically generated calendar that when you click on an individual day, instead of opening a new web page, it swaps the calendar for the events of the day. The events are listed in a table and I want to be able to click on a row and and have it trigger a function which uses location.assign(). So each row looks like the following,
<tr id="message-7">
New page in calendar loads and creates,
<tr id="message-132">
Clicking does not trigger the function. In the example from the other question, it accesses the text of the element in order to make the element unique as opposed to giving the element a unique id # as in my situation.
Am I approaching the problem the wrong way? Could I add something like a "title=132" tag that I could reference?
Ideally try not to make too much meaning out of the ID. Instead use data as shown here.
So instead of
<tr id="message-7">
use
<tr id="1234567" data-message="7">
Then in code you can address the data as:
var messageVal = $("#1234567").data("message")
And if you need to add a generic click event then you might want to use a dummy css class assignment for all appropriate TR's:
<tr id="1234567" data-message="7" class="messageRow">
so that you can write
$(".messageRow").on("click", function(event){
event.preventDefault()
var messageVal = $(this).data("message")
This is useful in the case where only some TR's will contain clickable content - just don't assign the class to the others.
Using jQuery I'm doing a call to my server which returns some json. I then have a callback defined using .done to create a callback, which doesn't seem to behave sequentially.
I've got a div in my html (<div id="properties"></div>), and I try to fill that div with a table of results:
request.done(function(data){
if (data['result'].length == 0) {
$("#properties").html("<h3>No results were found..</h3>");
} else {
$("#properties").html("<table><thead><tr><th>Status</th><th>Title</th></tr></thead><tbody>");
data['result'].forEach(function(prop){
$("#properties").append("<tr>");
$("#properties").append("<td>prop.status</td>");
$("#properties").append("<td>prop.title</td></tr>");
});
$("#properties").append("</tbody></table>");
}
});
The result I get is this:
<div id="properties">
<table class="table table-hover"><thead><tr><th>Status</th><th>Title</th></tr></thead><tbody></tbody></table>
<tr></tr>
<td>prop.status</td>
<td>prop.title</td>
</div>
I know that .done is only called once the ajax call returns something, but withint that call, it should behave sequentially right? There are 2 things I really really don't understand here:
Why do the table row and data get written after the </table> tag?
And why on earth does the <tr></tr> gets written before the <td> tags, even though the last </tr> is appended together with the last <td> in the lastappend()` in the foreach loop?
So I also tried appending the whole table row in one go:
$("#properties").append("<tr><td>prop.status</td><td>prop.title</td></tr>");
This works a bit better, but still only produces this:
<div id="properties">
<table class="table table-hover"><thead><tr><th>Status</th><th>Title</th></tr></thead><tbody></tbody></table>
<tr><td>prop.status</td><td>prop.title</td></tr>
</div>
Javascript has puzzled me before, but this really blows my mind. Any tips are welcome!
What you are seeing here are tags closing out on you, because those elements are getting created in whole on append/html. In order to get the behavior you're expecting build in a string, say something more like this:
request.done(function(data){
if (data['result'].length == 0) {
$("#properties").html("<h3>No results were found..</h3>");
} else {
var propertiesTableHTML = "<table><thead><tr><th>Status</th><th>Title</th></tr></thead><tbody>";
data['result'].forEach(function(prop){
propertiesTableHTML += "<tr>";
propertiesTableHTML += "<td>" + prop.status + "</td>";
propertiesTableHTML += "<td>" + prop.title + "</td>";
propertiesTableHTML += "</tr>";
});
propertiesTableHTML += "</tbody></table>";
$("#properties").html(propertiesTableHTML);
}
});
You are expecting .html() and .append() to work like document.write() but they don't. When used with HTML, they expect proper HTML. Broken HTML (for example missing end tags) is corrected which leads to the unexpected behavior. This part of your code for example:
$("#properties")
.html("<table><thead><tr><th>Status</th><th>Title</th></tr></thead><tbody>");
Produces the following result:
<table>
<thead>
<tr>
<th>Status</th>
<th>Title</th>
</tr>
</thead>
<tbody>
</tbody><!-- tag closed automatically -->
</table><!-- tag closed automatically -->
Along the same lines, this code:
$("#properties").append("<tr>");
$("#properties").append("<td>prop.status</td>");
$("#properties").append("<td>prop.title</td></tr>");
Produces the following result:
...
</table>
<tr></tr><!-- tag closed automatically -->
<td>prop.status</td>
<td>prop.title</td><!-- </tr> ignored -->
One possible solution is to revise your code like this:
$("#properties").html("<table><thead><tr><th>Status</th><th>Title</th></tr></thead><tbody></tbody></table>");
data['result'].forEach(function(prop){
var $tr = $("<tr></tr>").appendTo("#properties > table > tbody");
$("<td></td>").text(prop.status).appendTo($tr);
$("<td></td>").text(prop.title).appendTo($tr);
});
You can't add tags to the DOM, you can only add elements. When you try to add a <table> tag, it will add a complete table element. When you try to add the ending tag, it will be ignored (or possibly cause an error, depending on the browser) because it's not code that can be parsed into an element.
Rewrite the code to add elements instead of tags:
$("#properties").html("<table><thead><tr><th>Status</th><th>Title</th></tr></thead><tbody></tbody></table>");
var tbody = $("#propertis tbody");
data['result'].forEach(function(prop){
var row = $("<tr>");
row.append($("<td>").text(prop.status));
row.append($("<td>").text(prop.title));
tbody.append(row);
});
By creating table cells as elements and use the text method to set the content, you avoid the problem with any special characters that would need HTML encoding (e.g. <. >, &) to mess up the HTML code.
My problem has left me trying many solutions and stumped for a while now. My problem is exactly this:
There's a HTML table and a button on a page. Upon pressing the button, a script will run, copying the contents of the cells in the table into a text box. Here is the code for the table:
<table>
<tr><th></th><th>Category1</th></tr>
<tr><td>1.</td><td class="rule">Rule1</td></tr>
<tr><td>2.</td><td class="rule">Rule2</td></tr>
<tr><th></th><th>Category2</th></tr>
<tr><td>3.</td><td class="rule">Rule3</td></tr>
<tr><td>4.</td><td class="rule">Rule4</td></tr>
<tr><th></th><th>Category3</th></tr>
<tr><td>5.</td><td class="rule">Rule5 </td></tr>
<tr><td>6.</td><td class="rule">Rule6</td></tr>
<tr><td>7.</td><td class="rule">Rule7</td></tr>
<tr><th></th><th>Category4</th></tr>
<tr><td>8.</td><td class="rule">Rule8</td></tr>
</table>
My first thoughts were to write a script that iterated through the table and copied the contents of each cell (and creating a new line after every 2 cells). I realized very quickly, that I had no idea how to do that. After some searching I was able to come up with a script that clones the table, and it actually works quite well. This code is here:
$("button").click(function () {
$("table").clone().appendTo(".copy");
});
There are two problems that arise from using this method, however. I want plaintext, not a carbon copy of the table. The other problem is that this method only works when I clone the table into a div, it will not work when I try to clone it to a text box.
I've searched for a while for something similar to this and can only find solutions to copying single rows or cells. I had originally started there but couldn't figure out a way to write a loop that started at the beginning of the table and iterated through the entire thing, copying the contents as it iterated row by row (and creating a new line with each new row that it encountered). The loop would obviously end when there were no more rows to iterate through... This all sounds so simple to do, I know there must be a way.
Please Note: This script will be applied to a Site.Master Page so the script must be able to run for a plethora of tables. All of the tables follow the same structure shown above, but some will have more rows than others.
Any ideas? Any help is greatly appreciated.
You could use the .each() JQuery Method:
JS
function cloneTableContents()
{
$("table tr").each(function()
{
$(this).children().each(function()
{
$(".copy").append($(this).text());
});
});
}
JS For All Tables On Page In Order
function cloneTableContents()
{
$("table").each(function()
{
$(this).find("tr").each(function()
{
$(this).children().each(function()
{
$(".copy").append($(this).text()+" ");
});
});
});
}
HTML
<table id="mine">
<tr><th></th>
<th>Category1</th>
</tr>
<tr><td>1.</td><td class="rule">Rule1</td></tr>
<tr><td>2.</td><td class="rule">Rule2</td></tr>
<tr>
<th></th>
<th>Category2</th>
</tr>
<tr><td>3.</td><td class="rule">Rule3</td></tr>
<tr><td>4.</td><td class="rule">Rule4</td></tr>
<tr>
<th></th><th>Category3</th>
</tr>
<tr><td>5.</td><td class="rule">Rule5 </td></tr>
<tr><td>6.</td><td class="rule">Rule6</td></tr>
<tr><td>7.</td><td class="rule">Rule7</td></tr>
<tr>
<th></th><th>Category4</th>
</tr>
<tr><td>8.</td><td class="rule">Rule8</td></tr>
</table>
<textarea class="copy"></textarea>
<button onclick="cloneTableContents('mine','.copy');">Copy</button>
Working Example:
http://casewarecomputers.com:8088/soHelp.html
IE is giving me an error (Error: Invalid target element for this operation.) when trying to execute this code:
var d1 = document.getElementById( name + '-body');
d1.insertAdjacentHTML('beforeend', html );
Without having to put the entire function in here, the point of it is to add some text inputs dynamically when a user clicks a button. I did a bit of searching and found many statements that insertAdjacentHTML doesn't work right within tables, which is what I need it to do.
Is there a workaround for this?
Edit: Here is the html I am trying to insert. If you want I can post the generated html from Chrome also.
"<tr id=\"node-" + counter + "\">
<td>
<textarea onclick=\"Common.removeInstructions(id)\" name=\"on\" id=\"action-" + counter + "\" wrap=\"soft\" cols=\"35\" rows=\"4\" style=\"resize: none; overflow: hidden;\">
Please limit responses to 150 characters. Blank fields will be ignored.
</textarea>
</td>
<td>
<input classname=\"TextInput\" id=\"actionDate-" + counter + "\" newline=\"1\" style=\"width: 100px;\" class=\"TextInput\" assemblers=\"jaba.ui.input.TextInput\" jaba-pagerowindex=\"1\"/>
</td>
</tr>"
IE often doesn't allow you to dynamically add table rows/cells.
Pre-creating the rows/cells which you want added with display:none, then changing their innerHTML and display when needed is an useful workaround for that.
Adding FabrÃcio Matté as an answer so I can accept it.
If you'd show us the generated HTML and what you're trying to do, it'd be much easier to reply. Anyway, I've had a problem inserting rows/cells in a table on IE before, my solution was pre-creating the rows/cells with display:none when the table is created, then changing the 's innerHTML together with their display.
I have created a small application written in XHTML, JavaScript/JQuery and PHP.
The PHP reads and writes to a small SQLite database.
How would I go about inserting <td> cells into a pre-scripted table. The cells would need to be configured using some information from my database. For example, below are two cells with their data retrieved from my database:
Cell One
Starts: 120px;
Finishes: 180px;
Background: Blue;
Cell Two
Starts: 240px;
Finishes: 300px;
Background: Green;
On my table row, it is 500px in width. How would I insert the cells above into the row. In this example, the first cell would start 120px into the row and have a width of 180px. The second cell would start 240px into the row and have a width of 300px.
I just can't seem to work out a way of doing this, any ideas would be very helpful.
Thank you for any input, all is appreciated.
Hunter.
forgive me if this answer is too simplistic but it sounds like you just need to loop through a variable that stores the cells that need to be inserted into a table that already exists.
Then you can dynamically generate the styles of whatever tag you need to edit such as style="<?= background-color:green; ?>"
I'm not exactly sure what you mean by starts and finishes. If your trying do placements then it will be a lot more complicated and you need some sort of position element in your db that can be referenced. But if you just mean height and width then you can also add these elements to the dynamically generate style
Not entirely sure what you're asking, but I'll give it a shot.
var c1 = 'stuff, stuff stuff.' // Your data for cell1
, c2 = 'more stuff.' // Data for cell2
$('table tr:first').append(
// Ugly multiline string
'<td width=120></td>
<td width=60 style="background-color: blue">' + c + '</td>
<td width=60></td>
<td width=60 style="background-color: green">' + c2 + '</td>
<td width=200></td>' // Filler
);
When building the tables, Put html comment tags with parameters so you can scan pre created output and insert where and how you like.
<table>
<!--|str1|2|60|100|--><tr>
<!--|str1td1|--><td width='60'>content row 1</td><!--|etr1td1|-->
<!--|str1td2|--><td width='100'>content row 2</td><!--|etr1td2|-->
</tr><!--|etr1|-->
<!--|str2|2|60|100|--><tr>
<!--|str2td1|--><td width='60'>content row 1</td><!--|etr2td1|-->
<!--|str2td2|--><td width='100'>content row 2</td><!--|etr2td2|-->
</tr><!--|etr2|-->
</table>
Then if you want to go back into your output and insert stuff, just strrpos (php) to the tr you want to edit and gather between comment tags, pharse the pipe seperated fields, you know the first is the id tag, the second is how many td's and the next two can be added to figure the width so far. Then find the tag for the end of the td you want to insert into after. Do your insert (include new tags!). Then go back and re comment the tr info you just read and include new row and information.
After all done and ready to output, go back and remove and the comment tag stuff from output. Or leave it in if you are lazy, it is just html comment stuff that will not be seen but kinda heavy on the text size side.
Sounds more complicated than it is, kind hard to explain but you should know exactly what i mean and the process can be more elaborate or simple to meet your needs.
If this is close to what you need, then hope this helps or ask me more, if not then i am sleepy so please excuse me.