Javascript Archives - Justin Silver https://www.justinsilver.com/tag/javascript/ Technology, Travel, and Pictures Sat, 16 Mar 2019 23:52:32 +0000 en-US hourly 1 https://wordpress.org/?v=6.0.1 https://www.justinsilver.com/wp-content/uploads/2013/06/cropped-apple-touch-icon-160x160.png Javascript Archives - Justin Silver https://www.justinsilver.com/tag/javascript/ 32 32 Inserting & Triggering Custom Events In jQuery Functions https://www.justinsilver.com/technology/inserting-triggering-custom-events-in-jquery-functions/?utm_source=rss&utm_medium=rss&utm_campaign=inserting-triggering-custom-events-in-jquery-functions https://www.justinsilver.com/technology/inserting-triggering-custom-events-in-jquery-functions/#respond Fri, 02 Oct 2015 20:13:45 +0000 http://justinsilver.com/?p=3937 I recently had the need to detect when new elements were appended to the DOM, however by default in jQuery there is no “append” event. This meant that the code I wanted to write,...

The post Inserting & Triggering Custom Events In jQuery Functions appeared first on Justin Silver.

]]>
AmpedSense.OptimizeAdSpot('AP'); AmpedSense.OptimizeAdSpot('IL'); AmpedSense.OptimizeAdSpot('IR');

I recently had the need to detect when new elements were appended to the DOM, however by default in jQuery there is no “append” event. This meant that the code I wanted to write, was invalid.

(function($) {
	$(document).on('append', function(){
		// handle the "append" event using the elements from the arguments
	});
})(jQuery);

The solution I ended up using involved caching the existing jQuery.append() to jQuery._append() and then overriding jQuery.append() to call the cached function internally, followed by the triggering of my new “append” event.

(function($) {
	// store a copy of the append() function as _append()
	$.fn._append = $.fn.append;

	// overwrite the existing append()
	$.fn.append = function () {
		return $.fn
			// apply the cached (function)ality using _append()
			._append.apply(this, arguments)
			// trigger our custom "append" event to fire handlers.
			.trigger("append", [arguments]);
	};
})(jQuery);

The post Inserting & Triggering Custom Events In jQuery Functions appeared first on Justin Silver.

]]>
https://www.justinsilver.com/technology/inserting-triggering-custom-events-in-jquery-functions/feed/ 0
ACF: Link to Specific Tab https://www.justinsilver.com/technology/wordpress/acf-link-to-specific-tab/?utm_source=rss&utm_medium=rss&utm_campaign=acf-link-to-specific-tab https://www.justinsilver.com/technology/wordpress/acf-link-to-specific-tab/#comments Thu, 03 Sep 2015 16:04:50 +0000 http://justinsilver.com/?p=3931 Advanced Custom Fields, or ACF, provides a great user interface for defining and laying out custom fields for Posts, Pages, Custom Post Types, Options, Users and more in WordPress. The Tab Field provides an...

The post ACF: Link to Specific Tab appeared first on Justin Silver.

]]>
AmpedSense.OptimizeAdSpot('AP'); AmpedSense.OptimizeAdSpot('IL'); AmpedSense.OptimizeAdSpot('IR');

Advanced Custom Fields, or ACF, provides a great user interface for defining and laying out custom fields for Posts, Pages, Custom Post Types, Options, Users and more in WordPress. The Tab Field provides an easy way to clean up your user interface by seperating different field inputs into different tabs, making it easier for your users to find what they are looking for.

One feature that is missing from the Tab field however is the ability to link directly to a specific tab from another page. We can work around this with some pretty straightforward JavaScript. In short when the acf “ready” event fires, we want to look at all the tab buttons, and if any match our URL hash (in lowercase with spaces replaced with hyphens) then we “click” that link, loading the appropriate tab. Subsequently we can update the hash in the address bar any time a new tab is clicked making it easy for uses to bookmark the page or send the link to another user.

If your tab name is “Options Tab 1” the link to it would be something like edit.php?post_type=my-post-type#options-tab-1.

