change status active/inactive using ajax in yii2 - ajax

[
'attribute' => 'status',
'format' => 'html',
'value' => function ($data) {
if($data->status==true) {
return Html::a("Inactive", "#", ['id' => $data->id, 'class' => 'a_status']);
}
else {
return Html::a("Active", "#");
}
]
The problem is, this code is not returning "id" attribute in link. So, wanted to know if this is currect way to put link in grid view or can someone point me correct way?'
Thx in advance.

Your code is missing one closing parenthesis and a change in format key's value -
Try -
[
'attribute' => 'status',
'format' => 'raw', //It was 'html' before
'value' => function ($data) {
if($data->status==true) {
return Html::a("Inactive", "#", ['id' => $data->id, 'class' => 'a_status']);
}
else {
return Html::a("Active", "#");
}
} //missing parenthesis
]

Well, you are missing a lot of code. Here are some observations.
*) I am using this kind of definition for the column
'value'=>function ($model, $key, $index, $widget) {
I am not sure if it makes a difference, try it this way maybe this is the problem.
Other things:
*) why are you using return
Html::a("Inactive", "#", ['id' => $data->id, 'class' => 'a_status']);
and not something like
Html::a("Inactive", ['change-status', 'status' => 'active', 'id' => $data->id], ['class' => 'a_status']);
You are creating in this way the link with the proper url already. If somebody does not have javascript enabled it will still work for them, just with a refresh.
Now you can create a global ajax function that you can reuse with ease for a lot more screens.
Now the actionChangeStatus function can end like this
if(Yii::$app->request->getIsAjax()) {
Yii::$app->response->format = 'json';
return ['success' => true];
} else {
return $this->redirect(['index']);
}
My ajax looks like this
jQuery.ajax({
"type": "GET",
"url": element.attr('href'),
"cache": false,
})
.success(function ( response ) {
$.pjax.reload({container: "#main-pjax", async:false, timeout: 4000});
});

Related

Yii2: Reusing Form Fields through Widget

I have a field that is a Select2 widget field and it's usually used in many forms, but copy pasting the same code after a while gets really annoying. Therefore I decided perhaps its best to create a widget just for this field.
The field is as follows
<?= $form->field($model, 'contact_id')->widget(Select2::className(), [
'initValueText' => empty($model->contact_id) ? '' : $model->contact->contact_id . ' ' . $model->contact->fullname,
'options' => [
'class' => 'input-sm',
'id' => 'contact_id',
'placeholder' => '-- Search --',
'disabled' => $disabled,
'onchange' => new JsExpression("get_contact_info($(this).val())"),
],
'pluginOptions' => [
'allowClear' => true,
'language' => [
'errorLoading' => new JsExpression("function () { return 'Waiting for results...'; }"),
],
'ajax' => [
'url' => $fetch_url,
'dataType' => 'json',
'data' => new JsExpression('function(params) { return {q:params.term}; }'),
'results' => new JsExpression('function(data,page) { return {results:data.results.text}; }'),
],
'escapeMarkup' => new JsExpression('function (markup) { return markup; }'),
'templateResult' => new JsExpression('function(contact) { return contact.text; }'),
'templateSelection' => new JsExpression('function (contact) { return contact.text; }'),
],
]); ?>
This field utilizes Ajax Fetching, and must allow to be used in create and update forms.
Can anyone please point me to the right direction.
I see two solution:
a) create widget - more work, but flexible using by adding additional settings
b) create separate view and render it - faster, but no so flexible

In CakePHP3 how do I create a custom model rule which validates that a time is after another time in the same table?

Columns (both datatype time):
Start
End
End cannot be before start.
$validator
->requirePresence('end', 'create')
->notEmpty('end')
->add('end', [
'time' => [
'rule' => 'time',
'message' => 'end can only accept times.'
],
'dependency' => [
'rule' => [$this, 'endBeforeStart'],
'message' => 'end can not be before start.'
],
]);
If it is a PUT request which only contains end, the model will need to query the existing record to compare against start. If it is a PUT which contains both then it need to validate against the intended new parameter.
How does cakePHP3 do this?
private function endBeforeStart($fieldValueToBeValidated, $dataRelatedToTheValidationProcess)
{
//What goes here?
}
I can't seem to find any examples of doing this online.
I'm not quite sure and haven't tested it, but maybe this gives you some hints:
$validator
->add('end', [
'endBeforeStart' => [
'rule' => function ($value, $context) {
// If it's a POST (new entry):
if ( $context['newRecord'] == '1' ) {
// Do your comparison here
// Input values are e.g. in $context['data']['starttime']
// If end is before start:
return false;
}
// If it's a PUT (update):
else {
// If starttime is not in $context['data']['starttime']
// check for the old value in $getOldEntry
$getOldEntry = $this->getOldEntry( $context['data']['id'] );
// And do your comparison here...
// If end is before start:
return false;
}
return true;
},
'message' => 'end can not be before start.' ],
])
public function getOldEntry($id = null) {
return $this->get($id);
}
I'm also not sure if the last function has to be private or public...

