Yii autofill with related values - php

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.

Related

Laravel (Beginner) - Display data from a selected row from a dropdown

This is Controller.php
public function dropdown($id)
{
$stations = Station::lists('station_name','id');
return view('stations.show')->withStation($station);
return view('stations.dropdown',compact('stations', 'selectedStation','selectedStation'));
}
This is the view.php
{{ Form::select('station',$stations,null,['class' => 'form-control']) }}
<br>
<?php
if(isset($_GET['submit'])){
$selectedStation = $_GET['station'];
echo $selectedStation;echo "<br>";
}
else
{
echo "not working";
}
?>
corresponding Database table.
This gives me a drop-down like in the below image.
When a station is selected it displays only "id" of the selected station. How to retrieve other columns of the selected station ?.
Many ways that you can tackle this and I have also made some assumptions.
Your list (it would seem) only contains the name & the id.
I assume that you don't want to reload the page when you get the information for the specific item that you have chosen in the dropdown.
Here are the first 2 options that come to mind.
1.) AJAX - Use javascript framework like jQuery and monitor change() for the select, on change get the id and fire it to another route in Laravel which takes the ID and returns some more information in JSON. You can then use JS to display this to your users as you please.
2.) Preloaded JSON - Write new DB Query that gets all the information that you want and store it in JSON format inside some <script> tags. It wont be viewable to the user. Then you can use jQuery or other JS framework to grab that data again on change()
Part 2 will be faster, and if you have got 100,000s records i would advise that for perf.
Apologies if I totally misunderstood the question, it seems like you need a JS solution rather than Laravel/PHP solution. (Without a bad UX) if you did wan't more data you would need to post it and the fetch data from DB on new request.
To display all the columns of all stations you can do the following.
Please note, doing this you fetch all which may not be necessary and there may be better methods available on the eloquent model class depending on what you are trying to do.
Controller
public function showTable()
{
//Fetch all stations from the database
$stations = Station::all();
//Return fetched data to the view
return view('stations.show', ['stations' => $stations]);
}
View - stations/view.blade.php
<ul>
#foreach ($stations as $station)
<li>{{$station->station_name}} - {{$station->rainfall}}</li>
#endforeach
</ul>
For more information and examples about the eloquent model class you can check: https://laravel.com/docs/5.2/eloquent

how to change form fields dynamically in Yii framework

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.

Yii very weird save() behaviour

I have encountered something very, very weird. Working in VirtualBox, Ubuntu, Apache2, PHP, MySQL I got some very strange behaviour from one particular model.
I wanted to add ability to enter multiple language versions of the same string, say product name. I used jQuery to make nice tabs with languages and created temporary array to store all that information, used CActiveForm widget to collect and present data.
<?php foreach($languages as $language): ?>
<div id="tab_<?=$language->code?>">
<div class="row">
<?php echo $form->labelEx($model,'name'); ?>
<?php echo $form->textField($model,"translations[$language->code][name]",array('size'=>60,'maxlength'=>128)); ?>
<?php echo $form->error($model,"translations[$language->code][name]"); ?>
</div>
</div>
[...]
So this is how I collect data into a $translations array. This is my $translations array:
$translations = array(
'name' => 'NewName',
'sub_name' => 'Subname'
);
Then I obviously assign it to a proper model in Controler action:
[...]
foreach ($translations as $key => $value){
$x = new Translations();
$x->language = $key;
$x->id = $product->id;
$x->name = $value['name'];
$x->sub_name = $value['sub_name']
$x->save();
}
[...]
Now there are also other fields that are only one per product:
[...]
<div class="row">
<?php echo $form->labelEx($model,'something'); ?>
<?php echo $form->textField($model,'something',array('size'=>60,'maxlength'=>128)); ?>
<?php echo $form->error($model,"something"); ?>
</div>
</div>
And those are stored simply by
$product->save();
Everything is in a neat transaction.
HOWEVER....
What I get in result is like this (join on translations and product table):
id name subname something
1 NewN
2 NewName S
3 NewName Subname Som
4 NewName Subname Something
4 records when I only add ONE.... and more text I put in, more records are created. Split by random number of characters, sometimes as little as 4 sometimes as much as 12. This is repeatable but not always.... I am totaly dumbstruck by this behaviour.
Anyone ever saw anything like this and can shed ANY light on it?
Thanks in advance!
The problem could be coming in at many stages:
the form
the controller
binding the data from the form to the model
the model saving (ActiveRecord)
or even the database
So 'divide and conquer' your problem.
MySQL
Turn on your 'general mysql log' to see the queries that are being sent to MySQL. If they look like the weird forms you are seeing above, then it's not the database. It's unlikely you'll have any problems at this stage, but it's good to rule it out.
ActiveRecord
Then hardcode your values into the model. In your controller, just create an instance of the model and save it. Does that replicate the problem you're having? If so, it's a problem with your implementation of ActiveRecord. Try removing the relationships and work on that.
Controller
There could be something weird in your controller. Again, hardcode the data that you want to pass to the model when you create the instance.
Binding
It could be a problem with how you are binding data from the form to the model. Manually set the values of the form, then bind that data to the model as normal.
This is where back-end testing can really help you, as you can isolate what's working from what's not. Look into tools like Behat and PHPUnit.

