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).
Related
I have a dropdown with countries, and I want to add a dependent dropdown or textfield with Ajax according to the selected value in the main dropdown.
Case 1
For example, if the user selects the United States(US) or Canada(CA), the Ajax should fire and add a dependent dropdown.
If the US
Dropdown
New York
New Jersey
California
And more options
If CA
Dropdown
Ontario
Manitoba
Quebec
And more options
The select(dependent dropdown) has to be required.
Case 2
If the user selects any other country, the Ajax should fire and add a dependent textfield
If any country but not US nor CA
Textfield
The textfield has to be required too.
I tried the options here
Using the AJAX command option
//This is my main select
$form['country'] = [
'#type' => 'select',
'#title' => $this->t(‘Select Country'),
'#options' => [
‘US’ => t(‘United State’),
'CA' => t('Canada’),
‘BR’ => t(‘Brazil’),
‘CO’ => t(‘Colombia’),
],
'#default_value' => 'US',
'#required' => TRUE,
'#empty_option' => $this->t('Please select'),
'#ajax' => [
'callback' => [$this, 'addDependentField’],
'event' => 'change',
'wrapper' => 'output-dependent’, // This element is updated with this AJAX callback.
'progress' => [
'type' => 'throbber',
'message' => $this->t('Verifying entry...'),
],
]
];
// Here I want to add a select or textfield. This dependes on the value from the main select above
$form[‘dependent_field’] = [
'#title' => $this->t('State/Province'),
'#prefix' => '<div id=“dependent-field”>’,
'#suffix' => '</div>',
];
public function addDependentField(array &$form, FormStateInterface $form_state) {
$selectedValue = $form_state->getValue('country');
switch ($selectedValue) {
case 'US':
$elem = [
'#type' => 'select',
'#options' => [
'NY' => t('New York'),
'CA' => t('California'),
'NJ' => t('New Jersey'),
'WA' => t('Washington'),
],
'#required' => TRUE,
'#attributes' => [
'id' => ['edit-output'],
],
];
break;
case 'CA':
$elem = [
'#type' => 'select',
'#options' => [
'ON' => t('Ontario'),
'PE' => t('Prince Edward Island'),
'QC' => t('Quebec'),
],
'#required' => TRUE,
'#attributes' => [
'id' => ['edit-output'],
],
];
break;
default:
$elem = [
'#type' => 'textfield',
'#size' => '60',
'#required' => TRUE,
'#attributes' => [
'id' => ['edit-output'],
],
];
break;
}
$renderer = \Drupal::service('renderer');
$renderedField = $renderer->render($elem);
// Create the AjaxResponse.
$response = new AjaxResponse();
$response->addCommand(new ReplaceCommand('#edit-output-2', $renderedField));
// Return the AjaxResponse object.
return $response;
}
This works only the first time, then stops working, I think it is because the fields’ types are different.
Using the render array option
I just changed all code after switch for the code below
return $form['dependent_field'] = $elem;
And it has the same behavior, it works only the first time then stops working.
I also tried
This to update multiple times
Replace more than one element form
Drupal 8 add ajax form element after ajax call
And also I found the same bad behavior after trying those answers, I still think it might be because one field is dropdown, and the other is `texfield`` because I want to update it over the same field with different types.
I think you don't need a specific AJAX for it.
You can use Form API '#states'
You can use this code to do ajax request.
This will get the list of states for the country selected
$('#countries').change(function(){
$.get("url/"+country,function(data,status){
various countries = JSON.parse(data);
for(var i = 0; i<countries.length; i++){
document.getElementById().innerHTML += "<option>"+countries[i].state+"</option>";
//here you can add the form field you wish to.
}
}
});
This is my form field.
As can see, there is a div tag with details id right below the form field. I wanted to print the content inside the div tag out whenever I select the contact.
$url2 = yii\helpers\Url::toRoute('op-client/contact');
$this->registerJs($this->render('script2.js'), \yii\web\VIEW::POS_READY);
$form->field($model, 'contact_id')->widget(Select2::classname(), [
'data' => $getcontact,
'language' => 'en',
'options' => ['placeholder' => 'Select'],
'pluginOptions' => [
'allowClear' => true
],
'pluginEvents' =>
[
'change' => 'function()
{
var contactid = $(this).val();
getDetails(contactid);
"'.$url2.'"
}',
],
]).'
<div id="details">
</div>
Script2.js
function getDetails(contactid,url2)
{
var csrfToken = $('meta[name="csrf-token"]').attr("content");
console.log(contactid);
$.ajax({
type:"POST",
cache:false,
url:url2,
data:{contactid:contactid, _crsf:csrfToken},
success:function(data){
$("#details").html(data);
//document.getElementById("details").innerHTML = data;
},
})
}
Controller
public function actionContact()
{
$request = Yii::$app->request;
$contact = $request->post('contactid');
$contacts =OpContact::find()
->where(['id'=>$contact])
->one();
echo $contacts->name;
}
The problem seems like I cant print out the contact name. I can get the correct contact id but I cant print out the name inside the div tag, it just show blank onchange. Is there anything wrong with my calling method? Thanks
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();
}
});
Hi guys i have a gridview like below
and i want to get the 'user_id' of the checked column
how can i do that???
I could easily get the checked column id but i dont know how to get data of those checked column in gridview
i want to get it via javascript so that i can pass it to service
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'showOnEmpty'=>true,
'columns' => [
['class' => 'yii\grid\CheckboxColumn'],
[
'attribute' => 'event_id',
'label' => 'Event Title',
'value' => 'event.title'
],
[
'attribute' => 'user_id',
'label' => 'Email',
'value' => 'users.email',
],
'user_type',
],
]);
?>
and here is my javascript to get ids of checked column
jQuery(document).ready(function() {
btnCheck = $("#send");
btnCheck.click(function() {
var keys = $("#w0").yiiGridView("getSelectedRows");
}
});
Let me tell you the flow of this
On homepage is a gridview like this
Now user will click on that small user sign and that will open the page you can see below
Thats when i want to send messages to all selected users
Because in my case title is from different table and name and email are from different table so i want ids of user table
For that i want user_id but i am getting some random values
What can i do here???
I tried this but its returning some random string
public function search($params)
{
if(!isset($_GET['id'])){
$id='';
}
else{
$id=$_GET['id'];
}
$query = Checkin::find()->where(['event_id'=> $id]);
$query->joinWith(['event', 'users']);
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$this->load($params);
if (!$this->validate()) {
return $dataProvider;
}
$query->andFilterWhere([
'id' => $this->id,
'created_date' => $this->created_date,
'created_by' => $this->created_by,
'updated_date' => $this->updated_date,
'updated_by' => $this->updated_by,
]);
$query->andFilterWhere(['like', 'user.email', $this->user_id]);
$query->andFilterWhere(['like', 'user_type', $this->user_type]);
$dataProvider->keys ='user_id';
return $dataProvider;
}
Update your DataProvider set $dataProvider->keys ='userId' then you will able to get all keys of user_id
data-id of GridView and get allSelectedColumns
You need to just replace this code
['class' => 'yii\grid\CheckboxColumn'],
with below code
[
'class' => 'yii\grid\CheckboxColumn',
'checkboxOptions' => function($data) {
return ['value' => $data->user_id];
},
],
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);
}