Adding listener to matchMedia.js polyfill issue - listener

I am using https://github.com/paulirish/matchMedia.js/ along with the listener extension, however, I do not know how to write a listener for the match media query below. Any assistance would be much obliged.
JS:
if (matchMedia("(min-width: 52em)").matches) {
$("details").attr("open", "open");
}

var handleMyMediaQuery = function(mql) {
if (mql.matches) {
// do match actions
} else {
// do unmatch actions
}
},
myMediaQuery = window.matchMedia('(min-width: 52em)');
handleMyMediaQuery(myMediaQuery);
myMediaQuery.addListener(handleMyMediaQuery);
The first use of 'handleMyMediaQuery' checks immediately for a match to the media query and the second 'myMediaQuery.addListener(handleMyMediaQuery)' is triggered when the media query matches and then again when the media query does not match.
Hope that makes sense.

Related

How to write custom sort logic on sort column event in ng2-smart-table

I'm looking to hook-up sort events performed on ng2-smart-table. Followed https://akveo.github.io/ng2-smart-table/#/documentation, I see bunch of events that are exposed like rowSelect, mouseover etc but I don't see sort events published/emitted by the library. I'm thinking of changing Ng2SmartTableComponent and emit an event when (sort) is called internally. May I know if anyone did it already or is there a hack I can rely upon.
The source of the sort in ng2-smart-table is shown on GitHub (link to code).
If you want to change the compare-Function (as used by default) you can add your own custom function in your ng2-smart-table-configuration:
columns: {
group_name: {
title: 'Groupname',
compareFunction(direction: any, a: any, b: any) => {
//your code
}
}
}
I was searching for an event to sort my data remotely and I have found a solution. Also I have some logic for page change event (remote paging). Here is what works for me.
ts
source: LocalDataSource = new LocalDataSource();
ngOnInit() {
this.source.onChanged().subscribe((change) => {
if (change.action === 'sort') {
this.sortingChange(change.sort);
}
else if (change.action === 'page') {
this.pageChange(change.paging.page);
}
});
}
html
<ng2-smart-table [settings]="settings" [source]="source"></ng2-smart-table>
This solution won't replace custom logic but it might help you solve your problem.

Call showTab in the screen created event

I am using LightSwitch HTML and I have a screen with multiple tabs, and in the screen 'created' event I want to show one of the tabs based on some logic:
myapp.MyScreen.created = function (screen)
{
if (/* some logic */) {
screen.showTab("TabOne");
} else {
screen.showTab("TabTwo");
}
}
However this throws an error when I open the screen:
TypeError: Cannot read property 'pageName' of undefined.
Has anyone encountered this and found a workaround?
Thanks for the help,
In order to use the showTab API command in the screen's created event, its use needs to be delayed until the screen has fully displayed.
This can be achieved by using a combination of the jQuery mobile pagechange event (as the LightSwitch HTML Client uses jQuery mobile) and a setTimeout with a zero timeout (to delay the showTab until the loading screen is rendered).
The following shows a revised version of your example using this approach:
myapp.MyScreen.created = function (screen) {
$(window).one("pagechange", function (e, data) {
setTimeout(function () {
if (/* some logic */) {
screen.showTab("TabOne");
} else {
screen.showTab("TabTwo");
}
});
});
};
Alongside a more advanced alternative, this approach is covered in more detail in my answer to the following post:
LightSwitch Tabbed screen in Browse template
However, as this approach is based upon delaying the showTab until the initial screen has been fully displayed, it does result in a noticeable transition from the default tab to the one displayed by the showTab method.
Whilst slightly more involved, if you'd prefer to avoid this noticeable transition, it's possible to customise the LightSwitch library to introduce a new option into the standard showScreen method. This new option will allow the desired tab page name to be specified when showing a screen.
If you'd like to introduce this additional option, you'll need to reference the un-minified version of the LightSwitch library by making the following change in your HTML client's default.htm file (to remove the .min from the end of the library script reference):
<!--<script type="text/javascript" src="Scripts/msls-?.?.?.min.js"></script>-->
<script type="text/javascript" src="Scripts/msls-?.?.?.js"></script>
The question marks in the line above will relate to the version of LightSwitch you're using.
You'll then need to locate the section of code in your Scripts/msls-?.?.?.js file that declares the showScreen function and change it as follows:
function showScreen(screenId, parameters, options) {
//return msls_shell.showScreen(
// screenId, parameters, null, false,
// options ? options.beforeShown : null,
// options ? options.afterClosed : null);
return msls_shell.showScreen(
screenId, parameters,
options ? options.pageName : null,
false,
options ? options.beforeShown : null,
options ? options.afterClosed : null);
}
You can then use this new pageName option in any of the standard screen display methods as follows:
msls.application.showScreen("MyScreen", null, { pageName: "TabOne" });
// or
myapp.showScreen("MyScreen", null, { pageName: "TabOne" });
// or
myapp.showMyScreen(null, { pageName: "TabOne" });
This results in the screen being displayed on the desired tab, without a noticeable transition from the default tab.