Jeditable, PHP + MySQL

Okay, I'm horrendously new to MySQL and PHP, but could use some help here.
Grand vision: a big page full of editable fields (I'm using Jeditable, an edit-in-place jquery plugin) that stores values to different fields in the same row of a MySQL database.
I'm totally lost on how to properly post the values to different fields of the MySQL database, though. What I have is below; it's derived from the examples Jeditable provides. I can enter data into the fields, but it saves the ID of the field - not the data - and it appends it into multiple columns of my database, not the one correct column.
So, in short - how would I map what you see here to different locations in my MySQL database (example: one line item/record with a customer name value, a size value, an MRR at initial sale value, etc?)
Here is my HTML-
<!-- JQuery to extract form data... -->
<script type="text/javascript" charset="utf-8">
$(document).ready(function() {
$('#paragraph_1').editable('save.php');
});
$(document).ready(function() {
$('#custsize').editable('save.php');
});
$(document).ready(function() {
$('#mrratsale').editable('save.php');
});
</script>
<!-- my form fields... -->
<h2 id="paragraph_1" name="paragraph_1"></h2>
<h3 id="custsize" name="custsize"></h3>
<h3 id="mrratsale" name="mrratsale"></h3>
...and here is my save.php file...
<?php
require_once 'config.php';
$query=sprintf("INSERT INTO customerdata (ListItemID, CustName, CustSize, MrrAtSale)
VALUES (%d, '%s', '%s', '%s')",
$id, $_POST['id'], $_POST['id'], $_POST['id'], stripslashes($_POST['value']));
$dbh->exec($query);
/* What is echoed back will be shown in webpage after editing.*/
print $_POST['value'];
?>
Any help at all would be much, much, much appreciated (and try not to laugh!)
What you have to do is target each editable database write to its own function - so you can target individual fields.
So your html files should read (I also cleaned up your JS):
<!-- JQuery to extract form data... -->
<script type="text/javascript" charset="utf-8">
$(document).ready(function() {
$('.paragraph_1').editable('save.php?type=paragraph');
$('.custsize').editable('save.php?type=custsize');
$('.mrratsale').editable('save.php?type=mrratsale');
});
</script>
<!-- my form fields... -->
<h2 id="1" class="paragraph_1"></h2>
<h3 id="1" class="custsize"></h3>
<h3 id="1" class="mrratsale"></h3>
Notice how I added query strings to the save.php file. You should also change the elements' id to a field in the record, so you can update the correct record.
The php file:
<?php
require_once 'config.php';
$type = (isset($_GET['type'])) ? $_GET['type'] : "";
$value = (isset($_POST['value'])) ? $_POST['value'] : ""; //value posted
$id = (isset($_POST['id'])) ? $_POST['id'] : ""; //id of the element
if($type == "paragraph") {
mysql_query("UPDATE customerdata SET paragraph='$value' WHERE id='$id'");
} elseif ($type == "custsize") {
mysql_query("UPDATE customerdata SET CustSize='$value' WHERE id='$id'");
} elseif ($type == "mrratsale") {
mysql_query("UPDATE customerdata SET MrRatSale='$value' WHERE id='$id'");
};
print $value;
?>
You should add some validation and clean the data before putting it in the database but this should get the jEditable working.
Note that you should probably update the record rather than inserting it otherwise you will be creating a new record everytime the data is editted.
You can see the id is used to update the correct record.
I haven't really used jEditable recently but this should get you started.
Okay, I'm a bit confused. Is your problem that you are trying to target certain fields, but yet you can't? If so, make sure there is a field designated as a Primary Key and use that to specify which row you want the field to be updated. If you don't target a specific row containing a precise value to be be matched up against, I fail to see how you're going to ever change the correct record when you have more than one in a table.
Second, how are you handling all of these fields? I hope they are not just generated on the fly each time the form code is saved. I say this because unless you have a very good naming convention setup, it will be a nightmare to ever sort out data saved in that table later on. In other words, spend some time clearly labeling your fields (user_name, user_email, etc. NOT field01, field02, etc.) Also be aware that if the code is somehow creating a new field based on what fields are present/submitted, that opens up a bunch of other stuff to be mindful of. Can a person make a page with a thousand form fields in HTML, submit that and your database try and make afield for all of them? If you have some sort of field verification system in place (with some finite limits in place), I'd suggest stop relying on code you didn't make/understand to build/manage your database info automagically. Just make the fields you need and name them intelligently.
Third, why not just code the PHP and MySQL stuff by hand? Not only will that help you learn how to code better in both of those, it also sounds like the Jeditable thing is a waste of time if it doesn't work like you want with minimal tweaks. What you're describing is not hard to do - and don't use JQuery if you can help it (it's a crutch for new JS people).
Hope some of this helps/answers your question(s).