(function($){
	// run when ACF is ready
	acf.add_action('ready', function(){
		// check if there is a hash
		if (location.hash.length>1){
			// get everything after the #
			var hash = location.hash.substring(1);
			// loop through the tab buttons and try to find a match
			$('.acf-tab-wrap .acf-tab-button').each(function(i, button){ 
				if (hash==$(button).text().toLowerCase().replace(' ', '-')){
					// if we found a match, click it then exit the each() loop
					$(button).trigger('click');
					return false;
				}
			});
		}
		// when a tab is clicked, update the hash in the URL
		$('.acf-tab-wrap .acf-tab-button').on('click', function($el){
			location.hash='#'+$(this).text().toLowerCase().replace(' ', '-');
		});
	});
})(jQuery);

The post ACF: Link to Specific Tab appeared first on Justin Silver.

]]>
https://www.justinsilver.com/technology/wordpress/acf-link-to-specific-tab/feed/ 5
Moving Average Custom Function for Google Spreadsheets https://www.justinsilver.com/technology/moving-average-custom-function-for-google-spreadsheets/?utm_source=rss&utm_medium=rss&utm_campaign=moving-average-custom-function-for-google-spreadsheets https://www.justinsilver.com/technology/moving-average-custom-function-for-google-spreadsheets/#comments Sun, 09 Aug 2015 22:54:54 +0000 http://justinsilver.com/?p=3898 Moving Averages can be calculated in Google Spreadsheets using standard functions, however the formulas can get pretty complex when dealing with different durations, and it also requires the formula to be included in each...

The post Moving Average Custom Function for Google Spreadsheets appeared first on Justin Silver.

]]>
AmpedSense.OptimizeAdSpot('AP'); AmpedSense.OptimizeAdSpot('IL'); AmpedSense.OptimizeAdSpot('IR');

Moving Averages can be calculated in Google Spreadsheets using standard functions, however the formulas can get pretty complex when dealing with different durations, and it also requires the formula to be included in each field. The first time I tried to solve this by writing a custom function that would calculate the moving average per cell, however I quickly ran into an error stating that I was running too many scripts per second for Google’s liking.

I am working with rows of time series data, so I really want to add a new column with a moving average in it. It would also be nice to show the average of the available data if the full set isn’t available for convenience. To accomplish both of these I created a function that can be placed in the header and returns an array of results, including the header itself, of a moving average of the value from another column.

Custom function via Google Script

Open Google Scripts by selecting Tools  > Script editor... to open the browser based IDE. A sample file will open by default, you can look it over or just remove all of the contents. Once the file is cleared, enter the following JavaScript to define a custom function named MOVING_AVERAGE.

function MOVING_AVERAGE(column, days, dateColumn){
	// defaults
	days = ( typeof days == 'undefined' )? 30 : days;
	dateColumn = ( typeof dateColumn == 'undefined' )? 'A' : dateColumn;
	var now = (new Date()).getTime();
	
	var sheet = SpreadsheetApp.getActiveSpreadsheet();
	var lastRow = SpreadsheetApp.getActiveSheet().getMaxRows()-1;
	var dates = sheet.getRange(dateColumn+"2:"+dateColumn).getValues();
	var values = sheet.getRange(column+"2:"+column).getValues();
	for (; values[lastRow - 1] == "" && lastRow > 0; lastRow--) {}
	var title = sheet.getRange(column+"1").getValue();
	var results = [ days + " days " + title ];
	for ( var rowIndex = 0; rowIndex < lastRow; rowIndex++ ){
		// we are after "today" 
		var inTheFuture = (now+3600 <= (new Date(dates[rowIndex])).getTime());
		
		if (inTheFuture){
			results.push(0);
		} else {			
			var lookback = ( rowIndex < days )? rowIndex : days-1;
			var startRow = rowIndex - lookback;
			
			var total = 0;
			for ( var i=startRow; i<=rowIndex; i++ ){
				total += parseFloat( values[i] );
			}
			
			results.push(parseFloat(total/((rowIndex-startRow)+1)));
		}
	}
	
	return results;
}

