Calling a JavaScript method before rendering - cakephp

I have one-page app where header, footer and top navigation are static and the "pages" are opened with Ajax.
Example:
Element from the main navigation:
Something
JavaScript:
$('body').on('click', '[data-open-dynamic]', function () {
var url = $(this).data('openDynamic');
openDynamic(url);
})
function openDynamic(url)
{
$.ajax({
url: url,
async: true,
success: function (data) {
//some other logic
$('.content').html(data).fadeIn();
}
})
}
The problem is that I need to open these pages from direct URLs also. Now if I try to open domain.com/controllerName/actionName the design is broken as the layout is set to ajax in the controller:
public function initialize()
{
parent::initialize();
$this->layout = 'ajax';
}
I tried to do something with beforeFilter(), beforeRender(), shutdown() but it seems the JavaScript file containing the method openDynamic() is not loaded yet and I can't call it.
public function beforeRender(\Cake\Event\Event $event)
{
parent::beforeRender($event);
$url = $event->subject->request->here; // the URL is correct
echo 'openDynamic("' . $url . '");';
$this->response->stop();
}
Also I'm not sure if the header, footer and navigation will be loaded properly in this way. How can I achieve this?

How about only setting the layout to be ajax if the page is requested via AJAX? You can test this using $this->request->is('ajax'):-
public function beforeRender(\Cake\Event\Event $event)
{
parent::beforeRender($event);
if ($this->request->is('ajax')) {
$this->layout = 'ajax';
}
}
This would be cleaner than mixing JavaScript with PHP in your code.

Related

how to pass ASP.NET MVC view values to angular js controller

I want to pass ASP.NET MVC view (.cshtml) values to angular js controller. I am familiar with Angular js, But not on MVC. I have values in MVC cshtml. I want to pass that value to my angular controller. Please provide me some info or demo project or link which explains in detail.
i want somthing like below,
Get value from mvc model and pass it to cshtml.
from cshtml pass value to angular js controller and display in angular html page
I do not want to use cshtml as my view. I want to get data from cshtml to angular controller and display in seperate html
Using the very first tutorial I pulled up I grabbed this snippet:
var AwesomeAngularMVCApp = angular.module('AwesomeAngularMVCApp', ['ngRoute']);
AwesomeAngularMVCApp.controller('HomeController', HomeController);
var configFunction = function ($routeProvider) {
$routeProvider.
when('/Listings', {
url: 'routesDemo/one'
})
.when('/Listing', {
url: 'routesDemo/two'
})
.when('/Listings', {
url: 'routesDemo/three'
});
}
configFunction.$inject = ['$routeProvider'];
AwesomeAngularMVCApp.config(configFunction);
Now this how you link a view to a controller action in MVC:
using System.Web.Mvc;
namespace AwesomeAngularMVCApp.Controllers
{
public class RoutesDemoController : Controller
{
public ActionResult One(string title)
{
var listings = db.Articles.Contain(title);
return PartialView(listings, "..\Views\Shared\WhateverPartialView.cshtml");
}
[HttpPost]
public async Task<ActionResult> Two(Article article)
{
if(ModelState.isValid){
_db.Add(article)
}
return View(article); //This one returns entire page
}
public JsonResult Three(string title)
{
var listing = db.Articles.Where(t => t.Title == title).SingleOrDefault();
return Json(listing, JsonRequestBehavior.AllowGet);
}
}
}
These partial views would be in the Views folder in a sub folder RoutesDemo
one.cshtml GET
two.cshtml POST ie: a href="#/Article/6" type=submit" class="btn"
$("form").submit( function(){
$.ajax( function(url, data){
});
});
three.cshtml GET ie
$.ajax({
url: '#Url.Action("routeDemo", "three")',
//url: baseUrl + url,
data: {
search: searchBlue.val()
},
success: function (data) {
$("#msg").html("Results for" + searchBlue.val());
searchBlue.searchMeme({ searchComplete: true });
$('#main').fadeOut(800, function () {
$('#main').html("" + data + "").fadeIn().delay(800);
});
searchBlue.val("");
},
error: function (xhr, status, error) {
alert(error);
}
});
If you want to pass values to the angular controller use razor syntax and bind the value to the html input. The top of the view file will make it so angular knows what type of object to expect.
IE: Top of Two.cshtml
#model AwesomeAngularMVCApp.Article
That should be it besides route.config for angular
If you want to handle the Model object using razor syntax check out this tutorial. Pretty cut and dry.If that is not enough I will show example of binding #Model.attribute/property to an html element after work tomorrow
EDIT
<div class="row-fluid" ng-controller="PersonDetailsController" ng-init="personId=#Model.Id">
Angular injects it in the scope during initialization, so you can refer to it as $scope.personId

