I am using CakePHP for an application where I am trying to add some Ajax functionality to update in page content.
JavaScript libraries: Prototype, Scriptaculous, jQuery, jEditable
By default: Load 5 rows and option to load 10 more rows on the page
Editable options: clicking on a field will use the jEditable to allow users to edit the fields and save.
Current situation: When the page loads for the first time, all functionalities work, but when I load 10 more rows, the JavaScript functions stop working.
Here is the index view file which calls an element containing all the entries with the JavaScript functions:
<div id="latestResults" class="wrap">
<?php
echo $this->element('current_entries', array('entries' => $entries));
?>
</div>
<script type="text/javascript">
var clientsInput= <?php echo json_encode($clients); ?>;
$j('.client').editable("<?php echo $this->Html->url(array('controller'=>'entries', 'action'=>'editEntryClient')); ?>/", {
data : clientsInput,
name : 'data[Entry][client_id]',
type : 'select',
onblur : 'submit'
});
//Inline editor for projects
var projectsInput= <?php echo json_encode($projects); ?>;
$j('.project').editable("<?php echo $this->Html->url(array('controller'=>'entries', 'action'=>'editEntryProject')); ?>/", {
data : projectsInput,
name : 'data[Entry][project_id]',
type : 'select',
onblur : 'submit'
});
//Inline editor for tasks
var tasksInput= <?php echo json_encode($tasks); ?>;
$j('.task').editable("<?php echo $this->Html->url(array('controller'=>'entries', 'action'=>'editEntryTask')); ?>/", {
data : tasksInput,
name : 'data[Entry][task_id]',
type : 'select',
onblur : 'submit'
});
//Inline editor for hours spent
$j('.hours_spent').editable("<?php echo $this->Html->url(array('controller'=>'entries', 'action'=>'editEntryHoursSpent')); ?>/", {
name : 'data[Entry][hours_spent]',
onblur : 'submit'
});
//Inline editor for notes
$j('.notesCol').editable("<?php echo $this->Html->url(array('controller'=>'entries', 'action'=>'editEntryDescription')); ?>/", {
name : 'data[Entry][description]',
onblur : 'submit'
});
//Load more
$j('#load_more').click(function(){
//Get last id
var currentNumberOfRows = $j('.row').length;
var newNumberOfRowsToDisplay =currentNumberOfRows + 10;
var urlToGet = "<?php echo $this->Html->url(array('controller'=> 'entries', 'action'=>'displayCurrentEntries')); ?>/" + newNumberOfRowsToDisplay;
$j.get(urlToGet, function(data){
$j('#latestResults').html(data);
});
});
<?php echo $this->Html->script('inpage', array('inline'=>true)); ?>
current_entries.ctp
<?php
$i = 0;
foreach ($entries as $entry):
$class = null;
if ($i++ % 2 == 0) {
$class = ' class="altrow"';
}
$div_id = null;
$div_id = "id='entry_".$entry['Entry']['id']."'";
$row_id = "id='row_".$entry['Entry']['id']."'";
?>
<!-- ROW 1 -->
<div class="row">
<!-- clients -->
<div class="clientCol">
<div class='client result' id='client_<?php echo $entry['Entry']['id']; ?>'><?php echo $entry['Client']['name']; ?></div>
</div>
<!-- projects -->
<div class="projectCol">
<div class='project result' id='project_<?php echo $entry['Entry']['id']; ?>'><?php echo $entry['Project']['name']; ?> </div>
</div>
<!-- tasks -->
<div class="taskCol">
<div class='task result' id='task_<?php echo $entry['Entry']['id']; ?>'><?php echo $entry['Task']['name']; ?> </div>
</div>
<!-- hours -->
<div class="hoursCol">
<div class='hours_spent result' id='hours_spent_<?php echo $entry['Entry']['id']; ?>'><?php echo $entry['Entry']['hours_spent']; ?> </div>
</div>
<!-- Date -->
<div class="dateCol">
<?php echo $entry['Entry']['date_of_task']; ?>
</div>
<!-- notes -->
<div class="notesCol" id='description_<?php echo $entry['Entry']['id']; ?>'>
<?php echo $entry['Entry']['description']; ?>
</div>
<!-- submit -->
<div class="submitCol">
<div class="options">
<a class="duplicate" href=""></a>
<?php echo $ajax->link('', array('controller'=>'entries', 'action' => 'delete', $entry['Entry']['id']), array('class'=>'remove', 'update'=>'latestResults'), 'Are you sure you want to delete this?'); ?>
</div>
</div>
<div class="clear"> </div>
</div>
<?php endforeach; ?>
<!-- //ROW 1 -->
<!-- Load Row -->
<div class="row load">
Load 10 more rows
</div>
<!-- // Load Row -->
When the page loads, all the $j('div.class').editable('') functions work. But whenever it is loading more rows, all these functions stop working alltogether. I might be missing something really simple here, but any help or guidance on this would be brilliant. Note that the loadmore only updates the #latestResults in page through the Ajax call.
Thanks a million in advance.
Regards
Tas
Related
I have a page for team members of a company. The team members are rendered with an ACF repeater that has fields for Name, Job Title, and Biography. On the page I would like to render just their Name, and Job Title. If you were to click on a team member, that would open a modal that would render that team members biography.
I have this working, but my approach adds the Biography field to the DOM for each team member, hides it, and passes it into the modal on click. I am wondering if it is possible to pass the Biography field into the modal without having to render the text in the DOM initially and hiding it?
Below is my current code:
<!-- acf repeater -->
<?php if( have_rows('team_member') ): ?>
<?php while( have_rows('team_member') ): the_row();
$name = get_sub_field('name');
$job_title = get_sub_field('job_title');
$biography = get_sub_field('biography');
?>
<div class="team-member">
<div>
<?php echo $name ?>
</div>
<div>
<?php echo $job_title ?>
</div>
<div class="biography" style="display: none;">
<?php echo $biography ?>
</div>
</div>
<?php endwhile; ?>
<!-- modal -->
<div class="modal">
modal
<div class="modal-biography">
</div>
</div>
<?php endif; ?>
<!-- javascript -->
jQuery(function($) {
$('.team-member').on('click', function() {
var modalBiography = $(this).find('.biography').text();
$('.modal-biography').text(modalBiography);
})
});
If you don't need to display the bio div, I'd suggest just putting it into a data-bio attribute:
<div class="team-member" data-bio="<?php echo $biography; ?>">
<div><?php echo $name; ?></div>
<div><?php echo $job_title; ?></div>
</div>
then tweak js a bit to pull this data-bio instead:
jQuery(function($) {
$('.team-member').on('click', function() {
var modalBiography = $(this).data('bio');
$('.modal-biography').text(modalBiography);
})
});
I'm showing a loading bar before the content loads successfully. And after load I am displaying the content by jQuery but when i visit the page first time the loader is showing forever and the on load event isn't firing. It fires when i manually refresh the page. What's wrong with my code?
Event call code:
$(window).on('load', function(){
$("#slider-pre-loader").fadeOut("slow");
$("#video-blog-slider").fadeIn();
});
Dynamic HTML:
<div id="slider-pre-loader"></div>
<div id="video-blog-slider" style="display: none">
<div class="blog-category-items blog-page" id="blogIndex">
<div class="container">
<?php
$hpos = 0;
foreach ($categories as $category):
$categoryhref = fakeUrl::genSlugFromText($category['name']);
$listVideos = $category['videos'];
if (in_array($category['name'], $categoryDisplay)) :
?>
<div class="blog-groups">
<div class="group-heading">
<h3>
Test title
</h3>
</div>
<?php if ($category['desc'] != '') :?>
<p class="group-desc"><?php echo $category['desc'];?></p>
<?php endif;?>
<?php
$slideClass = '';
if (!$detect->isMobile() && !$detect->isTablet() ) {
$slideClass = 'blog-slider';
}
?>
<div class="<?php echo $slideClass;?> owl-lg-dot mb-none owl-theme owl-loaded" id="videoList">
<?php
$v = 0;
foreach ($listVideos as $video) :
$v++;
$itemClass = '';
if (($detect->isMobile() || $detect->isTablet()) && $v > 5) {
$itemClass = 'item-disable';
}
$videoSlug = fakeUrl::genSlugFromText($video['title']);
?>
<div class="blog-item <?php echo $itemClass;?>">
<div class="blog-image">
<a href="/blog/<?php echo $videoSlug; ?>" title="<?php echo $video['title'];?>">
</a>
</div>
<div class="caption">
<a class="blog-list-video-title" href="/blog/<?php echo $videoSlug; ?>" title="<?php echo $video['title'];?>">
</a>
</div>
<div class="blog-metas">
<small class="blog-views"><?php echo number_format($video['views']); ?> views</small>
</div>
</div>
<?php
endforeach;
?>
</div>
</div>
<?php
endif;
endforeach;
?>
</div>
</div>
</div>
jQuery placed before event call:
<script src="//code.jquery.com/jquery-1.11.3.min.js" async></script>
Don't place async attribute on your script tags unless you really need your script file to be loaded asynchronously. Right now, your 'jQuery' code is being loaded asynchronously, i.e. jQuery is most probably not loaded when you are trying to attach your event.
The only explanation for it working the second time upon manual refresh is that the browser is 'synchronously' loading the cached resource. Different browsers do this differently, so you can expect inconsistent behaviour there.
Just remove the async attribute, and you should see your event firing every time.
The $(window) selector is for selecting the viewport whereas the $(document) selector is for the entire document (that is, what's inside the <html> tag).
Try using the following:
$(document).on('load', function(){
$("#slider-pre-loader").fadeOut("slow");
$("#video-blog-slider").fadeIn();
});
I hope this working with you, I have created example you will be woking with document.ready it means JQuery see and focus on all elements in your web page, here is fiddle
Simple for test
<div id="slider-pre-loader">no</div>
<div id="video-blog-slider" style="display: none">
hi
</div>
OR your code
<div id="slider-pre-loader">no</div>
<div id="video-blog-slider" style="display: none">
<div class="blog-category-items blog-page" id="blogIndex">
<div class="container">
<?php
$hpos = 0;
foreach ($categories as $category):
$categoryhref = fakeUrl::genSlugFromText($category['name']);
$listVideos = $category['videos'];
if (in_array($category['name'], $categoryDisplay)) :
?>
<div class="blog-groups">
<div class="group-heading">
<h3>
Test title
</h3>
</div>
<?php if ($category['desc'] != '') :?>
<p class="group-desc"><?php echo $category['desc'];?></p>
<?php endif;?>
<?php
$slideClass = '';
if (!$detect->isMobile() && !$detect->isTablet() ) {
$slideClass = 'blog-slider';
}
?>
<div class="<?php echo $slideClass;?> owl-lg-dot mb-none owl-theme owl-loaded" id="videoList">
<?php
$v = 0;
foreach ($listVideos as $video) :
$v++;
$itemClass = '';
if (($detect->isMobile() || $detect->isTablet()) && $v > 5) {
$itemClass = 'item-disable';
}
$videoSlug = fakeUrl::genSlugFromText($video['title']);
?>
<div class="blog-item <?php echo $itemClass;?>">
<div class="blog-image">
<a href="/blog/<?php echo $videoSlug; ?>" title="<?php echo $video['title'];?>">
</a>
</div>
<div class="caption">
<a class="blog-list-video-title" href="/blog/<?php echo $videoSlug; ?>" title="<?php echo $video['title'];?>">
</a>
</div>
<div class="blog-metas">
<small class="blog-views"><?php echo number_format($video['views']); ?> views</small>
</div>
</div>
<?php
endforeach;
?>
</div>
</div>
<?php
endif;
endforeach;
?>
</div>
</div>
</div>
Javascript:
$(document).ready(function() {
$("#slider-pre-loader").fadeOut('slow');
$("#video-blog-slider").fadeIn('slow');
});
I have traveled many articles Stack OverFlow but none have solved my problem. I just want to use Ajax with Cake php to refresh a DIV containing the results of my pagination.
Note:
I included the jQuery library.
I called the RequestHandler component:
public $components = array('RequestHandler');
public function beforeFilter() {
if($this->RequestHandler->isAjax()){
$this->layout=null;
Configure::write('debug', 0);
}
}
I checked the presence of a "ajax.ctp" in the layout folder
Here is my search function:
public function searchIndex(){
//debug($this->request->data); die;
$search = $this->request->data['Concessionnaire']['search'];
$this->Paginator->settings = array(
'conditions' => array('Concessionnaire.ville LIKE' => '%'.$search.'%'),
'limit' => 5
);
$data = $this->Paginator->paginate('Concessionnaire');
$this->set('concessionnaires', $data);
$this->render('index');
}
Views :
<div class="row">
<div class="large-12 columns">
<div class="panel">
<h4>Recherchez une ville :</h4>
<?php echo $this->Form->create('Concessionnaire',array('id' => 'textBox', 'type' => 'post','url' => array('controller' => 'concessionnaires', 'action' => 'searchIndex'))); ?>
<?php echo $this->Form->input('search', array('label'=>"",'placeholder'=>'Tapez le nom d\'une ville, puis la touche Entree de votre clavier' ,'id'=>'search')); ?>
<?php echo $this->Form->end(); ?>
</div>
</div>
</div>
<div class="row">
<div class="large-12 columns">
<div class="panel" id="conssR">
<!-- generation vignettes -->
<?php foreach ($concessionnaires as $concessionnaire): ?>
<div class="panel conssPanel radius">
<h4><b><?php echo h($concessionnaire['Concessionnaire']['nom']); ?></b></h4>
<div class="row">
<div class="large-6 columns" style="padding-left: 70px; font-size: 20px;">
<?php echo h($concessionnaire['Concessionnaire']['adresse']); ?><br>
<?php echo h($concessionnaire['Concessionnaire']['cp']); ?>
<?php echo h($concessionnaire['Concessionnaire']['ville']); ?>
<!-- <p>It's a little ostentatious, but useful for important content.</p> -->
</div>
<div class="large-6 columns" style="font-size: 20px; text-align: center;">
Tel: <?php echo h($concessionnaire['Concessionnaire']['tel']); ?><br>
Site: <?php echo h($concessionnaire['Concessionnaire']['website']); ?>
</div>
</div>
<?php
// $map_id = "map_canvas";
// $marker_id = 1;
// $position = "rue du depot, 62000 ARRAS";
// echo $this->GoogleMap->addMarker($map_id, $marker_id, $position);
?>
</div>
<?php endforeach; ?>
</div>
</div>
</div>
I want to reload the DIV "#conssR" with the string results entered in the form "Concessionnaires". For now , when i write something and valid, the controller show me the result by refreshing the page but I just want to recharge the DIV.
Thank you in advance for your help
$this->Paginator->options(array(
'update' => '#conssR',
'evalScripts' => true
));
The code above is not part of function it is part of view files which are in View folder and it creates the proper JavaScript to update the div.
Check : http://book.cakephp.org/2.0/en/core-libraries/helpers/paginator.html
It is a helper and helper code goes in your view
if($this->request->is('ajax'))
{
$this->render('/Elements/ajax');
}
The above code is used to render ajax.ctp in View/Elements folder which you are not doing at the moment.
I'm creating my web page using Yii. When I created the page, Yii created a form very similar than the following:
<?php
/* #var $this SiteController */
/* #var $model ContactForm */
/* #var $form CActiveForm */
$this->pageTitle=Yii::app()->name . ' - Contact';
$this->breadcrumbs=array(
'Contact',
);
?>
<?php if(Yii::app()->user->hasFlash('contact')): ?>
<div class="flash-success">
<?php echo Yii::app()->user->getFlash('contact'); ?>
</div>
<?php else: ?>
<div class="form">
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'contact-form',
'enableClientValidation'=>true,
'clientOptions'=>array(
'validateOnSubmit'=>true,
),
)); ?>
<p class="note"><?php echo Yii::t('app','Fields with');?> <span class="required">*</span> <?php echo Yii::t('app','are required.');?></p>
<?php echo $form->errorSummary($model); ?>
<div class="row">
<?php echo $form->labelEx($model,'name'); ?>
<?php echo $form->textField($model,'name'); ?>
<?php echo $form->error($model,'name'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'email'); ?>
<?php echo $form->textField($model,'email'); ?>
<?php echo $form->error($model,'email'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'subject'); ?>
<?php echo $form->textField($model,'subject',array('size'=>60,'maxlength'=>128)); ?>
<?php echo $form->error($model,'subject'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'body'); ?>
<?php echo $form->textArea($model,'body',array('rows'=>6, 'cols'=>50)); ?>
<?php echo $form->error($model,'body'); ?>
</div>
<?php if(CCaptcha::checkRequirements()): ?>
<div class="row">
<?php echo $form->labelEx($model,'verifyCode'); ?>
<div>
<?php $this->widget('CCaptcha'); ?>
<?php echo $form->textField($model,'verifyCode'); ?>
</div>
<div class="hint"><?php echo Yii::t('app','Please enter the letters as they are shown in the image above.');?>
<br/><?php echo Yii::t('app','Letters are not case-sensitive.');?></div>
<?php echo $form->error($model,'verifyCode'); ?>
</div>
<?php endif; ?>
<div class="row buttons">
<?php echo CHtml::submitButton('Submit'); ?>
</div>
<?php $this->endWidget(); ?>
</div><!-- form -->
<?php endif; ?>
In the begining, this form worked, but after that, I improved the web page adding more features. Few minutes ago, I was checking all the page and I saw that the reloaded captcha button didn't work. Now, When I try to reload the captcha, the web page is reloaded and display a empty page with this code:
{"hash1":774,"hash2":774,"url":"\/MyApp\/site\/captcha.html?v=526045d3d1187"}
I tried to search for some similar error in google, but I didn't find anything. To be honest, I don't understand what is happening. I guess that the code that I added in another file of my web page produce this error, but I don't have any idea...I don't understand what means this code.
Please, I need your help!
Someone could help me? THANKS
EDIT:
If I look the source code of the web page on my browser, and I search for "captcha.html", I can see the following code:
<script type="text/javascript">
/*<![CDATA[*/
jQuery(function($) {
jQuery('#yw0').after("<a id=\"yw0_button\" href=\"\/MyApp\/site\/captcha.html?refresh=1 \">Obtenga un nuevo c\u00f3digo<\/a>");
jQuery(document).on('click', '#yw0_button', function(){
jQuery.ajax({
url: "\/MyApp\/site\/captcha.html?refresh=1",
dataType: 'json',
cache: false,
success: function(data) {
jQuery('#yw0').attr('src', data['url']);
jQuery('body').data('captcha.hash', [data['hash1'], data['hash2']]);
}
});
return false;
});
But I didn't find the captcha.html in any place...
EDIT 2:
I found the problem. I added javascript code at the end of the main page of my wep page. I added this:
<script type="text/javascript" src="<?php echo Yii::app()->theme->baseUrl; ?>/scripts/jquery-1.4.1.min.js"></script>
<script type="text/javascript" src="<?php echo Yii::app()->theme->baseUrl; ?>/scripts/jquery-ui-1.8.12.custom.min.js"></script>
<script type="text/javascript" src="<?php echo Yii::app()->theme->baseUrl; ?>/scripts/jquery-photostack.js"></script>
<script type="text/javascript" src="<?php echo Yii::app()->theme->baseUrl; ?>/scripts/jquery-coin-slider.min.js"></script>
If I remove this code, the captcha can be reload correctly. Please, someone could tell me what I'm doing badly here? Why my javascript code produce this? How can I solve it?
The problem is this code in CCaptcha Yii widget:
jQuery(document).on('click', '$selector', function(){
jQuery.ajax({
...
});
return false;
});
The click listener is on document, instead of the element itself. When you add your script tags after this code, you load a new jQuery version that clears all those listeners on init.
To solve this, use only one jQuery version, preferably Yii included one.
If you really want to replace it, do it the right way, in CClientScript->scriptMap in config, set the value of jquery.js and jquery.min.js keys to the new URL of jQuery.
Have a look here:
http://test.neworgan.org/100/
Scroll down to the community section.
What I'm trying to achieve is to get the data for new organizers, (e.g.: number of friends / amount donated) to show once users click on their thumbnails. right now each user has his or her own unique data stored externally.
Once the users click the thumbnail, 'inline1' appears with the content.
As of now, I'm only able to get the data from the last user to show regardless of whichever user's thumbnails I'm clicking on. I just need a bit of help as to how to change the content depending on which thumbnail users click. So I was wondering if I could have some help here?
Here's that part of the code that matters:
<div class="top-fundraisers-wrapper">
<div class="subsection top-fundraisers">
<?php if ($top_fundraisers && is_array($top_fundraisers)): ?>
<?php foreach ($top_fundraisers as $index => $fundraiser): ?>
<a title="" class="fancybox" href="#inline1">
<div class="top-fundraiser">
<div id="newo<?php print htmlentities($index + 1); ?>" class="top-fundraiser-image">
<img src="<?php
if($fundraiser['member_pic_medium']) {
print htmlentities($fundraiser['member_pic_medium']);
} else {
print $template_dir . '/images/portrait_placeholder.png';
}
?>"/>
</div>
</div>
</a>
<?php endforeach;?>
<?php endif; ?>
</div>
</div>
</div>
<div id="inline1">
<div class="top-fundraiser-image2">
<img src="<?php
if($fundraiser['member_pic_large']) { print htmlentities($fundraiser['member_pic_large']);
} else {
print $template_dir . '/images/portrait_placeholder.png';
}
?>"/>
</div>
<span class="member-name"><?php print htmlentities($fundraiser['member_name']); ?></span>
<span class="friend-count"><?php print number_format($fundraiser['num_donors']) . (($fundraiser['num_donors'] == 1) ? ' Friend' : ' Friends'); ?></span>
<span class="fundraisers-text"> Donated: </span><span class="fundraisers-gold"> $<?php print number_format($fundraiser['total_raised']); ?></span>
</div>
Best way is to use Ajax. Something like this
$("#button").click( function() {
$.ajax({
url: 'file.php',
method: 'post',
data: { id: $(this).val() },
error: function() {
alert('error while requesting...');
}, success: function(data) {
alert( data ); /** received data - best to use son **/
}
});
});
Next parse json var json = $.parseJSON(data);
or ... use dataJson option.
Next Your data should be inserted using class or id to specific location.
Create another loop for content
<?php if ($top_fundraisers && is_array($top_fundraisers)):
$i = 1;
foreach ($top_fundraisers as $index => $fundraiser): ?>
<a title="" class="fancybox" href="#inline<?php echo $i; ?>">
// ... content
<?php $i++;
endforeach;
endif; ?>
And another loop
<?php if ($top_fundraisers && is_array($top_fundraisers)):
$i = 1;
foreach ($top_fundraisers as $index => $fundraiser): ?>
<div id="inline<?php echo $i; ?>">
// inline content here
</div>
<?php $i++;
endforeach;
endif; ?>
Hope your JavaScript function to open fancybox works fine via calling class. So by following code you do not need to play with Javascript code.
Building anchors tags:
<?php
if (!empty($top_fundraisers) && is_array($top_fundraisers)) {
foreach ($top_fundraisers as $index => $fundraiser) {
<a title="" class="fancybox" href="#inline<?php echo $fundraiser['id']; ?>">HTML Content Goes Here</a>
<?php
} //end of foreach
} // end of if condition
?>
Building Popup HTML DOMs:
<?php
if (!empty($top_fundraisers) && is_array($top_fundraisers)) {
foreach ($top_fundraisers as $index => $fundraiser) {
<div id="inline<?php echo $fundraiser['id']; ?>">HTML Content Goes Here</div>
<?php
} //end of foreach
} // end of if condition
?>
You cannot perform this because PHP runs server-side and JavaScript runs in the browser.
To perform this you can use AJAX to get the div as required by user.
...or store the data client-side and change the content of #inline1 based on which item was clicked