Reputation: 1743
My userinterface using REST API and getting data as a json. I append this data in HTML like below but my script files are very large and low readability.
So i am looking for a new way to import json data to HTML. Is there any way to do it with jQuery ?
I heard about sth. with AngularJS but i don't have no time to learn another fw or library. I want to do it with jQuery, if it is possible.
function publish_survey() {
$.ajax({
url : URL_API + URL_POLL,
type : 'get',
data : {'user_id' : user_id},
dataType: 'json',
success : function (response) {
console.log(response);
var html = '';
for (var i = 0; i < response.data.length; i++) {
var date = new Date(response.data[i].created_at);
var formatted_date = date.getDay() + ' ' + G_MONTHS[date.getMonth()] + ', ' + date.getFullYear();
html += '<div class="col-lg-2 col-md-3 col-sm-4 col-xs-6">' +
'<div class="mt-card-item" onclick="">' +
'<div class="mt-card-avatar mt-overlay-1">' +
'<img src="' + PATH_LAYOUT_IMAGES + '/poll_bg.png" />' +
'<div class="mt-overlay">' +
'<ul class="mt-info">' +
'<li>' +
'<a class="btn default btn-outline" href="javascript:void(0);" onclick="previewPoll(\''+response.data[i].id+'\');">' +
'<i class="fa fa-eye"></i>' +
'</a>' +
'</li>' +
'</ul>' +
'</div>' +
'</div>' +
'<div class="mt-card-content">' +
'<h3 class="mt-card-name">' + response.data[i].title + '</h3>' +
'<p style="font-size:10px;">' + formatted_date + '</p>' +
'<div class="mt-card-social">' +
'<button class="btn blue-hoki btn-block" onclick="selectPoll(this, \''+response.data[i].id+'\');">'+LANG.option.select+'</button>' +
'</div>' +
'</div>' +
'</div>' +
'</div>';
}
$('#poll-publish > .row').append(html);
}
});
}
Upvotes: 2
Views: 3503
Reputation: 6125
A lot depends on what browsers you have to remain compatible with. There are some things you can do to improve the existing code, but the best solution requires newer browsers (or a transpiler).
First, I'd recommend you use the extract method technique to separate the server-query logic from the formatting logic. (This works in any browser.) The reason for doing this is that it at least isolates the "make HTML" part of the code from the "query-the-server" part of the code, and can make the code clearer even if it's still fairly long. So consider this refactor:
function publish_survey() {
$.ajax({
url : URL_API + URL_POLL,
type : 'get',
data : {'user_id' : user_id},
dataType: 'json',
success : function (response) {
console.log(response);
var html = '';
for (var i = 0; i < response.data.length; i++) {
html += make_html_for_card(response.data[i]);
}
$('#poll-publish > .row').append(html);
}
});
}
function make_html_for_card(card) {
var date = new Date(card.created_at);
var formatted_date = date.getDay() + ' ' + G_MONTHS[date.getMonth()] + ', ' + date.getFullYear();
return '<div class="col-lg-2 col-md-3 col-sm-4 col-xs-6">' +
'<div class="mt-card-item" onclick="">' +
'<div class="mt-card-avatar mt-overlay-1">' +
'<img src="' + PATH_LAYOUT_IMAGES + '/poll_bg.png" />' +
'<div class="mt-overlay">' +
'<ul class="mt-info">' +
'<li>' +
'<a class="btn default btn-outline" href="javascript:void(0);" onclick="previewPoll(\''+card[i].id+'\');">' +
'<i class="fa fa-eye"></i>' +
'</a>' +
'</li>' +
'</ul>' +
'</div>' +
'</div>' +
'<div class="mt-card-content">' +
'<h3 class="mt-card-name">' + card[i].title + '</h3>' +
'<p style="font-size:10px;">' + formatted_date + '</p>' +
'<div class="mt-card-social">' +
'<button class="btn blue-hoki btn-block" onclick="selectPoll(this, \''+card[i].id+'\');">'+LANG.option.select+'</button>' +
'</div>' +
'</div>' +
'</div>' +
'</div>';
}
This doesn't fundamentally alter the behavior of the code; it just makes publish_survey()
easier to read and to reason about because it's shorter: All the HTML-formatting junk is in a single function that is responsible for just formatting HTML and doing nothing else. If you do this a lot, you could conceivably move all of the HTML-formatting functions together, and even move them into a separate JavaScript file so as to actually separate your application logic from your presentation code.
While that solution does move the HTML out of the way, what that solution doesn't address, though, is how to make the embedded HTML itself less ugly to look at: That encoded HTML is ugly, and it's painful to work with and maintain. Surely there must be a better way, which I think is really what your question is about.
Modern JavaScript (ES6) includes a new template literal (or template string), a new JavaScript feature designed to address exactly this problem. You use backtick (`) to wrap the string, instead of an apostrophe or double quote. Inside a template string, you can use newlines normally, and you can embed content with curly braces. So the make_html_for_card()
function becomes something like this, if you have support for template literals:
function make_html_for_card(card) {
var date = new Date(card.created_at);
var formatted_date = date.getDay() + ' ' + G_MONTHS[date.getMonth()] + ', ' + date.getFullYear();
return `
<div class="col-lg-2 col-md-3 col-sm-4 col-xs-6">
<div class="mt-card-item" onclick="">
<div class="mt-card-avatar mt-overlay-1">
<img src="{PATH_LAYOUT_IMAGES}/poll_bg.png" />
<div class="mt-overlay">
<ul class="mt-info">
<li>
<a class="btn default btn-outline" href="javascript:void(0);" onclick="previewPoll('{card[i].id}');">
<i class="fa fa-eye"></i>
</a>
</li>
</ul>
</div>
</div>
<div class="mt-card-content">
<h3 class="mt-card-name">{card[i].title}</h3>
<p style="font-size:10px;">{formatted_date}</p>
<div class="mt-card-social">
<button class="btn blue-hoki btn-block" onclick="selectPoll(this, '{card[i].id}');">{LANG.option.select}</button>
</div>
</div>
</div>
</div>
`;
}
The resulting code is considerably less unpleasant: It's just plain HTML, wrapped in backticks (`), and has {curly braces} around embedded content.
Sadly, not all browsers support this. Notably, IE does not, but Edge 13+ does, as well as Chrome 41+, Firefox 34+, and Safari 9.1+. (Full list of browser support is available here.)
If you have to have backward compatibility to a browser that doesn't support template literals, then your only chance for really cleaning up the code is to use a transpiler (like BabelJS), which lets you write modern JS code that uses things like template literals, and the transpiler then automatically converts the code into "older" JS code for browsers that can't handle the new features.
Upvotes: 4