how to change form fields dynamically in Yii framework - php

I'm new to Yii framework and I'm designing a form (I'm using create form) to create a row in database.
Let me explain about the scenario succintly, so that I can make it clear for what I want-
I have 10 fields in this form. Out of this 10 fields, five fields change dynamically.
I created two div's basically div A and div B and repeated the fields as required for the two cases.
Say some fields which are textfields in div A will be dropdownlists in div B.
<div id="A">
<?php echo $form->labelEx($model,'selectionList'); ?>
<?php echo $form->textArea($model,'selectionList',array('rows'=>6, 'cols'=>50)); ?>
<?php echo $form->error($model,'selectionList'); ?>
</div>
<div id="B">
<?php echo $form->labelEx($model,'selectionList'); ?>
<?php echo $form->dropdownList($model,'selectionList',array('rows'=>6, 'cols'=>50)); ?>
<?php echo $form->error($model,'selectionList'); ?>
</div>
I have two radiobuttons say Single and Multi. When I select Single radiobutton, div A should be considered and div B discarded and when I select Multi, vice versa should happen.
So, is this the right way to change the form fields dynamically. Or else how can I do this using Ajax validation.

Not so related to question:
1) You are using same name for all fields, so only last one will be submitted (check generated html, name is MyModel[selectionList] and not MyModel[][selectionList]
2) You will have lots of problems with Ajax validation and dynamic fields (generated via js), since CActiveForm will generate js code via php.
Related to question:
3) To use one or another field, i suggest you to have two separate field names and just hide with js/css one, that is not needed right now. After submitting, just check value of radio button and decide what fields will be saved.
To validate these inputs, you have to use model scenarios (will define in rules what to validate and what not to):
$model = MyModel();
if ($_POST['C'] == 'multi') {
$model->scenario = 'validateOnlyFirstField';
} else {
$model->scenario = 'validateOnlySecondField';
}
Also you can use second CActiveForm.validate() parameter to define what attributes to validate.

Related

Change to different form on drop down menu selection

I have an apparel ordering form on a page. I want to "swap-out" that form with another one when I select an option from a drop-down list/menu. Ajax maybe? PHP include()? The options in the drop-down would select different forms already created as templates in another directory and render it in place of the other form.
I just want one form showing at a time. Thanks! :)
Don't put too many hidden forms if you can. It's just bad design, especially regarding performance. Your best bet is to:
Create some PHP files with a form inside each
Use an AJAX request to communicate if the condition is met
If you like stuffing up things in one file try passing a unique parameter with AJAX to the PHP file and check its value to decide which form to load.
Example:
var xhr = new XMLhttpRequest();
formID = (condition) ? 1 : 2; // etc
//^^ This one line above means:
if (condition) {
formID = 1;
}
else {
formID = 2;
}
...
// GET request
xhr.open("GET", "forms.php?formID=" + formID);
// POST request
xhr.send("formID=" + formID);
In PHP:
<?php
if (isset($_POST["formID"]) && $_POST["formID"] === 1):
?>
<form id = "1"></form>
<?php
else:
?>
<form id = "2"></form>
<?php
endif;
?>
[EDIT]:
If you want to have each form in a different file then the above code will be:
<form>...</form> // No PHP necessary
In JavaScript use xhttp.send("") without putting any values (only if the forms are in different files).

WordPress Parent/Child Page Filtering

I want to create a form with two fields. The first field lists all pages and the second field lists all child pages (if they exist) of the chosen page from the first field. When the form is submitted the site redirects the user to the chosen page. How can I implement this form?
You're going to need to do an AJAX request to get the second drop down list.
There is a function built into WordPress which gets the pages and you can specify parent ID's and also to show only top level pages.
Heres an example of the code but you'll need to then implement it in a way that best suits your requirements
<?php
$top_level_pages = get_pages(array('parent'=> 0));
?>
<select>
<?php
foreach($top_level_pages as $top_level_page) {
echo '<option>'.$top_level_page['post_title'].'</option>';
}
?>
</select>
You will then need to determine what option the user has clicked and run an AJAX request to fill the second select.
The second select should look something like this:
<?php
$id = $_GET['page_id']; // get the id of the page from the first select
$child_pages = get_pages(array('child_of'=>$id));
?>
<select>
<?php
foreach($child_pages as $child_page) {
echo '<option>'.$child_page['post_title'].'</option>';
}
?>
</select>
Read more about the get_pages() function here: http://codex.wordpress.org/Function_Reference/get_pages

