I have HTML code for kind of blog page. Below - code of 1 post and its height cuts by CSS. It will be many posts on blog page. I want to see all content of particular page by clicking "Read More" button.
Div with blog content has dynamic id which gets from database by PHP.
How can I change height of div with class "blog_article" by clicking "Read More" button?
I thought of using JS/Jquery but cannot get id of "blog_article" div.
Or maybe there is some better way to do this?
<div class="blog_article_wrapper">
<div class="blog_article" id="<?php echo $id; ?>">
<!--Some content-->
</div>
<div class="blog_article_read_more">
<button onclick="blogReadMore()">Read More</button>
</div>
</div>
but cannot get id of "blog_article" div
Why can't you?:
<button onclick="blogReadMore(<?php echo $id; ?>)">Read More</button>
Or, if it's a string:
<button onclick="blogReadMore('<?php echo $id; ?>')">Read More</button>
Then blogReadMore() has a reference to the id:
function blogReadMore(id) {
// use the id to identify the element and modify it however you want
}
Conversely, since you tagged jQuery, you can traverse the DOM from the button click to determine the element without needing any id at all. Something like this:
$('.blog_article_read_more button').click(function () {
var article = $(this).closest('.blog_article_wrapper').find('.blog_article');
// do whatever you like with the article
});
There's a more straight forward way than Azim's answer, but based on the same ideas:
I would still use the read_more class, although not actually needed. I will assume such a class applied to the button.
$('.read_more').click(function(){
var blog_article = $(this).parent().parent().find('.blog_article');
blog_article.css('height', '100px'); //change height here
});
In this case I use .parent() method in order to get the parent object from the clicked item, rather than relying on .closest(). Two calls to .parent() are needed because the <button> resides inside a <div> and we need the parent of that div before we can drill down.
Alternatively:
$('.read_more').click(function(){
var blog_article = $(this).parent().prev();
blog_article.css('height', '100px'); //change height here
});
Because the button's parent <div> is the direct sibling of the one we're interested in. No selectors needed at all!
You have the id right there, you can generate it just fine with blogReadMore('<?php echo $id; ?>'). But you don't need the id, your button lives inside the thing you need expanded so you can look it up that way, too.
You're using fairly ancient JS event handling techniques so this won't be as clean as modern code should be (which doesn't use onclick and other things, but adds the event listening after the DOM has been set up), but you can just pass onclick="blogReadMore(this)" so that your blogReadMore function knows the element that triggered it. Then you just go through the sequence of element.parentNode until you find the element with element.classList.contains('blog_article')===true (both of those have equivalent jQuery calls)
Sort of an answer, but the real one would be "this is not a very good way to generate your code. Generate the HTML and then attach the JS event handling afterwards".
Use a class for read more button, say read_more like <button class="read_more">Read More</button>. And use following jquery.
$('.read_more').click(function(){
var blog_article = $(this).closest('.blog_article_wrapper').find('.blog_article');
blog_article.height(100); //change height here
});
Related
I have added Elements using Jquery inside PHP after loading them from the database. Each button has two classes, one controlling the GUI and another controlling the Click for particular button. The code is as under
echo "<script type='text/javascript'>$('.main').append('<button class=b_ui b$index>Change</button>'); </script>";
Now if I check the classes from Inspect Element perspective of the browser, it shows 2 classes. But when I click on it and get class of element using this code
$('.b_ui').click(function()
{
cls = $(this).attr('class');
alert('no. '+cls);
}
It shows only first class (GUI) and not the other which I want to use for handling click.
Any help ?
Put quotes around the class attribute. <button class=\"b_ui b$index\">Change</button>
You should use "on" method:
$(document).on('click', '.b_ui', function() {
cls = $(this).attr('class');
alert('no. '+cls);
});
When adding elements dynamically to the DOM, they are not accessible by jQuery like an element which was there at page load. say you have this div:
<div id="div"></div>
and you add some content with jQuery so it now looks like this:
<div id="div"><span id="span"></span></div>
you cannot refer directly to the span using jQuery with $('span[id=span]'), you have to target a containing element then filter which contained element you want:
$('#id').on('click','span',function(){});
I'm new to jQuery and am trying to create jQuery UI buttons dynamically and them to a list. I can create one list item but no more are appended after it. What am I doing wrong?
$('#buttonList').append('<li><button>'+ username + '</button>')
.button()
.data('type', userType)
.click(function(e) { alert($(this).data('type')); })
.append('<button>Edit</button></li>');
<div>
<ul id="buttonList">
</ul>
</div>
This only creates one list item with two buttons (although the second button seems to be encased in the first one, but I can probably figure that issue out). How do I get it to create multiple list items with their own unique 'data' values (i.e. I can't do a find() on a particular button class and give it data values as all buttons would then have the same data)?
I suggest to exchange the position of what you are appending and where you are appending to. This way, you retain the appended object, and should be able to work with it as a standard jQuery selector. From your code i commented out the .button() and the .append() lines, because i'm not sure what you want to do with them. Should you need help adding those lines, just drop a comment to my answer ;)
Oh, i almost forgot: i use var i to simulate different contents for username and userType data.
A JSFiddle for you is here: http://jsfiddle.net/cRjh9/1/
Example code (html part):
<div>
<p id="addButton">add button</p>
<ul id="buttonList">
</ul>
</div>
Example code (js part):
var i = 0;
$('#addButton').on('click', function()
{
$('<li><button class="itemButton">'+ 'username' + i + '</button></li>').appendTo('#buttonList')
//.button()
.find('.itemButton')
.data('type', 'userType'+i)
.click(function(e) { alert($(this).data('type'));
})
//.append('<button>Edit</button></li>')
;
i++;
});
You need complete tags when you wrap any html in a method argument. You can't treat the DOM like a text editor and append a start tag, append some more tags and then append the end tag.
Anything insterted into the DOM has to be complete and valid html.
You are also not understanding the context of what is returned from append(). It is not the element(s) within the arguments it is the element collection you are appending to. You are calling button() on the whole <UL>.
I suggest you get a better understanding of jQuery before trying to chain so many methods together
Just a very simplistic approach that you can modify - FIDDLE.
I haven't added the data attributes, nor the click function (I'm not really sure I like the
inline "click" functions - I generally do them in jQuery and try to figure out how to make
the code efficient. Probably not very rational, but I'm often so).
JS
var names = ['Washington', 'Adams', 'Jefferson', 'Lincoln', 'Roosevelt'];
for( r=0; r < names.length; r++ )
{
$('#buttonList').append('<li><button>'+ names[r] + '</button></li>');
}
$('#buttonList').append('<li><button>Edit</button></li>');
Think of the following HTML code to apply Jquery:
HTML code:
<div id="outer_div">
<div id="inner_div_1"></div>
<div id="inner_div_2"></div>
<div id="inner_div_3"></div>
</div>
By default, the "outer_div" is hidden. It appears while clicked on a button using Jquery show() function.
I wanted to do the following: On click within anywhere of "outer_div" excluding the area within "inner_div_1" , the "outer_div" would again be hidden. I failed while tried the following codes. What should I amend?
Attempted Jquery 1:
$("#outer_div:not(#inner_div_1)").on("click",function(){
$("#outer_div").hide("slow");
});
Attempted Jquery 2:
$("#outer_div").not("#inner_div_1").on("click",function(){
$("#outer_div").hide("slow");
});
Your support would be highly appreciated.
You need to consider that a click in the inner div is also a click on the outter div. That being said, you just need to check the target and target parents :
$("#outer_div").on("click",function(e){
if(!$(e.target).closest('#inner_div_1').length) $("#outer_div").hide("slow");
});
You can use some of the data in the event
$("#outer_div").on("click",function(e){
if( // Fast check to see if this is the div
e.target.id !=='inner_div_1'
// We limit the 'closest()' code to the outer div. This adds children to the exclude
&& $(this).closest('#inner_div_1, #outer_div')[0].id=='outer_div'){
alert('good click');
}
});
This is a solution for your code now, this works perfect when not too many excluding objects. But no wildcard selectors, which is nice.
And a jsFiddle demo.
Other properties can be used to, like a class:
$("#outer_div").on("click",function(e){
if( e.target.className!=='even'
&& $(this).closest('.even, #outer_div')[0].id=='outer_div'){
alert('yay, clicked an odd');
}
});
I made 7 lines, gave the even ones a class 'even'.
I am generating twitter bootstrap modals dynamically based on the user action (Long Story). Lets say some times user can see 100 modals on his screen. In each and every modal I have 5 dynamic buttons, each have it own purpose and did same in all modals, and have different id's.
I am attaching onClick events to those buttons by using jquery when ever there is a new twitter modal opens up by using the button id as follows
$(document).on("click","#btn"+btnNumber, function(){
//Code Goes Gere
});
So If I open 100 modals, each have 5 buttons, Is it good idea to assigning click events for 500 times ?
or Is it good Idea to assign click events by using it's name attribute for 1 time as follows
$(document).ready(function(){
$(document).on("click","btnNameAttr", function(){
//Code Goes Gere
});
});
The jQuery on() can help you in this. First you need to detach appending DATA to your element ID like btn+btnNumber. You can add your custom information in any data-x attribute like data-custom-info and use the jQuery attr('data-custom-info') syntax to retrieve the information. The event handlers registered with on() method is also available for future elements(elements created after script execution). Like below.
When creating new button, add render it as..
<input .... class="btnWithData" data-custom-info="1" ... />
<input .... class="btnWithData" data-custom-info="2" ... />
and your event handler goes like..
$(document).ready(function(){
$('body').on('click','.btnWithData',function(){
//DO WHATEVER
var buttonData=$(this).attr('data-custom-info');
//DO WHATEVER
});
});
You should assign delegated event listeners using jQuery.on() method as #Ananthan-Unni suggests, but in the form:
$.on('click', 'button', listener)
In this case you do not need to assign unique ids or attributes. You can use tag name or class name as a selector (2nd argument).
Have a look here: https://api.jquery.com/on/ and read on delegated events.
Best is don't use closures they require memory. Rely on good old data tags, instead:
$(document).ready(function () {
$("#wrapper").on("click", "btnNameAttr", function () {
var n;
n = $(this).data("number");
// code goes here
});
});
To differentiate the actually clicked element inside #wrapper you use data-number attributes like this:
<div id="wrapper">
<img data-number="000" />
<img data-number="001" />
<img data-number="002" />
<img data-number="003" />
</div>
This code will perform much better and you can still have all functionality you want by using wrapping <div> elements and data-number="" attributes. And you don't interfere with class or id attributes you might already have on those elements.
You can even add the command to the tag:
<img data-number="000" data-command="edit" />
<img data-number="000" data-command="show" />
<img data-number="000" data-command="delete" />
And switch on it:
switch ($(this).data("command"))
{
case "edit":
// edit element with number n here
break;
}
Is there any alternative solution (in JavaScript) for document.getElementById(); to select a specific element, specifying both the class and id ?
for example I have such a content:
<a class="q_href" onclick="showQuestion(1)">Question 1:</a>
<div class="q_content" id="1"></div>
<a class="q_href" onclick="showQuestion(2)">Question 2:</a>
<div class="q_content" id="2"></div>
And I want to select the corresponding div under the "Question X" link in the function
function showQuestion(id)
{
var thediv = GetByClassAndId("q_content",id); // how to implement this function ?
WriteQuestionIn(thediv); //Ajax
}
Thanks in advance.
you can try document.querySelector()
like document.querySelector(".q_content#2") use the para like css selector..
Since ID is always unique (unless u make a mistake) u have no need to use both class and id to select the element.
Such an approach is not correct, and should be avoided at all cost.
What I suspect is your problem, is that the ID is only a number. Try adding a prefix which is a letter. Do view source to this page to see examples.
<a class="q_href" onclick="showQuestion(1)">Question 1:</a>
<div class="q_content" id="q1"></div>
<a class="q_href" onclick="showQuestion(2)">Question 2:</a>
<div class="q_content" id="q2"></div>
function showQuestion(id)
{
var thediv = document.getElementById("q"+id);
WriteQuestionIn(thediv); //Ajax
}
Actually there is a function $ in jQuery for doing this operation. If you are using any framework, then you should remember there is always a jQuery library available. Else if you are using custom PHP, then add one of them like jQuery or other because they provide lots of types of selectors.
Now here is the code after adding jQuery:
$("#yourid") //basic selector
$("#yourid.yourclass").show()
Use .show() to show the selected element
Use .hide() To hide element