简体   繁体   中英

Better way to generate HTML using coffeescript / jQuery than using strings?

This is the first time I've done an "answer your own question" post, so I hope I'm approaching this right.

My question was, "Is there a better way to generate html with jQuery than using tag strings?" I wanted to be able to generate nested html without creating long messy strings like

$("<form action='#{submitURL}' class='my_form'><input type='text'>...</form>")

but instead use nested function calls. I want the HTML generation code to look something like this:

$.el.form
    id: "enrollment_form"
    class: "myFormClass"
    action: "/do_form", method: "post"
    [
        $.el.input
            type: "text"
            name: "last_name"
            placeholder: "Last name"
        $.el.input
            type: "text"
            name: "first_name"
            placeholder: "First name"
        $.el.div
            class: "action"
            $.el.input
                type: "submit"
    ]

I created a simple jQuery extension that does the trick (I created an "el" namespace to avoid collisions). The usage is as follows:

$.el.<html element name>(htmlAttributes, content)

...where content can be another call to $.el., or an array of such calls

So to create this:

<u><i>This is underlined italicized</i></u>

You would write:

$.el.u {},
    $.el.i {}, "This is underlined italicized"

And to create this:

<ul class="my_class">
    <li>First item</li>
    <li>Second item</li>
    <li>Third item</li>     
</ul>

You would write:

$.el.ul {class: "my_class"},
    [
        $.el.li {}, "First item"
        $.el.li {}, "Second item"
        $.el.li {}, "Third item"
    ]

This simplifies the HTML generation and gets rid of a bunch of messy string interpolation and concatenation.

The jsFiddle is here: https://jsfiddle.net/jplato/tv1Lqa52/8/ and I would welcome any feedback on how to improve it.

If you are creating very large DOM element, I would definitely recommend using javascript template ( Handlebars is my favorite)

If you are creating small piece of DOM, there is an elegant way of doing that. ie put all the attributes into {}.

like : $("tagName",{attr1: value1, attr2, value2....});

For example if we want to create a simple form

<form action="google.com">
    <input type="text" value="hello" class="red-border">
    <button type="submit">click me</button>
</form>

Using this code is more readable than putting everything into a giant string, and also easier to bind events to each element

var form = $("<form/>",{
        action: "google.com"
    });

var input = $("<input>",{
        type:"text", 
        value:"hello",
        class:"red-border"
    }).appendTo(form);

var button = $("<button/>",{
        text:"click me", 
        type:"submit",
        style:"font-size:20px"
    }).appendTo(form);

button.click(function(){
    alert("clicked");
})

form.appendTo($("#container"));

FIDDLE LINK

Teacup is, in my opinion, the best solution to this. Your first example might be something like (UNTESTED):

render ->
  form '.my_form'
    action: submitURL
    ->
      input type: 'text', ->
        ...

And your second example (again, UNTESTED):

render ->
  form '#enrollment_form.myFormClass',
    action: '/do_form'
    method: 'post'
    ->
      input type: 'text', name: 'last_name', placeholder: 'Last name'
      input type: 'text', name: 'first_name', placeholder: 'First name'
      div '.action', ->
        input type: 'submit'

That looks pretty close to, if not cleaner than, your example.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM