Adding Nested form rows PHP/Javascript - php

Overview:
I am creating a dynamic web invoicing system,
Most of the page are textareas and I have used tables to nest as they will post data into seperate tables after the form is submitted. When the "Nested" Add a Row is selected, it should add a row inside with form field that has details on which row and which position so it can be gathered in a for loop when it is posted.
Image:
Problem:
Adding a row in the circled area does not add it in the last row, It add's it as it is in the image. Additionally it only works on the first item, the second add a row does not even register a click.
I am unsure how to get the variables to create the form name[][] in this particular index size and the parents index number (located in javascript line 2-3)
Relevent Code:
Javascript
$("#additemrow").click(function(){
var currentListItem = $(this).length;
var currentJobItem = $(this).parents('#items').index('#items');
currentListItem++;
$("#listitem:last").after(/*Blank Form Row*/);
bind();
})
PHP
<table id="items">
<tr class="item-row"><td>/*form elements*/</td></tr>
<tr class="list-row">
<td colspan=5>
<table class="itemlist">
<?php
$itemCount = 0;
foreach($jobListItem as $items) {
foreach($items as $item) {
if($problem['item_id'] == $item['item_id']) {
?>
<tr id="listitem">
<td class="list-item">
<div class="delete-wpr">
<textarea class="item" name="item[/*A PARENT ITEM NUMBER*/][<?php echo $itemCount;?>][item]"></textarea>
<a class="deleteitem" href="javascript:;" title="Remove row">X</a>
</div>
</td>
</tr>
<?php
}
$itemCount++;
}
}
?>
<tr>
<td colspan="5"><a id="additemrow" href="javascript:;" title="Add a row">Add a row</a></td>
</tr>
</table>
//NEXT ITEMLIST GOES HERE
</table>
EDIT: Foreach Loop is just used to get variables from a array.
Please let me know if you need more details or bits of code as im not sure if I have given enough information.

Regarding the problem where your row gets insertet at the top:
Like Bertrand Lefort already said: in JQuery you can append nodes to the end of another (parent) node by calling parent_node.append(child_node) (more information here)
You can also add elements before/after another element by calling another_element.before(element) / another_element.after(element) or (be aware of reversed syntax!) element.insertBefore(another_element) / element.insertAfter(another_element)
Regarding the problem where only the first "add a row" registers a click:
You're selecting by id. Id's are (or should be) unique, so when you call $("#additemrow").click(function(){ ... }) the onClick-function will only be attached to the first element that matches the given id (as far as I remember).
If you want to attach the same onClick-function to multiple elements use class instead. However, if you do so, you got to make sure you insert the new element relative to the clicked element (eg. by using .parent(), .siblings() or similar functions).
Regarding your problem #2, I don't really know what you're trying to do, but this is what I noticed:
currentListItem and currentJobItem seem to be unused in their scope, since you are declaring them as local variables but not using them
.parents('#items').index('#items') is redundant because .parents('#items') already selects only the parent elements that match '#items'. If you want to get the index of the matched element, use index() (without parameters, see jquery API for more)
Some other notes:
If you have the time (and the need of a clean project) I recommend using template engines like Smarty to separate your logic from the output. This improves the readability of your code and also makes it easier to find/eliminate bugs.
I hope this helped a little bit. If you provide more information on what you're trying to do and what doesn't work as you expext, I will try to provide further help and update my answer.

You could add an id to the parent html element, then in your click handler:
$("#additemrow").click(function(){
$("#parent").append(/*Blank Form Row*/);
})

Related

how to remove(not delete) dynamically generated table elements?

