Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>First of all, the "CoffeeScript" that js2coffee produced is, as expected, pretty terrible CoffeeScript. It is pretty obvious that a piece of software just transliterated from one language to another without understanding what the code was really doing. I'd strongly recommend that you learn JavaScript (and CoffeeScript if desired) if you're going to be doing any web development at all.</p> <p>Now into the code. The function breakdown is fine but what's inside the functions is overly complicated.</p> <p>You don't need to keep track of <code>row_i</code> in a global variable, you don't even have to keep track of it at all as you can always compute the indexes you need; so we'll throw that out and pretend it never happened.</p> <p>Your main HTML should look more like this:</p> <pre><code>&lt;table class="student_input_form"&gt; &lt;thead&gt; &lt;tr&gt; &lt;th&gt;Name&lt;/th&gt; &lt;th&gt;Gender&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody&gt; &lt;/tbody&gt; &lt;/table&gt; </code></pre> <p>Put your table headers inside a <code>&lt;thead&gt;</code> since that's what <code>&lt;thead&gt;</code> is for; also, if your header row is inside <code>&lt;tbody&gt;</code> then you'll have to make a bunch of +1/-1 adjustments when working with the real body <code>&lt;tr&gt;</code>s. Might as well use <code>&lt;th&gt;</code> for the headers too. This gives you a more semantic structure and makes things easier to style and work with.</p> <p>The <code>emptyRow</code> function can and should be greatly simplified. You should pass <code>row_i</code> as an argument. And, you have string interpolation in CoffeeScript so you don't need all that <code>string + string</code> noise. You can also use "here-strings" in CoffeeScript and jQuery is happy to take a whole HTML fragment when you call <code>append</code>; these simple things allow you to do things like this:</p> <pre><code>emptyRow = (row_i) -&gt; """ &lt;tr&gt; &lt;td&gt;&lt;input type="text" size="5" value="#{row_i}"&gt;&lt;/td&gt; ... &lt;/tr&gt; """ </code></pre> <p>That's actually readable unlike a big mess of escaped quotes and string concatenation. You can also use a partial to populate a <code>&lt;script&gt;</code> to use as a template, that gives you:</p> <pre><code>&lt;!-- Your partial would go inside... --&gt; &lt;script id="empty_row" type="text/x-template"&gt; &lt;tr&gt; &lt;td&gt;&lt;input type="text" size="5" value="{row_i}"&gt;&lt;/td&gt; &lt;td&gt;&lt;input type="text" size="5" name="mm{row_i}" id="id_mm{row_i}"&gt;&lt;/td&gt; &lt;/tr&gt; &lt;/script&gt; </code></pre> <p>and then <code>emptyRow</code> reduces to:</p> <pre><code>emptyRow = (row_i) -&gt; $('#empty_row').html().replace(/\{row_i\}/g, row_i) </code></pre> <p>A real client-side template solution would be better I suppose but a simple bit of regex mangling will do for simple cases like this.</p> <p>The <code>refresh</code> function can also be greatly simplified. If you're going to be using a jQuery selector several times, make your life easier by computing it only once and saving it in a variable:</p> <pre><code>$tbody = $('.student_input_form tbody'); </code></pre> <p>The HTML structure above makes it easy to figure out how many rows we currently have:</p> <pre><code>current_rows = $tbody.find('tr').length </code></pre> <p>and we get how many we need as an argument:</p> <pre><code>refresh = (need_rows) -&gt; </code></pre> <p>If we need to add new rows, then you can use a simple loop combined with an range array:</p> <pre><code>if(current_rows &lt; need_rows) $tbody.append(emptyRow(i)) for i in [current_rows ... need_rows] </code></pre> <p>The <code>...</code> is more or less the same as it is in a Ruby Range and that gives us two things at once:</p> <ol> <li>The correct number of new <code>&lt;tr&gt;</code>s.</li> <li>The correct index values for <code>emptyRow</code> so that we don't end up with duplicate <code>id</code> attributes.</li> </ol> <p>If you need to remove rows, then you can nicely take advantage of <a href="http://api.jquery.com/gt-selector/" rel="nofollow">jQuery's <code>:gt</code> selector</a> which can take a negative index to count from the end (just like Ruby's arrays...):</p> <pre><code>else if(current_rows &gt; need_rows) $tbody.find("tr:gt(#{need_rows - current_rows - 1})").remove() </code></pre> <p>We're still stuck with a <code>-1</code> adjustment but that's life.</p> <p>The result is nice and lean:</p> <pre><code>refresh = (need_rows) -&gt; $tbody = $('.student_input_form tbody') current_rows = $tbody.find('tr').length if(current_rows &lt; need_rows) $tbody.append(emptyRow(i)) for i in [current_rows ... need_rows] else if(current_rows &gt; need_rows) $tbody.find("tr:gt(#{need_rows - current_rows - 1})").remove() </code></pre> <p>Then to crank it all up:</p> <pre><code>$(document).ready -&gt; $("#nos").change -&gt; refresh(parseInt($(@).val(), 10)) </code></pre> <p>Note that the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt" rel="nofollow"><code>parseInt</code></a> call is here so that <code>refresh</code> can assume that <code>need_rows</code> is a number. Also note that <code>parseInt</code> is called with an explicit <em>radix</em> argument, <strong>always specify an explicit radix when using <code>parseInt</code></strong> so that you don't get octal surprises and similar bits of confusion.</p> <p>You're welcome to compare my version with your original version to see where the bugs were.</p> <p>Demo: <a href="http://jsfiddle.net/ambiguous/qmVaK/" rel="nofollow">http://jsfiddle.net/ambiguous/qmVaK/</a></p> <hr> <p>Some lessons:</p> <ol> <li>Don't use someone else's code when you don't understand how it works.</li> <li>If you're going to write CoffeeScript, learn CoffeeScript and write code on CoffeeScript. Forget that translation tools like js2coffee exist, they do you no real favors.</li> <li>Learn how your tools work. There are lots of useful things in CoffeeScript and jQuery that can make your code more compact and much easier to understand.</li> </ol>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload