angular 7 add html with binding after view init - javascript

I have an issue here,
i want to add to my html this code
<dx-report-viewer [reportUrl]="reportUrl" height="800px">
<dxrv-request-options [invokeAction]="invokeAction" [host]="hostUrl">
</dxrv-request-options>
</dx-report-viewer>
but only after getting params from
self.queryParams = self.route.queryParams.subscribe(params => {
if (params['id']) {
self.ReportId = params['id']; // (+) converts string 'id' to a number
console.log(self.ReportId);
self.reportUrl += "ReportId=" + self.ReportId;
}
Because otherwise the url will be wrong ...
but i can't get it work is it because dx-report is a directive from an external library ?
If someone can help would be great !!

Create a property and default it to false:
paramsAdded: boolean = false;
Wrap the report element in a div using *ngIf:
<div *ngIf="paramsAdded">
<dx-report-viewer [reportUrl]="reportUrl" height="800px">
<dxrv-request-options [invokeAction]="invokeAction" [host]="hostUrl">
</dxrv-request-options>
</dx-report-viewer>
</div>
When the parameters are available set the property to true to render the report element(s):
self.queryParams = self.route.queryParams.subscribe(params => {
if (params['id']) {
self.ReportId = params['id']; // (+) converts string 'id' to a number
console.log(self.ReportId);
self.reportUrl += "ReportId=" + self.ReportId;
self.paramsAdded = true;
}

Related

How to create an onclick function that retrieves the object ID on the HTML and attach the ID onto the API to be fetched and used?

i'm a beginner developer in javascript trying to make a website to impress recruiters. I've succesfully retrieve information from my API and used it on my website which took me ages to figure out. Now the next problem is how do i make an onclick event that gets the ID i hardcoded onto the specific movie poster on my HTML, to be used in javascript to change the API address and get the data for that specific movie.
Notes: i have a modal onclick to host all the movie data on that modal.
My Javascript and HTML is below.
HTML
<div class="poster" onclick="toggleModal(); getimdbID()" id="tt4154796">
<div id="imdbID">tt4154796</div>
<img
src="https://m.media-amazon.com/images/M/MV5BMTc5MDE2ODcwNV5BMl5BanBnXkFtZTgwMzI2NzQ2NzM#._V1_SX300.jpg"
alt=""
class="poster__img"
/>
<p class="movie__title">Avengers: Endgame</p>
<p class="year">2019</p>
</div>
Javascript
async function getMovie() {
const movies = await fetch(`https://www.omdbapi.com/?i=tt4154796&apikey=4148fa0f`);
const movieData = await movies.json();
const { Title, Year, Runtime, Genre, Director, Actors, Plot, Awards, Poster, Metascore, imdbRating, imdbVotes, BoxOffice, } = movieData
document.getElementById('title').textContent = Title;
document.getElementById('year').textContent = Year;
document.getElementById('genre').textContent = Genre;
document.getElementById('runtime').textContent = Runtime;
document.getElementById('plot').textContent = Plot;
document.getElementById('director').textContent = Director;
document.getElementById('actors').textContent = Actors;
document.getElementById('awards').textContent = Awards;
document.getElementById('metascore').textContent = Metascore;
document.getElementById('boxoffice').textContent = BoxOffice;
document.getElementById('imdbRating').textContent = imdbRating;
document.getElementById('imdbVotes').textContent = imdbVotes;
document.getElementById('poster').src = Poster;
}
getMovie()
// ToggleModal
let isModalOpen = false;
function toggleModal() {
if(isModalOpen) {
isModalOpen = false;
return document.body.classList.remove("modal--open");
}
isModalOpen = true;
document.body.classList += " modal--open";
}
I've tried to create a function onclick to get the value of the ID onclick but that didn't work.
function getimdbID() {
let x = document.querySelector("#imdbID").value
console.log(x)
}
Im guessing you want your function to return the "tt4154796" thats contained within the div. If this is the case you'll want to use document.querySelector("#imdbID").innerText.
Since using .value is typically used to retrieve or change values entered into input fields.

Loading page info into array, and cycling page info as URLs

I;ve built a CMS that allows users to build static pages of images and text content solely for displaying on television screens throughout our building. I've completed this to the point of viewing the display with it's pages but only if I call it explicitly in the url. The problem is, I want to load by display which is stored in the URL.
For instance, the url now if you click on Display 3 is http://local.CMSTest.com/showDisplay.php?display=3
and this calls a function using 3 as the display ID that grabs all pages with that display ID. This works, but in my html where I throw a foreach in there, it loads both pages associated with that display into a crammed page, half and half. So I know it's working but I need to store these pages into an array for javascript as well I believe.
I'm thinking there may be a way where I can load it with the first page on default and append it to the url like http://local.CMSTest.com/showDisplay.php?display=3&page_id = 2 and then after the time is up, it can go to the next one and change the URL http://local.CMSTest.com/showDisplay.php?display=3&page_id = 3
So the PHP and HTML is working at this moment:
<div class="row top">
<?php include 'banner.php'?>
</div>
<div class="row middle" style="background-image: url(<?php echo $showDisplays['background_img']?>);">
<div class="col-lg-12">
<?if($showDisplays['panel_type_id'] == 1){?>
<div class="fullContent" style=" height: 100%; ">
<?php echo $showDisplays['content']?>
</div>
<?}?>
</div>
</div>
<div class="row bottom">
<?php include 'ticker.php';?>
</div>
<?php }?>
I want to try some javascript like this that will take each page from the array, replacing the following URLs with page IDs from my previous array. How can I do this properly?
<script type="text/javascript">
var Dash = {
nextIndex: 0,
dashboards: [
{url: "http://www.google.com", time: 5},
{url: "http://www.yahoo.com", time: 10},
{url: "http://www.stackoverflow.com", time: 15}
],
display: function()
{
var dashboard = Dash.dashboards[Dash.nextIndex];
frames["displayArea"].location.href = dashboard.url;
Dash.nextIndex = (Dash.nextIndex + 1) % Dash.dashboards.length;
setTimeout(Dash.display, dashboard.time * 1000);
}
};
window.onload = Dash.display;
</script>
UPDATE:
Current array
Array ( [pageID] => 104 [page_type_id] => 1 [display_id] => 3 [slide_order] => [active] => 1 [background_img] => [panel_id] => 96 [panel_type_id] => 1 [page_id] => 104 [cont_id] => 148 [contID] => 148 [content] =>This is full content)
First you would need to access your php array from javascript and you can do that by using php's json_encode which will convert the array to a JSON object.
Then you can use URL search params to alter the query parameters for the next URL which you can call. See the below example
function setDisplay() {
let params = new URL(document.location).searchParams;
let pageID = params.get("pageID");
let disply = params.get("display");
// set the html based on pageID and display
}
function getNextURL() {
// encode your php array to json
// let obj = <?php echo json_encode($myArray); ?>;
// probably what obj will look like after above line
// this is just for this example, you should use the line commented out above
var obj = {
"pageID": 104,
"page_type_id": 1,
"display_id": 3,
}
let params = new URL(document.location).searchParams;
params.set("pageID", obj.pageID);
params.set("display", obj.display_id);
let url = window.location.href.split('?')[0];
let nextURL = url + "?" + params.toString();
console.log(nextURL);
return nextURL
}
getNextURL();
You would need to
parse the frames.displayArea.location.href for its query parameters.
assign to Dash.nextIndex either (params.page_id + 1) % Dash.dashboards.length because the page_id is the currently diplaying page and we want the next page... or 0 if params.page_id is undefined.
build your URL from dashboard.url appending the display_id and page_id parameters.
For cleanliness, I recommend creating a var called newURL since we need to build a custom string.
display: function() {
// step 1
let queryString = frames.displayArea.location.href.split("?")[1];
let paramArr = queryString.split("&");
let params = {};
paramArr.forEach((param) => {
let [name, value] = param.split("=");
params[name] = value;
})
console.log("params: ", params)
// step 2
Dash.nextIndex = (params.page_id)
? (params.page_id + 1) % Dash.dashboards.length
: 0;
var dashboard = Dash.dashboards[Dash.nextIndex];
// step 3
let newURL = dashboard.url + "?display_id=" + params.display_id
+ "&page_id=" + Dash.nextIndex;
// Unrelated nit: bracket access IMHO should only be used when specifying a
// property by the string value contained in a variable, or when the
// property name would be an invalid javascript variable name (starting
// with a number, including spaces, etc)
frames.displayArea.location.href = newURL;
setTimeout(Dash.display, dashboard.time * 1000);
}

TagHelper child tag unescaped attribute value

No matter how I try to skin it, I can't get the output from my TagHelper for the Google Analytics onclick attribute to not be escaped. Specifically the single quotes.
TagBuilder listTag = new TagBuilder("ul");
listTag.AddCssClass(ListClass);
foreach (Category category in Links)
{
bool isSelectedCategory = category.PathValue == ViewContext.RouteData.Values["controller"].ToString()
|| (category.PathValue == "home"
&& ViewContext.RouteData.Values["controller"].ToString().ToLowerInvariant() == "home"
&& ViewContext.RouteData.Values["action"].ToString().ToLowerInvariant() == "index");
TagBuilder listItemTag = new TagBuilder("li");
listItemTag.AddCssClass(ListItemClass);
if (isSelectedCategory) { listItemTag.AddCssClass(ListItemActiveClass); }
TagBuilder linkTag = new TagBuilder("a");
linkTag.InnerHtml.Append(category.Name);
linkTag.AddCssClass(LinkClass);
if (isSelectedCategory) { linkTag.AddCssClass(LinkActiveClass); }
linkTag.Attributes["href"] = urlHelper.RouteUrl("default", new
{
controller = category.PathValue,
action = "index",
topicPathString = category.DefaultTopic?.PathValue,
articlePathString = category.DefaultTopic?.DefaultArticle?.PathValue
});
if (EnableGoogleAnalytics)
{
string gaOnClick = $"ga('send', 'event', 'Navbar', 'Links', '{category.Name}');";
linkTag.MergeAttribute("onclick", gaOnClick);
}
listItemTag.InnerHtml.AppendHtml(linkTag);
listTag.InnerHtml.AppendHtml(listItemTag);
}
output.Content.SetHtmlContent(listTag);
base.Process(context, output);
Outputs onclick="ga'send', 'event', 'Navbar', 'Links', 'Guides');".
What I need is gaOnClick="ga('send', 'event', 'Navbar', 'Links', 'Guides');".
Is this possible with nested tag elements, or do I need to approach it in a different way?
Having spent most of the morning trying to find a solution, it's only fitting that I stumble across one shortly after posting!
Based on Creating html helpers without encoding, but with an added utility class based on Convert IHtmlContent/TagBuilder to string in C#, has solved the problem.
HtmlString decodedLinkTag = new HtmlString(
System.Net.WebUtility.HtmlDecode(
Utility.TagBuilderToString(linkTag)));
listItemTag.InnerHtml.AppendHtml(decodedLinkTag);

I want to compare that old and new value are same or not for input textbox in angularjs?

I have two input box in angularjs html structure.
When I click on my button or a tag I want my textbox old and new value in angularjs or I want to compare that old and new value are same or not.
I'm using angular 1.4.7.
<input phone-input ng-show="mode == 'edit'" ng-model="leader.work"/>
<input phone-input ng-show="mode == 'edit'" ng-model="leader.mobile"/>
<a ng-show="mode == 'edit'" ng-click="mode = null;save_profile(leader)" style="cursor: pointer" title="Save">Save</a>
$scope.save_profile = function (leader) {
/* How to get/compare both text box old and new value are same or not*/
};
try this
function TodoCrtl($scope) {
$scope.newValue = 'Initial Text';
$scope.save_profile = function(newvalue, oldvalue) {
//Here you can access old value and new value from scope.
$scope.new = 'New Value :' + $scope.newValue;
$scope.old = 'Old Value :' + $scope.oldValue;
//After accessing update the scope old value to new value with function parameters
$scope.newValue = newvalue;
$scope.oldValue = newvalue;
};
$scope.changeValue = function() {
$scope.newValue = 'Dynamic Change';
};
}
<!DOCTYPE html>
<html ng-app>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.min.js"></script>
<meta charset=utf-8 />
<title>ng-click</title>
</head>
<body>
<div ng-controller="TodoCrtl">
<input type=text ng-model="newValue" ng-init="oldValue=newValue">
<button ng-click="save_profile(newValue,oldValue)">Save</button>
<div>{{new}}</div>
<div>{{old}}</div>
<br>
<button ng-click="changeValue()">Change Dynamic</button>
</div>
</body>
</html>
The simplest possible approach which will work in all occasions is to make a copy of the leader when you load it and compare current leader with the copy you made when you press the button.
function TodoCtrl($scope) {
// initialization
var originalLeader = null;
$scope.leader = null;
$scope.mode = 'edit';
// this is where you get your leader data, in my example
// I simply set it to demo data but you can load the
// data using AJAX for example
var loadLeader = function() {
var leaderData = {
mobile: '000',
work: '111'
};
originalLeader = angular.copy(leaderData);
$scope.leader = leaderData;
}
// loadLeader will be invoked on page load
loadLeader();
$scope.save_profile = function (leader) {
// you have access to your original data and current data,
// you can compare them and do whatever you want with them
console.log('originalLeader ', originalLeader);
console.log('leader ', leader);
// for example
if ( leader.mobile != originalLeader.mobile ) {
alert('Mobile has changed from ' + originalLeader.mobile + ' to ' + leader.mobile);
}
};
}
Some answers suggested to use $scope.$watch, you can implement your solution using that but you need to be careful as the $scope.$watch callback will be invoked on each change. To illustrate what I mean let's add something like this to your code:
$scope.$watch('leader.mobile', function(newVal,oldVal) {
console.log('newVal ', newVal);
console.log('oldVal ', oldVal);
});
Let the leader.mobile be 000 at the init time.
You type 1 to the text box, now leader.mobile is 0001, the callback function will be invoked and the log will be:
newVal 0001
oldVal 000
Now you press backspace and delete 1 you previously typed, the leader.mobile variable is now 000 and the log is:
newVal 000
oldVal 0001
Your current data is same as starting data but the $scope.$watch was invoked twice and is difficult to determine if data has really changed or not. You would need to implement some additional code for that, something like this:
// be careful about this, you need to set to null if you reload the data
var originalMobile = null;
$scope.$watch('leader.mobile', function(newVal,oldVal) {
// set originalMobile to value only if this is first
// invocation of the watch callback, ie. if originalMobile
// was not set yet
if ( originalMobile == null ) {
originalMobile = oldVal;
}
});
$scope.save_profile = function(leader) {
if ( leader.mobile != originalMobile ) {
// ...
}
}
You can use the $watch function. The link below will show you how to implement it. You can get an old and new value with it.
How do I use $scope.$watch and $scope.$apply in AngularJS?

How to write VISIBILITY if-else condition in ANGULARJS?

How to Write Condition on data which is fetching from Json to Angularjs?
Example : if user FIRM NAME exists Show else if user FULL NAME exists Show else Show REALNAME
I have a working Example of fetching data
at line number 25 <h3 class="moduletitle">Name : {{ module.realname }}</h3>
Please See that in PLUNKER
I hope i will get the working code update along with PLUNKER
I can suggest you have a function that returns the entity in which you want to display. Then using ng-show / ng-hide to display/hide the things you want.
Example:
function pseudoDecide(){
var displaythis = "";
if(/*boolean exp*/){ displaythis = "firm" }
else if(/*boolean exp*/) { displaythis = "full" }
else(/*boolean exp*/) { displaythis = "real" }
return displaythis;
}
Then <div ng-show="{{psedoDecide() === 'firm'}}>" etc etc, something like that.
With AngularJS 1.1.5+, you can use the ternary operator inside an expression. In your case, I believe you want something like:
<h3 class="moduletitle">Name : {{ module.firmname ? module.firmname : (module.fullname ? module.fullname : module.realname)) }}</h3>
If you don't want a nested ternary in your template, you could also go this route:
Somewhere in your controller:
$scope.pickName = function (module) {
var val;
if (module.firm_name) {
val = module.firm_name;
} else if (module.full_name) {
val = module.full_name;
} else {
val = module.realname;
}
return val;
};
And in your template:
<h3 class="moduletitle">Name : <span ng-bind="pickName(module)"></span></h3>

Categories