Hi I have looped and echoed out this result
echo '<tr><td id="'.$row['productID'].'"><img height="150px" width="130px"
src="products/'.$row['image_url'].'"></td><td>'.$row['name'].'</td>
<td>'.$row['price'].'</td></tr>';
The above resulted in a table full of data, now How do i remove a specific row, I want to remove it not delete from the table, as in a shopping cart where you remove the item but not delete it from the table. How would you use javascript or any other in this case?
Thank you very much.
Make a extra field in table.
Default value for the active Row is 1....
deactive row is value is 0
When retrieve the data form table used the where function for the Active rows
Please you don't need JQuery for something simple like this..
document.getElementById('id_off_product').style.display = 'none';
You don't need jQuery to do this, although you can use it if you want.
If you want to hide the product:
document.getElementById('product_id').style.display = 'none';
With jQuery:
$('#product_id').hide();
If you want to show it again:
document.getElementById('product_id').style.display = '';
With jQuery:
$('#product_id').show();
If you want to completely remove the product:
document.getElementById('product_id').remove();
With jQuery:
$('#product_id').remove();
Also, you should probably put the id on the actual table row (tr) instead of on the table cell (td).
skimberk1's answer is most comprehensive. Here is an example that would allow a button on the row that would remove the row (parent/tr).
<table id="test">
<tr>
<td>one</td><td>two</td><td id="test" onclick="removerow(this);">remove</td>
</tr>
</table>
function removerow(e) {
e.parentNode.remove();
}
http://jsfiddle.net/FqbHW/19/embedded/result/
If completely removing is not desirable, then hiding or otherwise indicating it's inactive is possible... I would in that case also point you to Taveer's answer. You would need to track which rows are active/inactive. If you need additional details on this please comment.
Give it a id and using jQuery do as
$('yourid').hide(); // to hide
$('yourid').show(); // to show
if u use jquery, u have to know the id of product to remove
$('td#productId').parent().hide();

alert gives [object NodeList]

I have a function in Javascript & jQuery .
dynamic_link = $j('#dynamic_link_add_btn').parent().parent().parent().parent()
.children('tbody').html();
function add_tier (t,html_handle){
alert(html_handle);
$j(t).parent().parent().parent().parent()
.children('tbody').append(html_handle);
}
It is called by onclick="add_tier(this,dynamic_link)":
<td class="a-right" colspan="4">
<button class="scalable add" type="button" id="dynamic_link_add_btn" onclick="add_tier(this,dynamic_link)">
<span>Add Extra Links</span>
</button>
</td>
What is it?
Handles dynamic form fields (appending HTML, to be more precise).
How should it work?
It should add the HTML it gets from the dynamic_link variable to the designated place.
It works fine with other rows.
Rows have multiple input boxes and checkboxes.
What it does right now?
The alert gives out [object NodeList].
What I have tried till now?
Iterated the NodeList. It doesn't return the HTML (I am not sure that it even does that task).
NOTE: The form is really a big one. There are many dynamic_link type variables which stores HTML. I have also compared character by character between the working and the not working LOC.
Edit: $j is just the $ of jQuery. It's been defined with jQuery.noConflict.
first of all you can use jQuery instaed of $j . that way you don't need to add jQuery.noConflict
then another point
instead of using
dynamic_link = $j('#dynamic_link_add_btn').parent().parent().parent().parent().children('tbody').html();
very easily you can use
dynamic_link = jQuery('#dynamic_link_add_btn').parents('.class_name').children('tbody').html();
class_name is the class name of your parent element that you want to select.
then you can try
jQuery('#dynamic_link_add_btn').live('click',function(){
var dynamic_link = jQuery(this).parents('.class_name').children('tbody').html();
alert(dynamic_link);
jQuery(this).parents('.class_name').children('tbody').append(dynamic_link);
});
to give a specific solution , you should post your HTML

Embedded php within JQuery within HTML table within PHP ... won't fire

