Meteor finding this._id in onRendered function - meteor

I have an initializing function and I want to detect when a label is removed for a dropdown menu (from Semantic UI):
call.js
Template.calledit.onRendered(function() {
$('.ui.dropdown').dropdown({
onLabelRemove(value) {
console.log(value);
console.log(this._id);
}
});
});
call.html
<template name="calledit">
<div class="field">
<label>Assign Units</label>
<div id="edit_call_assign_units_{{_id}}" class="ui multiple search selection dropdown">
<input type="hidden" name="edit_call_assign_units_{{_id}}" value="{{units}}">
<i class="dropdown icon"></i>
<div class="default text">Assign Units</div>
<div class="menu">
<div class="item" data-value="420">420</div>
<div class="item" data-value="F-117">F-117</div>
<div class="item" data-value="805">805</div>
<div class="item" data-value="230">230</div>
<div class="item" data-value="506">506</div>
</div>
</div>
</div>
<template>
However, I have a problem with detecting the _id of the template that it was called in. How would I access this._id in the onRendered function?

Looks like wrong context, maybe this
Template.calledit.onRendered(function() {
var tmpl = this;
$('.ui.dropdown').dropdown({
onLabelRemove(value) {
console.log(value);
console.log(tmpl._id);
}
});
});
Or if you use ecmascript, then
Template.calledit.onRendered(function() {
$('.ui.dropdown').dropdown({
onLabelRemove: (value) => {
console.log(value);
console.log(this._id);
}
});
});

Related

Component not updating when one-way databound property updated

I'm having a heck of a time understanding why my component's UI will not re-render when a simple one-way databound property (List) is updated. I have other routable components re-rendering using the same approach without issue, but this non-routable component does not seem to want to behave the same way? It is my understanding that the component should update WITHOUT having to call StateHasChanged() on either onclick events.
#inherits Aivia.Bases.AltitudePage;
#inject IAlertService _alertService
#inject IJSRuntime _js;
#if (dsAlerts != null && dsAlerts.Any())
{
<div class="alerts mt-3">
<div class="container">
#foreach (var dto in dsAlerts)
{
<div class="alert alert-primary p-3" role="alert">
<div class="row g-0">
<div class="col-auto icon">
<i class="fa-solid fa-comments"></i>
</div>
<div class="col">
<div class="title">
#dto.Title
</div>
<div class="description">
#dto.Description
</div>
<div class="actions">
<button type="button" class="btn btn-primary" onclick="#(() => Read(dto))">
<i class="fa-regular fa-circle-check me-2"></i>
Dismiss
</button>
</div>
</div>
</div>
</div>
}
</div>
</div>
}
#code {
private IEnumerable<dtoAlert> dsAlerts = Enumerable.Empty<dtoAlert>();
protected override void OnInitialized()
{
GetAlerts();
}
private void GetAlerts()
{
this.dsAlerts = _alertService.queryUnreadAlerts(this.UserID).OrderBy(x => x.CreatedOn).ToList();
}
private void Read(dtoAlert dto)
{
_alertService.Read(this.UserID, dto.ID);
GetAlerts();
}
}
onclick="#(() => Read(dto))" simply needed to be #onclick="#(() => Read(dto))"

how to properly use meteor's ironRouter waitOn?

