1
\$\begingroup\$

I've worked hard on this code and it functions exactly as I wanted, but I've been told it is a little bit unreadable. My focus is to get the code as clean as possible, and have things as efficient as possible.

This is the code I am working with: http://jsfiddle.net/xT5X5/6/

//latest
var maxFields = 10;

$('.form').on('click', '.add', function () {
      var value_src = $(this).prev();
       var container = $(this).parent().prev();
    if ($.trim(value_src.val()) !== '') {
        if (container.children().length < maxFields) {
            var value = value_src.val();
            var html = '<div class="line">' +
                '<input class="accepted" type="text" value="' + value + '" />' +
                '<input type="button" value="X" class="remove" />' +
                '</div>';

            $(html).appendTo(container);
            value_src.val('');
        } else {
            alert("You tried to add a field when there are already " + maxFields);
        }
    } else {
        alert("You didn't enter anything");
    }

})
    .on('click', '.remove', function () {
       $(this).parents('.line').remove();
});

$(".current").keyup(function(e) {
    if (e.which == 13) {
        $(this).next("input").trigger("click");
    }
});

$(document).on("keyup",".accepted",function(e) {
    if (e.which == 13) {
        $(this).closest('.copies').next().find(".current").focus();
    }
});

Can anyone give me any pointers on how I've done, and if there are any improvements that you can spot. Any feedback would be much appreciated!

Thank you.

\$\endgroup\$
13
  • 1
    \$\begingroup\$ You are storing your application state in the HTML instead of keeping a JavaScript object and separating concerns ("requirements" for example is conceptually an array, not a list of DOM elements). This approach will make it very hard for your code to scale in terms of maintenance (Even atm, it's not very readable). Also, please post the code here as well. \$\endgroup\$ Jun 25, 2013 at 15:22
  • 1
    \$\begingroup\$ Posted the code. I am adding in fields (I'm guessing thats what dom elements are applying to in this case) because it seemed a lot easier to submit in a form that way \$\endgroup\$
    – J.Zil
    Jun 25, 2013 at 15:44
  • 1
    \$\begingroup\$ @BenjaminGruenbaum I disagree. I'd say state should be stored in the DOM. That, I'd argue, is exactly how to separate concerns: JS controls behavior, the DOM contains the data, and CSS governs presentation. If the user is supposed to see what's going on, the data must necessarily be added to the DOM at some point, so I'd say keep it there to begin with. To get a "clean" JS array rather than a list of DOM elements, a simple jQuery .map() will suffice. \$\endgroup\$
    – Flambino
    Jun 25, 2013 at 21:00
  • 1
    \$\begingroup\$ @Flambino I consider that a blunt mistake. You're developing a web application not a document. The state should be stored in JavaScript, in models like in any sensible GUI that does separation of concerns. This is exactly what the transition from static web pages to web applications is all about. Do you honestly think querying your presentation is reasonable whenever you want to know your application's state? Storing HTML in JavaScript strings and having no separation of concerns? Storing application state in the DOM is dangerous and harmful. Separate the right concerns. \$\endgroup\$ Jun 25, 2013 at 21:05
  • \$\begingroup\$ I'm a little confused. Are we talking about submitting the array via ajax so that the results don't have to be stored in actual DOM field elements? The advantage of using fields is that I can easily edit the contents of each field after they have been added, otherwise I would probably just have text in printed above with no way to edit \$\endgroup\$
    – J.Zil
    Jun 25, 2013 at 22:39

1 Answer 1

1
\$\begingroup\$

First of all there is a great article on refactoring jQuery by Jack Franklin.

Second is my solution that i came up with in last 2 hours(ocd kicked in). My solution is probably not right, because i still have a ton to learn and would appreciate any feedback !!

Here fiddle with implementation. Here is a short version of what is going on inside, as you can see i tried to refactor each action in it's own method:

// detail object that handles our form
var details = {
    maxFields: 10,
    form: "",
    init: function(el) {},
    bindEvents: function() {},
    appendCopy: function(event) {},
    removeCopy: function(event) {},
    createCopy: function(value) {},
    focusOnEnter: function(event) {},
    addCopyOnEnter: function(event) {},
    _isValueEmpty: function(val) {},
    _isMaxReached: function(copyContainer) {},
    _getParent: function(event){},
    _getCurrent: function(event){}
    _getCopyContainer: function(event){},
    _getValue: function(event){},   
};

// initialize our details object
    details.init(".form");

I think this could also be rewritten using $.deferred where each deferred would be responsible for tracking it's own progress (requirements,benefits,qualifications).

\$\endgroup\$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.