Modernizr Feature Detection with v3

I would like to ask if there's any significant difference/performance issue for detecting using the following two methods:
Let's say we're testing for 3d transforms.
Using the new function that Modernizr 3 offers:
Modernizr.on('csstransforms3d', function(result) {
if (result) {
element.className = 'myFirstClass';
}
else {
element.className = 'mySecondClass';
}
});
And with the standard way:
if (Modernizr.csstransforms3d) {
element.className = 'myFirstClass';
} else {
element.className = 'mySecondClass'
}
The Modernizr.on function is only (or mainly) for asynchronous detects and deferred actions. See the full explanation and example by #stucox for more details.
csstransforms3d is not async, and available right away. There would be no reason to be using the on event callback method for it. The function is rather inefficient with setTimeout() calls which aren't good for performance.
Only use on for deferred events on async detects.
They aren't really comparable because depending on the situation, one will always be better suited than the other. Performance isn't really the issue.
The standard way, checking Boolean values in a Dictionary is an extremely fast operation. If you have a function that gets executed in reaction to some user interaction, this will be the best way to get feature info. For example:
$('#showVideo').on('click', function() {
if (Modernizr.video) {
// load HTML5 video
}
else {
// load Flash video
}
});
Similarly, listening to JS events is very efficient. What the new event-based model in Modernizr allows is for you to react to the Modernizr tests completing. This is great if your site needs to make changes ASAP when feature detection data is available. For example:
Modernizr.on('draganddrop', function(result) {
if (!result) {
alert('This site requires Drag and Drop. Please update your browser.')
}
});
Previously you had to watch for DOM updates on the <body> and check the classes in order to get this information.

Can I force the increment value on scroll for dijit.form.NumberSpinner?

I'm using the dijit.form.NumberSpinner() widget in a form for looking up indexed content. This works great in most cases—entering a number, using the arrow keys, and using the spinner buttons all respond in the right manner. However, on some browsers (notably Firefox), using the scroll wheel over the field increments the value by something > 1.
Is there a way to force the scroll increment on such a number field to be 1 across all browsers? The +3/-3 behavior is strongly undesirable for my application as the results are scrolled through in real time as the value is updated.
I am already using a custom widget derived from NumberSpinner so adding or over-riding a property should not be difficult if that is what is required, I just don't know what to change. The docs only say the increment should be 1 for arrow keys, they don't say anything about scrolling.
That's because it depends on what the event itself provides (= given by the browser). Currently it uses either the evt.wheelDelta or evt.detail property from the mousewheel event to determine the increment value. However, there are no standards yet and most implementations are using certain functions to normalize the scrolling speed.
If you use the following code in Firefox:
require(["dojo/ready", "dojo/mouse", "dojo/on", "dijit/registry", "dijit/form/NumberSpinner", "dojo/parser"], function(ready, mouse, on, registry) {
ready(function() {
on(registry.byId("mySpinner").domNode, mouse.wheel, function(evt) {
console.log(evt.detail);
});
});
});
It will show you that this value is 3 or -3 when executed in Firefox.
If you really don't want it to depend on what the browser says, you can override the _mouseWheeled function:
FixedNumberSpinner = declare("dijit/form/FixedNumberSpinner", [ NumberSpinner ], {
_mouseWheeled: function(/*Event*/ evt){
evt.stopPropagation();
evt.preventDefault();
var wheelDelta = evt.wheelDelta > 0 ? 1 : -1;
var detailDelta = evt.detail > 0 ? -1 : 1;
var scrollAmount = evt.detail ? detailDelta : wheelDelta;
if(scrollAmount !== 0){
var node = this[(scrollAmount > 0 ? "upArrowNode" : "downArrowNode" )];
this._arrowPressed(node, scrollAmount, this.smallDelta);
if(this._wheelTimer){
this._wheelTimer.remove();
}
this._wheelTimer = this.defer(function(){
this._arrowReleased(node);
}, 50);
}
}
});
But please remember that the implementation might still change in the near future, so personally I would just stick with the increment of 3.
A full example can be found on JSFiddle: http://jsfiddle.net/4ZQTY/5/
EDIT: As mentioned in the comments, an even easier solution would be to override the adjust() function.
In most cases it is best to leave the behavior of such widgets alone. The mouse wheel action taken will be familiar to the users of each browser as the stock input widgets respond the same way.
In the event that over-riding this does make sense, you can tweak the adjust() method of the dijit widget. If you want to force the widget to step through every intermediate value no matter size adjustment was requested, you can force the delta value to be 1, then proceed with the contents of the original function.
adjust: function (val, delta) {
delta = delta > 0 ? 1 : -1;
return this.inherited(arguments);
}
(jsfiddle)
Thanks to Dimitri M's answer for putting me onto the hunt, but I found overriding the value in adjust() to be simpler than re-defining _mouseWheeled().

