I have a problem with angularJs.
After open the pop-up and dynamically add a button on the pop-up, I don't know how to trigger an button event.
I tried almost 'everything'.
Here is an example: https://plnkr.co/edit/QfnDttJE2OnfHzt65tBQ?p=preview
ok given your code, it could be improved a bit but this should be solid solution:
https://plnkr.co/edit/UiOsyHBjVZTW33yr6h3z?p=preview
Javascript:
app.controller('ModalInstanceCtrl', function ($uibModalInstance,$compile) {
var $ctrl = this;
$ctrl.buttonArray = [];
$ctrl.cancel2 = function () {
$uibModalInstance.dismiss('cancel');
};
$ctrl.add2 = function(){
$ctrl.buttonArray.push('message' + $ctrl.buttonArray.length)
};
$ctrl.message = function () {
alert('Message');
};
});
HTML:
<div ng-app="app" ng-controller="postoviCtrl as $ctrl">
<script type="text/ng-template" id="modalOdabraniPost.html">
<div class="modal-body">
<p>Header</p>
<hr/>
<button class="btn btn-sm" type="button" ng-click="$ctrl.add2()">Add</button>
<div id="content">
<button ng-repeat="btn in $ctrl.buttonArray" class="btn btn-primary btn-sm" type="button" ng-click="$ctrl.message()">{{btn}}</button>'
</div>
</div>
<div class="modal-footer">
<button class="btn btn btn-primary" type="button" ng-click="$ctrl.cancel2()">Close</button>
</div>
</script>
Open
</div>
I've a bootstrap modal which contains a table of users.
I can select a user from the table and on clicking 'save', the details of seleced user is displayed.
I'm displaying 10 users per page in the table of the modal.
However, if I select any user from page 1 and then click next to select some users from page 2 and click on 'save', my selection from page 1 is not retained.
I mean the checkbox is cleared on page 1, whenever I click on next or previous.
How do I retain this selection on my checkbox, even if I click on next or previous at any page?
Here's the snippet:
var currentPageNo = 0; // Keep track of currently displayed page
// Select button that is descendant of userList
$('#userList .prev-btn').click(function(){
userList(currentPageNo-10);
});
$('#userList .next-btn').click(function(){
userList(currentPageNo+10);
});
$('#adminList .prev-btn').click(function(){
adminList(currentPageNo-10);
});
$('#adminList .next-btn').click(function(){
adminList(currentPageNo+10);
});
function userList(pageNo) {
var resType="userList";
createTable(resType,pageNo);
}
function adminList(pageNo) {
var resType="adminList";
createTable(resType,pageNo);
}
function createTable(resType, pageNo) {
// Update global variable
currentPageNo = pageNo;
// Set visibility of the correct "prev" button:
$('#' + resType + ' .prev-btn').toggle(pageNo > 0);
// Ask one record more than needed, to determine if there are more records after this page:
$.getJSON("https://api.randomuser.me/?results=11&resType="+resType + "&pageIndex=" + pageNo, function(data) {
var $table = $('#' + resType + ' table');
$('tr:has(td)', $table).empty();
// Check if there's an extra record which we do not display,
// but determines that there is a next page
$('#' + resType + ' .next-btn').toggle(data.results.length > 10);
// Slice results, so 11th record is not included:
data.results.slice(0, 10).forEach(function (record, i) { // add second argument for numbering records
var json = JSON.stringify(record);
$table.append(
$('<tr>').append(
$('<td>').append(
$('<input>').attr('type', 'checkbox')
.addClass('selectRow')
.val(json),
(i+1+pageNo) // display row number
),
$('<td>').append(
$('<a>').attr('href', record.picture.thumbnail)
.addClass('imgurl')
.attr('target', '_blank')
.text(record.name.first)
),
$('<td>').append(record.dob)
)
);
});
// Show the prev and/or buttons
}).fail(function(error) {
console.log("**********AJAX ERROR: " + error);
});
}
var savedData = []; // The objects as array, so to have an order.
function saveData(){
var errors = [];
// Add selected to map
$('input.selectRow:checked').each(function(count) {
// Get the JSON that is stored as value for the checkbox
var obj = JSON.parse($(this).val());
// See if this URL was already collected (that's easy with Set)
if (savedData.find(record => record.picture.thumbnail === obj.picture.thumbnail)) {
errors.push(obj.name.first);
} else {
// Append it
savedData.push(obj);
}
});
refreshDisplay();
if (errors.length) {
alert('The following were already selected:\n' + errors.join('\n'));
}
}
function refreshDisplay() {
$('.container').html('');
savedData.forEach(function (obj) {
// Reset container, and append collected data (use jQuery for appending)
$('.container').append(
$('<div>').addClass('parent').append(
$('<label>').addClass('dataLabel').text('Name: '),
obj.name.first + ' ' + obj.name.last,
$('<br>'), // line-break between name & pic
$('<img>').addClass('myLink').attr('src', obj.picture.thumbnail), $('<br>'),
$('<label>').addClass('dataLabel').text('Date of birth: '),
obj.dob, $('<br>'),
$('<label>').addClass('dataLabel').text('Address: '), $('<br>'),
obj.location.street, $('<br>'),
obj.location.city + ' ' + obj.location.postcode, $('<br>'),
obj.location.state, $('<br>'),
$('<button>').addClass('removeMe').text('Delete'),
$('<button>').addClass('top-btn').text('Swap with top'),
$('<button>').addClass('down-btn').text('Swap with down')
)
);
})
// Clear checkboxes:
$('.selectRow').prop('checked', false);
handleEvents();
}
function logSavedData(){
// Convert to JSON and log to console. You would instead post it
// to some URL, or save it to localStorage.
console.log(JSON.stringify(savedData, null, 2));
}
function getIndex(elem) {
return $(elem).parent('.parent').index();
}
$(document).on('click', '.removeMe', function() {
// Delete this from the saved Data
savedData.splice(getIndex(this), 1);
// And redisplay
refreshDisplay();
});
/* Swapping the displayed articles in the result list */
$(document).on('click', ".down-btn", function() {
var index = getIndex(this);
// Swap in memory
savedData.splice(index, 2, savedData[index+1], savedData[index]);
// And redisplay
refreshDisplay();
});
$(document).on('click', ".top-btn", function() {
var index = getIndex(this);
// Swap in memory
savedData.splice(index-1, 2, savedData[index], savedData[index-1]);
// And redisplay
refreshDisplay();
});
/* Disable top & down buttons for the first and the last article respectively in the result list */
function handleEvents() {
$(".top-btn, .down-btn").prop("disabled", false).show();
$(".parent:first").find(".top-btn").prop("disabled", true).hide();
$(".parent:last").find(".down-btn").prop("disabled", true).hide();
}
$(document).ready(function(){
$('#showExtForm-btn').click(function(){
$('#extUser').toggle();
});
$("#extUserForm").submit(function(e){
addExtUser();
return false;
});
});
function addExtUser() {
var extObj = {
name: {
title: "mr", // No ladies? :-)
first: $("#name").val(),
// Last name ?
},
dob: $("#dob").val(),
picture: {
thumbnail: $("#myImg").val()
},
location: { // maybe also ask for this info?
}
};
savedData.push(extObj);
refreshDisplay(); // Will show some undefined stuff (location...)
}
.parent {
background-color: #0000FF;
color: white;
border: 1px solid black;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<button class="btn btn-primary btn-sm" data-toggle="modal" data-target="#userList" onclick="userList(0)">User List</button>
<button class="btn btn-primary btn-sm" onclick="logSavedData()">Get Saved Data</button>
<button class="btn btn-primary btn-sm" data-toggle="modal" data-target="#adminList" onclick="adminList(0)">User Admin</button>
<button class="btn btn-primary btn-sm" data-toggle="modal" data-target="#extUser">Open External Form</button>
<div class="modal fade" id="userList" role="dialog">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">User List</h4>
</div>
<div class="modal-body">
<div class="table-responsive">
<table class="table table-bordered table-hover" id="datatable">
<tr>
<th>Select</th>
<th>Name</th>
<th>DOB</th>
</tr>
</table>
</div>
<div class="row">
<div class="col-sm-offset-3 col-sm-4">
<button type="button" class="btn btn-primary prev-btn"><span class="glyphicon glyphicon-chevron-left"></span></button>
</div>
<div class="col-sm-4">
<button type="button" class="btn btn-primary next-btn"><span class="glyphicon glyphicon-chevron-right"></span></button>
</div>
</div>
<hr/>
<div class="row">
<div class="col-sm-offset-3 col-sm-4">
<button type="button" class="btn btn-primary btn-sm" onclick="saveData()">Save selected</button>
</div>
<div class="col-sm-4">
<button type="button" class="btn btn-primary btn-sm close-less-modal" data-dismiss="modal">Close</button>
</div>
</div>
<br />
</div>
</div>
</div>
</div>
<div class="modal fade" id="adminList" role="dialog">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Admin List</h4>
</div>
<div class="modal-body">
<div class="table-responsive">
<table class="table table-bordered table-hover" id="datatable">
<tr>
<th>Select</th>
<th>Name</th>
<th>DOB</th>
</tr>
</table>
</div>
<div class="row">
<div class="col-sm-offset-3 col-sm-4">
<button type="button" class="btn btn-primary prev-btn"><span class="glyphicon glyphicon-chevron-left"></span></button>
</div>
<div class="col-sm-4">
<button type="button" class="btn btn-primary next-btn"><span class="glyphicon glyphicon-chevron-right"></span></button>
</div>
</div>
<hr/>
<div class="row">
<div class="col-sm-offset-3 col-sm-4">
<button type="button" class="btn btn-primary btn-sm" onclick="saveData()">Save selected</button>
</div>
<div class="col-sm-4">
<button type="button" class="btn btn-primary btn-sm close-less-modal" data-dismiss="modal">Close</button>
</div>
</div>
<br />
</div>
</div>
</div>
</div>
<div class="modal fade" id="extUser" role="dialog">
<div class="modal-dialog modal-lg">
<!-- External User-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Add External User</h4>
</div>
<div class="modal-body">
<form class="form-horizontal" id="extUserForm">
<div class="form-group">
<label class="control-label col-sm-3" for="name">Name:</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="name" name="name" required>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-3" for="myImg">Image:</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="myImg" name="myImg" required>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-3" for="dob">DOB:</label>
<div class="col-sm-8">
<input type="date" class="form-control" id="dob" name="dob" required>
</div>
</div>
<hr />
<div class="form-group">
<div class="col-sm-offset-3 col-sm-3">
<button class="btn btn-primary btn-sm">Submit</button>
</div>
<div class="col-sm-3">
<button type="reset" class="btn btn-primary btn-sm">Reset</button>
</div>
<div class="col-sm-3">
<button type="button" class="btn btn-primary btn-sm close-external-modal" data-dismiss="modal">Close</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
<div class="container"></div>
If you want the checkboxes to persist even when you move to another page, I would suggest that you actually keep those rows with checkboxes, but just hide them when moving to the next page.
The idea is that you never remove rows, but only add them when moving to a page you had not yet visited. But when going back to previous pages, you just make those 10 rows visible, and hide all others. That way you will even have a better user-experience, since those pages do not have to be requested from the server any more.
To achieve this, you just have to make a few changes in the first few lines of the creatTable function:
function createTable(resType, pageNo) {
// Update global variable
currentPageNo = pageNo;
// Set visibility of the correct "prev" button:
$('#' + resType + ' .prev-btn').toggle(pageNo > 0);
// *** See if we have that page already loaded
var $table = $('#' + resType + ' table');
// *** Count the rows already in the table, to see if we already have the page
var lastPageNo = $('tr:has(td)', $table).length - 1;
if (currentPageNo < lastPageNo) {
// *** We have the page: hide all rows, except those of that page
$('tr:has(td)', $table).hide().slice(currentPageNo, currentPageNo+10).show();
return;
}
// Otherwise make the request.
// Ask one record more than needed, to determine if there are more records after this page:
$.getJSON("https://api.randomuser.me/?results=11&resType="+resType + "&pageIndex=" + pageNo, function(data) {
//*** don't clear the table, but hide all rows, so they can be reused when paging back
$('tr:has(td)', $table).hide();
// Check if there's an extra record which we do not display,
// but determines that there is a next page
$('#' + resType + ' .next-btn').toggle(data.results.length > 10);
// ...etc ... etc
Here is the whole snippet:
var currentPageNo = 0; // Keep track of currently displayed page
// Select button that is descendant of userList
$('#userList .prev-btn').click(function(){
userList(currentPageNo-10);
});
$('#userList .next-btn').click(function(){
userList(currentPageNo+10);
});
$('#adminList .prev-btn').click(function(){
adminList(currentPageNo-10);
});
$('#adminList .next-btn').click(function(){
adminList(currentPageNo+10);
});
function userList(pageNo) {
var resType="userList";
createTable(resType,pageNo);
}
function adminList(pageNo) {
var resType="adminList";
createTable(resType,pageNo);
}
function createTable(resType, pageNo) {
// Update global variable
currentPageNo = pageNo;
// Set visibility of the correct "prev" button:
$('#' + resType + ' .prev-btn').toggle(pageNo > 0);
// *** See if we have that page already loaded
var $table = $('#' + resType + ' table');
// *** Count the rows already in the table, to see if we already have the page
var lastPageNo = $('tr:has(td)', $table).length - 1;
if (currentPageNo < lastPageNo) {
// *** We have the page: hide all rows, except those of that page
$('tr:has(td)', $table).hide().slice(currentPageNo, currentPageNo+10).show();
return;
}
// Otherwise make the request.
// Ask one record more than needed, to determine if there are more records after this page:
$.getJSON("https://api.randomuser.me/?results=11&resType="+resType + "&pageIndex=" + pageNo, function(data) {
//*** don't clear the table, but hide all rows, so they can be reused when paging back
$('tr:has(td)', $table).hide();
// Check if there's an extra record which we do not display,
// but determines that there is a next page
$('#' + resType + ' .next-btn').toggle(data.results.length > 10);
// Slice results, so 11th record is not included:
data.results.slice(0, 10).forEach(function (record, i) { // add second argument for numbering records
var json = JSON.stringify(record);
$table.append(
$('<tr>').append(
$('<td>').append(
$('<input>').attr('type', 'checkbox')
.addClass('selectRow')
.val(json),
(i+1+pageNo) // display row number
),
$('<td>').append(
$('<a>').attr('href', record.picture.thumbnail)
.addClass('imgurl')
.attr('target', '_blank')
.text(record.name.first)
),
$('<td>').append(record.dob)
)
);
});
}).fail(function(error) {
console.log("**********AJAX ERROR: " + error);
});
}
var savedData = []; // The objects as array, so to have an order.
function saveData(){
var errors = [];
// Add selected to map
$('input.selectRow:checked').each(function(count) {
// Get the JSON that is stored as value for the checkbox
var obj = JSON.parse($(this).val());
// See if this URL was already collected (that's easy with Set)
if (savedData.find(record => record.picture.thumbnail === obj.picture.thumbnail)) {
errors.push(obj.name.first);
} else {
// Append it
savedData.push(obj);
}
});
refreshDisplay();
if (errors.length) {
alert('The following were already selected:\n' + errors.join('\n'));
}
}
function refreshDisplay() {
$('.container').html('');
savedData.forEach(function (obj) {
// Reset container, and append collected data (use jQuery for appending)
$('.container').append(
$('<div>').addClass('parent').append(
$('<label>').addClass('dataLabel').text('Name: '),
obj.name.first + ' ' + obj.name.last,
$('<br>'), // line-break between name & pic
$('<img>').addClass('myLink').attr('src', obj.picture.thumbnail), $('<br>'),
$('<label>').addClass('dataLabel').text('Date of birth: '),
obj.dob, $('<br>'),
$('<label>').addClass('dataLabel').text('Address: '), $('<br>'),
obj.location.street, $('<br>'),
obj.location.city + ' ' + obj.location.postcode, $('<br>'),
obj.location.state, $('<br>'),
$('<button>').addClass('removeMe').text('Delete'),
$('<button>').addClass('top-btn').text('Swap with top'),
$('<button>').addClass('down-btn').text('Swap with down')
)
);
})
// Clear checkboxes:
$('.selectRow').prop('checked', false);
handleEvents();
}
function logSavedData(){
// Convert to JSON and log to console. You would instead post it
// to some URL, or save it to localStorage.
console.log(JSON.stringify(savedData, null, 2));
}
function getIndex(elem) {
return $(elem).parent('.parent').index();
}
$(document).on('click', '.removeMe', function() {
// Delete this from the saved Data
savedData.splice(getIndex(this), 1);
// And redisplay
refreshDisplay();
});
/* Swapping the displayed articles in the result list */
$(document).on('click', ".down-btn", function() {
var index = getIndex(this);
// Swap in memory
savedData.splice(index, 2, savedData[index+1], savedData[index]);
// And redisplay
refreshDisplay();
});
$(document).on('click', ".top-btn", function() {
var index = getIndex(this);
// Swap in memory
savedData.splice(index-1, 2, savedData[index], savedData[index-1]);
// And redisplay
refreshDisplay();
});
/* Disable top & down buttons for the first and the last article respectively in the result list */
function handleEvents() {
$(".top-btn, .down-btn").prop("disabled", false).show();
$(".parent:first").find(".top-btn").prop("disabled", true).hide();
$(".parent:last").find(".down-btn").prop("disabled", true).hide();
}
$(document).ready(function(){
$('#showExtForm-btn').click(function(){
$('#extUser').toggle();
});
$("#extUserForm").submit(function(e){
addExtUser();
return false;
});
});
function addExtUser() {
var extObj = {
name: {
title: "mr", // No ladies? :-)
first: $("#name").val(),
// Last name ?
},
dob: $("#dob").val(),
picture: {
thumbnail: $("#myImg").val()
},
location: { // maybe also ask for this info?
}
};
savedData.push(extObj);
refreshDisplay(); // Will show some undefined stuff (location...)
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<button class="btn btn-primary btn-sm" data-toggle="modal" data-target="#userList" onclick="userList(0)">User List</button>
<button class="btn btn-primary btn-sm" onclick="logSavedData()">Get Saved Data</button>
<button class="btn btn-primary btn-sm" data-toggle="modal" data-target="#adminList" onclick="adminList(0)">User Admin</button>
<button class="btn btn-primary btn-sm" data-toggle="modal" data-target="#extUser">Open External Form</button>
<div class="modal fade" id="userList" role="dialog">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">User List</h4>
</div>
<div class="modal-body">
<div class="table-responsive">
<table class="table table-bordered table-hover" id="datatable">
<tr>
<th>Select</th>
<th>Name</th>
<th>DOB</th>
</tr>
</table>
</div>
<div class="row">
<div class="col-sm-offset-3 col-sm-4">
<button type="button" class="btn btn-primary prev-btn"><span class="glyphicon glyphicon-chevron-left"></span></button>
</div>
<div class="col-sm-4">
<button type="button" class="btn btn-primary next-btn"><span class="glyphicon glyphicon-chevron-right"></span></button>
</div>
</div>
<hr/>
<div class="row">
<div class="col-sm-offset-3 col-sm-4">
<button type="button" class="btn btn-primary btn-sm" onclick="saveData()">Save selected</button>
</div>
<div class="col-sm-4">
<button type="button" class="btn btn-primary btn-sm close-less-modal" data-dismiss="modal">Close</button>
</div>
</div>
<br />
</div>
</div>
</div>
</div>
<div class="modal fade" id="adminList" role="dialog">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Admin List</h4>
</div>
<div class="modal-body">
<div class="table-responsive">
<table class="table table-bordered table-hover" id="datatable">
<tr>
<th>Select</th>
<th>Name</th>
<th>DOB</th>
</tr>
</table>
</div>
<div class="row">
<div class="col-sm-offset-3 col-sm-4">
<button type="button" class="btn btn-primary prev-btn"><span class="glyphicon glyphicon-chevron-left"></span></button>
</div>
<div class="col-sm-4">
<button type="button" class="btn btn-primary next-btn"><span class="glyphicon glyphicon-chevron-right"></span></button>
</div>
</div>
<hr/>
<div class="row">
<div class="col-sm-offset-3 col-sm-4">
<button type="button" class="btn btn-primary btn-sm" onclick="saveData()">Save selected</button>
</div>
<div class="col-sm-4">
<button type="button" class="btn btn-primary btn-sm close-less-modal" data-dismiss="modal">Close</button>
</div>
</div>
<br />
</div>
</div>
</div>
</div>
<div class="modal fade" id="extUser" role="dialog">
<div class="modal-dialog modal-lg">
<!-- External User-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Add External User</h4>
</div>
<div class="modal-body">
<form class="form-horizontal" id="extUserForm">
<div class="form-group">
<label class="control-label col-sm-3" for="name">Name:</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="name" name="name" required>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-3" for="myImg">Image:</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="myImg" name="myImg" required>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-3" for="dob">DOB:</label>
<div class="col-sm-8">
<input type="date" class="form-control" id="dob" name="dob" required>
</div>
</div>
<hr />
<div class="form-group">
<div class="col-sm-offset-3 col-sm-3">
<button class="btn btn-primary btn-sm">Submit</button>
</div>
<div class="col-sm-3">
<button type="reset" class="btn btn-primary btn-sm">Reset</button>
</div>
<div class="col-sm-3">
<button type="button" class="btn btn-primary btn-sm close-external-modal" data-dismiss="modal">Close</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
<div class="container"></div>
I have a editable-select nested inside other, when I submit the nested editable-select changes, it does not call the onaftersave assigned function ('vm.addOperation()'), it also shows the outter editable-select edit form.
I want it just to show the nested edit form and the function call to work.
My html code:
<div editable-select="vm.selectedUser"
e-ng-options="user.objectId as user.displayName for user in vm.users"
onshow="vm.getUsers()"
onaftersave="vm.addUser()">
<div class="container" ng-repeat="u in entity.authorizedUsers">
<div class="row">
<div class="col-xs-2">
{{u.id}}
</div>
<div class="col-xs-4">
<div editable-select="vm.selectedOperation"
e-ng-options="operation.id as operation.name for operation in vm.operations"
onshow="vm.getOperations()"
onaftersave="vm.addOperation()">
<div class="container" ng-repeat="op in u.authorizedOperations">
<div class="row">
<div class="col-xs-3">
{{op.name}}
</div>
<div class="col-xs-push-2">
<button class="btn btn-xs btn-danger"
ng-click="vm.removeOperation(entity.id, u.id, op.id)">
<i class="fa fa-trash-o"></i>
</button>
</div>
</div>
</div>
</div>
</div>
<div class="col-xs-push-4">
<button class="btn btn-xs btn-warning pull-left"
ng-click="vm.removeuser(entity.id, u.id)">
<i class="fa fa-trash-o"></i>
</button>
</div>
</div>
</div>
</div>
I've manage to fix the problem with the following code. It's an ugly workaround tho, please if someone has a more elegant solution I'd very much appreciate it.
in html:
<div editable-select="vm.selectedOperation"
e-form ="nestedForm"
onshow="vm.getOperations()"
ng-click="nestedForm.$show(); vm.xEditableNestedFormFix(nestedForm); $event.stopPropagation()"
e-ng-options="operation.id as operation.name for operation in vm.operations"
onaftersave="vm.addOperation()">
in js:
vm.xEditableNestedFormFix = function (form) {
var editorElement = form.$editables[0].controlsEl[0].firstChild;
editorElement.onclick = function (event) {
event.stopPropagation();
}
var submitButton = form.$editables[0].buttonsEl[0].firstChild
submitButton.onclick = function (event) {
form.$submit();
event.stopPropagation();
}
var cancelButton = form.$editables[0].buttonsEl[0].lastChild
cancelButton.onclick = function (event) {
event.stopPropagation();
}
}
I have been struggling with an angular-js problem, I am unable to figure out why my ng-click is not sending through any values to the jquery function that is hooked up to it. It triggers the jquery fine, but when it comes into the jquery no variables comes with it!
So some information first of all:
I am using angular-bootstrap-calendar Link to Project (This is what I am having issues with)
Using angular-bootstrap-calendar I have implemented a custom day template using instructions from github Instruction Page
The ng-click triggers my code correctly though no information is passed from the click to my customer event.
<span data-cal-date
ng-click="vm.calendarCtrl.dateClicked(day.date)"
class="pointer btn"
id="openDay"
ng-bind="day.dayLabel">
</span>
<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"
edit-event-html="'<i class=\'glyphicon glyphicon-pencil\'></i>'"
delete-event-html="'<i class=\'glyphicon glyphicon-remove\'></i>'"
on-edit-event-click="vm.eventEdited(calendarEvent)"
on-delete-event-click="vm.eventDeleted(calendarEvent)"
cell-is-open="vm.isCellOpen"
day-view-start="06:00"
day-view-end="22:00"
day-view-split="30"
cell-modifier="vm.modifyCell(calendarCell)"
on-view-change-click="vm.dateClicked(day)">
</mwl-calendar>
vm.dateClicked = function (day) {
alert("Do Something");
};
Results
day = undefined
Versions:
"angular-bootstrap-calendar": "0.19.3",
"angular": "1.5.0",
"font-awesome": "4.5.0",
"moment": "2.12.0",
"interact.js": "1.2.6",
"angular-bootstrap": "1.2.4",
"angular-touch": "1.5.0",
"angular-animate": "1.5.0",
Full Code Examples
ManRoster.cshtml
<div class="col-lg-12">
<div class="col-lg-12 panel panel-default">
<div ng-app="UserCal" class="textfix">
<script id="calendarWeekView.html" type="text/ng-template">
<div class="cal-week-box" ng-class="{'cal-day-box': vm.showTimes}">
<div class="cal-row-fluid cal-row-head">
<div class="cal-cell1"
ng-repeat="day in vm.view.days track by $index"
ng-class="{
'cal-day-weekend': day.isWeekend,
'cal-day-past': day.isPast,
'cal-day-today': day.isToday,
'cal-day-future': day.isFuture}"
mwl-element-dimensions="vm.dayColumnDimensions"
mwl-droppable
on-drop="vm.eventDropped(dropData.event, day.date)">
<div id="resourcescount">
{{ day.events.length }}
</div>
<span ng-bind="day.weekDayLabel">
</span>
<br>
<small>
<span data-cal-date
ng-click="vm.calendarCtrl.dateClicked(day.date)"
class="pointer btn"
id="openDay"
ng-bind="day.dayLabel">
</span>
</small>
</div>
</div>
<div class="cal-day-panel clearfix" ng-style="{height: vm.showTimes ? (vm.dayViewHeight + 'px') : 'auto'}">
<mwl-calendar-hour-list day-view-start="vm.dayViewStart"
day-view-end="vm.dayViewEnd"
day-view-split="vm.dayViewSplit"
day-width="vm.dayColumnDimensions.width"
view-date="vm.viewDate"
on-timespan-click="false"
ng-if="vm.showTimes">
</mwl-calendar-hour-list>
<div class="row">
<div class="col-xs-12">
<div class="cal-row-fluid"
ng-repeat="event in vm.view.events track by event.$id">
<div ng-class="'cal-cell' + (vm.showTimes ? 1 : event.daySpan) + (vm.showTimes ? '' : ' cal-offset' + event.dayOffset) + ' day-highlight dh-event-' + event.type + ' ' + event.cssClass"
ng-style="{
top: vm.showTimes ? ((event.top + 2) + 'px') : 'auto',
position: vm.showTimes ? 'absolute' : 'inherit',
width: vm.showTimes ? (vm.dayColumnDimensions.width + 'px') : '',
left: vm.showTimes ? (vm.dayColumnDimensions.width * event.dayOffset) + 15 + 'px' : ''
}"
data-event-class
mwl-draggable="event.draggable === true"
axis="vm.showTimes ? 'xy' : 'x'"
snap-grid="vm.showTimes ? {x: vm.dayColumnDimensions.width, y: 30} : {x: vm.dayColumnDimensions.width}"
on-drag="vm.tempTimeChanged(event, y)"
on-drag-end="vm.weekDragged(event, x, y)"
mwl-resizable="event.resizable === true && event.endsAt && !vm.showTimes"
resize-edges="{left: true, right: true}"
on-resize-end="vm.weekResized(event, edge, x)">
Shift
<strong ng-bind="(event.tempStartsAt || event.startsAt) | calendarDate:'time':true" ng-show="vm.showTimes"></strong>
<a href="javascript:;"
ng-click="vm.onEventClick({calendarEvent: event})"
class="event-item"
ng-bind-html="vm.$sce.trustAsHtml(event.title)"
uib-tooltip-html="event.title | calendarTrustAsHtml"
tooltip-placement="left"
tooltip-append-to-body="true">
</a>
</div>
</div>
</div>
</div>
<div id="ResourceInfo">
This will be the select panel
</div>
</div>
</div>
</script>
<!-- This is the end of the testing script -->
<div ng-controller="Cal 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"
edit-event-html="'<i class=\'glyphicon glyphicon-pencil\'></i>'"
delete-event-html="'<i class=\'glyphicon glyphicon-remove\'></i>'"
on-edit-event-click="vm.eventEdited(calendarEvent)"
on-delete-event-click="vm.eventDeleted(calendarEvent)"
cell-is-open="vm.isCellOpen"
day-view-start="06:00"
day-view-end="22:00"
day-view-split="30"
cell-modifier="vm.modifyCell(calendarCell)"
on-view-change-click="vm.dateClicked(date)">
</mwl-calendar>
<br />
</div>
</div>
</div>
</div>
ManRoster.js
angular.module('UserCal', ['mwl.calendar', 'ui.bootstrap', 'ngAnimate'])
.controller('Cal', populateCal);
function populateCal($http, calendarConfig) {
var resultset = [];
var userID = 1;
var vm = this;
calendarConfig.templates.calendarWeekView = 'calendarWeekView.html';
vm.calendarView = 'week';
vm.viewDate = new Date();
vm.events = [];
vm.isCellOpen = true;
vm.toggle = function ($event, field, event) {
$event.preventDefault();
$event.stopPropagation();
event[field] = !event[field];
};
vm.dateClicked = function (day) {
alert("Do Something");
};
}
Plunker As Requested
Let's try this one. I've created a custom directive to capture click events, it seems to be capturing the date consistently for me.
http://plnkr.co/edit/1XlQkgj5eJeuy728bEwI?p=preview
Add a directive (i just called it testDirective):
angular.module('UserCal', ['mwl.calendar', 'ui.bootstrap', 'ngAnimate'])
.controller('Cal', populateCal)
.directive('testDirective', testDirective);
emphasized text
function testDirective() {
return {
link: function(scope,elem,attrs) {
angular.element(elem).on('click', function (evt) {
alert('You clicked on: ' + scope.vm.viewDate)
});
}
};
}
Add it to the mwl-calendar element:
<mwl-calendar test-directive events="vm.events"
Initial Idea:
Alright, I think I have it now. In index.html, change
on-view-change-click="vm.dateClicked(date)"
to
on-view-change-click="vm.dateClicked(this.vm.viewDate)"
It should look like this:
<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"
edit-event-html="'<i class=\'glyphicon glyphicon-pencil\'></i>'"
delete-event-html="'<i class=\'glyphicon glyphicon-remove\'></i>'"
on-edit-event-click="vm.eventEdited(calendarEvent)"
on-delete-event-click="vm.eventDeleted(calendarEvent)"
cell-is-open="vm.isCellOpen"
day-view-start="06:00"
day-view-end="22:00"
day-view-split="30"
cell-modifier="vm.modifyCell(calendarCell)"
on-view-change-click="vm.dateClicked(this.vm.viewDate)">
</mwl-calendar>
Plunker: http://plnkr.co/edit/kKpjoCFvaR6xBjQL1bT6?p=preview
I have follow.js:
'user strict';
var SaurioApp = angular.module('SaurioApp', []);
SaurioApp.controller('SearchCtrl', function($scope, $http){
$scope.followUser = function(user_id,follow_to_id){
$http.get('ajax/follow', {
params: {user_id: user_id,follow_to_id: follow_to_id}
}).success(function(data){
$scope.unfollow = '<button class="btn btn-danger" ng- click="followUser({{Auth::user()->id}},{{$user->id}})">Seguir</button>';
});
}
});
and the view in blade
<div class="row" ng-app="SaurioApp">
<div class="col-xs-12 col-sm-12 col-md-12" >
<p ng-controller="SearchCtrl" >
#{{ unfollow }}
<button class="btn btn-primary" ng-click="followUser({{Auth::user()->id}},{{$user->id}})">Follow</button>
</p>
</div>
</div>
The insert is successful, but I can't delete the "Follow" button and append the new one: "Unfollow." How can I make this work?
<div class="row" ng-app="SaurioApp">
<div class="col-xs-12 col-sm-12 col-md-12" >
<p ng-controller="SearchCtrl" >
<button ng-show='unfollow' class="btn btn-danger" ng-click="followUser({{Auth::user()->id}},{{$user->id}})">Seguir</button>
<button ng-hide='unfollow' class="btn btn-primary" ng-click="followUser({{Auth::user()->id}},{{$user->id}})">Follow</button>
</p>
</div>
</div>
Similar to what #redoc says but with two buttons, one for unfollow and one for follow
SaurioApp.controller('SearchCtrl', function($scope, $http){
$scope.followUser = function(user_id,follow_to_id){
$http.get('ajax/follow', {
params: {user_id: user_id,follow_to_id: follow_to_id}
}).success(function(data){
$scope.unfollow = true;
});
}
});
It seems as if the only changes needed to be made are the CSS class and button text so in this case instead of trying to send HTMl code through the scope just send a variable and use ng-class to make the switch. Something like this:
'user strict';
var SaurioApp = angular.module('SaurioApp', []);
SaurioApp.controller('SearchCtrl', function($scope, $http){
$scope.followUser = function(user_id,follow_to_id){
$scope.unfollow=false;
$http.get('ajax/follow', {
params: {user_id: user_id,follow_to_id: follow_to_id}
}).success(function(data){
$scope.unfollow = true;
});
}
});
<div class="row" ng-app="SaurioApp">
<div class="col-xs-12 col-sm-12 col-md-12" >
<p ng-controller="SearchCtrl" >
#{{ unfollow }}
<button ng-class="{btn-danger: unfollow=false }" ng-click="followUser({{Auth::user()->id}},{{$user->id}})">Follow</button>
</p>
</div>
</div>
You can also change the button text dynamically with something like this:
<button value="{{(unfollow=false)? 'Follow' : 'Seguir'}}" ng-class="{btn-danger: unfollow=false }" ng-click="followUser({{Auth::user()->id}},{{$user->id}})"></button>
I guess the point being there is no need to actually recreate the HTML code just change the elements.