Data doesn't show in AngularJS - javascript

First of all I want to apologize for my bad English :)
I am having a problem with AngularJS, when I want to load a modal from datagrid.
Here is my code for the grid:
<tr ng-repeat="data in filtered = (list | filter:search | orderBy : predicate :reverse) | startFrom:(currentPage-1)*entryLimit | limitTo:entryLimit track by $index">
<td>{{data.lastName}} {{data.firstName}}</td>
<td>{{data.email}}</td>
<td>{{data.phoneNumber}}</td>
<td>{{data.cityID}}</td>
<td><button class="btn btn-primary btn-xs" ng-click="show(data.id)">DETAILS</button></td>
Modal code :
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title"><strong>{{row.firstName}} {{row.lastName}}</strong> Details</h4>
</div>
<div class="modal-body">
<table class="table table-condensed table-hover info-table">
<tbody>
<tr>
<td>Email:</td>
<td>{{row.email}}</td>
</tr>
</tbody>
</table>
</div>
</div>
and JS code:
$scope.show = function (id) {
$http.get('inc/getDetails.php?id='+id).
success(function(data) {
$scope.row = data;
$('#det-modal').modal('show');
});
};
The modal is loading, but does not load the data.

The code would not work because the row variable is out of scope when the modal is invoked as its in non-angular world.
You should not access the DOM element directly in controller so the following line should not be used in angular world.
$('#det-modal').modal('show');
To fix the issue consider using https://angular-ui.github.io/bootstrap/ which would enable you to pass in the row as a scope variable.

Related

Angular Show Password after click

I have an inventory page that also contains a password field.
I would like to hide the password when the page is loaded, best would be to have points displayed **** and after click password is shown or a pop up.
JS
var get_cert = function () {
$http.get($scope.url.cert_list).then(
function (response) {
$scope.certs = response.data;
}
);
}
// execute get function
get_cert();
HTML
<div class="panel panel-default">
<table class="table table-striped valign_middle">
<tr class="table_header">
<td>Name</td>
<td>Pass</td>
</tr>
<tr ng-repeat="cert in certs | filter:search | orderBy:['name']">
<td>{{cert.name}}</td>
<td>
<button class="w3-btn w3-black w3-hover-green w3-ripple" ng-click="get_cert()">Show</button>
<span ng-show="get_cert()">{{cert.password}}</span>
</td>
</tr>
</table>
<button ng-show="!cert.showPw" class="w3-btn w3-black w3-hover-green w3-ripple" ng-click="cert.showPw = true">Show</button>
<span ng-show="cert.showPw">{{cert.password}}</span>
You can use ng-click to do cert.showPw = true, which will append a property called showPw (a boolean) to the object. Combined with ng-show, you can easily switch between the two.
This way you'll keep your controller free of any additional logic needed. You may include ng-click on the span which holds the password which will set showPw = false to switch it back to a button.
See my JSFiddle for full example.
Create a input
<input type="password" name="???">
Then you can change its type to "text" with
$("#idOfInout")type = 'text';

Selector th Jquery [duplicate]

