I built a web app with CodeIgniter 3, with PHP 7.0 and MySQL 5.6.
I have a table named 'departments' and the users can create rows with a form on the app.
The result in the database looks like this:
id 1
name accounting
In another form, I allow users to create a sub-department, which depends on one department. I let the user choose the department in a dropdown menu. The name of the options are the name of the department and the value is the id, according to the stored data.
<select name="department">
<option value="department_id">department_name</option>
...
</select>
But I use the CodeIgniter form_helper, so I get the data from my database, an array containing the rows (which are arrays):
echo form_drop_down('department', $departments_from_DB);
I read in the CI's DOC (about html_escape() function) that the form_helper should escape its content:
If you use any of the form helper functions listed on this page, the form values will be automatically escaped, so there is no need to call this function. Use it only if you are creating your own form elements.
But when I make a test with an alert script, the alert works, so...
I don't know how to escape the names of the departments. In fact I know, html_escape() works, but sometimes it's needed, sometimes not, sometimes it escapes twice, I'm a little confused.
A solution could be to write the html code in a loop, and escape the PHP value, but is there a more elegant solution ?
The form_dropdown() function escapes the values of the <option value="xxx">Name</option> tag ('xxx' in my example), but not the word between the tags ('Name' in my example).
To escape everything, use html_escape() on the array given the the form_dropdown() function.
Example:
$array_data = array(
'a' => 'Jack',
'<script>bad_script</script>' => 'John',
'c' => '<script>another_bad_script</script>'
);
// this will escape the array's key values (Jack and John are ok but not the last one)
echo form_dropdown('select_value', $array_data);
// this will escape the entire array
echo form_dropdown('select_value', html_escape($array_data));
Related
I have this in my controller
public function editProfile(Request $request){
$question1 = Question::where('group',1)->lists('question', 'id');
$question2 = Question::where('group',2)->lists('question', 'id');
return view('user', compact(''question1', 'question2'));
}
$question = {\"1\":\"What is the first name of your best friend in high school?\",\"2\":\"What was the name of your first pet?\",\"3\":\"What was the first thing you learned to cook?\",\"4\":\"What was the first film you saw in the theater?\"}
$question2 = {\"5\":\"Where did you go the first time you flew on a plane?\",\"6\":\"What is the last name of your favorite elementary school teacher?\",\"7\":\"In What city or town does your nearest sibling live?\"}
I would like to translate the value in both question 1 and question 2 and pass it to user blade without changing the key, Any suggestions?
As specified at the localization doc, you need to populate a lang file with translation strings. So, let's say you want to show both Spanish and English strings. In this case you'd need to create two files: /resources/lang/en/messages.php and /resources/lang/es/messages.php. The content of one of those files would be somewhat like this:
<?php
// resources/lang/es/messages.php
return [
'welcome' => 'Bienvenido'
];
This way, you could access the strings in there with the following method: __('messages.welcome'), which would return the string for the language set on your config/app.php -- the default entry is en, by the way, but you can set it to whatever you want. The value in there will define which language will be chosen when selecting strings.
Another method to create translation strings is using the string itself as key, storing them in a JSON file instead of PHP. For example, the following translation string:
{
"I love programming.": "Me encanta programar."
}
would be accessible through this: __('I love programming.').
Having said that, you may solve your problem through the two methods presented above. You could store in your DB keywords for the questions instead of the whole text, and create translation for as many languages as you want. Also, you could keep the questions in your database and create translation strings for those questions. Finally, you'd need to iterate over the fetched entries and translate each one of them, or use some Collection helper to do the hard work for you, like transform or map.
I want to make 3 dependents drop down list, each drop down dependent to the previous drop down, so when I select an item from first drop down , all data fetch from database and add to second drop down as item.
I know how to do this in a normal php page using ajax, but as opencart uses MVC I don't know how can I get the selected value
Basically, you need two things:
(1) Handling list changes
Add an event handler to each list that gets its selected value when it changes (the part that you already know), detailed tutorial here in case someone needed it
Just a suggestion (for code optimization), instead of associating a separate JS function to each list and repeating the code, you can write the function once, pass it the ID of the changing list along with the ID of the depending list and use it anywhere.
Your HTML should look like
<select id="list1" onchange="populateList('list1', 'list2')">
...
</select>
<select id="list2" onchange="populateList('list2', 'list3')">
...
</select>
<select id="list3">
...
</select>
and your JS
function populateList(listID, depListID)
{
// get the value of the changed list thorugh fetching the elment with ID "listID"
var listValue = ...
// get the values to be set in the depending list through AJAX
var depListValues = ...
// populate the depending list (element with ID "depListID")
}
(2) Populating the depending list
Send the value through AJAX to the appropriate PHP function and get the values back to update the depending list (the part you are asking for), AJAX detailed tutorial here
open cart uses the front controller design patter for routing, the URL always looks like: bla bla bla.bla/index.php?route=x/y/z&other parameters, x = folder name that contains a set of class files, y = file name that contains a specific class, z = the function to be called in that class (if omitted, index() will be called)
So the answer for your question is:
(Step 1) Use the following URL in your AJAX request:
index.php?route=common/home/populateList
(Step 2) Open the file <OC_ROOT>/catalog/controller/common/home.php , you will find class ControllerCommonHome, add a new function with the name populateList and add your logic there
(Step 3) To use the database object, I answered that previously here
Note: if you are at the admin side, there is a security token that MUST be present in all links along with the route, use that URL:
index.php?route=common/home/populateList&token=<?php echo $this->session->data['token'] ?> and manipulate the file at the admin folder not the catalog
P.S: Whenever the user changes the selected value in list # i, you should update options in list # i + 1 and reset all the following lists list # i + 2, list # i + 3 ..., so in your case you should always reset the third list when the first list value is changed
P.P.S: A very good guide for OC 1.5.x => here (It can also be used as a reference for OC 2.x with some modifications)
I'm having some trouble using the Former plugin for Laravel, to handle forms & fields.
The use-case is an "edit"-form for a given model.
Former::text('title')
->label('Title')
->value( $title );
Former::text('description')
->label('Description')
->value( $description );
Rules:
The title must always exist and be at least 10 chars long.
The description may be empty.
Expected behaviour:
When loading the edit form, I expect the form to show the values of $title and $description in the fields.
Whenever submitting a the form with invalid field-values, I expect the submitted values to be shown in the fields, instead of the values of $title and $description.
Problem:
This works only when submitting non-empty strings!
When submitting an empty-string, it's like Former handles it like the field-hasn't even been submitted, and therefore uses the value given by $title or $description instead.
I thought Former was able to do this "smart", and take the value($variable) value only if the posted data does not contain the field. But it seems Former is taking the variables value also when the submitted was empty.
Why is this a problem?
Imagine you edit both fields, and actually want to change the title and remove the description entirely, which is valid according to the rules. Then, because you entered a too short title, the validation does not pass, and title will get the new (too short) title as field-value, while the description value will fall back to the value of the $description variable, instead of showing an empty field, which was posted.
It feels like $_POST['description'] = "" is treated like $_POST['description'] = null or is not set - even though the empty field is part of the post.
In your view
//replace
Former::text('title')
->label('Title')
->value( $title );
//with
Former::text('title')
->label('Title')
... and in your controller
//add
Former::populate($model);
$model beeing the model in question :)
$model->title must ofc exist and have the same value as $title in your original code.
if you use ->value($somevalue) with Former, $somevalue will allways be used.
I use a RESTAdapter model to fill a Ember's select view with options.
The contentBinding is mapped the a property in the controller, where I use this.set('myProperty', model.find(someQuery)).
model.find(someQuery) with 1 result works perfect, but model.find(someQuery) with many results have a weird effect. The last object from the result is showed as many times as the length of the result.
{{view Ember.Select contentBinding="myProperty" optionValuePath="content.id"
optionLabelPath="content.name"
selectionBinding="selectedResult"
prompt=" "}}
Interesting. At first glance the code you included in your question looks fine. To debug:
1) Check to be sure the query results are what you expect.
content = model.find(someQuery); //with many results
// wait for results...
console.log(content.getEach('id')); //expect array of ids
console.log(content.getEach('name')); //expect array of names
2) examine contents of myProperty - from template:
{{#each myProperty}}
<pre>{{id}}.{{name}}</pre>
{{/each}}
Expect template to output id/name for each option.
I normally name my db specific fields in my forms like this "objectname[columnname]", I tseems CI cant access these values using $this->input->post('objectname[columnname]'), what do I do? there is not a chance in hell im renaming 100+ form fields.. I am actually disliking CI, it really is getting in the way of progress by changing the de facto PHP norms...
And were you using $_POST['objectname[columnname]'] or $_POST['objectname']['columnname'] ?
Have you tried the equivalent for the latter
$obj = $this->input->post('objectname');
echo $obj['columnname'];
?
If it works, you can write you own helper to retreive that like post_val('objectname[columnname]').
I saw this post whilst looking for a similar issue, but worked out a CI way to do it, sorry if I'm resurrecting it, but it does appear fairly high on the Google results.
// Load the 'array' helper
$this->load->helper('array');
// Use the 'element' function to return an element from the array
echo element('ColumnName', $this->input->post('ObjectName'));
Hope this helps anyone who comes here in future.
HTML code:
<input type="text" value="" name="myPostArrayName[]">
<input type="text" value="" name="myPostArrayName[]">
Handling form with codeigniter:
$data = $this->input->post('myPostArrayName', TRUE);
You can access data in order like this
echo 'Value of the first element in the form array is '.$data[0];
echo 'Value of the second element in the form array is '.$data[1];
I think someone who has access to codeigniter documentation, had better to add a simple html post array handling example.
I seems I can rely on the $_POST var, but I thought this was reset?
You can cast the post array as an object and use method chaining to return sub-arrays (now properties) using PHP 5.3's method chaining all on one line.
Extend the input class by making a class called MY_Input and put the extended class in the application/core folder. CI 2.0 will automatically use the extended class with the MY_ prefix, and you can add methods to this new class. Extending the input class is cleaner than making helpers.
This method casts the post array, or a nested array (a sub array below the parent), as an object.
/* Cast an array from CI post as an object and return the object */
public function post_obj($key = null){
$post_return = $this->post($key);
if (false === $post_return)
return false;
return (object)$post_return;
}
Now I can retrieve nested values in one line of code using PHP 5.3's method chaining for objects.
$active = $this->input->post_obj('user')->active;
I just went with the $_POST['objectname']['colname'] option as i usually do even though this is probably not the CI way..