Specific questions are at the end of this (very long) pre-amble. Sorry, I tried to make it as short as poss. (took over an hour to write the question).
A .php file uses a (php) function to read rows in a SQL db and dynamically create an HTML table.
For each row, the SQL data is returned via $book['id'], $book['code'], $book['description'], etc.
The $book['code'] is a two-char alpha-numeric ID, eg. B7 or DW
In the HTML for each row is a <td></td> containing an anchor tag with an onclick= event that runs a JQuery script (to show/hide elements for that row).
Suppose a couple or rows were clicked and a couple of elements were hidden by the embedded JQuery script (which is working correctly, by the way)
When the user views a different page and then returns to this one, hidden elements (that were hidden by the JQuery script) are no longer hidden.
I wish to preserve a string of $book['code'] values for each clicked row an d, upon return to the first page, parse that string to reset the hidden elements.
<?php
function render_row_from_mysql() {
$output .= '
...create header row...
foreach ($books as $book)
{
create table row cells 1, 2, 3, 4
after cell 4:
<td>
<a id="addToShelf.php" onclick="
jQuery.ajax(\'./addToShelf.php?id='.$book['id'].'ats'.'\');
jQuery(addToShelfLink'.$book['id'].')[0].style.display = \'none\';
jQuery(rfs'.$book['id'].')[0].style.display = \'block\';
jQuery(mt'.$book['id'].')[0].style.display = \'none\';
jQuery(grn'.$book['id'].')[0].style.display = \'block\';
return false;
">
add to bookshelf
</a>
</td></tr>' ;
}
}
Questions:
Why doesn't the JQuery code above, which works correctly, need closing parentheses?
What is the syntax for creating/updating a var, in the anchor tag, that would preserve the cumulative clicked-row data? I ask because my many attempts all break the code.
Should the var be initialized at the top of the function, before the foreach loop?
I tried using PHP to create/update a cookie by inserting the following code after "return false;" (see below). The below php code does create a cookie when pasted into a separate script for testing.) The php code does not fire. Why?
The answers are:
1) Still not sure, just syntax.
2) As mentioned in Q4, I had been entering code AFTER the "return false;" statement, which is what concludes the onclick event. Therefore, any code placed after "return false;" would not fire as part of the onclick event... and there was nothing else to MAKE it fire.
3) Irrelevant
4a.) The above code is created within a PHP code block -- one cannot create a PHP code block inside JQuery inside HTML that is being created by (i.e. already inside) PHP.
4b.) Further to answer (2), my alert() tests would not fire because they followed the "return false;" statement,
4c.) Any new PHP code must be moved out of the HTML and placed back with the rest of the PHP, such as above the function(render_row_from_mysql){}.
It is now "back to the drawing board" to figure out how to preserve the "clicked items" data between when a user leaves this page and when he returns back to it. At this time, I suspect that will be some kind of a FORM $POST event, but having never done one before I'm not sure what that will look like.
I completely agree with Bjorn comment from 22 minutes ago. You need to remove all that onclick code and add a identifying class to your anchor tags. You sure also make sure that each HTML element has a unique id, it is a W3C validation requirement. If each book's id is unique system wide I would use that, see Example below:
<?php
function render_row_from_mysql() {
$output .= '
foreach ($books as $book)
{
//create table row cells 1, 2, 3, 4
//after cell 4:
<td>
<a id="'.$book['id'].'" class="addToShelf">
add to bookshelf
</a>
</td></tr>' ;
}
}
Add this javascript code to the bottom of your HTML code.
jQuery(document).ready(function($) {
// bind event to all anchor tags with class addToShelf
$('a.addToShelf').click(function() {
var book_id = this.id;
$.ajax('addToShelf.php?id='+book_id, function() {
// execute code after the ajax request is complete...
$('addToShelfLink'+book_id).hide();
$('rfs'+book_id).show();
$('mt'+book_id).hide();
$('grn'+book_id).show();
});
return false;
});
});

How can I add a jQuery Dialog for each row in an HTML table

