Angularjs popover nglick does not trigger at second time - javascript

My problem is I create a popover for controlling the element's width and offset.
Here is the screenshot for better understanding.
However, the problem is when first click the element (for example: Description1 ), the popover pops up and the ng-click of the four arrows work. But second time click the element, the popover still comes, but the ng-click of the four arrows does not works anymore!
Here is part of the html code:
<div id="sortable" ng-repeat="object in arrayForShow">
<div ng-show="checkType(object)">
<div ng-switch on="getKeyValue(object)">
<div ng-switch-when="default">
<div ng-class="classGenerate(object)" class="well nomargin" id="resizable" pop-over-width-offset argument='object' addwidth='addWidth(object)' decreasewidth='decreaseWidth(object)' addoffset='addOffset(object)' decreaseoffset='decreaseOffset(object)'>
{{object.default}}
</div>
pop-over-width-offset is an directive, and pass object into it and bind four method: addWidth, addOffset, decreaseOffset, which are in the controller.
The directive part code:
app.directive "popOverWidthOffset", ($templateCache, $compile)->
restrict: 'A',
controller: 'CustomiseFormCtrl'
scope: {
argument: '='
addwidth: '&'
decreasewidth: '&'
addoffset: '&'
decreaseoffset: '&'
}
link: (scope, element, attrs)->
content = $templateCache.get('angular/templates/popOverCustomisationChangeWidthOffset.html')
scope.$watch 'content', ()->
popOverContent = $compile(content)(scope)
options = {
content: popOverContent,
placement: "top",
html: true,
trigger: "click"
}
$(element).popover(options)
, true
And the template url code is as follows:
<table>
<tbody>
<tr>
<td>
<a class="btn btn-link" ng-click="addwidth(argument)">
<span class="glyphicon glyphicon-chevron-up">
</a>
</td>
<td> </td>
<td>
<a class="btn btn-link">
<span class="glyphicon glyphicon-chevron-up" ng-click="addoffset(argument)">
</a>
</td>
</tr>
<tr>
<td class="form-group" width="40px;">
<input class="form-control" ng-model="argument.position[1]" style="text-align: center;">
</td>
<td> </td>
<td class="form-group" width="40px;">
<input class="form-control" ng-model="argument.position[2]" style="text-align: center;">
</td>
</tr>
<tr>
<td>
<a class="btn btn-link" ng-click="decreasewidth(argument)">
<span class="glyphicon glyphicon-chevron-down">
</a>
</td>
<td> </td>
<td>
<a class="btn btn-link">
<span class="glyphicon glyphicon-chevron-down" ng-click="decreaseoffset(argument)">
</a>
</td>
</tr>
</tbody>
</table>

Replace this:
popOverContent = $compile(content)(scope)
with this:
popOverContent = function() {
return $compile(content)(scope);
};
;)

Related

Angular 2 upload Image button is refreshing page

