Loading JSON var into an existing HTML table through Button-Click - javascript

I have an already written (in html) table and i want to "rewrite" it when i press the "refresh data" button. So far, i lose all of my css style for a reason (like i' m creating a new table from scratch). My code:
HTML - Table :
<div id="priceInfo">
<button id="priceInfoB">refresh data</button>
</div>
<table id="myTable" border='1'>
<tr class="head">
<th></th>
<th data-city="ny">New York</th>
<th data-city="il">Chicago</th>
<th data-city="ca">San Francisco</th>
</tr>
<tr>
<th class='rowTH' id="one">A Poetic Perspective</th>
<td>Sat, 4 Feb 2012<br />11am - 2pm</td>
<td>Sat, 3 Mar 2012<br />11am - 2pm</td>
<td>Sat, 17 Mar 2012<br />11am - 2pm</td>
</tr>
<tr class="even">
<th class='rowTH' id="two">Walt Whitman at War</th>
<td>Sat, 7 Apr 2012<br />11am - 1pm</td>
<td>Sat, 5 May 2012<br />11am - 1pm</td>
<td>Sat, 19 May 2012<br />11am - 1pm</td>
</tr>
<tr>
<th class='rowTH' id="three">Found Poems & Outsider Poetry</th>
<td>Sat, 9 Jun 2012<br />11am - 2pm</td>
<td>Sat, 7 Jul 2012<br />11am - 2pm</td>
<td>Sat, 21 Jul 2012<br />11am - 2pm</td>
</tr>
<tr class="even">
<th class='rowTH' id="four">Natural Death: An Exploration</th>
<td>Sat, 4 Aug 2012<br />11am - 4pm</td>
<td>Sat, 8 Sep 2012<br />11am - 4pm</td>
<td>Sat, 15 Sep 2012<br />11am - 4pm</td>
</tr>
</table>
JSON Var :
var eventsJson='{"events":{"event":[{"id":"1","name":"A Poetic Perspective","isFree":"true","locations":[{"location":"New York","eventDate":"2015-05-02","eventTime":"14:00"},{"location":"Chicago","eventDate":"2015-05-01","eventTime":"14:00"},{"location":"San Francisco","eventDate":"2015-06-01","eventTime":"15:00"}],"descr":"Vivamus elementum, diam eget ullamcorper fermentum, ligula libero euismod massa, quis condimentum tellus lacus sit."},{"id":"2","name":"Walt Whitman at War","isFree":"false","locations":[{"location":"New York","eventDate":"2015-07-02","eventTime":"14:00"},{"location":"Chicago","eventDate":"2015-07-01","eventTime":"14:00"},{"location":"San Francisco","eventDate":"2015-08-01","eventTime":"15:00"}],"descr":"Donec convallis eu metus eget dictum. Etiam non lobortis dui."},{"id":"3","name":"Found Poems & Outsider Poetry","isFree":"false","locations":[{"location":"New York","eventDate":"2015-06-02","eventTime":"11:00"},{"location":"Chicago","eventDate":"2015-07-01","eventTime":"14:00"},{"location":"San Francisco","eventDate":"2015-06-01","eventTime":"15:00"}],"descr":"Ut fermentum, elit vel iaculis viverra, dui libero ultrices nibh, ut ornare."},{"id":"4","name":"Natural Death: An Exploration","isFree":"true","locations":[{"location":"New York","eventDate":"2015-05-02","eventTime":"14:00"},{"location":"Chicago","eventDate":"2015-05-01","eventTime":"14:00"},{"location":"San Francisco","eventDate":"2015-06-01","eventTime":"15:00"}],"descr":"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent aliquet urna ut tortor consequat."}]}}';
Any help will be appreaciated. Any manual and/or command i havent thought about will be helpful!

Loop through the json data
For each record, clone the table rows you need. Demo here
Using jQuery to build table rows from Ajax response(Json)
Swap the cell data with data from your JSON
Append the rows to the table

Related

TINYMCE Editor External Templates: Uncaught TypeError: Cannot read property 'indexOf' of undefined

I am using TINYMCE Editor Version 4.8.2 (2018-08-09) and trying to add few prebuilt templates in .html in the list. I installed the template plugin in the plugin directory and initiated it in init-tinymce.js as below.
tinymce.init({
/* replace textarea having class .tinymce with tinymce editor */
selector: "textarea",
/* plugin */
plugins: [
"template"
],
/* toolbar */
toolbar: "template",
/* templates */
templates: [
{
title : "Default Template 1",
src : "tinymce-templates/template1.html",
description : "Default Template"
},
{
title : "Default Template 2",
src : "tinymce-templates/template2.html",
description : "Default Template"
}
]
});
Now when I try to open and insert my added templates then I am able to see my both template in the dropdown list but when I cant see the preview. On inspecting, I found this error shared below.
Uncaught TypeError: Cannot read property 'indexOf' of undefined plugin.min.js:1
at S (plugin.min.js:1)
at i.onselect (plugin.min.js:1)
at Vg.c.fire (tinymce.min.js:2)
at i.fire (theme.min.js:1)
at w (plugin.min.js:1)
at plugin.min.js:1
at i.<anonymous> (plugin.min.js:1)
at Vg.c.fire (tinymce.min.js:2)
at i.fire (theme.min.js:1)
at HTMLDivElement.o (theme.min.js:1)
S # plugin.min.js:1
onselect # plugin.min.js:1
Vg.c.fire # tinymce.min.js:2
fire # theme.min.js:1
w # plugin.min.js:1
(anonymous) # plugin.min.js:1
(anonymous) # plugin.min.js:1
Vg.c.fire # tinymce.min.js:2
fire # theme.min.js:1
o # theme.min.js:1
C # tinymce.min.js:2
d
And my template is like something below...
<div class="mceTmpl">
<div class="row">
<div class="box">
<div class="col-lg-12">
<hr>
<h2 class="intro-text text-center">Build a website
<strong>worth visiting</strong>
</h2>
<hr>
<hr class="visible-xs">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc placerat diam quis nisl vestibulum dignissim. In hac habitasse platea dictumst. Interdum et malesuada fames ac ante ipsum primis in faucibus. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.</p>
</div>
</div>
</div>
</div>
I believe where you have a src attribute the correct attribute is url. Per the documentation I see this:
This option lets you specify a predefined list of templates to be
inserted by the user into the editable area. It is structured as an
array with each item having a title, description and content/url.

How do I update blog post in Mongoose?

I am building a blog site using CRUD operations. I can create, read and delete but I am having hard time with updating a created post.
Basically I have it where I can click on the "edit" button on an individual entry in home.ejs and into the edit.ejs route where that input fields are populated with current title and content. But what I can not figure out is clicking "Publish" in edit.ejs to update its own post.ejs title and content. When it is done, I want to redirect it back to the main page. Down on the "app.post("/edit/:id")" route, am I supposed to use "PUT" request to update the post?
I am sorry if this is tough to follow. I am not very good at explaining things.
Here's the relevant code:
app.js
const express = require("express");
const bodyParser = require("body-parser");
const ejs = require("ejs");
const mongoose = require("mongoose");
const _ = require("lodash");
const aboutContent = "Hac habitasse platea dictumst vestibulum rhoncus est pellentesque. Dictumst vestibulum rhoncus est pellentesque elit ullamcorper. Non diam phasellus vestibulum lorem sed. Platea dictumst quisque sagittis purus sit. Egestas sed sed risus pretium quam vulputate dignissim suspendisse. Mauris in aliquam sem fringilla. Semper risus in hendrerit gravida rutrum quisque non tellus orci. Amet massa vitae tortor condimentum lacinia quis vel eros. Enim ut tellus elementum sagittis vitae. Mauris ultrices eros in cursus turpis massa tincidunt dui.";
const contactContent = "Scelerisque eleifend donec pretium vulputate sapien. Rhoncus urna neque viverra justo nec ultrices. Arcu dui vivamus arcu felis bibendum. Consectetur adipiscing elit duis tristique. Risus viverra adipiscing at in tellus integer feugiat. Sapien nec sagittis aliquam malesuada bibendum arcu vitae. Consequat interdum varius sit amet mattis. Iaculis nunc sed augue lacus. Interdum posuere lorem ipsum dolor sit amet consectetur adipiscing elit. Pulvinar elementum integer enim neque. Ultrices gravida dictum fusce ut placerat orci nulla. Mauris in aliquam sem fringilla ut morbi tincidunt. Tortor posuere ac ut consequat semper viverra nam libero.";
let app = express();
app.set('view engine', 'ejs');
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(express.static("public"));
mongoose.connect("mongodb://localhost:27017/blogDB", {
useNewUrlParser: true
});
const postSchema = {
date: String,
title: String,
content: String
}
const Post = mongoose.model("Post", postSchema);
app.get("/", (req, res) => {
Post.find({}, (err, posts) => {
res.render("home", {
posts: posts
});
});
});
app.get("/about", (req, res) => {
res.render("about", {
aboutContent: aboutContent
});
});
app.get("/contact", (req, res) => {
res.render("contact", {
contactContent: contactContent
});
});
app.get("/compose", (req, res) => {
res.render("compose");
});
app.post("/compose", (req, res) => {
const postTitle = req.body.postTitle;
const postBody = req.body.postBody;
let date = new Date();
let postDate = date.toLocaleString('en-US');
const post = new Post({
date: postDate,
title: postTitle,
content: postBody
});
post.save(err => {
if (!err) {
res.redirect("/");
}
});
});
app.get("/edit/:id", (req, res) => {
const requestedId = req.params.id;
console.log(req.body);
Post.findOne({
_id: requestedId
}, (err, post) => {
if (!err) {
res.render("edit", {
title: post.title,
content: post.content
});
}
});
});
app.post("/edit/:id", (req, res) => {
const requestedId = req.params.id;
console.log(req.body);
Post.findOne({
_id: requestedId
}, (err, post) => {
if (!err) {
res.render("edit", {
title: post.title,
content: post.content
});
}
});
});
app.get("/posts/:id", (req, res) => {
const requestedId = req.params.id;
Post.findOne({
_id: requestedId
}, (err, post) => {
if (!err) {
res.render("post", {
title: post.title,
content: post.content
});
}
});
});
app.post("/delete", (req, res) => {
const deletePost = req.body.delete;
Post.findByIdAndDelete(deletePost, (err) => {
if (!err) {
res.redirect("/");
}
});
});
app.listen(3000, function () {
console.log("Server started on port 3000");
});
home.ejs
<%- include("partials/header") -%>
<h1>Home</h1>
<button type="button" class="new-entry btn btn-dark">New Entry</button>
<div class="entries-container">
<% posts.forEach(post => { %>
<div class="blog-entry">
<p class="post-date">Posted on
<%= post.date %>
</p>
<h2>
<%= post.title %>
</h2>
<div class="entry-footer">
<button type="button" class="btn btn-outline-primary">VIEW</button>
<form action="/edit" method="POST">
EDIT</button>
</form>
<form action="/delete" method="POST">
<button type="submit" name="delete" value="<%= post._id %>" class="btn btn-outline-danger">DELETE</button>
</form>
</div>
</div>
<% }) %>
</div>
<%- include("partials/footer") -%>
edit.ejs
<%- include("partials/header") -%>
<h1>Compose</h1>
<form action="/edit" method="PUT">
<div class="form-group">
<label for="postTitle">Title</label>
<input type="text" name="postTitle" class="form-control" id="postTitle" autocomplete="off" value="<%= title %>">
<label for="postBody">Post</label>
<textarea name="postBody" class="form-control" autocomplete="off" rows="8"><%= content %></textarea>
</div>
<button type="submit" name="button" class="btn btn-primary">Publish</button>
</form>
<%- include("partials/footer") -%>
post.ejs
<%- include("partials/header") -%>
<h2 class="post-title"><%= title %></h2>
<p class="post-content"><%= content %></p>
<%- include("partials/footer") -%>
If you want to simply update your existing blog post title and content with sending POST request then you can do it with findOneAndUpdate() as below:
app.post("/edit/:id", (req, res) => {
const requestedId = req.params.id;
console.log(req.body);
Post.findOneAndUpdate({
_id: requestedId // Query Part
},
{
$set: {
title: req.body.title, // Fields which we need to update
content: req.body.content
}
},
{
new: true // option part ( new: true will provide you updated data in response )
},(err, post) => {
if (!err) {
res.render("edit", {
title: post.title,
content: post.content
});
}
});
});

Angularjs - UI Boostrap: Accordion Open and close all

i have written some code to open and close all tabs of an accordion respectively use a separate 'open' and 'close' button. How ever it requires me to dynamically add a key value pair(a Boolean value) to my json data.
What is the best practice in this situation? should i add the Boolean value as a static json element or is it OK to dynamically add values when their sole purpose is for visual structure and not relevant to actual object data.
HTML/Angular directives
<div id="app" ng-app="demoApp">
<div id="controller" ng-controller="demoAppCtrl">
<uib-accordion close-others="false">
<div class="btn-group form-group">
<button type="button" class="btn btn-warning" ng-click="toggle(true)">Open</button>
<button type="button" class="btn btn-warning" ng-click="toggle(false)">Close</button>
</div>
<uib-accordion-group is-open="hero.state" ng-click="setOpened(false)" ng-repeat="hero in heroes">
<uib-accordion-heading>
{{hero.name}}
</uib-accordion-heading>
{{hero.bio}}
</uib-accordion-group>
</uib-accordion>
</div>
</div>
Javascript/Angular
var app = angular.module('demoApp', ['ngAnimate','ui.bootstrap']);
app.controller('demoAppCtrl', function($scope) {
// This json object contain only one entry as an example
$scope.heroes = [
{'name': 'Captain America', 'team': 'Avengers', 'bio': 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum vitae metus placerat, condimentum nisl et, accumsan sapien. Quisque molestie magna nulla, id malesuada sem interdum a.'}
];
$scope.addDefaultState = function(val) {
for (var i=0;i<$scope.heroes.length;i++) {
$scope.heroes[i].state = val;
}
}
$scope.addDefaultState(false);
$scope.toggle = function(status) {
$scope.heroes.forEach(function(e) {
e.state = status;
});
}
});
codepen.io - Working example (with corrections)
In my opinion the static json should not contain Boolean state value. It is okay to dynamically add values for visual presentation.
In your code the function addDefaultState is not needed. The is-open="hero.state" will take care of default state cause initially it will not find state and will consider it as false. So you change your code like below it should work too:
var app = angular.module('demoApp', ['ngAnimate','ui.bootstrap']);
app.controller('demoAppCtrl', function($scope) {
// This json object contain only one entry as an example
$scope.heroes = [
{'name': 'Captain America', 'team': 'Avengers', 'bio': 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum vitae metus placerat, condimentum nisl et, accumsan sapien.'}
];
$scope.toggle = function(status) {
$scope.heroes.forEach(function(e) {
e.state = status;
});
}
});

ng-repeat shows only the last item from json

How can I display a specific number of items from JSON using ng-repeat. Right now its displaying only the last item.
JSON
{
"list":{
"item": {
"id":1,
"img": "1.jpg",
"user": "David Belle",
"text": "Cum sociis natoque penatibus et magnis dis parturient montes"
},
"item": {
"id":2,
"img": "2.jpg",
"user": "Jonathan Morris",
"text": "Nunc quis diam diamurabitur at dolor elementum, dictum turpis vel"
},
"item": {
"id":3,
"img": "3.jpg",
"user": "Fredric Mitchell Jr",
"text": "Phasellus a ante et est ornare accumsan at vel magnauis blandit turpis at augue ultricies"
}
}
}
ANGULARJS
Controller
app.controller('mainCtrl', ['$scope', '$resource', function($scope, $resource) {
$scope.msAPI = $resource("data/messages-notifications.json");
$scope.msResult = $scope.msAPI.get();
}]);
HTML
<div ng-controller="mainCtrl">
<a href="" ng-repeat="w in msResult.list">
<div class="lv-title">{{ w.user }}</div>
<small class="lv-small">{{ w.text }}</small>
</a>
</div>
The easiest way would be to change your JSON structure to include an array (instead of an object), as follows:
{
"list": [{
"id":1,
"img": "1.jpg",
"user": "David Belle",
"text": "Cum sociis natoque penatibus et magnis dis parturient montes"
}, {
"id":2,
"img": "2.jpg",
"user": "Jonathan Morris",
"text": "Nunc quis diam diamurabitur at dolor elementum, dictum turpis vel"
}, {
"id":3,
"img": "3.jpg",
"user": "Fredric Mitchell Jr",
"text": "Phasellus a ante et est ornare accumsan at vel magnauis blandit turpis at augue ultricies"
}]
}

Splitting ng-repeat every 3 items

Using AngularJS, I'm iterating over a JSON object containing an array of event objects, containing an array of competition objects.
I wish to show each event in a table, and then each competition in a td, but only three cells per row
I'm using ng-repeat to return a list of tables for each event, but I'm having trouble with splitting the competitions into a new <tr> every three <td>s
Aside from rebuilding my own massive object from the JSON, what is the best way to do what I'm describing in Angular?
Current view:
<table ng-repeat="listing in listings">
<tr>
<th colspan="3">{{listing.name}}</th>
</tr>
<tr>
<td ng-repeat="competition in listing.competitions">
{{competition.id}} - {{competition.name}}
</td>
</tr>
</table>
Desired output:
<table>
<tr>
<th colspan="3">Event Name</th>
</tr>
<tr>
<td>competition id - competition name</td>
<td>competition id - competition name</td>
<td>competition id - competition name</td>
</tr>
<tr>
<td>competition id - competition name</td>
<td>competition id - competition name</td>
<td>competition id - competition name</td>
</tr>
</table>
Controller:
app.controller('EventsCtrl', function ($scope, $http) {
$scope.loading = true;
$http.get('scripts/JSON/events.json').then(function (response) {
var listings = response['data'].events;
$scope.listings = listings;
});
});
events.json
{
"events": [
{
"id": 418,
"name": "et ullamco",
"competitions": [
{
"id": 933,
"name": "qui in deserunt occaecat et",
"startTime": 1381092189
},
{
"id": 853,
"name": "eu enim ex incididunt do",
"startTime": 1380708266
},
{
"id": 5738,
"name": "ad est ut aliquip et",
"startTime": 1381366623
},
{
"id": 7599,
"name": "sit ex voluptate aliqua dolor",
"startTime": 1381284106
},
{
"id": 7481,
"name": "laborum consequat deserunt do aliqua",
"startTime": 1380874273
},
{
"id": 3441,
"name": "amet reprehenderit sint sunt proident",
"startTime": 1380554850
},
{
"id": 1959,
"name": "ullamco minim minim in voluptate",
"startTime": 1380651981
}
]
},
You are using a table but the semantics of your data indicate you have a list of lists. You should consider outputting this with <ul><li> instead of a grid.
<ul ng-repeat="listing in listings">
<li>
<h2>{{listing.name}}</h2>
<ul ng-repeat="competition in listing.competitions">
<li>
{{competition.id}} - {{competition.name}}
</li>
</ul>
</li>
</ul>
You can achieve your desired layout with CSS quite easily using the above HTML. Checkout the "block grids" in Twitter Bootstrap or Foundation for examples. Tables should generally be used only for data that is actually tabular.
However...
You're question does still bear answering since there may be other reasons to alternate templates in the way you suggest. You could use a function for this to get things three at a time:
<table ng-repeat="listing in listings">
<tr>
<th colspan="3">{{listing.name}}</th>
</tr>
<tr ng-repeat="group in competitions">
<td ng-repeat="competition in group">
{{competition.id}} - {{competition.name}}
</td>
</tr>
</table>
In your controller you can create a "list of lists" to bind to the nested repeaters
// Adapted from Fresheyeball's solution
$scope.competitions = []
compSet = []
for(var i; i < $scope.listings.competitions; i++){
var competition = $scope.listings.competitions[i];
if( i % 3 ){
$scope.competitions.push(compSet);
compSet = [];
}
compSet.push(competition);
}

Categories

Resources