Here is what I want to do. I have the following html displaying projects from by db.
<div class="col-md-5">
<ul class="todo-projects-container">
<li class="todo-padding-b-0">
<div class="todo-head">
<button class="btn btn-square btn-sm green todo-bold">Add Project</button>
<h3>Projects</h3>
<p>4 Waiting Attention</p>
</div>
</li>
<?php foreach ($projects as $project): ?>
<li class="todo-projects-item">
<h3><?php echo $project->project_name ?></h3>
<p><?php echo $project->project_body ?></p>
<div class="todo-project-item-foot">
<p class="todo-red todo-inline">Project #<?php echo $project->project_id ?></p>
<p class="todo-inline todo-float-r">32 Members
<a class="todo-add-button" href="#todo-members-modal" data-toggle="modal">+</a>
</p>
</div>
</li>
<div class="todo-projects-divider"></div>
<?php endforeach; ?>
</ul>
</div>
When I first load the page, the first project receives the class="active" (using jquery) and whenever a click a project it removes the active class from the previous li and adds to the clicked one. So far so good.
Now I need to display the following:
<ul class="todo-tasks-content">
<li class="todo-tasks-item">
<h4 class="todo-inline">
<a data-toggle="modal" href="#todo-task-modal">Welcome to the hotel California</a>
</h4>
<p class="todo-inline todo-float-r">Bob,
<span class="todo-red">TODAY</span>
</p>
</li>
<li class="todo-tasks-item">
<h4 class="todo-inline">
<a data-toggle="modal" href="#todo-task-modal">Talking 'bout my generation</a>
</h4>
<p class="todo-inline todo-float-r">Shane,
<span class="todo-red">TODAY</span>
</p>
</li>
</ul>
On the above html all the info is obviously static. I know how to make ajax calls to fetch info from my db. What I don't really know how to do is displaying the corresponding tasks according to project_id whenever I click on a project.
I assume I need to make an ajax call and return the data along with some html and then do something like (dummy syntax)
onclick(function() {
var tasksHTML = insert ajax call here
});
Not sure if this is the right approach, I'm new to js. Any suggestions?
UPDATE:
Here is a picture:
In the picture, there is an active (clicked) project and on the right are the tasks that have that project id. How do I change the tasks list when I click a project?
First we need to give javascript a way to get the id so it can pass it to the PHP file that gets the tasks.
I assume you're binding JQuery click to the <li> so also include a data attribute and call it projectid. Or add this data attribute wherever the click method is bound.
<?php foreach ($projects as $project): ?>
<li class="todo-projects-item" data-projectid="$project['id']">
//.................
<?php endforeach; ?>
If you are using JQuery do this in your .click method
$('.todo-projects-item').click(function(){
//Get your project id from the data-attribute
projectId = $(this).data('projectid');
//run your ajax
$.post('phpfile.php', {projectId:projectId}, function(r){
//your phpfile.php should echo a json of the tasks
//see example below
$('.class-of-the-task-div').html(r.html);
}, 'JSON');
});
your php file can be something like this
$r['html'] = '<ul class="todo-tasks-content">
<li class="todo-tasks-item">
//....................Stuff
</li>
</ul>';
echo json_encode($r);
Related
i have this div in my homepage.php file:
<?php foreach($posts as $post): ?>
</div class="post>
<div class="options">
<div class="option"></div>
<div class="option"></div>
<div class="option"></div>
</div>
<div class="none editanddelete">
<button type="button" class="edit">edit</button>
<button type="button" class="delete">delete</button>
</div>
<div class="imageandname">
<img src="<?php echo $post->user_image ?>">
<div class="username"><?php echo $post->username ?></div>
</div>
<div class="post_body">
<?php echo $post->post_body ?><br>
</div>
</div>
<?php endforeach; ?>
the $posts is array that is coming from database through controller and each time i publish a post, the body will add new div like above with the data needed from the $post array, now as shown above, the child div with class "editanddelete" is hidden by giving class "none" which is display:none;
now with javascript i want to make an event where when i click on the child div with class="options", it toggles the "none" class of the child div with class="editanddelete", like the following:
post = document.querySelector('.post');
options = post.querySelector('.options');
editanddelete = options.querySelector('.editanddelete');
options.addEventListener('click', () => {
editanddelete.classList.toggle('none');
})
when i execute this code, it works fine on the first post (div) that is dynamically created, but when i add another post, the event will not work on the second post div, i tried to use querySelectorAll and loop "options" classes that will be created dynamically, but it just does not work as expected and the event affects other divs, what i want is to make the event for all divs, every div on it's own
You need to work with the same .editanddelete element as .options is clicked.
JS code could be like
var options = document.querySelector('.options');
// here maybe would be for cycle over options (I can't test it now)
options.addEventListener('click', () => {
this.parentNode.querySelector('.editanddelete').classList.toggle('none');
})
(This is an extension of a series of questions I have asked previously as I'm going through the process of learning how to work with Wordpress)
I'm using a small javascript to turn on and off the display of posts on a page, depending on the posts respective category. The script enables a group of filter buttons at the top of the page to switch between displaying posts that belong to a certain category.
Now I would like to change the page's code so that upon loading the page for the first time (i.e. before any of the filter buttons have been clicked) there is no content/posts being displayed at all. Right now when accessing the page, all posts which belong to the parent category of the sub-categories (which the buttons allow to filter) are being displayed.
How do I have to change the site to do so?
An online version of the site can be visited here: http://udkdev.skopec.de/category/studierende/
Here's the site's code along with the javascript of the filter-button at the bottom:
<?php get_header(); ?>
</div>
<br>
<div class="wrapper-offset-fix wrapper-studierende">
<div class="projekte content">
<div class="button-group filters-button-group">
<button class="projekt-btn btn" id="category-stud-sose17">SoSe 2017</button>
<button class="projekt-btn btn" id="category-stud-wise1617">WiSe 2016/17</button>
<button class="projekt-btn btn" id="category-wise-201415">SoSe 2016 </button>
<button class="projekt-btn btn" id="category-sose-14">WiSe 2015/16</button>
<button class="projekt-btn btn" id="category-sose-14">SoSe 2015 </button>
<button class="projekt-btn btn" id="category-sose-14">WiSe 2014/15</button>
</div>
<?php if (have_posts()): ?>
<?php while(have_posts()): the_post(); ?>
<div <?php post_class(); ?>>
<?php
if ( has_post_thumbnail() ) {
the_post_thumbnail('full');
} ?>
<?php the_content(); ?>
</a>
<!--<div class="meta">Tags: <?php the_tags( '', ', ', '<br />' ); ?> </div>-->
</div>
<?php endwhile; ?>
<?php else : ?>
<h2>Couldn’t find any articles!</h2>
<?php endif; ?>
</div>
<script>
var $btns = $('.btn').click(function() {
if (this.id == 'all') {
$('.projekte > .post').fadeIn(300);
} else {
var $el = $('.' + this.id).fadeIn(300);
$('.projekte > .post').not($el).fadeOut(300);
}
$btns.removeClass('active');
$(this).addClass('active');
})
</script>
<?php get_footer(); ?>
You can begin this by first hiding all the posts. One way to do this would be add a CSS style
.projekte .post {display:none;}
Looking at your codes, rest should just work out by itself. I would however swap these lines so that the posts are removed before the new ones are added like this:
$('.projekte > .post').not($el).fadeOut(300);
var $el = $('.' + this.id).fadeIn(300);
in this issue, i use booster widgets tbcollapse to make some like a inbox in message menu, unread or new message is have status 0, so when i click the panel title in collapse widgets, it will open div with id #collapse, and change the status in database to be 1 (readed), its possible??? how?
<?php $collapse = $this->beginWidget('booster.widgets.TbCollapse');
<div class="panel-group" id="accordion">
<?php for ($a = 0; $a<count($pesan); $a++){ ; ?>
<div class="panel panel-warning">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#collapse<?php echo $a ;?>">
<?php echo $pesan[$a]["sender"] ;?>
</a>
</h4>
</div>
<div id="collapse<?php echo $a ;?>" class="panel-collapse collapse">
<div class="panel-body">
<?php echo $pesan[$a]["message"] ;?>
</div>
</div>
</div>
<?php }; ?>
</div>
Just use bootstrap's collapse events to trigger an ajax call, for what you want probably the best option is the shown.bs.collapse event, for example:
$('#myCollapsible').on('shown.bs.collapse', function () {
//Get the id of the message and use ajax to update the database
});
Edit #1
A little example:
First add a custom id to your widget
<?php $collapse = $this->beginWidget('booster.widgets.TbCollapse',
array('id'=>"myCollapsible")
);?>
At the end of your view add a script tag, or you can register a script with yii's CClientScript. For the sake of simplicity I will use script tags
<script>
$(function(){
$('#myCollapsible').on('shown.bs.collapse', function (e) {
var target=$(e.target);//get shown element
if(target.attr('id')===$(this).attr('id'))return;//Event is fired on page load, ignore event on main collapse
$.post('controllerUrl',{messageId:$(e.target).attr("id")},function(data){//call server to update
//do something if everything was ok or display error
});
});
});
</script>
In your controller just add a method to update the message status
public function actionUpdateMessage{
MessageModel::model()->updateByPK($_POST['messageId'],'viewed'=>'1');//update the model whose id was sent, provide some validation if needed
return;//end processing
}
Hope this helps
Edit #2
In case you need to put more metadata for the ajax call, I recommend to use data attributes in your elements, so for example you could add an Id based on your database
<div id="collapse<?php echo $a ;?>" class="panel-collapse collapse"
data-messageId="<?php echo $pesan[$a]["id"] ;?>">
<div class="panel-body">
<?php echo $pesan[$a]["message"] ;?>
</div>
</div>
And in the javascript code you can retrieve the info with data method like the following
<script>
$(function(){
$('#myCollapsible').on('shown.bs.collapse', function (e) {
var target=$(e.target);//get shown element
if(target.attr('id')===$(this).attr('id'))return;//Event is fired on page load, ignore event on main collapse
$.post('controllerUrl',{messageId:$(e.target).data("messageId")},function(data){//call server to update
//do something if everything was ok or display error
});
});
});
</script>
Edit #3
If retrieving data attributes using jquery data method doesn't work, you still can access these attributes using attr method
$.post('controllerUrl',{messageId:target.attr("data-messageId")},function(data){//call server to update
//do something if everything was ok or display error
});
If the data attributes aproach doesn't work, you can also try with hidden fields like this:
Firs, instead of setting data-messageId attribute, add inside your panel-collapse div an input hidden like the following:
<div id="collapse<?php echo $a ;?>" class="panel-collapse collapse">
<input type="hidden" value="<?php echo $pesan[$a]["id"] ;?>"/>
<div class="panel-body">
<?php echo $pesan[$a]["message"] ;?>
</div>
</div>
Then, change the following in the javascript:
$.post('controllerUrl',{messageId:target.find("input").val()},function(data){//call server to update
//do something if everything was ok or display error
});
I have an area on my Wordpress theme where I am showing info about a random taxonomy. Basically, the taxonomy is "playwrights" and I am featuring a random one on the home page. Here is the HTML:
<div id="home-top-right">
<?php
$allpw = get_terms( 'playwrights', 'hide_empty=0' );
$randpw = $allpw[ array_rand( $allpw ) ];
$randpw = get_term($randpw->term_id, 'playwrights');
$pwlink = get_term_link($randpw->term_id, 'playwrights');
?>
<div class="title">
Playwright Spotlight
<li class="fa fa-refresh refresh"></li>
</div>
<div class="content" id="p-spotlight">
<?php if (get_field('image', 'playwrights_'.$randpw->term_id)) { ?>
<div class="thumb">
<?php $imageid = get_field('image', 'playwrights_'.$randpw->term_id); ?>
<a href="<?php echo $pwlink; ?>">
<?php echo wp_get_attachment_image($imageid, 'pwthumb'); ?>
</a>
</div>
<?php } ?>
<div class="text">
<div class="sub-title">
<?php echo $randpw->name; ?>
</div>
<?php echo print_excerpt('', '200'); ?>
</div>
</div>
</div>
I want to be able to click a button (in the code, it is the <i> tag) and reload just that section (not the whole page) with a new random taxonomy term (playwright). I'm not great at JS/jquery and I'm not able to find a tutorial online that gets me where I need to go, especially considering the exchange between post data and the js function.
How should I go about this?
By default, WordPress has an admin-ajax.php file which you can send AJAX calls to. You can create a hook that is linked to your own custom function in which you can do the stuff you want, like getting the random term and send it back to the client.
Then you can pass a value to your AJAX call, called 'action'. When admin-ajax.php is getting a POST request with the action you 'hooked', your custom function is being executed.
Have a look at the links below for a more detailed explanation:
http://premium.wpmudev.org/blog/how-to-use-ajax-with-php-on-your-wp-site-without-a-plugin/
http://codex.wordpress.org/AJAX_in_Plugins
I'm new to jQuery and am having trouble figuring out the right way to loop a set of code for a basic carousel/banner rotator. I've tried a few versions of "for" statements and .each(), but I can't get it to work on my own so I'm reaching out for help.
Here's my code so far:
$('.next-1').click(function () {
$('.featured-1').fadeOut(500,function(){
$('.featured-2').fadeIn(500,function(){
$('.featured-2').toggleClass("hide");
});
});
});
$('.next-2').click(function () {
$('.featured-2').fadeOut(500,function(){
$('.featured-3').fadeIn(500,function(){
$('.featured-3').toggleClass("hide");
});
});
});
And then a similar code block for going back within the slider:
$('.prev-2').click(function () {
$('.featured-2').fadeOut(500,function(){
$('.featured-1').fadeIn(500,function(){
$('.featured-2').toggleClass("hide");
});
});
});
$('.prev-3').click(function () {
$('.featured-3').fadeOut(500,function(){
$('.featured-2').fadeIn(500,function(){
$('.featured-3').toggleClass("hide");
});
});
});
This code does work right now, I just don't want to have to output so many unnecessary lines of code when I know I could loop it. I'd like to be able to loop until there are no more "featured-n" divs to cycle through (being able to cycle around to the beginning would be great too!)
Here's the PHP/HTML I'm using to generate each "featured-n" div block:
function home_slider_loop() {
$count = 0;
query_posts ('tag=slider');
if (have_posts()) : while (have_posts()) : the_post();
$count++;
?>
<div class="featured-post featured-<?php echo $count; if ($count>1) { echo ' hide';}?>">
<div class="featured-header">
<h1 class="featured-title"><?php the_title(); ?></h1>
<p class="author">Written by Evan Luzi</p>
</div>
<div class="image-wrap">
<?php the_post_thumbnail('full', array('class' => 'slider-image')); ?>
<div class="slider-nav">
<div class="featured-prev prev-<?php echo $count; ?>"></div>
<div class="featured-next next-<?php echo $count; ?>"></div>
</div><!--End Navigation-->
</div><!--End Image <?php echo $count; ?>-->
<div class="featured-footer">
<?php the_excerpt(); ?>
<a class="more-link" href="<?php the_permalink(); ?>" alt="<?php the_title(); ?>" >Read more</a>
</div>
</div><!--End Featured <?php echo $count; ?>-->
<?php
endwhile;
endif;
}
Here's a sample of one of the static HTML outputs (just imagine this iterated several times with the "featured-n" classes incrementing:
<div class="featured-1">
<div class="featured-header">
<h1 class="featured-title">5 Useful Cinematography Apps for iOS You Should Download Today</h1>
<p class="author">Written by Evan Luzi</p>
</div>
<div class="image-wrap">
<img width="1018" height="416" src="http://www.tbabdev.com/wp-content/uploads/2013/07/cinematography-apps-8-hero.jpg" class="slider-image wp-post-image" alt="cinematography-apps-8-hero" />
<div class="slider-nav">
<div class="featured-prev prev-1"></div>
<div class="featured-next next-1"></div>
</div><!--End Navigation-->
</div><!--End Image 1-->
<div class="featured-footer">
<p>The devices we have in our pockets, the ones that can run these apps, these are the new leathermans. They have everything we need. They eliminate the need to carry paper manuals and enable us to do complex timelapse calculations in a fraction of the time as a paper and pen.</p>
<a class="more-link" href="http://www.tbabdev.com/?p=27" alt="5 Useful Cinematography Apps for iOS You Should Download Today" >Read more</a>
</div>
</div><!--End Featured 1-->
You can see the code in action at http://www.tbabdev.com/
Thank you in advance for your help and please be kind to a n00b :)
Use something like this :
$('.nav .prev').click(function(){
activeBlock = $('.featured.active');
prevBlock = activeBlock.prev('.featured');
activeBlock.fadeOut('slow',function(){
prevBlock.fadeIn().addClass('active');
}).removeClass('active');
});
$('.nav .next').click(function(){
activeBlock = $('.featured.active');
nextBlock = activeBlock.next('.featured');
activeBlock.fadeOut('slow',function(){
nextBlock.fadeIn().addClass('active');
}).removeClass('active');
});
Html
<div class="nav">
<div class="prev"> </div>
<div class="next"> </div>
</div>
<div class="featured-post featured <?php if($count>1) echo 'hide' ?>">
<div class="featured-header">
<h1 class="featured-title"><?php the_title(); ?></h1>
<p class="author">Written by Evan Luzi</p>
</div>
<div class="image-wrap">
<?php the_post_thumbnail('full', array('class' => 'slider-image')); ?>
</div>
<!--End Image <?php echo $count; ?>-->
<div class="featured-footer">
<?php the_excerpt(); ?>
<a class="more-link" href="<?php the_permalink(); ?>" alt="<?php the_title(); ?>" >Read more</a>
</div>
</div>
You could do it this way :
$('.featured-next, .featured-prev').click(function () {
//find out if the clicked element is a prev or next element, extract the last part, will be useful later
var direction = $(this).hasClass("featured-next") ? "next" : "prev";
//select the ".featured-n" block which is the super-parent of clicked element
var $fullBlock = $(this).closest('div[class^="featured-"]'); //or add a class here to make your life easier
//fade out full block
$fullBlock.fadeOut(500, function () {
//search for the next element and show it
//note that $fullBlock.next() => $fullBlock["next"]() => $fullBlock[direction]()
$fullBlock[direction]().fadeIn(500, function () {
//toggle the class "hide" of the element next to fullBlock
$(this).toggleClass("hide");
});
});
});
Explanation:
You can join up both prev and next events together.
Then, you have to check if its a next or a prev element. Set that to a variable called direction. We'll be using this to find out if we have to use prev() or next() when we're trying to fadeIn featured-n divs.
Find the parent with the class set to featured-n (in your case its the superparent). It might be better if you give a common class to all these elements so that we can stop using 'div[class^="featured-"]' selector, which is slightly inefficient.
Fade out the superparent.
In the callback, based on the direction variable, we'll have to decide if the carousel is gonna go to prev block or next block, something like this :
if(direction === "prev")
{
$fullBlock.prev().fadeIn(//your code)
}
else
{
$fullBlock.next().fadeIn(//your code)
}
You must also know that, in an object like this :
var data = {"name" : "Blah Blah"}
To get the "Blah Blah" out, we can say
data.name
or we could say :
data["name"]
So based on this, in our situation, instead of
$fullBlock.prev()
Or we could say
$fullBlock["prev"]()
Which is what direction variable contains. So finally, we could do this to select the next/prev element based on what was clicked :
$fullBlockdirection
Show the prev/next element.
Add/remove "hide" class.
Hope this helped!