I have a html form with two buttons on it:-
[1] One button is used to upload an image file (.jpg)
[2] and the second one is to submit the form.
The problem is that the upload image button seems to be refreshing the page after the method for uploading the image has completed. Below is my html:-
<div class="m-b-18px">
<div class="col-m-12">
<a (click)="readRecipes()" class="btn btn-primary pull-right">
<span class="glyphicon glyphicon-plus"></span>Read Recipes
</a>
</div>
</div>
<div class="row">
<div class="col-md-12">
<form [formGroup]="create_recipe_form" (ngSubmit)="createRecipe()">
<table class="table table-hover table-responsive table-bordered">
<tr>
<td>
Name
</td>
<td>
<input name="name" formControlName="name" type="text" class="form-control" required />
<div *ngIf="create_recipe_form.get('name').touched && create_recipe_form.get('name').hasError('required')"
class="alert alert-danger">Name is required
</div>
</td>
</tr>
<tr>
<td>
Description
</td>
<td>
<textarea name="description" formControlName="description" class="form-control" required>
</textarea>
<div *ngIf="create_recipe_form.get('description').touched && create_recipe_form.get('description').hasError('required')"
class="alert alert-danger">
Description is required
</div>
</td>
</tr>
<tr>
<td>
Image
</td>
<td>
<input name="selectFile" id="selectFile" type="file" class="form-control btn btn-success" />
<button type="button" class="btn btn-primary" (click)="uploadImage($event)" value="Upload Image">Upload Image</button>
<input type='hidden' id='image_id' name='img_id' value="6" formControlName="image_id" />
</td>
</tr>
<tr>
<td></td>
<td>
<button class="btn btn-primary" type="submit" [disabled]="!create_recipe_form.valid">
<span class="glyphicon glyphicon-plus"></span> Create
</button>
</td>
</tr>
</table>
</form>
</div>
</div>
My code for the uploadImage method is below:-
uploadImage(e) {
let files = this.elem.nativeElement.querySelector('#selectFile').files;
let formData = new FormData();
let file = files[0];
formData.append('selectFile', file, file.name);
this._imageService.uploadImage(formData)
.subscribe(
image => {
console.log(image);
this.addImageIdToHtml(image)
e.preventDefault();
e.stopPropagation();
},
error => console.log(error)
);
}
As soon as the above method has finished running the page appears to refreshing causing my app to go back to the land page. This is not the behaviour I want. What I actually want is the form page to be retained until the Submit form button is pressed. Can anyone help me please?
Use div tags instead of form tag.
Change the button type as button.
<button type="button">Upload Image</button>
Modify the code as follows.
<div class="m-b-18px">
<div class="col-m-12">
<a (click)="readRecipes()" class="btn btn-primary pull-right">
<span class="glyphicon glyphicon-plus"></span>Read Recipes
</a>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div [formGroup]="create_recipe_form" (ngSubmit)="createRecipe()">
<table class="table table-hover table-responsive table-bordered">
<tr>
<td>
Name
</td>
<td>
<input name="name" formControlName="name" type="text" class="form-control" required />
<div *ngIf="create_recipe_form.get('name').touched && create_recipe_form.get('name').hasError('required')"
class="alert alert-danger">Name is required
</div>
</td>
</tr>
<tr>
<td>
Description
</td>
<td>
<textarea name="description" formControlName="description" class="form-control" required>
</textarea>
<div *ngIf="create_recipe_form.get('description').touched && create_recipe_form.get('description').hasError('required')"
class="alert alert-danger">
Description is required
</div>
</td>
</tr>
<tr>
<td>
Image
</td>
<td>
<input name="selectFile" id="selectFile" type="file" class="form-control btn btn-success" />
<button type="button" class="btn btn-primary" (click)="uploadImage($event)" value="Upload Image">Upload Image</button>
<input type='hidden' id='image_id' name='img_id' value="6" formControlName="image_id" />
</td>
</tr>
<tr>
<td></td>
<td>
<button class="btn btn-primary" type="button" [disabled]="!create_recipe_form.valid">
<span class="glyphicon glyphicon-plus"></span> Create
</button>
</td>
</tr>
</table>
</div>
</div>
</div>
You should not upload files on Angular folders like (Assets) , cuz it will recompile every time new file added to Angular environment and that will cause you the page refreshment you didn't want.
If you are using button tag inside the form tag, add type="button" inside the button tag.
<button type="button"></button>
This will work perfectly

Angular2 Javascript Push - Add item to array

I'm building a form in Angular2 which contains a field that is an array of objects. I've so far built the table with a Delete Row button per row and an Add Row button. These use the JavaScript push() and slice() methods.
There is a big bug though:
When adding a new row, the content of the previous rows is deleted.
That is to say, the content of the row is deleted, not the row itself.
Any ideas why?
Component Code:
public addRow(): void {
this.table.push({});
}
public deleteRow(row: object): void {
this.table.splice(this.table.indexOf(row), 1);
}
HTML Template
<form #TimesheetForm="ngForm" (ngSubmit)="saveTimesheet()">
<div class="row">
<div class="col text-right">
<button type="button" class="btn" (click)="addRow()"><i class="fa fa-plus-square" aria-hidden="true"></i> Add Row</button>
</div>
</div>
<table class="table">
<thead>
<td class="table__header">Date</td>
<td class="table__header">Time</td>
<td class="table__header">Actions</td>
</thead>
<tbody>
<tr *ngFor="let row of table">
<td class="table__item">
<input class="input" [(ngModel)]="row.date" name="date">
</td>
<td class="table__item">
<input class="input" [(ngModel)]="row.time" name="time">
</td>
<td class="table__item">
<button type="button" class="btn btn--negative" (click)="deleteRow(row)"><i class="fa fa-times" aria-hidden="true"></i> Delete</button>
</td>
</tr>
<tr *ngIf="school.rows.length == 0">
<td colspan="3">No rows exist yet. Click Add Row to start logging your timesheet.</td>
</tr>
</tbody>
</table>
</div>
<div class="row">
<div class="col">
<button class="btn btn--positive" type="submit"><i aria-hidden="true" class="fa fa-check"></i> Save</button>
</div>
<div class="col text-right">
<button class="btn btn--negative"><i aria-hidden="true" class="fa fa-times"></i> Cancel</button>
</div>
</div>
</form>
With template driven forms, we need to remember that the name attribute needs to be unique, otherwise the fields will be evaluated as the same field. So what your form does now, is not adding new form controls when you add new rows, instead it manipulates the one and same form field. If you were to put something like <pre>{{TimesheetForm.value | json}}</pre> in your template, you can see, that despite pushing new rows, there is only one form control name date and one form control named time.
So what we need to do is to provide an unique name, we can do that by using the index of the items in your table array. So do the following:
<tr *ngFor="let row of table; let i = index">
<td>
<input [(ngModel)]="row.date" name="date{{i}}">
</td>
<td>
<input [(ngModel)]="row.time" name="time{{i}}">
</td>
<!-- more code here -->
</tr>

