Let’s say I have this markup:
<div id="content">
<div id="firstP"><p>First paragraph</p></div>
<div id="secondP"><p>Second paragraph</p></div>
<div id="thirdP"><p>Third paragraph</p></div>
<div id="fourthP"><p>Fourth paragraph</p></div>
</div>
I want to add a new <div> with jQuery and focus on this new element. .focus does not do anything.
function addParagraph() {
var html = "<div id=\"newP\"><p>New paragraph</p></div>";
$("#content").append(html);
$("#newP").focus();
}
Any idea why?
I think the main answer is incorrect. DIV and P tags can receive focus providing you specify a tabindex property for them. i.e.
<div class="someclass" tabindex="100">
Once the tabindex is specified you can either tab to these elements or shift focus with .focus() .
Using a scrollTo plugin seems like a bit of an overkill here.
There's no problem with your code, it's just that a paragraph or div tag can't receive focus. Focus can only be given to things you can interact with, such as links, input elements, textareas, etc.
To scroll the window to this newly added element, you can use a plugin such as ScrollTo.
On a side note, your code could be simplified a bit:
var html = "<div id=\"newP\"><p>New paragraph</p></div>";
$("#content").append(html);
$("#newP p").focus();
var html = "<div id=\"newP\"><p>New paragraph</p></div>";
$(html)
.appendTo('#content')
.focus() // or scrollTo(), now...
;
This code will avoid dependencies on other plugins and allow you to have it on any element.
$('html, body').animate({ scrollTop: $("#newP").offset().top }, 500);
You need to use a HTML page anchor not focus. Example:
http://localhost/mypage.html#fourthP
I think what you're looking for is using the 'ScrollTo' plugin in jQuery. You can check it out here.
You can specify what to scroll...
$('div.pane').scrollTo(...);//all divs w/class pane
Or just scroll the window:
$.scrollTo(...);//the plugin will take care of this
There are many different ways to specify the target position.
These are:
A raw number
A string('44', '100px', '+=30px',
etc )
A DOM element (logically, child of
the scrollable element)
A selector, that will be relative to
the scrollable element
A hash { top:x, left:y }, x and y
can be any kind of number/string
like above.
Bonus:
In digging up this information, I also found LocalScroll and SerialScroll (animates scrolling from one item to the next).
Only form elements and such can attain focus. If you want the browser to scroll down to that particular paragraph, there is no "default" way of doing so with jQuery, but there is a plugin for it at jQuery.ScrollTo and a blog explaining how to do it manually at Animated scroll with jQuery
Instead of
$("#newP").focus();
it should be used:
window.location.href=window.location.href + "#newP";
You can assign tabidex and then you can set focus to that element
$('#table').attr("tabindex",1).focus();
This will work for Div Table etc which can't get focus by itself.
Related
On a web page we have a list of profiles. On the right hand side of the profile is some text, followed by an arrow img#arrow.
When img#arrow is clicked, we have the following jQuery we hope to run:
However, the corresponding .bottom-sec is not toggling.
jQuery('#arrow').click(function(){
var $parent = $(this).parent();
$($parent).addClass('active');
jQuery($parent +' .bottom-sec').toggle();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="profile-right">
<h2>Bob Brown</h2>
<h3>Non-Executive Chairman</h3>
<p>Intially showing text.</p>
<div class="bottom-sec" style="display: none;">
<p>Initially hidden text.</p>
</div>
<img id="arrow" src="/wp-content/themes/wtc/images/icons/down-arrow-circle-hi.png">
</div>
Problem
The problem with your code is exactly what the comment on your question is saying, but he didn't explain anything:
You're combining two different ways of selecting elements. One is with selectors, the other is traversing. You're using them in a way which isn't possible (the $parent + ' .bottom-sec' part). The comment linked to a jQuery page about traversing which you should definitely read! It tells you a lot about how to use traversing functions, which you could use!
Solution
There are multiple solutions to this, but I'll write down the one I think is the best:
First of all, change the HTML a bit. I've removed the element style of .bottom-sec and changed the id of the image to a class, because you have multiple images with the same id on the page, which is not a recommended thing to do. Classes can occur more than once, id's cannot.
<div class="profile-right">
<h2>Bob Brown</h2>
<h3>Non-Executive Chairman</h3>
<p>Intially showing text.</p>
<div class="bottom-sec">
<p>Initially hidden text.</p>
</div>
<img class="arrow" src="/wp-content/themes/wtc/images/icons/down-arrow-circle-hi.png">
</div>
I've reduced the JavaScript to the following. Note that is just reduced to one line, where a click on the .arrow element goes searching for the closest .profile-right parent. If, for whatever reason, you decide to change the HTML and the .arrow element is no longer a child of the .profile-right, this code still works. The only thing it does is toggle an active class on the .profile-right.
jQuery(document).on('ready', function() {
jQuery('.arrow').on('click', function(){
jQuery(this).closest('.profile-right').toggleClass('active');
});
});
The document ready listener was added because of OP's comment.
With CSS, we can use the new .active class to show or hide the element.
.profile-right .bottom-sec {
display: none
}
.profile-right.active .bottom-sec {
display: block
}
Original Code Fix
If for some reason you wanted to use your original code, this is how it should be:
// Nothing wrong about this part.
// Your only worry should be that there could be
// multiple elements with the same ID, which is something really bad.
jQuery('#arrow').click(function(){
// This part is correct, no worries
var $parent = $(this).parent();
// Removed the $(...), because $parent is already a jQuery object
$parent.addClass('active');
// Changed the selector to a find function
$parent.find('.bottom-sec').toggle();
});
You could also combine all of the code inside the listener function to just one line:
jQuery('#arrow').click(function(){
$(this).parent().addClass('active').find('.bottom-sec').toggle();
});
Change your js code like below.
jQuery('#arrow').click(function(){
var $parent = $(this).parent();
$($parent).addClass('active');
jQuery($parent).find('.bottom-sec').toggle();
});
In your event listener you can catch the element (the down arrow) that triggered the event. It will be referred as this.
Then you can go through the DOM tree using .next() and .parent() to access the <div> to toggle.
Note: you may need more functions than the one I explained above.
Note 2: without code or more detailed information, we can't help you further, I will edit this answer if you add details.
I want to use jQuery to work with events in a given search box. My issue is that
I don't know how to build the selector correctly, so that JQuery accepts it.
I think I'm getting confused because I need the second element in the list and need to select that one.
The runtime HTML looks like this: (Adapted from Chrome Developer tools, only the relevant class and IDs are shown. There are no IDs to be shown.)
<body class=km-ios7 km-7 km-m0 km-web km-black-status-bar km-vertical km-widget km-pane>
<div class="km-widget km-view">
<!-- Begin 3rd party control -->
<div class=class="km-widget km-view">
<div km-header>
<div class="km-content km-widget km-scroll-wrapper">
<div class=km-scroll-header>
<div class=km-scroll-container>
<div class="km-listview-wrapper">
<form class="km-filter-form">
<div class="km-filter-wrap">
<input type=search >
What I've tried
Since my event wasn't firing I assume my selector was wrong. I opened chrome developer tools after I did "inspect element". The bottom of the tools listed all the parent tags used for that element (with no class or ID). As a test, I've tried hiding the search box using the following:
$("div").hide(); // hides everything...
$("div div").hide(); // hides the wrong element on the page
$("input").hide(); // nothing
$(":input").hide(); // nothing... saw this example somewhere, don't understand it
$("input:text").hide(); // nothing... saw this example (http://stackoverflow.com/q/17384218/328397), don't understand it
I looked at this W3 document, but didn't see what I was looking for (unless I missed it)
Any assistance in getting the right selector would be appreciated.
In the page you linked it's the second div under defaultHomecontent, so
$("#defaultHomeContent div:nth-child(2)")
You actually want to hide the div with class km-filter-wrap.
A safer alternative may be to not deal with selectors and instead show/hide the wrapper element for the ListViewFilter's searchInput element:
var listView = $("#local-filterable-listview").kendoMobileListView({
...
}).getKendoMobileListView();
listView._filter.searchInput.parent().hide();
or
listView.wrapper.find(".km-filter-wrap").hide();
In general, it's a good idea to use the elements that are exposed by Kendo UI controls as much as possible instead of manually building queries (since they might change in future versions).
You could also extend the ListView widget with your own API method for this:
kendo.mobile.ui.ListView.fn.filterVisible = function(value) {
var wrapper = this._filter.searchInput.parent();
if (value) {
wrapper.show();
} else {
wrapper.hide();
}
};
then you could use
listView.filterVisible(false); // hide the filter
you can use the find function. Let suppose you have input field inside footer div like this.
<div id="footer">
<div>
<div>
<input type="text" name="text" value="Search" />
</div>
</div>
</div>
You can use selector like this $("#footer input").hide() or $("#footer").find("input").hide() or $('input[name=text]', '#footer').hide();
Based on what you have added.
You could use
$("input[type='search']")
as a selector.
See if that helps. Here is an example
You could also combine the selectors in this manner:
var $container = $("div.km-widget");
var $searchBox = $container.find("input[type='search']");
I have a dropdown function that I need to work only on the div clicked, not all (I have 14+ of the same classes on the page that need to be displayed when a certain one is clicked)
At the moment my jQuery is as follows.
$('.qacollapsed').hide();
$('.qa').click(function () {
$('.qacollapsed').slideToggle();
$(this).toggleClass('active');
});
Of course, that is toggling all qacollapsed classes when there is 14 on the page (Q&A)
Is there a way for it to only drop down the one that is clicked?
the HTML
<div class="qa">
<h4 class="question"> </h4>
</div>
<div class="qacollapsed">
<p> </p>
</div>
It would be helpful to provide a snippet of HTML here, but I'll take a guess at the structure of your markup for now..
Instead of referencing all .qacollapsed elements, you need find elements that are close to the .qa that was clicked, e.g.:
$('.qa').click(function () {
$(this) // start with the clicked element
.find('.qacollapsed') // find child .qacollapsed elements only
.slideToggle();
$(this).toggleClass('active');
});
This will work if .qacollapsed is inside .qa - if not, you might need to use next (for siblings), or one of the other jQuery tree traversal methods.
Yo could find() it or use this as a context in the selector to choose only a descendent of the clicked object
$('.qa').click(function () {
$('.qacollapsed', this).slideToggle();
//You could do $(this).find('.qacollapsed').slideToggle();
$(this).toggleClass('active');
});
Check out the jQuery selectors and why not just use $(this)?
$('.qacollapsed').hide();
$('.qa').click(function () {
$(this).toggleClass('active').next().slideToggle();
});
Personally, I'd give all the divs IDs, the clickable bit being the ID of the question in the database for example, and the answer just being id='ID_answer' or something, then use jquery to slide in the div with the id corresponding to the link clicked, ie
Var showIt = $(this).attr('id') + '_answer'
$('.qacollapsed').not('#'+showIt).hide();
$('#'+showIt).slideToggle;
That will hide all the divs without that ID and show the required one.
Dexter's use of .next above looks simpler though, I've not tried that as being relatively new to jquery too.
How is it possible to select an element based on its position?
<div id="parent">
<p id="text">This is a text</p>
</div>
//CSS
#parent{width:100px;height:100px;position:absolute;left:100px;top:100px;}
Now using the left=100px,top=100px how can I select the div element using JQuery?
Something like this might work:
var el = document.elementFromPoint(100, 100);
var $el = $(el); // if you really want to use jQuery.
Documentation for document.elementFromPoint.
This might not be what you're looking for: it will only get the visible, topmost element at that point, and it will get whatever element occupies that space, not just one whose top-left corner is at that point. But, chances are, it'll help :).
It is supported by all major browsers, although you could get wacky results with Safari 4 or Opera 10.10.
The jQuery css() function allows you to retrieve the value of CSS properties, for example css('left') will return the left position of your element.
However, in your question you as about selecting the div element based on its location. I presume you mean something like $('left=100px'). This is not possible. jQuery uses CSS selectors which query the structure, not the style of the DOM.
You could loop through every element to check the position. Here is a quick sample function:
function getElementsByPosition(x,y) {
var elements=new Array();
$('*').each(function() {
if($(this).css('top')==x && $(this.css('left'))==y) {
elements[elements.length]=this;
}
});
return elements;
}
Update: Domenic's solution is much more elegant. Please consider his before using mine.
I have a function here for centering an element within it's parent.
Check out the demo: http://jsfiddle.net/kE9xW/1/
right now it's only applying the centering to the first element, how do i make the function loop itself so it centers every #element on the page. the demo is self explanatory, thanks!
There are a few things you need to do.
As already suggested, id's must be unique, so change the id="..." to class="...". You will also need to change your css to be based on the class not the id (change #element' to '.element')
<div class="container">
<p> ... </p>
<div class="element">
</div>
</div>
Use each in your method to loop over all elements selected by the selector $('.element').
element.each(function(){
// work here in $(this) for the current element
});
You forgot to take the top of the parent div into account, which made all elements overlap each other. So your yPas becomes:
var yPos = $(this).parent().position().top +
parseInt($(this).parent().css('height'))/2 -
parseInt($(this).css('height'))/2 - yPosFromCenter;
Check the working fiddle: http://jsfiddle.net/H99DT/
First, the easiest but most important part: change your IDs to classes. IDs must be unique per page so jQuery's ID selector and JavaScript's document.getElementById() function are only going to give you the first matching element:
Each id value must be used only once within a document. If more than one element has been assigned the same ID, queries that use that ID will only select the first matched element in the DOM.
Change
<div id="container">
...
<div id="element">
to
<div class="container">
...
<div class="element">
and change
$('#element')
to
$('.element')
Next, the more difficult part: you are currently issuing one centerDiv() call to your elements with coordinates from center of 0, 0. That's going to take all your .elements and position them at the exact same spot.
If that's not what you intend, you're going to have to loop through them using .each() and decide the xPosFromCenter and yPosFromCenter in each iteration. It's not clear to me yet how your function works so you may have to explore on your own and see what you can come up with.
Scratch that, see Jamiec's working example for the solution.
Change Id to class in you divs, then make container's position relative with css, and I'll suggest make jQuery plugin from your function. See results http://jsfiddle.net/kE9xW/1/