pass value from jquery to Cakephp controller

I am beginner to CakePHP and trying the send the textbox value during change function to my controller action using ajax.
Can someone help to how to pass the value form jquery to cakephp controller. If there is example code could great.
Let's say you want to send your data to a method called 'ajax_process' in the users controller. Here's how I do it:
in your view .ctp (anywhere)
<?php
echo $this->Form->textarea('text_box',array(
'id' => 'my_text',
));
?>
<div id="ajax_output"></div>
In the same view file - the jquery function to call on an event trigger:
function process_ajax(){
var post_url = '<?php echo $this->Html->url(array('controller' => 'users', 'action' => 'ajax_process')); ?>';
var text_box_value = $('#my_text').val();
$.ajax({
type : 'POST',
url : post_url,
data: {
text : text_box_value
},
dataType : 'html',
async: true,
beforeSend:function(){
$('#ajax_output').html('sending');
},
success : function(data){
$('#ajax_output').html(data);
},
error : function() {
$('#ajax_output').html('<p class="error">Ajax error</p>');
}
});
}
In the UsersController.php
public function ajax_process(){
$this->autoRender = false; //as not to render the layout and view - you dont have to do this
$data = $this->request->data; //the posted data will come as $data['text']
pr($data); //Debugging - print to see the data - this value will be sent back as html to <div id="ajax_output"></div>
}
Disable cake's security for the ajax_process method, in AppController.php:
public function beforeFilter() {
$this->Security->unlockedActions = array('ajax_process');
}
I haven't tested any of this code but it should give you what you need

Call CI Controller from ExtJs

I am creating controller in Code Igniter and make form in ExtJs 4.2.1 now from where i call control and how?
i used url property of form and put controller name there but nothing happen
Update
I think i am not clearing my question actually i want to post data through submit function in which i pass data to php file in my server side i use Code Igniter Rest Api so here i want pass data to specific controller
ExtJs is a javascript framework and is executed on the client side. It has its own MCV system.
It makes no sense to mix up a php controller with a javascript view.
Be sure to read the introduction to MVC in ExtJS.
Also in ExtJS you don't call the controller. On initialisation of the app, all controllers get lloaded. In the controller you define what it has to control, and from then on the magic hhappens: The events defined in the controller are fired whenever needed.
In ExtJS 3.3.1
In login form put the buttons and call function submit_login();
buttons: [{
text: 'Login',
handler: function() {
submit_login();
}
}]
Submit_login() code is, I used Ext.Ajax.request to submit login parameters
You can debug the message with alert(response.responseText):
function submit_login() {var useridx = Ext.getCmp('useridx').getValue();var userpasswordx = Ext.getCmp('userpasswordx').getValue();Ext.Ajax.request({url:'".$url."', method:'POST',
params :{useridx:useridx,userpasswordx:userpasswordx},
success:function(response){
//alert(response.responseText);
//return;
var jsonData = Ext.util.JSON.decode(response.responseText);
var resultMessage = jsonData.Message;
var isLogin = jsonData.isLogin;
if (isLogin)
{
window.location = '';
}
else
{
Ext.Msg.alert('Info',resultMessage);
}
},
failure: function(){
Ext.Msg.alert('Not OK');
}
});
}
variable $url is:
$url = "index.php/apps/login";
You can create Apps controller
and create function login
public function login()
{
$this->load->view('login');
}
Create login.php in view
if ($i==1) {
//session_start();
$this->session->set_userdata('userid',$useridx); echo '{"success" : true, "isLogin": true,"Message" : "User Successfully Login"}';
} else {
echo '{"success" : true, "isLogin": false, "Message" : "Salah User: '.$useridx.' dan Password "}';
}
You also do this in Ext JS 4.2.1 with same code.
This is works for me
Andrex Maulana

