Change the way the number of elements are shown on selecting a Point if multiple items exist at that point - arcgis

Currently in ArcGIS Online if multiple items exist in a single point the template is shown like this
Will I be able to view the details with the number of elements as a part of the template like this

You can retrieve the number of selected features using Popup.featureCount.
The following CodePen uses this property to provide a dynamic PopupTemplate.title: https://codepen.io/arnofiva/pen/5b532f8577d097107cf8040da57e0b97
var template = layer.popupTemplate;
var defaultTitle = template.title;
// Compute popup title before it is shown
template.title = function() {
var total = view.popup.featureCount;
if (total > 1) {
return defaultTitle + " - Count: " + total + "";
} else {
return defaultTitle;
}
}
See the following ArcGIS API for JavaScript resources for more information on popups and widgets:
Popup Widget
PopupTemplate - use functions to set content
Popup with DOM node
Widget development - ViewModel pattern

Related

IG - how to register changes to cell being edited - eg. to action shortcut key (Oracle Apex Interactive Grid)

We have common functionality across multiple pages: Cancel/Save/Back/Next (buttons).
I added shortcut keys via app-level static JavaScript file: Alt-C/S/B/N (using common CSS on the buttons & jQuery binds).
Problem: when using shortcut key whilst editing a cell, the edits to the cell were not saved with Alt-S, Alt-N. (For same reason, no confirmation requested on Cancel/Back, since the grid did not see any changes.)
Much searching and reading of documentation did not reveal the answer...
After a huge amount of effort: inspecting of widget/ interactiveGrid/ model/ getCurrentView via the console & inspect-panes (partly because I didn't find/inspect the .interactiveGrid('getViews','grid).getColumns() for a long time), I found a solution, but I feel there must be a more elegant one. Advice sought! TIA.
Here is my solution. Note the namespace is lps, and I have aliased apex.jQuery as lps.$ prior to the code below. I include comments for my Oracle colleagues less experienced with JS, Apex, jQuery, etc.
The solution works for all 4 shortcut keys, and should work for any IG (possibly even without a static id on the containing region, although my test case has a static id). There is some supporting code after the main solution. All happening on page load via the static JS file.
The jQuery selectors must only bind to a single button on each page!
lps.$(window).on('keydown',function($evt) // Capture Alt + shortcut key in keydown event
{
// $evt is the jQuery simplified event
if( $evt.altKey ) // the alt-key is being pressed-and-held
{
var key = $evt.key.toUpperCase();
if( lps.shortcuts[key] )
{
if( lps.$($evt.target).is('input,textarea') ) // effect the onchange() JavaScript (more specifically, the IG version thereof)
{
// We've pressed a shortcut key combo, whilst editing a cell, so the IG-onchange-y event hasn't yet fired
var tgtEle = $evt.target,
newVal = tgtEle.value, // the value of the on-screen element, regardless of change-status
tgtId = tgtEle.id, // this tallies with an elementId exposed via the igCols below
activeFld;
// IG stuff - igId - get the IG overall id via an IG ancestor div of the target field, then losing the trailing _ig suffix
var igId = lps.$(tgtEle).parents('div.a-IG')[0].id.replace(/_ig$/,'')
igWidget= apex.region(igId).widget(),
igGrid = igWidget.interactiveGrid('getViews','grid'),
igModel = igGrid.model,
igView = igWidget.interactiveGrid('getCurrentView'),
igRecId = igView.getActiveRecordId(),
igCols = igGrid.getColumns(); // this provides meta information about the columns in the IG
for( var i=-1; ++i<igCols.length; ) // find the field name of this IG-column from target element id
{
if( igCols[i].elementId === tgtId )
{
activeFld = igCols[i].property;
break;
}
}
// Phew. Eventually setValue on the IG-cell so Apex knows the cell has changed without an onchange firing
igModel.setValue(igModel.getRecord(igRecId),activeFld,newVal);
}
$evt.originalEvent.preventDefault(); // we're consuming the event, so stop it doing some native browser trick we don't want
lps.$(lps.shortcuts[key].selector).select(); // select the to-be-clicked-element
lps.$(lps.shortcuts[key].selector).click(); // synthesise a click on the selector'd element
}
}
});
Supporting code to pre-establish what our 4 shortcut keys are to be:
lps.shortcuts = { // keys and their jQuery selectors
B : { selector:'button.nav-back' },
C : { selector:'button.nav-cancel' },
N : { selector:'button.nav-next' },
S : { selector:'button.nav-save' },
};
Code to add hover-title to the buttons:
// Advertise the shortcut with a 'title' attribute (appears as popup tip when hover over the element)
for( var key in lps.shortcuts ){
lps.$(lps.shortcuts[key].selector).attr('title','Alt+'+key);
}

