Laravel 4: Form::macro with Form::model - laravel

Is it possible to use a custom Form::macro() with the Form::model() feature?
When I tried it at first glance, I could not get the model data to be passed to the macro method.

Only Form functions like Form::text will look for the form model automatically. Inside your macro, you could do this a couple of ways. Easiest would be to use Form::getValueAttribute($name). For example:
Form::macro('myField', function() {
$value = Form::getValueAttribute('username');
return "<input type='text' name='username' value=$value >";
});
And then you'd use it in the blade template like this:
<?php
$user = new User;
$user->username = "bob";
echo Form::model($user);
echo Form::myField();
echo Form::close();
?>
You can find all of the available form functions in the source code here: https://github.com/laravel/framework/blob/master/src/Illuminate/Html/FormBuilder.php

Related

How to create dynamic Checkboxlist in Yii?

I would like a help to solve this problem. I'm using Yii 1.1 and trying to create a dynamic CheckBox list in which its elements change depending on the value selected in a DropDown element.
I created this DropDown element with the arguments in Ajax to perform the function update in the Controller. The function in the Controller is doing the lookup in the table according to the value passed.
Up to this point, the code is working fine, generating an array with the values that should be displayed. The problem is that I'm not able to configure the return of these data and I can't even display them in the View.
Below is the code data:
View - DropDown element:
echo CHtml::activeDropDownList($model, 'standard',
array(CHtml::listData(standard::model()->findAll(), 'name','name')),
array('empty'=>'',
'ajax'=>array(
'type'=>'POST',
'url'=>CController::createUrl('/getTeam',array('form'=>'Team','field'=>'standard')),
'update'=>'#Audit_team'),
)
);?>
Controller:
public function actionGetTeam($form,$field) {
$post = $_POST;
$standard = $post[$form][$field];
$Lists = TblAuditStandard::model()->findAll("standard = $standard");
foreach ($Lists as $List){
$AuditTeam[] = $List->name." - ".$List->login;
asort($AuditTeam);
foreach ($AuditTeam as $id=>$value )
echo CHtml::tag('option',array('value'=>$id),$value,true);
}
}
View - Checkbox element:
<div class="row">
<?php echo $form->labelEx($model,'team'); ?>
<?php echo CHtml::activeCheckBoxList($model,'team',array()); ?>
<?php echo $form->error($model,'team'); ?>
</div>
I hope someone can help me solve this problem. Thanks.

Get Laravel 5 controller name in view

Our old website CSS was set up so that the body tag had an id of the controller name and a class of the action name, using Zend Framework 1. Now we're switching to Laravel 5. I found a way to get the action name through the Route class, but can't find a method for the controller name. I don't see anything in the Laravel docs like this. Any ideas?
This is how you do with action. You inject the Route class, and then call:
$route->getActionName().
I'm looking for something similar for controllers. I've checked the entire route class and found nothing.
If your layout is a Blade template, you could create a view composer that injects those variables into your layout. In app/Providers/AppServiceProvider.php add something like this:
public function boot()
{
app('view')->composer('layouts.master', function ($view) {
$action = app('request')->route()->getAction();
$controller = class_basename($action['controller']);
list($controller, $action) = explode('#', $controller);
$view->with(compact('controller', 'action'));
});
}
You will then have two variables available in your layout template: $controller and $action.
I use a simple solution. You can test and use it in everywhere, also in your views:
{{ dd(request()->route()->getAction()) }}
I will simply use as bellow
$request->route()->getActionMethod()
To get something like PostController try following ...
preg_match('/([a-z]*)#/i', $request->route()->getActionName(), $matches);
$controllerName = $matches[1];
$matches[1] includes the first group while $matches[0] includes everything matched. So also the # which isn't desired.
use this
strtok(substr(strrchr($request->route()->getActionName(), '\\'), 1), '#')
To add to Martin Bean answer, using Route::view in your routes will cause the list function to throw an Undefined offset error when this code runs;
list($controller, $action) = explode('#', $controller);
Instead use this, which assigns null to $action if not present
list($controller, $action) = array_pad(explode('#', $controller), 2, null);
You can use this to just simply display in the title like "Customer - My Site" (laravel 9)
{{ str_replace('Controller', '', strtok(substr(strrchr(request()->route()->getActionName(), '\\'), 1), '#'))}} - {{ config('app.name') }}
You can add this (tested with Laravel v7+)
<?php
use Illuminate\Support\Facades\Route;
echo Route::getCurrentRoute()->getActionMethod();
?>
or
You can use helper function
<?php echo request()->route()->getActionMethod(); ?>
for example :-
Route::get('test', [\App\Http\Controllers\ExampleController::class, 'exampleTest'])->name('testExample');
Now If I request {app_url}/test then it will return exampleTest

Update multilingual content with AJAX in Yii

