I use GMAP3 plugin to render driving direction. And would like to add a clear button so it can be clear but I haven't been able to find the right syntax in GMAP3. Here is the my js code, modified from the sample in gmap3.net. I have markers plotted already and latlng are retreived from plotted markers instead of from clicks position on the map.
function removePath() {
$(mapID).gmap3({
action: 'clear',
name: 'directionRenderer'
// tag: 'path' // works too with tag instead of name
});
function updatePath() {
$(mapID).gmap3({
action: 'getRoute',
options: {
origin: m1.getPosition(),
destination: m2.getPosition(),
travelMode: google.maps.DirectionsTravelMode.DRIVING
},
callback: function (results) {
if (!results) return;
$(mapID).gmap3({
action: 'setDirections',
directions:results,
});
}
});
};
function updateDirection(mm) { // Directions between m1 and m2
var mmID = $(mm).prop('id');
...
if (mmID == 'clearDirection') {
...
removePath();
return;
};
...
if (m1 && m2) { updatePath(); };
};
function initmap() {
$(mapID).gmap3(
{
action: 'init',
options: defaultMapOptions
},
// add direction renderer to configure options (else, automatically created with default options)
{ action: 'addDirectionsRenderer',
preserveViewport: true,
markerOptions: { visible: false },
options: {draggable:true},
tag: 'path'
},
// add a direction panel
{ action: 'setDirectionsPanel',
id: 'directions'
}
);
};
A is in place in HTML documents as directions panel. It has a a wrapper which is hidden when the route is cleared by using jquery css property change. The wrapper div's display property is changed back to 'block' whenever value is assigned to either m1 or m2.
<body>
...
<div id="direction_container" class="shadowSE">
....
<div id="directions"></div>
....
</div>
</body>
Its absolutely working fine.
$map.gmap3({ action: 'clear', name: 'directionRenderer' });
*Instructions-
If you later draw the route then you must write below code otherwise directions not display.
$map.gmap3({ action: 'addDirectionsRenderer', preserveViewport: true,
markerOptions: { visible: false} },
{ action: 'setDirectionsPanel', id: 'directions' });
Thanks...
Use this:
$(mapID).gmap3({action:"clear", name:"directionRenderer"});
The chosen answer above didn't work for me. I'm unsure if it's version related, but the solution I'm using is more simple:
$(your-selector).gmap3({clear: {}});
Afterwards, you can draw a new route without reconnecting the directions rendered with the map.
Related
Let's say I have a component with tpl in HTML format, which has a variable named testname, default value is null.
A listener of beforerender calls to a function in viewController, and in this function, I need to load a store and a callback function to update the variable testname in the view, based on the store record returned.
The problem I met is the order of code execution. The function in the viewController always ended first before the store.load callback get executed. Therefore the front view will never get updated. I have tried to setup the asynchronousLoad to false but it doesn't help.
Here is the code in the viewController.
onViewRendering: function(theView) {
console.log('setp 1');
var theStore = Ext.create('App.store.Test');
theStore.load({
asynchronousLoad: false,
callback: function(record) {
console.log('setp 2');
if (record) {
theView.data.testname = 'updated';
}
}
});
console.log('setp 3');
}
Console log displays in step 1, 3, 2.
And here is the code in the View:
Ext.define('App.view.TestView', {
extend: 'Ext.component',
data:{
testname:null
},
tpl:'<p>{testname}</p>',
listeners: {
beforerender: 'onViewRendering'
}
})
Here is the store code:
Ext.define('App.store.Test', {
extend: 'Ext.data.Store',
alias: 'store.test',
autoLoad: true,
remoteFilter: true,
fields: ['id', 'name'],
proxy: {
type: 'direct',
directFn: 'test.getTest'
}
})
I am new to Extjs and really need some help here, thanks in advance!
To update tpl after store load, you have to call setData method like below:
Code snippet:
onViewRendering: function(theView) {
console.log('setp 1');
var theStore = Ext.create('App.store.Test');
theStore.load({
asynchronousLoad: false,
callback: function(record) {
console.log('setp 2');
if (record) {
theView.setData({testname: 'updated'}); //setData method
}
}
});
console.log('setp 3');
}
I'm reading the book 'Discover meteor' and have a question about pagination(pagination chapter).
I have a code in my router.js:
//router.js
...
PostsListController = RouteController.extend({
template: 'postsList',
increment: 4,
postsLimit: function() {
return parseInt(this.params.postsLimit) || this.increment;
},
findOptions: function() {
return {sort: {submitted: -1}, limit: this.postsLimit()};
},
subscriptions: function() {
this.postsSub = Meteor.subscribe('posts', this.findOptions());
},
posts: function() {
return Posts.find({}, this.findOptions());
},
data: function() {
var hasMore = this.posts().count() === this.postsLimit();
var nextPath = this.route.path({postsLimit: this.postsLimit() + this.increment});
return {
posts: this.posts(),
ready: this.postsSub.ready,
nextPath: hasMore ? nextPath : null
};
}
});
...
Router.route('/:postsLimit?', {
name: 'postsList'
});
And this working fine. My problem description:
I have another route ('/news') and whant to make pagination for this route too. How i should properly extend PostsListController to make it?
Every my post have a tag option, in this case it is a 'news', so i want to see only posts with 'news' tag.
I'm tryed to just copy-paste this controller(PostsListController) and:
renamed it;
set another template;
changed:
posts: function() {
return Posts.find({}, this.findOptions());
}
to:
posts: function() {
return Posts.find({postType: 'news'}, this.findOptions());
}
It not working, on my /page news i can see only all my news articles and spinner. I'm added:
Router.route('/news/:postsLimit?', {
name: 'newsTemplate',
controller: NewsTemplateController
});
But when i'm goind to /news/1 i'm see all my posts(not only one) and button 'show more'.
I think this copy-paste approach so bad but i have not ideas how to make it working proper way.
Your first issue where /news shows all the posts is because your first Route specification is too generic.
Router.route('/:postsLimit?', {
name: 'postsList'
});
This route specification will send all requests with one parameter to the PostsListController
ie. all of these paths will route to the PostsListsController:
/asdf
/test
/news
To fix this, you might want to make the first route more specific:
Router.route('/posts/:postsLimit?', {
name: 'postsList'
});
I am not sure why you are getting more than one item when going to /news/1.
Can you post your code for that controller?
By default, under the Formatting menu (when the button is clicked), there are these options:
Normal Text
Quote
Code
Header 1
Header ...
Header 5
I would like to only have these options:
Normal Text
Quote
Code
Is there any way to do that? I've been scouring the configuration options and haven't been able to find out how to do it.
Olivérs answer is wrong.
You can easily achieve this by doing the following:
$('#redactor').redactor({
formattingTags: ['p', 'blockquote', 'pre']
});
Demo: http://jsfiddle.net/EkM4A/
Sadly the only way to achieve this is to decorate your redactor instance before init and overwrite the default toolbar setting in redactor.
You can see a working POC here: http://jsfiddle.net/Zmetser/7m3f9/
And the code below:
$(function() {
// Decorate redactor Object before init
$.Redactor.fn = (function () {
var toolbarInitOriginal = this.toolbarInit;
// Create a new toolbarInit method which suits our needs
this.toolbarInit = function (lang) {
// Grab the default toolbar...
var toolbar = toolbarInitOriginal(lang);
// ...and overwrite the formatting dropdown menu
toolbar.formatting.dropdown = {
p: {
title: lang.paragraph,
func: 'formatBlocks'
},
blockquote: {
title: lang.quote,
func: 'formatQuote',
className: 'redactor_format_blockquote'
},
pre: {
title: lang.code,
func: 'formatBlocks',
className: 'redactor_format_pre'
},
};
return toolbar;
};
return this;
}.call($.Redactor.fn));
// Init redactor
$('#redactor').redactor({
buttons: ['link', 'formatting', 'html']
});
});
I am trying to generate the direction on a button click. User selects locations point a and point b and then press a button and code draw direction from that point a to point b. I have successfully completed this code but I am not able to remove the previous directions drawn on map. Please see the image link http://i.stack.imgur.com/z1fqo.png
. I want to remove the a,b direction from the map as it was last direction.
$et_main_map.gmap3({
getroute:{
options:{
origin:org,
destination:dest,
travelMode: google.maps.DirectionsTravelMode.DRIVING
},
callback: function(results){
console.log(results);
if (!results) return;
$(this).gmap3({
directionsrenderer:{
divId:'directionPath',
options:{
directions:results,
suppressMarkers: true
}
}
});
}
}
});
The above code adds the directions.
The below code is not removing the directions on map.
$et_main_map.gmap3({
clear: {
name:["directionRenderer"]
}
});
I have tried many things for eg followed below links.
http://gmap3.net/forum/viewtopic.php?id=341
Gmap3 Clear Directions
Please help me.
Thanks
You should give directionsrenderer function an ID ("whatEverYourID") so that it will be recognized when clear function is called:
$et_main_map.gmap3({
getroute:{
options:{
origin: org,
destination: dest,
travelMode: google.maps.DirectionsTravelMode.DRIVING
},
callback: function(results){
console.log(results);
if (!results) return;
// this is addition lines for handling directions container------
if (!$("#dircontainer").length>0) {
$("<div id='dircontainer' class='googlemap'></div>").insertAfter("#map");
} else {
// this will clear previous the googlemap directions html container
$("#dircontainer").html("");
}
// --------------------------------------------------------------
$(this).gmap3({
// clear previous direction
clear: {
id: "whatEverYourID"
},
map:{
options:{
center:[tolat, tolong],
zoom: 10
}
},
directionsrenderer:{
container: $("#dircontainer"),
options:{
directions:results
},
// this is the ID you have to add
id: "whatEverYourID"
}
});
}
}
});
I hope it will help
I needed to update my gmap3 library. For those who want to fix this issue just update gmap3.js to version 5.1.1. This will fix the issue.
I have found many references on how to create a 'loading' message or mask when loading data in to a grid in Ext JS 4 via a data store / proxy (I am using direct type).
So I had added this in my controller at one point (because I was NOT getting a loading message previously) :
init: function() {
var store = this.getEncountersStore();
store.on({
beforeload: function(store,operation,eopts) {
Ext.getBody().mask('Loading...');
},
load: function(store,records,success,operation,eopts) {
Ext.getBody().unmask();
}
});
}
That seems to work for me in my MVC application, however, next I added a task manager timer to automatically refresh the grid data every 10 seconds:
this.runningTask = Ext.TaskManager.start ({
run: this.loadEncounterData,
interval: 10000,
scope: this
});
loadEncounterData: function() {
var store = this.getEncountersStore();
store.load({
params: {
},
callback: function(r,options,success) {
if(success == true)
...
} //callback
}); //store.load
I noticed that there were now TWO 'loading' mask messages on the screen!
So, I removed my 'store.on' code block above from my controller init, and now I have only one message.
So where does the other message come from?
Is it part of a Grid?:
Ext.define('ESDB.view.encounter.List', {
extend: 'Ext.grid.Panel',
...
I found a page that seems to asking the same question, though I was not able to figure out how to get it to work, or how to do it according to ExtJS 4 / MVC.
loadMask is not a config in Grid panel.
You can add as a config in gridpanel
viewConfig : {
loadMask: false
}
The loadMask is part of the gridView.
http://docs.sencha.com/ext-js/4-0/#!/api/Ext.grid.View-cfg-loadMask
GridPanel components all have a gridView component that defines various things to do with the table view in the panel.
To prevent a loadMask on a grid, you set config for loadMask to false, IE:
Ext.define('ESDB.view.encounter.List', {
extend: 'Ext.grid.Panel',
loadMask : false,
...
You could change your load function to just load the store:
loadEncounterData: function() {
var store = this.getEncountersStore();
store.load();
...
Then you could use the following approach to automatically handle the loadMask whenever the grid store loads.
Using Ext.util.DelayedTask is handy to prevent the loadMask from appearing if the load takes less than 500ms.
Ext.define('ESDB.view.encounter.List', {
extend: 'Ext.grid.Panel',
...
initComponent: function() {
var me = this;
me._mask = new Ext.LoadMask(me, {msg: 'Loading...'});
me._maskd = new Ext.util.DelayedTask(function() {
me._mask.show();
});
me.store = Ext.create('Ext.data.Store', {
...
listeners: {
beforeload: function() {
me._maskd.delay(500);
...
},
load: function() {
me._maskd.cancel();
me._mask.hide();
...
}
}
});
...