How can I pass a variable between angularjs views? - angularjs

I have a .slim file with AngularJS code. In this file, there's different views.
In the upload view, I have two radio buttons and I would like to keep the value of the radio selected in my edit view.
I read that I need a service, but I don't know Angular (and i'm pretty bad with javascript) so it's a bit difficult to understand and know what I have to do...
This is my whole view:
.gr-picture-upload-modal.modal.fade data-backdrop="static"
.modal-dialog
.modal-content data-ng-controller="PictureUploadCtrl" data-ng-if="view == 'upload'"
.modal-header
button type="button" class="close" data-ng-click="cancel()" ×
h4.modal-title= t('views.shared.picture_upload_modal.title')
.modal-body.picture-upload
.picture-upload-dropbox data-ng-model="files" data-ngf-drop=true data-ngf-drag-over-class="'dragover'" data-ngf-multiple="true" data-ngf-allow-dir="false" data-accept="image/jpeg,image/jpg,image/png,image/gif,image/bmp"
= t('views.shared.picture_upload_modal.drag_and_drop_or')
button type="button" class="btn-link" data-ngf-select="true" data-ng-model="files" data-ngf-multiple="true" data-accept="image/jpeg,image/jpg,image/png,image/gif,image/bmp"
= t('views.shared.picture_upload_modal.select')
= t('views.shared.picture_upload_modal.one_or_more_image')
p.picture-upload-hint= t('views.shared.picture_upload_modal.hints')
.list-group.picture-upload-list-group data-ng-show="pictures.length > 0"
.list-group-item data-ng-repeat="picture in pictures"
.row
.col-xs-8
img.picture-upload-thumbnail data-ngf-src="picture" alt="{{picture.name}}"
span.picture-upload-filename data-ng-hide="picture.upload.aborted || picture.errors" data-ng-bind="picture.name"
span.picture-upload-error.text-warning data-ng-show="picture.upload.aborted"= t('views.shared.picture_upload_modal.upload_aborted')
span.picture-upload-error.text-danger data-ng-show="picture.errors" data-ng-bind="picture.errors[0]"
.col-xs-3
.progress.picture-upload-progress data-ng-show="picture.progress >= 0"
.progress-bar data-ng-class="progressClass(picture)" style="width:{{picture.progress}}%;"
.col-xs-1
button.btn-link.picture-upload-abort type="button" title=t('views.application.buttons.cancel') data-ng-hide="picture.upload == null || picture.progress == 100 || picture.upload.aborted" data-ng-click="picture.upload.abort();picture.upload.aborted=true" ×
.modal-footer data-ng-show="pictures.length > 0"
div data-ng-if="successUpload > 0"
.row
.col-xs-4
p.pull-left= t('views.shared.picture_upload_modal.position')
.radio-inline
label
input type="radio" ng-model="position" value="first"= t('views.shared.picture_upload_modal.first_position')
.radio-inline
label
input type="radio" ng-model="position" value="last"= t('views.shared.picture_upload_modal.last_position')
.col-xs-8
button type="button" class="btn btn-primary pull-right" data-ng-disabled="uploading != 0" data-ng-click="editView()"= t('views.application.buttons.done')
div data-ng-if="successUpload == 0"
a.btn.btn-primary.pull-right href="" data-ng-class="{'disabled': (uploading != 0)}" data-ng-click="done('#{user_pictures_path(current_user.username)}')"
= t('views.application.buttons.done')
.modal-content data-ng-if="view == 'edit'"
.modal-header
.btn-toolbar.pull-right
.btn-group
button type="button" class="btn btn-default" data-ng-disabled="navIndex <= 0 || loading" data-ng-click="prevPicture()"
span.icon.icon-arrow-left
button type="button" class="btn btn-default" data-ng-disabled="navIndex >= (pictures.length - 1) || loading" data-ng-click="nextPicture()"
span.icon.icon-arrow-right
a.btn.btn-default href="" data-ng-class="{'disabled': loading}" data-ng-click="done('#{user_pictures_path(current_user.username)}')"
= t('views.application.buttons.done')
h4.modal-title #{t('views.shared.picture_upload_modal.new_image')} ({{navIndex + 1}}/{{pictures.length}})
.modal-body
form data-ng-submit="update(editPicture)"
.container-fluid
.row
.col-xs-12.col-md-4
.thumbnail.picture-upload-edit-thumbnail data-ng-style="{'background-image' : 'url(' + editPicture.image.thumbnail + ')'}"
.col-xs-12.col-md-8
.form-group data-ng-class="{'has-error': editPicture.errors['title']}"
label.control-label for="picture_title"= t('picture.labels.title')
input.form-control type="text" id="picture_title" name="picture[title]" data-ng-model="editPicture.title" autocomplete="off" maxlength="50"
span.help-block data-ng-bind="editPicture.errors['title'][0]"
.form-group data-ng-class="{'has-error': editPicture.errors['category_id']}"
label.control-label for="picture_category_id"= t('picture.labels.category')
- cache('categories._picture_upload_modal.select_tag', skip_digest: true) do
= select_tag 'category', options_for_select(Category.order(name: :asc).all.collect { |c| [c.name, c.id] }), id: 'picture_category_id', class: 'form-control', include_blank: true, data: { ng_model: 'editPicture.category_id' }
span.help-block data-ng-bind="editPicture.errors['category_id'][0]"
.form-group data-ng-class="{'has-error': editPicture.errors['description']}"
label.control-label for="picture_description"= t('picture.labels.description')
textarea.form-control id="picture_description" name="picture[description]" data-ng-model="editPicture.description" maxlength="800"
span.help-block data-ng-bind="editPicture.errors['description'][0]"
.form-group data-ng-class="{'has-error': editPicture.errors['tags_string']}"
label.control-label for="picture_tags_string" = t('picture.labels.tags_string')
input.form-control type="text" id="picture_tags_string" name="picture[tags_string]" data-ng-model="editPicture.tags_string" autocomplete="off" placeholder=t('picture.placeholders.tags_string')
span.help-block data-ng-bind="editPicture.errors['tags_string'][0]"
.form-group data-ng-class="{'has-error': editPicture.errors['license']}"
label.control-label for="picture_license"= t('picture.labels.license')
= select_tag 'license', options_for_select(t('picture.labels.licenses').collect { |k, v| [v, k] }), id: 'picture_license', class: 'form-control', include_blank: true, data: { ng_model: 'editPicture.license' }
span.help-block data-ng-bind="editPicture.errors['license'][0]"
.btn-toolbar.pull-right
button type="submit" class="btn btn-primary" name="commit" data-ladda="loading" data-style="expand-right"= t('helpers.submit.submit')
button type="button" class="btn btn-default" data-ng-class="{'disabled': loading}" data-ng-show="navIndex >= (pictures.length - 1)"
= link_to t('views.application.buttons.done'), URI::unescape(user_pictures_path(current_user.username, picturesNb: '{{pictures.length}}', position: '{{position}}'))
This is my radio buttons:
.radio-inline
label
input type="radio" ng-model="position" value="first"= t('views.shared.picture_upload_modal.first_position')
.radio-inline
label
input type="radio" ng-model="position" value="last"= t('views.shared.picture_upload_modal.last_position')
And this is where I want the value of the radio selected:
button type="button" class="btn btn-default" data-ng-class="{'disabled': loading}" data-ng-show="navIndex >= (pictures.length - 1)"
= link_to t('views.application.buttons.done'), URI::unescape(user_pictures_path(current_user.username, picturesNb: '{{pictures.length}}', position: '{{position}}'))
Also, this is my controller:
App.controller 'PictureUploadCtrl', ['$scope', '$rootScope', 'Upload', 'newPictures', ($scope, $rootScope, Upload, newPictures)->
$scope.pictures = []
$scope.uploading = 0
$scope.successUpload = 0
$scope.position = 'last'
$scope.$watch 'files', (files)->
if files and files.length
for file in files
$scope.pictures.push(file)
$scope.upload file
null
$scope.upload = (picture)->
$scope.uploading += 1
picture.upload = Upload.upload({
url: '/pictures',
data: { picture: { image: picture }}
}).progress((event)->
picture.progress = Math.min(100, parseInt(100.0 * event.loaded / event.total))
).success((data, status, headers, config)->
picture.id = data.picture.id
newPictures.add(data.picture)
$scope.uploading -= 1
$scope.successUpload += 1
).error((data, status, headers, config)->
if data is null
null
else if data.errors.base?
picture.errors = data.errors.base
else if data.errors.image?
picture.errors = data.errors.image
else if data.errors.image_fingerprint?
picture.errors = data.errors.image_fingerprint
$scope.uploading -= 1
)
$scope.cancel = ->
for picture in $scope.pictures
if picture.progress < 100 and not picture.upload.aborted
picture.upload.abort()
picture.upload.aborted = true
$scope.closeModal()
$scope.pictures = []
$scope.uploading = 0
$scope.successUpload = 0
$scope.progressClass = (picture)->
if picture.upload.aborted
'progress-bar-warning'
else if picture.progress == 100 and picture.errors?
'progress-bar-danger'
else if picture.progress == 100
'progress-bar-success'
else
''
]
Could you explain to me how can I keep the value of {{position}} between the views?
EDIT:
Well, I edited a service and added the position:
App.factory 'newPictures', ->
return {
pictures: []
position: 'last'
add: (picture)->
#pictures.push(picture)
clear: ->
#pictures = []
}
Then, in the directive, I just added the $scope.position
$scope.editView = ->
$scope.pictures = newPictures.pictures
$scope.position = newPictures.position
$scope.editPicture = $scope.pictures[0]
$scope.view = 'edit'
in my controller:
$scope.setPosition = (position) ->
$scope.position = position
newPictures.position = position
And I edited my view to add ng-change:
.row
.col-xs-4
p.pull-left= t('views.shared.picture_upload_modal.position')
.radio-inline
label
input type="radio" ng-model="position" data-ng-change="setPosition('first')" value="first"= t('views.shared.picture_upload_modal.first_position')
.radio-inline
label
input type="radio" ng-model="position" data-ng-change="setPosition('last')" value="last"= t('views.shared.picture_upload_modal.last_position')
I'm not sure if it's a clean way to do what I want but it works

