I need to close soft keyboard on iOS simply clicking outside of input field in Angular app.
I found part of solution:
$scope.hideKeyboard = function() {
document.activeElement.blur();
var inputs = document.querySelectorAll('input');
for(var i=0; i < inputs.length; i++) {
inputs[i].blur();
}
};
<input type='text' ... ng-blur='hideKeyboard()' />
but ng-blur does not help me.
something like this doesn't work.
Found easy solution. On top level div (root of project) I added:
ng-click='angular.noop()'
no need for code above, or anything else.
Related
My control group (jquery mobile 1.4) renders perfectly when dynamically creating the radio group initially, but when I add another radio to it, the buttons are styled, but separated. When I reload the app, they are together again.
function showPlaces() {
$('#radio-group').empty();
for(var i = 0; i < connections.length; i++) {
$('#radio-group').append('<label><input type="radio" name="places" id="' + i + '" />' + place + '</label>');
}
$('input[type=radio]').checkboxradio().trigger('create');
$('#radio-group').controlgroup().trigger('create');
}
// The function is called when app starts, and again after I add another place
Some other things I've tried:
$("#radio-group").controlgroup("refresh");
$('#radio-group').controlgroup('refresh');
$("[data-role=controlgroup]").controlgroup("refresh");
$('input[type=radio]').checkboxradio('refresh');
Also tried .controlgroup('container'), before the .append, but get "cannot call methods on controlgroup prior to initialization".
Here's the html:
<form>
<fieldset data-role="controlgroup" id="radio-group">
<!-- Dynamically injected radio buttons go here -->
</fieldset>
</form>
You should .append() items into .controlgroup("container") inside for loop, and then enhance radio buttons .checkboxradio().
for(var i = 0; i < connections.length; i++) {
$('#radio-group')
.controlgroup("container")
.append('<label><input type="radio" name="places" id="+i+" />Place</label>');
}
$("#radio-group")
.enhanceWithin()
.controlgroup("refresh");
You dont even need to use .checkboxradio(), instead use .enhanceWithin() on parent container.
Demo
Structure of jQueryUI's Accordion is something like this,
<h2>title</h2><div>content</div>
for each item. What I am going to do is create accordion inside of my backbone view through looping, but backbone create div tag for each item so I have html code like this
<div><h2>title</h2><div>content</div></div>
This makes jQuery Accordion control does not work correctly, collapse and expand is not working.
I think this can be solved if I can set nothing on el or tagname, but I cannot find out.
Is there any way to solve this problem?
I think you'd be better off leaving the accordion to one view and then have a separate view inside each panel. After all, the <h2>s are controls for the accordion as-a-whole rather than for a specific panel.
You'd have some per-panel views like this:
var P = Backbone.View.extend({
render: function() {
// Add the panel's content to this.$el (which is a <div> by default).
return this;
}
});
And then an accordion view like this:
var A = Backbone.View.extend({
render: function() {
var panels = [ ... ];
for(var p, i = 0; i < panels.length; ++i) {
p = new P({ ... });
this.$el.append('<h3><a>' + panels[i] + '</a></h3>');
this.$el.append(p.render().el);
}
// The accordion wants to know the sizes of things so
// we let the DOM sort itself out before binding the
// accordion.
var _this = this;
setTimeout(function() { _this.$el.accordion() }, 0);
return this;
}
});
Then you can simply $('#something').append((new A).render().el) and it all works out nicely while leaving everything where it should be.
You could also add a title method to the P views and then A could ask the panel what its name/title/header should be so that all the per-panel information is nicely contained in the per-panel view.
Demo: http://jsfiddle.net/ambiguous/Y49W8/
I have an unordered 'source' list that can contain up to around 1,000 list items. I want to be able to drag the items from the source list into a connected 'destination' list. I have everything working great until my source list gets filtered. I'm using the jquery quicksearch plugin to filter (search) my source list. The filter is accomplished by setting 'display:none;' on items that don't match the search.
When 1..n items in my source list are hidden, the drag operation is not fluid when initiated. Meaning, I click on the item I want to drag, move my mouse around the screen, but the item I'm dragging does not appear under my cursor until about a full second after I've initiated the drag.
For diagnosis, I've slimmed down my use case to just one list that I want to sort. I've completely eliminated the use of quicksearch by just hard coding half of my list items as hidden. I'm still able to reproduce the 'non-fluid' behavior. My example is here:
http://pastebin.com/g0mVE6sc
If I remove the overflow style from the list in my example, the performance is a little better, but still slower than I'd hope to see.
Does anyone have any suggestions for me before I start considering other options?
Thanks in advance.
As you can see on this jsferf example, calculating outerWidth()/outerHeight() (this is what the plugin does - see below) for hidden elements (with display none) is terribly slower than for visible elements, wether it is achieved by a style attribute or a class.
The only way I have found to bypass this and still achieve the same result is to set the height for the elements to hide to zero, instead of working with the display property, whether using the style atttibute or a class:
<li style="height: 0;">b</li>
<li class="hidden">b</li>
.hidden { height: 0 }
DEMO (with class) - DEMO (with style attr)
What's happenning with sortable when dragging an element ?
When starting dragging, the plugin refreshes the list of all items and recalculates positions of all elements. The plugin actually gets outerWidth and outerHeight:
_mouseStart: function(event, overrideHandle, noActivation) {
...
//We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
this.refreshPositions();
...
}
refreshPositions: function(fast) {
...
for (var i = this.items.length - 1; i >= 0; i--) {
var item = this.items[i];
...
if (!fast) {
item.width = t.outerWidth();
item.height = t.outerHeight();
}
var p = t.offset();
item.left = p.left;
item.top = p.top;
};
...
return this;
},
If you still want to use display:none, this is a simple fix to the jQuery UI source specified in Didier's answer:
if (!fast) {
if(item.item.css('display') === 'none') {
item.width = 0;
item.height = 0;
}
else {
item.width = t.outerWidth();
item.height = t.outerHeight();
}
}
This is my very first post on stackoverflow, so do let me know if I messed something up.
I was also having a similar problem, but with hidden drop containers instead of sortable items. Here is my solution applying Jordan's answer to both sortable items and their containers and simply replacing the relvent method.
$.ui.sortable.prototype.refreshPositions = function(fast) {
//This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
if(this.offsetParent && this.helper) {
this.offset.parent = this._getParentOffset();
}
for (var i = this.items.length - 1; i >= 0; i--){
var item = this.items[i];
//We ignore calculating positions of all connected containers when we're not over them
if(item.instance != this.currentContainer && this.currentContainer && item.item[0] != this.currentItem[0])
continue;
var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
if (!fast) {
/********** MODIFICATION ***********/
if(item.item.css('display') === 'none') {
item.width = 0;
item.height = 0;
} else {
item.width = t.outerWidth();
item.height = t.outerHeight();
}
/********** END MODIFICATION ***********/
}
var p = t.offset();
item.left = p.left;
item.top = p.top;
};
if(this.options.custom && this.options.custom.refreshContainers) {
this.options.custom.refreshContainers.call(this);
} else {
for (var i = this.containers.length - 1; i >= 0; i--){
/********** MODIFICATION ***********/
if (this.containers[i].element.css('display') == 'none') {
this.containers[i].containerCache.left = 0;
this.containers[i].containerCache.top = 0;
this.containers[i].containerCache.width = 0;
this.containers[i].containerCache.height = 0;
} else {
var p = this.containers[i].element.offset();
this.containers[i].containerCache.left = p.left;
this.containers[i].containerCache.top = p.top;
this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
}
/********** END MODIFICATION ***********/
};
}
return this;
};
I came across with the same problem...
I've searched for a solution, but it seems there is no solution to the jquery problem, only some workaround...
I didn't found either a solution, just another workaround.
In my case I just created a general method to to a search in a sortable list, where on keyup, the code goes and do a find on every element in the list and was hiding it by fadeout if didn't match the value.
This was working very well, but when you have hundreds of items in a list, the of hidden gets big enough to trigger the slow effect on the drag&drop.
My solution was to reorder the list, bringing to the top the matched items..
Just remove and appendTo again...
This way I don't have problems with the hidden elements :)
Sorry this was no solution, but just another workaround..
Regards
More recently I came accross with this issue again... and found that my workaround was not the best solution anymore. Since the issue is the height... I've just create a CSS class with
.hidden {display: block; line-height:0; height: 0; overflow: hidden; padding: 0; margin: 0; }
and instead of setting the element hidden with just add this class and remove it to show/hide the element..
Regards,
AP
I got the same issue today with sortable + draggable table rows.
The solution was simple : use visibility:collapse instead of display:none and removing the jQuery hide/show function for the hidden lines did the trick. It's a lot faster now.
Hope I will help.
I have a little problem, and I can't figure out where does it come from.
I'm using jQuery UI (and of course jQuery)
I have the following HTML:
<input type="checkbox" id="test" value="test"/>
<label for="test">Show Test</label>
<div id="checkedDiv"></div>
and the following JS:
function clickChange() {
var currentText = this.nextSibling.innerHTML;
this.nextSibling.innerHTML =
(this.checked) ? currentText.replace("Show","Hide") :
currentText.replace("Hide", "Show");
$("#checkedDiv").text(this.nextSibling.innerHTML);
}
var test=document.getElementById("test")
test.onclick=clickChange;
$("#test").button();
The problem is that on the first click, the innerHTML doesn't change. After that it works.
And to be a little more disappointed, the nextSibling seems to change (at least from what is seen in the #checkedDiv), but doesn't appear on the DOM Tree on firefox/firebug.
Am I missing something ?
Thanks
(if you want to try it yourself, it's here: http://jsfiddle.net/nvNKW/3/ )
EDIT:
The (or at least one) solution is to use label as suggested by Aziz Shaikh:
function clickChange() {
var currentText = $(this).button( "option","label");
$(this).button( "option","label",(this.checked)? currentText.replace("Show","Hide") : currentText.replace("Hide", "Show"));
}
And there is no need to change the html or the button initialisation.
Try setting the label using $("#test").button({ label: newText }); instead of this.nextSibling.innerHTML
Edit: So your fixed JS function would be:
function clickChange() {
var currentText = this.nextSibling.firstChild.innerHTML;
var newText = (this.checked) ? currentText.replace("Show","Hide") : currentText.replace("Hide", "Show");
$("#test").button("option", "label", newText);
$("#checkedDiv").text(this.nextSibling.innerHTML);
}
It's because nextSibling() also returns text nodes. You are changing the blank empty space after the input, not the next tag.
jQuery makes it easy, do
$(this).next('label').html()
I spent a lot of time trying to configure a styleswitcher script that replace my html background and css from one color to another, I got some texts using SIFR3, mainly h1, h2 tahs and h2 a: links...
My only problem is that when I'm switching, the flash text doesnt take the color change into consideration, I've tried to play with rollBack but I'm out of luck.
I found an interessant solution here :
function changeColor(hexValue) {
var css = '.sIFR-root { color: ' + hexValue + '; }';
for (var i = 0; i < sIFR.replacements['h1'].length; i++) {
sIFR.replacements['h1'][i].changeCSS(css);
}
for (var i = 0; i < sIFR.replacements['h2'].length; i++) {
sIFR.replacements['h2'][i].changeCSS(css);
}
}
// after switching stylesheet:
changeColor('#FF9900');
It works for h1, h2 but not for my h2 a: links...
Can you tell me how to adjust this?? It would be really really nice.
Right now when firing this function, my links just turn in their old html look with underline text decoration. Thanks !!
You need to pass in the new (or existing) styles for the a as well.