Dynamical ng-model in ng-repeat is undefined

I need help with dynamically generated models inside ng-repeat. I have a HTML with ng-repeating table rows. Each row has an option to update image name and price with update button.
HTML
<tr role="row" class="odd" ng-repeat="i in slideShowImages track by $index">
<td>
<img ng-src="{{i.thumb_path}}" width="100px" height="auto" >
</td>
<td>
<div class="form-group">
<input type="text" name="imageName" ng-model="i.imageName[$index]"
class="form-control" id="imageName" required>
</div>
</td>
<td>{{i.date_taken | myDate}}</td>
<td>
<div class="form-group">
<input type="text" name="imagePrice" ng-model="i.imagePrice[$index]"
class="form-control" id="imagePrice" required>
</div>
</td>
<td>
{{i.position}}
</td>
<td>
<a ng-click="updateImage(i.id_thumb, $index)">
<button class="btn btn-block btn-success">Update</button>
</a>
</td>
<td>
<a ng-click="deleteImage(i.id_thumb, $index)">
<button class="btn btn-block btn-danger">Delete</button>
</a>
</td>
</tr>
And this is my controller function which is trying to get the values
$scope.updateImage = function(id, $index){
$scope.models = {};
console.log(id);
console.log($index);
console.log($scope.i.imageName[$index]);
console.log($scope.i.imagePrice[$index]);
};
// result of console logs
4
0
angular.js:13550 TypeError: Cannot read property 'imageName' of undefined
at Scope.$scope.updateImage (locationsCtrl.js:243)
at fn (eval at compile (angular.js:14432), <anonymous>:4:486)
at expensiveCheckFn (angular.js:15485)
at callback (angular.js:25018)
at Scope.$eval (angular.js:17229)
at Scope.$apply (angular.js:17329)
at HTMLAnchorElement.<anonymous> (angular.js:25023)
at HTMLAnchorElement.dispatch (jQuery-2.1.4.min.js:3)
at HTMLAnchorElement.r.handle (jQuery-2.1.4.min.js:3)
Guess i'm doing something wrong, based on error that imageName and imagePrice can't be undefined. I hope you guys can help me. If you need any additional information's please let me know and i will provide. Thank you in advance
You had ng-repeat with i in slideShowImages which says that, on each iteration i will have current element of collection over the UI only(not in controller scope). So you can not get $scope.i value inside controller. You have to pass that value from updateImage as a parameter like ng-click="updateImage(i)". Then you can play with i object which is available on UI.
HTML
<td>
<a ng-click="updateImage(i)">
<button class="btn btn-block btn-success">Update</button>
</a>
</td>
<td>
<a ng-click="deleteImage(i, $index)">
<button class="btn btn-block btn-danger">Delete</button>
</a>
</td>
Controller
$scope.updateImage = function(i){
console.log(i.imageName);
console.log(i.imagePrice);
};
You cannot ge the i object of ng-repeat in the controller.
What else one can do is filter using any other key in the json.
Example:
$scope.currentImageName = $filter('filter')(slideShowImages,{ id: $index});
Here assuming slideShowImages has a field id of value - $index.
Also, add the dependency injection$filter in the controller definition.

ngIf always evaluates as true

