Zend File element and setElementsBelongTo() - php

I'm currently trying to create a form using Zend_Form. Inside the form there is a displayGroup of File element and Text element. Since it is a dynamic form, I would like the input field names to be in array form (something like the one below).
requestRow[1][fileName]
requestRow[1][fileDesc]
requestRow[2][fileName]
requestRow[2][fileDesc]
setElementsBelongTo() worked for the text elements but not on the File elements. Is it the correct behavior? Or do I need extra method call or attribute/property for that?
If it is the specification, is there any workaround for that?
I have also tried manually setting the File element name with array format but it also doesn't work.
I'm using Zend 1.12
Thank you in advance!

Saw the following comment about the current limitation File element.
Posted by Thomas Weidner (thomas) on 2011-09-19T06:30:50.000+0000
No, this is a limitation of php's file upload capability. From ZF's
manual:
{quote} File elements in Subforms
When you use file elements in subforms you must set unique names. For
example, if you name a file element in subform1 "file", you must give
any file element in subform2 a different name.
If there are 2 file elements with the same name, the second element is
not be displayed or submitted.
Additionally, file elements are not rendered within the sub-form. So
when you add a file element into a subform, then the element will be
rendered within the main form. {quote}
Posted by Thomas Weidner (thomas) on 2011-09-29T18:11:15.000+0000
Closing as wont fix as there is actually no way to solve this
limitation
http://framework.zend.com/issues/browse/ZF-11741

Related

Altering the text after a checkbox using the Drupal Form Api

I got the following issue. A clients wants that the text after checkboxes are links to other pages and thus between ...
I have the following code:
$form['boxes_brands'] = array(
'#type'=>'checkboxes',
'#title'=>'<div id="title-container">Merken</div>',
'#options'=>$brandArr,
'#default_value'=>$_SESSION['filter_brands_cat'],
);
=> $brandArr is an array of brands.
I looked in the Form Api of Drupal but I did not find an option to do this. I could alter the values in $brandArr but of course that changes the value of the value attribuut of the input object too.
Using the prefix and suffix options won't do it either because I don't want the checkboxes in the tags too.
Is there a clean way to do this?
Thanks!
If you created the form with the UI, then you should be able to specify something like this in as the options and links would be rendered as links:
google|This is a link to google
yahoo|Yahoo
bing|Bing!
See example:
Otherwise, you should be able to modify the $brandArr accordingly to create links in the label. Doing this should NOT change the value of the attribute as it should be a $value->$label associative array. You just need to change the $label not the $value.

How to update XML file through web form using PHP: form name issue

