what is the best way to create elements?

Asked

Viewed 142 times

5

for(var i=0; i< numTotalPerguntasDig; i++){

strInterface +=

            "<ul>"+
            "<li class=\"col-md-2 \">"+
            "   <button type=\"button\" class=\"btn btn-danger btn-info-bloco form-control\">"+
            "       <span class=\"glyphicon glyphicon-plus-sign\" aria-hidden=\"true\"></span>" +
            "       <span class=\"texto-btn\">/span>"+
            "   </button>"+
            "</li>"+*/
            "<li class=\"col-md-2 \">"+"<input type='text' class='info-1 form-control' style='width: 100%' value='"+arraySeq[i]+"'/>"+"</li>"+
            "<li class=\"col-md-6 \">"+"<input type='text' class='info-2 form-control'  placeholder='Digite'/>"+"</li>"+
            "<li class=\"col-md-2 \">"+
            "   <select class='info-3 form-control'>"+
            "       <option value='1'>1</option>"+
            "   </select>"+
            "</li>"+
            "<li class=\"col-md-2\">"+
                "<button class='btnadd btn btn-danger btn-sm form-control' value='x'><span class='glyphicon glyphicon-remove' aria-hidden='true'></span> </button>"+
            "</li>"+
            "</ul>";


menu.append(strInterface);

}

append or createElement?

What is the best or most visual way to understand the code in a future maintenance?

  • Look, they’re both legible, the createElement will require a few more lines, but nothing problematic, in any case the biggest problem above is this concatenation of strings, in this case the use of a Template Engine will make your code much cleaner.

  • do you have any indication of template engine? angular.js can be used as a template engine?

  • Denali, I posted an example with Handlebars, the advantage of it is independent of jQuery, so it can be used with whatever library. you can also use the Mustache, Jsrender.

  • Denali, I believe it is possible, but I believe that the Angularjs template engine is quite dependent on its structure, using it stand-alone can be quite complicated, so if you’re using Angularjs, use the Angularjs Template Engine, or choose another of your preference,

5 answers

6

Using jQuery it is possible to create an element in a way that I particularly consider more elegant, but each element needs to be created individually.

div = $("<div>", {
  "class" : "novo_elemento segunda_classe",
  id : "elemento_teste",
  height : "150px",
  width : "200px"
});

$("body").html(div);
#elemento_teste{
    border: solid 1px red;
}

