2

enter image description hereI am experimenting with the following .js code that adds form field dynamically to a page for me :

var i=$('table tr').length;
$(".addmore").on('click',function(){
    addNewRow();
});

$(".addmany").on('click',function(){
    addNewRow();
    addNewRow();
});

$(document).on('keypress', ".addNewRow", function(e){
    var keyCode = e.which ? e.which : e.keyCode;
    if(keyCode == 9 ) addNewRow();
});
var addNewRow = function(){
    html = '<tr>';
    html += '<td><input class="case" id="caseNo_'+i+'" type="checkbox"/></td>';
    html += '<td><input type="text" data-type="productCode" name="data[InvoiceDetail]['+i+'][product_id]" id="itemNo_'+i+'" class="form-control autocomplete_txt" autocomplete="off"></td>';
    html += '<td><input type="text" data-type="productName" name="data[InvoiceDetail]['+i+'][productName]"  id="itemName_'+i+'" class="form-control autocomplete_txt" autocomplete="off"></td>';
    html += '<td><input type="text" name="data[InvoiceDetail]['+i+'][price]" id="price_'+i+'" class="form-control changesNo" autocomplete="off" onkeypress="return IsNumeric(event);" ondrop="return false;" onpaste="return false;"></td>';

    html += '<td><input type="text" name="data[InvoiceDetail]['+i+'][quantity]" id="quantity_'+i+'" class="form-control changesNo quanyityChange" autocomplete="off" onkeypress="return IsNumeric(event);" ondrop="return false;" onpaste="return false;">';
    html += '<input type="hidden" id="stock_'+i+'"/>';
    html += '<input type="hidden" id="stockMaintainer_'+i+'" name="data[InvoiceDetail]['+i+'][stockMaintainer]" />';
    html += '<input type="hidden" id="previousQuantity_'+i+'"/>';
    html += '<input type="hidden" id="invoiceDetailId_'+i+'"/>';
    html += '</td>';
    html += '<td><input type="text" id="total_'+i+'" class="form-control totalLinePrice addNewRow" autocomplete="off" onkeypress="return IsNumeric(event);" ondrop="return false;" onpaste="return false;"></td>';
    html += '<td><input type="checkbox" data-type="staged" name="data[InvoiceDetail]['+i+'][staged]"  id="staged_'+i+'" class="form-control autocomplete_txt" autocomplete="off"></td>';
    html += '</tr>';
    $('table').append(html);

    $('#caseNo_'+i).focus();

    i++;
}

It works perfectly, and I am able to add product lines in as needed.

HOWEVER, I would like to be able to add rows IN BETWEEN existing rows.
Does anyone know how I would do that?

Right now the code executes as below :

Apples
Bananas
Oranges

Add Row(button)

Apples
Bananas
Oranges
New Item

I want it to work like this when needed :

Apples
New Item
Bananas
Oranges

Possibly via a icon next to each row, that you click on to add a row above or below said item.

Sample of form :

