How to insert HTML in focussed textAngular element? - javascript

I have multiple textAngular fields in same page with common toolbar and I have created a directive to auto insert some text in textAngular field at current caret position. Now the problem is I can insert the code when there is only one textAngular field. But with multiple textAngular fields, I am unable to find which textAngular field is focussed.
Here is my code :
HTML
<div class="row mrgn20">
<div class="formFld">
<text-angular name="message" ta-target-toolbars="messageToolbar" ng-model="composeEmail.body"></text-angular>
<text-angular name="emailSignature" ta-target-toolbars="messageToolbar" ng-model="composeEmailCtrl.emailSignature.text"></text-angular>
<text-angular-toolbar ta-toolbar="[['uploadAttachment','bold','italics', 'ul', 'insertLink', 'fontSize', 'uploadImage', 'fontColor']]" class="toolbar" name="messageToolbar"></text-angular-toolbar>
</div>
<auto-insert-text options="composeEmailCtrl.autoInsertTextOptions" insert-in="message"></auto-insert-text>
</div>
JS
Controller
function ($scope){
$scope.composeEmailCtrl = {};
$scope.composeEmail ={};
$scope.candidate = {
name : 'Rahul',
company : 'Test Company'
}
$scope.composeEmailCtrl.autoInsertTextOptions = [{
title: 'candidate fullName',
value: scope.candidate.name,
key : 'candidate_fullname'
}, {
title: 'company name',
value: scope.candidate.company,
key : 'company_name'
}];
}
Directive
app.directive('autoInsertText', function(textAngularManager) {
return {
restrict: 'E',
template: '<span translate="insert_auto_text"></span> <span ng-repeat="option in options"><button type="button" ng-bind="option.title" ng-click="insertText($event,option)" unselectable="on"></button></span>',
scope: {
options: "=",
insertIn: "#"
},
link: function(scope, elem, attr) {
var _editorScope = '';
scope.insertText = function(event, option) {
_editorScope = _editorScope || textAngularManager.retrieveEditor(scope.insertIn).scope;
_editorScope.displayElements.text[0].focus();
_editorScope.wrapSelection("insertHTML", option.value, true);
}
}
};
});
The autoInsertText directive takes the insert options and the textangular field name in which the value is to be inserted. I want to support insertion in multiple textAngular fields depending on the current caret position.

Related

AngularJS Custom Directive using ng-options populated from service

