Zend_Form array notation with no indices - arrays

I would like to create a form that allows the user to input any number of values, each in a separate text field using an array notation. The example expected HTML output is:
<dd id="dupa-element">
<input type="text" name="dupa[]" value="">
<input type="text" name="dupa[]" value="">
</dd>
However, I can't seem to find a way to introduce multiple input elements within a single element, using array notation without indices.
Currently, I do this:
$elt1 = new Zend_Form_Element_Text('1');
$elt1->setOptions(array('belongsTo' => 'dupa'));
$elt2 = new Zend_Form_Element_Textarea('2');
$elt2->setOptions(array('belongsTo' => 'dupa'));
While this works, Zend_Form treats these as independent elements (which can have different sets of validators and filters - that's sort of cool) and the resulting HTML is something along these lines:
<dd id="dupa-1-element">
<input type="text" name="dupa[1]" id="dupa-1" value="">
</dd>
<dd id="dupa-2-element">
<input type="text" name="dupa[2]" id="dupa-2" value="">
</dd>
Is there a (preferably simple) way to achieve the indexless array notation I'm after?

I would follow MWOP's tutorial on creating composite elements. More work, but it's less Trial&Error then akond's solution. Basic idea for me would be extending the Zend_Form_Element_Multi (what you want is how Zend_Form_Element_Multiselect/MultiCheckbox works).

I managed to do this by having a "container subform", and then adding subforms to that "container" e.g.:
$container = new Zend_Form_SubForm();
$subform1 = new Zend_Form_SubForm();
$container->addSubForm($subform1, '1');
$subform2 = new Zend_Form_SubForm();
$subform2->addSubForm($subform1, '2');
$mainForm = new Zend_Form();
$mainForm->addSubform($container,'mysubforms');
Hope that helps.

You need a custom view helper for that.
class Zend_View_Helper_FormMySelect extends Zend_View_Helper_Abstract
{
function formMySelect ($name, $value = null, $attribs = null, $options = null, $listsep = "<br />\n")
{
$result = array ();
foreach ($options as $option)
{
$result [] = sprintf ('<input type="text" name="%s[]" value="">', $name);
}
return join ($listsep, $result);
}
}
Than have in your form something like that:
$form = new Zend_Form();
$form->addElement ('select', 'test', array (
'label' => 'Test',
'multioptions' => array (
'test 1',
'test 2',
'test 3',
),
));
$form->test->helper = 'formMySelect';

Related

Call to a member function save() on null: PROBLEM IN UPDATING

I cannot update my record using foreach
ScoreController.php
public function updateScore(Request $request, $id)
{
foreach ($request->score as $key => $id) {
$scores = Score::find($request->score[$key]);
$scores->save();
}
//dd($request->all());
return redirect('/tabulation')->with('status', 'Score added!');
}
Blade
#foreach ($scores as $score)
<label for="{{$score->id}}" value="{{$score->id}}"></label>
<input type="text" name="score[]" value="{{$score->score}}"/>
#endforeach
First of all, <label> elements do not have a value attribute:
<label for="{{ $score->id }}" value="{{ $score->id }}"></label>
That value="{{ $score->id }}" does nothing, and isn't sent to the server. If you want to send the score's ID to the server, pass that in your input:
#foreach($scores AS $score)
<input type="text" name="scores[{{ $score->id }}]" value="{{ $score->score }}"/>
#endforeach
Next, in your controller, access your variables correctly:
foreach($request->input("scores") AS $id => $scoreValue){
$score = Score::find($id);
$score->score = $scoreValue;
$score->save();
}
The reason you're getting Call to a member function save() on null is that you're trying to find a Score that has an id of whatever $score->score contains. You're not passing or referencing the id correctly.

How To Insert (array values) More then 1 Value From Input Into 1 Row Of Database In Laravel?

I have a form like bellow with more then 1 Input in my form with 1 name like bellow:
<form>
<input type="text" name="family">
<input type="text" name="inputCurrName[]">
<input type="text" name="inputCurrName[]">
<input type="text" name="inputCurrName[]">
<input type="submit" name="submit" value="submit">
</form>
and i have a table with 2 column with column name Family and CurrName
I want to save multiple names into one Row of CurrName Column in form submission , for example this is my data when submitted:
Family Input: ali
inputCurrName[] Inputs : array(jack,peter,lara)
I want to save only 1 record in database with that data like:
familyColumn Value: ali | CurrNameColumn Value: {jack,peter,lara}
I have used code below but it save 3 record in database!
$input = $request->all();
for ($i = 0; $i <= count($input['inputCurrName']); $i++) {
$user_data = [
'family' => $input['family'],
'curr_name' => $input['inputCurrName'][$i],
];
User::Creat($user_data);
}
What should i DO?
You are doing a for loop checking the length of inputCurrName, so it loops through each inputCurrName, which is why you are getting 3 records per FamilyName. In this case, you would only care about 1 record per FamilyName.
There are a few ways you can insert the array of inputCurrName values into 1 record with FamilyName.
You can use serialize() to create a storable representation of a value and unserialize() to decode it when retrieving from the database.
-OR-
You can use implode() to create a comma delimited list when inserting the record. And upon retrieval from the database, use explode() to iterate through each of the comma delimited values.
-OR-
If you prefer json you can do the same with json_encode() and json_decode() the same way as serialize() and unserialize()
+------------+---------------------------------------------------------+
| FamilyName | CurrName |
+------------+---------------------------------------------------------+
| Ali | a:3:{i:0;s:5:"Laura";i:1;s:6:"Peter ";i:2;s:4:"Jack";} |
| Ali | Laura,Peter,Jack |
+------------+---------------------------------------------------------+
Using the following code will give you an example for the table above. curr_name_optional is part of the $user_data array to showcase implode().
<?php
if(isset($_POST) && count($_POST) > 0) {
$inputFamilyName = $_POST['family'];
$inputCurrentName = $_POST['inputCurrName'];
// Your laravel code here..
$user_data = [
'family' => $inputFamilyName,
'curr_name' => serialize($inputCurrentName),
'curr_name_optional' => implode(',', $inputCurrentName),
'curr_name_optional_1' => json_encode($inputCurrentName)
];
echo "<pre>";
print_r($user_data);
echo "</pre>";
}
?>
<form method="post">
Family Name: <input type="text" name="family"/> <br/>
Curr Name: <input type="text" name="inputCurrName[]"/><br/>
Curr Name: <input type="text" name="inputCurrName[]"/><br/>
Curr Name: <input type="text" name="inputCurrName[]"/><br/>
<input type="submit" name="submit" value="submit"/>
</form>
Also, I would make sure to trim and sanitize your form input data before inserting into the database.
You can simply use a foreach and then convert the data into json format then insert into a single row
$arr = [];
foreach($request->get('inputCurrName') as $key => $value){
$arr[$key] => $value;
}
$user_data = [
'family' => $request->get('family_name'),
'curr_name' => json_encode($arr),
];
User::Create($user_data);
Not sure how its working but, you seem to forgot passing csrf-token in your form. Add #csrf just below the <form> tag.

Codeigniter Model: How to use values from a query for further calculations?

i have a function in a model with the following query, and i want to make some calculations with value1, value2 and value3 outside the query. how to get the values out of this result()?
function ($id,$username$) {
$this->db->select("id,value1,value2,value3,value4");
$this->db->from("table1");
$this->db->where("username=$username and id = $id");
$query=$this->get();
$result = $query->result();
$result['$testvalue'] = (value1 * value2/113) + value3;
return $result; }
can someone help? i already found out how to use values from a table, but not from a query!
ok now i know how to use row_array.
i call the row_array in the controller
$data = $this->model_testmodel->testfunction($id, $username);
...
$this->load->view('pages/view_test', $data);
now i wanna know how the view would look like.
i tried many different ways.
in the moment i am stuck with ...
<?php foreach $data as $value: ?>
<label>Value1:</label>
<input type="text" name="value1" value="<?php echo $value['value1']; ?>">
<label>Value2:</label>
<input type="text" name="value2" value="<?php echo $value['value2']; ?>">
...
<?php endforeach; ?>
but i get two errors:
Message: Undefined variable: data
Message: Invalid argument supplied for foreach()
Try this...
function ($id,$username)
{
$this->db->select("id,value1,value2,value3,value4");
$this->db->from("table1");
$this->db->where(array('id'=>$id,'username'=>$username));
$query=$this->db->get();
$result = $query->row();
$testvalue = (($result->value1 * $result->value2/113) + $result->value3);
//test here
echo $testvalue;
$res = array();
$res['testvalue'] = $testvalue;
$res['value1'] = $result->value1;
$res['value2'] = $result->value2;
$res['value3'] = $result->value3;
return $res;
}
It returns $res as array.Easy to execute of you got problem comment.. if it works accept.Lets enjoy..
Then make a function call and accept array in a variable..like this..
first load model then make function call.from your controller
$this->load->model('model_name');
$data= $this->model_name->function_name($id,$username);
//Fetch returned array like this..
echo $data['testvalue'];
echo $data['value1'];
//so on

Translation of form input

I'm currently internationalising my cake-php-webapp which is working very fine.
Everything is translated but form inputs:
echo $this->Form->input('name', array('class' => 'form-control'));
This generates a label
<label for="UserName">Name</label>
How can I specify that "Name" should be translated as well?
I think this would be the best way I know so far:
echo $this->Form->input('name', array('class' => 'form-control', 'label'=>__('field_name')));
But is there a way without specifying the label?
In CakePHP 2.3, if you take a look in the built-in FormHelper class:
public function label($fieldName = null, $text = null, $options = array()) {
...
if ($text === null) {
if (strpos($fieldName, '.') !== false) {
$fieldElements = explode('.', $fieldName);
$text = array_pop($fieldElements);
} else {
$text = $fieldName;
}
if (substr($text, -3) === '_id') {
$text = substr($text, 0, -3);
}
$text = __(Inflector::humanize(Inflector::underscore($text)));
}
...
}
It looks to me like if you don't set the label text, it derives your label text from the field name, then calls the translate function on it.
Have you tried just creating an input without specifying the label text, then saving a translation for the text that automatically gets generated for that input's label in your corresponding .po file?

Uploading multiple files userfile[] array?

I am trying to upload multiple images and I have a jquery plugin set up so I can browse for multiple files and select them.
The only problem I am having is accessing the file array in my controller, does anyone know how I can do this? Thanks.
view:
<input type="file" name="userfile[]" id="userfile" class="multi" />
I had this same issue on a project last year, after a bit of searching I found a perfect function.
I take no credit it for it, but cannot remmeber where I found it so if anyone knows please link back to the author.
Make sure the form has the files named like this
<input type="file" name="userfile"/>
<input type="file" name="userfile2" />
<input type="file" name="userfile3" /> ..etc
Or
<input type="file" name="userfile[]" />
The function..
function multiple_upload($upload_dir = 'uploads', $config = array())
{
$files = array();
if(empty($config))
{
$config['upload_path'] = '../path/to/file';
$config['allowed_types'] = 'gif|jpg|jpeg|jpe|png';
$config['max_size'] = '800000000';
}
$this->load->library('upload', $config);
$errors = FALSE;
foreach($_FILES as $key => $value)
{
if( ! empty($value['name']))
{
if( ! $this->upload->do_upload($key))
{
$data['upload_message'] = $this->upload->display_errors(ERR_OPEN, ERR_CLOSE); // ERR_OPEN and ERR_CLOSE are error delimiters defined in a config file
$this->load->vars($data);
$errors = TRUE;
}
else
{
// Build a file array from all uploaded files
$files[] = $this->upload->data();
}
}
}
// There was errors, we have to delete the uploaded files
if($errors)
{
foreach($files as $key => $file)
{
#unlink($file['full_path']);
}
}
elseif(empty($files) AND empty($data['upload_message']))
{
$this->lang->load('upload');
$data['upload_message'] = ERR_OPEN.$this->lang->line('upload_no_file_selected').ERR_CLOSE;
$this->load->vars($data);
}
else
{
return $files;
}
}
Now it's been a while since I've used it so if you need any extra help setting it up just let me know.
To use Jquery multiple upload using html elements array [] developed as follows in the act of receiving data sobrescrevi the global variable $ _FILES PHP so that the function do_upload could read later. see:
#copy the original array;
$temp_array;
foreach($_FILES['fil_arquivo'] as $key => $val)
{
$i = 0;
foreach($val as $new_key)
{
$temp_array[$i][$key] = $new_key;
$i++;
}
//
}
$i = 0;
foreach($temp_array as $key => $val)
{
$_FILES['file'.$i] = $val;
$i++;
}
#clear the original array;
unset($_FILES['fil_arquivo']);
$upload_path = 'media/arquivos';
$config['upload_path'] = $upload_path;
$config['allowed_types'] = 'doc|docx|xls|xlsx|ppt|pptx|pdf|txt|jpg|png|jpeg|bmp|gif|avi|flv|mpg|wmv|mp3|wma|wav|zip|rar';
$config['encrypt_name'] = true;
$this->upload->initialize($config);
foreach($_FILES as $key => $value)
{
if( ! empty($value['name']))
{
if($this->upload->do_upload($key))
{
$this->upload->data();
}
}
}
The HTML provided by ojjwood above will produce multiple input boxes. If you'd only like to have one input box but still upload multiple files, you need to include the attribute multiple="multiple" in your <input> element. The [] in name="userfile[]" allows the posted data to be an array and not just a single value.
On the Codeigniter/PHP side of things, you need to use $_POST['userfile] instead of $this->input->post('userfile') for working with arrays.

Resources