How to update existing template row in HTML/JS - javascript

I'm considering using a template to dynamically create rows in a web application to gradually update the page as the server sends new data after it finishes its calculations. Creating new rows with the template works fine, but I was wondering how I could update the information in existing rows created using the template, or if it is even possible to update existing rows using templates.
<!-- reusable template for row objects -->
<template id="post_template">
<!-- template content -->
<div class="card mb-3 animated fadeIn shadow-sm">
<div class="cared-body">
<h4 class="card-title" id="title"></h4>
<span class="text-muted" id="content"></span>
</div>
</div>
</template>

Related

Dynamically created Bootstrap collapse in Angular 6 not working

In Angular 6 I iterate through a data set in order to dynamically create an accordion/collapse. The issue is that Bootstrap is initialized at page load, however, this accordion is created after page load, after an API call. So after the accordion is rendered, its is not interactive, as the new DOM elements were not picked by the initilization of bootstrap at page load.
If I could just get bootstrap to re-initialize from the JS entirely, that would be perfect.
Otherwise I need to find a way to re-initialize Bootstrap collapse so that it picks up all of the new DOM additions that are created. Here is the markup. Ive tried $('.collapse').collapse() like the docs say but that only collapses the content, it does not initialize the controls to toggle the content.
<div id="accordion" *ngIf="data && data.length > 0">
<!-- Chart -->
<div class="card" *ngFor="let chart of data; let chartIndex = index">
<div class="card-header" id="heading{{chartIndex}}">
<h4 class="mb-0">
<a href="#"
class="acc-btn"
data-toggle="collapse"
data-target="#collapse{{chartIndex}}"
aria-expanded="true">
<span class="fa fa-chevron-up"></span>
<span class="fa fa-chevron-down"></span>
{{chart.sectionName}}
</a>
</h4>
</div>
<div id="collapse{{chartIndex}}" class="collapse show" data-parent="#accordion">
<div class="card-body">
<table class="scenario">
<tr>
<th *ngFor="let header of chart.headers">{{header}}</th>
</tr>
<tr *ngFor="let row of chart.data">
<td *ngFor="let value of row"><app-parent-child-data-list [data]="value"></app-parent-child-data-list></td>
</tr>
</table>
</div>
</div>
</div>
</div>
You should not mix Angular and JQuery together. They will conflict with each other since both will be manipulating the DOM and each will have issues knowing that the other made changes.
The best solution would be to use something like NG-Bootstrap which is a pure Angular implementation of most of Bootstrap JQuery code. https://ng-bootstrap.github.io/#/home
If you were only using the accordion, you could also write your own simple function to toggle the accordion hidden/shown classes, but as your app grows you may find adding NG-Bootstrap would just be easier.

Dygraph will not display in Bootstrap card