This question already has answers here:
jQuery - How to select by attribute
(3 answers)
Closed 5 years ago.
I'm trying to understand how to use the Jquery selector
https://learn.jquery.com/using-jquery-core/selecting-elements/
I have a table and I want to create an input within the modal, my difficulty actually is how to use the selector correctly to access the content of <th scope="row">
<table>
<thead>
<tr>
<th>ID</th>
<th>Edit</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">123</th>
<th><span class="oi" data-glyph="pencil"></span></th>
</tr>
</tbody>
</table>
When I click on edit the modal opens
Modal
<div class="modal fade" id="formModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Modal Form</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form method="POST" style="padding:100px">
<div id="dvInputsUpdate"></div>
<button name='btn-update' type="submit" class="btn btn-primary">Atualizar</button>
</form>
</div>
</div>
</div>
</div>
I tried $('table.row')
Jquery
$(document).on('click', '#formModal', function() {
var inpId = 0;
$('#dvInputsUpdate').html('');
$('table.row', function() {
var chkValue = $(this).closest('th').next('td').text();
$('#dvInputsUpdate').append($('<div class="form-group"><label >ID</label><input type="text" id="' + ("input" + inpId) + '" value="' + chkValue + '" /></div>'));
inpId++;
});
return false;
});
---UPDATE---
Thank you all so much for the answers, but you have not solved it yet. I've learned that Scope is not yet supported by html5.
I inserted a class="update" in th: $('th[class="update"]')
But this is not working yet
table.row will look specifically at the table element and then of those elements, look for a class name of .row. I believe for your case, you want to look for nested .row classes in the table element so you should change it to $('table th'). I'm not sure what attribute scope is but if you want to use .row, you can define a <th class="row"> instead and then use $('table.row')
If you really want to use the attribute scope, you can also specify that in jQuery by doing ${'th[scope="row"]')
You might want to have a look at the jQuery selectors.
Elements with attributes having a specific value can be selected via [attributName="desiredValue"].
In your case: $('th[scope="row"]')
To access <th scope="row">:
var thScopeRow = $('th[scope="row"]');
scope is an attribute of <th>, not class, so the correct syntax would be $('th[scope="row"]'). In the snippet i selected this specific th using this method and changed the color of text just for example:
$('th[scope="row"]').css("color", "red");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th>ID</th>
<th>Edit</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">123</th>
<th><span class="oi" data-glyph="pencil"></span></th>
</tr>
</tbody>
</table>
UPDATE
"I inserted a class="update" in th: $('th[class="update"]')"
If you are using <th class="row">123</th> and it's only one element on the page with such class, you can get it via $('.row')[0]. ([0] is needed because $('.row') will find ALL elements on the page with such class. So think about it as an array). If you have for example 2 elements on the page with such class and want to get the second, so use $('.row')[1] and so on.

boostrap modal not updating with vue js v2 two way binding

