CakePHP - How to use login form as Element - cakephp

I am learning CakePHP. I am trying to develop a login system, but instead of using the login.ctp as a user/view, I wish I could use it as a element because I have the login form in many other pages. How can I declare within my users_controller that my function login() will use just the element. I said that because I used $this->render('/elements/login') and it did work. However, my element login.ctp was within my default.ctp layout, thus, I had two login forms. One was the element and the other as my content in my default.ctp layout.
Thanks!

Layouts are for the "greater" markup of a page: head and meta information, includes, "footer" stuff like your analytics. Generic content pointers go in the middle - so there's no need to mark anything as specific as a form in a layout unless you really do want to include that form on every page that uses that layout.
It sounds like you either called $this->render() in your view? $this->render() is a controller method. $this->element is the view method.
Or you called $this->element('/elements/login'); from in your login.ctp view? That would mean the controlller rendered the default login.ctp view, which called the login.ctp element.
And thus you saw two. To fix:
To return something other than the default view associated with an action (such as your login snippet), call $this->render('name/of/whatever'); as the last line of the controller method. It will return the view you specify; set will pass whatever variables to it, just like a regular view call and if you want to get fancy, specify the layout as ajax and watch the magic start like $this->render('/elements/login', 'ajax').
If you need to call several elements in a single view file, use the method $this->element('/fancy/nav/whatever'); you can also place them in layouts as appropriate (navigation, etc.)
HTH. :)

I had the same thing done to my project and this is what I did.
Basically, I created a new loginElement.ctp and placed it in the element folder. I create new sets of HTML code that would fit the layout where I wanted to use this element and the loginElement.ctp <form would then submit the data to login action in the users_controller.
If you need to and when I get home later, I can post my exact code here.
==================================== EDIT =========================================
These are the codes I used:
First of all you will notice that the action in the login form points to /login.
I have that setup in my /config/routes.php file as such
Router::connect('/login', array('controller' => 'users', 'action' => 'login'));
Then the other codes are below
/views/elements/thinlogin.ctp
<div id="login">
<form method="post" action="/login" accept-charset="utf-8" class="formBox">
<fieldset>
<input type="hidden" name="_method" value="POST" />
<div class="form-col">
<label for="username" class="lab">Username/Email</label>
<input name="data[User][username]" type="text" id="UserUsername" class="input">
</div>
<div class="form-col form-col-right">
<label for="password" class="lab">Password</label>
<input type="password" name="data[User][password]" id="UserPassword" class="input">
</div>
<div class="form-col form-col-submit">
<input name="" value="Login" class="submit" type="submit">
</div>
<div class="form-col form-col-check">
<label><input name="remember" class="checkbox" type="checkbox">Remember me on this computer</label>
</div>
</fieldset>
</form>
</div>
/views/pages/home.ctp
<div id="home_top_right_top">
<?php
if (!$this->Session->check('Auth.User.id'))
{
echo $this->element('login/thinlogin');
}else{
echo $this->element('login/loggedin');
}
?>
</div>

Related

router::url doesn't work in the same controller

I have this form:
<div id="buscador">
<form action="<?php echo Router::url(array('controller'=>'categorias','action'=>'buscar'));?>" name="form_search" id="form_search" method="post" >
<input type="text" name="search">
<input type="submit" value="Buscar" class="buscador" id="boton_buscar"/>
</form>
</div>
It works fine in all controllers except when you are using the controller "categorias"... in that case, the result is this: http....Categorias/buscar/Buscar
Any idea why this happens?
The problem was present elsewhere, I didn't consider that when clicking the button inside the View "buscar", then JS acts on that click (and this generates the buscar/Buscar problem)

Detecting value change in ng-model without using $watch and form for application having large number of models

My application has a lot of models in the page. I want to detect whether user has changed value of any model on click of save. Using $watch on every model puts too much load, so don't want to use this method. Is there any good approach for this?
Small snippet is like below:
<div>
<div class="ttere2">
<input type="radio" name="nc2-radio3" ng-model="nc2PenaltyAfter" value="specificDays" />
<input class="ggfe1" ng-model="nc2AfterDays" ng-disabled="nc2PenaltyAfter!='specificDays'" type="number" min="1" max="100" step="1" value="1" />days</div>
<div class="admin_wp-line">
<input type="radio" name="nc2-radio3" ng-model="nc2PenaltyAfter" value="immediately"/> Immediately </div>
<div class="acfv1">model 1</div>
</div>
<div style="margin-top: 20px;"><button ng-click="saveData();">Done</button></div>
............too many inputs go here
</div>
Use .$dirty! Angular will set this on every element that is bound using ng-model, automatically, when it has been changed. It will also set it on the entire form. You can access it in code like this:
if ($scope.myForm.$dirty) {
// Your code here
}
Angular will provide six useful variables on the form, and every ngModel-bound element in your form: $dirty and $pristine, $valid and $invalid, and $touched and $untouched. You can mix and match these to drive a lot of useful behaviors, and they're available both in your controller (using the expression shown above) and your template (directly).