Use the custom function in your spreadsheet

You can now use this function by adding the following into the formula field of a column header. Keep in mind that this won’t update on demand so you will need to remove/re-add the formula to recalculate.

=MOVING_AVERAGE( "COLUMN", DAYS_INT )

Or if your date column isn’t “A”, then you can specify it like so.

=MOVING_AVERAGE( "COLUMN_DATA", DAYS_INT, "COLUMN_DATE" )

 

The post Moving Average Custom Function for Google Spreadsheets appeared first on Justin Silver.

]]>
https://www.justinsilver.com/technology/moving-average-custom-function-for-google-spreadsheets/feed/ 3
Hide Edit/Del Links on Salesforce Standard Page https://www.justinsilver.com/technology/salesforce/hide-edit-del-link-on-salesforce-standard-pages/?utm_source=rss&utm_medium=rss&utm_campaign=hide-edit-del-link-on-salesforce-standard-pages https://www.justinsilver.com/technology/salesforce/hide-edit-del-link-on-salesforce-standard-pages/#comments Thu, 13 Nov 2014 00:36:35 +0000 http://justinsilver.com/?p=3831 It is not possible to control the visibility of the Edit/Del action links for a related list. On a VisualForce page you can insert your own CSS or Javascript to control the display, which...

The post Hide Edit/Del Links on Salesforce Standard Page appeared first on Justin Silver.

]]>
AmpedSense.OptimizeAdSpot('AP'); AmpedSense.OptimizeAdSpot('IL'); AmpedSense.OptimizeAdSpot('IR');

It is not possible to control the visibility of the Edit/Del action links for a related list. On a VisualForce page you can insert your own CSS or Javascript to control the display, which you can also do on a Salesforce standard layout, albeit in a slightly more complicated fashion.

The trick is to use a Custom Link on your Home Page Layout. This Custom Link is defined as an onClick, but will actually load code inline with the use of REQUIRESCRIPT. Inside the REQUIRESCRIPT will be our Javascript payload, Base64 encoded.

Create Javascript Payload

First let’s compile the Javascript we need to control the UI on standard page layouts. In this case we want to hide the Edit/Del links on a related list, so view the page and use your developer tools to look at the DOM. You want to find the ID of the top level element in the related list table, something like “500c0000004BtmN_00sE0000004gkgq_body”. Use the following snippet as an example.

jQuery(document).ready(function($){
	// hide this sidebar module
	$('#sidebarDiv div.linksModule').each(function(){
		var $module = $(this);
		if ( $module.find('.brandPrimaryFgr').text()=='UserInterfaceInjection'){
			$module.hide();
			return false;
		}
	});
	// hide the Edit/Del links
	jQuery('#500c0000004BtmN_00sE0000004gkgq_body .actionColumn').hide();
});

Now we need to convert this to Base64. Any way is fine, but online is pretty easy: https://www.base64encode.org/.

alF1ZXJ5KGRvY3VtZW50KS5yZWFkeShmdW5jdGlvbigkKXsNCgkvLyBoaWRlIHRoaXMgc2lkZWJhciBtb2R1bGUNCgkkKCcjc2lkZWJhckRpdiBkaXYubGlua3NNb2R1bGUnKS5lYWNoKGZ1bmN0aW9uKCl7DQoJCXZhciAkbW9kdWxlID0gJCh0aGlzKTsNCgkJaWYgKCAkbW9kdWxlLmZpbmQoJy5icmFuZFByaW1hcnlGZ3InKS50ZXh0KCk9PSdVc2VySW50ZXJmYWNlSW5qZWN0aW9uJyl7DQoJCQkkbW9kdWxlLmhpZGUoKTsNCgkJCXJldHVybiBmYWxzZTsNCgkJfQ0KCX0pOw0KCS8vIGhpZGUgdGhlIEVkaXQvRGVsIGxpbmtzDQoJalF1ZXJ5KCcjNTAwYzAwMDAwMDRCdG1OXzAwc0UwMDAwMDA0Z2tncV9ib2R5IC5hY3Rpb25Db2x1bW4nKS5oaWRlKCk7DQp9KTs=

