Edit items by clicking a button. Angular.js - javascript

I currently have a directive to dynamically edit a field. I have in the header of the accordion a field to edit and another field in the content of the accordion. If I click the edit button, the fields in the respective row can be edited, and this works fine. My problem is when I save or when I cancel it (when I click on the save or cancel button) immediately disappears the text field of both the header and the contents of the header. I need the text field ONLY disappear for the item in which I am going to save or cancel. When you click on the edit button, the 2 text fields should appear in both the header and the content (this works). And when clicking save or cancel, the text field in the selected element should disappear / appear.
<div ng-controller="AccordionDemoCtrl">
<uib-accordion close-others="true">
<div ng-repeat="faq in faqs">
<div class="col-sm-11" >
<div uib-accordion-group class="panel-default" is-open="faq.open">
<uib-accordion-heading >
<span ng-click="ignoreClick($event);" ><a href='' click-to-edit edit-state='faq.editState' ng-model='faq.pregunta' typeinput='textarea' >{{faq.pregunta}}</a></span> <i class="pull-right glyphicon" ng-class="{'glyphicon-chevron-down': faq.open, 'glyphicon-chevron-right': !faq.open}"></i>
</uib-accordion-heading>
<span click-to-edit edit-state='faq.editState' ng-model="faq.respuesta" >{{faq.respuesta}}</span>
</div>
</div>
<div class="col-sm-1" >
<button type="button" ng-click="toggleEditState($index)" class="btn btn-default">
<span class="glyphicon glyphicon glyphicon-edit"></span>
</button>
</div>
</div>
</uib-accordion>
</div>
https://plnkr.co/edit/S4OllJV64EYFNo6WIjVH?p=preview

use one-way (one-directional) binding for editState
scope: {
model: '=ngModel',
editState: '<'
},
https://plnkr.co/edit/dNehOxAIRHsRqgK9wXJx?p=preview

I believe you'll need to manage two separate booleans at the controller level so one directive doesn't overwrite the status of the other and then you have to set both booleans with your open button. I kept the master state so your glyph button will open or close both and the save/cancel should operate independently of each other.
$scope.editState = false;
$scope.editHeader = false;
$scope.editBody = false;
$scope.toggleEditState = function(index, val) {
debugger;
$scope.editState = !$scope.editState;
$scope.faqs[index].editHeader = $scope.editState;
$scope.faqs[index].editBody = $scope.editState;
}
<div ng-repeat="faq in faqs">
<div class="col-sm-11" >
<div uib-accordion-group class="panel-default" is-open="faq.open">
<uib-accordion-heading >
<span ng-click="ignoreClick($event);" ><a href='' click-to-edit edit-state='faq.editHeader' ng-model='faq.pregunta' typeinput='textarea' >{{faq.pregunta}}</a></span> <i class="pull-right glyphicon" ng-class="{'glyphicon-chevron-down': faq.open, 'glyphicon-chevron-right': !faq.open}"></i>
</uib-accordion-heading>
<span click-to-edit edit-state='faq.editBody' ng-model="faq.respuesta" >{{faq.respuesta}}</span>
</div>
</div>
<div class="col-sm-1" >
<button type="button" ng-click="toggleEditState($index)" class="btn btn-default">
<span class="glyphicon glyphicon glyphicon-edit"></span>
</button>
</div>
https://plnkr.co/edit/91cGWoTKyJsZQKxYapiT?p=preview
You could also communicate the master status with the directives if you wanted their input fields to open and close both.

Related

Display xeditable editable form inside popup

Need to wrap the editable form inside a bootstrap uib-popover-template.
Have tried the editable ui-bootstrap popover approach, but it is not working as expected.
Plunker 1 --> https://plnkr.co/edit/vXeVoFYVU2IU08CF
angular-bootstrap approach - Not able show/hide the form
Plunker 2 --> https://plnkr.co/edit/upUFeEeQbxs8VfF5?preview
x-editable approach - Not able wrap it inside the popover
<div class="ui-popover-wrapper">
<a href="#" editable-text="user.name"
ng-click="editableForm.$show()">{{user.name || 'empty' }}</a>
</div>
<form editable-form name="editableForm" onaftersave="saveUser()" ng-show="editableForm.$visible">
<div>
<span class="title">DDown1: </span>
<span editable-select="user.status" e-name="status" e-ng-options="s.value as s.text for s in statuses">
{{ (statuses | filter:{value: user.status})[0].text || 'Not set' }}
</span>
</div>
<div>
<!-- editable username (text with validation) -->
<span class="title">DropDown Date: </span>
<span editable-date="user.date" onbeforesave="checkDate($data)"
>{{ (user.date | date: "yyyy-MM-dd") || 'empty' }}</span>
</div>
<div>
<!-- buttons to submit / cancel form -->
<span ng-show="editableForm.$visible">
<button type="submit" class="btn btn-primary" ng-disabled="editableForm.$waiting">
Save
</button>
<button type="button" class="btn btn-default" ng-disabled="editableForm.$waiting" ng-click="editableForm.$cancel()">
Cancel
</button>
</span>
</div>
</form>
I have edited your first plunkr: https://plnkr.co/edit/QNKoOd7rZzAiIRJf
You need to pass the id of your template as a string to the bootstrap popover directive:
uib-popover-template="'myPopoverTemplate.html'"
I also removed this from your code:
ng-show="editableForm.$visible"
I am assuming you want to show the popover on click.