Related

Bound AngularJS template not changing in angular datatable

I am using angular data table from below link
http://l-lin.github.io/angular-datatables/archives/#!/bindAngularDirective
I am using the defer rending concept here.
I have 2 button
Active (Show when user status is 1)
Inactive (Show when user status is 0)
As 2 way data binding not working here. I am unable to show Inactive button after clicking on active & viceversa
Below is my code
$scope.setCustomers = function (s, dto, dtc, f, c, h, t) {
s.dtInstance = {};
s.actions = {};
//dtOptions - Makes the ajax request to get the customer records, also builds the buttons to copy,csv,excel..etc
s.dtOptions = dto.fromSource('customers/showCustomers.json')
.withPaginationType('full_numbers')
.withDisplayLength(25)
.withOption('createdRow', createdRow)
.withDOM('<"html5buttons"B>lTfgitp').withDisplayLength(25);
// dtColumns - Builds the columns and renders the rows for each column
s.dtColumns = [
dtc.newColumn('name').withTitle('Name'),
dtc.newColumn('email').withTitle('Email'),
dtc.newColumn('phone').withTitle('Phone'),
dtc.newColumn('status').withTitle('Status')
.renderWith(function (data) {
return "<div style=text-align:center;>" + (data == 1 ? 'Accepted' : data == 2 ? 'Declined' : 'Pending') + "</div>";
}),
dtc.newColumn(null).withTitle('Actions').notSortable()
.renderWith(actionsHtml)
];
function createdRow(row, data, dataIndex) {
c(angular.element(row).contents())(s);
}
function actionsHtml(data, type, full, meta) {
s.actions[data.id] = data;
var actions = '<button ladda="loadingDemo' + data.customer_id + '" class="ladda-button ladda-button-demo btn btn-primary btn-xs" data-style="zoom-in" ng-click="resetPassword(actions[' + data.id + '])" uib-tooltip="Reset Password" tooltip-placement="top"><i class="fa fa-key"></i></button> '
+ '<i class="fa fa-money"></i></button> '
+ '<i class="fa fa-files-o"></i></button> '
+ '<i class="fa fa-eye"></i></button> '
+ '<i class="fa fa-pencil"></i></button> ';
if (data.is_active == 1) {
actions += '<button class="btn btn-success btn-xs" data-is_active="' + data.is_active + '" ng-click="setStatus(actions[' + data.id + '])" tooltip-placement="top" uib-tooltip="Inactive"><i class="fa fa-thumbs-up"></i></button> ';
} else {
actions += '<button class="btn btn-danger btn-xs" data-is_active="' + data.is_active + '" ng-click="setStatus(actions[' + data.id + '])" tooltip-placement="top" uib-tooltip="Active"><i class="fa fa-thumbs-down"></i></button> ';
}
return actions;
}
}
$scope.setCustomers($scope, DTOptionsBuilder, DTColumnBuilder, $filter, $compile, $http, toaster);
Thanks