What is the best way to get jQuery/Ajax to work with CodeIgniter in this example?

I have a problem trying to get CodeIgniter and jQuery to produce ajax functionality. I have been coding all day, learning jQuery, and generally getting my butt kicked. Let me break down the situation, and hopefully, someone will have the courage to help me.
I have a trouble ticket system that displays many tickets on a page... each ticket is nested inside of a multitude of divs like so:
<div class="eachticketwrapper" id="ticket-362">
<div class="actionlog">
<form action="<?= base_url();?>admin/updateticket/362" method="post" id="362" name="362">
<ul class="displayinline">
<p>Action Log:
<span class="actionlog-362">
<?php echo $actionlog; ?>
</span>
</p>
</div> <!--actionlog-->
<p>
<textarea name="actionlogbox362" cols="100" rows="2" id="actionlogbox362" style="" ></textarea>
</p>
<div class="finalbuttons">
<?php echo form_open('admin/updateticket/'.'362'); ?>
<li><?php
$attrib = "class='updatebutton-362' id='updatebutton-362'";
echo form_submit("RapidTask",'Update',$attrib); //setup the button, and set permissions. ?></li>
<?php echo form_close(); // close the form. ?>
</div> <!--finalbuttons-->
</div> <!--eachticketwrapper-->
When run, the $actionlog should resemble something like the following:
worker - 2009-06-25 18:15:23 - Received and Acknowledges Ticket.
worker - 2009-06-25 18:15:23 - Changed Status to In Progress
worker - 2009-06-25 18:15:46 - Changed Priority to High
worker - 2009-06-25 18:15:46 - Changed Category to Network Connection Problem
worker - 2009-06-25 18:17:16 - did something
And then there is a textarea and an update button following it.
Here is the contents of my supplementary jQuery file:
$(document).ready(function() {
$('.updatebutton-362').click(function()
{
var id = $(this).attr("id").split("-"); // Split the id value at the hyphen, and grab the ticketnum.
$('.actionlog-'+id[1]).load('http://localhost/ci/index.php/ajaxtestc/'); // do something...
return false; // return false so default click behavior is not followed.
});
});
the ajaxtestc controller looks like this:
function index()
{
$data['actionlog'] = $this->m_tickets->actionLogPull(362);
$this->load->vars($data);
$this->load->view('content/ajaxtestform');
}
And the m_tickets model looks like this:
function actionLogPull($requestedNum=NULL)
{
$this->db->where('ticketnum', $requestedNum); // Grab only the status for the ticket requested $requestednum=NULL
$requestedTicket = $this->db->get('tickets'); // set the initial ticket info to a variable
$returnvalue = $requestedTicket->row('actionlog');
return $returnvalue;
}
Now... here is what I WANT. I want to click the update button, have it take whatever the worker has typed into the text area, add it to the end of the existing log in the database, and refresh the action log on the screen.
I can't come up with a clear way to do this. Can anyone shed some light on how I could start this process?
Any help is greatly appreciated, and thanks in advance.
Inside $('.updatebutton-362').click, change the .load() line to (replace name, id with whatever parameters you want to send):
$.post('http://localhost/ci/index.php/ajaxtestc/',
{name: "John Doe", id: "anything"},
function(data) {
$('.actionlog-'+id[1]).html(data);
}
});
Then above everything in index() in the ajaxtestc controller, parse the _POST variables and call whatever function you have in your model to update the action log.
Whatever is displayed by the index() action will be loaded into the actionlog span.
First, your code look mess. The first tag seems unclosed, and the form_open is nested inside it.
My rule of thumb to developing a web is, make it work without any javascript first. Then add javascript as better experience.
In your case above, try build the form with old way, after submit, redirect to page you want. After that working well, add jquery one at a time. Use jquery form plugins to submit form. Add a simple checking in the controller to handle ajax request.
I usually use json for form submit, so in controller, I will return a json_encode array to a ajax submitted form request.
Hope this help you.

Categories