AJAX causes inconsistent renderings - javascript

I am using Angular2 and have a template which uses ngFor to display a div DIV1 if a flag is true else to display another div DIV2.
This flag is retrieved with AJAX from the server in the ngOnInit() method of the component.
The problem is that if the flag is initialized to true bue retrieved as false then when the page is rendered initially DIV1 is rendered and very fast it disappears and DIV2 is displayed. This is annoying and the user can notice the temporary inconsistent view rendering (especially if the AJAX call is slow).
It is a simple case and therefore I don't provide an example since here I don't want to test if the aforementioned functionality works.
The question is how should I treat this and similar cases so that only the correct divs should be displayed?

You can add another flag that indicates if the value was already retrieved and wrap your content in an *ngIf or use hidden
<div *ngIf="realValueRetrieved">
<!-- <div [hidden]="realValueRetrieved"> -->
<div *ngIf="flag">
</div>
</div>
and set realValueRetrieved to true if it is false, otherwise don't change it.
Actually there are unlimited ways to handle that and it's up to you what you actually want. Display a spinner, display nothing, use an animation when the value arrives and the content is revealed, ....

Related

Load Angular 2 component to area

I have a website, where a settings dialog should be loaded in a specific are, when clicked on a button.
The settings dialog is a component which loads data from REST endpoints.
I don't want to insert the component and just hide it, since I want to save resources.
What's the correct Angular 2 way to do this?
You can use ngIf for that kind of purpose, it will insert element only if the condition is true
<div *ngIf="condition">
<!-- Content present in DOM only if condition == true -->
</div>
This way your data won't be loaded at runtime, but when the component is inserted (=> when the condition becomes true).
EDIT : Load based on shouldBeLoaded, then show / hide based on shouldBeDisplayed ; once shouldBeLoaded is set to true, its value should not change
<component *ngIf="shouldBeLoaded" *ngShow="shouldBeDisplayed">
</component>
There is 2 ways to do that:
<div [hidden]="condition"> content </div> it will create content, but hide it when condition is true
<div *ngIf="condition"> content </div> it will create content when condition is true, otherwise it won't

How to hide/show adf component automatically