dropdown values load sometimes and sometimes not in angularjs

I am working on angularjs , where I am loading dropdowns from database in angularjs controller. I am facing an intermittent issue that sometimes dropdown values load and sometimes don't . Its working on my local but when I upload on server this intermittent issue is coming.
I have even tried to use ng-init on html and then put login there in that function but still this issue is there.
here is html
<div class="x_panel" ng-init="loadDropDownData()">
<div class="x_title">
<h2 id="EditjobTitle" style="display:none">Edit Job<small></small></h2>
<button class="btn col-md-offset-9" id="btnBack" style="display:none" ng-click="Cancel()">Back</button>
<h2 id="NewjobTitle">New Engagement<small></small></h2>
<div class="clearfix"></div>
</div>
<div class="x_content">
<br>
<form name="JobForm" id="demo-form2" data-parsley-validate="" class="form-horizontal form-label-left" novalidate="">
<div class="form-group">
<div class="col-md-6 col-sm-6 col-xs-12 col-md-offset-3 save-buttons">
<button type="submit" class="btn btn-success" ng-click="JobForm.$valid && save()">Save</button>
<button class="btn" ng-click="Cancel()">Cancel</button>
</div>
</div>
<h5>Job Data</h5>
<input type="hidden" id="JobID" ng_value="{{Job.JobNum}}">
<div class="form-group">
#Html.Label("Job Name", new { #class = "control-label control-label-j col-md-2 col-sm-3 col-xs-12" })
<div class="col-md-3 col-sm-3 col-xs-12">
<input type="text" name="JobName" ng-model="Job.JobName" ng-minlength="4" id="txtJobName" class="form-control col-md-7 col-xs-12" required="" maxlength=25>
</div>
#Html.Label("EngType", new { #class = "control-label control-label-j col-md-2 col-sm-3 col-xs-12" })
<div class="col-md-3 col-sm-3 col-xs-12">
<select name="EngType" ng-model="Job.EngType" ng-options="s.ID as s.EngTypes for s in Job.lstEngType" class="form-control col-md-7 col-xs-12" required="">
<option value="">-- Select EngType --</option>
</select>
</div>
</div>
</form>
</div>
</div>
and Js file is as below
app.controller('AddJobController', function ($scope, $location, $filter, ShareData, jobService, $compile) {
$scope.phoneNumbr = /^\+?\d{3}[- ]?\d{3}[- ]?\d{4}$/;
$scope.datePattern = /^[0-9]{2}\/[0-9]{2}\/[0-9]{4}$/i
$scope.regEx = "/^[0-9]{10,10}$/;";
$scope.listOfStatus = [];
$scope.showStatusError = false;
$scope.statusText = "";
$scope.loadDropDownData = function() {
loadJobInitdata();
}
$(document).ready(function () {
$("#txtCloseDate").datepicker({ format: 'mm/dd/yyyy' });
$("#txtDraft_Date").datepicker({ format: 'mm/dd/yyyy' });
$("#txtFinal_Date").datepicker({ format: 'mm/dd/yyyy' });
$("#txtOpenDate").datepicker({ format: 'mm/dd/yyyy' });
$("#txtFinalSent").datepicker({ format: 'mm/dd/yyyy' });
$('body').off('click', '.remove-record').on('click', '.remove-record', function () {
removeSpan = "";
var addButton = "<div class='col-md-3 col-sm-3 col-xs-12'>\
<input type='button' class='btn btnAddDeadline' value='Add Deadline' />\
</div>";
var ifAdd = false;
if ($(this).parent().find('.btnAddDeadline').length == 1) {
ifAdd = true;
}
if ($scope.Job.JobNum != null && $scope.Job.JobNum != undefined) {
var ID = $(this).parent().find('.deadline-datepicker').attr('id')
ID = ID.replace("Date", "");
var removeSpanElement = $(this);
if (ID != "txtDeadlines") {
var promiseDeleteDeadline = jobService.DeleteDeadline(ID)
promiseDeleteDeadline.then(function () {
removeSpanElement.parent().remove();
if (ifAdd) {
PopulateDeadline(null, addButton, removeSpan);
$('.deadline-datepicker').datepicker({
ignoreReadonly: true,
startDate: new Date()
});
}
})
}
else {
$(this).parent().remove();
if (ifAdd) {
PopulateDeadline(null, addButton, removeSpan);
$('.deadline-datepicker').datepicker({
ignoreReadonly: true,
startDate: new Date()
});
}
}
}
else {
$(this).parent().remove();
if (ifAdd) {
PopulateDeadline(null, addButton, removeSpan);
$('.deadline-datepicker').datepicker({
ignoreReadonly: true,
startDate: new Date()
});
}
}
});
})
if (ShareData.value == 0) {
//loadJobInitdata();
}
else {
Edit();
}
$scope.maxlength = 3;
$scope.Job = [];
function Edit() {
if (!ShareData.createAsNewJob) {
$('#NewjobTitle').hide();
$('#EditjobTitle').show();
$('#btnBack').show();
}
//loadJobInitdata();
var promiseEditjobData = jobService.EditJob(ShareData.value);
promiseEditjobData.then(function (jobdata) {
GetDeadlinesbyJobID(ShareData.value);
getStatusCommentsJobId(ShareData.value);
$scope.Job = jobdata.data;
var CloseDate = $scope.Job.CloseDate = (jobdata.data.CloseDate != null && jobdata.data.CloseDate != undefined) ? $filter('date')(new Date(jobdata.data.CloseDate), 'MM/dd/yyyy') : null
var OpenDate = $scope.Job.OpenDate = jobdata.data.OpenDate = (jobdata.data.OpenDate != null && jobdata.data.OpenDate != undefined) ? $filter('date')(new Date(jobdata.data.OpenDate), 'MM/dd/yyyy') : null
var Draft_Date = $scope.Job.Draft_Date = jobdata.data.Draft_Date = (jobdata.data.Draft_Date != null && jobdata.data.Draft_Date != undefined) ? $filter('date')(new Date(jobdata.data.Draft_Date), 'MM/dd/yyyy') : null
var Final_Date = $scope.Job.Final_Date = jobdata.data.Final_Date = (jobdata.data.Final_Date != null && jobdata.data.Final_Date != undefined) ? $filter('date')(new Date(jobdata.data.Final_Date), 'MM/dd/yyyy') : null
$scope.Job.Deadlines = jobdata.data.Deadlines = (jobdata.data.Deadlines != null && jobdata.data.Deadlines != undefined) ? $filter('date')(new Date(jobdata.data.Deadlines), 'MM/dd/yyyy') : null
console.log(new Date(CloseDate));
var myDate = new Date(1978, 2, 11)
if (CloseDate != null) { $("#txtCloseDate").datepicker("update", new Date(CloseDate)); }
if (OpenDate != null) { $("#txtOpenDate").datepicker("update", new Date(OpenDate)); }
if (Draft_Date != null) { $("#txtDraft_Date").datepicker("update", new Date(Draft_Date)); }
if (Final_Date != null) { $("#txtFinal_Date").datepicker("update", new Date(Final_Date)); }
ShareData.value = 0;
if (ShareData.createAsNewJob == true) {
$scope.Job.JobNum = null;
ShareData.createAsNewJob = false;
}
},
function (errorPl) {
$scope.error = errorPl;
ShareData.value = 0;
alert($scope.error);
});
}
function loadJobInitdata() {
var promiseLoadDLLs = jobService.GetJobInitData();
promiseLoadDLLs.then(function (pl) {
//$scope.Job = pl.data
$scope.Job.lstEngType = pl.data.lstEngType,
$scope.Job.lstWorkProduct = pl.data.lstWorkProduct,
$scope.Job.lstNAICSCode = pl.data.lstNAICSCode,
$scope.Job.lstSubject = pl.data.lstSubject,
$scope.Job.lstManager = pl.data.lstManager,
$scope.Job.lstClientType = pl.data.lstClientType,
$scope.Job.lstFeeBasis = pl.data.lstFeeBasis,
$scope.Job.lstBillingCycle = pl.data.lstBillingCycle,
$scope.Job.lstExpenses = pl.data.lstExpenses,
$scope.Job.lstSalesperson = pl.data.lstSalesperson,
$scope.Job.lstPriority = pl.data.lstPriority,
$scope.Job.lstStaff = pl.data.lstStaff,
$scope.Job.lstLogo_in_Client_Logo_File = pl.data.lstLogo_in_Client_Logo_File,
$scope.Job.lstTombstone_Status = pl.data.lstTombstone_Status
},
function (errorPl) {
$scope.error = errorPl;
alert($scope.error);
});
}
$scope.Cancel = function () {
$location.path(ShareData.page);
}
$scope.AddDeadline = AddDeadline;
});