I've really hit a brick wall with this, and I know I'm probably missing something here, but I'm stuck and need help. What I'm trying to do is use a service to populate the options in an ng-options directive; however, the ng-options are inside of a custom directive, and I've tried everything from track by, to testing it outside of the directive, inside the directive, etc. Can someone please take a look at this code and see if you can spot what I'm missing? Any help is greatly appreciated. It WILL work as far as executing the update to the ng-model; however, at page landing and record selection, it will not initially select the proper option, but if I take the track by out, it will initialize with the proper selection, it just won't update ng-model when/if I do that.
angular
.module('app')
.controller('mainCtrl', ['acctList', 'CONSTANTS', 'FORMFIELDS', function(acctList, CONSTANTS, FORMFIELDS) {
var mainCtrl = this;
mainCtrl.form = {};
mainCtrl.formFields = FORMFIELDS;
mainCtrl.currentRecord = null;
mainCtrl.editedRecord = {};
mainCtrl.setCurrentRecord = function(value) {
mainCtrl.currentRecord = value;
mainCtrl.editedRecord = angular.copy(mainCtrl.currentRecord);
};
mainCtrl.statuses = CONSTANTS.statuses;
}])
.value('FORMFIELDS', [
{
key: 'active_flag',
inputtype: 'select',
type: 'text',
class: 'form-control',
id: 'activeFl',
name: 'activeFl',
placeholder: 'Active Flag',
required: true,
maxlength: 1,
disabled: false,
labelfor: 'inputActiveFl',
labeltext: 'Active Flag',
field: 'mainCtrl.editedRecord.ACTIVE_FL',
options: 'list as list.desc for list in mainCtrl.statuses track by list.value'
}
])
.value('CONSTANTS',
{
statuses: [
{
id: 1,
value: "Y",
desc: "Active"
},
{
id: 2,
value: "N",
desc: "Inactive"
}
]
}
)
.directive('formTemplate', ['$compile', function($compile) {
function linker(scope, element, attr) {
scope.$watch(attr.modeltemp, function(modeltemp) {
// if ngModel already equals modeltemp or modeltemp doesn't exist, return
if (attr.ngModel == modeltemp || !modeltemp) return;
// remove all attributes to prevent duplication
element.removeAttr('placeholder');
element.removeAttr('type');
element.removeAttr('class');
element.removeAttr('id');
element.removeAttr('name');
element.removeAttr('ng-required');
element.removeAttr('maxlength');
element.removeAttr('ng-disabled');
// add the ng-model attribute presently tied to modeltemp
element.attr('ng-model', modeltemp);
// if modeltemp is blank, then remove ng-model, as it would be null
if (modeltemp == '') {
element.removeAttr('ng-model');
}
// Unbind all previous event handlers, this is
// necessary to remove previously linked models.
element.off();
// run a compile on the element, injecting scope, to reconstruct the element
$compile(element)(scope);
});
console.log(scope.acctCtrl);
}
// dynamic templating function associated with the templateUrl in the DDO
function template (tElement, tAttrs) {
// set the type variable equal to the value from the tAttr for 'inputtype' coming from the view
var type = tAttrs['inputtype'];
// just declaring the return variable for cleanliness
var tpl;
// begin the switch-case statement for each inputtype, then set it's return variable equal to the respective url
switch(type) {
case 'input':
tpl = '/common/directives/formTemplate/formTemplate.template.html';
break;
case 'select':
tpl = '/common/directives/formTemplate/formTemplateSelect.template.html';
break;
default:
tpl = '/common/directives/formTemplate/formTemplate.template.html';
break;
}
return tpl;
}
return {
restrict: 'EA',
replace: true,
templateUrl: template,
link: linker
};
}])
<form class="form-horizontal" ng-submit="submit()" name="mainCtrl.form.newAcctForm">
<div class="col-lg-6 form-fields" ng-repeat="fields in mainCtrl.formFields" ng-class="{ 'has-error': mainCtrl.form.newAcctForm.{{fields.name}}.$dirty }">
<label class="control-label" for="{{fields.labelfor}}">{{fields.labeltext}}</label>
<div form-template modeltemp="fields.field" inputtype="{{fields.inputtype}}"></div>
</div>
</form>
<select class="{{fields.class}}" id="{{fields.id}}" name="{{fields.name}}" ng-options="{{fields.options}}" ng-required="{{fields.required}}" maxlength="{{fields.maxlength}}" ng-disabled="{{fields.disabled}}">
<option value="">Please select...</option>
</select>
While this does work, did you consider using lifecycle hooks instead, waiting until after the view has loaded/initialized? Your solution works, but it's a bit like using a rocket launcher on an ant hill.

AngularJS + select2 - How to set initial value