Hi I want to hide an adf component automatically.I have a selectOneChoice that contain some number (from 1 to 12).
Example when I select 2, it show's two field automatically without clicking any button..
i used this function to hide a declared componenet but just when i click a button..
function enableField(actionEvent) {
var nameInputText = actionEvent.getSource().findComponent("soc1");
nameInputText.setProperty("visible", true);
actionEvent.cancel();
}
i set the componement "soc1" visible = true than through the javascript function i change it..
SO the probleme here is how to read the number from the selectonechoise and how to set the component visible directly without clicking any button.
Actually Rendered won't do what you want. You want to use Visible property instead. Rendered causes the actual markup for the component not to be rendered on the page, so a Partial Refresh will not cause it to appear. Rendered is reserved, usually, to hide items that are secure. We set rendered property to false on the item(s), but then refresh the parent containing component - usually a layout manager - then it works. So either refresh the layout manager that contains the item or use Visible. I demonstrated this exact use case last week in class and it works as described.
Basicaly, you don't need javascript solution or any programming to achieve this.
You should set attributes rendered(this way component won't be rendered at the page at all) and partialTriggers that points to selectOneChoice component for components you want to show or hide. Also you have to set autoSubmit="true" for your selectOneChoice component.
<af:selectOneChoice id="soc1" autoSubmit="true" .../>
<af:panelGroupLayout id="plg1" partialTriggers="soc1">
<af:outputText id="ot1" rendered="#{bindings.lov.inputValue le 1}" inputValue="text1"/>
</af:panelGroupLayout>
Note: its not working code, just a sample
It will work following way, on valueChange event at selectOneChoice component value is submitted and partialRefresh fires for components that have it in partialTriggers specified. And rendered attribute will either render or remove component depending on it's EL expression. Components that should be managed wrapped into another component to make sure PPR reach it when they ain't rendered.

fullcalendar and bootstrap visible-print

I am trying to include two fullcalendars on one page. The first should only be visible on screen and the second should only be visible on print.
<div class="hidden-print">
<h1>This is hidden in print</h1>
<div id="calendar"></div>
</div>
<div class="visible-print">
<h1>This is visible in print</h1>
<div id="calendar2"></div>
</div>
But when I print the page, the second calendar is not visible and if I check the source the contents of the second calendar is not rendered. I created a plunk to demonstrate it: http://run.plnkr.co/plunks/RQx1Up2Y1jbzs9Ixm2aX/
(code: http://plnkr.co/edit/RQx1Up2Y1jbzs9Ixm2aX)
It makes sense since this is expected behaviour according to the fullcalendar docs:
"Notice that this example calls render whenever any tab is shown, not just the tab that the calendar is within. This is okay, because FullCalendar is smart enough to only render calendars that are visible to the user." http://fullcalendar.io/docs/display/render/
Is it somehow possible to override this behaviour and put a fullcalendar within a "visible-print"-class anyway?
This isn't a great answer and I would love to see a better one. But it should work if you have a fairly static fullcalendar.
Essentially, start with the FC outside of the visible-print, render it, then move it in.
$('#calendar2').fullCalendar({});
$('#calendar2').fullCalendar('render');
$('#calendar2').appendTo(".visible-print");
Plunker
Note that every time you make a change to it, it will need to be moved out and rendered again.

Looking for example logic to pull a DOM value into a Custom Script Adobe DTM data element

Actual Question:
Does anyone have any basic example logic of how to pull the value of a DOM element in to a custom script data element?
Background:
I'm trying to build some custom data elements in Adobe Dynamic Tag Management (DTM). I want to capture specific sections of my breadcrumb in to elements - e.g. Given breadcrumb trail Home >> Category 1 >> Category 4 >> Page 1, I would want X = Category 1, Y = Category 4, Z = Page 1
Unfortunately, the anchors in the breadcrumbs do not use consistent identifiers, so I need conditional logic in order to select them. Example: When I'm on the Category 1 landing page, the category's element has ID "Current" but otherwise it has the id "L1Link" - therefore I would want the following logic:
if(#L1Link exists)
X = #L1Link
else
X = #Current
Unfortunately, I'm not sure how to select a DOM element in my Custom Function. I don't think _satellite.$data is what I want (I don't want data, I just want the text of the hyperlink). I tried using cssQuery, but I don't really have a callback to pass anything back to (and contrary to the documentation, it seems to get very upset if I don't have a callback).
Go to Rules > Data Elements and create a Data Element with the following:
Name: category_1
Type: Custom Script
Then click on "Open Editor" and add the following:
var x = document.getElementById('L1Link')||document.getElementById('Current');
if (x) return x.innerText||x.textContent;
else return '';
This will first look for #L1Link and failing that, will look for #Current. If it is found, it will return the link's text.
Based on your post, set Remember this value for as "Pageview"
Save Changes
Next, navigate to
Rules > Page Load Rules
If you don't already have a general page load rule setup that is set to pop on every page load, create one and name it something like "every page".
In the Conditions > Criteria choose Data:Custom from the dropdown and then click Add Criteria
Then add the following in the Custom textarea:
return _satellite.getVar('category_1')||true;
This condition will explicitly invoke the data element to ensure that it gets invoked, because DTM is moody and sometimes may not evaluate data elements. It falls back to true to ensure the condition always returns true, so that the condition will not cause the rule to fail to execute.
Then in the Adobe Analytics section of the rule, choose whatever eVar and/or prop you want to set (e.g. prop1) and set as %category_1%
Save Rule
You will want to repeat this process for each item you are looking to make a data element to pop an Adobe Analytics variable for, though you only need one rule, and one condition for all of them. The condition code would be:
_satellite.getVar('category_1');
_satellite.getVar('category_2');
//etc..
return true;
NOTE: DTM has some caveats of order of execution vs. load/timing of things. This is in part due to the nature of async loading but there is also a mislabeling of order of execution in the documention (see my Issue #2) that Adobe has acknowledged. Basically, you may need to play with the Trigger rule at setting in the page load rule vs. what you set the "Load Adobe Analytics page code at" dropdown to in the Adobe Analytics Tool General config section and hope for the best. I setup a test page to verify all this in my post and pretty much anything I chose in either one worked, but then my test page had virtually nothing on it except the DTM page code and a link.
Very interesting this post, always your explanations are very clear #crayon. By the way, you know how call data elements into script on Thirth party tags (HTML non sequential)? I'm trying to do and honestly, I miss.
When use a Java script non sequential I can take Data element, but my intention is pass Data Element value into image pixel, like:
<img src="//t.qservz.com/tr.aspx?campaign=169779d3852b32ce8b1a1724dbf5217d&type=ppl&retmode=4&orderid=[[orderid]]&totalprice=[[totalprice]]&level=**ValueDataElement**&redirect_url=[[URL]]" border="0" width="1" height="1"><img style="border: 0;" width="1" height="1" src="https://tags.qservz.com/pixel?id=1901&type=img" />
If you can help me, I'm grateful,
JuliĆ .

Can I cache an empty form template as a second page in browser?

can I cache an empty form template as a second page in browser cache
so that when you click "create event" button on first page it immediately
opens empty form template without having a need to download the template
from the server as it's cached.
Just like CREATE EVENT button in Google calendar; which let's you to switch between calendar and new event form template.
Well, you can either use Javascript for building the new page from scratch when the respective action is invoked (probably quite tedious) or you can use an invisible section (e.g., a separate <div>) of the HTML page (style = display: none) and make it visible by changing its class to a visible style and making the original page invisible (change its style to display: none).
One way to accomplish this would be to load your second view into a hidden container. You can hide it with a simple CSS display property toggle, like this:
<div id="mySecondView" style="display: none;">
<!-- content of second view here -->
</div>
And on button click you can do this to unhide it:
With jQuery:
$('#mySecondView').show();
or
$('#mySecondView').fadeIn();
Without jQuery:
document.getElementById('mySecondView').style.display = '';
Of course you'll have to position the second view via CSS as you want it, otherwise it'll just pop up in some weird place that won't make sense.

Categories