Dynamically add components depending on data being recieved Angular 5 - javascript

I do have this working.. but I want to know if there is a better way.. because I can see how the way could potentially be a problem in the future..
Basically I have a page that brings in data and populates on the page, every time you click a 'next' button the data changes and so the page changes..
Now I have a few tools that I have set up in components and sometimes when the data says tool === true I show the tool component on the page so how Ive done it at the moment is like so
<div class="program-item">
<div class="main">
<div *ngFor="let asset of item?.fields?.asset" class="program-item_inner">
<div [innerHTML]="asset.fields.textBlock"></div>
<!-- tool -->
<app-tool *ngIf="asset.fields.tools === 'tool'"></app-bmi-tool>
<button *ngIf="asset.fields.tools == 'BMI Tracker'" class="full-width-btn program-item_next-button" (click)="next(item?.sys.id); child.getBmi();">CALCULATE BMI</button>
<button *ngIf="item?.fields?.assetType !== 'tool'" class="full-width-btn program-item_next-button" (click)="next(item?.sys.id)">{{(item?.fields?.nextButtonText == null || item?.fields?.nextButtonText == undefined) ? 'NEXT' : item?.fields?.nextButtonText}}</button>
</div>
so basically when the data has been recieved check to see if asset.fields.tools === tool and then show the tool component.. this isnt a great way to do it because I have a few tools and I would have to do that for every single one
Is there another way I could do this?

Related

Calling same function to change element.style.display to "block" on two different pages with different outcome

I am working on a simple CRUD-web-app consisting of 3 pages, a landing/index page, 1 page to see display the saved data and 1 page to make changes and save these changes in an indexeddb.
On two of these pages i call a simple javascript-function to change .style.display from "none" to "block" in order to display a modal. For some reason it only works on one page. On the other page (HTML code displayed below) the modal is displayed for only a split second before one gets navigated to the landing page.
function modalOpen(){
let modal = document.getElementById("aModal");
modal.style.display = "block";}
The javascript file containing this code is linked in both HTML files.
Following below is the corresponding HTML Code. The function gets called in line 5.
<main>
<form>
....
<button id="bSubmitExercise" onclick="edit('all')">Änderungen speichern</button>
<button id="bOpenDeleteModal" onclick="modalOpen()">Übung löschen</button>
<button id="bBackToIndex" onclick="location.href='detailsExercise.html'">Zurück zur Übersicht</button>
</form>
</main>
<article id="aModal" class="aModal">
<section class="sModalContent">
<h5 id="hExercisesName"></h5>
<div class="dContModalButtons">
<button id="bModalConfirmDelete" class="bModal" onclick="deleteExercise()">Löschen</button>
<button id="bModalClose" class="bModal" onclick="modalClose()">Fenster schließen</button>
</div>
</section>
</article>
When i open the chrome devtools and call the modalOpen()-function from console, the modal gets displayed as intended.
This behavior occurs wether using chrome, edge or when built as apache cordova app for android mobile. Cache an saved data cleared multiple times in both browsers.
Why is this (not) happening?
For historical reasons, by default the <button> tag acts as a submit button when it's in a <form>. You can do one of two things:
If you're using some sort of ajax mechanism anyway, you might not need a <form> at all;
You can explicitly make the buttons <button type=button> to disable that submit behavior

Validation for file upload in angularjs

Hi I am developing web application in angularjs. I am developing file upload module. I have one form and inside form i have file upload control. On clicking on submit(submitting form) if the file is not uploaded then i want to make file control as red. i have designed css class to make file control red.
<div class="upload-button bank button1" ng-class="{'has-error':
vm.hasFileInputError(myFileID) }">
<div class="upload-button-icon" >
<span class="text">{{ 'ID' | translate }}</span>
<input type="file" file-modelsr="myFileID" />
</div>
</div>
I am writing validation rule in javascript.
$scope.vm = {};
function hasFileInputError(myFileID) {
return this.form2.$submitted && this.form2.myFileID.$invalid ||
form2.myFileID.$invalid && form2.myFileID.$dirty;
}
On clicking on submit button if file has not uploaded then i want to make file control as red. This is not happening. I am trying to figure out this issue but nothing worked out. May i get some help to fix this? Thank you.
You have pass your myFileID to function. then why you need $form validation? Because if any other fields are not valid then the form.&dirty always return false.
So better to change your method be like
vm.hasFileInputError = function (myFileID) {
return myFileID == undefined || myFileID == '' ? true : false
}
EDIT:
And you should read this discussion : AngularJS - Why use "Controller as vm"?

Having Issue on Loading Pre-loader only From External entery