I want to use Select2 in my AngularJS project, So I added an input like this :
<select class="find-neighborhood js-states form-control"
ng-model="regionIdentifier"
ng-init="">
</select>
Luckily , Whenever regionIdentifier is change, I find out. Actually I want to set initial value in my Select2. Here is my javascript code :
$(".find-neighborhood").select2({
dir: "rtl",
placeholder: "find neighborhood ...",
allowClear: true,
data: $scope.regions
});
My $scope.regions looks like :
[object,object,object]
Each object is like :
0 :Object
id:52623
regionSlug:yvuj
text:yvuj1
How to init value in my select2?
You should create a directive to make this work globally and fine. Here is a simple example which let you initialize a select2 set the default option values to your selection. You can find a working version on plnkr. While select2 depends on jQuery you may will look for an other lib to make it work. Some dev's preffer to have no jQuery included in AngularJS projects.
Controller
//option list
$scope.regions = {
'test1' : {
id: 1
},
'test2' : {
id: 2
},
'test3' : {
id: 3
},
'test4' : {
id: 4
},
'test5' : {
id: 5
}
};
//model & selected value setup
$scope.regionIdentifier = 3;
View
<select class="js-example-basic-single"
ng-model="regionIdentifier"
items="regions"
items-selected="regionIdentifier"
id="regionSelection"
select-two>
</select>
Directive
/**
* Simple select2 directive
*/
angular.module('app').directive('selectTwo', ['$timeout', function($timeout){
return {
restrict : 'EA',
transclude : true,
terminal: true,
templateUrl : 'views/directive/select2.html',
scope: {
items: "=",
itemsSelected: "="
},
link: function($scope, $element, $attrs, $controller){
//format options https://select2.github.io/select2/#documentation
function format(state) {
//init default state
var optionTemplate = state.text;
if (!state.id || state.id == 0) { //option group or no selection item
return optionTemplate;
}
return optionTemplate;
}
//init on load
$timeout(function(){
//if multiple options are possible, parse an comma seperated list into itemsSelected like 1,2,5,23,21
if (angular.isString($scope.itemsSelected) && $scope.itemsSelected.split(',').length > 1) {
$scope.itemsSelected = $scope.itemsSelected.split(',');
}
$($element[0]).select2({
formatResult: format,
formatSelection: format,
escapeMarkup: function(m) { return m; }
}).val($scope.itemsSelected == undefined ? [0]: [$scope.itemsSelected]).trigger("change");
});
}
};
}]);
Directive template views/directive/select2.html
<option ng-repeat="(name, item) in items track by $index"
value="{{ item.id }}">
{{ name }}
</option>

Angular js change 'file' type to 'text' type [Safari]

I have inputs that build from objects in array.
Everything got right but when input.type = 'file', Angular change it to text type and i cant figure it out.
Did anything notice this?
My template:
<span ng-repeat="input in formInputs">
<label for="{{input.id}}">{{input.label}}</label>
<input type="{{input.type}}" id="{{input.id}}" name="{{input.name}}" ng-model="input.insert" ng-required="input.must">
</span>
My array:
var formInputs = [
{
label : 'first name',
id : 'id1',
type : 'text',
name : 'name1',
must : true,
insert : ''
},
{
label : 'upload file',
id : 'id2',
type : 'file',
name : 'name2',
must : true,
insert : ''
}
]
My result:
<span ng-repeat="input in formInputs">
<label for="id1">first name</label>
<input type="text" id="id1" name="name1" ng-model="input.insert" ng-required="input.must">
<label for="id2">upload file</label>
<input type="text" id="id2" name="name2" ng-model="input.insert" ng-required="input.must">
</span>
EDIT:
I have this flowing:
<input type="{{childInput.type}}" id="{{childInput.id}}" name="{{childInput.name}}">
And this array:
var formInputs = [
{
id : 'id',
type : 'file',
name : 'name',
}
]
The resolute [only in Safari]:
<input type="text" id="id" name="name">
Why its happening?
Thanks for your help!
From the AngularJS Documentation for input:
Note: Not every feature offered is available for all input types. Specifically, data binding and event handling via ng-model is unsupported for input[file].
So it looks like Angular falls back to type="text". There are a lot of answers which bring solutions to this, check out:
ng-model for <input type=“file”/>
From that answer, here's a way to deal with a file input.
.directive("fileread", [function () {
return {
scope: {
fileread: "="
},
link: function (scope, element, attributes) {
element.bind("change", function (changeEvent) {
var reader = new FileReader();
reader.onload = function (loadEvent) {
scope.$apply(function () {
scope.fileread = loadEvent.target.result;
});
}
reader.readAsDataURL(changeEvent.target.files[0]);
});
}
}
}]);
As mentionned by Hackerman, his jsfiddle seem to work (with Angular 1.0.1) at first sight, but it doesn't seem to populate the model correctly.

AngularJS Getting the value of a selected dropdown option in a variable

