How to auto indent html written as a string? - javascript

I have a looong string of HTML inside a Javascript.
Is there any way I can auto indent it?
The conventional way in Sublime Text (pressing F12) won't work because Sublime doesn't know it's HTML.
Here's a portion of it:
'<ul class="obj-ul">' +
'<li ng-repeat="(key, val) in argVal">' +
'<p class="arg-key">{{key}}</p>' +
'<span class="arg-colon">:</span>' +
'<div ng-if="utils.isPrimitive(val)" class="inline-block">'+
'<p ng-click="editVal=!editVal" ng-show="!editVal" class="arg-val">{{argVal[key]}}</p>' +
'<input ng-show="editVal" ng-model="argVal[key]" ng-blur="editVal=!editVal" class="arg-val" />' +
'</div>'+
'<div ng-if="!utils.isPrimitive(val)" class="inline-block">'+
'<rapid-args arg-val="argVal[key]"></rapid-args>' +
'</div>'+
'</li>' +
'<div ng-if="utils.showButtons.showButtonInObject(templateArgVal)">' +
'<button ng-click="vars.show_addObjectItem=!vars.show_addObjectItem">+</button>'+
'<div ng-if="vars.show_addObjectItem" class="add-item">'+
'<input ng-model="newKey" type="text" class="arg-key"/>'+
'<span class="arg-colon">:</span>' +
'<div id="new-value">'+
'<div ng-if="!vars.show_addObjectValue" class="value-types">'+
'<p ng-click="objects.addItem(argVal, newKey, \'array\'); vars.show_addObjectItem=!vars.show_addObjectItem" class="value-types-type">Array</p>'+
'<p ng-click="objects.addItem(argVal, newKey, \'object\'); vars.show_addObjectItem=!vars.show_addObjectItem" class="value-types-type">Object</p>'+
'<p ng-click="vars.show_addObjectValue=!vars.show_addObjectValue" class="value-types-type">String</p>'+
'<p>{{showValInput}}</p>' +
'</div>' +
'<div ng-if="vars.show_addObjectValue">'+
'<input ng-model="newVal" type="text" class="arg-key"/>'+
'<button ng-click="objects.addNewKeyVal(argVal, newKey, newVal); vars.show_addObjectValue=!vars.show_addObjectValue">&#10003</button>'+
'<button ng-click="vars.show_addObjectValue=!vars.show_addObjectValue">Cancel</button>'+
'</div>' +
'</div>' +
'</div>' +
'</div>'+
'</ul>' +

