Angular 5 compile html with components - angular5

I'm working on a project using angular 5 and I'm trying to render components that come from database. I have a lot of components and the user can create a page and include them as he or she wants.
This is a migration intent from a project in Angular 1.6. So, this is what I have in angular 1.6
<div html-angular-bind="{{$ctrl.content}}"> </div>
And this is html-angular-bind definition for this example:
angular.module('App').directive('htmlAngularBind', [
'$compile', function($compile) {
return function(scope, elem, attrs) {
scope.$watch("$ctrl.content", function(newValue, oldValue) {
var compiled, el, html;
html = attrs.htmlAngularBind;
el = angular.element(html);
compiled = $compile(el);
elem.html(el);
return compiled(scope);
});
};
}
]);
So, let's supose I have components <component1></component1>, <component2></component2>...<component1000></component1000> in the page created by the user. All of them get replaced by the HTML defined in those components.
The question is: Is there any way to do the same in Angular 5?

Related

VueJS, displaying static images vs. binding a function from methods [duplicate]

I'm looking for the right url to reference static assets, like images within Vue javascript.
For example, I'm creating a leaflet marker using a custom icon image, and I've tried several urls, but they all return a 404 (Not Found):
Main.vue:
var icon = L.icon({
iconUrl: './assets/img.png',
iconSize: [25, 25],
iconAnchor: [12, 12]
});
I've tried putting the images in the assets folder and the static folder with no luck. Do I have to tell vue to load those images somehow?
For anyone looking to refer images from template, You can refer images directly using '#'
Example:
<img src="#/assets/images/home.png"/>
In a Vue regular setup, /assets is not served.
The images become src="data:image/png;base64,iVBORw0K...YII=" strings, instead.
Using from within JavaScript: require()
To get the images from JS code, use require('../assets.myImage.png'). The path must be relative (see below).
So your code would be:
var icon = L.icon({
iconUrl: require('./assets/img.png'), // was iconUrl: './assets/img.png',
// iconUrl: require('#/assets/img.png'), // use # as alternative, depending on the path
// ...
});
Use relative path
For example, say you have the following folder structure:
- src
+- assets
- myImage.png
+- components
- MyComponent.vue
If you want to reference the image in MyComponent.vue, the path sould be ../assets/myImage.png
Here's a DEMO CODESANDBOX showing it in action.
A better solution would be
Adding some good practices and safity to #acdcjunior's answer, to use # instead of ./
In JavaScript
require("#/assets/images/user-img-placeholder.png")
In JSX Template
<img src="#/assets/images/user-img-placeholder.png"/>
using # points to the src directory.
using ~ points to the project root, which makes it easier to access the node_modules and other root level resources
In order for Webpack to return the correct asset paths, you need to use require('./relative/path/to/file.jpg'), which will get processed by file-loader and returns the resolved URL.
computed: {
iconUrl () {
return require('./assets/img.png')
// The path could be '../assets/img.png', etc., which depends on where your vue file is
}
}
See VueJS templates - Handling Static Assets
Right after oppening script tag just add import someImage from '../assets/someImage.png'
and use it for an icon url iconUrl: someImage
this finally worked for me, image passed as prop:
<img :src="require(`../../assets/${image}.svg`)">
What system are you using? Webpack? Vue-loader?
I'll only brainstorming here...
Because .png is not a JavaScript file, you will need to configure Webpack to use file-loader or url-loader to handle them. The project scaffolded with vue-cli has also configured this for you.
You can take a look at webpack.conf.js in order to see if it's well configured like
...
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
},
...
/assets is for files that are handles by webpack during bundling - for that, they have to be referenced somewhere in your javascript code.
Other assets can be put in /static, the content of this folder will be copied to /dist later as-is.
I recommend you to try to change:
iconUrl: './assets/img.png'
to
iconUrl: './dist/img.png'
You can read the official documentation here: https://vue-loader.vuejs.org/en/configurations/asset-url.html
Hope it helps to you!
It works for me by using require syntax like this:
$('.eventSlick').slick({
dots: true,
slidesToShow: 3,
slidesToScroll: 1,
autoplay: false,
autoplaySpeed: 2000,
arrows: true,
draggable: false,
prevArrow: '<button type="button" data-role="none" class="slick-prev"><img src="' + require("#/assets/img/icon/Arrow_Left.svg")+'"></button>',
Having a default structure of folders generated by Vue CLI such as src/assets you can place your image there and refer this from HTML as follows <img src="../src/assets/img/logo.png"> as well (works automatically without any changes on deployment too).
I'm using typescript with vue, but this is how I went about it
<template><div><img :src="MyImage" /></div></template>
<script lang="ts">
import { Vue } from 'vue-property-decorator';
export default class MyPage extends Vue {
MyImage = "../assets/images/myImage.png";
}
</script>
You could define the assets path depending on your environment
const dev = process.env.NODE_ENV != 'production';
const url = 'https://your-site.com';
const assets = dev ? '' : url;
<template>
<img :src="`${assets}/logo.png`"/>
<p>path: {{assets}}</p>
</template>
<script>
export default {
data: () => ({
assets
})
}
</script>
Ideally this would be inside an utils js file, or as an extended app defineProperty, like:
const app = createApp(component);
app.config.globalProperties.$assets = assets;
app.mount(element);
and will be available as:
<template>
<img :src="`${$assets}/logo.png`"/>
<p>path: {{$assets}}</p>
</template>
<script>
export default {
mounted() {
console.log(this.$assets);
}
}
</script>
load them in created, mounted or where you need them
async created() {
try {
this.icon = (await import('#assets/images/img.png')).default;
} catch (e) {
// explicitly ignored
}
and then
<img :src=icon />
Inside code you can directly require image using.
const src = require("../../assets/images/xyz.png");
Or
In order to dynamically load image need this.
const image = new window.Image();
image.src = require("../../assets/images/xyz.png");
image.onload = () => {
// do something if needed
};

Howto debug JavaScript inside ASP .Net Core 3.1 MVC applications (Razor view - *.cshtml)?

I have latest Visual Studio 2019 16.5.4 Enterprise.
I've just created an ASP .Net Core 3.1 MVC application from a template (with default settings).
And I've added some JavaScript code to a Home Page's Index.cshtml:
#{
ViewData["Title"] = "Home Page";
}
<div class="text-center">
<h1 class="display-4">Welcome</h1>
<p>Learn about building Web apps with ASP.NET Core.</p>
</div>
#section Scripts {
<script>
function GetJSON_Simple() {
var resp = [];
return resp;
}
debugger;
var simpleData = GetJSON_Simple();
</script>
}
And I'm not able to debug JavaScript code (breakpoints inside GetJSON_Simple function body or on var simpleData = GetJSON_Simple() is never hit). I've tried both Chrome and MS Edge (Chromium).
According to this article (Debug JavaScript in dynamic files using Razor (ASP.NET) section):
Place the debugger; statement where you want to break: This causes the
dynamic script to stop execution and start debugging immediately while
it is being created.
P.S. I've already have Tools->Options->Debugging->General with turned on Enable JavaScript Debugging for ASP.NET (Chrome and IE) checkbox and of course I'm compiling in Debug.
My test project is attached
Howto debug JavaScript inside ASP .Net Core 3.1 MVC applications
(Razor view - *.cshtml)?
In fact, it is already a well-known issue. We can not debug the js code under Net Core razor page but only for code in separate js or ts files. See this link.
Solution
To solve it, I suggest you could create a new single js file called test.js and then reference it in razor page and then you can hit into js code when you debug it.
1) create a file called test.js and migrate your js code into it:
function GetJSON_Simple() {
var resp = [];
return resp;
}
debugger;
var simpleData = GetJSON_Simple();
2) change to use this in your cshtml file:
#{
ViewData["Title"] = "Home Page";
}
<div class="text-center">
<h1 class="display-4">Welcome</h1>
<p>Learn about building Web apps with ASP.NET Core.</p>
</div>
#section Scripts {
<script scr="xxx/test.js">
</script>
}
3) clean your project, then rebuild your project and debug it and you will hit into Js code.
Another way is to explicitly define the source mapping name for the script directly in your javascript code via a sourceURL comment.
<script>
...your script code
//# sourceURL=blah
</script>
The script in that block will show up in Chrome with the value you specified. You can then view and debug just like a normal .js file.
This is especially useful if you don't want to refactor an existing codebase that has embedded javascript in the cshtml files or really ANY codebase that has javascript loaded on the fly.
Live Example
You can actually see an example with the built-in javascript runner here. Just click 'Run Snippet' and then search for "blahblah" in your Page sources. You should see this:
alert("test");
//# sourceURL=blahblah

