Writing HTML in JavaScript - javascript

I've got this div in my HTML that I want to add dynamically, but it's a lot of HTML to put inside a JavaScript string I think, is there any other, or better ways to do it?
I am programming in MVC if anyone know some tricks there
My HTML
<div class="container">
<div class="panel panel-info col-lg-10 col-lg-offset-1 added-panel">
<div class="panel-heading">Random1 - Random2</div>
<div class="panel-body">
<div>Random3</div>
</div>
</div>
</div>
My jQuery
$('#mybtn').click(function () {
$('#mydiv').append('<div class="container"><div class="panel panel-info col-lg-10 col-lg-offset-1 added-panel"><div class="panel-heading">Random1 - Random2</div><div class="panel-body"><div>Random3</div></div></div></div>');
});

You can create a template which can be read when required. By using script with "text/template" as type.
Here's an example.
$(document).ready(function() {
$('button').click(function() {
$('#mydiv').append($('#templateId').html());
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>button</button>
<div id="mydiv">mydiv</div>
<script type="text/template" id="templateId">
<div class="container">
<div class="panel panel-info col-lg-10 col-lg-offset-1 added-panel">
<div class="panel-heading">Random1 - Random2</div>
<div class="panel-body">
<div>Random3</div>
</div>
</div>
</div>
</div>
</script>

You can write HTML-code in Javascript function inside in /* comment */ and convert this function to text with method functionname.toString() and parsig text between "/*" and "*/" that works in all old browsers.
Example:
function myfunc()
{/*
<div class="container">
<div class="panel panel-info col-lg-10 col-lg-offset-1 added-panel">
<div class="panel-heading">Random1 - Random2</div>
<div class="panel-body">
<div>Random3</div>
</div>
</div>
</div>
*/}
function getLines(func)
{
var myhtml = func.toString();
var htmlstart = myhtml.indexOf('/*');
var htmlend = myhtml.lastIndexOf('*/');
return myhtml.substr(htmlstart+2, htmlend-htmlstart-2);
}
$('#mybtn').click(function () {
$('#mydiv').append( getLines(myfunc) );
});
This simple trick can be used also for sending XML, HTML or plain text via JSONP .

Generally, it's not the best idea to mix interests (HTML, JS, CSS). Keep it separate and use templating engines. However, of course you can put HTML into your Javascript files, I would format it properly.
var myTMPL = '<div class="container">' +
'<div class="panel panel-info col-lg-10 col-lg-offset-1 added-panel">' +
'<div class="panel-heading">Random1 - Random2</div>' +
'<div class="panel-body">' +
'<div>Random3</div>' +
'</div>' +
'</div>' +
'</div>';
and then use it like
$('#mydiv').append( myTMPL );

You could try having the html as a hidden element on the page and insert that. It tidies it up a bit:
<div id="myOtherDiv" style="display: none;">
<div class="container">
....... rest of html
</div>
</div>
script:
$('#mybtn').click(function () {
$('#mydiv').append($("#myOtherDiv").html());
});

Something like this: 1. Place all html to add into a new div named addingtext:
<div name="addingtext">
<div class="container">
<div class="panel panel-info col-lg-10 col-lg-offset-1 added-panel">
<div class="panel-heading">Random1 - Random2</div>
<div class="panel-body">
<div>Random3</div>
</div>
</div>
</div>
</div>
2. get all inner HTML (source) of your div named addingtext:
var stringtoadd = document.getElementsByName("addingtext").innerHTML;
Then
$('#mydiv').append(stringtoadd);

If you know angular.js you could create a separate html file for the text you want to add/replace and instead of replacing all the text through javascript you could just create <div ng-include="'html-with-text.html'"></div> with javascript.

There are many ways to do it (all the answers provided here works fine). But you need to choose an effective method to do it. I'm still learning the JS. So I really can't help you in choosing an effective method. But you can try this method too.
Instead of append(), you can also use load() (reference to the load() api)
Main HTML code:-
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>button</button>
<div id="myDiv">mydiv</div>
<div id = "addHere"> </div>
HTML of what you want to add (Suppose the title of this HTML is addon.html):-
<div class="container">
<div class="panel panel-info col-lg-10 col-lg-offset-1 added-panel">
<div class="panel-heading">Random1 - Random2</div>
<div class="panel-body">
<div>Random3</div>
</div>
</div>
</div>
Finally, your JS
$('#mybtn').click(function () {
$('#addHere').load('/addon.html');
});
This will place your addon HTML right after your div.

Related

How to get all strings and replace it with another from the database JavaScript

I apologize in advance for being weak English :(
My website looks like this:
https://scr.hu/LoDJpD
<div class="container-fluid">
<div class="col-sm-12 col-md-10 col-md-offset-1 col-lg-10 col-lg-offset-1 text-center">
<div class="card col-md-6 col-sm-6 row-2">
<div class="card-bg">
<div class="image" style="background-image: url('kwadrat.jpg');"></div>
<div class="title"><h1><hr>DNI OTWARTE<hr></h1></div>
<div id="big" class="text">#string/big</div>
</div>
</div>
<div class="card col-md-3 col-sm-3 row-2">
<div class="card-bg">
<div class="image" style="background-image: url('dlugi.jpg');"></div>
<div class="title"><h1><hr>PROJEKTY<br>UNIJNE<hr></h1></div>
<div id="small1" class="text">#string/small1</div>
</div>
</div>
<div class="card col-md-3 col-sm-3 row-2">
<div class="card-bg">
<div class="image" style="background-image: url('maly1.jpg');"></div>
<div class="title"><h1><hr>BUSINESS<br>ENGLISH<hr></h1></div>
<div id="small2" class="text">#string/small2</div>
</div>
</div>
<div class="card col-md-12 row-1">
<div class="card-bg">
<div class="image" style="background-image: url('banner.jpg');"></div>
<div class="title"><h1><hr>CZECHOMANIA<hr></h1></div>
<div id="bigwidth" class="text">#string/bigwidth</div>
</div>
</div>
</div>
</div>
I would like to convert the "#string/text" text to a variable from the database.
In the database, the variable also has the name "#string/text".
Right now I have a simple script, but I know it will be ineffective
text = document.getElementById("big").innerHTML;
lang = document.getElementById("jezyk");
function en(){
document.getElementById("jezyk").className="flag flag-gb";
}
function pl(){
document.getElementById("jezyk").className="flag flag-pl";
}
function useen(){
if(lang.className == "flag flag-gb" && text == "#string/big"){
document.getElementById("big").innerHTML="GB variable form database";
}
}
function usepl(){
if(lang.className == "flag flag-pl" && text == "#string/big"){
document.getElementById("big").innerHTML="PL variable form database";
}
}
setInterval(function jezyk(){
usepl();
useen();
jezyk();
}, 10);
Is there an easier way to retrieve text and replace it from the database?
Can somebody suggest some better and faster functions?
Use an object ( maybe retrieve it from server via JSON), like this:
var translate={
lang:["en","pl"],
values:{
curr_lang:["english","polish"],
info:["english text","polish text"]
}
};
So you can easily display a language chooser:
translate.lang.map(function(language){
var button=document.createElement("button");
button.textContent=language;
button.onclick=changeLanguage.bind(this,language);
document.body/* or a custom element*/.appendChild(button);
});
Traversing the whole dom is not that fast, so may just do it once, and replace all #identifier# with spans (may do this on serverside already and cache it):
document.body.innerHTML=document.body.innerHTML.split("#").reduce(function(part,i){
if(part%2===0) return part;
return "<span id='"+part+"' class='replace'>...</span>";
}).join("");
So the actual replacing is quite easy:
function changeLanguage(lang){
var index=translate.lang.indexOf(lang);
document.querySelectorAll(".replace").forEach(fumction(el){
var select=el.id;
el.textContent=(translate.values[select]||["error","error"])[index];
});
}
A sample text
This site is currently in #curr_lang# ...
The good way
Use some javascript frame work as Angular or React. It'll take some time to learn, but will be nice for you.
I'm not understanding what you want to do on this page, will those texts change frequently? Use setInterval will freeze your page, don't use it.

AngularJS - JQuery News Ticker - After moving news the javascript function doesn't get called

This is an awkward problem, which will be better explained by looking at the live demo. Basically I have a news box populated with ng-repeat using Angular. Then I am using a jquery plugin called news ticker which allows the news headlines to move around. The first time you land on the page the news items are in their proper spots and they call the function accordingly. After moving them up or down, they stop calling the function, set a breakpoint in the code and after moving the breakpoint is never hit.
Edit - After researching this further I have found that it is because the elements need to be compiled using $compile after they're re added. However following some examples I have not gotten this to work. I need a way of compiling after a move event with this plugin.
Live demo
Angular Script for with function that should be called.
$scope.UpdateNews = function (item,number) {
console.log(item + ' ' + number);
switch (item)
{
case 'General':
$scope.NewsCast.General.Body = $scope.News.GeneralNews[number].Text;
break;
}
};
What the HTML looks like with the news boxes
<script src="http://www.jqueryscript.net/demo/Responsive-jQuery-News-Ticker-Plugin-with-Bootstrap-3-Bootstrap-News-Box/scripts/jquery.bootstrap.newsbox.min.js" type="text/javascript"></script>
<div class="row">
<div class="col-md-6 col-lg-3">
<div class="panel panel-default">
<div class="panel-heading"> <span class="glyphicon glyphicon-list-alt logo-inverse pull-left"></span><b> General News</b></div>
<div class="panel-body">
<div class="row">
<div class="col-xs-12">
<ul class="demo1" style="overflow-y: hidden; height: 280px;" ng-model="Idk">
<li style="" class="news-item text-left" ng-repeat="item in News.GeneralNews"><strong>{{item.DateValue | date: "MMM dd yyyy"}}</strong> {{item.Preview}}<a class="FakeClickable" ng-click="UpdateNews('General',item.index)" data-target="#GeneralModal" data-toggle="modal">Read more...</a></li>
</ul>
<div ng-if="Width>768">
<div ng-include="'../pages/Modals/General/GENERAL_INLINE.html'"></div>
</div>
</div>
</div>
</div>
<div class="panel-footer"> </div>
</div>
</div>

wrapAll() is creating double the divs?

I have a container div with two divs inside of it, like such:
<div class="container">
<div class="child1"></div>
<div class="child2"></div>
</div>
I have wrapped another div around 'child1' and 'child2' but it's appearing twice which I haven't been able to fix:
$(".child1, .child2").wrapAll('<div class="style"></div>');
Which is rendering out as the following:
<div class="container">
<div class="style">
<div class="style">
<div class="child1"></div>
<div class="child2"></div>
</div>
</div>
</div>
But what I actually want is the following:
<div class="container">
<div class="style">
<div class="child1"></div>
<div class="child2"></div>
</div>
</div>
How do I go about fixing this? I have tried numerous other methods of trying to sort the double-append.
EDIT: The issue was jquery was firing twice, I moved the code out of the existing file and into a new file. Once I did this the answers below all worked.
Try:
$(".container > div").wrapAll('<div class="style"></div>');
Change you markup little bit, (just add common class)
<div class="container">
<div class="child1 child"></div>
<div class="child2 child"></div>
</div>
now use below code:
$( ".child" ).wrapAll( "<div class='style' />");
$(".child1").next().andSelf().wrapAll("<div class='style'/>");
Try it...
I ran this in fiddle and it seems to work fine... ??????
You can do this though...
$(".container").each(function() {
var ch1 = $(this).find('.child1');
var ch2 = $(this).find('.child2');
var st = $('<div class="style">');
st.append(ch1);
st.append(ch2);
$(this).html('').append(st);
});

Angular JS binding working only once in the page

I have a page where I do multiple binding to the same object (item, item2, message, messageType)
Though I placed the binding in several part of the page it works only the first time i placed. The objects are filled with ajax calls that return correctly the value (I logged them in the console)
What sounds even strange to me is that the <infomessage> directive has been used in several other places in the app (twice in the same page) and worked perfectly.
Do you have any idea on why these bindings don't work?
I even tried to $watch the objects and they are properly changes but seems that the view use the updated value only the first time
<div class="container" ng-app="MyApp" >
<div class="row" ng-controller="MyCtrl" >
<div class="col-lg-10">
<h3>...</h3>
</div>
<div class="col-lg-10">
<infomessage type="{{messageType}}" message="{{message}}"></infomessage>
</div>
<div class="col-lg-10">
Item: {{item.idbene_ext}} / {{item.id}} / {{item.img}}<br>
Ubicazione: {{item2.id}} {{item2.code}}
</div>
</div>
<div class="row" style="margin-top:20px">
<div class="col-xs-1"></div>
<div class="col-xs-4" ng-class="{'ubiBox':true,'ausilio-enabled':(item!=null),'ausilio-disabled':(item==null), 'boxfocus':(item==null)}">
<div ng-show="item==null">
<div class="number">1</div>
<img src="assets/images/disabled-128.png" width="100" class="img_none"/>
<h4> {{item.idbene_ext}} Select an item</h4>
</div>
<div ng-show="ausilio!=null">
<h4>Item:{{item.idbene_ext}}</h4>
</div>
</div>
<div class="col-xs-2"></div>
<div class="col-xs-4" ng-class="{'ubiBox':true,'ubi-enabled':(item!=null),'ubi-disabled':(item==null),'boxfocus':(item!=null) }">
<div ng-show="item==null">
<div class="number">2</div>
<img src="assets/images/Office-disabled-128.png" width="100" class="img_none"/>
<h4> Select the second item</h4>
</div>
<div ng-show="item!=null">
<h4>Item2 {{item2.code}}</h4>
</div>
</div>
<div class="col-xs-1"></div>
</div>
<div class="row">
<div class="col-lg-10">
<infomessage type="{{messageType}}" message="{{message}}"></infomessage>
</div>
<div class="col-lg-10">
Item: {{item.idbene_ext}} / {{item.id}} / {{item.img}}<br>
Ubicazione: {{item2.id}} {{item2.code}}
</div>
</div>
Here's the angularJS code
MyApp.controller("MyCtrl",function($scope,$http,Config,BarcodeService){
$scope.iditem2=-1
$scope.iditem=-1
$scope.item2=null
$scope.item=null
$scope.message=""
$scope.messageType=""
$scope.$on(BarcodeService.handleitem2,function(){
$scope.message=""
$scope.messageType=""
if($scope.item==null){
$scope.message="select an item before"
$scope.messageType="error"
}
$scope.iditem2=BarcodeService.id
$http
.post(Config.aj,{call:"item2.getitem2",id:$scope.iditem2})
.success(function(data){
$scope.item2=data.payload
})
})
$scope.$watch("item",function(){
console.log("---->",$scope.item)
},true)
$scope.$on(BarcodeService.handleitem,function(){
$scope.message="loading item"
$scope.messageType="info"
$scope.iditem=BarcodeService.id
$http
.post(Config.aj,{call:"item.getArticoloByIdMin",id:BarcodeService.id})
.success(function(data){
$scope.message="item loaded!!"
$scope.item=data.payload
})
})
})
Ok guys, got it!
The problem was lying in the fact that I have two in my application but i placed the ng-controller only on the first one.
This caused all the binding in the second div to fail because they were outside the controller.
I moved the ng-controller in the parent div that contains both and now everything works like a charm.
Thanks anyway to #wachme and #ivarni for taking care of my question.
Happy coding to *

Javascript: How to hide a div which is dynamically created?

I'm creating a div dynamically using the following code:
$('#pageTabContent').append($('\
<div class="tab-pane" id="'+user_id+'">\
<div class="extras_area">\
<div class="expand_heading">Header to be clicked</div>\
<div class="expandable_content">this should be expanded.</div>\
</div>\
</div>'));
This is expanded within this HTML:
<div id="right_column">
<ul id="pageTab" class="nav nav-tabs"></ul>
<div id="pageTabContent" class="tab-content"></div>
</div>
I now want to expand the .expandable_content when I click the .expand_heading. To do this, I'm trying something like this in my javascript:
$("#right-column").on("load", ".expand_heading", hide);
$("#right-column").on("click", ".expand_heading", function(){
$(this).next(".expandable_content").slideToggle(100);
});
Unfortunately, that doesn't work. I don't know how to hide the div correctly when it is dynamically created. Can anybody help me out here?
Working Demo http://jsfiddle.net/t3WVs/
$('#pageTabContent').append($('\
<div class="tab-pane" id="'+Math.random()+'">\
<div class="extras_area">\
<div class="expand_heading">Header to be clicked</div>\
<div class="expandable_content">this should be expanded.</div>\
</div>\
</div>'));
//$(document).on("load", ".expand_heading", hide);
$(document).on("click", ".expand_heading", function(){
$(this).next(".expandable_content").slideToggle(100);
});
// if needed default close expand
// $('.expand_heading').click();
Why don't just use display:none rule:
$('#pageTabContent').append($('\
<div style="display:none;" class="tab-pane" id="'+user_id+'">\
<div class="extras_area">\
<div class="expand_heading">Header to be clicked</div>\
<div class="expandable_content">this should be expanded.</div>\
</div>\
</div>'));

Categories