I am generating an HTML table with PHP (using the codeigniter framework) and I'm trying to add a link that will open a jquery dialog with some information that is specific to that row. Sort of a 'More Info' type link that simply opens the dialog.
When I add the dialog div to that row and encapsulate the required information in it, it breaks the table (cannot have a div in the table).
Plus, it seems I would need to add an unknown amount of jquery dialog functions declared... I'm assuming some sort of a function is needed and the ID of the element that opens the dialog as well as the ID for the dialog would be passed to the function. But, it seems there should be something built into jQuery for something like this.
Am I missing something, and if so does anybody have any tips to get me pointed in the right direction?
Embed the information as metadata on the row, a la…
<tr data-foo="additional data here" data-bar="even more data">…</tr>
And in your javascript, a little magic called .live():
$('#your_table .show_dialog').live('click', function(){
var data_for_dialog = {
foo: $(this).closest('tr').attr('data-foo'),
bar: $(this).closest('tr').attr('data-bar')
}
show_dialog(data); // your own code to show the dialog
});
Where you have an <a> tag with the class "show_dialog". Note that this isn't very efficient if you have a lot of attributes or any of them contain data that needs to contain newlines. You could improve this by iterating over each attribute defined on that <tr> and automatically including the attributes starting with data-. That's out of the scope of this question though.
As far as showing the dialog, something like this would be sufficient:
function show_dialog(data) {
var $dialog = $('#dialog');
for(var attr in data) {
$dialog.find("." + attr).html(data[attr]);
}
$dialog.show();
}
<div id="dialog">
<p class="data-foo"></p>
<p class="data-bar"></p>
</div>
That's untested, but should illustrate what's happening well enough.
Note: You can define custom attributes in HTML5 so long as they are prefixed with "data-", hence that showing up everywhere above.
I agree with Tomalak's comment to use one box and change the content in it.
If you wanted to do what I think you are trying to do(without seeing your code) it seems that you might be putting the dialog div in the <table> tag instead of a <td> tag, that would be the first thing to check.
Secondly to open the dialog you can just reference the div next to the link:
<table>
<tr>
<td>
<span class="MoreInfo">More info</span>
<div>stuff for dialog</div>
</td>
</tr>
</table>
$(document).ready(function(){
$('.MoreInfo').next().dialog({ autoOpen: false })
$('.MoreInfo').click(function(){
$(this).next().dialog('open');
});
});
Edit: Sorry messed up the Jquery I am assuming you are using the JqueryUI Dialog

How do you search a table for a definition to a word in jQuery?

This is a little hard to explain, but I have an HTML table, full of SQL definitions, that cross-talk a great deal. For example, one is talking about "INSERT statements", and mentions a "unique key". Another one of the rows talks about unique keys.
I'd like to create little definition bubble (when you hover over "unique key" in the INSERT row) with the definition from the appropriate row. I was planning on using jQuery, but I'm open to alternatives. Any ideas?
UPDATE: My code is here
There are a few jQuery tooltip plug-ins (which is really what you're after). Personally I've been using jQuery Tooltip and am happy with it. I've used it to put some pretty complex content in a tooltip.
I don't fully understand the rest of your question. Do you want this to happen automatically? Is the table present on the page? Is server side code creating the definition bubbles?
Now jQuery Tooltip has a bodyHandler attribute where you can supply a callback (function) that'll define the content of the tooltip so that bit's fine. Do you want these links/tips automatically created though?
EDIT: Take a look at this highlight plug-in as well. Even if you don't use it you can copy the methods for finding text in your document and wrapping elements around them. Something like:
$(function() {
$("table.definitions th").each(function() {
var term = $(this).text();
var definition = $(this).nextSibling().text(); // assuming it's in a <td> in the same row
// find all occurrences of 'term' in relevant text block
// and wrap in <span class="term" title="definition">...</span>
});
});
Then optinoally use jQuery Tooltip to make a more modern tooltip out of that title.
jQuery should work just fine for this task. Store the value for the definition bubble somewhere out of sight and use jQuery to pop it up when you hover.
instead of parsing the HTML directly, maybe you can give each <tr/> an id that can be used to find the definition. conversely, if you'd like more control over which text triggers the bubble, wrap the words in a <span /> with an id.
jt
Rather than wrapping in span as #jason suggested, I'd suggest using the < acronym > or < abbr > tags to markup your chosen words.
In any case, you could then do something like this.
I'll leave setting up the tooltip to you.
Javascript
$(document).ready(function() {
$('acronym').hover(function(){
var text = $('#definition_'+$(this).attr('title')).text();
console.log(text);
$('#cbfsettinguptooltip').text(text)
});
});
HTML
<table border="1" cellspacing="0" cellpadding="5">
<tr>
<td >Insert</td>
<td id="definition_insert">The insert statement is better than the <acronym title="select">select</acronym> statement</td>
</tr>
<tr>
<td >Select</td>
<td id="definition_select">No No Select is best, much better than <acronym title="insert">insert</acronym></td>
</tr>
</table>
<div id="cbfsettinguptooltip">
</div>

Categories