AngularJs change button text as well as color

Hi I am trying to change color as well as text of a button i.e. switch between two texts & colors. Suspend/unsuspend text and red/green color.
What I want to do is for the moment (because later, server will give info about whether user is suspended or not) randomly give them any one of these two texts&colors, and I click on button it should turn to other text & color.
I tried but I am wrong somewhere and I cant find it. Please help. And if there is any better way then please suggest to me, I am new to angular.
HTML:
<button type="button" class="btn btn-danger" ng-if="checkStatus(person.isSuspended)" ng-click="person.isSuspend=suspendUser(!person.isSuspend)">{{suspendText}}</button>
<button type="button" class="btn btn-primary" ng-if="checkStatus(!person.isSuspended)" ng-click="person.isSuspend=suspendUser(person.isSuspend)">{{suspendText}}</button>
Javascript:
$scope.checkStatus = function (bool) {
if (bool) {
$scope.suspendText = "UNSUSPEND"
return true;
} else {
$scope.suspendText = "SUSPEND"
return false;
}
}
$scope.suspendUser = function (bool) {
if (bool) {
if ($window.confirm("Are You Sure Want to Unsuspend ?")) {
$scope.suspendText = "SUSPEND"
return !bool;
}
else {
return bool;
}
} else {
if ($window.confirm("Are You Sure Want to Suspend ?")) {
$scope.suspendText = "UNSUSPEND"
return !bool;
} else {
return bool;
}
}
}
Check this Plunkr: http://plnkr.co/edit/DEbTtpwu749sVT6iSojd?p=preview
Asumming you are through a User List with name & status (boolean true: Active - false: inactive):
user = {name:'John', status: true}
Here you can check how change the status, text & button color. In a short angular Way.
<li ng-repeat="user in users">
({{ user.active ? 'Active' : 'Inactive'}})
{{ user.name }}
<div ng-class="user.active? 'btn btn-danger' : 'btn btn-primary' " ng-click="user.active=!user.active">
{{ user.active ? 'Suspend' : 'Unsuspend'}}
</div>
</li>
<body ng-controller="MainCtrl as vm">
<button class="btn"
ng-class="{ 'btn-primary': vm.isSuspended , 'btn-danger': !vm.isSuspended }"
ng-bind="vm.text"
ng-click="vm.toggleSuspend()">
</button>
</body>
angular.module('app', [])
.controller('MainCtrl', function() {
var vm = this;
vm.toggleSuspend = function() {
vm.isSuspended = !vm.isSuspended;
vm.text = vm.isSuspended ? 'unsuspend' : 'suspend';
};
vm.isSuspended = true;
vm.toggleSuspend();
});
You will just need one button instead of two. A better way of showing the colors would be using ng-class, where you can write expressions to toggle the class.
<button type="button" class="btn" ng-class="person.isSuspended? 'btn-danger':'btn-success'" ng-click="person.isSuspended = !person.isSuspended">{{suspendText}}</button>
Note the way ng-class is written. I am using ternary operator to check if person.isSuspeneded is true, if it is, apply the class btn-danger, else apply btn-success. Now you have got a way cleaner code.
Attached is the plnkr - http://plnkr.co/edit/Uk2rHFacMFLbXyxGzK1b?p=preview
Try to replace your ng-if with ng-show in button.
<div ng-controller="MyCtrl">
<button type="button" class="btn btn-danger"
ng-show="person.isSuspend"
ng-click="person.isSuspend=suspendUser(!person.isSuspend)">{{suspendText}}</button>
<button type="button" class="btn btn-primary"
ng-show="!person.isSuspend"
ng-click="person.isSuspend=suspendUser(person.isSuspend)">{{suspendText}}</button>
</div>
var myApp = angular.module('myApp',[]);
function MyCtrl($scope, $window) {
// first you need to initialize your scope if you didn't
$scope.person = {
isSuspend: false
};
$scope.suspendText = "SUSPEND";
$scope.suspendUser = function (bool) {
if (bool) {
if ($window.confirm("Are You Sure Want to Unsuspend ?")) {
$scope.suspendText = "SUSPEND"
$scope.person.isSuspended = false;
}
else {
$scope.person.isSuspended = true;
}
} else {
if ($window.confirm("Are You Sure Want to Suspend ?")) {
$scope.suspendText = "UNSUSPEND"
$scope.person.isSuspended = true;
} else {
$scope.person.isSuspended = false;
}
}
}
}
angular change button text