I'm developing an AngularJS application, using v1.3.9. I have a couple ng-if directives which are always evaluating true, and I can't figure out why.
<tr data-ng-repeat="line in chat">
<td class="message-timestamp">{{line.time | date:'short'}}</td>
<div ng-if="line.type === 'gist'">
<td class="message-nick">{{line.nick}}</td>
<td class="message-text">{{line.message}}
<p>
<code ng-show="showGist" walrus-auto-gistify data-gist-id="{{line.options[0]}}"></code>
<br>
<button ng-click="showGist = !showGist" class="btn btn-primary btn-xs">Show/Hide</button>
</p>
</td>
</div>
<div ng-if="false">
<td class="message-nick"><span class="glyphicon glyphicon-arrow-right"></span></td>
<td class="message-text">{{line.message}}</td>
</div>
</tr>
When I run this, both ng-if directives are evaluated as true, so both divs are displayed.
chat is just an array of objects.
I'm pretty sure it has to do with the fact that you have a <div> as a direct child of a <tr>. I've had issues with this type of design in the past where it causes strange behavior.
A solution to this is to put the <div>'s within the <td>, like below:
<tr data-ng-repeat="line in chat">
<td class="message-timestamp">{{line.time | date:'short'}}</td>
<td class="message-nick">
<div ng-if="line.type === 'gist'">{{line.nick}}</div>
<div ng-if="line.type !== 'gist'"><span class="glyphicon glyphicon-arrow-right"></span></div>
</td>
<td class="message-text">
<div ng-if="line.type === 'gist'">
<p>
<code ng-show="showGist" walrus-auto-gistify data-gist-id="{{line.options[0]}}"></code>
<br />
<button ng-click="showGist = !showGist" class="btn btn-primary btn-xs">Show/Hide</button>
</p>
</div>
<div ng-if="line.type !== 'gist'">{line.message}}</div>
</td>
</tr>
EDIT: Attempt at a JSFiddle here

Anguarjs Directive at Form Level, accessing all fields and checking for validation

In a form (itemSelectionForm), I am rendering multiple tables with ng-repeat. And in each table I have radio buttons which have names appended with index. Now, I want to write an angular JS directive (selectAtleastOneItemToReturn) that I would put on the form (with select-atleast-one-item) which will do form validation based on children tables radio button. Now, I don't know how I access those children tables radio buttons and their values in that directive so that I can write validation code. And, if radio buttons value changes I want to do validation again and again. And if the form is invalid , the next button would be disabled. The HTML is as below.
<div class="panel-group" data-ng-form="itemSelectionForm" select-atleast-one-item>
<div class="panel panel-default" data-ng-repeat="item in items">
<div class="panel">
<div class="panel-body">
<table class="table table-bordered">
<thead>
<tr>
<th>Action</th>
<th>Item Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<label>
<input type="radio" name="inputRadios{{$index}}" value="option 1" data-ng-model="item.action" required/>
</label>
</td>
<td>{{item.description}}</td>
</tr>
<tr>
<td>
<label>
<input type="radio" name="inputRadios{{$index}}" value="option 2" data-ng-model="item.action" required/>
</label>
</td>
<td colspan="2">Option 2</td>
</tr>
<tr>
<td>
<label>
<input type="radio" name="inputRadios{{$index}}" value="option 3" data-ng-model="item.action" required/>
</label>
</td>
<td colspan="2">Option 3</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="right">
<button type="submit" class="btn green-button left space-left" data-ng-disabled="itemSelectionForm.$invalid" data-ng-click="goForward()">Next</button>
</div>
Easiest is probably to pass down the form object to the directive, and put a $watch on the property you need, which would probably be $error in your case - although I'm not very clear on what you're trying to achieve actually...
JS:
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $log){
$scope.items = [
{
action: 'fooAction',
description: 'Foo'
},
{
action: 'barAction',
description: 'Bar'
}
];
});
app.directive('selectAtleastOneItem', function(){
return {
restrict: 'A',
scope: {
frm: '=selectAtleastOneItem'
},
link: function(scope, element, attrs){
scope.$watch('frm.$error', function(newVal, oldVal){
console.log(newVal);
}, true);
}
}
});
HTML:
<div ng-app="myApp">
<div ng-controller="myCtrl">
<div ng-form="itemSelectionForm" select-atleast-one-item="itemSelectionForm">
<div ng-repeat="item in items">
{{item.description}}
<input type="radio" name="inputRadios{{$index}}" ng-model="item.action" required>
</div>
</div>
</div>
Fiddle: http://jsfiddle.net/dwkmy20j/1/
Hopefully that gets you going a bit.

Categories

Resources