Differentiate staticCards & Dynamiccards - javascript

From Json API, data are read and displayed in the HTML.
User can also add custom articles which are stored as staticCards object inside script tag.
Now i wanted to find the HTML which is rendering the staticCards and add a class only to those articles.
How can i differentiate ? staticCards & Dynamiccards (directly rendered from JSON API)
var staticCards = [{
"cardLayout": "comms-double-image",
"cardLabel": "STORY",
"cardTitle": "households receive their share of $3.4 billion",
"cardDate": "05 April 2017",
"fileReference": "/content/dam/caas/newsroom/images/2016-09-15-newsroom-habib-spoons-banner-image.png",
"imageFocus": "image-centre-focus",
"cardLinkURL": "#",
"cardLinkDTM": "data-tracker-id=\"cards_1_1\" data-tracker-type=\"button\" data-tracker_ei=\"cards_1_1\" "
}]
<script type="text/x-handlebars-template" id="comms-double-image">
<article class="card card-double cvp comms image" data-tags="">
<a href="{{link}}" class="link" data-tracker-id="{{trackerId}}" data-tracker-type="{{trackerType}}" data-tracker_ei="{{trackerEI}}">
<div class="mobile-wrapper">
<div class="background-container" style="background-image : url({{image}});">
<h4 class="eta font-low-impact">{{label}}</h4>
</div>
<div class="content">
<time datetime="{{date-time}}">{{date-time}}</time>
{{#xif "this.title > 45"}}
<h3>{{title}}</h3>
{{else}}
<h3 class="delta">{{truncate title 55}}</h3>
{{/xif}}
<p class="cta">{{link-desc}}</p>
</div>
</div>
</a>
</article>
</script>

Related

how to add <a> HTML tag or URL in object array in .ejs

I am new to creating array object , and I dont know how to add link in <a> tag in an array
object code:
powerUpList: [
{
id:1,
name:'Stack Export',
description:'Export your complete stack back in an excel sheet. ',
url: "https://help.stackby.com/article/145-export-stack-in-excel",
category:'Data Recovery',
status:0,
},
{
id:2,
name:'Microsoft Excel Importer',
description:'Import an excel file to create a new stack or import it to a table. ',
url: "https://help.stackby.com/article/146-excel-importer",
category:'Import',
status:0,
},
{
id:3,
name:'Append CSV file in an existing table',
description:'Import a CSV file into an existing table and map the columns to take the form of your table. ',
url: "https://help.stackby.com/article/144-import-data-in-an-existing-table",
category:'Data Transformation',
status:0,
},
],
powerUpCategoryList: [
'Data Recovery',
'Import',
'Data Transformation',
'Sharing',
'Automation',
'Apps',
],
this is my JS object code
and this is actual code in .ejs where all instance perform , and the accordian does not close ,
powerup.ejs
<div class="col-md-9" id="root">
<div role="tablist" id="accordion-1">
<%for (var i = 0; i < powerUpList.length; i++) { %>
<div class="card">
<div class="card-header" role="tab">
<a data-toggle="collapse" aria-expanded="true" aria-controls="accordion-1 .item-<%= i+1 %>" href="div#accordion-1 .item-<%= i+1 %>"><%= powerUpList[i].name%></a>
<%if (powerUpList[i].status == 0) { %>
<a class="live-lable status-live" >
Live
</a>
<%}else if(powerUpList[i].status == 1){-%>
<a class="live-lable status-comingsoon" >
Coming soon
</a>
<%}else if(powerUpList[i].status == 2){-%>
<a class="live-lable status-beta" >
In-Beta
</a>
<%}-%>
</div>
<div class="collapse show item-<%= i+1 %>" role="tabpanel" data-parent="#accordion-1">
<div class="card-body">
<p class="card-text" ><%= powerUpList[i].description%></p>
--------- HERE I WAnt to show **URL** as learn more
Learn more..
</div>
</div>
</div>
<%}-%>
</div>
</div>
here , I want to show in url: "https://help.stackby.com/article/145-export-stack-in-excel", in as download link , and open new window , but i don't know how to add in <a> tag in file
From what I understand, you can do
learn more

angular repeat with template?

I'm currently trying to figure out how to use templates in angular. At present, I'm playing with ui.router (angular-ui-router) but I can't find good documentation on how the templating language is used to embed a sub-template view, especially as relates to a repeating element for different model instances.
BACKGROUND:
I am basically converting a static-local-filesystem image uploader/manager to work with amazon S3. The background essentials are already worked out, now I'm trying to improve the UI itself by converting it from 10 year old javascript to angular.js. I have it 'working' for an all-in-one html page but would prefer to modularize it to make it more dynamic.
CONTEXT:
I get a list of objects under a given prefix back from a listObjectsV2() call to the AWS sdk via the s3 client. I parse the results to break it into a pseudo-directory tree then display one directory at a time starting at the [virtual] root dir just after the prefix. (FYI the prefix is a userid)
I built a UserDir object that uses a PseudoDir sub object to define a virtual directory with array properties for 'subdirs' (more PseudoDir objects representing virtual sub-directories) and 'images' (S3 objects that are image files of one type or another).
What I want to display for any given 'current' directory (e.g. "" or the user root) is first a list of folder icons for each the curDir.subdirs, then a thumbnail icon for each of the curDir.images.
QUESTION:
I already have this working from a single html file and even managed to figured out how to use ui.router to create a for the main page. Now I want to modularize it so that a different controller will handle folder icon/info behavior, and another for image icons/behaviors.
i.e. I have already started building a 'FolderController' and a 'ImageController' and would like the ngRepeat for 'image in curDir.images' for example, to invoke a state with it's own template but I can't seem to find an example on how to do that.
Here is the current all-in-one template code. But I would like to move each sub-block into a state for FolderController with a templates/folder.html template and one for ImageController with a templates/image.html but can't seem to find an example of how to write the syntax:
<!-- folders -->
<div ng-repeat="(folder, pDir) in subdirs" ng-controller="FolderController" ng-init="folderName=folder;awsObject=pDir">
<div id="{{folderName}}" class="Item">
<div class="Icon ui-draggable ui-draggable-handle">
<img id="{{folderName}}Icon" src="../../images/folder.png">
</div>
<div id="{{folderName}}Desc" class="Description">
<span id="{{folderName}}Name" class="filename" title="{{folderName}}/">{{folderName}}/</span>
</div>
</div>
</div>
<!-- images -->
<div ng-repeat="(filename, uImage) in images" ng-controller="ImageController" ng-init="uImage=uImage">
<div id="image{{uImage.hash}}" class="Item">
<div class="Icon ui-draggable ui-draggable-handle">
<img id="icon{{uImage.hash}}" ng-src="{{ uImage.thumbSrc }}"></div>
<div id="desc{{uImage.hash}}" class="Description">
<span id="name{{uImage.hash}}" class="filename" title="{{filename}}">{{filename}}</span>
<img id="thumb{{uImage.hash}}" src="../../images/tick_image-services.png" class="Check Right" ng-show="uImage.usedInLayout" title="Used in layout"><br />
<span id="date{{uImage.hash}}" ng-show="(uImage.mtime > 0)">Date uploaded: {{ uImage.mtime | date: 'EEE MMM dd yyyy' }}</span><br />
<span id="size{{uImage.hash}}" ng-show="(uImage.size > 0)">Size: {{ uImage.size | humanizeBytes }}</span><br />
<span id="dims{{uImage.hash}}" ng-show="((uImage.width > 0) && (uImage.height > 0))">Dimensions: {{ uImage.width }} x {{ uImage.height }} pixels</span><br />
<span id="aspect{{uImage.hash}}" ng-show="(uImage.aspectRatio)">Aspect Ratio: <span class="AspectRatio">{{ uImage.aspectRatio }}</span></span><br />
</div>
</div>
</div>
You can create two components, one for folders and one for images, see here for official docs.
A rough draft would look like:
angular.module('myApp').component('images', {
templateUrl: 'imageList.html',
bindings: {
images: '='
}
});
imageList.html:
<div ng-repeat="(filename, uImage) in images" ng-controller="ImageController" ng-init="uImage=uImage">
<div id="image{{uImage.hash}}" class="Item">
<div class="Icon ui-draggable ui-draggable-handle">
<img id="icon{{uImage.hash}}" ng-src="{{ uImage.thumbSrc }}"></div>
<div id="desc{{uImage.hash}}" class="Description">
<span id="name{{uImage.hash}}" class="filename" title="{{filename}}">{{filename}}</span>
<img id="thumb{{uImage.hash}}" src="../../images/tick_image-services.png" class="Check Right" ng-show="uImage.usedInLayout" title="Used in layout"><br />
<span id="date{{uImage.hash}}" ng-show="(uImage.mtime > 0)">Date uploaded: {{ uImage.mtime | date: 'EEE MMM dd yyyy' }}</span><br />
<span id="size{{uImage.hash}}" ng-show="(uImage.size > 0)">Size: {{ uImage.size | humanizeBytes }}</span><br />
<span id="dims{{uImage.hash}}" ng-show="((uImage.width > 0) && (uImage.height > 0))">Dimensions: {{ uImage.width }} x {{ uImage.height }} pixels</span><br />
<span id="aspect{{uImage.hash}}" ng-show="(uImage.aspectRatio)">Aspect Ratio: <span class="AspectRatio">{{ uImage.aspectRatio }}</span></span><br />
</div>
</div>
and your original html would look like:
<!-- folders -->
<div ng-repeat="(folder, pDir) in subdirs" ng-controller="FolderController" ng-init="folderName=folder;awsObject=pDir">
<div id="{{folderName}}" class="Item">
<div class="Icon ui-draggable ui-draggable-handle">
<img id="{{folderName}}Icon" src="../../images/folder.png">
</div>
<div id="{{folderName}}Desc" class="Description">
<span id="{{folderName}}Name" class="filename" title="{{folderName}}/">{{folderName}}/</span>
</div>
</div>
</div>
<image-list [images]="images" ></image-list>
EDIT
Here is an example plunker which shows a simple implementation of a component, with data binding and ng-repeat in it, no need for ui-router for what you asked for. Please note that the html I wrote above is a botched copy paste of what you wrote - so the double ng-repeat was a mistake, updated the html.

Populating a View from a data array of objects Angular

I have a data store in a variable requestData which I want to use in populating the notification component view
requestData = {
"bookId": "5e5bb8ac59441513cca2e64c",
"bookTitle": "Take Great Photographs",
"request": [
{
"_id": "5e21d286b3ee501ebc39d899",
"firstname": "Ibaji",
"lastname": "Offor"
},
{
"_id": "5e2c5a20aff8434278639ff5",
"firstname": "Cheksmate",
"lastname": "Fidelis"
}
]
}
the view is supposed to look like the image below after the view has been populated with the above data
this is the code for the notification.component.html
<section class="main profile " my-books>
<div class="profile-header">
<h1>Notifications</h1>
</div>
<div class="book-list-header">
<h2>Showing Recent Notifications</h2>
<!-- <span>(Confirm by click the recieved button once book is returned)</span> -->
</div>
<div history *ngFor="let item of requestData">
<a [routerLink]="['details']">
<h3>9:15 AM | Mon, Feb 11, 2019</h3>
<div class="first">
<span>
<span class="image-cropper" style=" width: 36px; height: 36px;">
<img src="assets/images/avatar.jpg" alt="profile image" avatar>
</span>
<h4>{{item.request.firstname}} {{item.request.lastname}}</h4>
</span>
<span>
<h3>Book Title</h3>
<h4>{{item.bookTitle}}</h4>
</span>
</div>
</a>
</div>
</section>
Any attempt to help will be really appreciated
From the above mentioned requestData, the data is an object, and you are trying to use *ngFor="let item of requestData" on object which is invalid and it should throw the error.
Reason is array's are only the iterables in *ngFor.. So change your above code with the following,
<div history *ngFor="let item of requestData.request">
<a [routerLink]="['details']">
<h3>9:15 AM | Mon, Feb 11, 2019</h3>
<div class="first">
<span>
<span class="image-cropper" style=" width: 36px; height: 36px;">
<img src="https://www.w3schools.com/howto/img_avatar.png" style="width:50px; border: 2px solid #fff; border-radius:50%" alt="profile image" avatar>
</span>
<h4>{{item.firstname}} {{item.lastname}}</h4>
</span>
<span>
<h3>Book Title</h3>
<h4>{{requestData.bookTitle}}</h4>
</span>
</div>
</a>
</div>
Here requestData.request is an array so you need to iterate only this array using *ngFor and replace, {{item.request.firstname}} with {{item.firstname}} and so on for all related data.
To assign the value of bookTitle, you need to use like this directly from the object,
{{requestData.bookTitle}}
Working stackblitz example here..

How to dynamically add items and attributes to HTML with javascript or jQuery referencing items from a csv or json file

I am trying to make the following bit of code easier to maintain. I am not a web developer so bear with me. I think the following approach is appropriate.
I would like to dynamically add content and attributes to an html file using either javascript or jQuery. The items could reside in a .csv or .json (or something else?) file.
Given content like this
<div class="filtr-container">
<div class="col-12 col-sm-6 col-md-4 card filtr-item" data-category="cat-1" data-date="2018-02-09">
<div class="card-inner-border box-shadow">
<a href="address-1.html">
<img class="card-img-top rounded-top" src="./images/image-1.jpg" alt="img-2-alt">
</a>
<div class="card-body">
<h5 class="card-title">Title-1</h5>
<p class="card-text card-desc">
This is a description for title-1 content.
</p>
<a href="address-1.html">
<button type="button" class="btn btn-sm btn-outline-secondary">View</button>
</a>
<p class="card-text">
<small class="text-muted">Last updated February 2, 2018</small>
</p>
</div>
</div>
</div>
<div class="col-12 col-sm-6 col-md-4 card filtr-item" data-category="cat-2, cat-3" data-date="2018-02-14">
<div class="card-inner-border box-shadow">
<a href="address-2.html">
<img class="card-img-top rounded-top" src="./images/image-2.jpg" alt="img-2-alt">
</a>
<div class="card-body">
<h5 class="card-title">Title-2</h5>
<p class="card-text card-desc">
Here is a long description for title-2 content.
</p>
<a href="address-2.html">
<button type="button" class="btn btn-sm btn-outline-secondary">View</button>
</a>
<p class="card-text">
<small class="text-muted">Last updated February 14, 2018</small>
</p>
</div>
</div>
</div>
<!-- MANY MORE CARDS / ITEMS ... -->
</div> <!-- End of filtr-container -->
I think we could abstract the details into something like this (.csv)
item-id,title,description,categories,address,image,image-alt,update
1,Title-1,This is a description for title-1 content.,cat-1,address-1.html,image-1.jpg,img-1-alt,2018-02-09
2,Title-2,Here is a long description for title-2 content.,"cat-2, cat-2",address-2.html,image-2.jpg,img-2-alt,2018-02-14
What's a nice approach of attack for using `javascript` or `jQuery` to add this content from the `.csv` or `.json` file?
A few concerns:
The headers of the .csv will not match verbatim (e.g. <p class="card-desc"> aligns with the .csv header of description)
There could be embedded comma-separated items (e.g. item 2 has categories cat-2, cat-3 so it gets quotes " in the .csv -- maybe .json would better (?) or perhaps its a non-issue)
If possible can we reuse the date item for both data-date= and the final piece of text <small class="text-muted"> which converts the date into Last updated month-name-long, dd, yyyy instead of yyyy-mm-dd.
Some attributes are partial references (e.g. the src for an image is just the final part of the path; stated as image-1.jpg in the .csv not ./images/image-jpg).
To hopefully help make this feel less complicated, here's a picture with the highlighted elements that could be "referenced" from the .csv file.
To me this feels like:
Read in the .csv file.
For each item in the .csv file, append objects to $(".filtr-container") with the shell layout...
But I'm lost when it comes to the particulars or if that's an appropriate approach.
You seem to be searching for template parsing. You can find many libraries that will ease this burden. In its simplest form, template parses carry out the steps in the following code. If you don't need the flexibility, power, features, etc. from a template parser library or full framework, you should consider not including the thousands of lines of code if all you want to accomplish is what is shown below.
Since you mentioned both JSON and CSV I've included the code to parse both. I'll leave the AJAX and date formatting magic to you. I don't think I populate the ID either, but this shows that more data than template attributes will work fine.
let template = document.getElementById('card-template').innerHTML;
let container = document.querySelector('.filtr-container');
// Do some ajax magic to get csv file
let csv = `item-id,title,description,categories,address,image,image-alt,update
1,Title-1,This is a description for title-1 content.,cat-1,address-1.html,https://via.placeholder.com/75,img-1-alt,2018-02-09
2,Title-2,Here is a long description for title-2 content.,cat-2 cat-2,address-2.html,https://via.placeholder.com/75,img-2-alt,2018-02-14`;
let csvLines = csv.split("\n");
let csvHeaders = csvLines.shift().split(',');
csvLines.forEach(line => {
let parsed = template;
let props = line.split(',');
props.forEach((prop, idx) => {
parsed = parsed.replace('{{' + csvHeaders[idx] + '}}', props[idx]);
});
container.innerHTML = container.innerHTML + parsed;
});
let json = `[{
"item-id": "1",
"title": "Title-1",
"description": "This is a description for title-1 content.",
"categories": "cat-1",
"address": "address-1.html",
"image": "https://via.placeholder.com/75",
"image-alt": "img-1-alt",
"update": "2018-02-09"
}, {
"item-id": "2",
"title": "Title-2",
"description": "Here is a long description for title-2 content.",
"categories": "cat-2 cat-2",
"address": "address-2.html",
"image": "https://via.placeholder.com/75",
"image-alt": "img-2-alt",
"update": "2018-02-14"
}]`;
let data = JSON.parse(json);
data.forEach(col => {
let jParsed = template;
for (prop in col) {
jParsed = jParsed.replace('{{' + prop + '}}', col[prop]);
}
container.innerHTML = container.innerHTML + jParsed;
});
<div class="filtr-container">
<script type="template" id="card-template">
<div class="col-12 col-sm-6 col-md-4 card filtr-item" data-category="{{categories}}" data-date="{{date}}">
<div class="card-inner-border box-shadow">
<a href="{{address}}">
<img class="card-img-top rounded-top" src="{{image}}" alt="{{image-alt}}">
</a>
<div class="card-body">
<h5 class="card-title">{{title}}</h5>
<p class="card-text card-desc">
{{description}}
</p>
<a href="{{address}}">
<button type="button" class="btn btn-sm btn-outline-secondary">View</button>
</a>
<p class="card-text">
<small class="text-muted">Last updated {{update}}</small>
</p>
</div>
</div>
</div>
</script>
This post might help you parse your CSV document. If your data lives in a JSON, you can use JSON.parse
Once you properly retrieved and parsed your data, it's a matter or rendering it to the DOM.
You can do it using the standard javascript library, JQuery or frameworks such as React or VueJS

Bind list to multiple target divs in WinJS

I have list declared in js file like this (full list contain 6 items, but can be more or less than that)
var dataArray = [
{
type: "item", title: "Cliff",
picture: "../../images/slike_etnologija/srednji_vek/01.jpg",
text: "some description"
},
{
type: "item", title: "Grapes",
picture: "../../images/slike_etnologija/srednji_vek/02.jpg",
text: "another description"
},
two templates declared in html file
<div id="galleryTemplate" data-win-control="WinJS.Binding.Template">
<div class="overlaidItemTemplate">
<img class="image img-responsive" src="#" data-win-bind="src: picture; alt: title" />
<div class="overlay">
<h2 class="ItemTitle" data-win-bind="innerText: title"></h2>
</div>
</div>
</div>
<div id="textTemplate" data-win-control="WinJS.Binding.Template">
<div>
<p data-win-bind="innerText: text"></p>
</div>
</div>
and two controls where i need to show data from list
<div class="col-md-12" id="basicFlipView"
data-win-control="WinJS.UI.FlipView"
data-win-options="{ itemDataSource : EtnologijaGallery.itemList.dataSource, itemTemplate: galleryTemplate }">
</div>
<p data-win-control="WinJS.UI.ListView"
data-win-options="{ itemDataSource : EtnologijaGallery.itemList.dataSource, itemTemplate: textTemplate }">
</p>
I'm trying to show image gallery in flipbox and text description associated to each image in listview next to it. Due to design i can't put both things in same template.
My flipbox works fine, and shows all images, but listview don't work. It shows, first, only 3 descriptions from list, and those 3 descriptions are shown in control with scroll bar, instead changing when user change image in flipbox.
Can someone help me solve this?
As mentioned on http://www.buildwinjs.com/tutorial/2WinJS_Binding/bindingInit/, WinJS Binding is one-time binding and you bound the same array to two separate controls.
I think you should check FlipView's onpageselected event and when that event occurs, update the div with the proper text. I guess the ListView is not needed to be used in this case at all.

Categories

Resources