How to set up custom ajax pagination in cakephp 2.*

How do i set up ajax in cakephp without using the default ajax helper? The default ajax helper puts the js code on the page itself, I don't want that. I want it to be set in a seperate js file (ie general.js) instead. How do i do that? I have pagination already set up.
First make sure you have jquery set up. In your default.ctp (View/Layouts/default.ctp) add the following line within the <head> section:
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
In your AppController.php file (Controller/AppController.php) add the following lines
function beforeRender() {
if ($this->request->is('ajax')) {
$this->layout = false;
}
}
This causes the behaviour that when an ajax call is made to an controller action only the view itself is loaded rather than the whole layout.
In your general.js file (webroot/js/general.js) add the following code:
$(document).ready(function(){
ajaxPagingNavigation();
});
function ajaxPagingNavigation() {
$(".paging a").click(function(e) {
$.ajax({
url: $(this).attr('href'),
cache: false
}).done(function( html ) {
$("#content").html(html);
ajaxPagingNavigation();
});
e.preventDefault();
});
}

Which one should I use? Backbone.js Router.navigate and window.location.hash

I began learning Backbonejs recently, by reading a book. and I feel a little bit confuse about this issue.Here is a Router:
define(['views/index', 'views/login'], function(indexView, loginView) {
var SelinkRouter = Backbone.Router.extend({
currentView: null,
routes: {
'home': 'home',
'login': 'login'
},
changeView: function(view) {
if(null != this.currentView)
this.currentView.undelegateEvents();
this.currentView = view;
this.currentView.render();
},
home: function() {
this.changeView(indexView);
},
login: function() {
this.changeView(loginView);
}
});
return new SelinkRouter();
});
and this is the boot method of a application:
define(['router'], function(router) {
var initialize = function() {
// Require home page from server
$.ajax({
url: '/home', // page url
type: 'GET', // method is get
dataType: 'json', // use json format
success: function() { // success handler
runApplicaton(true);
},
error: function() { // error handler
runApplicaton(false);
}
});
};
var runApplicaton = function(authenticated) {
// Authenticated user move to home page
if(authenticated) window.location.hash='home';
//router.navigate('home', true); -> not work
// Unauthed user move to login page
else window.location.hash='login';
//router.navigate('login', true); -> not work
// Start history
Backbone.history.start();
}
return {
initialize: initialize
};
});
My question is about the runApplication part. The example of the book that I read passed router into module just like this, but it used window.location.hash = "XXX", and the router wasn't touched at all.
I thought the "navigate" method would make browser move to the page I specified, but nothing happened. Why?
And for the best practice sake, what is the best way to achieve movement between pages(or views)?
thanks for any ideas.
You could also use the static method to avoid router dependency (while using requirejs for instance).
Backbone.history.navigate(fragment, options)
This way, you just need :
// Start history
Backbone.history.start();
// Authenticated user move to home page
if(authenticated)
Backbone.history.navigate('home', true);
// Unauthed user move to login page
else
Backbone.history.navigate('login', true);
According to the documentation, if you also want to call the function belonging to a specific route you need to pass the option trigger: true:
Whenever you reach a point in your application that you'd like to save
as a URL, call navigate in order to update the URL. If you wish to
also call the route function, set the trigger option to true. To
update the URL without creating an entry in the browser's history, set
the replace option to true.
your code should look like:
if(authenticated)
router.navigate('home', {trigger: true});
Once your router is created, you also have to call
Backbone.history.start();
Backbone.history.start([options])
When all of your Routers have
been created, and all of the routes are set up properly, call
Backbone.history.start() to begin monitoring hashchange events, and
dispatching routes.
Finally the runApplication logic will be something similar to this:
var runApplicaton = function(authenticated) {
var router = new SelinkRouter();
// Start history
Backbone.history.start();
// Authenticated user move to home page
if(authenticated)
router.navigate('home', true);
// Unauthed user move to login page
else
router.navigate('login', true);
}

Resources