I am trying to invoke load() on a video tag.
HTML Code:-
<div [ngClass]="{
'file-upload-grid-row': isGridRowStylingApplied,
'file-upload-grid-column': !isGridRowStylingApplied
}">
<div id="test" class="file-drag-and-drop">
<div class="card">
<div></div>
<div><button type="button" class="btn btn-primary" (click)="drop.showFileSelector()">Browse</button></div>
<div><button type="button" class="btn btn-danger" (click)="onRemove()">Cancel</button></div>
<div></div>
</div>
<div><ngx-dropzone class="custom-drop-zone size" [expandable]="true" (change)="onSelect($event)"
[disableClick]="true"
[multiple]="false" #drop>
<ngx-dropzone-label [hidden]="!showDragAndDropText">{{dragAndDropText}}</ngx-dropzone-label>
<ngx-dropzone-preview *ngFor="let file of allFiles" [removable]="true">
<ngx-dropzone-label>{{ file.name }} ({{ file.type }})</ngx-dropzone-label>
</ngx-dropzone-preview>
<!-- for image preview -->
<img *ngIf="isImageUploaded" [src]="fileURL">
<!-- for video preview -->
<video *ngIf="isVideoUploaded" id="my_video_1" controls><source [id]=fileURL [src]="fileURL"></video>
<!-- for audio preview -->
<audio *ngIf="isAudioUploaded" controls><source [src]="fileURL"></audio>
</ngx-dropzone>
</div>
</div>
<div>
<p class="text">
<ng-content></ng-content>
</p>
</div>
</div>
Component.ts
const myVideo: any = document.getElementById('my_video_1');
if (myVideo){
console.log('came');
myVideo.load();
}
The value of myVideo is always null. Can anyone please tell me what I am doing wrong?
I am using Angular8 and I have used an open-source file component - ngx-dropzone to dropping file.
Using document get element methods in Angular is wrong
Try use ViewChild decorator and you’ll can get html element from the elementRef. And also you need set { static: false } for ViewChild, because your video element has structure directive “*ngFor”. These elements may be available in AfterViewInit function and later
https://angular.io/api/core/ViewChild
Related
I am trying to add a button but it is showing me this error.
here is my html code
<div card-container>
<template class="mainTemplate">
<div class="cards">
<div class="card">
<img data-image src="" alt="">
<div data-title class="header"></div>
<div data-body class="body"></div>
<button data-button class="btn">read more</button>
<p data-paragraph class="fullText"></p>
</div>
</div>
</template>
</div>
here is the javascript code
let showDitail = document.querySelector(".btn");
showDitail.addEventListener("click", showMore);
function showMore(){
alert("e")
}
You're using the <template> tag, which is an element that holds html markup but it's not rendered on page load.
In order to render its contents, one has to handle the <template> element via javascript, using the html structure as - in fact - a template for filling another structure (a table, a divs grid, etc.).
Since the sub-elements of <template> are not part of the DOM yet, let showDitail = document.querySelector(".btn"); will result in null. That's why you cannot bind events to it.
Either change the tag to something else (a div maybe), or handle the template properly via javascript.
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template
let showDitail = document.querySelector(".btn");
showDitail.addEventListener("click", showMore);
function showMore(){
alert("e")
}
<div card-container>
<div class="mainTemplate">
<div class="cards">
<div class="card">
<img data-image src="" alt="">
<div data-title class="header"></div>
<div data-body class="body"></div>
<button data-button class="btn">read more</button>
<p data-paragraph class="fullText"></p>
</div>
</div>
</div>
</div>
I have this piece of code. It get's the logo of a game from steam
<div class="col-md-3">
<img src="http://cdn.edgecast.steamstatic.com/steam/apps/{{game.steamID}}/header.jpg" style="width: 100%; height: auto;"/>
</div>
this is part of a thumbnail div which is tied to a ngFor loop.
now for some context, and my question.
My app uses the steam WebAPI to get a list of all the games a user owns, and stores it in a database.
it then displays the list of these games to the user, with the game logo.
there are some "games" that aren't actually games, dedicated servers mostly.
but these non-games don't have any images attached to them. I want to remove these entries from the webpage whenever they crop up. The best way I can think of is to catch any 404 errors and tell the thumbnail to hide itself.
so my question is, is it possible to use ngIf to hide a div if the image url comes back with a 404 error?
EDIT
I'm adding the entire thumbnail's code for anyone that might want to look a the bigger picture.
<div class="thumbnail" style="color: black" *ngFor="let game of games">
<div class="row">
<div class="col-md-3">
<img src="http://cdn.edgecast.steamstatic.com/steam/apps/{{game.steamID}}/header.jpg" style="width: 100%; height: auto;"/>
</div>
<div class="col-md-9">
<div class="row">
<div class="col-md-12">
<h2>{{game.name}}</h2>
</div>
</div>
<div class="row">
<div class="col-md-12">
<!--<p>{{countRequests(game.id)}} People want to play<span class="pull-right">Sinse: GET_LAST_REQUEST_DATE</span></p>-->
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="centerBlock">
<div class="btn-group btn-group-lg btn-block">
<button *ngIf="page > 1" class="btn btn-primary btn-outline" (click)="previousPage()">Previous</button>
<button *ngFor="let page of pages" class="btn btn-primary btn-outline"(click)="gotoPage(page)">{{page}}</button>
<button *ngIf="page < maxPages" class="btn btn-primary btn-outline" (click)="nextPage()">Next</button>
</div>
</div>
</div>
</div>
Using Angular events you can hide the image itself:
<img #image src="..." (error)="image.hidden = true" [hidden]="image.hidden">
Or any other element:
<div [hidden]="image.hidden"></div>
Or completely remove any div:
<div *ngIf="!image.hidden"></div>
When using *ngFor
Listen to the (error) event of the image element & if the image is broken you can hide the image itself:
<div *ngFor="let some of somethings">
<div *ngIf="some.imageUrl" class="image-class-1 img-class-2">
<img src="{{some.imageUrl}}" (error)="some.imageUrl = null"/>
</div>
</div>
This is what I would do based on what you have said:
1 - I would take the full image url as a property of game.
2 - Also add a property hide to the object.
3 - Consult image using $http service in the controller.
4 - When consulting image the response is 404 then the value of property hide should be true.
5 - As you now have a property hide you can just go ng-hide="game.hide"
Here is an example:
function MyCtrl($scope,$http) {
$scope.games = [{name: 'Game 1', url: 'https://res.cloudinary.com/idemo/image/upload/ar_315:250,c_fill,e_saturation:50,g_faces,r_50,w_450/balloons.jpg'},
{name: 'Game 2', url: 'https://res.cloudinary.com/idemo/image/upload/ar_315:250,c_fill,e_saturation:50,g_faces,r_50,w_450/balloons.jpg'},
{name: 'Game 3', url: ''}]
angular.forEach($scope.games, function(value, key) {
$http.get('value.url').then(function(response){
if(response.status === 404){
value.hide = true
}
});
});
}
i have two ng-repeats that i would like to connect together using their unique id. The idea is that you click a movie poster and the corresponding streaming video will come up the screen above using CSS hide/show. This is what i have so far:
<div class="contentContainer" ng-app="webtest">
<div class="" ng-controller="LandingPageController">
<div class="videoContainer" ng-repeat="movie in movies" >
<video width="800" controls>
<source src="{{movie.stream}}" type="video/mp4">
</video>
</div>
<div class="moviesContainer">
<div class="movieCell" ng-repeat="movie in movies">
<a href="#tab{{movie.id}}">
<img class="movieCellImage" src="content/images/moviePosters/{{movie.images.cover}}">
<div class="movieCellImageBackground">
<div class="movieCellTitle">{{movie.title}} {{movie.id}}</div>
</div>
</a>
</div>
</div>
</div>
</div>
If you use Angular, you don't have to/ should use jQuery.
Angular allows you to handle click event with ng-click.
To your <a> add ng-click="select_video(movie.id)" (you can also remove href).
And you controller should look like this:
var app = angular.module('{your-app-id}', []);
app.controller('LandingPageController', function ($scope) {
$scope.selected_id = null;
$scope.movies = (...) /* The array of movies. */
$scope.select_video = function(id) {
$scope.selected_id = id;
};
});
Then, to every .videoContainer > * add ng-if="selected_id == movie.id".
Should work, let me know if it doesn't.
EDIT:
Also reorganize your HTML like this:
<div ng-controller="...">
<div class="videoContainer" ng-repeat="...">
<div ng-if="...">
<!-- <video /> here, and stuff visible only if this video is selected -->
</div>
<!-- Your <a /> -->
</div>
</div>
You don't need 2 loops. Create a reference to selected item, and set it up in the loop like:
<a ng-click="selectedMovie = movie">...</a>
Let then angular do everything for you.
<div ng-controller="LandingPageController">
<video width="800" controls>
<source src="{{selectedMovie.streams[0].url}}" type="video/mp4">
</video>
<div class="newscontainer">{{selectedMovie.id}} CLICKED</div>
<div class="moviesContainer" id="tabs">
<div class="movieCell" ng-repeat="movie in movies">
<a ng-click="selectedMovie = movie">
<img class="movieCellImage" src="content/images/moviePosters/{{movie.images.cover}}">
<div class="movieCellImageBackground">
<div class="movieCellTitle">{{movie.title}} {{movie.id}}</div>
</div>
</a>
</div>
</div>
</div>
EDIT:
Not tested, may not work. If so, try <a ng-click="$parent.selectedMovie = movie">...</a>
My HTML is:-
<div class="mb10">
<input id="input-upload-img1" type="file" class="file" data-preview-file-type="text" name="img1" accept='image/*,video/*'>
</div>
I'm using FileInput JS library, which initializing a file input type adds more HTML to it.
JQuery
$("#input-upload-img1").fileinput();
After Initializing, it adds few HTML to it.
<div class="mb10">
<span class="file-input file-input-new">
<div class="file-preview "> <!-- This whole div is initially hidden, ie display:none-->
<div class="close fileinput-remove text-right">×</div>
<div class="file-preview-thumbnails"></div>
<div class="clearfix"></div>
<div class="file-preview-status text-center text-success"></div>
<div class="kv-fileinput-error file-error-message" style="display: none;"></div>
</div>
<div class="input-group ">
<div class="form-control file-caption kv-fileinput-caption" tabindex="-1">
<div class="file-caption-name" style="width: 322.42px;"></div>
</div>
<div class="input-group-btn">
<button class="btn btn-default fileinput-remove fileinput-remove-button" type="button"><!-- This button is initially hidden, ie display:none-->
<i class="glyphicon glyphicon-ban-circle"></i>
Remove
</button>
<div class="btn btn-primary btn-file">
<i class="glyphicon glyphicon-folder-open"></i>
Browse …
<input id="input-upload-img1" class="file" type="file" accept="image/*,video/*" name="img1" data-preview-file-type="text">
</div>
</div>
</div>
</span>
</div>
After selecting an image, I get the following HTML:-
<div class="mb10">
<span class="file-input">
<div class="file-preview">
<div class="close fileinput-remove text-right">×</div>
<div class="file-preview-thumbnails">
<div id="preview-1469278203925-0" class="file-preview-frame">
<!--Check added image.-->
<img class="file-preview-image" style="width:auto;height:160px;" alt="IMG_20160606_210238.jpg" title="IMG_20160606_210238.jpg" src="blob:http://127.0.0.1:8000/27307c69-0599-4622-93f1-bf8ae6cc0e5c">
</div>
</div>
<div class="clearfix"></div>
<div class="file-preview-status text-center text-success"></div>
<div class="kv-fileinput-error file-error-message" style="display: none;"></div>
</div>
<div class="input-group ">
<div class="form-control file-caption kv-fileinput-caption" tabindex="-1">
<div class="file-caption-name" style="width: 234.22px;" title="IMG_20160606_210238.jpg"></div>
<div class="input-group-btn">
<button class="btn btn-default fileinput-remove fileinput-remove-button" type="button">
<i class="glyphicon glyphicon-ban-circle"></i>
Remove
</button>
<div class="btn btn-primary btn-file">
<i class="glyphicon glyphicon-folder-open"></i>
Browse …
<input id="input-upload-img1" class="file" type="file" accept="image/*,video/*" name="img1" data-preview-file-type="text">
</div>
</div>
</div>
</span>
</div>
Note the added img tag.
Now, I'm writing a JQuery to get the src of the img tag upon selecting a file. How can I do it?
Here is my jQuery:-
$('.file').change(function(){
var file = this.files[0];
if (!file){
return
}
var source_image = $(this).closest('div .file-preview-frame').find('.file-preview-image')
alert(source_image.attr('src'))
}
It returns undefined. I guess its because the dynamic adding of the image. How can I get the image source of the file selected.??
I think you've wrongly understood the usage of .closest. It reads, For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree. You see, when change on .file element occurs, it traverses through its ancestors where in span.file-input will be one of the ancestors and div.file-preview-frame is not. So you should visit span.file-input and then find div.file-preview-frame.
You should be probably doing this.
$('.file').change(function(){
var file = this.files[0];
if (!file){
return
}
var source_image = $(this).closest('span.file-input')
.find('div.file-preview-frame .file-preview-image')
alert(source_image.attr('src'))
}
Update
I went on to check the plugin and found few events like below which you can really use:
fileLoaded:
This event is triggered after a file is loaded in the preview.
Additional parameters available are:
file: the file object instance
previewId: the identifier for the preview file container
index: the zero-based sequential index of the loaded file in the preview list
reader: the FileReader instance if available.
Example:
$('#input-id').on('fileloaded', function(event, file, previewId, index, reader) {
console.log("fileloaded");
});
fileSelect
This event is triggered after files are selected in the file input via
the file browse button. This is slightly different than the change
event in the sense that this will be triggered even if the file browse
dialog is cancelled.
Example:
$('#input-id').on('fileselect', function(event, numFiles, label) {
console.log("fileselect");
});
I would prefer fileLoaded event which you can use as below:
$('.file').on('fileloaded', function(event, file, previewId, index, reader) {
console.log(file);
//file will have many details like lastModified, name, size, type etc.,
});
I have a template whereby I load details into via a JSON file. The content that is loaded in accompanies a video embed. Everything from the JSON files are working great, but the same video appears on every item. Is there a way that I can load individual videos assigned to each JSON file?
Here is the template:
<div class="container" ng-repeat="guide in guides">
<div class="row">
<div class="col-md-12">
<br/>
<p><a ng-href="#/"><span class="glyphicon glyphicon-home"></span> Back to Guide List</a></p>
<h1><span class="glyphicon glyphicon-play-circle"></span> Watch {{ guide.title }}</h1>
<span>{{ guide.info }}</span><br/><br/>
</div>
<div class="col-md-12">
<video video="marvel">
</video><!--This is the bit I'm having an issue with -->
</div>
<div class="col-md-6">
<h3><span class="glyphicon glyphicon-education"></span> Background to {{ guide.title }}</h3>
<span>{{ guide.background }}</span><br/><br/>
</div>
<div class="col-md-6">
<h3><span class="glyphicon glyphicon-save"></span> Downloads for {{ guide.title }}</h3><br/>
<a ng-href="{{ guide.pdf }}" target="_blank"><span class="glyphicon glyphicon-floppy-save"></span> Download Help Guide PDF</a><br/><br/>
<a ng-href="{{ guide.video }}" target="_blank"><span class="glyphicon glyphicon-floppy-save"></span> Download Video</a>
</div>
</div>
</div>
I'm unable to bind any data into the video tag (which is a directive I've built) - so does anyone have any suggestions?
Thanks in advance.
It should help if you reference a different video in each repeat iteration ;-)
<div class="col-md-12">
<video src="{{guide.my_video_uri}}">
</video>
</div>
If src=".." doesn't work, try ng-src="..".
thanks for the suggestion. I have in fact, tried this - the video tag is a little misleading; as it a custom directive called "video".
<video video="{{ guide.video }}">
</video>
this just brings up the error: Cannot GET /%7B%7B%20videoUrl%20%7D%7D
The directive brings in youtube embeds - which I am using for testing purposes first. The intention was to adjust the trustAsResourceUrl to another form of embed afterwards. The directive code is here below (i have changed the tag from video to video-player)
guideApp.directive('videoPlayer', function ($sce) {
'use strict';
return {
restrict: 'E',
scope: { video: '=' },
replace: true,
template: '<div class="embed-responsive embed-responsive-16by9"><iframe class="embed-responsive-item" width="100%" height="100%" src="{{ videoUrl }}" frameborder="0" allowfullscreen></iframe></div>',
link: function (scope) {
scope.$watch('videoPlayer', function (videoLink) {
if (videoLink) {
scope.videoUrl = $sce.trustAsResourceUrl("https://www.youtube.com/embed/" + videoLink);
}
});
}
};
});