.novo_elemento{
    background: black;
    height: 100px;
    width: 200px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

With this method you can add this element created using .append(), .prepend(), .appendTo(), .prependTo() and .html().

So you get an elegant statement of your element and can apply it in the way you most deem appropriate.

A "negative" point of creating an element in this way is the need to individually create each element which makes the initial creation more laborious, but this is also a positive point, as it also guarantees you greater control over each of them and makes it possible to reuse them, thus facilitating the maintenance of your code.

Just as an example of how this can help you get your code better maintained you can for example create templates of elements and from there modify only their particularities

Example:

inputDefault = $("<input>",{
    "class" : "input",
    name : "Input",
    type : "text"
});

inputAge = inputDefault.clone().attr({
    name : "age"+inputDefault.attr("name"),
    type : "number",
    placeholder: "Idade"
});

inputName = inputDefault.clone().attr({
    name : "name"+inputDefault.attr("name"),
    placeholder: "Nome"
});

$(".inputs").html(inputName)
	.append("<br>")
	.append(inputAge);
.inputs{
    background: #f0f0a0;
    border: 2px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="inputs"></div>

  • Erlon, I believe that Denali’s doubt is about keeping the code clean and with simpler maintenance, and setting up the menu creating all the tags in this way will not make the code very readable and let alone facilitate a future maintenance...

  • According to the example I posted it can create templates of menu items, and go modifying each item according to the need, only it would be interesting to have well defined a skeleton and a pattern. The bigger job would be to define and create the skeleton, from there until creating a menu with 500 items (hyperbole) would not be such an arduous and painful task.

  • In his HTML the only thing that changes in the for is value of input class="info-1..., then even dynamizing this value within a loop is easier with a defined skeleton. But your answer was also good @Tobymosque.

  • 1

    Erlon, I assumed that his example was just an example, and that his doubt was about readability when it came to building dynamic client-side content, although he agrees that in the example above his response is readable and easy to maintain, however the script can become quite complex depending on the data model. and don’t get me wrong, despite the criticism I found your response good, so much so that I gave +1 her.

  • Agree, thinking about final performance also I would already send a html ready pro client-side If it’s an absurdly long menu, it could hurt the page loading. But glad he got a solution to his problem, congratulations on the suggestion. : D

  • Mounting HTML on the server is not always the best performing option, remember that the template can be a separate file on the server and be stored on the client using the localStorage, thus allowing the reuse and decrease of data traffic.

  • I know, but in the vast majority of cases just displaying a ready HTML brings significant differences.

  • I am mounting the dynamic menu entirely on client-side. is there any problem? depends on the user’s machine too, is not?

  • There are some aspects to be evaluated, the user’s machine is one of the factors, but before that as you mount this menu in the client-side, looks for some performance tool to check how is the use page, so you will have how to evaluate the best solution for your case. As @Tobymosque said there are situations where the server-side slow due to high data load or poor quality of the hosting server.

Show 4 more comments

4


as I said, it is best not to use string concatenation, follow an example with the use of Handlebars (Template Engine).

Note that it is possible to add loops and conditions within your template. another important point to note is that the element <script type="text/template"></script> is ignored by the browser at render time, so it will only be used by the script (no impact on the initial page loading).

The two great advantages of this approach is to keep the script clean, just as the content of the template is much closer to the final HTML, with no escape characters (""") or concatenations ("" + variable + "").

var model = {
  perguntas: ["Banana", "Maça", "Pera"]
};

var menu = $("#menu");
var source  = $("#tmlMenu").html();
var tmlMenu = Handlebars.compile(source);
var menus = $.parseHTML(tmlMenu(model));

menu.append(menus);
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/3.0.3/handlebars.js"></script>
<div id="menu">

</div>

<script id="tmlMenu" type="text/template">
  {{#each perguntas}}
  <ul>
    <li class="col-md-2 ">
      <button type="button" class="btn btn-danger btn-info-bloco form-control">
        <span class="glyphicon glyphicon-plus-sign" aria-hidden="true"></span>
        <span class="texto-btn"></span>
      </button>
    </li>
    <li class="col-md-2 "><input type='text' class='info-1 form-control' style='width: 100%' value='{{this}}'/></li>
    <li class="col-md-6 "><input type='text' class='info-2 form-control'  placeholder='Digite'/></li>
    <li class="col-md-2 ">
      <select class='info-3 form-control'>
        <option value='1'>1</option>
      </select>
    </li>
    <li class="col-md-2">
      <button class='btnadd btn btn-danger btn-sm form-control' value='x'><span class='glyphicon glyphicon-remove' aria-hidden='true'></span></button>
    </li>
  </ul>
  {{/each}}
</script>

  • If I may play devil’s advocate here, in what sense exactly string concatenation is worse than loading and using an external library, which in turn will probably make its own string concatenations (plus a lot more)?

  • 1

    @mgibsonbr, even agree that for the above example the use of a Template Engine can be an exaggeration, especially if the only part of the system that needs this approach is the menu, another point, this blibioteca does not necessarily use string concatenation, it can make replacements using Regex as in example. For something simpler we can simply combine this formatting function with Wallace’s answer.

2

With jQuery you can create the element to define its attributes dynamically as follows:

$('<button/>', {
    class: 'btn btn-danger btn-info-bloco form-control',
    name: 'btn-login',
    text: 'Login'
}).appendTo('#form');

Practical and visually elegant.

2

Another way is by using the tag script with a type different.

Example:

$(function()
{
   $('#container').append($('#tpl').html());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script type="text/template" id="tpl">
      <div class="x">
        <p class='y'>Olá mundo</p>
  </div>
</script>

<div id="container"></div>

This happens because the content within script with the type text/template is not interpreted as javascript!

  • This one I didn’t know! + 1

  • Wallace, her HTML has a little bit of non-static.

  • 1

    In this case we can use undescore.js to parse this template by sending data.

1

One option is to use a ready text, add in the DOM, and then change only what you need. Assuming jQuery:

var item = "<li class=\"col-md-2 \">"+
            "   <button type=\"button\" class=\"btn btn-danger btn-info-bloco form-control\">"+
            "       <span class=\"glyphicon glyphicon-plus-sign\" aria-hidden=\"true\"></span>" +
            "       <span class=\"texto-btn\">/span>"+
            "   </button>"+
            "</li>"+*/
            "<li class=\"col-md-2 \">"+"<input type='text' class='info-1 form-control' style='width: 100%' value=''/>"+"</li>"+
            "<li class=\"col-md-6 \">"+"<input type='text' class='info-2 form-control'  placeholder='Digite'/>"+"</li>"+
            "<li class=\"col-md-2 \">"+
            "   <select class='info-3 form-control'>"+
            "       <option value='1'>1</option>"+
            "   </select>"+
            "</li>"+
            "<li class=\"col-md-2\">"+
                "<button class='btnadd btn btn-danger btn-sm form-control' value='x'><span class='glyphicon glyphicon-remove' aria-hidden='true'></span> </button>"+
            "</li>";

for(var i=0; i< numTotalPerguntasDig; i++){
    var elemento = $(item);
    elemento.find(".info-1.form-control").val(arraySeq[i]);
    menu.append(elemento);
}

Thus the structure of the HTML to be inserted is evident, and concatenation is only done once. The actual variable part occurs directly in the DOM (i.e. must be very efficient).

Browser other questions tagged

You are not signed in. Login or sign up in order to post.