I'm new to vue js and trying to use it with a bootstrap modal to view more data. My scenario is a table with multiple records and a button to see in depth details for the clicked record in a bootstrap modal. After clicking the first button it caches and doesn't update it while selecting another button for different details.
Does anyone see what I'm doing wrong?
(It's a combination of Laravel, jQuery and VueJS)
HTML Table:
<table class="table table-striped">
<thead>
<tr>
<th>E-mail address</th>
<th>Status</th>
<th>Sent at</th>
<th>Expires in</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td class="v-align-middle">
john#doe.example
</td>
<td class="v-align-middle">
<span class="label label-default">
pending
</span>
</td>
<td class="v-align-middle">
2017-06-05 17:59:15
</td>
<td class="v-align-middle">
29 days
</td>
<td>
<div class="btn-group pull-right">
<a href="#" class="btn btn-default" data-toggle="modal" data-target="#inviteDetailsModal" data-email="john#doe.example">
<i class="fa fa-eye"></i>
</a>
</div>
</td>
</tr>
<tr>
<td class="v-align-middle">
jane#doe.example
</td>
<td class="v-align-middle">
<span class="label label-default">
pending
</span>
</td>
<td class="v-align-middle">
2017-06-05 13:27:25
</td>
<td class="v-align-middle">
29 days
</td>
<td>
<div class="btn-group pull-right">
<a href="#" class="btn btn-default" data-toggle="modal" data-target="#inviteDetailsModal" data-email="jane#doe.example">
<i class="fa fa-eye"></i>
</a>
</div>
</td>
</tr>
</tbody>
JavaScript:
$('[data-target="#inviteDetailsModal"]').on('click', function () {
let email = $(this).data('email'),
baseUrl = $('html').data('base');
Vue.component('invite-details', {
data: function () {
return {
email: null,
token: null,
logs: [],
expires: null
}
},
methods: {
update: function (data) {
this.email = data['email'];
this.token = data['token'];
this.logs = data['logs'];
this.expires = data['expires'];
},
fetchData: function () {
this.$http.get(baseUrl + '/system/invites/' + email + '/details')
.then(response => {
this.update(response.body);
}, response => {
console.log('whoops something went wrong');
});
}
},
mounted: function () {
this.$el.addEventListener('shown.bs.modal', this.fetchData());
},
beforeDestroy: function () {
this.$el.removeEventListener('shown.bs.modal', this.fetchData());
}
});
new Vue({
el: '#inviteDetailsModal'
});
});
The bootstrap modal:
<div class="modal fade slide-up" id="inviteDetailsModal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content-wrapper">
<invite-details inline-template>
<div class="modal-content" id="details">
<div class="modal-header clearfix text-left">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">
<i class="pg-close fs-14"></i>
</button>
<h5>
Invite details for <span class="semi-bold">#{{ email }}</span>
</h5>
<p class="p-b-10">
<span data-tooltip="true" data-placement="bottom" title="token">
<em>#{{ token }}</em>
</span>
</p>
</div>
<div class="modal-body">
<table class="table table-striped">
<thead>
<tr>
<th>#</th>
<th>Sent at</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr v-for="log in logs">
<td>#{{ log.number }}</td>
<td>#{{ log.sentAt }}</td>
<td>#{{ log.status }}</td>
</tr>
</tbody>
</table>
</div>
<div class="modal-footer text-center">
<span class="hint-text">
<em>expires in <strong>#{{ expires }}</strong> days</em>
</span>
</div>
</div>
</invite-details>
</div>
</div>
Alright I dug in deep to get this working and went the extra mile because you mentioned your were new at VueJS. I recognised my old self in your code where you go into VueJS with a JQuery mindset ;-)
First few quick notes before dropping the full code:
Use the table DB row's integer ID to reference the user everywhere.
This way when the email is updated, you still know who it is in the
frontend. By examining the code I saw that the email can change
(because it's an updateable data property, but it's also used in
your GET request: baseUrl + '/system/invites/' + email +
'/details'
Subsequently, you can use this ID to easily generate unique instances
of your modal :-) This is the way you want to be working with VueJS!
Since you're using the same data in multiple places, have a look at
Vuex for a store. It may look daunting at first but it's great once
you get to grips with it. In your case, the same dataset would be
used for the original table and the modals. If one updates,
everything updates!
With Vuex you can trigger updates from anywhere. Right now the data
gets updated every time the eye button is clicked. However, this is
pretty hacky as I've made the button part of the modal's template,
and every time it gets clicked it calls fetchData() (check the
console). What you want to do ideally is use Vuex and generate
everything from the single point of truth dataset. Currently, if the
modal's data is updated, the original table is not.
With VueJS it's just as easy to create your own modal. The upside of
this is less overhead in your code, as you can use v-if, so it
won't be loaded into the DOM unless actually required. And judging
from your current code, the details button would be clicked
occasionally.
Install VueJS debugger if you haven't already:
https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd,
it will help you 'see' under the hood.
Alright so now for the code! First, add this line to your app.js file:
import JaimyTable from './components/stackoverflow/JaimyTable.vue'
Right above the var app = new Vue({ line. And add it to your components, so you end up with something like this:
import JaimyTable from './components/stackoverflow/JaimyTable.vue'
var app = new Vue({
components: {
JaimyTable,
},
});
Here's the JaimyTable.vue file:
<template>
<div class="container">
<table class="table table-striped">
<thead>
<tr>
<th>E-mail address</th>
<th>Status</th>
<th>Sent at</th>
<th>Expires in</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td class="v-align-middle">
john#doe.example
</td>
<td class="v-align-middle">
<span class="label label-default">
pending
</span>
</td>
<td class="v-align-middle">
2017-06-05 17:59:15
</td>
<td class="v-align-middle">
29 days
</td>
<td>
<div class="btn-group pull-right">
<jaimy-modal id="1"></jaimy-modal>
</div>
</td>
</tr>
<tr>
<td class="v-align-middle">
jane#doe.example
</td>
<td class="v-align-middle">
<span class="label label-default">
pending
</span>
</td>
<td class="v-align-middle">
2017-06-05 13:27:25
</td>
<td class="v-align-middle">
29 days
</td>
<td>
<div class="btn-group pull-right">
<jaimy-modal id="2"></jaimy-modal>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
import JaimyModal from './JaimyModal.vue'
export default {
components: { JaimyModal },
props: [],
mixins: [],
data: function () {
return {
//
}
},
computed: {
computed_variable() {
return '';
}
},
created() {
//
},
mounted() {
//
},
methods: {
//
},
watch: {
//
}
}
</script>
And please note the <jaimy-modal id="1"></jaimy-modal> lines. You probably want to use v-for to generate the all the <tr> rows automatically :) Make sure the id= corresponds to the ID in your database.
Now for the JaimyModal.vue where all the magic happens:
<template>
<div>
<a href="#" class="btn btn-default" data-toggle="modal" :data-target="'#inviteDetailsModal' + id" #click="fetchData()">
<i class="fa fa-eye"></i>
</a>
<div class="modal fade slide-up" :id="'inviteDetailsModal' + id" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content-wrapper">
<div class="modal-content" id="details">
<div class="modal-header clearfix text-left">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">
<i class="pg-close fs-14"></i>
</button>
<h5>
Invite details for <span class="semi-bold">{{ email }}</span>
</h5>
<p class="p-b-10">
<span data-tooltip="true" data-placement="bottom" title="token">
<em>{{ token }}</em>
</span>
</p>
</div>
<div class="modal-body">
<table class="table table-striped">
<thead>
<tr>
<th>#</th>
<th>Sent at</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr v-for="log in logs">
<td>{{ log.number }}</td>
<td>{{ log.sentAt }}</td>
<td>{{ log.status }}</td>
</tr>
</tbody>
</table>
</div>
<div class="modal-footer text-center">
<span class="hint-text">
<em>expires in <strong>{{ expires }}</strong> days</em>
</span>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: ['id'],
data: function () {
return {
email: null,
token: null,
logs: [],
expires: null,
baseUrl: 'https://yourbaseurl.com',
}
},
mounted: function () {
//
},
methods: {
update: function (data) {
this.email = data['email'];
this.token = data['token'];
this.logs = data['logs'];
this.expires = data['expires'];
},
fetchData: function () {
console.log('data fetched');
// Commented out for local purposes
// this.$http.get(this.baseUrl + '/system/invites/' + this.email + '/details')
// .then(response => {
// this.update(response.body);
// }, response => {
// console.log('whoops something went wrong');
// });
// Dummy data
this.update({
email: 'test#test ' + this.id + '.com',
token: 'token123123asdsasdasdasd',
logs: [
{
number: 1,
sentAt: '2017-01-01',
status: 'Ok',
},
{
number: 2,
sentAt: '2017-02-01',
status: 'Failed',
},
],
expires: '2017-10-01'
});
}
},
}
</script>
Important to note here is the :data-target="'#inviteDetailsModal' + id" part in the button, where the number corresponds to the id of the prop. By using the : you're making it an expression, and it resolves to a unique reference.
As you can see the setup is completely different than you had before. Where the modal is a nested component of your table row. Once you start thinking of Components as recurring parts of look and functionality, but with unique data within it, things will click fast. Think of it as Model in Laravel.
After a long time of being told that you need to separate design (CSS), mark-up (HTML) and functionality (JS), it's weird to have it all sitting there in 1 file. But embrace it, and you'll fall in love with VueJS :D
And give Vuex a look! The second you get multiple components that use and manipulate the same dataset, it's a god-send!
Ow and finally: the second you start thinking of using things like fn.trigger and whatnot, you're approaching VueJS wrong. Keep that in mind :) It has all the tools necessary for you to work with the page, and then some!
Happy coding!
Since you're using one modal component and are attempting to change its content based on the specific button in the table clicked, the mounted hook is only going to fire once when the component is initially mounted.
What you want is for the content to update each time the modal is shown.
First of, it looks like your component only needs one email prop. Move the rest of the props to be in the data method for the component, since (I'm assuming) they aren't being passed into the component:
props: ['email'],
data: function() {
return {
token: null,
logs: null,
expires: null,
}
}
Then, I would create a new method called fetchData to put the $http.get call in:
fetchData: function() {
this.$http.get('http://localhost:2000/system/invites/' + this.email + '/details')
.then(response => {
this.update(response.body);
}, response => {
console.log('whoops something went wrong');
});
}
In your modal component's mounted hook, add a listener to the bootstrap modal's show event using jQuery. And be sure to remove the listener in the component's beforeDestroy hook:
mounted() {
$(this.$el).on('shown.bs.modal', this.fetchData);
},
beforeDestroy() {
$(this.$el).off('shown.bs.modal', this.fetchData);
}
Now, every time the modal's show event fires, the $http.get request will fire based on the current value of the component's email property.
Here's an example fiddle.

angularJS print directive losing 2 way binding

I have a print directive in a SPA that seems to lose its 2 way data binding after the first print function is ran. I am sure it has something to do with the cloning and appending of the element.
The Directive is as follows:
agency.directive("pasPrint", ['AgentModel','Dev',
function(agentModel, dev) {
var printSection = document.getElementById("printSection");
function printElement(elem) {
// clones the element you want to print
var domClone = elem.cloneNode(true);
if (!printSection) {
printSection = document.createElement("div");
printSection.id = "printSection";
document.body.appendChild(printSection);
} else {
printSection.innerHTML = "";
}
printSection.appendChild(domClone);
}
return {
restrict: 'A',
link: function($scope, $element, attrs) {
$scope.printModel = {};
$scope.today = new Date().toJSON().slice(0,10);
$element.on("click", function () {
var elemToPrint = document.getElementById(attrs.printElementId);
if (elemToPrint) {
printElement(elemToPrint);
window.print();
}
});
},
controller: ["$scope","$element", "AgentModel", function($scope, $element, agentModel) {
$scope.agentModel = agentModel;
}]
};
}]);
the model that is used in the entire module here is the agentModel.singleAgent which of course represents a single agent. this directive simply prints a cover sheet for an agents hard copy record. the first time we pull up an agents record the cover sheet prints correctly. when we load another agent the print preview show's the correctly updated agent information. in the agentModel.singleAgent 2 way binding (the same values being used in the printSection that gets printed. However the second print attempt also prints the first agent information and so does any other attempt to print any other agents, they all print the first agents data, even thought the singleAgent model has been updated properly.
the html from the print preview is below:
<div class="modal-header ng-scope">
<button type="button" class="close" aria-label="Close" data-ng- click="cancel()"><span aria-hidden="true"> × </span></button>
<h3 class="modal-title ng-binding"> Edit & Print Cover Sheet </h3>
</div>
<div class="modal-body">
<form class="inline-form">
<div class="form-group">
<label class="form-label" for="PRINT_DESC">File Description: </label>
<input class="input-medium" type="text" id="PRINT_DESC" name="PRINT_DESC" data-ng-model="printModel.PRINT_DESC" />
</div>
</form>
<div id="printPreview">
<table class="table table-cell-nowrap table-responsive">
<thead>
<tr>
<th colspan="2"><strong>Type: <em>{{printModel.PRINT_DESC}}</em></strong></th>
<th colspan="2" style="border: 1px #dadada dotted"><div class="clearfix pull-right"><strong>{{agentModel.singleAgent.AGENT_NUMBER}}</strong></div></th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Agent Name: {{ agentModel.singleAgent.AGENT_LNAME }}, {{ agentModel.singleAgent.AGENT_FNAME }} </strong></td>
<td><strong>Agent #: {{ agentModel.singleAgent.AGENT_NUMBER }}</strong></td>
<td><strong>UID: {{ agentModel.singleAgent.AGENT_UID }}</strong></td>
<td></td>
</tr>
<tr><td colspan="4">Printed On: {{ today }} </td></tr>
</tbody>
</table>
</div>
<div id="printSection" class="col-md-12"><!-- place nothing in here except what should be printed. by default the content in the print section IS hidden -->
<table class="table table-cell-nowrap table-responsive printCoverFontSize">
<thead>
<tr>
<th colspan="2"><strong>Type: <em>{{printModel.PRINT_DESC}}</em></strong></th>
<th colspan="2" style="border: 1px #dadada dotted"><div class="clearfix pull-right"><strong>{{agentModel.singleAgent.AGENT_NUMBER}}</strong></div></th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Agent Name: {{ agentModel.singleAgent.AGENT_LNAME }}, {{ agentModel.singleAgent.AGENT_FNAME }} </strong></td>
<td><strong>Agent #: {{ agentModel.singleAgent.AGENT_NUMBER }}</strong></td>
<td><strong>UID: {{ agentModel.singleAgent.AGENT_UID }}</strong></td>
<td></td>
</tr>
<tr><td colspan="4">Printed On: {{ today }} </td></tr>
</tbody>
</table>
</div>
</div>
<div class="modal-footer">
<div class="pull-left">
<button class="btn btn-warning" data-pas-print data-print-element-id="printSection"><i class="fa fa-print fa-lg"></i> Print </button>
</div>
<div class="pull-right">
<button class="btn btn-default" data-ng- click="cancel()">Cancel</button>
</div>
the printModel model simply takes the value from the text box and includes it to be printed, just a descriptive term.
I am at a loss as to why this is not working. I did just piece this together from other scripts I found online to work with our application. I am a bit of an angular Newb and I really appreciate any help I can get so thank you in advance. please if you need more information feel free to ask. If I had to guess I would say it has something to do with cloning and the emptying of the element if I had to guess, but I am at a loss as to how to fix it. HELP please.

Attach click event for the weekday labels in Angular UI Bootstrap datepicker

I'm using Angular UI Bootstrap datepicker with the gm.datepickerMultiSelect extension and I'd like to make weekdays labels clickable, so that I could select all days in the month (like all Wednesdays). I can get/calculate all days of the same weekday and add them to the selected days scope, but as I'm rather new to AngularJS & Bootstrap UI, I can't find the right way to trigger that click event for the labels.
Angular UI Bootstrap lets you override their directive's templates. You can create your own template by putting it inside a <script> tag with type text/ng-template.
So we copy the contents of Angular UI's template/datepicker/day.html and we alter it a little bit to call a new function selectWeekday on our weekday's ng-click :
<script type="text/ng-template" id="template/datepicker/day.html">
<table role="grid" aria-labelledby="{{::uniqueId}}-title" aria-activedescendant="{{activeDateId}}">
<thead>
<tr>
<th>
<button type="button" class="btn btn-default btn-sm pull-left" ng-click="move(-1)" tabindex="-1"><i class="glyphicon glyphicon-chevron-left"></i></button>
</th>
<th colspan="{{::5 + showWeeks}}">
<button id="{{::uniqueId}}-title" role="heading" aria-live="assertive" aria-atomic="true" type="button" class="btn btn-default btn-sm" ng-click="toggleMode()" ng-disabled="datepickerMode === maxMode" tabindex="-1" style="width:100%;"><strong>{{title}}</strong></button>
</th>
<th>
<button type="button" class="btn btn-default btn-sm pull-right" ng-click="move(1)" tabindex="-1"><i class="glyphicon glyphicon-chevron-right"></i></button>
</th>
</tr>
<tr>
<th ng-if="showWeeks" class="text-center"></th>
<!-- Added ng-click and style -->
<th ng-click="selectWeekday(label)" style="cursor:pointer;" ng-repeat="label in ::labels track by $index" class="text-center"><small aria-label="{{::label.full}}">{{::label.abbr}}</small></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in rows track by $index">
<td ng-if="showWeeks" class="text-center h6"><em>{{ weekNumbers[$index] }}</em></td>
<td ng-repeat="dt in row track by dt.date" class="text-center" role="gridcell" id="{{::dt.uid}}" ng-class="::dt.customClass">
<button type="button" style="min-width:100%;" class="btn btn-default btn-sm" ng-class="{'btn-info': dt.selected, active: isActive(dt)}" ng-click="select(dt.date)" ng-disabled="dt.disabled" tabindex="-1"><span ng-class="::{'text-muted': dt.secondary, 'text-info': dt.current}">{{::dt.label}}</span></button>
</td>
</tr>
</tbody>
</table>
</script>
Note: This script tag must be within your ng-app or else it will be ignored and won't overwrite the original template.
Now we need to modify the datepicker directive with AngularJS decorators to add the selectWeekday function:
angular.module('myApp', [
'ui.bootstrap',
'gm.datepickerMultiSelect'
])
.config(function($provide) {
$provide.decorator('datepickerDirective', function($delegate) {
var directive = $delegate[0];
//get a copy of the directive's original compile function
var directiveCompile = directive.compile;
//overwrite the original compile function
directive.compile = function(tElement, tAttrs) {
// call the directive's compile with apply to send the original 'this' and arguments to it
var link = directiveCompile.apply(this, arguments);
//here's where the magic starts
return function(scope, element, attrs, ctrls) {
//call the original link
link.apply(this, arguments);
scope.selectWeekday = function(label) {
scope.$emit('datepicker.selectWeekday', label);
};
};
};
return $delegate;
});
})
And from the controller listen to datepicker.selectWeekday:
.controller('DateController', function($scope) {
$scope.$on('datepicker.selectWeekday', function(event, newVal) {
$scope.selectedWeekday = newVal;
});
});
From here you can add the logic to select the days based on the known selected weekday!
Here's a working plunkr: http://plnkr.co/edit/Ef4gd7SUYMcG05PuvqFh?p=preview

Categories