JQuery Datatables SearchPane Filter Value

I am using the SearchPanes extension to Datatables, I am trying to capture the value of the item in the SearchPane they chose, it appears that since SearchPanes uses filter() instead of search() that value is not available. Am I wrong?
You can access the selections as follows:
1) Add stateSave: true to the DataTable initialization definition. See this example.
This will cause all selections to be saved in the browser's local storage.
2) Use the following logic to access the browser's local storage:
var myStorage = window.localStorage;
var searchPanes = JSON.parse(myStorage.getItem('yourStorageIndexGoesHere'));
//console.log(searchPanes); // the full JSON - large!
//console.log(searchPanes['searchPanes']['panes']); // one object per search pane
searchPanes['searchPanes']['panes'].forEach(function(pane) {
console.log('ID = ' + pane.id + ' - selected: ' + pane.selected);
});
In my case, I used the search panes shown in this demo.
Here is a screenshot with some selections:
Here is what the sample code writes to the browser console for the above selections:
The "ID" data value is a zero-based column index. So, column 3 (index 2) is the Office column, and column 6 (index 5) is the Salary column.
The related "selected" data are arrays, containing one or more value. You can iterate the arrays to get each separate value.
You will need to replace yourStorageIndexGoesHere with the actual name of your storage entry. The easiest (manual) way to find this is to perform a filter using SearchPanes, and then open your browser tools (usually F12). Then (assuming FireFox in my case) navigate to Storage > Local Storage > and select the relevant key text.
Points to Note:
a) This assumes you are OK with activating the "local storage" feature. It means that the browser will remember the last applied filter, and re-apply it when a user returns to the DataTable browser page. If users do not want that feature, then my solution will not be suitable for you.
b) I can't advise you on where you need to place the JavaScript I provided, because I don't know what you want to do with this information. But, for example, you might want to use it after every draw() event - in which case, see here.
Jsut want to add, how the search pattern or the preselected searchPanes filters can be erased on demand - is stateSave is been enabled.
.on( 'stateLoadParams.dt', function (e, settings, data) {
//get the last search pattern, if this setting is enabled
//if not, erase last search
if (!cnf_lastSearch) {
//erase search input field
data.search.search = '';
data.start = 0;
//console.log(data)
} else {
}
//search through search panes array and erase content
if (!cnf_searchPanes) {
$.each((data['searchPanes']['panes']), function( i, val ) {
val.selected = '';
});
}
})

Get current page request url in handlebars?

