I have two components that display on one page (first is 70% of the page, the other 30%). One in which the map is and another where I want to show the panel (info on how to get to the destination: turn left, then right, etc.)
I used agm-directions to get the panel - https://robby570.tw/Agm-Direction-Docs/source/featured/direction.html (look at Update Panel With New Query ).
I managed to create it well and, when you click a button the panel will appear with the text, but on the map component, under the map (see picture 2). This is because I put <div #myPanel></div> under the map in the first component.
I want to get that panel text on the second component. I do not know how to do this because I bind the panel in the map component [panel]="myPanel", according to the documentation above.
So is there a way I can transfer that bonded data in a different component ?
Here is the first component html:
<agm-map [zoom]="zoom" [latitude]="lat" [longitude]="lng">
...
<agm-direction
[origin]="origin"
[destination]="destination"
[travelMode]="transitOptions"
[visible]="show"
[renderOptions]="renderOptions"
[markerOptions]="markerOptions"
[panel]="myPanel" <!-- THIS IS IMPORTANT FOR INFO -->
>
</agm-direction>
...
</agm-map>
<div #myPanel></div>
The second component is just some generic html.
TLDR: How can I get <div #myPanel></div> to work in a different component when I bind [panel]="myPanel" in agm-direction.
Managed to get the value thanks to
#ViewChild("myPanel", {static: false}) myPanel;
Then, in a function that activates when the button is clicked:
let _this = this;
setTimeout(function() {
console.log(_this.myPanel);
if(_this.myPanel != undefined){
let ivan = _this.myPanel;
console.log("test myPath", ivan);
//console.log("Test", JSON.stringify(this.myPanel.nativeElement.innerHTML));
console.log(_this.myPanel.nativeElement.innerHTML); //THIS IS THE ANSWER
}
}, 500);
Related
I have a question. I have these code snippets implemented in my class component and while it is working for the most part, I need to actual display the most recent rendered component on top of the list instead of appended to the bottom of the list. How can I do that easily?
Code snippets:
state = {
formCount: 0
}
//click event for button
onAddClicked = () => {
this.setState({formCount: this.state.formCount + 1});
}
//render components based on count
{ [...Array(this.state.formCount)].map((_, i) => <Form key={i}/>)}
So I have form count in state and on clicking on a button, it will increment the count and then depending on the count, it will render the same component whenever I click on the button.
However, right now it is adding the new components to the bottom instead of the top, how do I render the new component that gets rendered when clicking the button to the top of the list instead?
You could use .reverse() along with .keys():
[...Array(this.state.formCount).keys()].reverse().map((i) => <Form key={i}/>)
So you want to render the components in reverse order? With the most "recent" ones at the top? A simple way would be to .reverse() the array of components
Currently, I'm trying to add dynamic tabs which have child component, Within the child component, there are several ngx-smart-modal models. I'm able to create dynamic tabs with a close button on it. The issue arises when there are more than one tabs.
Issue
Instance 1: I'm on the first dynamically created tab and I try to click on the model present in a custom component, Model pops up in the last tab of the dynamically created tab. (With the last component details and not desired component details)
Instance 2: If it has only a single dynamically created a model then it works perfectly fine.
Code
HTML
<p-tabPanel [header]="doc.docName" leftIcon="ui-icon-web-asset" *ngFor="let doc of docProps; let i = index" [selected]="true" (onClose)="closeDocProps(doc)" [closable]="true">
<app-child-component [docId]="doc.docId" ></app-child-component>
</p-tabPanel>
app-child-component has several models present in it.
app-child-component (HTML)
<ngx-smart-modal #myModal identifier="myModal">
<h1>Title</h1>
<p>Some stuff...</p>
<button (click)="myModal.close()">Close</button>
</ngx-smart-modal>
TS (Parent component)
on document click operation in the parent component
this.docProps.push({
docId: document.id,
docName : document.docTitle
});
this.changeDetectorRef.detectChanges();
this.activeIndexNumber = this.docProps.length; // to open up the last tab clicked.
also, I'm changing the tab index number with the change of the tab.
onTabChange(event) {
this.changeDetectorRef.detectChanges();
this.activeIndexNumber = event.index;
}
Is there something that I'm doing wrong? Suggestions are highly welcomed.
stackblitz:
https://stackblitz.com/edit/angular-uy3kf5
This is my first foray into using VueJS so any pointers or better ways to tackle the problem are much appreciated. Here is where I am at http://codepen.io/anon/pen/ezBwJw
I'm building a pricing plan table where users can browse 4 different payment plans. The table is interactive, users have access to radio buttons which toggle between viewing prices in GBP & USD, as well as viewing the cost if they pay per year or per month. All of this is working, but the issue I now have is that I want to pass some data to a 'summary' section which will be presented to the user before they choose to sign up. The one piece of data I am struggling to pass to the summary table is the price.
When a user selects a plan I want the price that is currently showing in that plan to show in the 'Total to pay now' field. In jQuery I'd do something like this (simplified version of Codepen)...
<div>
<h1>Basic</h1>
<div class="price">7</div>
Select this plan
</div>
<h2 class="total"></h2>
$('.select-plan').on('click', function() {
var planName = $(this).parent().find('.price').text();
$('.total').text(planName);
});
I'm currently using v-if to show the different prices for the respective plans, so I'm lost as to how I would get the item that is currently in view and pass that to the summary field.
JQuery Way
One option is to create watchers that call an updatePrice method whenever a variable that effects the current price changes. For example:
watch: {
'activePlan': 'updatePrice',
'currency': 'updatePrice',
'frequency': 'updatePrice'
},
... and then in methods:
updatePrice: function() {
this.price = $('.price.' + this.activePlan).text();
}
Here is a fork of your CodePen with that change. Notice that I've added the plan name as a class so that the JQuery selector can find the correct element.
Component Way (do this!)
Personally, I think it you'd be better off taking a totally different approach. I would make a custom component for plans. This will let you encapsulates all the functionality you require in a reusable and manageable way.
For example, you could make a component like this
Vue.component('plan-component', {
template: '#plan-component',
props: ['frequency', 'name', 'priceYearly', 'priceMonthly'],
computed: {
'price': function() {
// Move the logic for determining the price into the component
if (this.frequency === 'year') {
return this.priceYearly;
} else {
return this.priceMonthly;
}
}
},
methods: {
makeActivePlan() {
// We dispatch an event setting this to become the active plan
// A parent component or the Vue instance would need to listen
// to this event and act accordingly when it occurs
this.$dispatch('set-active-plan', this);
}
}
});
Components are related to an HTML template. So in your HTML you would need a template tag with id plan-component.
<template id="plan-component">
<h1>{{ name }}</h1>
<div>
<span>{{ price }}</span>
</div>
<a class="select-plan" v-on:click="makeActivePlan($event)" href="#">Select this plan</a>
</template>
Thus each plan gets its own component which handles the data related to that plan. And instead of repeating the same HTML for each plan in a table, you can just use your new custom <plan-component>, and bind the appropriate values to each plan (these are the props).
I've implemented this more fully as a JSFiddle here. I got rid of USB vs GBP currency because I wanted to keep things simple. I hope this gives you some idea about how to tackle your problem!
I have an input in my view:
<label for="map-latitude_input">Latitude {{mapLatitudeInput}}</label>
<input
type="text"
placeholder="00.000"
[(ngModel)]="mapLatitudeInput"
[ngFormControl]="newListingForm.find('mapLatitudeInput')"
id="map-latitude_input"
class="transparent">
and inside my controller I am listening to map drag event from google maps api. On drag I want to update value inside my input and in its associated label. At the moment this looks like this:
//Update coordinates on map drag
map.addListener('drag', (event) => {
this.mapLatitudeInput = map.getCenter().lat();
console.log(this.mapLatitudeInput);
});
Now when I drag a map console keeps outputting correct value as I move it around, however in my view it stays exactly the same. What I also noticed is that if I drag map around and than do some action like select an option in select menu within same form that my input is in, it updates mapLatitudeInput to correct value, i'm not sure why this happens, but thought I'd mention it.
It's perhaps due to ZoneJS. This question could give you some hints: View is not updated on change in Angular2.
From where do you get your map instance. If it's instantiated outside a zone, Angular2 won't be able to detect updates of the mapLatitudeInput attribute.
You could try something like that:
export class MapComponent {
constructor(ngZone:NgZone) {
this.ngZone = ngZone;
}
map.addListener('drag', (event) => {
this.ngZone.run(() =>
this.mapLatitudeInput = map.getCenter().lat();
console.log(this.mapLatitudeInput);
});
});
This question could be also related to your problem: Angular2 child property change not firing update on bound property.
Hope it helps you,
Thierry
Left i have a list with all names. I select one name and click on a button 'add' (to the right list). Also i want to 'remove' items form the right list, back to the left list.
Someone an example?
$('#buttonid').click(function(){
var selecteditem = $('#listID option:selected').html();
$('#targetListId').append(selecteditem );
}
vice-vers for second question.
http://dev.sencha.com/deploy/dev/examples/dd/dnd_grid_to_grid.html
is an example to study
Is this what you're after?
I dont have example handy, however if you look at http://dev.sencha.com/deploy/dev/examples/grid/array-grid.html you can see grid example, focus on tpl to generate action (sell, buy) images/buttons, in listView you can also use tpl, change actions to remove (maybe only gray out if want to restore)...
But add action should be easier in EditGridPanel, If you want to still use listView I will suggest to have ad button on top or bottom toolbar, execute formPanel for data entry, when submit just add to listView.store
Dont forget to build communication to DB if needed in add and remove actions
That's really-really simple to do.
Just grab the selected record(s), remove from the store of left list, and add to the store of right list:
var left = // define your GridPanel or ListView
var right = // define your GridPanel or ListView
new Ext.Button({
text: "Move right ->",
handler: function() {
// when using GridPanel
var records = left.getSelectionModel().getSelections();
// when using ListView
var records = left.getSelectedRecords();
left.getStore().remove(records);
right.getStore().add(records);
}
});
I'm sure you can figure out how to implement the "Move left" button.
Note: Always first remove record from one store before adding to another as ExtJS currently doesn't support having one record in multiple stores. If you do it the other way around, strange things will happen.