So, I'm creating a fairly complex Vue application that fetches data from our backend API and displays it on the front-end, depending on filters the person selects. Its default is to display everything at once, then once the user selects filters, it will pull out the "card" components that don't have those attributes. Everything has been going great until today, which I tried to add Google Maps into it, via their API (I'm using the vue2-google-maps package to make this easier on myself, since we plan to implement Polylines in the future).
The problem is that I'm utilizing Foundation as my CSS framework and initializing the map within a Reveal modal. The only way I've been able to get the modal working without any warnings in the console is by using an example I found online which utilizes the mounted() property:
mounted() {
$(this.$el).foundation();
},
unmounted() {
$(this.$el).foundation.destroy();
}
This works great, until I try to call a Google Map inside the modal, because instead of creating the map when the modal fires, it creates everything on page load. Not a big deal if I was only creating a few maps... but on-load I'm rendering 92 maps. As you can imagine, this is incredibly slow.
In its simplest form, the structure of my app is:
<app>
<filters-component></filters-component>
<div class="off-canvas-content">
<nav-component></nav-component>
<div class="row card-grid">
<card-component>
<modal-component></modal-component>
</card-component>
</div>
</div>
</app>
Currently, the modal component is the only nested component, mostly just so it's easier to keep track of what modal belongs to which card.
Before, I was using a method to fire each modal, which looked like this, with a #click event on the open modal button, however, this still renders all maps on load and also gives a console error that reads "VM215130:180 Tried to initialize reveal on an element that already has a Foundation plugin." If you click the button more than once.
<a :data-toggle="'modal-' + school.id" #click="openModal(school.id)" class="float-right" tabindex="0" aria-label="Open More window" title="Open More window">
More <icon name="info-circle" label="More information icon"></icon>
</a>
<script>
export default {
methods: {
openModal: function($schoolid) {
$('#modal-' + $schoolid).foundation();
console.log('modal-' + $schoolid + ' launched')
}
}
</script>
Is there a way to only create the modal component when this button is clicked, or somehow lazy load it only when the modal is opened?
Related
I have a page that catalogues media (think similar to an instagram page). The media is viewable on modals, and I'd like to record a "view count" for each piece of media. So whenever the modal containing that media is toggled open, it records a view.
This is a simplified version of my code:
<button data-toggle="modal" data-target="media-number-999">Click to view Media 999!</button>
<div class="modal" id="media-number-999">Media #999 viewable here!</div>
I also have a page set up where visiting that page automatically increases the viewcount by 1, and then redirects elsewhere (using django)
urls.py:
path('views/<id>/', views.media_views, name="mediaviews"),
views.py:
def media_views(request,id):
Media.objects.filter(id=id).update(views=F('views') + 1)
return redirect('media_detail', id=id)
The reason I'm doing this is so that I can then reference the viewcount in the database to use for sorting/filtering/etc.
How can I make a button that both opens the modal, and also records a visit to /views/999/ ? Also open to alternative approaches if there are better ways! I've tried to figure out how to use Ajax to do this but haven't had any luck.
Thanks!
Add an onclick function to
</button data-toggle="modal" data-target="media-number-999" onclick="recordview(999)">Click to view Media 999!<//button>
Create a new endpoint on your app that has the following format: /record/{id}
Make a function recordview() that makes a simple HTTP request (No need for AJAX) to your new endpoint
Remove the Media.objects.filter(id=id).update(views=F('views') + 1)in media_views to avoid double recording (From when they clicked vs when they opened) or change the model in media_views
(There is no / at the start of but i had to add it otherwise StackOverflow wouldn't format it properly. Make sure to remove it (And let me know if you know how to format it without the damn slash!)
I have an select dialog. For performance reason, I have kept growing threshold as 100 records, out of 2000 total records.
So, the user can see 100 records when popovers open. I had written growingScrollToLoad so that when the user scrolls down, another 100 records get loaded.
However, this is not working somehow. Popover only shows 100 records initially, and even if I scroll down it doesn't load more data. I am not sure what am I doing wrong. I had tried using all the tags/properties describe in SAPUI5 Guidelines. Also, it works in https://sapui5.hana.ondemand.com/#/sample/sap.m.sample.SelectDialog/preview
<SelectDialog confirm="handleConfirm"
growingThreshold="100"
growingScrollToLoad="true"
items="{myModel>/AllData}"
multiSelect="true"
noDataText="No data"
liveChange="handleSearchOnDialog"
title="Choose"
autoAdjustWidth="true">
<StandardListItem id="idItemA"
description="{Name}"
iconDensityAware="false"
iconInset="false"
title="title"
type="Active"/>
</SelectDialog>
Please look at the API:
https://sapui5.hana.ondemand.com/#/api/sap.m.SelectDialog
You will notice growingScrollToLoad is not listed in the property section of sap.m.SelectDialog ==> you cannot use this functionality
The property growingScrollToLoad is a property of sap.m.ListBase. So if you want to use it you need to create a custom dialog that has a sap.m.List or any other child of sap.m.ListBase as content.
(sap.m.SelectDialog is a direct child to sap.ui.core.Control -> no direct relation to sap.m.ListBase)
I found a solution without changing control.
In XML file, I provided growingThreshold="100" growing="true" to Select dialog. In controller file, for onOpen event of Select dialog, I have written this piece of code:
var sGrowingThreshold = this._oSelectDialog.getGrowingThreshold(); //sGrowingThreshold will be 100
if (sGrowingThreshold)
{
this._oSelectDialog.setGrowing(sGrowingThreshold);
}
It worked and loads data everytime I scroll down till the end.
I jump from a page that is not a tab to a tab page.
On the tab page,I want to go-back when the item is clicked. I use $ionicHistory.goBack() to go back.
I found a strange situation, the firsttime $ionicHistory.goBack() is working, but the second time is not working。
My ionic version is : 1.3.1
I have created a codepen demo
to reproduce the bug:
click Go DashPage Button -> click Select button -> click item -> click Select button -> click item
Ionic maintains the history stack of tabs and menus separately.
Updated answer
Insted of
<ion-item ng-click="onItemClick()">item 1</ion-item>
try
<ion-item ui-sref="dash-page">item 1</ion-item>
Let me know if this helps
Old Answer
Create your own myGoBack() funtion
put this in your view
<ion-nav-buttons>
<button class="button" ng-click="myGoBack()"><i class="ion-chevron-left"></i> </button>
</ion-nav-buttons>
and this in your controller
$scope.myGoBack = function () { $ionicHistory.goBack(); }
If you are using tab pages ,i highly recommend to have every page as a tab. For those that you dont wish to appear on the tab but would like to use as a page, you can add the "hidden="true" property to
<ion-tab title="Home" icon-off="ion-home" icon-on="ion-home" href="#/app/home" hidden="true">
The way you have coded your 'chat' state will give you lots of problems in the future. To be better understand states, i suggest download starter apps. A good one would be Ionic Tabs Plus Sidemenu Starter
Its free and should give you a better understanding of using states outside of a tab, inside a tab-formatted ionic project.
I want to hide a list of users when I to display the nested view users.info .
I wrote this code
HTML
<div ng-hide="hide">
the list of users...
<a ui-sref="users.info"> <button ng-click="hideUsersList()"> </a>
</div>
Controller
$scope.hideList = function hideList()
{$scope.hide=true;};
it works and hide the list when I click on the button, but the problem is when I use the back button in the browser, hide still 'true' and I get a blank page
If you only hide the DOM element, the scope remains and the hide variable is still attached to it with the latest value.
If I understand correctly, what you are looking for is maybe switching the nested views when moving between states, that way each time you move to a new state you'll be instantiating a new controller and a new scope.
Nested States, Nested Views
I am trying to include two fullcalendars on one page. The first should only be visible on screen and the second should only be visible on print.
<div class="hidden-print">
<h1>This is hidden in print</h1>
<div id="calendar"></div>
</div>
<div class="visible-print">
<h1>This is visible in print</h1>
<div id="calendar2"></div>
</div>
But when I print the page, the second calendar is not visible and if I check the source the contents of the second calendar is not rendered. I created a plunk to demonstrate it: http://run.plnkr.co/plunks/RQx1Up2Y1jbzs9Ixm2aX/
(code: http://plnkr.co/edit/RQx1Up2Y1jbzs9Ixm2aX)
It makes sense since this is expected behaviour according to the fullcalendar docs:
"Notice that this example calls render whenever any tab is shown, not just the tab that the calendar is within. This is okay, because FullCalendar is smart enough to only render calendars that are visible to the user." http://fullcalendar.io/docs/display/render/
Is it somehow possible to override this behaviour and put a fullcalendar within a "visible-print"-class anyway?
This isn't a great answer and I would love to see a better one. But it should work if you have a fairly static fullcalendar.
Essentially, start with the FC outside of the visible-print, render it, then move it in.
$('#calendar2').fullCalendar({});
$('#calendar2').fullCalendar('render');
$('#calendar2').appendTo(".visible-print");
Plunker
Note that every time you make a change to it, it will need to be moved out and rendered again.