Sort of what Mouser suggested in a comment, you're going to have to remove the apostrophe's and plus signs from this code using a find+replace tool (notepad++ has one, I'm sure sublime will have one too) then do your formatting thing with F12 in sublime and then re-add your apostrophe's and plus signs using regex.
Here's a demonstration of how to remove your string formatting using Notepad++ (or any Regex based find and replace string manipulator):
Find What: '(.*?)'[\s]?\+
Replace With: $1
To add them back again after you've formatted you can simply do:
Find What: (.*)
Replace With: '$1' +

Here's a way:
Remove all the quotes and + used to concatenate the different lines, i.e., make it a single string (you may use search-replace -> replace all) without any + in between to join.
Copy the resulting string and paste at http://www.freeformatter.com/html-formatter.html or any other online html formatter.
Copy the result and paste it back.
Hope it helps.

Related

Why is this regex replace function creating line breaks in my html body?

I want to replace hashtags in the body of an html page with a Bootstrap4 Modal.
Sometimes, this function causes line breaks right after the replaced text link. Sometimes it doesn't. I don't understand why.
function replaceBlank() {
document.body.innerHTML = document.body.innerHTML.replace(/#blank/g, '' +
'<a data-target="#blankMod" data-toggle="modal" href="#">' +
'Blank' +
'</a>' +
'<div class="modal fade" id="blankMod">' +
'<div class="modal-dialog">' +
'<div class="modal-content">' +
'<div class="modal-header">' +
'<h4 class="modal-title">' +
'Blank' +
'</h4>' +
'<button type="button" class="close" data-dismiss="modal">' +
'x' +
'</button>' +
'</div>' +
'<div class="modal-body">' +
'Blank Text Body' +
'</div>' +
'</div>' +
'</div>' +
'</div>');
}
Do you ever run it more than once on the same page?
The text you are inserting contains the string you are replacing (the data-target="#blankMod" bit).
You are using the /g flag, so multiple replaces in one step will still work fine; but the second time you call it, it is bound to go a bit crazy.
If that is the problem, you could either stop using that data-target name, or you could capture a bit more context of where "#blank" appears in your document. (lookbehind/lookahead regex asserts are ideal for this, but require the latest versions of JavaScript, so may give browser compatibility issues.)
I discovered that the line breaks only occurred within paragraph <p> tags.
The replacement text was ending the <p> tag, and everything after it was considered a new paragraph.

Apply filters in AngularJS controller

I am newbee to angular and have this filter to translate the text (localization) which works well in my html/view:
<input type="button" class="btn btn-link" value="{{'weeklyOrdersPage.reposting' | translate}}" ng-click="sortBy('reposting')" />
What this does is to take the value from one resource file and display text and it works very well.
Now, I need to do something similar in controller where I am rendering a google map using javascript api. I need to set the text of the marker based on the language i choose. I tried this and it didn't work:
var markerConter = '<div class="infoWindowContent">' +
'<div><b>' + $filter('translate')("{{'weeklyOrdersPage.panelId'}}") + ': </b>' + panel.id + '</div>' +
'<div><b>' + $filter('translate')("{{'weeklyOrdersPage.panelClassification'}}") + ': </b>' + panel.panelClassification + '</div>' +
'<div><b>' + $filter('translate')('{{weeklyOrdersPage.quality}}') + ': </b>' + panel.format + '</div>'
'</div>';
Any pointers on how to move forward?
You don't need to use {{}} when writing code in controller
$filter('translate')('weeklyOrdersPage.panelId')
$filter('translate')('weeklyOrdersPage.panelClassification')
$filter('translate')('weeklyOrdersPage.quality')
That should solve the problem.

append jquery does not work

i am creating a search suggestion and i want to create a div and put suggestion elements like full name, image and ... in it.
so i have a empty div in my HTML code that my suggestions will be added to it.
<input type="text" name="query" autocomplete="off" id="base_main_search_box">
<button type="button" value="" id="base_main_search_box_button"></button>
<div id="main_searchSuggestion">
</div>
i want to appear search suggestions when user key up in input type.
so i create jQuery function.
my jQuery function is:
$('#base_main_search_box').keyup(function () {
$.ajax({url:'http://localhost:8000/search_suggestion/',success:function(result){
$(addSuggestion).append('<div class="base_searchSuggestionItem">' +
'<img src="' + result.movie_images[i] + '" class="base_searchSuggestionItem_image">' +
'<div class="base_searchSuggestionItem_info">' +
'<p class="base_searchSuggestionItem_info_name">' +
'<a href="">' +
result.movie_names[0] +
'</a>' +
'(' +
result.movie_yearProduction[0] +
')' +
'</p>' +
'<p class="base_searchSuggestionItem_info_description">' +
result.movie_descriptions[0] +
'</p>' +
'</div>' +
'</div>');
console.log('final: '+addSuggestion.innerHTML);
}
}});
});
the output is:
"final: undefined"
it is not correct.
As per the docs
.html() is not available on XML documents so you need to add it to DOM before setting or checking its HTML.
change the sequence as following
$(addSuggestion).append(search_item);
$(search_item).html(
div_innerHTML
);
console.log('div_innerHTML: '+div_innerHTML);
console.log('search_item: '+$(search_item).innerHTML);

Javascript break then back on to print html?

In php, if I'm echoing html I would usually break PHP then turn it back on again. Even if I had one variable in the middle e.g.
echo " ?>
<div class="className">Hello World</div>
<div class="className">it's a <?=$kindOfDay?></div>
<div class="className">day today</div>
<? "; ?>
Is there a way to do something similar in javascript? To allow me an easier way to write e.g.
html += '<div class="className">Hello World</div>';
html += '<div class="className">it\'s a ' + kindOfDay + '</div>';
html += '<div class="className">day today</div>';
Maybe this?
html = '<div class="className">Hello World</div>' +
'<div class="className">it\'s a great</div>' +
'<div class="className">day today</div>';
Arrays are the best for this, Try:
var kindOfDay = 'great',
html = ['<div class="className">Hello World</div>',
'<div class="className">it\'s a '+ kindOfDay + ' great</div>',
'<div class="className">day today</div>'].join('');
You could put the three elements into a single string, but there is not really any easier way to write it.
Edit:
To use a multi-line string in javascript, you can do
html +=
"This \
is \
a \
sentence.";
Keep in mind that some browsers will insert newlines, and some wont.

Dynamic angularjs template

I am trying to create a directive this way -
scope.nodeTemplate = '{{node.nodeText}}';
Part of template
'<ul>' +
'<li class="tree-node" data-ng-repeat="node in nodes">' +
'<span>' + scope.nodeTemplate + '</span>' +
'</li>' +
'</ul>'
Based on some condition I would like to change the nodeTemplate and it can be an html string like -
'<input type="text"/>'
But the issue is when it try to do this thing angular does not render the html. It simply puts the html string. I am kind of stuck here. Can someone suggest some solution?
You need to use ng-bind-html-unsafe like:
'<span ng-bind-html-unsafe="nodeTemplate"></span>'

Categories