How to prevent ngBlur from firing first - javascript

Supposedly I have an input text markup like this:
<input type="text" ng-focus="x = true" ng-blur="x = false">
So when you click it, this div shows up:
<div ng-show="x === true">
<ul>
<li ng-click="choose(1)">First</li>
<li ng-click="choose(2)">Second</li>
<li ng-click="choose(3)">Third</li>
</ul>
</div>
What happens is when I click one of the selections in the list, the div becomes hidden because the ng-blur from the text field is fired, therefore, the ng-click in the selection is not executed (or so this is what happens in my situation). Is there any workaround for this? Thanks.

A bit of a hack would be to put your ngBlurin a $timeout pushing it back one digest.
<input type="text" ng-focus="x = true" ng-blur="hideFields()">
function hideFields() {
$timeout(function() {
$scope.x = false;
});
}

Related

Click button to copy text to another div with angularjs

I have a list of Items with different button with them. Plunker
Quick View:
I want something like if I click on any of the buttons, related text will be copy to the div above. Also if I click on the button again it will removed from the Div.Same for each of the buttons. [I added manually one to show how it may display ]
I am not sure how to do that in Angular. Any help will be my life saver.
<div ng-repeat="item in csTagGrp">
<ul>
<li ng-repeat="value in item.csTags">
<div class="pull-left">
<button type="button" ng-class='{active: value.active && !value.old}' class="btn btn-default btn-xs">{{value.keys}}</button>
<span>=</span>
</div>
<div class="pull-left cs-tag-item-list">
<span>{{value.tags}}</span>
</div>
</li>
</ul>
</div>
The simplest thing would be to use $scope.tags object to store selected tags and add/remove them with the scope method similar to this:
$scope.tags = {};
$scope.toggleTag = function(tag) {
if (!$scope.tags[tag]) {
$scope.tags[tag] = true;
}
else {
delete $scope.tags[tag];
}
};
Demo: http://plnkr.co/edit/FrifyCrl0yP0T8l8XO4K?p=info
You can use ng-click to put in your scope the selected value, and then display this value instead of "Win".
http://plnkr.co/edit/IzwZFtRBfSiEcHGicc9l?p=preview
<div class="myboard">
<span>{{selected.tags}}</span>
</div>
...
<button type="button" ng-click="select(value)">{{value.keys}}</button>

Javascript/jQuery watch for CSS Changes