Is there a way to the current request url or path in Handlebars? I need to be able to switch what parts of the theme is loaded based on paths. I've tried {{url}} ... no luck. Using latest Stencil with Cornerstone.
I had to do something like this for a project with 3 different category page layouts. Without custom category templates in Stencil, you have to get a little creative.
First, inject the handlebars URL into your category.js file using the BigCommerce's inject handlebar helper seen here. Then parse it so you get only the unique parts, then perform some logic based on what you want to do.
I used the breadcrumb li length as an indicator of how deep I was in the category tree. There is likely a better way, but this is what I thought of first, and it worked just fine.
category.html
{{inject "currentPage" category.url}}
category.js
var pageURL = this.context.currentPage;
var pageURL = pageURL.replace(/\//g," ").replace("http:","").replace("storeurl.mybigcommerce.com","").replace("storeurl.com","").trim();
var catName = pageURL.substr(0,pageURL.indexOf(' '));
console.log('pageURL = ' + pageURL);
console.log('catName = ' + catName);
console.log($('ul.breadcrumbs li').length);
if( $('ul.breadcrumbs li').length == 3 ){
if(catName == "black-decker"){
if($(".cat-img").length){
$(".page").addClass("model-list");
$(".cat-img").hide();
$(".page").append("<div class='model-wrap'><div class='model-catalog' data-reveal-id='myModal'><span class='click-larger'>Click to view larger</span></div></div>");
$(".sidebarBlock-heading").text("Select Your Model Number Below:");
$(".brand-img").each(function(){
$(this).addClass(catName);
});
} else {
$(".page").addClass("model-list");
$(".sidebarBlock-heading").text("Select Your Model Number Below:");
$(".brand-img").each(function(){
$(this).addClass(catName);
});
// make page full width
$(".page-sidebar.cf.Left").addClass("full-width");
}
}
// MORE CODE etc...

Calling member functions on click/tap within sencha touch 2 templates

I am rather new to sencha touch, I've done a lot of research and tutorials to learn the basics but now that I am experimenting I have run into a problem that I can't figure out.
I have a basic DataList which gets its data from a store which displays in a xtemplate.
Within this template I have created a member function which requires store field data to be parsed as a parameter.
I would like to make a thumbnail image (that's source is pulled from the store) execute the member function on click/tap.
I can't find any information on this within the docs, does anyone know the best way to go about this?
Here is a code example (pulled from docs as I can't access my actual code right now).
var tpl = new Ext.XTemplate(
'<p>Name: {name}</p>'
{
tapFunction: function(name){
alert(name);
}
}
);
tpl.overwrite(panel.body, data);
I want to make the paragraph clickable which will then execute the tapFunction() member function and pass the {name} variable.
Doing something like onclick="{[this.tapFunction(values.name)]} " does not seem to work.
I think functions in template are executed as soon as the view is rendered so I don't think this is the proper solution.
What I would do in your case is :
Add a unique class to your < p > tag
tpl : '<p class="my-p-tag">{name}</p>'
Detect the itemtap event on the list
In your dataview controller, you add an tap event listener on your list.
refs: {
myList: 'WHATEVER_REFERENCE_MATCHES_YOUR_LIST'
},
control: {
myList: {
itemtap: 'listItemTap'
}
}
Check if the target of the tap is the < p > tag
To do so, implement your listItemTap function like so :
listItemTap: function(list,index,target,record,e){
var node = e.target;
if (node.className && node.className.indexOf('my-p-tag') > -1) {
console.log(record.get('name'));
}
}
Hope this helps

Simple store connected list for dojo

Is there a simpler list type than DataGrid that can be connected to a store for Dojo?
I would like the data abstraction of the store, but I don't need the header and cell stucture. I would like to be more flexible in the representation of the datalines, where maybe each line calls an function to get laid out...
You ask a really good question. I actually have a blog post that is still in draft form called "The DataGrid should not be your first option".
I have done a couple thing using the store to display data from a store in a repeated form.
I have manually built an html table using dom-construct and for each.
var table = dojo.create('table', {}, parentNode);
var tbody = dojo.create('tbody', {}, table); // a version of IE needs this or it won't render the table
store.fetch({ // this is a dojo.data.ItemFileReadStore, but you cana dapt to the dojo.Store API
query: {},
onComplete: function(itms) {
dojo.forEach(itms, function(itm, idx) {
var tr = dojo.create('tr', {}, tbody);
// use idx to set odd/even css class
// create tds and the data that goes in them
});
}
});
I have also created a repeater, where I have an html template in a string form and use that to instantiate html for each row.
var htmlTemplate = '<div>${name}</div>'; // assumes name is in the data item
store.fetch({ // this is a dojo.data.ItemFileReadStore, but you cana dapt to the dojo.Store API
query: {},
onComplete: function(itms) {
dojo.forEach(itms, function(itm, idx) {
var expandedHtml = dojo.replace(htmlTemplate, itm);
// use dojo.place to put the html where you want it
});
}
});
You could also have a widget that you instantiate for each item.