I have a list of events for a calendar. I'd like to hyperlink the title or location--though preferably the location (see below) to a website. How do I do this?
var events = [
{ date: "2015-10-10", title: 'October 15, 2015', location: 'Event One Deadline' },
{ date: "2015-10-25", title: 'October 25, 2015', 'location: 'Payment Deadline' },
{ date: "2015-12-25", title: 'December 25, 2015', location: 'Christmas: We're closed.' },
{ date: "2015-12-26", title: 'December 26, 2015', location: 'Boxing Day: We're closed.'} ];
If i got it right you want to change the data of location to make it a link, so here you go:
events.map(function( row,index ){
row.location = '' + row.location + '';
});
or the old way
for( var i = 0, length = events.length; i < length; i++ ) {
events[i].location = '' + events[i].location + '';
}
If i got your question, you need to parse JSON data.
Your code is JSON object
you can use jSON.parse(JSON_DATA)
var events = [
{ date: "2015-10-10", title: "October 15, 2015", location: "Event One Deadline" },
{ date: "2015-10-25", title: "October 25, 2015", location: "Payment Deadline" },
{ date: "2015-12-25", title: "December 25, 2015", location: "Christmas: We're closed." },
{ date: "2015-12-26", title: "December 26, 2015", location: "Boxing Day: We're closed."} ];
console.log(events); // Object
for(i=0;i<=events.length;i++){
console.log(events[i].date);
console.log(events[i].location);
console.log(events[i].title);
}
now values can use for make links
Note: your JSON data need to have double-qutos ("") instead of ''
you can now access value like: events[0].title and create link like:
events[0].location
Related
I have 2 moments: moment_start_date and moment_end_date.
I can figure out all holidays between those 2 moments using:
var holidays = moment_start_date.holidaysBetween(moment_end_date);
This gives me an array of moment objects, which tells me what days the holidays fall on, but it doesn't actually tell me the names of those holidays.
How do I go from a moment to a holiday name?
Most of the documentation for moment-holidays.js appears to go from a holiday name, to a date (the other direction).
We get the name of the holiday (if there is one) with the .isHoliday() method.
example: https://repl.it/#AndreasTeneketz/momentHoliday
const moment=require('moment-holiday')
const start = moment('01.01.2000','DD.MM.YYYY')
const end = moment('01.05.2000','DD.MM.YYYY')
const momentList = start.holidaysBetween(end)
const holidayList = momentList.map(momentHoliday=>({date:momentHoliday.format('DD.MM.YYYY'),name:momentHoliday.isHoliday() })
)
////// gives us //////
[ { date: '17.01.2000', name: 'Martin Luther King Jr. Day' },
{ date: '14.02.2000', name: 'Valentine\'s Day' }, { date: '21.02.2000', name: 'Washington\'s Birthday' },
{ date: '17.03.2000', name: 'Saint Patrick\'s Day' }, { date: '21.04.2000', name: 'Good Friday' },
{ date: '23.04.2000', name: 'Easter Sunday' } ]
I need to write a conditional that checked each image value and if its empty displays a stock photo 'selfie.jpg' and if it is not then display whatever is inside of it.
I know how to access it beat.officers[0].image. what I don't know is how to make the program check through the length of officers for each items image value, check if its empty and then display a photo based on the results of that check.
pls help its for a test.
A image of the Json object I am trying to work with
const policeData = [
{
beat:
{
name: 'Portishead',
latLong: ' ',
introText: 'Contact your local policing team, find opportunities to meet the team and view or contribute to community policing priorities for your area.',
officers: [
{
name: 'Trevor Dyson',
role: 'Neighbourhood Police Team Sergeant',
image: ''
},
{
name: 'Kirsten Karcher',
role: 'Police Community Support Officer',
image: 'kkarcher.jpg'
},
{
name: 'Bill Hoover',
role: 'Police Community Support Officer',
image: ''
},
{
name: 'Andrew Henry',
role: 'Partnership Support Officer',
image: ''
}
],
priorities: [
{
title: 'Road Safety Week',
updated: '18 November 2019',
path: '/road-safety-week/'
},
{
title: 'Community SpeedWatch',
updated: '14 August 2019',
path: '/community-speedwatch/'
},
{
title: 'Mopeds using footpaths and speeding vehicles',
updated: '04 September 2019',
path: '/mopeds-using-footpaths-and-speeding-vehicles/'
}
]
}
}];
So here is my template which is functional. As you can see though its not dynamic and I tried to input the conditional as a function with an if statement but its just not working. I did consider trying the turnery (condition : if yes : if no) but I struggled with that too.
Some of the image values are empty you see? Ultimately, I am trying to make it go through each object and check its image value and then run the conditional.
function kk(police) {
officers = police.beat.officers.length;
return `
<div class=person>
<img class="pol-photo" src = "${photoO(police.beat.officers[0])}"
<h2 class ="pol-name">${police.beat.officers[1].name}</h2>
<p> ${police.beat.officers[1].role}</p>
</div>
`
}
function photoO(pol) {
if (pol == '' ) {
return 'officer-profile.jpg'
} else {
return 'kkarcher.jpg'
}
}
You can use the functions from below to get the correct output. One function will return the HTML for just one officer while the other will return the HTML of all of them. You can test it below.
const policeData = [
{
beat:
{
name: 'Portishead',
latLong: ' ',
introText: 'Contact your local policing team, find opportunities to meet the team and view or contribute to community policing priorities for your area.',
officers: [
{
name: 'Trevor Dyson',
role: 'Neighbourhood Police Team Sergeant',
image: ''
},
{
name: 'Kirsten Karcher',
role: 'Police Community Support Officer',
image: 'kkarcher.jpg'
},
{
name: 'Bill Hoover',
role: 'Police Community Support Officer',
image: ''
},
{
name: 'Andrew Henry',
role: 'Partnership Support Officer',
image: ''
}
],
priorities: [
{
title: 'Road Safety Week',
updated: '18 November 2019',
path: '/road-safety-week/'
},
{
title: 'Community SpeedWatch',
updated: '14 August 2019',
path: '/community-speedwatch/'
},
{
title: 'Mopeds using footpaths and speeding vehicles',
updated: '04 September 2019',
path: '/mopeds-using-footpaths-and-speeding-vehicles/'
}
]
}
}];
// helper function to check if value is empty
function existsAndNotEmpty(value) {
if (typeof value != 'undefined' && value.length > 0) {
return true;
}
return false;
}
function getOfficerHTML(officer) {
let result = "";
if( existsAndNotEmpty(officer.image) ) {
result += '<img class="pol-photo" src = "' + officer.image + '" />';
} else {
result += '<img class="pol-photo" src = "officer-profile.jpg" />';
}
if( existsAndNotEmpty(officer.name) ) {
result += '<h2 class ="pol-name">' + officer.name + '</h2>';
} else {
result += '<h2 class ="pol-name">Unknown officer</h2>';
}
if( existsAndNotEmpty(officer.role) ) {
result += '<p>' + officer.role + '</p>';
} else {
result += '<p>Unknown role</p>';
}
return result;
}
function getAllOfficerHTML() {
let result = "";
let officerLength = policeData[0].beat.officers.length;
let officers = policeData[0].beat.officers;
for(var i=0; i < officerLength; i++){
result += getOfficerHTML(officers[i]);
}
return result;
}
// Now you can use it like this to print a single officer
var singleOfficer = getOfficerHTML(policeData[0].beat.officers[1]);
console.log(singleOfficer);
// or like this to get all ooficers at once
var allOfficers = getAllOfficerHTML();
console.log(allOfficers);
Using fullcalendar library, I would like to display the start time for each empty cell on my calendar (empty cells are the one marked with a red cross or red dots in the below screenshot, I modified a bit the aspect of the calendar):
So my expected output is a calendar were timeslots become buttons, when you click you start the process of booking a 30 minutes appointment which would start at the written time (the green slot is an hover effect in the following screenshot):
I can't find any easy way to do it through after reading fullcalendar documentation : https://fullcalendar.io/docs
Subsidiary question, I can't find the way to change the style of the empty cell in the CSS. Can't manage to select the elements through my Chrome console.
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
columnHeaderHtml: function(date) {
if (date.getUTCDay() === 0) {
var date_day = "Lundi";
}
if (date.getUTCDay() === 1) {
var date_day = "Mardi";
}
if (date.getUTCDay() === 2) {
var date_day = "Mercredi";
}
if (date.getUTCDay() === 3) {
var date_day = "Jeudi";
}
if (date.getUTCDay() === 4) {
var date_day = "Vendredi";
}
if (date.getUTCDay() === 5) {
var date_day = "Samedi";
}
if (date.getUTCDay() === 6) {
var date_day = "Dimanche";
}
if(date.getMonth() === 0)
{
var date_month = "Jan";
}
if(date.getMonth() === 1)
{
var date_month = "Fev";
}
if(date.getMonth() === 2)
{
var date_month = "Mar";
}
if(date.getMonth() === 3)
{
var date_month = "Avr";
}
if(date.getMonth() === 4)
{
var date_month = "Mai";
}
if(date.getMonth() === 5)
{
var date_month = "Juin";
}
if(date.getMonth() === 6)
{
var date_month = "Juil";
}
if(date.getMonth() === 7)
{
var date_month = "Août";
}
if(date.getMonth() === 8)
{
var date_month = "Sept";
}
if(date.getMonth() === 9)
{
var date_month = "Oct";
}
if(date.getMonth() === 10)
{
var date_month = "Nov";
}
if(date.getMonth() === 11)
{
var date_month = "Dec";
}
var day_num = date.getDate();
return '<b>'+date_day+'</b><br><small>'+day_num+" "+date_month+"</small>";
},
plugins: [ 'interaction', 'dayGrid', 'list', 'googleCalendar','timeGrid' ],
selectable: true,
defaultView: 'timeGridFourDay',
views: {
timeGridFourDay: {
type: 'timeGrid',
duration: { days: 4 },
buttonText: '4 day'
}
},
slotLabelFormat:{
hour: 'numeric',
minute: '2-digit',
omitZeroMinute: true,
meridiem: 'short'
},
locale:'fr',
header: {
left: 'prev today',
right: 'next'
},
validRange: {
start: '2019-08-05',
end: '2019-09-05'
},
allDaySlot:false,
firstDay:1,
minTime:"08:00:00",
maxTime:"20:00:00",
displayEventTime: true, // don't show the time column in list view
// THIS KEY WON'T WORK IN PRODUCTION!!!
// To make your own Google API key, follow the directions here:
// http://fullcalendar.io/docs/google_calendar/
googleCalendarApiKey: 'AIzaSyAL9K2UqkCVfV0n81mDW0iEpOJSwcklfsY',
// US Holidays
events: 'fr.fr#holiday#group.v.calendar.google.com',
eventClick: function(arg) {
arg.jsEvent.preventDefault() // don't navigate in main tab
console.log(arg);
},
select: function(info) {
console.log(info)
},
loading: function(bool) {
},
eventSources: [
{
googleCalendarId: 'contact#vetorino.com',
className: "gcalEvent"
}],
displayEventEnd:false,
events:[
{ // this object will be "parsed" into an Event Object
start: '2019-08-05 12:30:00', // a property!
end: '2019-08-05 14:00:00', // a property! ** see important note below about 'e6d' **
overlap: true,
backgroundColor:"#F7F7F7",
textColor:"#979797",
classNames:"closed",
}],
contentHeight: "auto",
});
calendar.render();
});
So far as shown in my previous screenshot I just managed to have empty cells, the only cells where you find some information are cells containing events.
As discussed in the comments above, there is no single element in the fullCalendar HTML which represents a specific "cell" or "slot" in the timeGrid view. The grid you can see on screen is actually an illusion created by layering multiple tables on top of each other.
So to meet your requirement for a user to be able to select a 20-minute appointment in a free slot, I can see two main options. The first is what I would normally recommend, using the standard fullCalendar functionality. The second is more like what you are asking for, but I think it over-complicates things.
1) This option simply sets the calendar with a slot duration of 20 minutes, and then has code to stop the user from selecting a longer period of time (they cannot select a shorter period, due to the slotDuration setting. This means that they can click on any empty space once and it will know to create an event of the correct length in that location. The user is not allowed to select any slot where an event already exists. (P.S. I expect in reality you will need to collect more data before adding events, but for the demonstration it adds an event instantly.)
document.addEventListener("DOMContentLoaded", function() {
var Calendar = FullCalendar.Calendar;
var calendarEl = document.getElementById("calendar");
var calendar = new Calendar(calendarEl, {
plugins: ["timeGrid", "interaction"],
header: {
left: "prev,next today",
center: "title",
right: "timeGridFourDay"
},
defaultView: "timeGridFourDay",
views: {
timeGridFourDay: {
type: "timeGrid",
duration: { days: 4 },
buttonText: "4 day"
}
},
slotLabelFormat: {
hour: "numeric",
minute: "2-digit",
omitZeroMinute: true,
meridiem: "short"
},
allDaySlot: false,
firstDay: 1,
minTime: "08:00:00",
maxTime: "20:00:00",
contentHeight: "auto",
slotDuration: "00:20:00",
selectable: true,
select: function(info) {
//console.log(info);
calendar.addEvent({ "title": "Test", start: info.start, end: info.end })
calendar.unselect();
},
selectOverlap: false,
selectAllow: function(selectInfo) {
var stM = moment(selectInfo.start);
var enM = moment(selectInfo.end);
var diff = enM.diff(stM, "minutes");
console.log(diff);
if (diff > 20)
{
return false;
}
return true;
},
events: [
{ "title": "Existing event", "start": "2019-08-08 10:00", "end": "2019-08-08 10:20"},
{ "title": "Existing event", "start": "2019-08-08 13:20", "end": "2019-08-08 13:40"},
]
});
calendar.render();
});
Demo: https://codepen.io/ADyson82/pen/aeqJQg
2) This option is closer to your desired UI (from your 2nd screenshot) but is a bit more complicated to achieve. I also, personally, think it leaves your calendar looking cluttered, and making it harder to see where the free and busy slots are, but ultimately it's up to you how you want to implement it. This works by adding a second event source, containing a list of all currently free slots. These are then used to display the start time of each free slot in the centre of it. They are coloured differently from the existing events (indicating a busy slot), so that it's a bit easier to tell the difference.
Of course, this requires you to use your server-side code to calculate all the currently free slots in your database and use that information to populate the second event source. (In the demo the free slot data is static, but of course that will not work in a real application.)
document.addEventListener("DOMContentLoaded", function() {
var Calendar = FullCalendar.Calendar;
var calendarEl = document.getElementById("calendar");
var calendar = new Calendar(calendarEl, {
plugins: ["timeGrid", "interaction"],
header: {
left: "prev,next today",
center: "title",
right: "timeGridFourDay"
},
defaultView: "timeGridFourDay",
views: {
timeGridFourDay: {
type: "timeGrid",
duration: { days: 4 },
buttonText: "4 day"
}
},
slotLabelFormat: {
hour: "numeric",
minute: "2-digit",
omitZeroMinute: true,
meridiem: "short"
},
allDaySlot: false,
firstDay: 1,
minTime: "08:00:00",
maxTime: "20:00:00",
contentHeight: "auto",
slotDuration: "00:20:00",
displayEventTime: false,
eventClick: function(info) {
if (info.event.extendedProps.type == "free") {
calendar.addEvent({
title: "Test",
start: info.event.start,
end: info.event.end
});
info.event.remove(); //delete the "free slot" event
}
},
eventSources: [
{
id: "busy",
events: [
{
title: "Existing event",
start: "2019-08-08 10:00",
end: "2019-08-08 10:20"
},
{
title: "Existing event",
start: "2019-08-08 13:20",
end: "2019-08-08 13:40"
}
]
},
{
id: "free",
backgroundColor: "green",
events: [
{
title: "08:00",
start: "2019-08-08 08:00",
end: "2019-08-08 08:20",
type: "free"
},
{
title: "08:20",
start: "2019-08-08 08:20",
end: "2019-08-08 08:40",
type: "free"
},
{
title: "08:40",
start: "2019-08-08 08:40",
end: "2019-08-08 09:00",
type: "free"
},
{
title: "09:00",
start: "2019-08-08 09:00",
end: "2019-08-08 09:20",
type: "free"
},
{
title: "09:20",
start: "2019-08-08 09:20",
end: "2019-08-08 09:40",
type: "free"
},
{
title: "09:40",
start: "2019-08-08 09:40",
end: "2019-08-08 10:00",
type: "free"
},
{
title: "10:20",
start: "2019-08-08 10:20",
end: "2019-08-08 10:40",
type: "free"
},
{
title: "10:40",
start: "2019-08-08 10:40",
end: "2019-08-08 11:00",
type: "free"
},
]
}
]
});
calendar.render();
});
For this demo I only created handful of the "free" slots (because it was tedious to create them), but hopefully you can get the idea of how it would start to look with dozens of them all over the calendar. Of course again you can amend the CSS to your requirements.
Demo: https://codepen.io/ADyson82/pen/JgpNEX
(You can of course amend the CSS of this further to make it appear more like your desired look and feel.)
Addendum: Here's the OP's final version, for anyone who is interested in the end product - based on taking the above suggestions into consideration: https://codepen.io/hugo-trial/pen/rXdajv
I have a simple VueJs component I'm building that doesn't render at all in IE 10.
Background: The Vue component is a listing of company events, that supports basic filtering and sorting. Unfortunately, I have to support IE10. I am not using babel, but tried to use it in troubleshooting this problem - had no effect
The error I'm getting is 'city' is undefined. IE10 is the only browser experiencing this issue.
Here's a CodePen of just the relevant code. I've added comments to clarify what's going on. Here is just the JS (see CodePen for full code and better context):
/* Server rendered data */
var events = [{
path: "events/residuals-biosolids",
name: "Residuals & Biosolids Conference",
sortDate: "1536165900000",
startDate: "4 September 2018",
endDate: "5 October 2018",
displayDate: "September 4 - October 5, 2018",
state: "WI",
city: "Milwaukee",
booth: "342",
featuredImg: "https://cdn2.hubspot.net/hubfs/4299619/event%20thumb.png"
}, {
path: "events/bio-expo",
name: "Biosolid Expo",
sortDate: "1548979200000",
startDate: "6 February 2019",
endDate: "5 March 2019",
displayDate: "February 6 - March 5, 2019",
state: "MN",
city: "Eagan",
booth: "12",
featuredImg: ""
}, {
path: "events/world-ag-expo",
name: "World AG Expo",
sortDate: "1549670400000",
startDate: "7 February 2019",
endDate: "2 February 2019",
displayDate: "February 7 - 2, 2019",
state: "CA",
city: "Tulare",
booth: "3815",
featuredImg: ""
}];
var eventsDesc = [{
path: "world-ag-expo",
name: "World AG Expo",
sortDate: "1549670400000",
startDate: "7 February 2019",
endDate: "2 February 2019",
displayDate: "February 7 - 2, 2019",
state: "CA",
city: "Tulare",
booth: "3815",
featuredImg: ""
}, {
path: "bio-expo",
name: "Biosolid Expo",
sortDate: "1548979200000",
startDate: "6 February 2019",
endDate: "5 March 2019",
displayDate: "February 6 - March 5, 2019",
state: "MN",
city: "Eagan",
booth: "12",
featuredImg: ""
}, {
path: "residuals-biosolids",
name: "Residuals & Biosolids Conference",
sortDate: "1536165900000",
startDate: "4 September 2018",
endDate: "5 October 2018",
displayDate: "September 4 - October 5, 2018",
state: "WI",
city: "Milwaukee",
booth: "342",
featuredImg: "https://cdn2.hubspot.net/hub/4299619/hubfs/event%20thumb.png?width=760&name=event%20thumb.png"
}];
var selectedStates = ["CA", "MN", "WI", ];
var selectedCities = ["Eagan", "Milwaukee", "Tulare", ];
/*
Vue code below
*/
var app = new Vue({
el: "#sg-events-wrapper",
data: {
message: "Hello Vue!",
dateOrder: "ascending",
selectedCity:"none",
selectedState:"none",
/*the data below is pulled from the script tag in the page.*/
eventCities:selectedCities,
eventStates:selectedStates,
eventList: events,
eventListDesc:eventsDesc,
},
computed: {
eventsSorted:function(){
/*chooses which server generated list to use for rendering events*/
if(this.dateOrder=="ascending"){
return this.eventList;
}
else{
return this.eventListDesc;
}
},
},
methods:{
/*handles the visual filtering when someone sets city and or state*/
isInStateAndCity:function(eventsCity,eventsState){
var citiesMatch;
var statesMatch;
if(eventsCity == this.selectedCity || this.selectedCity=="none"){
citiesMatch = true;
}else{
citiesMatch = false;
}
if(eventsState == this.selectedState ||this.selectedState=="none"){
statesMatch = true;
}else{
statesMatch = false;
}
if(citiesMatch && statesMatch){
return true;
}else{
return false;
}
}
}
});
Troubleshooting steps I've tried:
Used babel, though my code originally isn't written that way.
I used the babel-polyfill - did not seem to have an effect.
I tried to place the js that's in the script tag in the body into the main JS file to see if there was an issue with the js file being loaded for some reason before the code in the HTML. Had no effect.
What I think could be causing the issue: IE10 doesn't like assigning property values to objects like I'm doing. Not certain of this. It's just a guess and I can't think of another way to do it.
Screenshot of IE 10 console error and failed rendering in CodePen in-case it helps.
If you have any ideas but don't have a way to test: I can test any changes and send back a recording of what I see and the console if it has errors.
Posting the answer myself, as others will likely come across this issue too, and there isn't much info out there.
There were two issues. My selectedCities and selectedStates arrays had a comma at the end. Newer browsers don't care about that, but <=IE10 do.
In addition there is a VueJS issue. Someone updated Vue JS to use a new regex string that IE 10 and down do not understand. The fix is to either use an older version of VueJS or replace the regex. Instructions at the source of where I found this info:
https://github.com/vuejs/vue/issues/7946#issuecomment-393713941
const users =
[
{
name: "Joy soap",
customerName: "Salomy",
date: "19 March 2018",
time: "08:46am",
amount: 3000,
status: "paid",
number: 24,
images:
"https://snack1.amazonaws.com/~asset/9d799c33cbf767ffc1a72e53997218f7"
},
{
name: "Closeup tooth paste",
customerName: "Salomy",
date: "19 March 2018",
time: "08:46am",
amount: 3000,
status: "paid",
number: 20,
images:
"https://1.amazon4d99c3d76575cc03c2a7f816280"
},
{
name: "Iman Powder",
customerName: "Emanbe",
date: "20 March 2018",
time: "11:25am",
amount: 3000,
status: "paid",
number: 12,
images:
"https://1.amazonaws.com/~asset/ee06c63d01543a44631c3421df6ee5fa"
},
{
name: "John Bellion",
customerName: "Okonkwo Chioma",
date: "20 March 2018",
time: "08:46am",
amount: 3000,
status: "paid",
number: 3,
images:
"https://sn1.amazonaws.com/~asset/ee06c63d01543a44631c3421df6ee5fa"
}
];
Please I have an array of objects like the above that I want to render in a ListView with a Section Header function pointing to user.date... I want it to render a list of all the items on 19 March 2018, and then render the items on 20 March 2018 under the header also.
I have used ListView several times but I have never been able to use the section header in this way with the above arrays of object. Please a detailed explanation would be greatly appreciated. I know its probably a simple task to some of you but please be kind. I need a renderSectionHeader() function that can organize the data with respect to their dates so I can render it in my listview like this
`<ListView
ref={ref => (this.scrollView = ref)}
onContentSizeChange={() => {
this.scrollView.scrollToEnd({ animated: false});
}}
dataSource={this.state.userDataSource}
renderRow={this.renderRow.bind(this)}
renderSectionHeader={this.renderSectionHeader.bind(this)}
/>`
An example of what I want is here but I want to know how it can be done with the above array
ListView is no longer available in React-Native. You can use FlatList. Its very simple then ListView as well.
1) Import FlatList from react-native:
import { FlatList } from 'react-native';
2) Copy Below code into your render() method.
<FlatList
horizontal={true/false}
style={YOUR_COSTOM_STYLE}
data={YOUR_ARRAY}
renderItem={this.renderItem.bind(this)}
keyExtractor={(item, index) => String(index)}
/>
3) You do necessary stuff for your cell in renderItem method.
// Render Methods
renderItem({ item }) {
return (
// DO_YOUR_STUFF
);
}
You can more detail about FlatList from here.
One more example for header in FlatList