I have a simple dropdown that opens up a search field when you click it. Even though I have the text field of this search set to autofocus, it's not working for all browsers.
What method of Javascript/jQuery would I use to check if the containing UL css display is set to block, so that I can force the focus to be on the field using .focus().
HTML:
Quick Search
<ul class="dropdown-menu" role="menu">
<li id="li-quicksearch">
<form id="mainSearch" class="form-search">
<p>
<input type="text" id="inputSearch" class="form-control" placeholder="Quick Search" required="" autofocus autocomplete="off">
<button type="submit">SUBMIT</button>
</p>
</form>
</li>
</ul>
EDIT: There is no css change event so you'll have to approach the problem in 1 of 2 ways.
check the dom element in set intervals to see if its css has changed
trigger an event when the css of the dom element is changed by user interaction/your code.
the first way will look something like this:
var element = $(".dropdown-menu");
function checkForChanges()
{
if (element.css('display') == 'block')
{
// do your .focus() stuff here
}
setTimeout(checkForChanges, 500); // does this every half second.
}
or the second way:
$('.toggle').on('click', function() {
$('.dropdown-menu').toggle();
$('.dropdown-menu').trigger('change');
});
$('.dropdown-menu').on('change', function(){
if($(this).css(.css('display') == 'block')
{
// do your .focus() stuff here
}
});
You can check the display value of the ul using pure JavaScript with this:
JS:
var display = document.getElementById('dropdown-menu')[0].style.display;
if (display === 'block') {
//do what you want.
}
Or using jQuery:
if ($('.dropdown-menu').css('display') === 'block') {
//do what you want.
}
It looks like you are using bootstrap to create the dropdown. If that is the case you can use the "shown" event. However you need to attach the event on a container element.
Html
<div class="quickSearchContainer">
Quick Search
<ul class="dropdown-menu" role="menu">
<li id="li-quicksearch">
<form id="mainSearch" class="form-search">
<p>
<input type="text" id="inputSearch" class="form-control" placeholder="Quick Search" required="" autofocus autocomplete="off">
<button type="submit">SUBMIT</button>
</p>
</form>
</li>
</ul>
</div>
Javascript
$('#quickSearchContainer').on('show.bs.dropdown', function () {
$('#inputSearch').focus();
});
I want to thank everyone for their input, but the working solution that I found was to modify the bootstrap JS to allow for an autofocus on toggleClass of the OPEN for the dropdowns. Everyone gets kudos!

How to show hidden div immediately after clicking on link

So I've made a function that, when you click on a button, a certain div comes up with its own content. When clicking on the button again, the div will hide and another div will show up. This div will always show up when none of the other three divs aren't selected.
The problem is when I'm adding an href tag with an anchor link which is connected to each div, that I must click twice on the button before the hidden div will show.
Check fiddle here: http://jsfiddle.net/449r8Lwv/
So as you can see, when you click on one of the buttons, nothing happens except that the url changes which is a good thing. But clicking AGAIN on the same button lets you show the hidden div. This is not what I want, I want the div show up the first time you click on the button already.
Also, when going directly to the url with an anchor name in it, It will immediately show the div with it's content that is connected to the anchor, that's a good thing. But then if you click another button again, it will show the div that must normally show when NONE of the divs aren't selected which is not the case.
Example: You go to url website.com/test.html#2. Then when you click on button 3, then content of the connected div must come("3") up but instead the div(named #text) will come up when that one should only come up if none of the divs that are connected to the buttons arent showing up.
HTML:
1
2
3
<br><br><br>
<div id="clicks">
<a class="click" id="showInfo" data-target=".1"><button>1</button></a>
<a class="click" id="showDataInput" data-target=".2"><button>2</button></a>
<a class="click" id="showHistory" data-target=".3"><button>3</button></a>
</div>
<div class="1 target" style="display: none;"><a name="1">1</a></div>
<div class="2 target" style="display: none;"><a name="1">2</a></div>
<div class="3 target" style="display: none;"><a name="1">3</a></div>
<div id="text">"I WANT THIS DIV GONE EVERYTIME I LET DIV 1, 2 OR 3 SHOW BY CLICKING THE BUTTONS. BUT SHOW UP AGAIN WHEN 1, 2 OR 3 IS NOT SHOWING/SELECTED"</div>
JavaScript/jQuery
<script>
$(document).ready(function () {
var $targets = $('.target');
$('#clicks .click').click(function () {
var $target = $($(this).data('target')).toggle();
$targets.not($target).hide();
$('#text').css('display', $('div.target:visible').length ? 'none':'')
/*$('#contact_info').toggle(!$targets.is(':visible'));*/
});
});
</script>
<script>
function doToggle(num) {
var target = $('div.target' + num);
target.toggle();
$('.target').not(target).hide();
$('#text').css('display', $('div.target:visible').length ? 'none' : '')
}
$('#clicks .click').click(function () {
var num = $(this).data('target');
doToggle(num);
});
function handleHash() {
doToggle("." + location.hash.substring(1));
}
window.onhashchange = handleHash;
$(handleHash);
</script>
Thank you a lot.
ps: in the fiddle I only put the second script part because of some issues when I put the other part aswell. If you test it local you should use the whole JavaScript/jQuery part.
Since the URL is changing, you need to put doToggle(..) in the main section of your code.
Another problem is the data-target. jQuery may evaluate the number as a number. So .1 will become 0.1. We can add the . in JS.
<div id="clicks">
<button>1</button>
<button>2</button>
<button>3</button>
</div>
<div class="1 target" style="display: none;"><a name="1">1</a></div>
<div class="2 target" style="display: none;"><a name="1">2</a></div>
<div class="3 target" style="display: none;"><a name="1">3</a></div>
<div id="text">"I WANT THIS DIV GONE EVERYTIME I LET DIV 1, 2 OR 3 SHOW BY CLICKING THE BUTTONS. BUT SHOW UP AGAIN WHEN 1, 2 OR 3 IS NOT SHOWING/SELECTED"</div>
and the JavaScript:
function doToggle(num) {
var target = $('div.target' + num);
target.toggle();
$('.target').not(target).hide();
$('#text').css('display', $('div.target:visible').length ? 'none' : '')
}
$('#clicks .click').click(function () {
var num = '.' + $(this).data('target');
if (num === '.' + location.hash.substring(1)) {
doToggle(num);
}
});
function handleHash() {
doToggle("." + location.hash.substring(1));
}
if (location.hash.substring(1).length > 0) {
doToggle('.' + location.hash.substring(1));
}
window.onhashchange = handleHash;
$(handleHash);
Edited:
In you script before, doToggle was working, but after it executed, the url would change, making it look like doToggle wasn't working. The click handler should only perform the toggle if the hash url is the same as the toggled div.
http://jsfiddle.net/449r8Lwv/12/
I'd suggest to remove dots in your data-target attribute.
So, your HTML will look like this:
1
2
3
<br><br><br>
<div id="clicks">
<a class="click" id="showInfo" data-target="1"><button>1</button></a>
<a class="click" id="showDataInput" data-target="2"><button>2</button></a>
<a class="click" id="showHistory" data-target="3"><button>3</button></a>
</div>
<div class="1 target" style="display: none;"><a name="1">1</a></div>
<div class="2 target" style="display: none;"><a name="1">2</a></div>
<div class="3 target" style="display: none;"><a name="1">3</a></div>
<div id="text">"I WANT THIS DIV GONE EVERYTIME I LET DIV 1, 2 OR 3 SHOW BY CLICKING THE BUTTONS. BUT SHOW UP AGAIN WHEN 1, 2 OR 3 IS NOT SHOWING/SELECTED"</div>
And you can try it here.
Change
$('#clicks .click')
To
$('#clicks.click')
This should solve your problem.
So remove the space in your selector
example: jsfiddle
There is flaw in your code thats why it requires two click to show the div.
Flaw: when user clicks on a link/button say "1" first time both your click and onhashchange handler is getting fired one after another. i.e clickHandler is first display the div 1 which is again gets hidden by your onhashchange handler call.
Next time when you click on same link 'No hashchange will occur' and hence only click handler is getting fired which in turn display the div correctly.
Solution: I suggest you should only use click handler because of the nature of your requirement. Or if it doesn't fit your requirement, you can set global variable to track if one of the event is fired and check its value before calling doToggle in your hashchangehandler.

jQuery if radio button is selected then proceed to next element

I'm very new to JavaScript and jQuery. I know my code is not the prettiest, but I'm trying to start somewhere.
I have a series of questions that are shown one at a time, and want to create some sort of validation to prevent the user from going to the next question if a radio button on the first button hasn't been selected.
HTML (I have four of these .questionContainers
<div class="questionContainer">
<div class="question">
How much storage do you need?
</div>
<div class="answers">
<ul>
<li>
<label>
<input type="radio" id="storage">1GB or less
</label>
</li>
<li>
<label>
<input type="radio" id="storage">More than 1GB
</label>
</li>
</ul>
</div>
<div class="btnContainer">
<div class="next">
<a class="btnNext">Next</a>
</div>
</div>
</div>
JavaScript
(function(){
var Questions = {
container : $('.questionContainer'),
init : function() {
this.start();
if($('input[type=radio]:checked').length > 0){
this.container.find('a.btnNext').on('click', this.next);
}
},
start : function() {
this.container.not(':first').addClass('hide');
},
next : function() {
var container = $('.questionContainer');
$(this).closest(container).hide(function(){
$(this).closest(container).next().show();
});
}
};
Questions.init();
})();
The specific line that isn't working:
if($('input[type=radio]:checked').length > 0) {
this.container.find('a.btnNext').on('click', this.next);
}
The Problem
When I add the if statement and click a radio button followed by next, it does not go to the next question. I am not receiving any errors in the console.
This binds to the click event only if something is checked at the time that the start function is called (not what you want - it will never be true unless you pre-select a radio button for the user without their action):
if($('input[type=radio]:checked').length > 0){
this.container.find('a.btnNext').on('click', this.next);
}
Try replacing it with this instead:
this.container.find('a.btnNext').on('click', function () {
if($('input[type=radio]:checked').length > 0){
this.next();
}
});
This way you always bind to the click event, but the function that is bound only allows next to be called if something is checked at the time that the function is called (i.e. when the next button is clicked).

Selenium IDE sendKey to input element does not trigger event handlers

I am using selenium IDE, writing tests for an JQuery based application. I have on previous endeavours used sendKey and type. In the site there is a input box on top in a ul dropdown.
When a user types a number into the dropdown.
Clicks outside it.
The value typed gets reflected to other labels on the site.
In using selenium though:
focus
sendKeys
click
Does not trigger any event in the JS to update labels...
I have also tried using runscript $('body').click(); to trigger some event but no success.
<div class="lblButton optType">
<label id="lSystem" data-rule="{'id':'b10','value':10}">10</label>
<span class="arrow"></span>
<ul class="widget">
<li class="option tagV10" data-rule="{'id':'b10','value':10}">10</li>
<li class="option tagV20" data-rule="{'id':'b20','value':20}">20</li>
<li class="option tagV30" data-rule="{'id':'b30','value':30}">30</li>
</ul>
<input class="lblButtonIn" type="number" style="background-color: transparent;">123</input>
</div>
How do i properly simulate changing the input value and clicking outside the input/dropdown? (I can not share the full js but below is the part I think important:)
var parent = field.parent(), label = parent.find('>label');
field.bind( 'blur', function( e ) {
setTimeout( function() {
if ( field.hasClass('invalid') ) {
field.get(0).value = label.text();
field.removeClass('invalid');
}
else {
var v = field.get(0).value, r = '{\'id\':\'b'+v+'\',\'value\':'+v+'}';
label.html( field.get(0).value ).attr('data-rule',r);
}
updateGt(), $('body').click();
}, 20);

Categories