IE9 HTML5 placeholder - how are people achieving this?

I'm trying to use the placeholder="xxx" attribute in my web application, and I don't want to have a special visual for IE9. Can people throw out some good suggestions for achieving this functionality in IE9?
I've found a couple links on here but none of the suggested scripts were sufficient... and the answers were from mid-2011, so I figured maybe there is a better solution out there. Perhaps with a widely-adopted jQuery plugin? I do not want to use anything that requires intrusive code such as requiring a certain css class or something.
Thanks.
EDIT - I also need this to work for password input fields.
// the below snippet should work, but isn't.
$(document).ready(function() {
initPlaceholders()();
}
function initPlaceholders() {
$.support.placeholder = false;
var test = document.createElement('input');
if ('placeholder' in test) {
$.support.placeholder = true;
return function() { }
} else {
return function() {
$(function() {
var active = document.activeElement;
$('form').delegate(':text, :password', 'focus', function() {
var _placeholder = $(this).attr('placeholder'),
_val = $(this).val();
if (_placeholder != '' && _val == _placeholder) {
$(this).val('').removeClass('hasPlaceholder');
}
}).delegate(':text, :password', 'blur', function() {
var _placeholder = $(this).attr('placeholder'),
_val = $(this).val();
if (_placeholder != '' && (_val == '' || _val == _placeholder)) {
$(this).val(_placeholder).addClass('hasPlaceholder');
}
}).submit(function() {
$(this).find('.hasPlaceholder').each(function() { $(this).val(''); });
});
$(':text, :password').blur();
$(active).focus();
});
}
}
}
We just researched the same thing. We decided on reusing this gist, by Aaron McCall, after making some minor changes. The main advantage is that it's simple, easy to understand code:
Remove the kernel and setup_placeholders parts. Just call it immediately in an anonymous function.
Add var before test.
For browsers that support placeholder, it simply falls back to that. It also handles new input elements (note the use of delegate) in existing forms. But does not handle dynamic new form elements. It could probably be modified to do so with jQuery.on.
If you don't like this one, you can use one of the ones here. However, some of them are overcomplicated, or have questionable design decisions like setTimeout for detecting new elements.
Note that it needs to use two pairs of parens, since you're calling an anonymous function, then calling the returned function (this could be factored out differently):
(function () {
// ...
})()();
I wrote a jquery plugin a while back that adds the placeholder support to any browser that does not support it and does nothing in those that do.
Placeholder Plugin
Here's a jQuery plugin that works with password fields as well. It's not as tiny as the code suggested by Matthew but it has a few more fixes in it. I've used this successfully together with H5Validate as well.
http://webcloud.se/code/jQuery-Placeholder/