I have dropdown selection menu & want to send the dropdown selected value in request params of api. My code is...
<select class="form-control" id = "SelectionInput_reason">
<option name="careerType" value="type_1">Career</option>
<option name="examType" value="type_2">Exams</option>
</select>
getValue = function() {
var selectedValue = this.value;
var selectedText = this.options[this.selectedIndex].getAttribute('name');
alert(selectedValue);
alert(selectedText);
}
document.getElementById('SelectionInput_reason').addEventListener('change', getValue );
Please give answer in angularJS if possible...
also how can I get the text input of tinymceeditor in a variable ?
$scope.tinymceModel = 'Initial content';
$scope.getContent = function() {
console.log('Editor content:', $scope.tinymceModel);
};
$scope.setContent = function() {
$scope.tinymceModel = 'Time: ' + (new Date());
};
$scope.tinymceOptions = {
selector: 'textarea',
//plugins: 'link image code',
toolbar: ' bold italic | undo redo | alignleft aligncenter alignright | code'
};
HTML is..
<div class="form-group">
<textarea ui-tinymce="tinymceOptions" id="jander" ng-model="tinymceModel" placeholder="Ask your question" class="form-control"></textarea>
</div>
Bind a model in your select dropdown. Like below
<select class="form-control" id = "SelectionInput_reason" data-ng-model="inputReason">
In your controller you will get selected option
console.log($scope.inputReason)
Here is a sample code with a fiddle attached
var myApp = angular.module('myApp', []);
myApp.controller('MyCtrl', function($scope) {
$scope.shelf = [{
'name': 'Banana',
'value': '$2'
}, {
'name': 'Apple',
'value': '$8'
}, {
'name': 'Pineapple',
'value': '$5'
}, {
'name': 'Blueberry',
'value': '$3'
}];
$scope.cart = {
'fruit': $scope.shelf[0]
};
});
<div ng-controller="MyCtrl">
<div>
Fruit List:
<select ng-model="cart.fruit" ng-options="state as state.name for state in shelf"></select>
<br/>
<tt>Cost & Fruit selected: {{cart.fruit}}</tt>
</div>
</div>
Fiddle link : http://jsfiddle.net/Td2NZ/1867/
My advise in this scenario is try to keep all input choices as a Js Object (Like $scope.shelf in this code) cause thats what Angular is built for rigid and robust handling of the data, eventually you could just load those options from a server or json file and not having to touch your HTML at all!
Hope this helps!

Angular JS: "Select All" options of "multi-select select box"

I have created a multiselect select box using Angular JS: below is the code for the same:
JS:
$scope.foobars = [{
'foobar_id': 'foobar01',
'name': 'foobar01',
}, {
'foobar_id': 'foobar02',
'name': 'foobar02',
}, {
'foobar_id': 'foobar03',
'name': 'foobar03',
}, {
'foobar_id': 'foobar04',
'name': 'foobar04',
}, {
'foobar_id': 'foobar05',
'name': 'foobar05',
}];
HTML:
<select multiple="multiple" size="5" id="selFooBar" ng-model="foobarName" ng-options="medcenter as medcenter.name for medcenter in medcenters track by medcenter.medcenter_id">
<option selected="selected">Select All</option>
</select>
And the output is :
Question 1: Why am I not getting the default option "Select All" in the list? And How do I get that?
Question 2: How can I Select All optiions on click of "First Option : Select All"??
Please suggest!
If you want to keep the <option> in the <select> element before you add the ng-options you'll have to use transclusion. the ng-options directive doesn't use transclusion, but you can create a custom directive that does. You can do that by utilizing transcludeFn in the directive post compile function:
compile: function(element,attrs) {
return {
post: function(scope, element, attributes, controller, transcludeFn){
transcludeFn(function(clone, scope) {
// prepend the transcluded content to the select
element.prepend(clone);
// set the onclick of the clone to call the selectAll function
clone.bind('click', function(){
clone.scope().$parent.selectAll();
scope.$apply();
})
});
}
}
},
controller: function($scope) {
$scope.selectAll = function() {
$scope.selectedValues = $scope.values;
}
}
Then you can set the selectedValues to all possible values on the scope, whether that's isolate or inherited. In the following plnkr example it's isolated. On click the Select All option will select the other elements.
Plunker Example

Categories

Resources