Multiple Aurelia Instances - Aurelia Webpack Plugin - aureliaApp option - "module not found"

I am composing my web app as a number of Aurelia "feature" apps - although I'm not using Aurelia features as such. Consequently in my html markup I have two entry points pointing to different apps:
<!-- Top Navigation Bar -->
<div aurelia-app="topnav"></div>
<!-- Main App-->
<div aurelia-app="main"></div>
I am using webpack and everything works perfectly using the single "main" app. Webpack generates a JS file "main.bundle.js" which I include in the src tag.
Things are not so straightforward when I added the "topnav" app. In webpack I tell the plugin to use a different aureliaApp name:
new AureliaPlugin({ aureliaApp: "topnav"}),
and, as you can see my HTML entrypoint also calls "topnav". Webpack generates a JS file "topnav.bundle.js" which I also include. I have a file called "topnav.ts" which contains the aurelia Cionfigure function which ends:
aurelia.start().then(() => aurelia.setRoot(PLATFORM.moduleName("nav")));
And a pair of files "nav.ts", "nav.html" which constitute my viewmodel and view.
When I run the app aurelia loads and the "nav" module code executes. But I then get an error - see below.
The module which it reports that it cannot find is the one entered into the HTML markup.
Should this work? Have I missed something?
I should add, everything seems to work. I can create and update properties in the viewmodel and these are bound to the view. It's just that this error is thrown.
You are doing nothing wrong, just unsupported scenario. Per official doc-wiki: https://github.com/aurelia/webpack-plugin/wiki/AureliaPlugin-options#aureliaapp
You can have only 1 auto entry module with aureliaApp configuration. To solve this, you just need to add PLATFORM.moduleName('topnav') to your main.ts (and put it on root level)
Another way to do is to bootstrap manually:
// in your index.ts
import { bootstrap } from 'aurelia-bootstrapper';
// bootstrap top nav application, with one instance of Aurelia
bootstrap(aurelia => {
// do your configuration
aurelia
.start()
.then(() => aurelia.setRoot(
PLATFORM.moduleName('topnav'),
document.querySelector('#topnav')
);
});
// bootstrap main application, with another instance of Aurelia
bootstrap(aurelia => {
// aurelia.use.standardConfiguration();
// ...
aurelia
.start()
.then(() => aurelia.setRoot(
PLATFORM.moduleName('app'),
document.querySelector('app')
)
});

Aurelia library js file in Bundle but is resolved as static file

My project structure is as follows:
src
..lib
....someLibrary.js
bundles.js:
"bundles": {
"dist/app-build": {
"includes": [
"[**/*.js]",
"**/*.html!text",
"**/*.css!text"
],
"options": {
"sourceMaps": 'inline'
"inject": true,
"minify": true,
"depCache": true,
"rev": true
}
},
The project builds fine, but when I check app-build.js I don't find a definition for lib/someLibrary.js. I am using typescript for my own project so I assume this has something to do with that, how can I mix regular js files and output from my transpiled TS files into the same app-build bundle?
Update
So I tried to split the 'build-system' gulp task into two tasks: 'build-typescript' which is the same as 'build-system' was before, then I created 'build-libs' which looks like so:
gulp.task('build-libs', function() {
return gulp.src(paths.root + '**/*.js')
.pipe(plumber({errorHandler: notify.onError('Error: <%= error.message %>')}))
.pipe(changed(paths.output, {extension: '.js'}))
.pipe(sourcemaps.write('.', { includeContent: false, sourceRoot: '/src' }).on('error', gutil.log))
.pipe(gulp.dest(paths.output));
});
I then added to my dist/app-build bundle config: "lib/someLibrary.min.js"
And now my app-build.js does have the library defined, however when I try to use the library in one of my views using:
<require from="lib/someLibrary.min.js">
I get an error:
Failed to load resource: the server responded with a status of 404 (Static File '/dist/lib/someLibrary.min.html' not found)
What?!?? Why is it looking for html when nowhere is html ever involved in this whole scenario? Why is something that should be easy this hard?
Update2
So apparently 'require' does not work with javascript files. I changed to use the 'script' tag, however it seems these get stripped out when rendered by Aurelia. I am at a loss as to how to get Aurelia to do what I want it to.
Ok so after much frustration and disbelief at how hard something so simple could be, in addition to the changes to the build tasks mentioned above (which includes the javascript library file that has no npm/jspm package into the app-bundle) I created a modified version of this solution which looks as follows:
import { bindable, bindingMode, customElement, noView } from 'aurelia-framework';
#noView()
#customElement('scriptinjector')
export class ScriptInjector {
#bindable public url;
#bindable public isLocal;
#bindable public isAsync;
#bindable({ defaultBindingMode: bindingMode.oneWay }) protected scripttag;
public attached() {
if (this.url) {
this.scripttag = document.createElement('script');
if (this.isAsync) {
this.scripttag.async = true;
}
if (this.isLocal) {
const code = 'System.import(\'' + this.url + '\').then(null, console.error.bind(console));';
this.scripttag.text = code;
} else {
this.scripttag.setAttribute('src', this.url);
}
document.body.appendChild(this.scripttag);
}
}
public detached() {
if (this.scripttag) {
this.scripttag.remove();
}
}
}
To use it, simply add the following tag to the view where you want the script library to be used as follows:
<scriptinjector url="lib/bootstrap-toc.js" is-local.bind='true'></scriptinjector>
This will keep the original scriptinjector functionality which allows you to add remote 3rd party libraries to your Aurelia app but it will also allow you to load any local 3rd party libraries that you have bundled with your app.
Hope this helps someone.

How to integrate visual captcha in jsf page with javascript of jquery

I am trying to integrate visual captcha in my jsf page. is there a link where i can see steps for doing it. i followed the below steps from visual captcha for jquery but it didn't work.
Initialization
Include jQuery library and jQuery version of the visualCaptcha front-end library into the HTML page:
Create a visualCaptcha container into the HTML page:
Initialize the captcha with the $( element ).visualCaptcha( options ) jQuery function that returns a jQuery object within the visualCaptcha object. It uses two parameters: element is a selector of a container for the visualCaptcha, options is an object of the visualCaptcha options:
var el = $( '#sample-captcha' ).visualCaptcha( {
imgPath: 'img/',
captcha: { numberOfImages: 5 }
} );
// use the following code to get the captcha object
var capthca = el.data( 'captcha' );