<?php if(isset($invoice['InvoiceDetail'])&&!empty($invoice['InvoiceDetail'])){?>
                                    <?php foreach ( $invoice['InvoiceDetail'] as $key=>$item){?>
                                        <tr>
                                            <td> <input class="case" type="checkbox"/> </td>
                                            <td><input value="<?php echo isset($item['product_id']) ? $item['product_id']: ''; ?>" type="text" data-type="productCode" name="data[InvoiceDetail][<?php echo $key;?>][product_id]" id="itemNo_<?php echo $key+1?>" class="form-control autocomplete_txt" autocomplete="off"></td>
                                            <td><input value="<?php echo isset($item['productName']) ? $item['productName']: ''; ?>" type="text" data-type="productName" name="data[InvoiceDetail][<?php echo $key;?>][productName]" id="itemName_<?php echo $key+1?>" class="form-control autocomplete_txt" autocomplete="off"></td>
                                            <td><input value="<?php echo isset($item['price']) ? $item['price']: ''; ?>" type="number" name="data[InvoiceDetail][<?php echo $key;?>][price]" id="price_<?php echo $key+1?>" class="form-control changesNo" autocomplete="off" onkeypress="return IsNumeric(event);" ondrop="return false;" onpaste="return false;"></td>
                                            <td>
                                                <input value="<?php echo isset($item['quantity']) ? $item['quantity']: ''; ?>" type="number" name="data[InvoiceDetail][<?php echo $key;?>][quantity]" id="quantity_<?php echo $key+1?>" class="form-control changesNo quanyityChange" autocomplete="off" onkeypress="return IsNumeric(event);" ondrop="return false;" onpaste="return false;">
                                                <input value="<?php echo isset($item['quantityInStock']) ? $item['quantityInStock']: ''; ?>"  type="hidden" id="stock_<?php echo $key+1?>" autocomplete="off"/>
                                                <input value="0" type="hidden" id="stockMaintainer_<?php echo $key+1?>" name="data[InvoiceDetail][<?php echo $key;?>][stockMaintainer]" autocomplete="off"/>
                                                <input value="<?php echo isset($item['quantity']) ? $item['quantity']: ''; ?>" type="hidden" id="previousQuantity_<?php echo $key+1?>" autocomplete="off"/>
                                                <input value="<?php echo isset($item['id']) ? $item['id']: ''; ?>" type="hidden" id="invoiceDetailId_<?php echo $key+1?>" autocomplete="off"/>
                                            </td>
                                            <td><input value="<?php echo $item['price']*$item['quantity']; ?>" type="number" id="total_<?php echo $key+1?>" class="form-control totalLinePrice" autocomplete="off" onkeypress="return IsNumeric(event);" ondrop="return false;" onpaste="return false;"></td>
                                            <td><input type="checkbox" <?php if(isset($item['staged']) && $item['staged'] == 1) echo "checked=\"checked\""?> data-type="checkbox" name="data[InvoiceDetail][<?php echo $key;?>][staged]" id="staged_<?php echo $key+1?>" class="form-control autocomplete_txt" autocomplete="off"></td>

                                        </tr>
                                    <?php } ?>
                                <?php }else{?>
                                    <tr>
                                        <td><input class="case" type="checkbox"/></td>
                                        <td><input type="text" data-type="productCode" name="data[InvoiceDetail][0][product_id]" id="itemNo_1" class="form-control autocomplete_txt" autocomplete="off"></td>
                                        <td><input type="text" data-type="productName" name="data[InvoiceDetail][0][productName]" id="itemName_1" class="form-control autocomplete_txt" autocomplete="off"></td>
                                        <td><input type="number" name="data[InvoiceDetail][0][price]" id="price_1" class="form-control changesNo" autocomplete="off" onkeypress="return IsNumeric(event);" ondrop="return false;" onpaste="return false;"></td>
                                        <td>
                                            <input type="number" name="data[InvoiceDetail][0][quantity]" id="quantity_1" class="form-control changesNo quanyityChange" autocomplete="off" onkeypress="return IsNumeric(event);" ondrop="return false;" onpaste="return false;">
                                            <input type="hidden" id="stock_1" autocomplete="off"/>
                                            <input type="hidden" name="data[InvoiceDetail][0][stockMaintainer]" id="stockMaintainer_1" autocomplete="off"/>
                                            <input type="hidden" id="previousQuantity_1" autocomplete="off"/>
                                            <input type="hidden" id="invoiceDetailId_1" autocomplete="off"/>
                                        </td>
                                        <td><input type="number" id="total_1" class="form-control totalLinePrice addNewRow" autocomplete="off" onkeypress="return IsNumeric(event);" ondrop="return false;" onpaste="return false;"></td>
                                        <td><input value="1" type="checkbox" name="data[InvoiceDetail][0][staged]" id="staged_1" class="form-control autocomplete_txt" autocomplete="off"></td>                                 
                                        </tr>
                                <?php } ?>

enter image description here

