Apologies for troubling everyone with the billionth or so question about CakePHP and drop-down lists.
I have a database of employees, with fields such as name, department etc.
What I want to achieve is that the standard view of all employees can be filtered by selecting available departments and submitting a form. The departments available to select in the filter are automatically populated from the existing departments already in the database.
I'm fairly new to CakePHP, but what I'm trying to achieve is a drop-down list that is a 1 x N extract from the database. In HTML this would look like:
<option value="Human Resources">Human Resources</option>
<option value="Finance">Finance</option>
The idea is then to take this input and use it for a SQL query along the lines of:
SELECT * from Employees WHERE Department = 'finance'
etc.
At the moment this is the code I'm using in the controller to generate a list of all existing departments:
$this->set('department', $this->Employee->find('list', array('fields' => 'Employee.Department')));
and this I'm using this in the view to then make that into a dropdown box:
echo $this->Form->input('faculty', array('label' => 'Faculty', 'empty' => array('Any'), 'options' => $department));
The problem I am encountering is that it generates HTML along the lines of
<option value="1">Human Resources</option>
<option value="2">Finance</option>
I have read and re-read the documentation on forms and the find functions, but I can't seem to find the answer.
The only way forward I've found from that would be to manually specify the options using array('value' => 'label'), which given how long the full form is (and the 50+ departments we're talking about), is not something I fancy doing!
Am I:
Missing the right option in the Form Helper or the find function?
Just plain doing it wrong?
I know the logic for the filtering function works fine because the checkboxes are ok, and I've played around with options in the URL and if I enter it manually everything is fine.
So, what I do to get an array that looks like what you want is:
$options = array_combine($department, $department);
echo $this->Form->input('faculty', array('label' => 'Faculty', 'empty' => array('Any'), 'options' => $options));
That should render something like:
<option value="Human Resources">Human Resources</option>
<option value="Finance">Finance</option>
Related
I have a form for registering people to events, while the user can add or remove registered people - the number of inputs is dynamic.
Now, the regular inputs are easy to process, it's just
<input type="text" name="first_name[]">
And I process it as an array in a loop for each participant.
However, I need to have a multiple select input for each person, like
<select multiple name="extras[]">
<option value="42">Some extra feature</option>
...</select>
But that of course puts all the selected options into one array and I can't recognize which user picked which options.
I also tried name="extras[][]", but that just puts each value into a separate array.
How can I make the form/the PHP script a way that I can tell who chose what?
Thanks
send user specific info with option value like
<select multiple name="extras[]">
<option value="42###USER_ID">Some extra feature</option>
</select>
then explode it on your php script like
foreach($_POST["extras"] as $a->$b){
$userAndExtras = explode("###",$b);
$userId = $userAndExtras[1]; // gives USER_ID
$anotherValue = $userAndExtras[0]; // gives 42 or something like that
}
--
or use hidden fields
first sorry if my question isn't clear at all.
So, I have an app with Transaction module in cakePHP. That module (at least) have 3 chained dropdowns like this Supplier > Products > Packages. User choose Supplier, then in products select box show the result only products from that selected supplier. So do the packages, options will show when choose products.
Simply, I use this reference to do first chain. It works. But when going into Packages, it isn't easy as first lol. Why? Because the second form where Products and Packages element have more complex dimensional array from first. In first form (Supplier element), I fetch its data with $this->request->data['Order]['supplier_id']
But in second form, the data that will passed from Ajax like $this->request->data['OrderDetail'][$index]['product_id'] where the index in second form have increment number.
Example:
<select id="Product0" name=data[OrderDetail][0][product_id]></select>
<select id="Product1" name=data[OrderDetail][1][product_id]></select>
<select id="Product2" name=data[OrderDetail][2][product_id]></select>
Then in my controller,
public function functionName() {
$product_id['index'] = $this->request->data['OrderDetail']['index']['product_id'];
}
EDITED
Sorry, forgot to post my ajax code.
<?php
$this->Js->get('#OrderSupplierId')->event('change',
$this->Js->request(array(
'controller'=>'products',
'action'=>'gpbs'),
array(
'update'=>'.OrderDetailProduct',
'async' => true,
'method' => 'post',
'dataExpression'=>true,
'data'=> $this->Js->serializeForm(
array(
'isForm' => true,
'inline' => true)
)
)
));
How can I pass the dynamic index too in AJAX??
So, when it sent to controller, data from every "form element" will match.
Thanks, and sorry for my bad language (and description)
I have an HTML array of 10 select fields that must be populated by jQuery each time the div-popup is called. (Each one gets the same options) We have periodic needs for hundreds of employees and this form is intended to allow requests staffing to be forwarded to upper management for approval in a batch fashion by department. I’ll be using .serialize to submit the form but I am unclear as to how to initialize this element with the proper information for input selection. All the info I could find was about submitting the form array, which I already knew how to do.
Here is the HTML structure:
<select id="detJobsCR[]" name="detJobsCR[]"> </select>
And here is my attempt to populate the selection fields:
$.post("events.php",{a: 'detadd-joblist', dept_id: deptID}, function(data) {
for(var i=0;i<10;i++){
$('#detJobsCR[i]').html(data);
}
});
(I tried explicitly defining each elements array position [0],[1]..etc and that did not help.)
The data returned is simple HTML like:
<option value='38'>Admin Support Assistant I</option>
<option value='39'>Admin Admin Support Assistant II</option>...
Thanks for whatever assistance you can offer!
FYI Update: Musa's answer worked perfectly. I also had issues with Date & Time pickers not working, it turns out, for the same reason. When I converted them to classes I was able to use this(below), and the are all now working as well:
$(".detDateStart").datepicker();
Ids should be unique so each select should have its own id. If you want to have one identifiier to represent all the selects you could use a class e.g. <select class="detJobsCR" name="detJobsCR[]"> </select> and then select them with $('.detJobsCR') and set their html with .html(data)
$.post("events.php",{a: 'detadd-joblist', dept_id: deptID}, function(data) {
$('.detJobsCR').html(data);
});
Your problem is two fold:
You're putting i inside your quotes, so it's not interpreting the value of the variable i
Even if i wasn't inside the quotes, when jquery parses the [i] in the expression it's looking for elements with id detJobsCR and with attribute i defined.
Since you have only ONE element, with ID detJobsCR[] you would query it like this: $('#detJobsCR\\[\\]') You need to escape the [ and ] character so jquery knows it's a part of the ID and NOT a parsing rule (for parsing/looking for an attribute).
As suggested by Musa, you can make your life much easier by using a simple class name that doesn't require escaping values. But if you do want to select by id, the example above should do the trick.
My app contains a form with three choice fields / dropdown lists.
The first is linked to a "relational" field in the entity, and works fine.
The user is supposed to choose a table link first.
The second and third are both linked to string fields in that same entity.
Through jQuery, these choice fields get populated with values based on the decision the user makes in the first dropdown list.
After submitting the form, there is an error for the second and third field: they contain invalid input. When I check the form object, their values were not bound; their values never arrived.
The choice fields for collecting string data from the user looks like this:
->add('sourceName', 'choice', array
(
'label' => 'Choose source name:',
'empty_value' => 'Please choose a table link first...',
'choices' => array(),
'attr' => array('class' => 'extFieldChoice'),
)
After jQuery has done its job, the html select element looks like this:
<select id="someId" name="someName[sourceName]" required="required"
class="extFieldChoice">
<option value="first">first</option>
<option value="second">second</option>
<option value="manymore">Many more...</option>
</select>
I suspect that the error can be found in the initially empty choices array. However, it would be impossible to fill it with all possible choices, because they run in the hundreds.
I've the same problem few days ago and it drive me nuts to find a solution, I get to this question and even probably it's too late I want to share the solutions I've found in case there'll be someone with the same problem, I have found three of them, but none of them seems to be the perfect solution.
In my case I have to save the city selected by an user based on the zipCode. When a user save a new address he wrotes the zipCode and then via ajax I fill-in the city select with options of the cities.
My "choice" field declaration:
$builder->add('city', 'choice', array(
'label' => 'form.city',
'read_only' => true,
'mapped' => false,
'required' => false,
'empty_value' => false,
'choices' => array('none' => 'form.empty.city'),
'data' => null
));
The problem is that the form validation look for two things:
If the form it's related with an entity looks forward the entity
to validate, you can skip this validation easily with the "mapped"
=> false parameter.
The form validation itself, if you have a "choice" type field with or without choices defined when the form validate look towards the first choices you have declared. And I haven't been able to skip the validation for only this field.
So the three ways I have found:
Use the form event and before whe bind the request to the form $builder->addEventListener(FormEvents::PRE_BIND, function (DataEvent $event) use ($xxx) { ...}); (I have an example of use at the linked article) we make the same query to the database we have made on the ajax, we retrieve the values and add them to the chocie field. This is the better way if we think in code, but we have to do the same query twice, and I don't want to do that.
In my case I have to store a string with the city name so another option is to add the city field as a hidden one and insert the whole select as an element. But I don't like this one for many reasons, two of them: I don't like the idea of insert a hole , with and between the other form fields created by symfony2; the other one is that it requires more jquery that it's necessary from my point of view.
Based on the second option, I was filling in some other hidden fields based on the city selection the user has made, so I only include one more hidden field to save the city name; and when the form is submited I remove all the options from the select, so it matches the choices I have defined.
$('#cityChoice').on({
change: function(){
var optionSelected = $(this).find('option:selected');
$('#city').val(optionSelected.val());
$('#latitude').val(optionSelected.data('lat'));
$('#longitude').val(optionSelected.data('lng'));
}
});
$('#myForm').on({
submit: function(){
$('#mySelect option').remove();
}
});
I've decided for the third option, but I think the three of them have bad sides.
For my code, my drop down lists are initiated on the original page, via
<select name =country id=country
onchange=showRecords(this.value,'country','province')>"
This function is taking the value, equating it to country, then querying MySQL, and setting the results where id=province, and creating cascading dropdown lists. This is obviously via Ajax.
So, when $_REQUEST['province'] is set, then the Province dropdown list gets populated with all provinces from the country to which it belongs, etc.; i.e.;
<?if(isset($province)){
echo "<script>showRecords('".$country."','country','province');</script>";}?>
However, for the life of me, I cannot figure out how I can set the default value equal to $_REQUEST['province']. I cannot use the traditional way:
if (($selected) == ($value)) {
$options.= " selected";
}
Because it is querying the AJAX page with one piece of information at a time.
Any ideas would be greatly appreciated.
Your code doesn't seem to make a lot of sense. The particular thing that worries me is that you say ajax is loading one item at a time?
Perhaps something like this. A country select tag like...
<select onchange="showRecords(this)">
As well as creating the javascript function showRecords() which will be called when someone chooses an option in the select tag.
<script>
function showRecords(calling_element) {
// do AJAX call here using calling_element.options[calling_element.selectedIndex].value as the selected country. this.value does not work for select tags.
}
</script>
the PHP page that receives this AJAXed request would reply with a JSON object containing all of the province values, or a delimited list.
once the Javascript showRecords function receives the responce from the PHP page, it would add each of these options to the correct select tag. Once finished, it would set the default value to whichever option it wants by something like the following:
target_element.selectedIndex = {desired list index here};
I have a lot of assumptions to your questions,
first is, if bydefault you have the select province like this
<select id="province">
<option value=""></option>
<option value="California">California</option>
<option value="Washington">Washingthon</option>
</select>
then you can use this script to default select
document.getElementById("province").value="Washington";
but if bydefault you have the select province like this
<select id="province"></select>
then you can use this script to default select
document.getElementById("province").innerHTML='<option value="Wahsington">Washington</option>';
so it depend on your code and your need. maybe if you have another case the problem should be solved in another way.
cmmiiw :)