I have abround 6000 documents in my mongo collection, which I need to load up into meteor client upon app startup.
In my routes (located under app/client), I have this:
Router.map(function() {
this.route('home', {
path: '/',
template: 'dashboardWrapper',
waitOn: function() {
return Meteor.subscribe('nasdaq');
},
cache: true
});
});
My dashboardWrapper template looks like this:
<template name="dashboardWrapper">
{{#if Template.subscriptionsReady}}
{{> dashboard}}
{{/if}}
</template>
My dashboard template looks like this:
<template name="dashboard">
<div class="container">
<h2>Priority - 1 Incidents Over Time</h2>
<div class="row">
<div id="yearly-bubble-chart" class="dc-chart">
<strong>Yearly Performance</strong> (radius: fluctuation/index ratio, color: gain/loss)
</div>
</div>
<div class="row">
<div id="gain-loss-chart">
<strong>Days by Gain/Loss</strong>
<a class="reset" href="javascript:gainOrLossChart.filterAll();dc.redrawAll();" style="display: none;">reset</a>
<div class="clearfix"></div>
</div>
<div id="quarter-chart">
<strong>Quarters</strong>
<a class="reset" href="javascript:quarterChart.filterAll();dc.redrawAll();" style="display: none;">reset</a>
<div class="clearfix"></div>
</div>
<div id="day-of-week-chart">
<strong>Day of Week</strong>
<a class="reset" href="javascript:dayOfWeekChart.filterAll();dc.redrawAll();" style="display: none;">reset</a>
<div class="clearfix"></div>
</div>
<div id="fluctuation-chart">
<strong>Days by Fluctuation(%)</strong>
<span class="reset" style="display: none;">range: <span class="filter"></span></span>
<a class="reset" href="javascript:fluctuationChart.filterAll();dc.redrawAll();" style="display: none;">reset</a>
<div class="clearfix"></div>
</div>
</div>
<div class="row">
<div id="monthly-move-chart">
<strong>Monthly Index Abs Move & Volume/500,000 Chart</strong>
<span class="reset" style="display: none;">range: <span class="filter"></span></span>
<a class="reset" href="javascript:moveChart.filterAll();volumeChart.filterAll();dc.redrawAll();"
style="display: none;">reset</a>
<div class="clearfix"></div>
</div>
</div>
<div class="row">
<div id="monthly-volume-chart">
</div>
<p class="muted pull-right" style="margin-right: 15px;">select a time range to zoom in</p>
</div>
<div class="row">
<div>
<div class="dc-data-count">
<span class="filter-count"></span> selected out of <span class="total-count"></span> records | Reset All
</div>
</div>
<table class="table table-hover dc-data-table">
</table>
</div>
<div class="clearfix"></div>
</div>
</template>
The relevant part of Meteor.client looks like this:
if (Meteor.isClient) {
var ndx,data;
Template.dashboardWrapper.onCreated( function() {
var template = this;
template.subscribe("nasdaq");
});
Template.dashboard.onCreated( function() {
data = Nasdaq.find().fetch();
ndx = crossfilter(data);
});
Template.dashboard.onRendered(function(){
var self = this;
self.subscribe("nasdaq", function() {
self.autorun(function() {
data = Nasdaq.find().fetch();
});
});
What I expect from this, is for the dashboard template to wait until all the data from the Nasdaq collection loads up.
What happens is absolutely nothing - no data and no errors.
If I remove ironRounter all together, and refresh, I can get a couple of dozen records (out of 6000 total).
Is there a way reliably force the app to wait until every single document loads up?
Try subscribe right before load the current template, may be it will work.
Router.route('/dashboardWrapper/:_id', {
name: 'dashboardWrapper',
waitOn: function () {
return [
Meteor.subscribe('nasdaq')
];
},
data: function () {
return Nasdaq.findOne(this.params._id);
}
});

getting the text inside a tag from meteor expression

The code below suppose to get the text insdie of the list, so if task1 is clicked then an alert should say task1, if task2 is clicked, then the alert says text2...
But when I click on any of the link, no alert shows up let along its message. I must be doing something wrong. Pleas help. Thanks
Template.mainMenu.helpers({
menuItems: [
{menuItem: "task1"},
{menuItem: "task2"},
{menuItem: "task3"},
{menuItem: "task4"},
{menuItem: "task5"},
{menuItem: "task6"},
{menuItem: "task7"}
]
});
Template.mainMenu.events({
'click .menuItem': function(){
alert(event.target.menuItem.value);
}
});
<template name="mainMenu">
<div class="container">
<div class="row">
<section class="col-xs-12">
<div class="list-group">
{{#each menuItems}}
<a href="#" class="list-group-item menuItem">
<img src="/abc.png">
{{menuItem}} <span class="badge">></span>
</a>
{{/each}}
</div>
</section>
</div>
</div>
</template>
You haven't defined argument (event) of function.
Below example will help you understand that your code was throwing uncaught errors.
Template.mainMenu.events({
'click .menuItem': function(event){
try{
alert(event.target.menuItem.value);
} catch (e){
alert(e)
}
}
});
Update
Add data-value={{menuItem}} to link and then try to get this value using jQuery:
<template name="mainMenu">
<div class="container">
<div class="row">
<section class="col-xs-12">
<div class="list-group">
{{#each menuItems}}
<a href="#" class="list-group-item menuItem" data-value={{menuItem}}>
<img src="/abc.png">
{{menuItem}} <span class="badge">></span>
</a>
{{/each}}
</div>
</section>
</div>
</div>
</template>
Template.mainMenu.events({
'click .menuItem': function(event){
try{
alert($(event.currentTarget).data('value'));
} catch (e){
alert(e)
}
}
});

ng-view expression is; not working

index.cshtml
<head>
<meta name="viewport" content="width=device-width" />
<title></title>
<script src="~/Scripts/angular.min.js"></script>
<script src="~/Scripts/angular-route.min.js"></script>
<link href="~/Content/bootstrap.min.css" rel="stylesheet" />
<script src="~/App/App.js"></script>
<script src="~/App/Controllers/FlightCtrl.js"></script>
</head>
<body>
<div id="wrapper">
Hi
#*<resolve-loader></resolve-loader>*#
<div class="nav navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav" >
<li>#Html.ActionLink("Home", "Index", "Home")</li>
<li class="dropdown">
<a>Add Flight</a>
</li>
</ul>
</div>
</div>
</div>
<div ng-view> </div>
</body>
</html>
App.js
var AirReservationApp = angular.module("AirReservationApp", ['ngRoute']);
AirReservationApp.config(['$routeProvider',
function ($routeProvider)
{
$routeProvider.
when('/Admin', { templateUrl: 'App/Views/Flights/AddFlight.htm', controller: 'FlightCtrl' }).
otherwise({
redirectTo: '/Admin'
});
}
]);
AddFlight.html
<div ng-controller="FlightCtrl">
<ng-form name="formFlight">
<div>
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
<label class="col-xs-12 col-sm-12 col-md-12 col-lg-12" for="question">Question <span class="mandatory">*</span> </label>
<div class="form-group col-xs-9 col-sm-9 col-md-8 col-lg-8"
<input type="text" name="FlightCode"
ng-required="=true" existnamevalidate valid="YN"
placeholder="Enter Flight Code"
ng-model="CreateFlight.Flight.FlightCode">
<span class="help-block"
Flight code is required.>
</span>
<span class="help-block"
This Flight Code already exists.>
</span>
</div>
</div>
<!--ng-show="isTextType"-->
<div class="row btn-pos-change">
<div class="col-md-12 padding-top-12 btn-blocks">
<div class="form-group">
<button type="button" class="btn btn-success pull-right"
>
{{saveBtnText}}
</button>
</div>
</div>
</div>
</div>
</ng-form>
</div>
FlightCtrl.js
var FlightCtrl = angular.module("FlightCtrlModule", []);
FlightCtrl.controller("FlightCtrl", ["$scope", "$rootScope", "$timeout", "$window", "$route",
function ($scope, $rootScope, $timeout, $window, $route)
{
alert('Hello');
$scope.saveBtnText = "Create";
}]);
The expression {{saveBtnText}} does not show 'Create'. Can any one help me on this.
Try this.
First create the FlightCtrlModule module on top of the AirReservationApp module in the App.js and the inject it to the AirReservationApp module.
App.js
angular.module("FlightCtrlModule", []);
var AirReservationApp = angular.module("AirReservationApp", ['ngRoute', 'FlightCtrlModule']);
AirReservationApp.config(['$routeProvider',
function ($routeProvider) {
$routeProvider.
when('/Admin', { templateUrl: '/home.html', controller: 'FlightCtrl' }).
otherwise({
redirectTo: '/Admin'
});
}
]);
Now attach the FlightCtrl controller to the AirReservationApp module to have access to the FlightCtrlModule module.
FlightCtrl
//var FlightCtrl = angular.module("FlightCtrlModule", []);
AirReservationApp.controller("FlightCtrl", ["$scope", "$rootScope", "$timeout", "$window", "$route",
function ($scope, $rootScope, $timeout, $window, $route) {
alert('Hello');
$scope.saveBtnText = "Create";
}]);
UPDATE
If you want to keep your approach, what you can do is, move the flight controller above the app.js like so:
<script src="~/App/Controllers/FlightCtrl.js"></script>
<script src="~/App/App.js"></script>
And then inject the module FlightCtrlModule to the AirReservationApp module, like so:
var AirReservationApp = angular.module("AirReservationApp", ['ngRoute', 'FlightCtrlModule']);
both way have the same result.
Example Project - Dropbox

Angular-material's tabs and ui-bootstrap's datepicker conflict

I have a modal window with angular-material tabs and a ui-bootstrap datepicker. When I open datepicker, the text field moves up, and I cannot access either the datepicker or the field.
Here's a demo in jsFiddle
Here's my code:
var app = angular.module('myApp', ['ui.bootstrap', 'ngAnimate', 'ngAria', 'ngMaterial'])
.controller('myController', function ($scope, $modal) {
$scope.showModal = function () {
var modalInstance;
modalInstance = $modal.open({
templateUrl: "addNew.html",
controller: 'myController2',
size: 'lg'
});
};
$scope.showModal();
})
.controller('myController2', function ($scope, $modal) {
$scope.datepickers = {
start: false
}
$scope.openDatepicker = function ($event, which) {
$event.preventDefault();
$event.stopPropagation();
$scope.datepickers[which] = true;
};
$scope.dateOptions = {
formatYear: 'yy',
startingDay: 1
};
$scope.dateFormat = 'mediumDate';
});
<div ng-app="myApp">
<div ng-controller="myController">
<script type="text/ng-template" id="addNew.html">
<div class="modal-body">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Add</h3>
</div>
<div class="panel-body">
<md-tabs md-dynamic-height md-border-bottom>
<md-tab label="date">
<div class="form-horizontal">
<div class="row">
<div class="col-md-6">
<div class="row form-group">
<label for="dateStart" class="col-sm-2 col-md-4 control-label">
Date Start
</label>
<div class="col-sm-10 col-md-8">
<div class="input-group ui-datepicker">
<input type="text"
class="form-control"
name="dateStart"
id="dateStart"
datepicker-popup="{{dateFormat}}"
ng-model="campaign.dateStart"
is-open="datepickers.start"
datepicker-options="dateOptions"
ng-required="true"
ng-click="openDatepicker($event, 'start')"
close-text="Close"/>
<span class="input-group-addon" ng-click="openDatepicker($event, 'start')">
<i class="glyphicon glyphicon-calendar"></i>
</span>
</div>
</div>
</div>
</div>
</div>
</div>
</md-tab>
<md-tab label="other tabs"></md-tab>
<md-tab label="other tabs"></md-tab>
<md-tab label="other tabs"></md-tab>
<md-tab label="other tabs"></md-tab>
</md-tabs>
</div>
</div>
</div>
</script>
</div>
</div>
I used a css trick to add the scroll bar in this fiddle, but it's not very neat. So I was wondering if there is a way to expand the tab height when the datepicker is opened or the datepicker is shown over a modal window like the select window opens.
You'll want to have the dropdown datepicker appear as part of the regular document flow, that way it will occupy space and the tab picker will automatically make room for it. It doesn't do that currently because it uses .dropdown-menu, to which Bootstrap adds position: absolute;
Just override like this:
.dropdown-menu[datepicker-popup-wrap] {
position: static;
}
There are some other stylistic things you can do, but that is the basic principle.
Demo in jsFiddle

Resources