How to make an ajax call on submit button of a webform?

These are my code, I have done the form alter in template.php.
Please advice me ! I created a webform by webform module.My aim is to submit the form without the page load.
My code follows here:
function business_form_alter(&$form, &$form_state, $form_id) {
if($form_id == 'webform_client_form_7') {
$form['actions']['submit']['#ajax'] = array(
'callback' => 'business_webform_js_submit',
'wrapper' => 'webform-client-form-7',
'method' => 'replace',
'effect' => 'fade',
);
}
function business_webform_ajax_submit($form, $form_state) {
$sid = $form_state['values']['details']['sid'];
if ($sid) {
$node = node_load($form_state['values']['details']['nid']);
$confirmation = array(
'#type' => 'markup',
'#markup' => check_markup($node->webform['confirmation'], $node- >webform['confirmation_format'], '', TRUE),
);
return $confirmation;
}
else {
return $form;
}
}
There is a small mistake in your code. The name of the #ajax['callback'] function is different than the actual function.
You might want to rename the function:
function business_webform_js_submit($form, $form_state)
And it should work.

How to execute a method in AJAX with Symfony2 when passing JavaScript arguments?

I'm getting confused by AJAX/S2 when I need to pass some arguments retrieved with JavaScript to a method in the controller.
In my script I have at some point, I get the position var:
function handle_geolocation_query(position){
alert('Lat: ' + position.coords.latitude + ' ' +
'Lon: ' + position.coords.longitude);
$.when( getLakes(position.coords.latitude, position.coords.longitude)).done(function(result1) {
console.log(result1);
});
};
function getLakes(lat, long) {
return $.ajax({
url: "{{ path('getLakes') }}",
data: { lat:lat, lng: lng },
dataType: 'jsonp'
});
};
then the router is set that way:
getLakes:
pattern: /lakes
defaults: { _controller: PondipGeolocBundle:Default:getLakesSurrounding }
And In my controller I'm supposed to return an array:
public function getLakesSurrounding($lat=0, $lng=0, $limit = 50, $distance = 50, $unit = 'km')
{
$lat = $this->getRequest()->get('lat');
$lng = $this->getRequest()->get('lont');
$return= array( '1'=> array( 'title' => 'lake1',
'venue' => 'lake2',
'dist' => 'lake3',
'species' => 'lake4',
'stock' => 'lake4'),
'2'=> array( 'title' => 'lake1',
'venue' => 'lake2',
'dist' => 'lake3',
'species' => 'lake4',
'stock' => 'lake4'),
'3'=> array( 'title' => 'lake1',
'venue' => 'lake2',
'dist' => 'lake3',
'species' => 'lake4',
'stock' => 'lake4'),
'4'=> array( 'title' => 'lake1',
'venue' => 'lake2',
'dist' => 'lake3',
'species' => 'lake4',
'stock' => 'lake4'),
'5'=> array( 'title' => 'lake1',
'venue' => 'lake2',
'dist' => 'lake3',
'species' => 'lake4',
'stock' => 'lake4')
);
$return=json_encode($return); //jscon encode the array
return new Response($return,200,array('Content-Type'=>'application/json')); //make sure it has the correct content type
}
And then I'd like to pass it to another function that would set up the template with moustache to print it in the view (I'm not here yet ..)
My question is: I can't pass the needed lat and long data to my function. the router gets mad, the controller doesnt get anything and I don't get anything back from that script.
EDIT:I found my way to pass the variables, but I still can't get any response from my controller, nohing happen and the $.when does not execute any callback
I'm fairly new with AJAX, please advise.
Have a look at FOSJsRoutingBundle. With it you can use router from JS:
Routing.generate('my_route_to_expose', { "id": 10, "foo": "bar" });

