SitePoint Sponsor

User Tag List

Page 1 of 2 12 LastLast
Results 1 to 25 of 33
  1. #1
    SitePoint Guru
    Join Date
    Feb 2007
    Posts
    873
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Jquery add and remove table row

    Dear All,
    I am very new to jquery. So I would like to have a program to enable me to add and remove table row which have few columns. I dont quite understand jquery codes as I am very new to it. I found some sample on the net but most just add one column of data. I want to add and also increase the id of the text boxes which I add in the new row. Any guidance please?

  2. #2
    Non-Member
    Join Date
    Apr 2004
    Location
    Miami, FL, USA
    Posts
    449
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Here you go... I think this is what you're looking for:
    HTML Code:
    <html>
    	<head>
    		<script src="http://code.jquery.com/jquery-1.5.1.min.js"></script>
    		<script>
    		$(document).ready(function() {
    			var id = 0;
    			
    			// Add button functionality
    			$("table.dynatable button.add").click(function() {
    				id++;
    				var master = $(this).parents("table.dynatable");
    				
    				// Get a new row based on the prototype row
    				var prot = master.find(".prototype").clone();
    				prot.attr("class", "")
    				prot.find(".id").attr("value", id);
    				
    				master.find("tbody").append(prot);
    			});
    			
    			// Remove button functionality
    			$("table.dynatable button.remove").live("click", function() {
    				$(this).parents("tr").remove();
    				
    			});
    		});
    		</script>
    		<style>
    			.dynatable {
    				border: solid 1px #000; 
    				border-collapse: collapse;
    			}
    			.dynatable th,
    			.dynatable td {
    				border: solid 1px #000; 
    				padding: 2px 10px;
    				width: 170px;
    				text-align: center;
    			}
    			.dynatable .prototype {
    				display:none;
    			}
    		</style>
    	</head>
    	<body>
    		<table class="dynatable">
    			<thead>
    				<tr>
    					<th>ID</th>
    					<th>Name</th>
    					<th>Col 3</th>
    					<th>Col 4</th>
    					<th><button class="add">Add</button></th>
    				</tr>
    			</thead>
    			<tbody>
    				<tr class="prototype">
    					<td><input type="text" name="id[]" value="0" class="id" /></td>
    					<td><input type="text" name="name[]" value="" /></td>
    					<td><input type="text" name="col4[]" value="" /></td>
    					<td><input type="text" name="col3[]" value="" /></td>
    					<td><button class="remove">Remove</button>
    				</tr>
    		</table>
    	</body>
    </html>

  3. #3
    SitePoint Guru
    Join Date
    Feb 2007
    Posts
    873
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Dear Steve,
    Yes it works but I got few question sorry I am very new to this. First must we always include the jquery-1.5.1.min.js is it? What this file contains? What does this means var master = $(this).parents("table.dynatable"); and also the rest of the code with regards to clone? I am very new so trying to learn. When I do view source I cannot see the table with all the rows in it? Why ya? Thank you.

  4. #4
    SitePoint Member
    Join Date
    Feb 2013
    Posts
    1
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Question Its works perfect in jquery 1.5.1 but the remove button not working in 1.9.1

    Dear Sir,

    Thank you very much for posting the code.
    It works perfect in JQ 1.5.1.
    But the remove button (in those rows, added dynamically at run time) is not working in JQ 1.9.1.

    can you please help me with an Idea,


    Thank you
    Regards
    Anoop

  5. #5
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    5,358
    Mentioned
    179 Post(s)
    Tagged
    9 Thread(s)
    Hi there,

    The reason it breaks in the latest version of jQuery, is because the .live() function has been deprecated.

    Replace this:

    Code JavaScript:
    // Remove button functionality
    $("table.dynatable button.remove").live("click", function() {
      $(this).parents("tr").remove();
    });

    with this:

    Code JavaScript:
    // Remove button functionality
    $(document).on("click", "table.dynatable button.remove", function() {
      $(this).parents("tr").remove();
    });

    and all will be good.

  6. #6
    SitePoint Member
    Join Date
    Feb 2006
    Posts
    9
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I am trying to use this, but it doesn't seem to be making each row unique by adding a new number to the textbox. I need each row to have its own unique name, example: name="text1", name = "text2". all the values are being put into a list.

  7. #7
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    5,358
    Mentioned
    179 Post(s)
    Tagged
    9 Thread(s)
    Hi there,

    Quote Originally Posted by jeffmace View Post
    I am trying to use this, but it doesn't seem to be making each row unique by adding a new number to the textbox.
    It does for me. Could you post the code you are using?

    I need each row to have its own unique name, example: name="text1", name = "text2". all the values are being put into a list.[/QUOTE]

    What do you mean by row?
    The <tr> element?
    Unfortunately, <tr> elements do not have name attributes. They do have class attributes though, so try changing:

    Code JavaScript:
    prot.attr("class", "")

    into:

    Code JavaScript:
    prot.attr("class", "text" + id)

  8. #8
    SitePoint Member
    Join Date
    Nov 2010
    Location
    U.S.A
    Posts
    12
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Man! Nice simple bit of code that works perfectly! Except ...
    I am using this in a form. For some reason I can't figure out, when I add a new row, the form submits.
    I eliminated all other js code on the page and the result is the same, so I know none of my other code is interfering. The submit button is just a regular old submit. PopSelect() is just a function I wrote to create a select list.
    Any ideas?
    <table class="dynatable">
    <thead>
    <tr>
    <th>Test</th>
    <th>Weight (lbs)</th>
    <th>Class</th>
    <th><button class="add">Add</button></th>
    </tr>
    </thead>
    <tbody>
    <tr class="prototype">
    <td><input type="text" name="id[]" value="0" class="id" /></td>
    <td><input id="W00" type="number" maxLength="5" size="9" name="WgtArr[]"></td>
    <td><? echo PopSelect('ClArr[]', $ClassArr, '50', 'Mini'); ?></td>
    <td><button class="remove">Remove</button>
    </tr>
    </table>

  9. #9
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    5,358
    Mentioned
    179 Post(s)
    Tagged
    9 Thread(s)
    Can you post a link to the page where you are having the problem?

  10. #10
    SitePoint Member
    Join Date
    Nov 2010
    Location
    U.S.A
    Posts
    12
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    My client wouldn't like me to do that. I can post the code, though.
    I should mention, this is JQuery 1.8.2 with jQ Mobile 1.3.0.

    Below is the code. I'm really new to both jQuery and jQ Mobile, so it probably seems sloopy - and the css should probably not be in the body, but it will later go into the css file.

    Sorry, I don't see a selection for "code"
    Code:
    <?PHP
       session_start();
       include('../include/FunctionLibrary.inc');
       include('../include/ClassArray.inc');
     ?>
    <!DOCTYPE html>
    <html>
    <head>
       <title>Removed</title>
       <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
       <meta name="robots" content="noindex, nofollow" />
       <link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.0/jquery.mobile-1.3.0.min.css" />
       <link rel="stylesheet" type="text/css" href="css/jqm-datebox.min.css" />
       <link rel="stylesheet" href="<PHP echo($MainDir); ?>css/mobile.css" />
       <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js">
    <?PHP
       if(empty($Ajax)){$Ajax = "false";}
    ?>
    <script type="text/javascript">
    $(document).bind("mobileinit", function()
    {
       $.mobile.ajaxEnabled = "<?PHP echo($Ajax); ?>";
       $.mobile.pageLoadErrorMessage = "Under Construction";
       $.mobile.defaultPageTransition = "slide";
    <?PHP if($Ajax != "true"){echo('$.mobile.pushStateEnabled = "false";'."\n");} ?>
    });
    </script>
       <script src="http://code.jquery.com/mobile/1.3.0/jquery.mobile-1.3.0.min.js"></script>
       <script type="text/javascript" src="js/DateBox/jqm-datebox.core.min.js"></script>
       <script type="text/javascript" src="js/DateBox/jqm-datebox.mode.calbox.min.js"></script>
       <script type="text/javascript" src="js/Datebox/jqm-datebox.mode.datebox.min.js"></script>');
    </head>
    <body>
    <div data-role="page" id="RateWeight">
    <?PHP
       echo('
       <div data-role="header" data-id="HeadBar" data-position="fixed">');
       if($CurrentPage != "Home")
       {
          echo('
          <a href="'.$MainDir.'index.php" data-icon="home">Home</a>');
       }
       else
       {
          echo('
          <a data-ajax="false" href="{removed}">Full Site</a>');
       }
       echo('
          <h1><img src="'.$MainDir.'images/Logo.png" alt="" /></h1>');
          if($_SESSION['LoggedIn'])
          {
             echo('<a data-ajax="false" href="'.$MainDir.'login.php" data-icon="minus">Log Out</a>
             </div><!-- header -->
             <div class="SubHead"><a href="'.$MainDir.'menu/etselect.php" data-icon="plus">{removed}</a>');
             if(strlen($_SESSION[CompanyName]) > 12){echo('<br />');}else{echo('****');}
                echo($_SESSION[CompanyName].'
             </div>');
          }
          elseif(!$Login)
          {
             echo('<a href="'.$MainDir.'login.php" data-icon="login">Log In</a>
             </div><!-- header -->');
          }
          else
          {
             // Login button does not show in login screen
             echo('</div><!-- header -->');
          }
    ?>
    
       <div data-role="content">
          <div class="GrayBoxHead">
             <div style="float:right; width:100px; margin-top:-10px;"><form method="post" action="<?PHP echo($_SERVER[PHP_SELF]); ?>"><input id="RefreshBtn" name="RefreshBtn" type="button" data-icon="refresh" data-ajax="false" data-role="button" data-mini="true" data-inline="true" data-theme="b" value="Refresh" /></form></div>
             Rate Estimate
          </div>
          <div>
             <form id="RateForm" method="post" action="../rtest.php">
                <div data-role="fieldcontain">
                   <label for="CustType" class="select"></label>
                   <div class="LineLabel1">Type:</div>
                   <div class="RateInput">
                      <select id="CustType" name="CustType">
                         <option value="Shipper" selected>Shipper</option>
                         <option value="Consignee">Consignee</option>
                         <option value="ThirdParty">Third Party</option>
                      </select>
                   </div>
                </div>
                <div class="LineLabel2">Pickup Date:</div>
                <div class="RateInput"><input name="PUDate" id="PUDate" type="date" maxlength="10" value="" data-role="datebox" data-options='{"mode": "calbox","overrideDateFormat":"%m/%d/%Y","useFocus": true}'></div>
                <div class="LineLabel2">Customer Code:</div>
                <div class="RateInput"><input id="CustCode" type="number" maxlength="7" name="CustCode" value="<?PHP echo($_SESSION[CustCode]); ?>" /></div>
                <div class="LineLabel1">Origin Zip:</div>
                <div id="OriCell1" class="RateInput"><input id="OriZip" type="text" name="OriZip" value="" /></div>
                <div id="OriCell2" class="RateInput" style="display:none;"><label for="OriList" style="color:#800000; font-weight:bold;">Select the correct city:</label><select name="OriList" id="OriList"><option data-placeholder="true" value="">Select City...</option></select></div>
                <div class="LineLabel2">Destination Zip:</div>
                <div id="DesCell1" class="RateInput"><input id="DesZip" type="text" name="DesZip" value="" /></div>
                <div id="DesCell2" class="RateInput" style="display:none;"><label for="DesList" style="color:#800000; font-weight:bold;">Select the correct city:</label><select name="DesList" id="DesList"><option data-placeholder="true" value="">Select City...</option></select></div>
                <div class="GrayBox" style="padding:5px; clear:left; text-align:center;"><h3>Commodities</h3></div>
    
    
          <table class="dynatable">
             <thead>
                <tr>
                   <th>Test</th>
                   <th>Weight (lbs)</th>
                   <th>Class</th>
                   <th><button class="add">Add</button></th>
                </tr>
             </thead>
             <tbody>
                <tr class="ItemList">
                   <td><input type="text" name="id[]" value="0" class="id" /></td>
                   <td><input id="W00" type="number" maxLength="5" size="9" name="WgtArr[]"></td>
                   <td><? echo PopSelect('ClArr[]', $ClassArr, '50', 'Mini'); ?></td>
                   <td><button class="remove">Remove</button>
                </tr>
             </tbody>
          </table>
    
    
    
    
    
                <div class="GrayBox" style="padding:5px; clear:left; text-align:center;"><h3>Accessorials</h3></div>
                <div data-role="fieldcontain">
                   <fieldset id="Acc1" data-role="controlgroup">
                      <div class="SubTitle">Pickup Options</div>
                      <label for="lftcgp">Liftgate - Ground</label>
                      <input type="checkbox" id="lftcgp" name="Acc[]" value="lftcgp" />
                      <label for="isp">Inside</label>
                      <input type="checkbox" id="isp" name="Acc[]" value="isp" />
                      <label for="respik">Residential / Limited Access</label>
                      <input type="checkbox" id="respik" name="Acc[]" value="respik" />
                      <label for="pexpos">Tradeshow / Expo</label>
                      <input type="checkbox" id="pexpos" name="Acc[]" value="expos" />
                      <label for="pconstr">Construction Site</label>
                      <input type="checkbox" id="pconstr" name="Acc[]" value="constr">
                   </fieldset>
                </div>
                <div data-role="fieldcontain">
                   <fieldset id="Acc2" data-role="controlgroup">
                      <div class="SubTitle">Delivery Options</div>
                      <label for="lftcgd">Liftgate-Ground</label>
                      <input type="checkbox" id="lftcgd" name="Acc[]" value="lftcgd" />
                      <label for="isd">Inside</label>
                      <input type="checkbox" id="isd" name="Acc[]" value="isd" />
                      <label for="resdel">Residential / Limited Access</label>
                      <input type="checkbox" id="resdel" name="Acc[]" value="resdel" />
                      <label for="dexpos">Trade Show / Expo</label>
                      <input type="checkbox" id="dexpos" name="Acc[]" value="expos">
                      <label for="dconstr">Construction Site</label>
                      <input type="checkbox" id="dconstr" name="Acc[]" value="constr">
                      <label for="milita">Military Base</label>
                      <input type="checkbox" id="milita" name="Acc[]" value="milita">
                   </fieldset>
                </div>
                <div data-role="fieldcontain">
                   <fieldset id="Acc3" data-role="controlgroup">
                      <div class="SubTitle">Other Options</div>
                      <label for="notchg">Arrival Notification</label>
                      <input type="checkbox" id="notchg" name="Acc[]" value="notchg">
                      <label for="ccc">Customs Clearance</label>
                      <input type="checkbox" id="ccc" name="Acc[]" value="ccc">
                      <label for="hazmat">Hazardous Materials</label>
                      <input type="checkbox" id="hazmat" name="Acc[]" value="hazmat">
                      <label for="overle">Overlength Article</label>
                      <input type="checkbox" id="overle" name="Acc[]" value="overle">
                      <div>(12 ft or over. Shipments 16 ft or > of trailer call svc center)</div>
                      <label for="feep">COD Amount</label>
                      <input type="checkbox" id="feep" name="Acc[]" value="feep" onclick="if(this.checked){document.getElementById('CODBox').style.display = 'block'}else{document.getElementById('CODBox').style.display = 'none'}" />
                      <div id="CODBox">
                         Amount: <input type="text" id="CODAmt" name="CODAmt" value="" class="TextBox" style="border:1px solid #000000;" />
                      </div>
                   </fieldset>
                </div>
                <input type="hidden" name="Mobile" value="true" />
                <div data-role="fieldcontain"><input data-theme="b" type="submit" name="submit" value="Enter" /></div>
             </form>
          </div>
       </div><!-- /content -->
       <script type="text/javascript">
          function GetPUDate()
          {
             var date = new Date();
             var d  = date.getDate();
             var day = (d < 10) ? "0" + d : d;
             var m = date.getMonth() + 1;
             var month = (m < 10) ? "0" + m : m;
             var yy = date.getYear();
             var year = (yy < 1000) ? yy + 1900 : yy;
             var NewDate = month + "/" + day + "/" + year;
             $('#PUDate').trigger('datebox', {'method':'set', 'value':NewDate});
          }
          function IsNumeric(sText)
          {
             var ValidChars = "0123456789";
             var IsNumber=true;
             var Char;
             for (i = 0; i < sText.length && IsNumber == true; i++)
             {
                Char = sText.charAt(i);
                if (ValidChars.indexOf(Char) == -1)
                {
                   IsNumber = false;
                }
             }
             return IsNumber;
          }
          $('#RateWeight').live('pageinit', function()
          {
             GetPUDate();
             // function ClearForm()
             $("#RefreshBtn").bind("click", function()
             {
                GetPUDate();
                $("select#CustType option[selected]").removeAttr("selected");
                $("select#CustType option[value=Shipper]").attr("selected", "selected");
                $("#OriList").val("");
                $("#OriZip").val("");
                $("#DesZip").val("");
                $("#DesList").val("");
                $("#OriCell2").hide();
                $("#DesCell2").hide();
                $("#OriCell1").show();
                $("#DesCell1").show();
                for(i=0;i<12;i++)
                {
                   ItemID = i < 10 ? "#W0"+i : "#W"+i;
                   ClassID = "#ClArr["+i+"]";
                   II = ItemID.substring(1);
                   CI = ClassID.substr(1);
                   $(ItemID).val('');
                   $(ClassID).val("0500");
                }
                document.getElementById("CODBox").style.display = "none";
                document.getElementById("CODAmt").value = "";
                var CheckBoxes = ["lftcgp","isp","respik","pexpos","pconstr","lftcgd","isd","resdel","dexpos","dconstr","milita","notchg","ccc","hazmat","overle","feep"];
                alength = CheckBoxes.length;
                for(i=0;i<alength;i++)
                {
                   document.getElementById(CheckBoxes[i]).checked = false;
                }
                window.location = "<?PHP echo($MainDir); ?>rate.php";
             });
    
             $(document).on('vclick','#OriZip', function()
             {
                var ZipObj = document.getElementById("OriZip");
                ZipData = ZipObj.value.slice(0,3);
                if(ZipData == "Not")
                {
                   ZipObj.value = "";
                }
             });
    
             $("#OriZip").keyup(function()
             {
                var Ori = document.getElementById("OriZip");
                var ZipData = Ori.value.toUpperCase();
                var Max = IsNumeric(ZipData) ? 5 : 6;
                if(ZipData.length == Max && ZipData != "" && ZipData.substr(0,3) != "NOT") // NOT = First part of Not Found
                {
                   Ori.value = "Please Wait ...";
                   $.get("<?PHP echo($ServerDir); ?>include/ZipCitiesArray.php", "&ZipCode="+ZipData, OriSuccess, "text" );
                }
             });
              function OriSuccess( OriReturn )
              {
                var $Cell   = $('#OriCell1');
                var $List   = $('#OriCell2');
                var $Input  = $('#OriZip');
    
                var data = OriReturn.split(",");
                if(data.length > 1)
                {
                   $($Cell).hide();
                   $($List).show();
                   // Clear any current selections
                   // $("#OriList").html("") // Clear the list (Probably unnecessary so commented out
                   // Add an option to to the drop-down list for each City returned from the request
                   for(i=0; i < data.length; i++)
                   {
                      $("<option value = '"+data[i]+"'>"+data[i]+"</option>").appendTo("#OriList");
                   }
                   $Input.val("");
                   $('#OriList').focus();
                }
                else
                {
                   document.getElementById("OriZip").value = OriReturn;
                   if(OriReturn == "Not Found" || OriReturn.substr(0,6) == "Canada" || OriReturn == "")
                   {
                      if(OriReturn == ""){document.getElementById("OriZip").value = "";}
                      // Can't seem to find a way to set focus here. It has already gone to next field
                   }
                }
             }
    
             $(document).on('vclick','#DesZip', function()
             {
                var ZipObj = document.getElementById("DesZip");
                ZipData = ZipObj.value.slice(0,3);
                if(ZipData == "Not")
                {
                   ZipObj.value = "";
                }
             });
    
             $("#DesZip").keyup(function()
             {
                var Des = document.getElementById("DesZip");
                var ZipData = Des.value.toUpperCase();
                var Max = IsNumeric(ZipData) ? 5 : 6;
                if(ZipData.length == Max && ZipData != "" && ZipData.substr(0,3) != "NOT") // NOT = First part of Not Found
                {
                   Des.value = "Please Wait ...";
                   $.get("<?PHP echo($ServerDir); ?>include/ZipCitiesArray.php", "&ZipCode="+ZipData, DesSuccess, "text" );
                }
             });
             function DesSuccess( DesReturn )
             {
                var $Cell   = $('#DesCell1');
                var $List   = $('#DesCell2');
                var $Input  = $('#DesZip');
    
                var data = DesReturn.split(",");
                if(data.length > 1)
                {
                   $($Cell).hide();
                   $($List).show();
                   // Add an option to to the drop-down list for each City returned from the request
                   for(i=0; i < data.length; i++)
                   {
                      $("<option value = '"+data[i]+"'>"+data[i]+"</option>").appendTo("#DesList");
                   }
                   $Input.val("");
                   $('#DesList').focus();
                }
                else
                {
                   document.getElementById("DesZip").value = DesReturn;
                   if(DesReturn == "Not Found" || DesReturn.substr(0,6) == "Canada" || DesReturn == "")
                   {
                      if(DesReturn == ""){document.customer.elements["DesZip"].value = "";}
                   }
                }
             }
    //      });
    //      $(document).ready(function() {
             var id = 0;
    
             // Add button functionality
             $("table.dynatable button.add").on("vclick",".add", function() {
                id++;
                var master = $(this).parents("table.dynatable");
    
                // Get a new row based on the ItemList row
                var prot = master.find(".ItemList").clone();
                if(id < 10)
                {
                   prot.attr("class", "W0"+id);
                }
                else
                {
                   prot.attr("class", "W"+id);
                }
                prot.find(".id").attr("value", id);
    
                master.find("tbody").append(prot);
             });
    
             // Remove button functionality
             $("table.dynatable button.remove").live("click", function() {
                $(this).parents("tr").remove();
    
             });
          });
       </script>
    
       <? include($IncludeDir.'MobileFoot.inc'); ?>
    </div><!-- page -->
    </body>
    </html>

  11. #11
    SitePoint Member
    Join Date
    Nov 2010
    Location
    U.S.A
    Posts
    12
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well, after more testing, here's the relevant stuff.
    The problem is the form. The table works fine, but when you add a row, the form submits.

    Code:
    <!DOCTYPE html>
    <html>
    <head>
        <title>Dynamic Table</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
       <link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.0/jquery.mobile-1.3.0.min.css" />
       <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
       <script src="http://code.jquery.com/mobile/1.3.0/jquery.mobile-1.3.0.min.js"></script>
       <script type="text/javascript" src="http://www.modernizr.com/downloads/modernizr-latest.js"></script>
          <style>
             .dynatable {
                border: solid 1px #000;
                border-collapse: collapse;
             }
             .dynatable th,
             .dynatable td {
                border: solid 1px #000;
                padding: 2px 10px;
                width: 170px;
                text-align: center;
             }
             .dynatable .prototype {
                display:none;
             }
          </style>
    </head>
    <body>
    <section data-role="page" id="RateWeight">
        <section data-role="header">
            <h2>Table Test</h2>
        </section>
        <section data-role="content">
          <form id="RateForm" method="post" action="../rtest.php">
             <table class="dynatable">
                <thead>
                   <tr>
                      <th>ID</th>
                      <th>Name</th>
                      <th>Col 3</th>
                      <th>Col 4</th>
                      <th><button class="add">Add</button></th>
                   </tr>
                </thead>
                <tbody>
                   <tr class="prototype">
                      <td><input type="text" name="id[]" value="0" class="id" /></td>
                      <td><input type="text" name="name[]" value="" /></td>
                      <td><input type="text" name="col4[]" value="" /></td>
                      <td><input type="text" name="col3[]" value="" /></td>
                      <td><button class="remove">Remove</button>
                   </tr>
                   <tr><td colspan="5">
                </tbody>
             </table>
             <input type="hidden" name="Mobile" value="true" />
             <div data-role="fieldcontain"><input data-theme="b" type="submit" name="submit" value="Enter" /></div>
          </form>
        </section>
    </section>
       <script type="text/javascript">
          $('#RateWeight').live('pageinit', function()
          {
             var id = 0;
    
             // Add button functionality
             $("table.dynatable button.add").click(function() {
                id++;
                var master = $(this).parents("table.dynatable");
    
                // Get a new row based on the prototype row
                var prot = master.find(".prototype").clone();
                prot.attr("class", "")
                prot.find(".id").attr("value", id);
    
                master.find("tbody").append(prot);
             });
    
             // Remove button functionality
             $("table.dynatable button.remove").live("click", function() {
                $(this).parents("tr").remove();
    
             });
          });
          </script>
    </body>
    </html>

  12. #12
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    5,358
    Mentioned
    179 Post(s)
    Tagged
    9 Thread(s)
    Hi,

    Thanks for taking the time to make a simple example that I could run on my computer to reproduce your problem.
    I wish more people would do that!


    Quote Originally Posted by RationalRabbit View Post
    The problem is the form. The table works fine, but when you add a row, the form submits.
    Aye, clicking on the button to add a row is also submitting the form.
    To prevent this from happening, just pass a parameter to the callback in the .click() handler, and have your code prevent the form's default submit behaviour.

    In other words, change this:

    Code JavaScript:
    $("table.dynatable button.add").click(function() {
      id++;
      var master = $(this).parents("table.dynatable");
     
      // Get a new row based on the prototype row
      var prot = master.find(".prototype").clone();
      prot.attr("class", "")
      prot.find(".id").attr("value", id);
     
      master.find("tbody").append(prot);
    });

    To this:

    Code JavaScript:
    $("table.dynatable button.add").click(function(e) {
     e.preventDefault();
      id++;
      var master = $(this).parents("table.dynatable");
     
      // Get a new row based on the prototype row
      var prot = master.find(".prototype").clone();
      prot.attr("class", "")
      prot.find(".id").attr("value", id);
     
      master.find("tbody").append(prot);
    });

  13. #13
    SitePoint Member
    Join Date
    Nov 2010
    Location
    U.S.A
    Posts
    12
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ha! I was going through all kinds of complex means (none of which worked) trying to do just that.
    jQuery, to me, is not anything like learning a new language - where the basic tenants are fairly similar - it is like trying to understand a foreign object and I inevitably make the problem stranger than it really is.

    Thanks very much Pullo. You made my day twice over!

  14. #14
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    5,358
    Mentioned
    179 Post(s)
    Tagged
    9 Thread(s)
    You're welcome

    Thanks for taking the time to let me know this worked for you.

  15. #15
    SitePoint Member
    Join Date
    Nov 2010
    Location
    U.S.A
    Posts
    12
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Maybe I can bug you with one more problem that has been perplexing me.
    One of the cells contains a select list. I can set a default value (prot.find(".ClArr").attr("value","0500") fine. The problem is the display does not reflect that value. (even though it IS selected)
    I know that, somehow, apparently, you have to use selectmenu("refresh"), but, when I try to use it inside the function, no matter where I place it, nothing happens.
    Firebug says "cannot call methods on selectmenu prior to initialization; attempted to call method 'refresh'"

    This is probably a good subject on its own, because I have not been able to find a decent explanation on the Web, except when dynamically creating a select list. In my situation, the select list is already created and it is the same in each cell (except for the chosen value, of course).

  16. #16
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    5,358
    Mentioned
    179 Post(s)
    Tagged
    9 Thread(s)
    Hi there,

    Would it be possible for you to create an example page, as you did in post #11, which demonstrates your problem.
    Then I would be happy to take a look.

    I tried running your code from post #11 again, but there is no select list involved.

  17. #17
    SitePoint Member
    Join Date
    Nov 2010
    Location
    U.S.A
    Posts
    12
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You Bet!

    HTML Code:
    [CODE]
    <!DOCTYPE html>
    <html>
    <head>
       <title>Test copy</title>
       <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
       <meta name="robots" content="noindex, nofollow" />
       <meta name="viewport" content="width=device-width, initial-scale=1" />
       <link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.0/jquery.mobile-1.3.0.min.css" />
       <link rel="stylesheet" type="text/css" href="css/jqm-datebox.min.css" />
       <link rel="stylesheet" href="http://www.mmeinc.com/m/css/mobile.css" />
       <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js">
       <script type="text/javascript">
       $(document).bind("mobileinit", function()
       {
          $.mobile.ajaxEnabled = "false";
          $.mobile.pageLoadErrorMessage = "Under Construction";
          $.mobile.defaultPageTransition = "slide";
       $.mobile.selectmenu.prototype.options.initSelector = "#OriList";
       $.mobile.pushStateEnabled = "false";
       });
       </script>
       <script src="http://code.jquery.com/mobile/1.3.0/jquery.mobile-1.3.0.min.js"></script>
    </head>
    <body>
    <div data-role="page" id="RateWeight">
       <style type="text/css">
          .dynatable {border: solid 1px #000; border-collapse: collapse;}
          .dynatable th, .dynatable td {border: solid 1px #000; padding: 2px 10px; width: 33%; text-align: center;}
          .dynatable td {background-color:#619FCD;}
       </style>
       <div data-role="content">
          <div class="GrayBoxHead">
             <div style="float:right; width:100px; margin-top:-10px;"><form method="post" action="TestCopy.php"><input id="RefreshBtn" name="RefreshBtn" type="button" data-icon="refresh" data-ajax="false" data-role="button" data-mini="true" data-inline="true" data-theme="b" value="Refresh" /></form></div>
             Rate Estimate
          </div>
          <div>
             <form id="RateForm" method="post" action="../rtest.php">
                <table class="dynatable">
                <thead>
                   <tr>
                      <th>Weight (lbs)</th>
                      <th>Class</th>
                      <th><button class="add" data-mini="true">Add</button></th>
                   </tr>
                </thead>
                <tbody>
                   <tr class="ItemList">
                      <td><input class="WgtArr" id="W00" type="number" maxLength="5" size="9" name="WgtArr[]"></td>
                      <td><select class="ClArr"  name="ClArr[]" id="ClArr[]">
    <option value="0500" selected>50</option>
    <option value="0550">55</option>
    <option value="0600">60</option>
    <option value="0650">65</option>
    <option value="0700">70</option>
    <option value="0775">77.5</option>
    <option value="0850">85</option>
    <option value="0925">92.5</option>
    <option value="1000">100</option>
    <option value="1100">110</option>
    <option value="1250">125</option>
    <option value="1500">150</option>
    <option value="1750">175</option>
    <option value="2000">200</option>
    <option value="2500">250</option>
    <option value="3000">300</option>
    <option value="4000">400</option>
    <option value="5000">500</option>
    </select></td>
                      <td><button class="remove mini" data-mini="true">Remove</button>
                   </tr>
                </tbody>
                </table>
                <input type="hidden" name="Mobile" value="true" />
                <div data-role="fieldcontain"><input data-theme="b" type="submit" name="submit" value="Enter" /></div>
             </form>
          </div>
       </div><!-- /content -->
       <script type="text/javascript">
          $('#RateWeight').live('pageinit', function()
          {
             var id = 0;
             // Add button functionality
             $("table.dynatable button.add").click(function(e)
             {
                e.preventDefault();
                id++;
                var master = $(this).parents("table.dynatable");
    
                // Get a new row based on the ItemList row
                var prot = master.find(".ItemList").clone();
                prot.attr("class", "")
                if(id < 10)
                {
                   prot.find(".WgtArr").attr("id", "W0"+id);
                }
                else
                {
                   prot.find(".WgtArr").attr("id", "W"+id);
                }
    //           prot.find(".id").attr("value", id);
                prot.find(".WgtArr").attr("value","");
                prot.find(".ClArr").attr("value","0500");
                master.find("tbody").append(prot);
    //            prot.find(".ClArr").selectmenu( "refresh" );
             });
    
             // Remove button functionality
             $("table.dynatable button.remove").live("click", function()
             {
                $(this).parents("tr").remove();
             });
          });
       </script>
    </div><!-- page -->
    </body>
    </html>
    [/CODE]

  18. #18
    SitePoint Member
    Join Date
    Nov 2010
    Location
    U.S.A
    Posts
    12
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Of course, the refresh needs to be bound to the selection event (not the commented out line I have above) using an on("select") or something.
    I think the code would go something like
    Code:
        var ClSelect = $("select#ClArr[]");
        ClSelect[0].selectedIndex = {the index value};
        ClSelect.selectmenu("refresh");
    I just don't know where or how to put it

  19. #19
    SitePoint Member
    Join Date
    Nov 2010
    Location
    U.S.A
    Posts
    12
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well, except (I'm kind of forgetting what I was trying to do here) the cloned list also needs to refresh when it is created so it will display the default, rather than the previous lists selection.
    You can see by opening the new list that the default is, indeed, selected. The same when you change the selection. It is just not displaying the text of the selected index.

  20. #20
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    5,358
    Mentioned
    179 Post(s)
    Tagged
    9 Thread(s)
    Hi there,

    AFAIK, at the moment, clones of expandable items are not supported by jQuery mobile.
    You will be able to do this, but it will involve some kind of workaround.
    I'm off to work right now, but leave it with me and I'll have another look when I get back.

  21. #21
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    5,358
    Mentioned
    179 Post(s)
    Tagged
    9 Thread(s)
    So,

    I had a think about this and found a solution for you.
    Try this out:

    Code:
    <!DOCTYPE html>
    <html>
      <head>
        <title>Test copy</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <!--<link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.0/jquery.mobile-1.3.0.min.css" />-->
        <!--<link rel="stylesheet" href="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.css" />-->
        <link rel="stylesheet" href="./jquery.mobile-1.3.0.min.css" />
        <link rel="stylesheet" href="http://www.mmeinc.com/m/css/mobile.css" />
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
        <!--<script src="http://code.jquery.com/mobile/1.3.0/jquery.mobile-1.3.0.min.js"></script>-->
        <!--<script src="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.min.js"></script>-->
        <script src="./jquery.mobile-1.3.1.min.js"></script>
        <style type="text/css">
          .dynatable {border: solid 1px #000; border-collapse: collapse;}
          .dynatable th, .dynatable td {border: solid 1px #000; padding: 2px 10px; width: 33%; text-align: center;}
          .dynatable td {background-color:#619FCD;}
        </style>
      </head>
      <body>
      <div data-role="page" id="RateWeight">
          <form id="RateForm" method="post" action="../rtest.php">
            <table class="dynatable">
              <thead>
                <tr>
                  <th>Weight (lbs)</th>
                  <th>Class</th>
                  <th><button class="add" data-mini="true">Add</button></th>
                </tr>
              </thead>
              
              <tbody>
                <tr class="ItemList">
                  <td><input class="WgtArr" type="number" maxLength="5" size="9" name="WgtArr[]"></td>
                  <td class='repeatable'>
                    <select class="ClArr"  name="ClArr[]" id="ClArr">
                      <option value="0500" selected>50</option>
                      <option value="0550">55</option>
                      <option value="0600">60</option>
                      <option value="0650">65</option>
                      <option value="0700">70</option>
                      <option value="0775">77.5</option>
                      <option value="0850">85</option>
                      <option value="0925">92.5</option>
                      <option value="1000">100</option>
                      <option value="1100">110</option>
                      <option value="1250">125</option>
                      <option value="1500">150</option>
                      <option value="1750">175</option>
                      <option value="2000">200</option>
                      <option value="2500">250</option>
                      <option value="3000">300</option>
                      <option value="4000">400</option>
                      <option value="5000">500</option>
                    </select>
                  </td>
                  <td><button class="remove mini" data-mini="true">Remove</button></td>
                </tr>
              </tbody>
            </table>
          </form>
        </div>
        
        <script type="text/javascript">
          function cloneSelect() {
            var selectmenu = $.mobile.activePage.find('select').last().clone(),
            index = $.mobile.activePage.find('select').last().index()+1,
            id = $.mobile.activePage.find('select').last().attr('id'); 
            $('.holder').last().append(selectmenu.attr('id',id+index));
            $('#'+id+index).selectmenu(); 
          }
          
          $("table.dynatable button.add").click(function(e){
            e.preventDefault();
            
            var w = $(".ItemList td").first().clone();
            var c = $("<td class='holder'></td>");
            var b = $(".ItemList td").last().clone();
            
            var t = $('<tr class="ItemList">').append(w).append(c).append(b);
            $("tbody").append(t);
            cloneSelect();
            
            $("table.dynatable button.remove").live("click", function(){
              $(this).parents("tr").remove();
            });
          });
        </script>
      </body>
    </html>
    Apologies for the multiple inclusions of jQuery mobile, but when I was testing this, I kept getting time out errors.

    Anyway, how this works is as follows:

    As I mentioned, clones of expandable items are a bit tricky in jQuery mobile.
    We therefore have to clone all of the cells separately, creating a place holder for the select. We then append the cloned cells to a table row, which we then append to the table body.

    After that has been done, we are then in a position to reference the last select (and only the select, not the additional HTML that jQuery mobile wraps around it), increment its id, then, referencing it by its new id, apply the .selectmenu() method to it.

    Here's a demo.

    Hope that helps you.

    Reference: http://stackoverflow.com/questions/9...tmenu-in-table

  22. #22
    SitePoint Member
    Join Date
    Nov 2010
    Location
    U.S.A
    Posts
    12
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ah, Excellent!
    This routine is important for usability and data integrity, so it is not something I could just drop.
    Unfortunately, my JavaScript is rather rudimentary and I still feel like a complete stranger when it comes to jQuery, so I can't begin to tell you how much your help has been appreciated.

    The ID thing isn't working though. The id's come out like ClArr2, ClArr22, ClArr222, etc. I've tried several things, with varying degrees of unsatisfactory results due to relying on "last().index()", but can't seem to figure out what to do here.
    Somehow I need to get the last document.RateForm.ClArr[] index number or otherwise increment these id's. The only way I've come up with that works is to store a number in a global and that's well ...

  23. #23
    SitePoint Member
    Join Date
    Nov 2010
    Location
    U.S.A
    Posts
    12
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    This seems to work okay.
    (Also added line to clear Weight field on cloned cell)
    Original Select now has an ID of "ClArr0", while subsequent are ClArr1, etc.

    Code:
        <script type="text/javascript">
          var rid = 0;
          function cloneSelect() {
             rid++;
             var selectmenu = $.mobile.activePage.find('select').last().clone();
             $('.holder').last().append(selectmenu.attr('id','ClArr'+rid));
             $('#ClArr'+rid).selectmenu();
          }
    
          $("table.dynatable button.add").click(function(e){
             e.preventDefault();
    
             var w = $(".ItemList td").first().clone();
             $(w).find(".WgtArr").attr("value","");
             var c = $("<td class='holder'></td>");
             var b = $(".ItemList td").last().clone();
    
             var t = $('<tr class="ItemList">').append(w).append(c).append(b);
             $("tbody").append(t);
             cloneSelect();
          });
    
          $("table.dynatable button.remove").live("click", function(){
             $(this).parents("tr").remove();
          });
        </script>
    Then, if you want to add ID's for the Weight field, name the original, for instance, Wgt0
    then, after the cloneSelect(), add
    Code:
             w.attr("class", "")
             w.find(".WgtArr").attr("id", "Wgt"+rid);

  24. #24
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    5,358
    Mentioned
    179 Post(s)
    Tagged
    9 Thread(s)
    Excellent! That's a good solution.
    Way to go!


    Are we good now?

  25. #25
    SitePoint Member
    Join Date
    Nov 2010
    Location
    U.S.A
    Posts
    12
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yeah - working great!
    Thanks again, Pullo Dave!


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •