I'm using angular bootstrap calendar by https://github.com/mattlewis92/angular-bootstrap-calendar#installation
I am not able to see the calendar template it looks like this
angular controller is
module app.calendar.controllers {
import angularCalendar = angular.bootstrap.calendar;
export class calendarSample1Controller //implements angular.bootstrap.calendar.events.IOnEditEventClick
{
calendarTitle: string;
calendarView: string = "month";
viewDate: Date = new Date();
events: Array<angularCalendar.IEvent>;
isCellOpen: boolean = true;
customTemplateUrls: string[];
constructor(private calendarConfig: angularCalendar.ICalendarConfig, private $templateCache: ng.ITemplateCacheService, private $http: ng.IHttpService) {
$templateCache.get('calendar.html');
this.getEvents();
}
private getEvents() {
//TODO get all the events from service
this.events = [
{
title: 'An event',
color: this.calendarConfig.colorTypes.hearings,
startsAt: moment().startOf('week').subtract(2, 'days').add(8, 'hours').toDate(),
endsAt: moment().startOf('week').add(1, 'week').add(9, 'hours').toDate(),
draggable: false,
resizable: false,
}, {
title: '<i class="glyphicon glyphicon-asterisk"></i> <span class="text-primary">Another event</span>, with a <i>html</i> title',
color: this.calendarConfig.colorTypes.holidays,
startsAt: moment().subtract(1, 'day').toDate(),
endsAt: moment().add(5, 'days').toDate(),
draggable: false,
resizable: false,
}, {
title: 'This is a really long event title that occurs on every year',
color: this.calendarConfig.colorTypes.inspections,
startsAt: moment().startOf('day').add(7, 'hours').toDate(),
endsAt: moment().startOf('day').add(19, 'hours').toDate(),
recursOn: 'year',
draggable: false,
resizable: false,
}
];
}
eventClicked(calendarEvent: angularCalendar.IEvent): void {
console.log("clicked");
};
}
}
and the view I am using is this
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<h1>Calendar sample 1</h1>
<div ng-controller="calendarController as vm">
<h2 class="text-center">{{ vm.calendarTitle }}</h2>
<div class="row">
<div class="col-md-6 text-center">
<div class="btn-group">
<button class="btn btn-primary"
mwl-date-modifier
date="vm.viewDate"
decrement="vm.calendarView">
Previous
</button>
<button class="btn btn-default"
mwl-date-modifier
date="vm.viewDate"
set-to-today>
Today
</button>
<button class="btn btn-primary"
mwl-date-modifier
date="vm.viewDate"
increment="vm.calendarView">
Next
</button>
</div>
</div>
<br class="visible-xs visible-sm">
<div class="col-md-6 text-center">
<div class="btn-group">
<label class="btn btn-primary" ng-model="vm.calendarView" uib-btn-radio="'year'">Year</label>
<label class="btn btn-primary" ng-model="vm.calendarView" uib-btn-radio="'month'">Month</label>
<label class="btn btn-primary" ng-model="vm.calendarView" uib-btn-radio="'week'">Week</label>
<label class="btn btn-primary" ng-model="vm.calendarView" uib-btn-radio="'day'">Day</label>
</div>
</div>
</div>
<br>
<mwl-calendar events="vm.events"
view="vm.calendarView"
view-title="vm.calendarTitle"
view-date="vm.viewDate"
on-event-click="vm.eventClicked(calendarEvent)"
on-event-times-changed="vm.eventTimesChanged(calendarEvent); calendarEvent.startsAt = calendarNewEventStart; calendarEvent.endsAt = calendarNewEventEnd"
cell-is-open="vm.isCellOpen"
day-view-start="06:00"
day-view-end="22:59"
day-view-split="30"
cell-modifier="vm.modifyCell(calendarCell)">
</mwl-calendar>
</div>
The controller is bound like this
module app.calendar {
"use strict";
import calendarSample1Controller = app.calendar.controllers.calendarSample1Controller ;
import angularCalendar = angular.bootstrap.calendar;
angular.module("app.calendar", ['mwl.calendar', 'ui.bootstrap','ngAnimate',])
.controller("calendarController", ["calendarConfig", "$templateCache", '$http', calendarSample1Controller])
.config(function () {
});
}
There are no errors on the page but the template isn't loading,
I'm not sure where to place the templates, the project convention is not to use html files but to return razor views so I even attempted to give urls in the calendarConfig.templates but the code to get the template content gets called before the templates are actually loaded.
I'm not sure if I'm doing something wrong with this plugin, but if someone can explain how the templates are loaded that would be great.
Thanks!
The templates were simply not loaded, the js requires you to load the templates into templatecache, I used
template content to have them into the template cache in order to show them
Related
So, I'm working on a calendar app and I'm using Laravel and FullCalendar for this.
I want to be able to delete an event - once I click on the event in the calendar, a modal popup show up with a delete button. In order to delete the event, I must know its ID, but I can't get.
I can get it via JS selectors and display it as a text, but I can't figure out how to get it as a PHP variable so that I could use it in the action parameter of the form.
The reason why I'm doing this in the way I did it is: If I get all the events and "foreach" them into the "events" array of FullCalendar, my source code when the calendar renders would be a mess, full of events and their details. By using this approach, I find that events are not displayed in the source and the page renders more quickly (but I might be mistaken).
The way I display events from the database is as follows:
EventsController
public function getEvents()
{
return Event::where('event_date', '>', '2022-01-01')
->join('hospitals', 'events.hospital_id', '=', 'hospitals.hospital_id')
->select('hospitals.hospital_color', 'hospitals.hospital_max_people', 'event_id', 'event_content', 'event_date', 'user_id')
->get()
->map(fn ($events) => [
'id' => $events->event_id,
'title' => $events->event_content,
'start' => $events->event_date,
'allDay' => true,
'editable' => false,
'backgroundColor' => $events->hospital_color,
'borderColor' => $events->hospital_color,
'hospital_max_people' => $events->hospital_max_people,
'volunteer' => User::find($events->user_id)->first_name .' '. User::find($events->user_id)->last_name
]);
}
Events blade template - FullCalendar settings:
<script>
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
editable: false,
droppable: true,
selectable: true,
initialView: 'dayGridWeek',
views: {
dayGridWeek: {
type: 'dayGridWeek',
duration: { weeks: 2 },
buttonText: '4 day'
}
},
header: {
left: 'prev,next today',
center: 'title',
right: 'month,listMonth'
},
themeSystem: 'bootstrap5',
locale: 'en',
firstDay: '1',
contentHeight: 500,
height: 700,
expandRows: true,
events: 'getEvents',
eventClick: function(calendar, jsEvent, view) {
$('#eventDetail').modal("show");
$('#id').html(calendar.event.id);
$('#title').html(calendar.event.title);
$('#start').html(moment(calendar.event.start).format('DD.MM.YYYY'));
$('#volunteer').html(calendar.event.extendedProps.volunteer);
}
});
calendar.render();
});
</script>
Events blade template for showing modal:
<div class="modal fade" id="eventDetail" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="bar" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="staticBackdropLabel">Event details</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
Start: <p id="start"></p>
Volunteer: <p id="volunteer"></p>
Title: <p id="title"></p>
</div>
<div class="modal-footer">
<form method="POST" action="{{ route('calendar.destroy') }}" class="needs-validation" novalidate=""></p>
#csrf
#method('DELETE')
<div class="form-group">
<x-button tabindex="3">
{{ __('Delete event') }}
</x-button>
</div>
</form>
</div>
</div>
</div>
</div>
So, I did it in anoter way; just wanted to post the answer - I added a hidden input field: <input type="hidden" name="id" id="id" value=""> and the value is filled out when a modal opens with addition of this to the original id selector: $('#id').html(calendar.event.id).attr('value', calendar.event.id);
I also had to alter my delete route: Route::DELETE('calendar/destroy/{event_id}'
And that's it. Thank you anyway for your help
I am using the #jsplumb/browser-ui to create some Nodes within my Nuxtjs/Vuejs application like as mentioned in their documentation. But I would like to create the Nodes at run-time. I am unable to do it.
I would like to create the nodes/rectangle shapes whenever the user clicks on the Add Event button. So rather than creating the Nodes static way I would like to create it dynamically/run time based on the button click. I am not understanding how to do it using jsPlumb documentation how to do it as they don't have a specific code sample to achieve the same.
Following is the code I have:
<template>
<div>
<div class="container-fluid">
<div class="row">
<div class="col-md-6">
<button class="btn btn-primary btn-sm" #click="addConnector()">
Add Connector
</button>
<button class="btn btn-primary btn-sm" #click="addNode()">
Add Event
</button>
<button class="btn btn-success btn-sm" #click="submitEvents()">
Submit
</button>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div id="diagram" ref="diagram" style="position: relative; width:100%; height:100%;" />
</div>
</div>
</div>
</div>
</template>
<script>
let jsPlumb = null
export default {
data () {
return {
nodeCounter: 0,
nodeArray: [],
connectorCounter: 0,
connectorArray: [],
allEventsInfoArray: []
}
},
async mounted () {
if (process.browser) {
const jsPlumbBrowserUI = await import('#jsplumb/browser-ui')
jsPlumb = jsPlumbBrowserUI.newInstance({
dragOptions: {
cursor: 'pointer',
zIndex: 2000
},
container: this.$refs.diagram
})
console.log(jsPlumb)
}
},
methods: {
// On click of Add Node button create the draggable node into the jsPlumb canvas
addNode () {
// const container = "<button class='btn btn-info' id='container_" + this.nodeCounter + "'></button>"
this.nodeCounter++
},
// On click of Add Connector button create the draggable node into the jsPlumb canvas
addConnector () {
console.log('Add Connector : ')
jsPlumb.connect({
anchor: 'AutoDefault',
endpoints: ['Dot', 'Blank'],
overlays: [
{ type: 'Arrow', options: { location: 1 } },
{
type: 'Label',
options: { label: 'foo', location: 0.25, id: 'myLabel' }
}
]
})
}
}
}
</script>
<style scoped>
</style>
Hoping this answer would be helpful to someone in the future:
As per the response from contributors GitHub, we cannot create the Nodes/Shapes within the Jsplumb community edition.
Instead of Jsplumb, I started using the DrawFlow library which is just awesome and has all the requirements that I needed for my application.
In my vue app i am calling a function on click event, which is located in a component. Here is the component code:
Vue.component( 'new-board', {
template: `
<div>
<br/>
<div class="panel panel-primary">
<div class="panel-heading">
Create New Board
</div>
<div class="panel-body">
<input class="form-control" placeholder="Board Name"/>
<button
style="margin-top: 5px;"
#click.stop="addBoard"
class="btn btn-success btn-xs btn-block"
>
Add Board
</button>
</div>
</div>
</div>
`
} )
Here is the vue app instance:
var boardItem = new Vue( {
el: "#board-item",
data: {
boards: [
{ name: 'learning vue 2' }
],
newBoard: [],
viewNewBoard: true
},
methods: {
displayNewBoard: function() {
event.preventDefault()
if( this.viewNewBoard == false ) {
this.viewNewBoard = true
} else {
this.viewNewBoard = false
}
},
addBoard: function() {
console.log( 'add board' )
}
}
} )
Now, when i click on the Add Board button from the above component, it is showing this error:
Uncaught ReferenceError: addBoard is not defined
at click (eval at Xr (vue.min.js:7), :2:455)
at HTMLButtonElement.invoker (vue.min.js:6)
It seems that the button from the component can't find the addBoard method, which is written in the same file!
What i am missing here?
Try:
Vue.component( 'new-board', {
template: `
<div>
<br/>
<div class="panel panel-primary">
<div class="panel-heading">
Create New Board
</div>
<div class="panel-body">
<input class="form-control" placeholder="Board Name"/>
<button
style="margin-top: 5px;"
#click.stop="addBoard"
class="btn btn-success btn-xs btn-block"
>
Add Board
</button>
</div>
</div>
</div>
`,
methods: {
addBoard: function(){ console.log('add board');}
}
} )
A few changes here, if you want to share events with components that are not related you must use a new vue instance to fire those events and listen. So based on your code this should help.
window.Event = new Vue();
Vue.component( 'new-board', {
template: `
<div>
<br/>
<div class="panel panel-primary">
<div class="panel-heading">
Create New Board
</div>
<div class="panel-body">
<input class="form-control" placeholder="Board Name"/>
<button
style="margin-top: 5px;"
#click.stop="addBoard" // keep this as the name of the local method
class="btn btn-success btn-xs btn-block">
Add Board
</button>
</div>
</div>
</div>
`,
methods:{
addBoard(){
// fire the event, also you can add any params
Event.$emit('callAddBoard',data)
}
}
} )
And the main instance should listen to that event
var boardItem = new Vue( {
el: "#board-item",
data: {
boards: [
{ name: 'learning vue 2' }
],
newBoard: [],
viewNewBoard: true
},
methods: {
displayNewBoard: function() {
event.preventDefault()
if( this.viewNewBoard == false ) {
this.viewNewBoard = true
} else {
this.viewNewBoard = false
}
},
addBoard: function() {
console.log( 'add board' )
}
},
created(){
// here you listen and excute the remote event from component, and apply a local method.
Event.$on('callAddBoard', this.addBoard)
}
} )
As far as I tried this works , and you can send events to any component without the need of passing through the main instance.
I have a simple ItemView that's being rendered inside a modal window, using the technique of a custom modal region.
I have several modal regions on top of each other, and it does not seem to affect negatively the events of other views (that are also modal).
No events at all are being fired. I already debugged Marionette sources, and it looks like it's passing through the delegateEvents method correctly, without errors.
Here's the view:
"use strict";
define(function(require){
var Marionette = require("marionette");
var BaseModalView = require("views/Base/BaseModal");
var PointOfInterestModalTemplate = require("text!templates/PointOfInterest/PointOfInterestModal.html");
var DistanceHelper = require("utils/DistanceHelper");
return Marionette.ItemView.extend({
template: PointOfInterestModalTemplate,
events: {
"click #route-button": "route",
"click #like-button": "like",
"click .report-button": "report"
},
route: function(event) {
console.log("route");
//var coordinates = this.model.attributes.geometry.coordinates;
//var originalLatLng = L.latLng(coordinates[1], coordinates[0]);
//vent.trigger("routing:routeTo", originalLatLng);
},
like: function(event) {
console.log("like");
},
report: function(event) {
console.log("report");
},
onRender: function() {
var distanceHelper = new DistanceHelper();
var distanceString = distanceHelper.verboseDistance(this.model.geometry._latlng);
this.$("#distance-placeholder").html(distanceString);
}
});
});
My template is pretty lengthy, but here's the relevant part (I checked and the whole thing is production correct HTML)
<script type="text/template">
<div id="poi-info-modal" class="modal fade" tabindex="-1" style="display: none">
<div class="modal-header modal-header-blue">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">×</span></button>
<h4 class="modal-title">Details</h4>
</div>
<div class="modal-body">
<div class="container-fluid">
<h2><%= name %></h2>
<div class="row">
<div class="col-xs-12 col-md-12">
<p class="small">
<% if (address) { %>
<%= address %>
<% } else { %>
No address available
<% } %>
</p>
<p class="small">
<span id="distance-placeholder"></span>
</p>
</div>
</div>
<div class="row margin-top-row center-row">
<div class="col-xs-4 col-md-4">
<a href="javascript:void(0)" id="route-button" class="btn btn-circle btn-lg btn-blue">
<i class="fa fa-map-marker"></i>
</a>
</div>
<div class="col-xs-4 col-md-4">
<a id="like-button" class="btn btn-circle btn-blue btn-lg">
<i class="fa fa-heart"></i>
</a>
</div>
<div class="col-xs-4 col-md-4">
<a href="javascript:void(0)" class="report-button btn btn-circle btn-blue btn-lg">
<i class="fa fa-exclamation-triangle"></i>
</a>
</div>
</div>
</div> <!--container-->
</div> <!--modalbody-->
</div> <!--modal-div-->
Other views are used in similar fashion, and work quite well.
the basics for displaying this modal is using a region, like this:
var region = new ModalRegion();
region.show(new ModalView({model: model});
Here's is the region for reference. The weird thing is that this does give any errors or whatsoever.
"use strict";
define(function(require){
var $ = require("jquery");
var bootstrap = require("bootstrap");
var bootstrapModal = require("bootstrap-modal");
var Marionette = require("marionette");
return Marionette.Region.extend({
el: "#modal-container",
constructor: function(){
Backbone.Marionette.Region.prototype.constructor.apply(this, arguments);
this.on("show", this.showModal, this);
},
getEl: function(selector){
var $el = $(selector);
$el.on("hidden", this.close);
return $el;
},
showModal: function(view){
view.on("close", this.hideModal, this);
var width = view.modalWidth || 700;
var height = view.modalHeight || 600;
var maxHeight = view.modalMaxHeight || 600;
$(".modal").modal({
show: true,
width: width,
height: height,
maxHeight: maxHeight
});
},
hideModal: function(){
$(".modal").modal({
show: false
});
}
});
});
I know this kinda boring and hard to help, but I appreciated it. Thanks!
How do I use nested models with Backbone Forms List? I want to make a nested model with a custom template, but this is giving an error: "Render of undefined"
I want to make a view by backbone-forms with a custom template. The template is
<div class="container-fluid add-apikey" data-class="add-apikey">
<div class="page-head">
<h2>API Key</h2>
</div>
<div class="cl-mcont">
<div class="row">
<div class="col-sm-12">
<!-- New Zone -->
<div class="block-flat">
<form class="form-horizontal" role="form">
<div class="header">
<h3>Create New API Key</h3>
</div>
<div class="content">
<div class="formAlerts"></div>
<div class="formconfirm"></div>
<div class="required" data-fields="apiName">
</div>
<div class="required" data-fields="notes">
</div>
<div class="required" data-fields="weapons">
</div>
<div class="form-group editmode">
<div class="col-sm-offset-3 col-sm-9">
<button class="btn btn-primary readOnlySave" type="button">Generate Key</button>
<button class="btn btn-default readOnlyCancel">Cancel</button>
</div>
</div>
</div>
</form>
</div>
</div>
<!-- end new zone -->
</div>
</div>
and the js is
//Add api keys
var //util
util = require('./../../../util/util.js'),
apiKeyAddTpl = require('./../templates/apikeyadd.hbs'),
backboneFormList = require('backboneFormsList'),
backboneFormsModal = require('backboneFormsModal');
module.exports = Backbone.Form.extend({
template: apiKeyAddTpl,
schema: {
apiName: {
type: 'Text',
fieldClass: "field-apiName form-group",
editorClass: "form-control editmode"
},
notes: {
type: 'List',
fieldClass: "field-notes form-group",
editorClass: "form-control editmode"
},
weapons: {
type: 'List',
itemType: 'Object',
fieldClass: "field-weapon form-group",
editorClass: "form-control editmode",
subSchema: {
id: 'Number',
name: {
type: 'Text'
}
}
}
}
});
But this is giving me an error when I want to add a field under weapons.
The error is : Cannot read property 'render' of undefined.
You need to extend a View: Backbone.View.extend. This view have a el attribute. You must you must associate this attribute with the form. And the views have a method render that you can override.
Doc: backbone view