7
  • 1
    JQuery DOM manipulation methods include more than just append(), may be you can peruse the manual. Commented Aug 25, 2015 at 0:34
  • @mustaccio I am a semi-ok web developer that is just now adding php/sql to my list of ongoing learning skills, would you please at least point to a good source for the manual, or learning materials? Commented Aug 25, 2015 at 0:35
  • They are on the same web site from which you downloaded jQuery. Commented Aug 25, 2015 at 0:37
  • @mustaccio Thank you for that direction, I will take a look, and hopefully find something that will allow me to do this :) Commented Aug 25, 2015 at 0:38
  • @mustaccio I RTFM, and all I could come up with was the fact that you can append, prepend, append to, or prepend to different elements. However, I do not see how that is helpful in prepending to a dynamic variable. I am using a <?php echo $key+1?> in the id of each insert element that allows my above code to work, I imagine that I will have to somehow prepend to the $key item in order to make it work, but am unsure as to how to go about it.... Commented Aug 25, 2015 at 0:56

1 Answer 1

2

You could also consider making these rows sortable (with jQueryUI) so the user can decide to change the order later if that's important.

Otherwise think about this modification concept of your code:

var addNewRow = function(element, type) {
    var html = '<tr>' // etc ....

    (type == 'after') ? element.after(html) : element.append(html);

    $('#caseNo_'+i).focus();

    i++;
}

// Where ever you're doing this now..
addNewRow($('table'), 'append');

// maybe in click rule of (I am assuming - nested) icon in your TR, use .closest('tr') to get the element.
addNewRow($(this).closest('tr'), 'after');

To preserve numerical orders something like this:

var reOrder = function() {

    var table = $('table');
    table.children('tr').each(function(){
        var tr = $(this);
        var i = table.index(tr) + 1; // because index starts at 0
        tr.attr('data-some-attribute', 'new_value_'+i);
    }
};

OP wanted even more of the jQuery to see how it might all work together...

// Define Vars

var table = $('table'); // try to make this more specific of a selector../
var addRowButton = $('#specific-button');

// This function, with missing parts "etc" added in:
var addNewRow = function(element, type) {
    var html = '<tr>' // etc ....

    // don't forget to add the "add row button" html to this also

    (type == 'after') element.after(html) : element.append(html);

    $('#caseNo_'+i).focus();

    i++;
};

// Re Order table to preserve row numbering
var reOrder = function() {
    table.children('tr').each(function(){
        var tr = $(this);
        var i = table.index(tr) + 1; // because index starts at 0

        tr.attr('data-some-attribute', 'new_value_'+i);
    }
};


// You have 1 add row button:

addRowButton.click(function(){

    // Call to addNewRow
    addNewRow(table, 'append');

});

// I assume you'll nest your buttons to add a row below in your current row..
table.find('.add-row-button').click(function(){

    // Call to add row
    addNewRow($(this).closest('tr'), 'after');

    // Call to reOrder table
    reOrder();

});
Sign up to request clarification or add additional context in comments.

9 Comments

the closest tr is dynamic(sample) : <input value="<?php echo isset($item['quantity']) ? $item['quantity']: ''; ?>" type="hidden" id="previousQuantity_<?php echo $key+1?>" autocomplete="off"/> How would I find the closest element that $key+1 defines, even in prior saved inputs?
Checked out the sortable code, and it is pretty nifty, however on a ui level, the viability of sorting a blank line added to the bottom of the page(of dozens and dozens of items) clicking and dragging up a couple pages will not work :(
Ok, I read your first comment and am trying to make sense of it... still.. is your issue with making the new row have the correct i in jQuery or is the issue when you need to save it or load the page with PHP?
yes, the issue is making the row have the correct i in jQuery, for instance, if the user ADDS 5 rows to the html table, numbered a1, a2, a3, a4, a5, and saves the form(to the sql database), how will I in jQuery load those values a1-a5, as well as be able to add a NEW a3 to take the place of the old one, and then reorder all the existing a.#'s to where they need to be....
I changed the picture to reflect the row changes, and the problem with working with dynamic rows.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.