AngularJS post form to external URL

I have the following form in my AngularJS app which contain hidden fields with values filled based on user selection on some inputs on the form (radio buttons...etc), when the user click on the Submit link I should route the user to an external URL while passing hidden fields just as any normal form submission. Unfortunately I can't do this as some of the hidden field values are dependent on some calculations inside a function of the view related controller (as shown below in controller code, so I was wondering is there a way I can call the controller function from this form, then the controller function post the whole form and its field? Any example is highly appreciated. Thanks.
Note I am using link instead of a button.
<form name="clientPaymentForm" id="clientPaymentForm" action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top">>
<div>
<fieldset>
<input id="name" type="text" required placeholder="Client Name" ng-model="client.name">
...
...
<input type="hidden" name="amount" ng-value="order.total">
...
...
<a class="orderButton" href="javascript:{}" onclick="document.getElementById('clientPaymentForm').submit(); return false;">Order Now</a>
</fieldset>
</div>
</form>
Controller:
$scope.processOrder = function(){
//Order calculation happens here to update order.total value and can only happen after click click Order Now to place the order...
};
I guess this is a bit late, but what you want to use is the ng-click directive which will allow you to call functions defined directly on the scope.
Assuming that you've defined $scope.processOrder, change your a tag to the following:
<a class="orderButton" ng-click="processOrder()">Order Now</a>
And everything should work as hoped.
Alternatively, you could use ng-submit on the form to have it work when you press the "Enter" or "Return" key, as in:
<form name="clientPaymentForm" id="clientPaymentForm" action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top" ng-click="processOrder()">.

AngularJS - Variables in Layout to swap login/my account sections

Just getting into AngularJS coming from a Zend Framework 2/jQuery way of working.
My layout.html within Zend Framework would contain something like:
<html><body>
<div id="topNavigation" class="nav nav-fixed">
<?php
if ($this->identity()) :
?>
<button id="logoutBtn">Log out</button>
?>
else:
?>
<input type="text" name="username" />
<input type="password" name="password" />
<button>Login</button>
<?php
<?php
endif;
?>
</div>
<?php
// The content from each ViewAction
echo $this->content
?>
<footer>This is the common footer text.</footer>
</body></html>
Now I'm converting this to AngularJS I understand the index.html is the layout with ngView directive pointing to template files for each view.
How do I get variables into my layout to switch logged in state? If you can't really control the layout, where do I hold the code that maintains logged in state, cause I don't see anywhere for global code.
My angularJS index.html layout file is currently like the above:
<html><body>
<div id="topNavigation" class="nav nav-fixed">
<button id="logoutBtn">Log out</button>
<input type="text" name="username" />
<input type="password" name="password" />
<button>Login</button>
</div>
<div ng-view></div>
<footer>This is the common footer text.</footer>
</body></html>
The best place is probably in $rootScope which, since all controller's scopes inherit from this, can be thought of as 'global'.
I see in your index.html above, though, you haven't specified a controller. You would need to add a controller (probably in 'body'), and in that controller, add the login info to the $rootScope.
Once you have a variable in your $rootScope (say 'isLoggedIn'), then you can use the ng-show and ng-hide directives to determine what subsets of the DOM you want displayed.

Cakephp - Change validation errors div structure?

Is there any way of changing the validation error div structure? I want to insert an image just before the div.
Each error will be displayed inline with the input field, so I want to insert a left arrow image before the validation div.
Currently I am getting this:
<div class="input password required error">
<label for="StudentPassword1">Password</label>
<input type="password" name="data[Student][password1]" value="" id="StudentPassword1" class="form-error">
<div class="error-message">notempty</div>
</div>
I'd like:
<div class="input password required error">
<label for="StudentPassword1">Password</label>
<input type="password" name="data[Student][password1]" value="" id="StudentPassword1" class="form-error">
<img src='...' />
<div class="error-message">notempty</div>
</div>
How would you accomplish this? I'm guessing that I have to modify the core? Thanks
I'm guessing that I have to modify the core?
No. If your app requires changing Cake's core you are likely doing something wrong. Cake has a lot going on and it takes care of a lot of things for you. This happens to be one of the things you can customize to your liking.
When you create your Forms with the FormHelper you can specify default options for input() and one of those options includes the HTML structure and class used to wrap error messages.
I would just modify the CSS of the error-message class to include the image.
.error-message {
background:url( path/to/img.png ) no-repeat top left;
padding-left:40px; /* or whatever you need for the image to fit */
}
<?php echo $this->Form->create('User', array('class'=>'form-horizontal',
'inputDefaults' => array('error' => array(
'attributes' => array(
'wrap' => 'label', 'class' => 'text-error'
)
) )
)); ?>
This will make you customize the error output.

Resources