I have done some searching on tis but cannot seem to find any easy way or other examples on the subject (I am new to PHP, XML as of a couple of months ago so bear with me :) ).
I have an XML file populated with useable data
I need to be able to load the whole XML file into a form, each child node loading into its own form field
I want to modify the various fields
and then save everything back to the same XML file, using PHP to parse the data
PROBLEM : how to label the "names" in the form fields so I know how to populate the proper child nodes. XML file looks like:
<band id="1">
<group>Guns N Roses</group>
<member>Duff</member>
</band>
<band id="2">
<group>Iron Maiden</group>
<member>Paul</member>
</band>
To update this through a web form I thought it best to have the name attribute in the INPUT field the same as the child node name.... but then I have would have 2 x groups and 2 members.
Should I somehow append the attribute to the end of the name such that
<input name=group.1 value=$group.1>
<input name=group.1 value=$group.2>
(where $group.1 and $group.2 can be found using PHP DOM)
and then I have a unique name/value pair in the php $_POST array to use to update the XML file through DOM.
It all just seems very hackish and clunky, and I wonder if there is a more graceful way to do all of this. Again, very new to this... maybe there is already some obvious way to do this that I am completely missing.
Thanks for any help guys
Mr. B
First of all, your "XML" is not valid XML. It needs to have a root element that wraps all the content. Right now, you lack this root element because at the top level you have more than one element (......).
So correct this by wrapping your whole string into one other element:
$xml = "<root>$xml</root>";
Then load it in a DOMDocument element, and traverse and loop through it with DOMXPath or in a simpleXML object (which probably is quicker to code, not sure about performance).
edit: how to name the form elements for an easy update:
<input name="band[1][group]" value="$group1">
<input name="band[1][member]" value="$member1" />
<input name="band[2][group]" value="$group1">
<input name="band[2][member]" value="$member1" />
After you send the form via post, you can traverse all inputs doing a foreach over $_POST['band'] array:
if (count($_POST) > 0)
{
if (is_array($_POST['band'])
{
foreach ($_POST['band'] as $id => $band)
{
echo "Band $id has group ".$band['group']." and member ".$band['member']."<br />\n";
}
}
}

Zend Form Element Label "for" Attribute

I subclass Zend_Form to allow re-use as I describe in my other SO question. It's working very well, except for one issue that I found. In my view script I use this code to render the label for fields:
echo $this->formLabel($this->element->getFullyQualifiedName(),
$this->element->getLabel());
The rendered label has the original element id as the value in the for attribute rather than the new, suffixed, element id. Is there a bug in the Zend code, am I missing a step or doing something incorrectly?
I think the reason is that you use formLabel view helper independently. As a result, the helper is not aware of any attributes that you specified for your input text field. So, you should provide these attributes to the formLabel. For example you could do the following:
echo $this->formLabel(
$this->element->getFullyQualifiedName(),
$this->element->getLabel(),
$this->element->getAttribs()
);
The above code should produce for tag that matches your input elements id. Otherwise, the for tag will be set to the elements name.

How can I customize FancyUpload to upload multiple files, each with its own data (e.g. caption, title)?

I'll be answering this question
I want to allow my users to upload multiple files in one go and want to use FancyUpload to do it. I can get a basic version of FancyUpload working but I now need to allow users to specify some metadata for each file such as a caption or title.
Unfortunately, I've run into a couple of problems. First, I need to visually link the inputs for a file with that file. Upon choosing files for upload, FancyUpload displays a list of those files. Therefore, I will need a differing number of inputs depending on how many files have been chosen and I will also need to associate each of those inputs with a specific file.
Second, I need to POST the metadata along with the file. However, FancyUpload only allows you to specify metadata for every file. That is, I can have an input and add it as a POST parameter but then every file will receive that parameter. I need to be able to specify, say, a title for each file that is sent.
Please note that this answer assumes a working knowledge of JavaScript and Mootools. I'll tackle each problem in turn:
Rendering the Inputs
It turns out that the rendering of each file is handled by a method on the FancyUpload2.File class. To alter it, we will need to implement it as follows:
FancyUpload2.File.implement({
render: function() {
//copy the entire render function in here
}
});
Make sure you copy the entire render function across. At the moment, this will just override the default render method with... the default render method. However, we only want to alter the rendering process, not rewrite it so this is good. About halfway through the method is the line this.element = new Element('li', {'class': 'file'}).adopt( and then a list of elements inside the adopt method that FancyUpload will render. At the very end of the adopt method, enter the following:
new Element('input', {'class': 'caption', 'name': 'caption[]', 'type': 'text'})
As you can see this will add a new input to the list, intended to get a caption from the user. You might also want to add in a label and any other form elements.
Now if you select some files, you will notice that they are all rendered with the extra elements you have specified.
Posting the Inputs
When you create the FancyUpload object, you need to specify a new event in its options object:
onBeforeStart: function() {
var listSize = this.fileList.length;
for (var i=0; i < listSize; i++){
var caption = this.fileList[i].element.getElement('input.caption').get('value');
var opts = $merge(this.options.data, {
'caption': caption
});
this.fileList[i].setOptions({'data' : opts});
}
}
onBeforeStart gets fired just before we send the AJAX request. This means anything we do here will be done after the user has finished entering data and before that data gets sent. Brilliant! We need to add the new data to each file so the first thing to do is iterate over the file list. Then we find the value of caption input associate with the current file in the list and assign it to the var caption.
Then we access the files data with this.options.data and use $merge to create a new object with all that data and our new data as well. We assign this object to var opts. Finally we overwrite the files original options by using setOptions. Now when the file is sent, out data gets sent along with it and will be accessible from $_POST if you are using PHP.
Credits: I found the key to the solution to the second problem in this post.

Zend Framework - Static form elements

I have got a form which a user can use to create a new store and to edit an existing one. When this form is being used to edit a store there are certain fields that I want the user to see but not edit eg. store_id. I have explored the different Zend_Form_Elements hoping to find some kind of static element but with no luck.
So my question is, how do I display information using Zend_Form that a user can't edit?
Thanks.
readonly alone is not enough, because users will still be able to edit it if they really want. You should use $element->setIgnore(true) that will ensure that Zend_Form_Element won't try to populate the element from POST/GET, and I'd double check that also. You have to make sure the values you are getting into the databases can never contain this element.
Finally, if you would like your element to be displayed in a different way than just with readonly, you can do that by changing the element decorators.
I just managed to work this one out myself. The solution was to change the view helper on the elements to the formNote helper eg. $element->helper = 'formNote'. The result of this was that the value gets displayed as straight text instead of being inside a form element.
Thanks for your answers.
That's very good solution when you don't need to populate the element value when the form is submitted.
It's equivalent solution is to use the Form Element method setAttrib() and disable the form element
$formElement->setAttrib('disable','disable')
which will only freeze the element.
But if you need to populate the field, using the previous solutions you will probably need additional hidden field added, which will pass the value. Developing custom form element will be good style but that's not welcomed by each developer so you can use some tricky way to set a form element as a text only but populate its value. That way is when you create the element as a hidden field, set its value and use the Form Element method setDescription() to set and display the element text value.
$formElement = new Zend_Form_Element_Hidden( 'elName',
array( 'label' => 'elLabel', 'value' => 'elValue' ) );
$formElement->setDescription( 'elValue' );
Then you can render that hidden element and display the value with the
$formElement->getDescription().
$element->setAttrib('readonly', 'true');
http://www.w3.org/TR/html401/interact/forms.html#adef-readonly
According to Amr Mostafa, if you use:
$element->setAttrib('readonly', 'true');
OR
$element->setAttribs(array('disabled' => 'disabled'));
User still send values by POST/GET and they are stored in DB.
The only way for me to don't taking into account the values from POST/GES is:
$element->setIgnore(true)
Example:
$element = new Zend_Form_Element_Text('element');
$element->setIgnore(true);

Categories