I have a custom pre-loader on my index.php as
<div id="page-mask">
<div class="mask-spinner">
<div class="rect1"></div>
<div class="rect2"></div>
<div class="rect3"></div>
<div class="rect4"></div>
<div class="rect5"></div>
</div>
</div>
and jQuery as:
$(function() {
$(window).load(function() {
$("#page-mask .mask-spinner").delay(1000).fadeOut('slow');
$("#page-mask").delay(1500).slideUp(600);
});
});
which is working perfectly when users enter the site like www.domain.com but the pre-loader also is running when user get back to Home through the navigation a well. for example if user is in Portfolio page or Contact page and what to back to home through navigation the pre-loader runs again! which is not required now.
Can you please let me know how I can run the jquery only if users coming to home page through external links?
Thanks
Similar question is answere here by me where user wanted to run a script once per visit.
You can also check document.referrer if it is of the same domain or not before running a specific script
if ( document.referrer != location.hostname )
{
//run the script here
}
you can also check if the one contains the another like
if ( document.referrer.indexOf( location.hostname ) == -1 || location.hostname.indexOf( document.referrer) == -1 )
{
//run the script here
}
this way you will be able to make out whether you are navigating within the same site or coming from outside.

DOM manupulation in meteor

I want to know abt DOM manipulation in meteor. My code goes as follows:
<template name = "studentList">
{{#each}}
<div class = "name">
Name: {{this.name}}
</div>
<div class = "age">
Age: {{this.age}}
</div>
<button class = "edit"> Edit </button>
{{/each}}
<button class = "addStudent"> Add Student </button>
</template>
Template.studentList.helpers({
studentlist:function(){
return Students.find();
}
});
Template.studentList.events({
//I am doing the DOM manupulation here based on the buttons clicked
});
I get a list of Student Info from the DB and display them in the template. Now for each student, there is an edit button. When user clicks this edit button, I want to change the "name" and "age" field of the student as text field and give an option to "save" and "cancel".
Similarly, I have an "add student" button at the end of the template. When a user clicks it, I want to display a form, where student's name and age is added and then saved.
So far, I am being able to do this, but in a very naive way by using lots of Jquery/Javascript code in the events of studentList. I read many post that says this is not the correct way.
Can anyway please tell how can this feature be achieved in meteor. Or just to some possible ways of doing it.
Help appreciated.
This is a possible way to accomplish this.
Lets try to do this step-by-step
First this is how the HTML should look.
{{#if editName}} <!-- editName template helper -->
<!-- If the Session is equal to true this part of the html will be showed -->
<input type="text" class="newName" value="{{this.name}}" />
{{else}}
<!-- this is what we show by default on the view, if user click the div, the input will be showed -->
<div class="name">Name: {{this.name}} </div>
{{/if}}
Now the JS.
The helper should look like this.
Template.studentList.helpers({tName:function(){
return Session.get("studentName" + this._id); //getting the session true or false.
}
});
And the Events.
Template.studentList.events({
'click .name' : function(event,template){
//On this event we are Setting the Session to true and holding the id of the student
return Session.set("studentName" + this._id,true)
},
'keypress .newName':function(event,template){
//Some keypress to update the value
//using http://docs.meteor.com/#/full/template_$ to get the value using meteor
var newNameStudent = template.$('.newName').val();
if(event.keyCode == 13){ //if enter lets update the value
Students.update({_id:this._id},{$set:{name:newNameStudent}})
return Session.set("studentName" + this._id,false) //setting to false the session to hide the input and show the <div>
}
},
'click .cancel':function(){
return Session.set("studentName" + this._id,false) //setting to false the session to hide the input and show the <div>
}
})
If you see there is not too much code (i guess), you get the idea how to use the sessions to do simple CRUD operations.
I made a Meteorpad of this working example, check it.

button in jquery mobile doesnt work as expected

I have a jquery mobile webpage. The page consists of a listView which is dynamically generated with jquery. In the end of this list i want to have a simple button , that when i hit it i simply alert something.
My HTML code looks like this :
<div data-role="page" id="Home">
<div data-role="content">
<ul data-role="listview" data-inset="true" class="albums">
</ul>
<form>
<button id="loadMoreAlbums">More Albums...</button>
</form>
</div>
</div>
The button as you see is hard coded under the dynamically generated listView. The jquery for the button is as simple as that :
$("#loadMoreAlbums").click(function(){
alert("yeah i am loaging more!");
});
I have 2 questions now:
1) When i load this page , the button is first loaded and i can see it for 2-3 seconds till the list is loaded and it goes in the end of the list. I dont really like that behavior , i would like that the button is "created" after the listView is already created, so that i dont see it like that in the page. However this is not a really problem , just for cosmetic reasons.
2) The real problem is that when i hit the button , instead of just alerting the simple text and nothing more , it "loads" the page again , and makes the listView vanish and only the button stay on screen. Why is it behaving like that though? Why is it trying to "load" the page again? I just want it to alert something , or do whatever my jquery tells it to do.
Change your HTML from
<button>...</button>
to
<button type="button">...</button>
By default, a <button> element has type="submit" and will submit the form when clicked.
http://www.w3.org/TR/html5/forms.html#the-button-element
$("#loadMoreAlbums").button().click(function(e){
e.preventDefault();
alert("yeah i am loaging more!");
});
The button is acting as a submit. By adding e.preventDefault(); you can supress the submit action.

Categories