I need to change html class attribute for every ng-repeat element with button

i have html div where i use ng-repeat that gives me back elements from array
<div>
<div class="col-sm-3" ng-repeat="el in vm.filmovi " id="filmovi">
<img src="http://image.tmdb.org/t/p/w500/{{el.poster_path}}" style="width:100%;"><br>
<a ng-click="vm.set_favorit(el)" style="cursor:hand; color:white;" uib-tooltip="Postavi u omiljene">
<i class="glyphicon" ng-class="{'glyphicon-star-empty':el.favorit!=true, 'glyphicon-star':el.favorit==true}"
aria-hidden="true"></i></a>
<a href="http://www.imdb.com/title/{{el.imdb_id}}/" style="color:white;">
<strong>{{ el.title | limitTo: 20 }}{{el.title.length > 20 ? '...' : ''}}</strong></a>
<a class="glyphicon glyphicon-share-alt" style="margin-left:5px; color:white;" ng-click="vm.open()" uib-tooltip="share" ></a><br>
{{el.popularity}} <br>
<a style="color:white;" href="#" ng-click="vm.filter(genre)" ng-repeat="genre in el.genres"><small>{{genre.name}} </small></a>
<div ng-init="x = 0">
<span uib-rating ng-model="x" max="5"
state-on="'glyphicon-star'"
state-off="'glyphicon-star-empty'"></span></div>
</div>
</div>
now i created a button that changes value of id "filmovi"
<li><a href="#" ng-hide="vm.ulogovan" ng-click="vm.dugme();" >losta</a></li>
and created function vm.dugme() that gets element by id and sets class atribute to col-sm-4
vm.dugme=function(){
document.getElementById("filmovi").setAttribute("class","col-sm-4");
};
but when i did that only the first element changed
but i need for all of them to change to col-sm-4 , any suggestion?
Don't do DOM manipulation from angularjs controller. Instead make use of directive provided by angular.
You could use ng-class with expression so that whenever expression gets satiesfied the class will be added over that DOM. To add class put addColSm4 flag inside a controller and change that flag from dugme method of your controller. Also by looking at screenshot it seems like you need col-sm-3 class at the beginning, afterwards you need to apply col-sm-4.
HTML
<div class="row">
<div class="col-sm-3" ng-repeat="el in vm.filmovi"
ng-class="{'col-sm-4': vm.addColSm4, 'col-sm-3': !vm.addColSm4 }" >
.. Html will stay as is ..
</div>
</div>
<li>
<a href="#" ng-hide="vm.ulogovan"
ng-click="vm.dugme()">
losta
</a>
</li>
Code
vm.dugme = function (){
vm.addColSm4 = true;
};
Demo Plunker

In Javascript, how do I trigger a local file load via an html element?

I have an app where I can load a local file via clicking on a label:
<div class="igv-drag-drop-surface">
<div class="igv-drag-drop-file-icon-container" style="">
<i id="igv-drag-drop-file-icon" class="fa fa-file fa-5x" aria-hidden="true"></i>
<i id="igv-drag-drop-index-file-icon" class="fa fa-file-o fa-5x" aria-hidden="true"></i>
</div>
<div class="igv-track-file-input-container-css">
<input id="igv-track-index-file-input" class="igv-track-file-input-css" type="file" name="files[]" data-multiple-caption="{count} files selected" multiple="" style="">
<label for="igv-track-index-file-input" id="load-local-file-blurb" style="">
<strong>Choose index file</strong>
<span class="igv-drag-drop-surface-blurb"> or drop it here</span>
</label>
</div>
</div>
So, clicking on the label with id with load-local-file-blurb will present the file chooser. That works fine.
I want in addition to be able to click on the icon with id igv-drag-drop-index-file-icon to present the file chooser as well.
Here is a visual aid to what the widget looks like:
How do I do this?
Just trigger a click on the label.
For example:
var icon = '#igv-drag-drop-index-file-icon';
var label = '#load-local-file-blurb';
document.querySelector(icon).addEventListener('click', function() {
document.querySelector(label).click()
});
But the better approach is to perform click onto file input field.

Changes in html template do not reflect

