I'm trying to create a div which has the initial text loading... inside of it, and can later be overlapped by new elements that are loaded into it. Here's what I'm dealing with:
<div class="results" style="position:relative;" *ngIf="showResults">
<!-- show 'loading...' before the results load, which would then overlap this text -->
<div stlye="position: absolute; z-index: -1;">Loading ...</div>
<!-- angular2 loop to asynchronously load results -->
<div *ngFor="let loc of searchLocations | async" (click)="selectLocation(loc)" class="search-result">
{{ loc.name }}, {{ loc.adminName1 }}, {{ loc.countryCode }}
</div>
</div>
But when I run this, here's what I get something like
so my 'loading...' text has it's own boundry, when i want those proceeding elements to overlap ontop of that text. How can I accomplish something like this?
You could create a boolean for the loader.
export class YourClass(){
isLoading:boolean = true;
constructor(){
// Not sure how you are implementing your GET Request
// So no point in trying to replicate that, just where ever
// you assign searchLocations to an object
// fetch data logic ends with => {
isLoading = false;
}
}
}
Then in your html you just need to add an *ngIf
<div style="position: absolute; z-index: -1;"
*ngIf="isLoading">Loading ...</div>
You could even even make the loader a component to use anywhere, or you could hook into the showResults variable, as long as you place the loading div outside the showResults div with an attribute of *ngIf="!showResults" , which might mean a bit of a style tweek.
Related
For my site, I code a button allowing to change the css of a class present in a div card. My button is located in the card-footer. Having several cards, I can't / don't think to retrieve the element with an id (as there will be X times the same ID)
In order to circumvent this system, I therefore use a parentElement which goes up to the div card
<div class="card">
<div class="card-body">
<p class="change">Change one</p>
<p class="change">Change two</p>
<p class="change">Change three</p>
</div>
<div class="card-footer">
<i id="updateData">change</i>
</div>
</div>
jQuery($ => {
$('#updateData').click(e => {
var element = e.target.parentElement.parentElement;
$('.change').css('display','none');
});
});
I would like to indicate that only the class "changes" present in my element variable and not all the classes in the page.
I don't know how to add a variable to my ".css" command, do you know how ?
Thanks in advance !
First of all since you will have multiple elements with same id that means that you should not use ID and use class instead. Id is meant to be unique. So yours id="updateData" should become class="updateData". Now you can grab all of those buttons and assign event to all of them instead of just first like you were by using id selector.
$('.updateData').click(e=> {});
Next in order to be able to use clicked element in jQuery way convert from arrow function to regular anonymous function since arrow function overrides this keyword. And now you can use jQuery to hide like
$('.updateData').click(function() {
element = $(this).parent().parent();
element.hide();
});
If you want more precise selection to hide only .change elements use
$('.updateData').click(function() {
element = $(this).parent().parent();
element.find(".change").hide();
});
Not bad, but more efficient, when you have multiple click targets, is delegation:
$(document).on("click", ".updateData", function() { ... });
Also .hide() is convenient, but rather then "change the css of a class" add a class "hidden" or something! In best case the class further describes what the element is. CSS is just on top.
I have this code in angular application
html:
<input type="button" value="Add" (click)="addItems()" />
<div id="messageContainer" style="width:200px; height:300px; overflow-y:scroll;" #scrollMe >
<div *ngFor="let i of items">
{{i}}
</div>
</div>
component.ts:
items: string[] = [];
count = 20;
#ViewChild('scrollMe') private scrollContainer: ElementRef;
ngOnInit() {
this.addInitialItems();
}
addItems() {
const currentPosition = this.scrollContainer.nativeElement.scrollTop;
this.items.unshift(this.count.toString());
this.count++;
this.scrollContainer.nativeElement.scrollTop = currentPosition;
}
addInitialItems() {
for (let i = 0; i <= this.count - 1; i++) {
this.items.unshift(i.toString());
}
// this is not working
this.scrollContainer.nativeElement.scrollTop = this.scrollContainer.nativeElement.scrollHeight;
}
Initially messageContainer div should be filled with multiple items, with div scrolled to bottom, once user click an Add button it will add an item to the top of the messegaes list and should maintain the scroll position.
Retaining scroll position is done with
const currentPosition = this.scrollContainer.nativeElement.scrollTop;
//add new item
this.scrollContainer.nativeElement.scrollTop = currentPosition;
But, initial scrolling to bottom of div is not working,
this.scrollContainer.nativeElement.scrollTop = this.scrollContainer.nativeElement.scrollHeight;
scrollTop value is 0 even after setting it,
How to get this scrolled to bottom of the div initially?
#ViewChild objects are not fully defined until the 'ngAfterViewInit' lifecycle hook. Try moving your method call to that hook.
ngAfterViewInit() {
this.addInitialItems();
}
Something else you might want to try is binding to scrollTop directly in the template, so you won't have to access the nativeElement at all.
<input type="button" value="Add" (click)="addItems()" />
<div id="messageContainer" style="width:200px; height:300px; overflow-y:scroll;" [scrollTop]="myScrollVariable">
<div *ngFor="let i of items">
{{i}}
</div>
</div>
In your component you could then simply write something like
this.myScrollVariable = currentPosition;
Instead of modifying the DOM element directly. Granted, if you wanted to initialize the scroll to the scrollHeight, you'd probably still need to use ViewChild to access the nativeElement and get that attribute (although personally, I would just initialize scrollTop to some absurdly high number like 99999999, anything greater than scrollHeight will be the same as the exact scrollHeight).
If moving the method call to ngAfterViewInit doesn't work, try setting scrollTop inside a setTimeout function. Sometimes the Angular change detector is weird about picking up changes to the native DOM and as a workaround you can escape the change outside the regular angular event loop with a timeout.
setTimeout(()=>{ this.scrollContainer.nativeElement.scrollTop = whatever; },1)
To build off the accepted answer, you can pretty elegantly set a div to start scrolling at the bottom using template variables:
<div class="overflow-scroll" #scrollContainer [scrollTop]="scrollContainer.scrollHeight">
<!-- tall/wide content -->
</div>
Basically, I want to put a inside . However, the ion-slide swipe is so sensitive, so I cannot scroll the content in . It just swipes to the next slide.
Is it possible to disable the swipe action in a certain area in ?
As shown in the picture, I want to disable the swipe action on the B area. I guess (if possible) I need to put some class in ion-scroll and/or div under it, but I could not figure it out.
This is my partial HTML code:
<ion-slide-box on-slide-changed="slideHasChanged($index)">
<ion-slide>
... // A area content
<ion-scroll direction="x" ...>
<div style="width: 5000px; height: 100px" ...>
// B area. Very wide content
</div>
</ion-scroll>
... // C area content
</ion-slide>
</ion-slide-box>
I really appreciate your help.
Here's another approach:
add these to the wide element:
<div on-touch="mouseoverWideDiv()" on-release="mouseleaveWideDiv()">
then in your controller:
$scope.mouseoverWideDiv = function() {
$ionicSlideBoxDelegate.enableSlide(false);
};
$scope.mouseleaveWideDiv = function() {
$ionicSlideBoxDelegate.enableSlide(true);
};
Here is another way of doing this:
In your controller add a function:
$scope.disableSwipe = function() {
$ionicSlideBoxDelegate.enableSlide(false);
};
In your view add the ng-init attribute on the slide-box element
<ion-slide-box ng-init="disableSwipe()">
This will disable the slide-event.
You can now use a controller function to slide to a given index like this:
Since google sent me here when i was searching for solutions using ion-slides (instead of ion-slide-box) i will leave here the solution i ended up using.
One thing first: ion-slide-box is currently deprecated, so you should use ion-slides now.
First set options variable in ion-slides element:
<ion-slides options="options">
Then inside your controller you should configure the options variable with the noSwiping options as follows:
$scope.options = {
noSwiping: true,
noSwipingClass: 'do_not_swipe',
}
And then, in an element inside your ion-slide-page add the "do_not_swipe" class to the element you want swipe to be disabled.
Taking your code as an example, you should have your html like this:
<ion-slides options="options">
<ion-slide-page>
... // A area content
<ion-scroll class='do_not_swipe' direction="x" ...>
<div style="width: 5000px; height: 100px" ...>
// B area. Very wide content
</div>
</ion-scroll>
... // C area content
</ion-slide-page>
</ion-slides>
I am new to react and I have a react component structure like:
<MainComponent>
<Button />
<Content />
</MainComponent>
Now when I click on the Button, I need to replace the existing div (say div1) of the Content component with another div (div2). Can you please tell me how to do it. Thank you.
Note: Till now, on click event I have been changing the data of the single div using state and prop. Now I got to replace the whole div with another one.
Like this.
render() {
var returnIt;
if (useDivOne) returnIt = (<div id='one'></div>);
else returnIt = (<div id='two'></div>);
return (returnItj);
}
If this is your structure:
<MainComponent>
<Button />
<Content />
</MainComponent>
and Content renders something like:
<div>
this is div 1
</div>
I would think you would need to pass a prop to Content that would tell you which div to render, then in Content's Render you manipulate the properties of Boolean logic to present a different component:
class Content extends Component {
render() {
return(
{
!this.props.RenderDiv2Bool &&
<div>
This is Div1 and it will be rendered
because RednerDiv2Bool is false.
</div>
}
{
this.props.renderDiv2Bool &&
<div>
This is Div2 and it will be rendered
because RednerDiv2Bool is true.
</div>
}
)
};
}
Not necessarily better but just another way to do it.
Hi everyone,
I am stuck at one point while rendering the data from django views.
I want to use the CSS data produced in views to be used in the template.
I did all I could do,
i) inserted the element into the RequestContext, sent it to template
ii) From here, I tried to insert that CSS style data into div tag
This is my css data in VIEW( they are "left:xx px top: xx px" positions)
coords = {'usa':['usamap.png',['635px','322px'],['592px','381px'],['541px','398px'],['115px','582px']],
'canada':['canadamap.png',['201px','336px'],['377px','565px'],['420px','600px'],['441px','648px']]
}
template = loader.get_template('polls/phasex.html')
context = RequestContext(request,{'id_list':id_list,'country':country,'coords':coords[key],'temp':temp,})
return HttpResponse(template.render(context))
On template I am trying to access the data:
<div style={{'left: '|add:coords.1.0|add:'; top: '|add:coords.1.1|add:';'}} >
<text>{{'left: '|add:coords.1.0|add:'; top: '|add:coords.1.1|add:';'}}</text>
actually i should get this when i run:
<div style = 'left: 635px; top: 322px'>
But i am getting this on the webpage:
<div style="left:" 635px;="" top:="" 322px;="">
<text>left: 635px; top: 322px;</text>
</div>
I can't understand where's the problem? The text box was for debugging. It's printing properly, but i'm not getting the same inside css styles.
Thanks in Advance
You have to place variables inside quotes, like this:
<div style="left:{{ variable }}"></div>
And not like this
<div style={{ "left: variable" }}></div>