I am using md-select element and when I am selecting value form dropedown it's getting closed. But on focus out it's not closing.
I created a directive to manually remove the container and container also gets removed, but after that md-select is not working.
Here is my directive
.directive('mdSelectMenu', [function() {
return {
restrict: 'E',
link: function(scope, element) {
element.bind('focusout', function() {
console.log("focus out");
$("body,.landing_container").css("overflow","");
$(".md-select-menu-container").remove();
});
element.bind('focusin', function() {
console.log("focus");
$("body,.landing_container").css("overflow","hidden");
});
}
}
}])
Related
Plunker: http://plnkr.co/edit/ElXFi2mo44VpLVsaooOJ
I am modifying a working web app to utilize a jQuery UI plugin called Selectize. Previously I had an input element bound to the controller and a watch placed on that variable. I added the required code to selectize the component which has undone my watch and binding because this plugin modifies the DOM elements and obscures my bound element with new elements.
I would prefer to stay with the angular watch rather than calling a method in selectize to watch the value.
Comment out lines 7-16 to see that the watch is called correctly on every input change.
<input id="itemQuery" type="text" placeholder="Search" class="form-control" ng-model="myValue">
And the script:
angular.module('Sample.controllers', [])
.controller('mainController', ['$scope',
function($scope) {
$scope.myValue="";
$('#itemQuery').selectize({
delimiter: ',',
persist: false,
create: function(input) {
return {
value: input,
text: input
}
}
});
$scope.$watch('myValue', function(newValue, oldValue) {
alert("Old value: " + oldValue + " New value: " + newValue);
});
}]);
angular.module('Sample', ['Sample.controllers']);
First thing you can do is avoid implicit DOM manipulation inside controller and write a directive for that instead.
Updated Demo
App.directive('sampleSelectivize', function() {
return {
restrict: 'A',
link: function(scope, element, attrs) {
element.selectize({
delimiter: ',',
persist: false,
create: function(input) {
return {
value: input,
text: input
}
}
}).on('change', function(event) {
console.log($(this).val());
});
}
};
})
And apply it to your input
<input sample-selectivize id="itemQuery" />
If you've checked the documentation, there are different events can be helpful for you
https://github.com/brianreavis/selectize.js/blob/master/docs/events.md
Thanks to codef0rmer for pointing me in the right direction. The solution was to tell angular that the scope needed updating and to provide it with the new value for this components. The key part being that I needed to include require: '?ngModel' in my directive initializers and then angular provided it as the 4th parameter to the link function.
angular.module('Sample.controllers', [])
.controller('mainController', ['$scope',
function($scope) {
$scope.myValue = "";
$scope.$watch('myValue', function(newValue, oldValue) {
console.log("OldValue: " + oldValue + " New value: " + newValue);
});
}]).directive('sampleSelectivize', function() {
return {
restrict: 'A',
require: '?ngModel',
link: function(scope, element, attrs, ngModel) {
element.selectize({
delimiter: ',',
persist: false,
create: function(input) {
return {
value: input,
text: input
}
}
}).on('change', function(event) {
scope.$apply(applyChange);
});
function applyChange() {
ngModel.$setViewValue(element.context.value);
}
}
};
});
angular.module('Sample', ['Sample.controllers']);
I found this resource to be helpful though incomplete: http://docs.angularjs.org/api/ng.directive:ngModel.NgModelController
Solution plunk http://plnkr.co/edit/ieqQRWBub8ZJ8zOdEhEs?p=preview
Note: It uses console.log rather than alert.
I'm just exploring the Validate plug-in for JQuery. During implementing in my webapp made with JQueryMobile I stumbled over the fact that validating such an element is not so simple like usual input-elements.
So the Question is: How to enable validation for select?
The trick consists out of two parts:
Validate is by default ignoring :hidden. But that's what JQM does with an <select>: hide it and placing a div-span-wrapper on top. Solution is to redefine the ignore-selector:
{ignore: ":hidden:not(select)"}
To inform the user about the invalid field you have to show the error right on the wrapper:
$(error.element).closest('.ui-select').attr("title", error.message).addClass("invalidInput")
And now in an working example:
$.validator.setDefaults({
debug: true,
ignore: ":hidden:not(select)",
submitHandler: function() { alert("submitted!"); },
showErrors: function(map, list) {
$(this.currentElements).each(function() {
if(this.nodeName == "SELECT") {
$(this).closest('.ui-select').removeAttr("title").removeClass("invalidInput");
return true;
}
$(this).removeAttr("title").removeClass("invalidInput");
});
$.each(list, function(index, error) {
if(error.element.nodeName == "SELECT") {
$(error.element).closest('.ui-select').attr("title", error.message).addClass("invalidInput");
return true;
}
$(error.element).attr("title", error.message).addClass("invalidInput");
});
}
});
$('div[data-role="page"]').bind('pageinit', function(event) {
var rules = {};
$('input:not(:button)').each(function() {
rules[this.name] = {required:true};
});
$('#fzgherst').each(function() {
// revalidates the select when changed, other elements gets revalidatet onblur
$(this).on('change', function() {$(this).valid();});
rules[this.name] = {required:true};
});
$("form").validate({
rules: rules
});
});
That's all folks!
Have I done something obviously obtuse, or is there a special format for evaluating if() conditions within a jqueryUI button callback?
$(function(){
var focus_control = '';
$( '#alert' ).dialog({
autoOpen:false,
show: 'fade',
hide: 'fade',
buttons: {
Ok: function() {
$(this).dialog('close');
//Next line works if uncommented
//$('#username').focus();
//This if block breaks the js, but all works if this block commented out
//var focus_control assigned elsewhere (ajax)
if (focus_control=='staff_pick') {
$('#staff_pick').focus();
}else if {focus_control=='username') {
$('#username').focus();
}
}
}
});
});
Is there a better way to rewrite this? I tried:
if (focus_control!='') {
$('#%focus_control%').focus();
}
I have the following script using the jQueryUI autocomplete widget. It calls some function whenever a menu item in the selection box is being selected:
<script type="text/javascript">
$(function() {
$( "#tags" ).autocomplete({
source: [ "ActionScript", "AppleScript", "Asp"],
select: function() {
console.log("Element has been selected");
}
});
});
</script>
<div class="ui-widget">
<label for="tags">Tags: </label>
<input id="tags">
</div>
This works nicely. But I need this method in a multiple of instances of the autocomplete widget, so I prefer extending the autocomplete widget using the widget factory.
This works nicely whenever I want to override methods of the autocomplete plugin:
$.widget("ui.myAutocomplete", $.extend({}, $.ui.autocomplete.prototype, {
search: function( value, event ) {
// this WORKS!
console.log('overriding autocomplete.search')
return $.ui.autocomplete.prototype.search.apply(this, arguments);
}
}));
However, I have no clue how to do that for the underlying menu widget.
I tried to override the _init method and binding a function to the select event. However this does not work as I don't know how to access the bind method of the menu-widget (or this menu widget is not yet there at this point during runtime)
$.widget("ui.myAutocomplete", $.extend({}, $.ui.autocomplete.prototype, {
_init: function() {
// this does NOT work.
this.bind('select', function() { console.log('item has been selected') })
return $.ui.autocomplete.prototype._init.apply(this, arguments);
}
}));
I think you're close; you should be overriding _create instead of _init:
$.widget("ui.myAutocomplete", $.extend({}, $.ui.autocomplete.prototype, {
_create: function() {
// call autocomplete's default create method:
$.ui.autocomplete.prototype._create.apply(this, arguments);
// this.element is the element the widget was invoked with
this.element.bind("autocompleteselect", this._select);
},
_select: function(event, ui) {
// Code to be executed upon every select.
}
}));
Usage:
$("input").myAutocomplete({
/* snip */
});
Here's a working example: http://jsfiddle.net/EWsS4/
I have been wrestling with this one for a while now.
I want to have a confirm() before someone changes the accordion.
I have tried:
$(document).ready(function() {
var edited = false;
$(".accordion-me").accordion({
autoHeight: false,
navigation: true,
changestart: function(event, ui) {
if (edited) {
if (!confirm("You have unsaved changes. Do you want to navigate away?") {
event.preventDefault();
event.stopPropagation();
event.stopImmediatePropagation();
return false;
}
}
}
});
});
With little joy! I have also tried something like this
$(".accordion-me h3").each(function() {
$(this).unbind("click");
$(this).click(function(e) {
if (confirm("You have unsaved changes! Do you want to navigate away?")) {
$(this).unbind("click");
$(".accordion-me").accordion({
autoHeight: false,
navigation: true,
changestart: function(event, ui) {
if (edited) {
if (!confirm("You have unsaved changes. Do you want to navigate away?") {
event.preventDefault();
event.stopPropagation();
event.stopImmediatePropagation();
return false;
}
}
}
});
$(this).click();
}
});
});
But again with no joy.
Any help would be greatly appreciated.
Cheers
Use an empty event when creating the accordion, which will allow you to manage the click event of the accordion using a jQuery .click function.
You can then process the confirm box and allow the accordion click event to be executed only if confirmed.
$(document).ready(function()
{
var edited = false,
accordion_me = $('.accordion-me');
// activate the accordion, but with an empty event
accordion_me.accordion({
autoHeight: false,
navigation: true,
event: ''
});
// here's the new accordion event
$('.accordion-me h3').click(function()
{
// find the index of the event being called
var i = $('.accordion-me h3').index(this);
// if we have unsaved changes and do not confirm, stop accordion execution
if (edited && !confirm('You have unsaved changes. Do you want to navigate away?'))
{
return false;
}
// continue with the accordion execution. Activate the requested event index.
accordion_me.accordion('activate', i);
return false;
});
});
If your accordion is collapsible (as mine is) your accordion will still work as it did before.
Also, if you only have 1 accordion, I would recommend using an id to call it instead of the .accordion-me class, which will save some overhead.
If you still need to use a class to call it, put an html tag before it, i.e. div.accordion-me.
You have to bind it to the click event on the anchor tag. For example, if your header links are:
header 1
code would be (also in the document.ready function)
$('.accordionHeaderLink').click(function(){
if (!confirm("You have unsaved changes. Do you want to navigate away?")) {
return false;
}
});