Put this text aside, we will need it later when creating the Javascript link.

Create Custom Link

Visit Setup > Home > Customize > Custom Links

  1. Create a new Link
  2. Name: UserInterfaceInjection
  3. Behavior: Execute Javascript
  4. Content Source: onClick Javascript
  5. Body: {!REQUIRESCRIPT('data:application/javascript;base64,BASE64_JS')}, except that you want to replace BASE64_JS with your Base64 encoded Javascript.

Create Home Page Component

Visit Setup > Home > Home Page Components

  1. Create a new Component
  2. Name: UserInterfaceInjection
  3. Type: Links
  4. Choose UserInterfaceInjection Link

Add to Home Page Layout

Visit Setup > Home > Home Page Layouts

  1. Edit your layout to include UserInterfaceInjection

Now when you visit your page the Action column should be hidden from your related list. It’s pretty easy to see how this could be further expanded to add all kinds of custom functionality to standard Page Layouts in Salesforce.

The post Hide Edit/Del Links on Salesforce Standard Page appeared first on Justin Silver.

]]>
https://www.justinsilver.com/technology/salesforce/hide-edit-del-link-on-salesforce-standard-pages/feed/ 10
Use jQuery + Plugins with Visualforce Pages https://www.justinsilver.com/technology/salesforce/use-jquery-plugins-visualforce-pages/?utm_source=rss&utm_medium=rss&utm_campaign=use-jquery-plugins-visualforce-pages https://www.justinsilver.com/technology/salesforce/use-jquery-plugins-visualforce-pages/#respond Sun, 09 Nov 2014 11:31:25 +0000 http://justinsilver.com/?p=3820 The jQuery library makes it much easier to create cross-browser functionality on any web page, and Salesforce Visualforce pages are no exception. Going one step further and include jQuery plugins in your pages as...

The post Use jQuery + Plugins with Visualforce Pages appeared first on Justin Silver.

]]>
AmpedSense.OptimizeAdSpot('AP'); AmpedSense.OptimizeAdSpot('IL'); AmpedSense.OptimizeAdSpot('IR');

The jQuery library makes it much easier to create cross-browser functionality on any web page, and Salesforce Visualforce pages are no exception. Going one step further and include jQuery plugins in your pages as well for even more functionality and sparkles. But what do you do when you want to use a more recent version of jQuery, and your plugin is being reported as an undefined function in the console? To the rescue comes jQuery.noConflict(true);.

First you will want to upload both jQuery and your plugin as Static Resources, or from a CDN if you prefer. For our purposes we will assume they are Static Resources called jQuery and jQueryPlugin. As soon as the javascript sources is includes – jQuery first followed by plugins – we need to make a call to noConflict() to free up the $ resources. Using jQuery as an alias is easy and logical.

Next we want to tell our code to run after the DOM of the page has loaded, so we wrap our code inside a function that is called by jQuery.ready(). A neat trick here is to pass jQuery back into the callback function as $, so your code will know the version of jQuery you loaded and it’s attached plugins as the standard $.

<!-- include static resources -->
<apex:includeScript value="{!$Resource.jQuery}" />
<apex:includeScript value="{!$Resource.jQueryPlugin}" />
<script type="text/javascript">
// Alias to jQuery and free $
jQuery = $.noConflict(true);

// Call jQuery.ready(), and alias jQuery back to $ by passing as an argument
jQuery(document).ready(function($){
	// use $.plugin()
	$('#container').plugin();

	// attach events to DOM elements
	$('.button').on('click', function(){
		alert('clicked!');
	});
});
</script>

The post Use jQuery + Plugins with Visualforce Pages appeared first on Justin Silver.

]]>
https://www.justinsilver.com/technology/salesforce/use-jquery-plugins-visualforce-pages/feed/ 0