Reference a hidden defined form field in PHP

I am trying to create a template commenting system using Dreamweaver for a site. I have the form setup to submit the webpage and corresponding text to a mysql db. the webpage value is a hidden form field.
The form submits to the db okay but I want to create a repeating view for the comments. How do I reference the hidden form field so I can use it where "WHERE webpage=""" is called?
UPDATE: By repeating view I mean:
<?php do { ?>
<p><?php echo $row_InsertRecords['text']; ?></p>
<?php } while ($row_InsertRecords = mysql_fetch_assoc($InsertRecords)); ?>
My problem is I need to make partial edits to the PHP for that template so I can retrieve comments specific to the child page but Dreamweaver won't let me. It either propogates ALL of the PHP or none of it.
For a dynamic commenting system that uses the templates in Dreamweaver, you can use the following code in your dwt file:
$fname=basename($_SERVER['PHP_SELF']);
$query_ViewRecords = "SELECT * FROM commentsDB WHERE id='".$fname."'";
id can match a hidden value in your comment form defined as such:
<input type="hidden" name="IDField" value=<?php echo "\"$fname\""; ?>/>
The code above was part of code generated by Dreamweaver's DB functions that were later edited by me to add the WHERE clause. This way you can generate HTML that matched each child page when it is created by the template. Make sure codeOutsideHTMLIsLocked parameter is set to true for these changes to propagate to the child pages.

Yii autofill with related values

