i am working on simple custom module for Drupal 7, which take two numeric values and on submit display sum of two values on same page.
I have form ready, NOT completed but struggling as I am want to call calculateFunction() function when user submit form, takes parameter and sum values...
info
name = form_test
description = Small module which demo how to create input form in custom module.
core = 7.x
Module php
<?php
function form_test_menu()
{
$items['formtest'] = array(
'title' => 'Form Test',
'page callback' => 'drupal_get_form',
'page arguments' => array('form_test_form'),
'access callback' => TRUE,
);
return $items;
}
function form_test_form($form,&$form_submit) {
$form['firstname'] = array(
'#title' => t('First Number'),
'#type' => 'textfield',
'#required' => TRUE,
);
$form['lastname'] = array(
'#title' => t('Second Number'),
'#type' => 'textfield',
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Run Function'));
calculateFunction($form);
return $form;
}
function calculateFunction()
{
echo "sum of two numbers.....";
}
?>
Instead of calling calculateFuction() directly you need to set $form['#submit'] to an array containing the name of the functions you want to call when the form is submitted.
$form['submit'] just creates the submit form element. #submit sets which callback function to submit to.
You may also optionally set $form['#validate'] to validate the submitted data.
See the Form API tutorial at Drupal.org
The submit callback could look something like the following:
/**
* FAPI Callback for form_test_form().
*/
function calculateFunction($form, &$form_state) {
$values = $form_state['values'];
$sum = $values['first_name'] + $values['last_name'];
drupal_set_message('The sum is ' . $sum);
}
Related
I'm building custom form with select element using Drupal 7 Form Api. I'm attaching #ajax callback to it, which will fire on change event.
$form['landing']['country'] = array(
'#type' => 'select',
'#options' => array(),
'#attributes' => array('class' => array('landing-country-list')),
'#validated' => TRUE,
'#prefix' => '<div id="landing-countries" class="hide">',
'#suffix' => '</div>',
'#title' => 'Select country',
'#ajax' => array(
'wrapper' => 'landing-cities',
'callback' => 'get_cities',
'event' => 'change',
'effect' => 'none',
'method' => 'replace'
),
);
But the problem is that it prevents custom change function on the same select in js. In this function I want to get selected option value. So this will not fire:
$('body').on('change', 'select.landing-country-list', function() {
optval = $(this).find('option:selected').val();
});
This code is in file, which I include in $form:
$form['#attached']['js'] = array(
'https://code.jquery.com/jquery-2.2.4.min.js',
drupal_get_path('module', 'landing') . '/landing.js',
);
Thanks in advance for your help!
If you want to catch before ajax sending you can use :
$(document).ajaxSend(function(){
var val = $('select.landing-country-list').val();
});
Otherwise if you want to get value after ajaxcallback :
$(document).ajaxComplete(function(event, xhr , options) {
if(typeof options.extraData != 'undefined' && options.extraData['_triggering_element_name'] === 'country'){
// only on ajax event attached to country select
var val = $('select.landing-country-list').val();
}
});
I'm creating a module with differents forms. I have some forms which are modal forms using ctools.
On one of these modal forms i made a button to open a pdf on a new tab in my browser but it doesn't work.
I have a AJAX error.
This is my code:
function liste_apprenant_partenaire($js){
if ($js) {
ctools_include('ajax');
ctools_include('modal');
ctools_add_js('ajax-responder');
$form_state = array(
'ajax' => TRUE,
);
$output = ctools_modal_form_wrapper('liste_apprenant_partenaire_form', $form_state);
if (!empty($form_state['ajax_commands'])) {
$output = $form_state['ajax_commands'];
}
print ajax_render($output);
drupal_exit();
}
else {
return drupal_get_form('liste_apprenant_partenaire_form');
}
}
function liste_apprenant_partenaire_form($form, &$form_state){
$form['pv-button'] = array(
'#id' => 'pv-button',
'#type' => 'submit',
'#value' => 'PV',
'#submit'=>array('pv_apprenant_partenaire_button_form_submit'),
'#attributes' => array('onclick' => 'target="_blank";return true;'),
);
return $form;
}
function pv_apprenant_partenaire_button_form_submit(&$form, &$form_state){
require_once("sites/all/modules/print/lib/dompdf/autoload.inc.php");
$node_session=node_load($_SESSION['nid_session']);
$type_formation=$node_session->field_type[LANGUAGE_NONE][0]['value'];
$test=file_get_contents('sites/all/modules/multi_example/test.html');
$test=str_replace('+type_formation',"$type_formation",$test);
$dompdf = new Dompdf();
$dompdf->loadHtml($test);
$dompdf->render();
$dompdf->stream('my.pdf',array('Attachment'=>0));
}
When i put the path of the node in my browser, it's worked fine because the form appears normally not as a modal form.
But i research the same result using a modal form. So i think there is a problem with AJAX but i don't find the real solution.
do not use button type submit
use form item type link then if you need this link look like button then you can style this as a button
use like this in the form
$form['my_module_custom_link'] = array(
'#type' => 'link',
'#title' => 'PDF',
'#href' => "/my/hello",
'#attributes' => array(
'target' => '_blank',
),
it should display a link inside the form then style it as you need
I have two entity dropdowns field in my symfony form. On the front end i change the option list of 2nd drop drown using ajax based on the value of first dropdown selected value. and Upon submitting the form i get the error that,
This value is not valid.
below is the code;
/**
* #ORM\ManyToOne(targetEntity="State")
* #ORM\JoinColumn(name="province_id", referencedColumnName="id")
*/
protected $Province;
/**
* #ORM\ManyToOne(targetEntity="District")
* #ORM\JoinColumn(name="district_id", referencedColumnName="id")
*/
protected $District;
and in the form,
->add('domicileDistrict','entity', [
'label' => ucwords('District'),
'class'=>'GeneralBundle\Entity\District',
'required' => true,
'mapped' => true,
'attr' => ['class' => 'form-control'],
'label_attr' => ['class' => 'control-label'],
])
->add('domicileProvince','entity', [
'label' => ucwords('Province'),
'class'=>'GeneralBundle\Entity\State',
'required' => true,
'attr' => ['class' => 'form-control select2'],
'label_attr' => ['class' => 'control-label'],
])
and on front end,
$("#profile_from_type_domicileProvince").change(function() {
var state = $('option:selected', this).val();
getDistrictByState(state);
});
function getDistrictByState(state){
var dict = {
type: "POST",
url: "{{ url('ajax_district_by_stateId') }}?id=" + state,
success: function(e) {
$("#profile_from_type_domicileDistrict option").remove();
$.each(e, function(e, p) {
$("#profile_from_type_domicileDistrict").append($("<option />", {
value: e,
text: p
}));
});
}
};
$.ajax(dict);
}
UPDATE: Add PRE_SUBMIT Event;
After suggestion form #Alsatian, I update my form and add the event as below, but nothing happens on selecting first dropdown.
$builder->addEventListener(FormEvents::PRE_SUBMIT, [$this, 'preSubmitData']);
public function preSubmitData(FormEvent $event){
$form = $event->getForm();
$data = $event->getData();
if (array_key_exists('Province', $data)) {
$state = $data['Province'];
$event->getForm()
->add('District','entity', [
'label' => ucwords('District'),
'class'=>'GeneralBundle\Entity\District',
'required' => true,
'mapped' => true,
'query_builder' => function(DistrictRepository $repository) use ($state) {
$qb = $repository->createQueryBuilder('d')
->andWhere('d.verified = :verified')
->andWhere('d.active = :active')
->setParameter('verified', true)
->setParameter('active', true);
if ($state instanceof State) {
$qb = $qb->where('d.state = :state')
->setParameter('state', $state);
} elseif (is_numeric($state)) {
$qb = $qb->where('d.state = :state')
->setParameter('state', $state);
} else {
$qb = $qb->where('d.state = 1');
}
return $qb;
},
'attr' => ['class' => 'form-control select2'],
'label_attr' => ['class' => 'control-label'],
]);
}
}
I had the same problem.
I wrote a bundle here to deal with "extensible" choice types (also entity or document) :
https://github.com/Alsatian67/FormBundle/blob/master/Form/Extensions/ExtensibleSubscriber.php
How I do it :
Hooking in the form submission process, we can access to the submitted entity by the PRE_SUBMIT FormEvent.
All submitted entity are loaded and are in $event->getData().
Then we have just to take this submitted choices as new 'choices' option for the field.
Caution :
Doing it so it will only validate that the entity submitted exist !
If only a part of the entities are possible choices you have to add a constraint to validate them.
You can also set the choices in the PRE_SUBMIT event, depending on the value of the first dropdown (instead of using all submitted entities).
I am trying to get the IDs of all the selected check boxes in yii using JAVASCRIPT. Now i am able to get only the first element ID. Can anyone please suggest the correct code to get all the check box ID.
My View:
<input type="button" value="Multiple Host Date Entries" onclick="act();" />
<div id="grid"></div>
<?php
//zii.widgets.grid.CGridView bootstrap.widgets.TbExtendedGridView
$obj=$this->widget('bootstrap.widgets.TbExtendedGridView', array(
'id'=>'host_grid',
'dataProvider'=>$dataProvider,
'type' => 'striped bordered',
//'filter' => $model,
//'type' => 'striped bordered condensed',
//'summaryText' => false,
////'afterAjaxUpdate'=>'\'changeTRColor()\'',
//'itemView'=>'_view',
'columns'=>array(
array(
'id' => 'selectedIds',
'class' => 'CCheckBoxColumn',
'selectableRows'=>2,
'value' => '$data->host_id',
'checkBoxHtmlOptions' => array('name' => 'idList[]'),
),
array( // display 'create_time' using an expression
'name'=>'host_name',
'value'=>'$data->host_name',
),
array(
'name'=>'host_serviceid',
'value'=>'$data->host_serviceid',
),
array(
'name'=>'status',
'value'=>'$data->status',
),
array(
'class'=>'CButtonColumn',
'template'=>'{edit_date}{update}{delete}',
'htmlOptions'=>array('width'=>'95px'),
'buttons' => array(
'update'=> array(
'label' => 'Update',
'imageUrl' => Yii::app()->baseUrl.'/images/icons/a.png',
),
'delete'=> array(
'label' => 'Delete',
'imageUrl' => Yii::app()->baseUrl.'/images/icons/d.png',
),
'edit_date' => array( //the name {reply} must be same
'label' => 'Add Date', // text label of the button
'url' => 'Yii::app()->createAbsoluteUrl("NimsoftHostsDetails/View", array("id"=>$data->host_id))', //Your URL According to your wish
'imageUrl' => Yii::app()->baseUrl.'/images/icons/m.png', // image URL of the button. If not set or false, a text link is used, The image must be 16X16 pixels
),
),)
),
))
;
?>
I must select some check boxes and click on multiple host date entries button to go to the specific controller.
My JavaScript:
function act()
{
var idList=$("input[type=checkbox]:checked").serializeArray();
var jsonStr = JSON.stringify(idList);
/* Object.keys(idList).forEach(function(key) {
console.log(key, idList[key]);
alert(idList[key]);
});*/
var a=$("input[type=checkbox]:checked").val();
alert(a);
if(idList!="")
{
if(confirm("Add Dates for multiple hosts?"))
{
var url='<?php echo $this->createUrl('Nimsoft/Date_all',array('idList'=>'val_idList')); ?>';
url=url.replace('val_idList',jsonStr);
//url=url.replace('val_idList',json_encode(idList));
//alert(url);
window.open(url);
/*$.post('Date_all',idList,function(response)
{
$.fn.yiiGridView.update("host_grid");
});*/
}
}
else
{
alert("Please Select atleast one host");
}
}
I need to pass the IDs to NIMSOFT controller so that I can have a for loop to process each one of those.
you can retrieve the checked column in client side (javasctipt):
var idArray = $(gridID).yiiGridView('getChecked', columnID);
// or
$.fn.yiiGridView.getSelection(gridID);
For all checked row ids we use this
var id = $.fn.yiiGridView.getChecked("your-grid-id", "selectedIds"); // array of seleted id's from grid
As you probably know, Yii does not perform client-side validation with CHtml::ajaxSubmitButton. So after a long time spending on google and stackoverflow, I found that I should use the following link
a-simple-way-to-get-yii-client-side-form-validation-run-when-submitting-by-ajax
Now, It can perform client-side validation. But, the success or complete ajax functions does not fire after validation.
Any Idea?
To be more familiar with topic, I put my codes here:
Yii::app()->clientScript->registerCoreScript('yii');
Yii::app()->clientScript->registerScript('Yii Fix',";$.yii.fix = {
ajaxSubmit : {
beforeSend : function(form) {
return function(xhr,opt) {
form = $(form);
$._data(form[0], 'events').submit[0].handler();
var he = form.data('hasError');
form.removeData('hasError');
return he===false;
}
},
afterValidate : function(form, data, hasError) {
$(form).data('hasError', hasError);
return true;
}
}
};",CclientScript::POS_HEAD);
My form:
$uniqid = uniqid();
$form = $this->beginWidget('CActiveForm', array(
'id' => 'pagescontents-add-new-contents'.$uniqid,
'htmlOptions' => array(
'class' => 'form-horizontal',
'role' => 'form'
),
'enableClientValidation' => true,
'enableAjaxValidation'=>true,
'clientOptions' => array(
'validateOnSubmit' => true,
'validateOnChange'=>false,
'afterValidate'=>'js:$.yii.fix.ajaxSubmit.afterValidate',
),
));
//The rest of code
...
//Ajax submit button
$button_uniqid = uniqid();
echo CHtml::ajaxSubmitButton(Messages::getMessage('ADD_NEW'), $this->createUrl('pagescontents/addPage/'), array(
'beforeSend' => '$.yii.fix.ajaxSubmit.beforeSend("#pagescontents-add-new-contents'.$uniqid.'")',
'type'=>'POST',
'success' => "js:function(data){
$('#page_modal').html('');
$('.modal-backdrop').remove();
$('#pageContents_list').html(data);
}",
),
array(
'class' => 'btn btn-primary',
// 'data-dismiss' => 'modal',
'id' => 'deletesubmit_' . $button_uniqid
)
);
I try your code and find that if you remove the line "'enableAjaxValidation'=>true," your code will work perfectly please check it and let me know that is work for you too or not.