ui-grid button in cell

So I have been struggling with this for like 2 days and still no clue on what to do...
First of all I'm very new to angular and javascript in general so everything I wrote can (and may) be extremely wrong.
sample data:
{
'title' : 'awesome title',
'date' : '19-05-2015',
'place' : 'nice place',
'person' : 'Juliet Peterson',
'status' : 'OK'
}
What I need is, in an existing ui-grid, add a column containing either
if myData.person contains only one persone, this person
if myData.person is empty the text 'No person'
if myData.person contains multiple persons the text 'Choose from' wich on click will popup a list for selection.
My problem is that I am curently unable to get that working. the 2 first cases work fine but i'm struggling for the last one.
We are using bootstrap so my heart goes for either a dropdown list or a popover button
here is my current code:
html:
<div id="grid_post_id" ui-grid="gridPostOpts" ui-grid-edit class="grid"></div>
js:
$scope.choosePerson = function(a) {
if (a.length == 0) {
return 'No person';
} else {
var split = a.split(',');
if (split.length > 1) {
var res = '<button type="button" class="btn btn-default" data-container="body" data-toggle="popover" data-placement="right" data-content="';
for (var i = 0; i < split.length; i++) {
res = res + split[i];
}
res = res + '">Choose from</button>'
return res;
} else {
return a;
}
}
}
$scope.gridPosteOpts = {
columnDefs : [
{
name : 'Title',
field : 'title',
enableCellEdit : false
},
[...]
{
name : 'Person',
cellTemplate : '<div class="ui-grid-cell-contents">{{grid.appScope.choosePerson(row.entity.person)}}</div>',
enableCellEdit : false
}
this code is almost working as i got the rigth data in my cell but it is displayed instead of being interpreted as html (ie my cell contains the string '<button type="bu...')
Use
cellTemplate : `
<div class="ui-grid-cell-contents">
<button type="button" class="btn btn-default" data-container="body"
data-toggle="popover" data-placement="right"
data-content="{{grid.appScope.choosePerson(row.entity.person)}}">
Choose from
</button>
</div>`
and have choosePerson() just return the data.
You can't inject elements into the DOM using angulars {{}}. It will always be text-only
Finnaly managed to do it by myself using a mix of differents approaches found on SO!
I used #j2L4e template for the case "button needed" and just the text for the othercases; i choose between the two with an ng-if
here is the "final" code:
$scope.containsComma = function(a) {return a.contains(',')};
$scope.choosePersonBis = function(a) {
if (a.length == 0) {
return 'No person';
} else {
var split = a.split(',');
if (split.length > 1) {
var res = '';
for (var i = 0; i < split.length; i++) {
res = res + split[i];
}
return res;
} else {
return a;
}
}
;
$scope.gridPosteOpts = {
columnDefs : [
{
name : 'Title',
field : 'title',
enableCellEdit : false
},
[...]
{
title : 'Person',
cellTemplate : `
<div ng-if="grid.appScope.containsComma(row.entity.person)"
class="ui-grid-cell-contents">
<button type="button" class="btn btn-default"
popover="{{grid.appScope.choosePersonBis(row.entity.person)}}"
popover-placement="right"
popover-trigger="focus">
Choose person
</button>
</div>
<div ng-if="grid.appScope.notContainsComma(row.entity.person)"
class="ui-grid-cell-contents">
{{grid.appScope.choosePersonBis(row.entity.person)}}
</div>`
}
};
try replace this code
<div class="ui-grid-cell-contents">{{grid.appScope.choosePerson(row.entity.person)}}</div>
with
<div class="ui-grid-cell-contents" ng-bind-html="grid.appScope.choosePerson(row.entity.person)"></div>

Why Backbone Model change function inside a Marionette ItemView change event function triggers more then once?

Im working on a small project, and i have a problem with model binding. I'm using the Backbone.ModelBinder plugin for binding a model.
I'm checking changes on inputs, and get the name of the model attribute from the input data-name field. After that i check the changed data and do some stuff on the model. I have a function ChangeGuest and inside that im checking my model's (Nyiltnap.Reg) changes.
The problem is, this Nyiltnap.Reg.on("change:"+field ...){ ... } function runs as many times as many changes were made on the field named input.
Maybe i'm doing something wrong, or i missed something.
ItemView:
define(['text!templates/FormCompositeView.html', 'text!templates/EventIsFull.html', 'text!templates/ThankYou.html', 'models/RegModel'], function(Template, FullTemplate, ThankYou, Model) {
var FormCompositeView = Backbone.Marionette.ItemView.extend({
_modelBinder:undefined,
initialize: function() {
this.members = parseInt(Nyiltnap.Reg.get("members"));
this._modelBinder = new Backbone.ModelBinder();
var that = this;
Nyiltnap.Reg.on("change:name", function(r) { //HERE CHANGE TRIGGERS ONLY ONCE
if( ! _.has(r._previousAttributes, "name") ){
that.IncreaseMembers();
if(that.members < 10) that.$('.guest').attr("disabled", false);
if(that.$('#email').val() != '') that.$("#send-button").attr("disabled", false);
}
if( _.has(r._previousAttributes, "name") && r.changed.name == "" ){
that.DecreaseMembers();
Nyiltnap.Reg.unset("name");
that.$('.guest').attr("disabled", true);
that.$("#send-button").attr("disabled", true);
}
});
Nyiltnap.Reg.on("change:email", function(r) {
if( ! _.has(r._previousAttributes, "email") ){
if(that.$('#name').val() != '') that.$("#send-button").attr("disabled", false);
}
if( _.has(r._previousAttributes, "email") && r.changed.email == "" ){
that.$("#send-button").attr("disabled", true);
}
});
},
getTemplate: function() {
if( this.members < 10 ){
return _.template(Template);
}else{
return _.template(FullTemplate);
}
},
tagName: "ul",
id: "nyiltnap-form",
onRender: function() {
var MainBindings = {name : "[name=rname]", email : "#email", source : "#source", coupon : "#coupon", guest_1 : "#guest-1", guest_2 : "#guest-2", guest_3 : "#guest-3", guest_4 : "#guest-4", guest_5 : "#guest-5", guest_6 : "#guest-6", guest_7 : "#guest-7", guest_8 : "#guest-8", guest_9 : "#guest-9"};
if(this.members < 10) this._modelBinder.bind(Nyiltnap.Reg, this.el, MainBindings);
return this;
},
events: {
"change .guest" : "ChangeGuest",
"click #send-button" : "SendReg"
},
ChangeGuest: function(o) { //I WOULD LIKE TO MAKE THIS WORK
var that = this;
var field = $(o.target).data('name');
Nyiltnap.Reg.on("change:"+field, function(r) { //THIS RUNS AS MANY TIMES AS THE CONTENT OF THE 'field' HAS BEEN CHANGED
if( ! _.has(r._previousAttributes, field) ) {
that.IncreaseMembers();
that.AddInput(o);
}else{
if(_.has(r._previousAttributes, field) && _.result(r.changed, field) == ""){
that.DecreaseMembers();
}
}
});
},
IncreaseMembers: function() {
this.members++;
Nyiltnap.Reg.set("members", this.members);
Nyiltnap.vent.trigger("members:changed", this.members);
},
DecreaseMembers: function() {
this.members--;
Nyiltnap.Reg.set("members", this.members);
Nyiltnap.vent.trigger("members:changed", this.members);
},
AddInput : function(o) {
var target = $(o.target);
if(this.members < 9) target.next().next().slideDown();
}
});
return FormCompositeView;
});
Template:
<li>
<label for="guest1">My guests: </label>
<div id="guests">
<input name="guest-1" data-name="guest_1" id="guest-1" class="guest" type="text" disabled="disabled"/>
<input name="guest-2" data-name="guest_2" id="guest-2" class="guest" type="text" disabled="disabled"/>
<input name="guest-3" data-name="guest_3" id="guest-3" class="guest" style="display: none" type="text" />
<input name="guest-4" data-name="guest_4" id="guest-4" class="guest" style="display: none" type="text" />
<input name="guest-5" data-name="guest_5" id="guest-5" class="guest" style="display: none" type="text" />
<input name="guest-6" data-name="guest_6" id="guest-6" class="guest" style="display: none" type="text" />
<input name="guest-7" data-name="guest_7" id="guest-7" class="guest" style="display: none" type="text" />
<input name="guest-8" data-name="guest_8" id="guest-8" class="guest" style="display: none" type="text" />
<input name="guest-9" data-name="guest_9" id="guest-9" class="guest" style="display: none" type="text" />
<div class="clear"></div>
</div>
<div class="clear"></div>
</li>

Resources