I am doing a small application. For that Ihave two table like sles and stores
The sales table looks like this
============
Sales
============
id
store_id
Stores
=============
id
store_name
store_location
store_code
description
I have done the model and CRUD for both tables. In stores table I have entered some vales as per the table.
Now in sales controller I have rendered both sales and stores. so here my action create looking like this
public function actionCreate()
{
$model=new Sales;
$stores = new Stores;
// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);
if(isset($_POST['Sales'], $_POST['Stores']))
{
$model->attributes=$_POST['Sales'];
$stores->attributes=$_POST['Stores'];
$valid = $model->validate();
$valid = $stores->validate();
if($valid)
{
$stores->save(false);
$model->store_id = $stores->getPrimaryKey();
$model->save(false);
$this->redirect(array('view','id'=>$model->id));
}
}
$this->render('create',array(
'model'=>$model,
'stores'=>$stores,
));
}
and in sales(_form.php) is like this
<div class="row">
<?php echo $form->labelEx($stores,'store_name'); ?>
<?php echo $form->textField($stores,'store_name',array('size'=>60,'maxlength'=>80)); ?>
<?php echo $form->error($stores,'store_name'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($stores,'store_location'); ?>
<?php echo $form->textField($stores,'store_location',array('size'=>45,'maxlength'=>45)); ?>
<?php echo $form->error($stores,'store_location'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($stores,'store_code'); ?>
<?php echo $form->textField($stores,'store_code',array('size'=>45,'maxlength'=>45)); ?>
<?php echo $form->error($stores,'store_code'); ?>
</div>
Now here when I am doing a sales I want that when I will enter one store name by entering keys then it will start to show the related stores names and the store_location and store_code will be auto-fill. Now can someone kindly tell me how to do this? Any help and suggestions will be appreciable. Thanks a lot.
Edit
With this only one field can be autocomplete. But I want all the other related fields should be also autocomplete with this.
A few thoughts first, and then a general answer to your question.
First, a small niggle, you are really only validating the store model, because you reassign $valid right after checking the sale. Instead, the validation logic should be something more like this:
$valid = $model->validate() && $stores->validate();
If either is invalid, it will return false.
Second, I don't think this code is going to do what you want it to do. If you autocomplete the store information based on existing data and submit it back to the Create action, then your code will try to create a brand new store entry based on that information, introducing duplicate stores in your database. If you always created a brand new sale and a brand new store at the same time, this would work, but I'm pretty sure you don't want that.
Instead, to keep it simple this should be an action dedicated to creating only sales objects. Don't try to create a new store object, just start autofilling details into HTML span or div tags instead of into form fields. The only form field will be the field that is the store id, which will be added to your sales object to indicate the foreign key relationship.
Now, to get autofilling going on several fields, I am going to give you an outline and let you fill in the details. You are going to need a new action in your controller, and some Javascript on the page to handle the autofill.
public function actionGetStoreDetails($id) {
// Get the Store model associated with $id
// Create a JSON object based on this model. Hint, check out CJSON::encode()
// Return the result of the above function call.
}
Now you'll have a piece of Javascript on your view page that does something like the following, using jQuery as an example since it's already in Yii.
$(function () {
$('your-store-id-field-html-id-here').keyup(function () {
// Get the current value of the form field
// Make a $.get() request to the new action defined above, passing the ID
// In the callback function, you'll get a JSON object
// Take the elements of the JSON object, like store.store_name, and assign them to <span id="store_name"></span> type fields in your HTML.
});
});
I realize that this is not copy-and-paste code, but I hope it gives you a really good launching pad. You'll learn a ton if you take the time to fill in the blanks and figure out how to do it fully.

Validating dynamic number of form elements in PHP

I need to make a form where client information can be added by people at the administration department. On the first form page, information like client name, address and contact details can be entered, as well as whether or not the client has children.
The form gets validated by PHP. If the client does not have children, the data is saved to the database. If the client does have children, the form data gets saved in hidden form fields, and a second form page is shown, where up to 10 children and can be added.
However, on initial page view, only one text input is visible. With a javascript button, more text input fields can dynamically be added (until the limit of 10 is reached).
The problem is the validation in PHP. If one of the text inputs contains a non-valid string, the form should be re-displayed with the right number of fields, and those containing errors in a special HTML class (in the CSS i give that class a red border for usability reasons, so the user can immediately see where the error resides). However, because the adding of fields happens with Javascript, the form gets re-displayed with only one field.
Any ideas on how to address this problem are very welcome. I'm proficient in PHP, but JavaScript is very new to me, so I'm not able to make big changes to the script i found to dynamically add fields.
I've dealt with something similar in the past. There are a couple of options that come to mind.
Since you have JS code to generate new fields at the click of the button, why not expand that JS function so it can also be called with some parameters passed. If there are parameters, it will populate the fields with existing data.
Then, if the form is being re-displayed due to errors, or for editing, from PHP, pass some information to Javascript so that when the page loads, you create the fields and populate them with data.
To illustrate, I assume you have something like this:
Add Another Child
And you have the function:
function addNewFormField() {
// create new HTML element to contain the field
// create new input, append to element container
// add container to DOM
}
Change it so it is like this:
function addNewFormField(data) {
// create new HTML element to contain the field
// create new input, append to element container
// add container to DOM
if (data != undefined) {
newFormElement.value = data.value;
newContainerElement.class = 'error';
}
}
And from PHP, add some code that runs onload:
<script type="text/javascript">
window.onload = function() { // replace me with jQuery ready() or something proper
<?php foreach($childInList as $child): ?>
addNewFormField({ value: '<?php echo $child['name'] ?>' });
<?php endforeach; ?>
}
</script>
Hope that helps, its a high level example without knowing exactly how your form works but I've used similar methods in the past to re-populate JS created fields with data from the server side.
EDIT: Another method you could use would be to create the HTML elements on the PHP side and pre-populate them from there, but that could end up with duplicate code, HTML generation from JS and HTML generation of the same stuff from PHP. As long as the JS side was smart enough to recognize the initial fields added by PHP you can go with whatever is easiest to implement. Personally I'd just extend your JS code to handle optional data like illustrated above.

Categories