I am trying to add some buttons to the GeoNetwork 3 MapViewer. Unfortunately I'm new to AngularJS, which GN3 is written in. So what I've done is editing the html-template that the 'gnMainViewer' directive is using.
ViewerDirectve.js:
module.directive('gnMainViewer', [
'gnMap',
function(gnMap) {
return {
restrict: 'A',
replace: true,
scope: true,
templateUrl: '../../catalog/components/viewer/' +
'partials/mainviewer.html',
[...]
}]);
In this template I can find the buttons that are shown in the MapView.
mainviewer.html:
<div class="wrapper" data-ng-controller="gnViewerController">
<div data-gn-alert-manager=""></div>
<div id="map" ngeo-map="map" class="map"></div>
<div gn-gfi="" map="map"></div>
<div gn-localisation-input map="map"></div>
<!--Top right buttons - Tools-->
<div class="tools tools-right" gi-btn-group gnv-close-panel data-ng-controller="toolsController">
<button class="btn btn-default" ng-model="activeTools.addLayers" type="submit"
rel="#addLayers" gi-btn gnv-tools-btn>
<span class="fa fa-plus"></span>
<span role="tooltip" data-translate="">addLayers</span>
</button>
<button class="btn btn-default" ng-model="activeTools.layers" type="submit"
rel="#layers" gi-btn gnv-tools-btn>
<span class="fa fa-tasks"></span>
<span role="tooltip" data-translate="">Layers</span>
</button>
[...]
</div>
</div>
So I've added a button let's say:
<button class="btn btn-default" ng-model="" type="submit"
rel="#" gi-btn gnv-tools-btn>
<span class="fa fa-beer"></span>
<span role="tooltip">NewButton</span>
</button>
to the template.
Then I've saved my changed and refreshed the MapView-Page on my server. But a new button will not be displayed. Also, changing the comment "Top right buttons" to something else will not make any changes to the displayed MapView-Page.
Even restarting the server won't change anything.
Could somebody explain me why AngularJS reacts like this? Any Ideas?
Turned out I had to run the page in debug mode e.g. http://localhost:8080/geonetwork/srv/ger/catalog.search?debug#/map
to force to load all AngularJS files seperately and without cache.

AngularJS Nested Ng-repeat Counter Decrementation

I am trying to decrement a counter within a nested AnguarJs ng-repeat. I know it is a problem of scope, because the increment in the outer ng-repeat works fine, but in the inner ng-repeat is where I have to decrement and that is where I run into the problem (nothing happens). Is there any way to get an inner scope to increment/decrement/affect an outer scope? Here is the code I am working with.
<div class = "col-md-12 section-bg-conversations" ng-repeat="o in form.question | filter:searchText | orderBy:predicate" ng-show="$index<5 || form.showMoreQuestions" >
<!--section for question and option to answer-->
<span class="pull-left" style="margin-bottom:5px">
<ul style="color:#107A77; margin-left: -10px; list-style-type:none">
<li >
<!--below is only to toggle form view-->
<h7><strong><a style="color:#107A77;" ng-click="o.Answer = true" ng-show="!o.Answer">Comment</a></strong></h7>
</li>
<li>
<h7 ng-init="replyCounter=o.replyCounter">Replies ({{replyCounter}}) </h7>
</li>
<li>
<h7>
<a style="color:#107A77;text-size: 6px"
ng-init="followCounter=o.followCounter" ng-click="followConversation(o.id); o.isFollowing=true;
followCounter=followCounter+1" ng-show="!o.isFollowing">
Follow ({{followCounter}})
</a>
<span ng-show="o.isFollowing">
Following ({{followCounter}})
</span>
</h7>
</li>
</ul>
</span>
<span ng-show="o.isFollowing">
<a style='color:gold' ng-init="followCounter = o.followCounter" ng-click="unfollowConversation(o.followId); o.isFollowing = false;
followCounter = followCounter-1 " ng-hide="o.unfollowValue">Unfollow</a>
</span>
<!--form div below showing only submit and cancel-->
<div style="margin-top:5px">
<button class="btn btn-xs btn-primary" ng-init="replyCounter=o.replyCounter" style='background:#107A77'
ng-click="submitAnswer(o.id); replyCounter = replyCounter+1;">Submit</button>
<button class="btn btn-xs btn-primary" style='background:red' ng-click="o.Answer = false" ng-show="o.Answer">Cancel</button>
</div>
<div class = "col-md-offset-1" style="padding:5px"ng-repeat="a in o.replies" ng-show="$index<3 || o.showMoreReplies">
<span ng-show="a.isAuthor">
<a ng-init="replyCounter=o.replyCounter"style='color:red' ng-click="doDelete(a.id); a.deleteValue = true;
replyCounter = replyCounter-1">Delete</a>
</span>
</div>
I also included the followCounter as an exmaple of a counter that is working. Pretty much the main problem is in the last inner div that does ng-repeat="a in o.replies" and I'm not sure how to solve the problem of incrementing/decremeting the counter in the overall scope.

Categories