How to "print" a theme during AJAX request (Drupal)

When users click on a button (with id graph), I'd like to fill the default Drupal content div (<div class="content">) with a graphael instance.
The JavaScript:
jQuery(document).ready(function($) {
$('#toggle #graph').click(function() {
$.ajax({
url: "http://www.mysite.com/?q=publications/callback",
type: 'POST',
data: {
'format' : 'graph'
},
success: function(response) {
$('div#content div.content').html(response);
}
});
});
});
The PHP:
$items['publications/callback'] = array(
'type' => MENU_CALLBACK,
'title' => 'All Publications Callback',
'page callback' => '_process_publications',
'page arguments' => array(t('journal')),
'access callback' => TRUE,
);
which leads to the page callback: (I'm concerned with the if code block)
function _process_publications($venue) {
if( isset($_POST['format']) && $_POST['format'] == "graph" ){
_make_bar_chart($venue);
}
elseif( isset($_POST['format']) && $_POST['format'] == "list" ) {
_make_list($venue);
}
else{
return("<p>blah</p>");
}
}
and finally the function called within the callback function:
function _make_bar_chart($venue) {
// get active database connection
$mysql = Database::getConnection();
// if connection is successful, proceed
if($mysql){
// do stuff
$graphael = array(
'method' => 'bar',
'values' => $ycoordinates,
'params' => array(
'colors' => $colors,
'font' => '10px Arial, sans-serif',
'opts' => array(
'gutter' => '20%',
'type' => 'square',
),
'label' => array(
'values' => $xcoordinates,
'isBottom' => true,
),
),
'extend' => array(
'label' => array(
'values' => $ycoordinates,
'params' => array('attrText' => array(
'fill' => '#aaa',
'font' => '10px Arial, sans-serif',
)),
),
),
);
return theme('graphael', $graphael);
}
// else, connection was unsuccessful
else{
print("<p>bad connection</p>");
}
}
THE PROBLEM: returning a theme doesn't really send anything back to the AJAX request (unlike print statements). I tried to print the theme, but that produces a white screen of death. How would I generate the graph without printing something?
Much thanks to nevets on the Drupal forums for the helpful hint: http://drupal.org/node/1664798#comment-6177944
If you want to use AJAX with Drupal, you are best off actually using Drupal-specific AJAX-related functions. In my theme's page.tpl.php file, I added the following to make the links which would call AJAX:
<?php
// drupal_add_library is invoked automatically when a form element has the
// '#ajax' property, but since we are not rendering a form here, we have to
// do it ourselves.
drupal_add_library('system', 'drupal.ajax');
// The use-ajax class is special, so that the link will call without causing
// a page reload. Note the /nojs portion of the path - if javascript is
// enabled, this part will be stripped from the path before it is called.
$link1 = l(t('Graph'), 'ajax_link_callback/graph/nojs/', array('attributes' => array('class' => array('use-ajax'))));
$link2 = l(t('List'), 'ajax_link_callback/list/nojs/', array('attributes' => array('class' => array('use-ajax'))));
$link3 = l(t('Create Alert'), 'ajax_link_callback/alert/nojs/', array('attributes' => array('class' => array('use-ajax'))));
$output = "<span>$link1</span><span>$link2</span><span>$link3</span><div id='myDiv'></div>";
print $output;
?>
When one of the links above is clicked, the callback function is called (e.g. ajax_link_callback/graph):
// A menu callback is required when using ajax outside of the Form API.
$items['ajax_link_callback/graph'] = array(
'page callback' => 'ajax_link_response_graph',
'access callback' => 'user_access',
'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
);
.. and the callback to which it refers:
function ajax_link_response_graph($type = 'ajax') {
if ($type == 'ajax') {
$output = _make_bar_chart('journal');
$commands = array();
// See ajax_example_advanced.inc for more details on the available commands
// and how to use them.
$commands[] = ajax_command_html('div#content div.content', $output);
$page = array('#type' => 'ajax', '#commands' => $commands);
ajax_deliver($page);
}
else {
$output = t("This is some content delivered via a page load.");
return $output;
}
}
This replaces any HTML within <div class="content"> with the graphael chart returned from _make_bar_chart above.

Resources