I want to create a dygraph graph within the Bootstrap card body's second column (it just looks nice and clean). The div used by dygraph is graphdiv. I am using this.$refs.graphdiv to try to access it from within my vue script.
If I move the graphdiv <div> outside the card div then it works (see the comment). Why will the dygraph not work within the bootstrap card? Is it just one of those compatibility things one must log with the developer and wait for a fix?
<template>
<div>
<div class="card">
<div class="card-header">HEADER</div>
<div class="card-body">
<div class="row">
<div class="col-sm-3" style="width: 100%">
</div>
<div class="col-sm-9">
<div id="graphdiv" style="width: 100%" ref="graphdiv"></div>
</div>
</div>
</div>
</div>
</div>
<!--Comment: IF I PLACE IT HERE IT WORKS -->
</div>
</template>
Here is a reduced version of script:
<script>
import Dygraph from "dygraphs";
export default {
methods:{
plot_chart_series() {
//dataset = my data that I want to plot
const g = new Dygraph(this.$refs.graphdiv, dataset, {//options});
}
}
};
<script>
P.S.
My reason for using dygraph is I want to plot a dataset which is rather large (+-30000 datapoints), chart.js and Apexchart cannot manage that (I spent the better part of 3 hours trying to get them working). If there is no fix for my issue above, which other graphing libraries are there which are Vue friendly which can handle large datasets?
Workaround
I have managed to find a work-around and I can at least relatively narrow the problem and say that I do not think it is bootstrap.
<div class="card" ref="carder">
<div class="card-header">Graph</div>
<div class="card-body">
<div class="row">
<div class="col-sm-3">
<button>A_BUTTON</button>
</div>
<div class="col-sm-9">
<div ref="graphdiv" style="width: 100%"></div>
</div>
</div>
</div>
</div>
The above code snippet worked for me.
Changes to original:
I had an id="some_id" property in the containing parent div which I removed.
The entire card was wrapped in another div. This div had a ref="some_ref" property which I used from the Vue script to toggle the visibility. I did this with this.$refs.some_ref.style.display = "block"; & this.$refs.some_ref.style.display = "none";. I changed it to the following this.$refs.some_ref.style.visibility = "hidden"; and just changed the hidden to visible when I wanted to show the card. (It does not bother me that the hidden element still consumes space)
If I revert change number 2 above to the original then it fails to display. I still cannot explain it but it works.

How can I select an Animatedmodal to display different demos using one ID

I have a website that i am trying to personalize and I am trying to use the AnimatedModal.js framework. I have been able to display some content in one modal, but when it comes to make several modal it gets tricky, because there is just one ID. My question i, how can i use the same ID and change the content for other modals(demo03,demo04..etc.), in order to personalize each.
I will put some code in order to understand the problem
I have been reading the documentation but I am still stuck in this problem.
<!-- single work -->
<div class="col-md-4 col-sm-6 ads graphics">
<a id="demo02" href="#animatedModal" class="portfolio_item">
<img src="img/portfolio/03.jpg" alt="image" class="img-responsive" />
<div class="portfolio_item_hover">
<div class="portfolio-border clearfix">
<div class="item_info">
<span>Should open here </span> <em> ads / Graphics </em>
</div>
</div>
</div>
</a>
</div>
<!-- end single work -->
Then I have the demo where it displays the content of the modal, where it has the #animatedmodal ID
<div id="animatedModal" class="popup-modal ">
<!--THIS IS IMPORTANT! to close the modal, the class name has to match the name given on the ID -->
<div id="btn-close-modal" class="close-animatedModal close-popup-modal">
<i class="ion-close-round"></i>
</div>
<div class="clearfix"></div>
<div class="modal-content ">
<div class="container">
<div class="portfolio-padding" >
Hello World
</a>
</div>
</div>
</div>
</div>
this is my Js file where there is just one element assigned to it, to avoid showing the same content into all different classes.
$("#demo02").animatedModal();
I don't think it can be done without hacking the plugin.
As a matter of fact, the script jQuery.animatedModal ALWAYS TARGETS the page element which has id="animatedModal"
You can see the plugin source code here:
https://cdn.jsdelivr.net/npm/animatedmodal#1.0.0/animatedModal.js
...
//Defaults
var settings = $.extend({
modalTarget:'animatedModal',
...
Here is the AnimatedModal reference:
https://joaopereirawd.github.io/animatedModal.js/
At the bottom of the page, I can't see any OPTION regarding how to specify a different target, all options are about styles and animation features.
At this point, I think the only way to allow multiple modals on the same page is to rewrite the plugin, but I'm pretty sure you don't want to choose this way.

Check if Class exists through the DOM using Angular

I have a bunch of pages following the same layout but some of them have a "secondary" navigation bar at the top. When this navigation bar exists I have to push the main content down from the page using margin-top in the less.
My issue is I can't find a clean way of doing this just through the DOM.
sample.html
<!-- The secondary navigation below the header -->
<div class="navigation-row text-center">
<div class="col-xs-offset-2 col-xs-8 text-center">
<h4> Sample Page </h4>
</div>
</div>
<!-- Main Content -->
<div class="row">
...
index.html (inherited template that every page uses)
<!-- Main Content -->
<div class="content container-fluid">
<div ng-class="{'secondary-nav' : document.getElementsByClassName('navigation-row').length > 0}" ui-view="main"></div>
</div>
So basically in my main content section I am trying to check if the class navigation-row exists on the page (navigation-row is the class for the secondary navbar) and if it does then add the class secondary-navbar-padding to the div.
I have tried using angular.element which looks like
<div class="row" ng-class="angular.element($document).hasClass('navigation-row') ? 'secondary-navbar-padding' : ''">
but it didn't work. Is this even possible to do? Am I approaching this incorrectly or if there is a suggestion for a better cleaner way to do this I would be open to do that also.
I think you are only checking if the document element itself has that class.
You can count the number of elements with that class like this:
document.getElementsByClassName('navigation-row').length
So you could use ng-class this way:
<div class="row" ng-class="{'secondary-navbar-padding' : document.getElementsByClassName('navigation-row').length > 0}">

How do I put a couple of elements inside template?

I need to create templates in handlebars for an html page and the whole html should go inside of templates. For e.g. I have:
<div class= "something-pull-left-something">
<div class="someclass">
<li a href= ''>Some more info and some more divs and spans and html code</li>
</div>
</div>
and I should create a big template for the first div ''something-pull-left-something'' and smaller templates inside of it for the other items and I cant quite understand how this should happen.
Divide it up into parts as it makes sense. Try to avoid having one huge template. Instead, make one template that includes a number of other templates. You may run into performance issues but worry about that later -- it is likely not an issue.
Make main template which contains header, body and footer.
Add partials to the main template.
If you wants to use Bootstrap then you can go through this http://getbootstrap.com/components
or you can use bootstrap class
<div class="container">
<div class="col-md-12">
//code
</div>
<div class="col-md-12">
<div class="col-md-6">
//code
</div>
<div class="col-md-6">
//code
</div>
</div>
</div>

Categories