Refer to my code below, when user click on en button, the content will be changed to English, while clicking tw button, the content will be changed to Chinese.
However, the page will be refreshed each time when user click either en or tw button. I want to ask how can I implement AJAX content update in this case?
The result is when user click either en or tw button, the page won't be refreshed to change the content language.
Thanks
I have refer to Yii docs here, but seem that it is not appropriate for my case
C:\wamp\www\website\protected\views\site\index.php
<?php
$lang = isset($_GET["lang"]) ? $_GET["lang"] : "en_uk";
$lang = $lang == "en" ? "en_uk" : "zh_tw";
Yii::app()->setLanguage($lang);
?>
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="get">
<input type="submit" value="en" name="lang" />
<input type="submit" value="tw" name="lang" />
</form>
<div class="main">
<?php echo Yii::t(Yii::app()->controller->id, "Causeway Bay"); ?>
</div>
Best practice is to reload the page in these cases, because usually you have to update so much, that it is just not worth it.
That said, CHtml's ajaxSubmitButton is the cleanest way to implement this, because you can map every event of your call very easily. It looks something like this:
<?php
echo CHtml::ajaxSubmitButton('en', CHtml::normalizeUrl(array('site/changeLanguage')),
array(
'error'=>'js:function(){
alert("error");
}',
//if you add a return false in this, it will not submit.
'beforeSend'=>'js:function(){
alert("beforeSend");
}',
'success'=>'js:function(data){
alert("success, data from server: "+data);
}',
'complete'=>'js:function(){
alert("complete");
}',
//'update'=>'#where_to_put_the_response',
)
);
?>
You don't have to use every parameter of course. The update parameter can update a HTML tag instantly.
EDIT:
This can be done easily if you use the controller's renderPartial method, for instance in your site controller if you have the action responsible for the index.
public function actionIndex(){
//get variables, etc
if(Yii::app()->request->isAjaxRequest) {
$lang = $_POST['nameOfSubmit'];
}else {
//...
}
//if the 3rd parameter is true, the method returns the generated HTML to a variable
$page = $this->renderPartial('_page', array(/*parameters*/ ), true);
echo $page;
}
And then, in your view file you can simply have
<?php echo CHtml::ajaxSubmitButton('en', CHtml::normalizeUrl(array('site/index')),
array('update'=>'#content_div',));?>
and
<?php echo CHtml::ajaxSubmitButton('tw', CHtml::normalizeUrl(array('site/index')),
array('update'=>'#content_div',));?>

Retrieve product custom media image label in magento

I have a custom block loading products on my front page that loads the four newest products that have a custom product picture attribute set via:
$_helper = $this->helper('catalog/output');
$_productCollection = Mage::getModel("catalog/product")->getCollection();
$_productCollection->addAttributeToSelect('*');
$_productCollection->addAttributeToFilter("image_feature_front_right", array("notnull" => 1));
$_productCollection->addAttributeToFilter("image_feature_front_right", array("neq" => 'no_selection'));
$_productCollection->addAttributeToSort('updated_at', 'DESC');
$_productCollection->setPageSize(4);
What I am trying to do is grab the image_feature_front_right label as set in the back-end, but have been unable to do so. Here is my code for displaying the products on the front end:
<?php foreach($_productCollection as $_product) : ?>
<div class="fll frontSale">
<div class="productImageWrap">
<img src="<?php echo $this->helper('catalog/image')->init($_product, 'image_feature_front_right')->directResize(230,315,4) ?>" />
</div>
<div class="salesItemInfo">
<p class="caps"><?php echo $this->htmlEscape($_product->getName());?></p>
<p class="nocaps"><?php echo $this->getImageLabel($_product, 'image_feature_front_right') ?></p>
</div>
</div>
I read that $this->getImageLabel($_product, 'image_feature_front_right') was the way to do it, but produces nothing. What am I doing wrong?
Thanks!
Tre
It seems you asked this same question in another thread, so to help others who might be searching for an answer, I'll anser it here as well:
I imagine this is some sort of magento bug. The issue seems to be that the Magento core is not setting the custom_image_label attribute. Whereas for the default built-in images [image, small_image, thumbnail_image] it does set these attributes - so you could do something like:
$_product->getData('small_image_label');
If you look at Mage_Catalog_Block_Product_Abstract::getImageLabel() it just appends '_label' to the $mediaAttributeCode that you pass in as the 2nd param and calls $_product->getData().
If you call $_product->getData('media_gallery'); you'll see the custom image label is available. It's just nested in an array. So use this function:
function getImageLabel($_product, $key) {
$gallery = $_product->getData('media_gallery');
$file = $_product->getData($key);
if ($file && $gallery && array_key_exists('images', $gallery)) {
foreach ($gallery['images'] as $image) {
if ($image['file'] == $file)
return $image['label'];
}
}
return '';
}
It'd be prudent to extend the Magento core code (Ideally Mage_Catalog_Block_Product_Abstract, but I don't think Magento lets you override Abstract classes), but if you need a quick hack - just stick this function in your phtml file then call:
<?php echo getImageLabel($_product, 'image_feature_front_right')?>
Your custom block would need to inherit from Mage_Catalog_Block_Product_Abstract to give access to that method.
You could also use the code directly from the method in the template:
$label = $_product->getData('image_feature_front_right');
if (empty($label)) {
$label = $_product->getName();
}

How to remove the action attribute in the form_open_multipart() in Codeigniter?

Is there a way that I can remove the action attribute in CodeIgniter?
The code would normally be like this:
form_open_multipart('person/add', $attributes);
I was hoping that I could omit the first parameter so that I could not have an action attribute in the mark-up.
Thanks for those who could help.
Sure you can but consider:
1) The action attribute has a meaning and a function, don't know why you want it out
2) You can always pass it an empty string :
<?php echo form_open('');?>
or <?php echo form_open_multiaction('');?>
gives:
<form action="" method="post">
In case you're really sure about this, just open up the form_helper.php file, located in system/helpers/form_helper.php.
Pick lines 59 - 65 :
$action OR $action = $CI->config->site_url($CI->uri->uri_string());
$form = '<form action="'.$action.'"';
$form .= _attributes_to_string($attributes, TRUE);
$form .= '>';
and change line 60 to
$form = '<form ';
form_open_multiaction() just picks the form_open() and adds the enctype attribute, so you change form_open() and you're set.
It's up to you now, I still fail to see why an empty action won't suffice to your goals.

Resources