Get select information before submitting - ajax

well i was reading around the solutions that stack-overflow was giving but i couldn't find the correct one... so here is my question:
Im creating a form with multiple selects ( not the select multiple="true" ) , no , i mean a form with lets say 4 different selects... retrieving data from a database so if i fill my first "select" lets say Style1 then i would like to get the "style1" selection so i can configure my second select query based on that and i can DISTINCT the values im looking for... i don't know if you get my idea, i've read i need to use AJAX but i couldn't figure out how to...
<form method="post">
<select name="category">
<?php $test = mysql_query("SELECT category FROM test_table GROUP BY category");
while($testing = mysql_fetch_array($test)){
echo "<option value=".$testing["category"].">".$testing["category"]."</option>";
}
?>
</select>
<select name="model">
<?php $test2 = mysql_query("SELECT model FROM test_table WHERE model = 'TRYING TO COMPARE WITH THE VALUE WITH THE FIRST SELECT' GROUP BY model");
while($testing2 = mysql_fetch_array($test2)){
echo "<option value=".$testing2["model"].">".$testing2["model"]."</option>";
</select>
</form>
Well that was just to get an idea, is not like the real one but its a pretty close example.
Sorry for my weird spelling
Thanks for your help !

<form method="post">
<select name="category" onchange="javascript:getDroupDownValues(this.value);">
<?php $test = mysql_query("SELECT category FROM test_table GROUP BY category");?>
<?php while($testing = mysql_fetch_array($test)):?>
<option value="<?php echo $testing["category"];?>"><?php echo $testing["category"];?></option>
<?php endwhile;?>
</select>
<div id="model-category">
</div>
</form>
<script type="text/javascript">
function getDroupDownValues(value)
{
jQuery.ajax({
dataType: "html",
type: "POST",
evalScripts: true,
url: 'your ajax url', // example your site url /ajax.php
data: ({category:value}),
success: function(data, textStatus) {
jQuery("#model-category").html(data);
}
});
}
</script>
Now in ajax.php script
<?php if(isset($_REQUEST['category']) && $_REQUEST['category']):?>
<select name="model">
<?php $test2 = mysql_query("SELECT model FROM test_table WHERE model = '{$_REQUEST['category']}' GROUP BY model");?>
<?php while($testing2 = mysql_fetch_array($test2)):?>
<option value="<?php echo $testing2["model"];?>"><?php echo $testing2["model"];?></option>
<?php endwhile;?>
</select>
<?php endif;?>

Related

How to prepopulate a cascaded drop down and attachment on validation failure

I have 2 drop downs, just for simplicity let's say they are Country / States.
<select id="country_id" name = "country_id">
<option value="">Select...</option>
<?php foreach ($countries as $country): ?>
<option value="<?php echo $country->id; ?>" <?php if (null !== set_value("country_id") && set_value("country_id") == $country->id) : echo ' selected '; ?>>$country->name;
<?php endforeach?>
</select>
<select id="state_id" name = "state_id">
<option value="">Select...</option>
</select>
<input type="file" name="attachment_id" value="" />
What I do is when the country is selected I populate the states. This I do using AJAX and ".change" and this works well
The problem I'm having is when I do form_validation and
$this->form_validation->run() == FALSE
Then I reload all controls using set_value, which does work for the first drop down (the countries) just fine, however the second drop down stays empty( as there was no ".change" triggered on the "country_id" to populate "state_id".
Similarly I am asked to re-attach the file
So what I need and is not working is after form_validation fail to
Load up second drop down with data => RESOLVED see below with .trigger event
Select the previous selection int he second drop down => ALMOST RESOLVED however only if I use alert :)
The attachment should still stay attached until form is dismissed or committed successfully => NOT RESOLVED
I feel like I need to manually trigger the data change to get (1) but in my case I have a foreach (see above) where I just add lines and if the selection is the same I simply set is as "selected" but nothing happens after.
Here is the AJAX part
<script>
$(document).ready(function(){
$("#country_id").change(function(){
$.ajax({
url:"<?php echo base_url(); ?>location/getCountries",
data: {country_id: $(this).val()},
type: "POST",
success: function(data){
$("#state_id").html(data);
$("#state_id").val(null);
}
});
});
<?php if (!empty(set_value('country_id'))) : ?>
var value = "<?php echo set_value('country_id'); ?>";
$('#country_id').val(value);
$('#country_id').trigger('change');
<?php endif; ?>
<?php if (!empty(set_value('state_id'))) : ?>
var value = "<?php echo set_value('state_id'); ?>";
//without this alert the selection doesn't work
alert(value);
$('#state_id').val(value);
$('#state_id').trigger('change');
<?php endif; ?>
});
</script>
So I am getting the values saved only if I use an alert. This seems to be an asynchronous execution where the selection of second drop down is done before it gets populated, so the last thing to do is to figure out how to wait.
Still to do the attachment part
Thanks in advance!
Add this code at the end of view page
For country dropdown
<?php if (!empty(set_value('country_id'))) : ?>
<script type="text/javascript">
var value = "<?php echo set_value('country_id'); ?>";
$('select[name="country_id"]').find('option[value="'+value+'"]').attr("selected",true);
</script>
<?php endif; ?>
For state dropdown
<?php if (!empty(set_value('state_id'))) : ?>
<script type="text/javascript">
var value = "<?php echo set_value('state_id'); ?>";
$('select[name="state_id"]').find('option[value="'+value+'"]').attr("selected",true);
</script>
<?php endif; ?>
Follow the below points
1) For select tag, use set_select(), like this
<select name="myselect">
<option value="one" <?php echo set_select('myselect', 'one', TRUE); ?> >One</option>
<option value="two" <?php echo set_select('myselect', 'two'); ?> >Two</option>
<option value="three" <?php echo set_select('myselect', 'three'); ?> >Three</option>
</select>
2) If the form validation failed, call your ajax function to set second drop down.
3) For attachment, Whatever result of the form validation, first upload the image and keep the image path in session variable. After successful form validation, save the data into database and destroy the session variable.
edited >>>
**html**
<?php
if (isset($edit) && !empty($edit)) { //while editing
$StateID = $edit['StateID'];
$CountryID = $edit['CountryID'];
} else { // while adding
$StateID = set_value('StateID');
$CountryID = set_value('CountryID');
} ?>
<div class="col-3">
<div class="form-group">
<label class="mb-0">Country</label>
<select class="form-control Country" id="country" name="CountryID" data_state_value="<?php echo $StateID; ?>" >
<option value="">Select Country</option>
<?php
foreach ($country as $row) {
$selected = ($row->id == $CountryID) ? 'selected' : '';
echo '<option value="' . $row->id . '"' . $selected . '>' . $row->country_name . '</option>';
}
?>
</select>
<span class="text-danger font9"><?php echo form_error('CountryID'); ?></span>
</div>
</div>
<div class="col-3">
<div class="form-group">
<label class="mb-0">State</label>
<select class="form-control State" id="State" name="StateID">
</select>
<span class="text-danger font9"><?php echo form_error('StateID'); ?></span>
</div>
</div>
**script**
$(document).on('change', '.Country', function () {
var country_id = $(this).val();
var state_id = $(this).attr('data_state_value');
url = $("body").attr('b_url');
$.ajax({
url: url + "Education/fetch_state",
method: "POST",
data: {
country_id: country_id,
state_id: state_id
},
success: function (res) {
var response = $.parseJSON(res);
$('#State').html('<option value="">Select State</option>' + response.view);
$('.State').trigger('change');
}
});
});
$('.Country').trigger('change');
**controller**
public function fetch_state() {
$data = array();
if (isset($_POST['country_id']) && !empty($_POST['country_id'])) {
$states = $this->Location_model->fetch_state($this->input->post('country_id')); // array of states
$view = array();
if (!empty($states)) {
foreach ($states as $val) {
$selected = (isset($_POST['state_id']) && !empty($_POST['state_id']) && $_POST['state_id'] == $val['id']) ? 'selected' : '';
$view[] = "<option value='" . $val['id'] . "'" . $selected . ">" . $val['states_name'] . "</option>";
}
$data['view'] = $view;
$data['status'] = 0;
} else {
$data['status'] = 0;
$data['view'] = '<option value="">No State Found</option>';
}
} else {
$data['status'] = 0;
$data['view'] = '<option value="">Select State</option>';
}
echo json_encode($data);
}

Creating a cascade drop down without primary and foriegn key relationship with coeigniter

This is the structure of my table "task"
projectname
employee
clientname
task
Dependencies are as follows
One project has multiple task
One project has multiple employees
I need to create a dropdown list when user selects a particular project tasks relevant to them will automatically load to the next dropdown list. In this situation I do not need primary and foriegn key relationship. Any help would be really appreciated
This is my controller
public function Task(){
$data['cname'] = $this->welcome4->show_students3();
$data['projects'] = $this->welcome4->show_students();
$data['employee'] = $this->welcome4->show_students2();
$this->load->view('template/navigation');
$this->load->view('template/sideNav');
$this->load->view('template/header');
$this->load->view('Task',$data);
$this->load->view('template/footer');
}
This is my model
function show_students2(){
$query = $this->db->get('employee');
$query_result = $query->result();
return $query_result;
}
function show_students3(){
$query = $this->db->get('clientdetails');
$query_result = $query->result();
return $query_result;
}
function show_students4(){
$query = $this->db->get('task');
$query_result = $query->result();
return $query_result;
}
This is my view
<div class="form-group">
<label>Select Project</label>
</div>
<div class="form-group">
<select name="projectname" class="input form-control">
<option value="none" selected="selected">Select Project</option>
<?php foreach($projects as $s):?>
<option value="<?php echo $s->projectname?>"><?php echo $s->projectname?></option>
<?php endforeach;?>
</select>
</div>
<div class="form-group">
<label>Select Client</label>
<select name="cname" class="input form-control">
<option value="none" selected="selected">Select client</option>
<?php foreach($cname as $s):?>
<option value="<?php echo $s->cname?>"><?php echo $s->cname?></option>
<?php endforeach;?>
</select>
</div>
<div class="form-group">
<label>Select Employee</label>
</div>
<div class="form-group">
<select name="employee" class="input form-control">
<option value="none" selected="selected">Select Employee</option>
<?php foreach($employee as $s):?>
<option value="<?php echo $s->employee?>"><?php echo $s->employee?></option>
<?php endforeach;?>
</select>
</div>
This loads all projects, clients, employee in the database.But now I want when project is selected in the first drodown, second dropdown should show only relevant clients and employees to it. Not all of them
Lets consider this will be your Projects select box, in which you are loading data dynamically on page load with php.
<select name="projectname" id="projectname"></select>
Tasks select box.
<select name="tasks" id="tasks"></select>
Inside your controller add below mentioned code. This function will be used for get data from ajax call.
public function getTasks() {
$Id = $this->input->post('project_id');
if ($Id):
$this->load->model('Task_model', 'Tasks', TRUE);
$data = $this->Tasks->getProjectTasks($Id);
if ($data):
$result['status'] = true;
$result['records'] = $data;
endif;
else:
$result['status'] = false;
endif;
echo json_encode($fdata);
}
Inside model please add this function. Which will fetch data from DB
ans pass it to controller back.
public function getProjectTasks($id = null) {
if ($id):
$this->db->select('id,task');
$this->db->where('project_id', $id);
$this->db->where('status', TRUE);
$query = $this->db->get('tasks');
$records = $query->result();
if ($records):
return $records;
else:
return false;
endif;
else:
return false;
endif;
}
And finally in you View file please add below function.
$(document).on('#projectname', 'change', function() {
var projectId = $(this).val();
$.ajax({
type: 'POST',
url: 'URL',
data: {project_id: projectId},
dataType: "json",
beforeSend: function() {
$('#tasks')
.empty()
.append('<option selected="selected">Select Task</option>');
},
success: function(data) {
if (data.status) {
$.each(data.records, function(i, item) {
$('#tasks').append($('<option>', {
value: item.value,
text: item.text
}
));
});
} else {
$('#tasks')
.empty()
.append('<option selected="selected">No Task available</option>');
}
}
});
});

print related detail using dynamically created select list

I am coding a module in which i have to print the category.
For this firstly i had coded to filter on what basis you want to search (ID/ NAME) and then according to this information selected by user, a select list get created dynamically.
Here is the problem bit: this dynamically created select list, I want to print
it's related data (using where clause) in form field. I'm not getting the field's echo. The rest part (dynamic select list box) is appearing;
Here is my view:
<div class="navbar">
<div class="navbar-inner">
<h2>Show Category</h2>
<?php
$dropdown_category= array(
'c_id'=>'Category Code',
'c_name'=>'Category Name');
echo form_dropdown('clas',$dropdown_category,'','id="clas"');
?>
<div id="name_sec">
<!-- PRONT DROP DOWN HERE !-->
</div>
</div>
<br/>
<div class="navbar-inner">
<br/>
<div id="name_sec2">
<!-- PRONT form fields HERE !-->
</div>
</div>
<div class="navbar"></div>
</div>
My controller :
public function category_display()
{
//Checking so that people cannot go to the page directly.
$this->load->helper('form');
$this->load->database();
$tabel_for_this="its_category";
$data_toprint='';
$id=$this->input->post('send_data_post');
$query = $this->db->query("SELECT ".$id." FROM ".$tabel_for_this." ");
foreach ($query->result_array() as $r)
{
$dropdown_category2[$r[$id]] = $r[$id];
}
echo form_dropdown('clas2',$dropdown_category2,'','id="clas2"');
}
public function category_display_in_fields()
{
$this->load->helper('form');
$this->load->database();
$tabel_for_this="its_category";
$data_toprint='';
$id=$this->input->post('send_data_post_for_field');
$sql = "SELECT * FROM ".$tabel_for_this." where '".$id."'= ?";
$query = $this->db->query($sql,$id);
foreach ($query->result_array() as $r)
{
echo '<input type="text" name="c_dateadded" placeholder="Date" value>
<input type="text" name="'.$r['c_id'].'" placeholder="'.$r['c_name'].'" value>
<select name="c_addedby" placeholder="Added By" value>
<option>added by</option><option>name1</option><option>name2</option><option>name3</option><option>name4</option>
</select>
<input type="text" name="c_description" placeholder="Description" value>
<input type="text" name="i_nos." placeholder="Total Items No." value>
<input type="text" name="c_i_nos_avail" placeholder="Available Stock" value> ';
}
}
here is my js :
<script type="text/javascript" src="http://code.jquery.com/jquery-1.6.4.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$("#clas").change(function(){
var send_data=$("#clas").val();
$.ajax({
type:"post",
url:"category_display",
data:"send_data_post="+send_data,
success:function(data){
$("#name_sec").html(data);
}
});
});
});
</script>
<!-- CODE TO PRINT DATA IN FIELDS!-->
<script type="text/javascript">
$(document).ready(function(){
$("#clas2").change(function(){
var send_data2=$("#clas2").val();
$.ajax({
type:"post",
url:"category_display_in_fields",
data:"send_data_post_for_field="+send_data2,
success:function(data2){
$("#name_sec2").html(data2);
}
});
});
});
</script>
JUST FOR TESTING PURPOSE I HAVE CODED DATABASE RELATED THING IN CONTROLLER
Both the column and the variable in your where clause are the same:
$id=$this->input->post('send_data_post_for_field');
$sql = "SELECT * FROM ".$tabel_for_this." where '".$id."'= ?";
$query = $this->db->query($sql,$id);
So the returning query will do something like this:
SELECT * FROM table WHERE var = var
Which is wrong.
It should be something like this:
$sql = "SELECT * FROM ".$tabel_for_this." where id= ?";

Display Dynamic SKU on configurable product view Magento

I have this script to show the dynamic sku on select option, but i cannot get working.
Is loading the correct sku, but on select nothing happen.
This code get list of sku on Javascript and update a div on select option for product on configurable product view.
<?php
$_product = $this->getProduct();
$_attributes = Mage::helper('core')->decorateArray($this->getAllowAttributes());
?>
<?php if ($_product->isSaleable() && count($_attributes)):?>
<dl>
<?php foreach($_attributes as $_attribute): ?>
<dt><label class="required"><em>*</em><?php echo $_attribute->getLabel() ?></label></dt>
<dd<?php if ($_attribute->decoratedIsLast){?> class="last"<?php }?>>
<div class="input-box">
<select name="super_attribute[<?php echo $_attribute->getAttributeId() ?>]" id="attribute<?php echo $_attribute->getAttributeId() ?>" class="required-entry super-attribute-select" onchange="return changeSku(this);">
<option><?php echo $this->__('Choose an Option...') ?></option>
</select>
</div>
</dd>
<?php endforeach; ?>
</dl>
<script type="text/javascript">
var spConfig = new Product.Config(<?php echo $this->getJsonConfig() ?>);
</script>
<?php endif;?>
<?php
$conf = Mage::getModel('catalog/product_type_configurable')->setProduct($_product);
$col = $conf->getUsedProductCollection()->addAttributeToSelect('*')->addFilterByRequiredOptions();
echo '<script type="text/javascript">';
echo '
document.observe("dom:loaded", function() {
$("sku-container").update("<strong>Product Id: </strong> Select an option to display Product Id");
});
';
echo ' function changeSku(sel){';
$itemId = array();
foreach($col as $simple_product){
$itemId[] = array($simple_product->getSelectLabel() => $simple_product->getSku());
}
//echo "<pre>";
//print_r($itemId);
//echo "</pre>";
foreach($itemId as $val){
foreach($val as $k => $v){
echo "\n".'if(sel.options[sel.selectedIndex].value == "'.$k.'"){'."\n";
echo '$("sku-container").update("<strong>Product Id: </strong>'.$v.'");'. "\n";
echo '}';
}
}
echo "\n".'if(sel.options[sel.selectedIndex].value == ""){'."\n";
echo '$("sku-container").update("<strong>Product Id: </strong> Select an option to display Product Id");'. "\n";
echo '}';
echo "}";
echo "\n</script>";
?>
I appreciate any help.
Thanks
The script is almost correct except for $simple_product->getSelectLabel() being a wrong key. No such method/property exists in a simple product model. In order to make the script work, this key should be replaced with a right one - a Product Id. Utilizing product id, it is possible to find the sku of the product being selected.
So, first of all you need to reorganize itemId array to make it a "productId => productSku" map:
$productMap = array();
foreach($col as $simpleProduct){
$productMap[$simpleProduct->getId()] = $simpleProduct->getSku();
}
Then you need to change the "onchange" function call to pass Configurable's attribute id to the changeSku() function. Thus the underlying logic is able to search appropriate simple product's attributes.
onchange="return changeSku(<?php echo $_attribute->getAttributeId() ?>, this);">
And after that you need utilize configurable's config in order to map selected simple product's attribute id to the product id selected:
function changeSku(confAttributeId, sel) {
var productMap = <?php echo Mage::helper('core')->jsonEncode($productMap);?>;
var selectedAttributeId = sel.options[sel.selectedIndex].value;
if (selectedAttributeId) {
var options = spConfig.config.attributes[confAttributeId].options;
var productId = options.find(function (option) {return option.id == selectedAttributeId}).products[0]
$("sku-container").update("<strong>Product Id: </strong>" + productMap[productId]);
} else {
$("sku-container").update("<strong>Product Id: </strong> Select an option to display Product Id");
}
}
For your reference, below is the summary of how the whole template looks like (I've beautified it a little):
<?php
$_product = $this->getProduct();
$_attributes = Mage::helper('core')->decorateArray($this->getAllowAttributes());
?>
<?php if ($_product->isSaleable() && count($_attributes)):?>
<dl>
<?php foreach($_attributes as $_attribute): ?>
<dt><label class="required"><em>*</em><?php echo $_attribute->getLabel() ?></label></dt>
<dd<?php if ($_attribute->decoratedIsLast){?> class="last"<?php }?>>
<div class="input-box">
<select name="super_attribute[<?php echo $_attribute->getAttributeId() ?>]" id="attribute<?php echo $_attribute->getAttributeId() ?>" class="required-entry super-attribute-select"
onchange="return changeSku(<?php echo $_attribute->getAttributeId() ?>, this);">
<option><?php echo $this->__('Choose an Option...') ?></option>
</select>
</div>
</dd>
<?php endforeach; ?>
</dl>
<script type="text/javascript">
var spConfig = new Product.Config(<?php echo $this->getJsonConfig() ?>);
</script>
<?php endif;?>
<div id="sku-container"></div>
<?php
$conf = Mage::getModel('catalog/product_type_configurable')->setProduct($_product);
$col = $conf->getUsedProductCollection()->addAttributeToSelect('*')->addFilterByRequiredOptions();
$productMap = array();
foreach($col as $simpleProduct){
$productMap[$simpleProduct->getId()] = $simpleProduct->getSku();
}
?>
<script type="text/javascript">
document.observe("dom:loaded", function() {
$("sku-container").update("<strong>Product Id: </strong> Select an option to display Product Id");
});
function changeSku(confAttributeId, sel) {
var productMap = <?php echo Mage::helper('core')->jsonEncode($productMap);?>;
var selectedAttributeId = sel.options[sel.selectedIndex].value;
if (selectedAttributeId) {
var options = spConfig.config.attributes[confAttributeId].options;
var productId = options.find(function (option) {return option.id == selectedAttributeId}).products[0]
$("sku-container").update("<strong>Product Id: </strong>" + productMap[productId]);
} else {
$("sku-container").update("<strong>Product Id: </strong> Select an option to display Product Id");
}
}
</script>
This will do the task you originally needed.
Also note the following
Your approach won't work for a configurable product with two or more configurable attributes. For that product a final simple product is not known until a user selects values for all the select inputs. So an approach should be changed to check all the selects before outputting SKU.
The code doesn't consider a case, when user edits product configuration, rather than specifying configuration for a new product. You can go to editing mode from the Shopping Cart clicking the Edit link. In such a case all the select inputs will be pre-filled with previously chosen values. But the text will say "Select an option to display Product Id". The script might also produce other Javascript errors in Edit mode. The code should be slightly modified in order to support Edit mode as well.
The template is overfilled with logic. A Magento template should have only simple prints and foreach-iterations. All the methods like $conf->getUsedProductCollection()->addAttributeToSelect('*')->addFilterByRequiredOptions() are better to be moved to block. This reduces code complexity.
Hope it helps.

Subcategories with Ajax and Codeigniter

I have select box with categories and I want to display subcategories in another select box using ajax an CodeIgniter.
This is part of my view:
<script type="text/javascript">
$(document).ready(function(){
$('#tip_category').change(function(){
msg = 'category_id='+$(this).val();
$.ajax({
type : 'POST',
url : '<?php echo base_url().'admin/tips/ajax_subcategory';?>',
data : msg
});
});
});
</script>
Category:<br/>
<select name="tip_category" id="tip_category">
<?php foreach($categories as $category): ?>
<option value="<?php echo $category['id'] ?>"><?php echo $category['name'] ?>
</option>
<?php endforeach; ?>
</select><br/>
Subcategory:<br/>
<select name="tip_subcategory"
<?php if(isset($subcategories)): ?>
<?php foreach($subcategories as $subcategory): ?>
<option value="<?php echo $subcategory['id'] ?>"><?php echo $subcategory['name'] ?>
</option>
<?php endforeach; ?>
<?php endif; ?>
</select><br/>
This is part of my controller:
public function ajax_subcategory() {
$this->load->model('tips_model');
$data['subcategories'] = $this->tips_model->get_subcategories($this->input->post('category_id'));
}
My problem is that i dont know how to send data ($data['subcategories']) back to view and display subcategories. Thx for help !
I think you are just missing the return (in whatever format you need):
return $data;
You can modify your controller to:
public function ajax_subcategory() {
$this->load->model('tips_model');
$data['subcategories'] = $this->tips_model->get_subcategories($this->input->post('category_id'));
return $this->output->set_output($data);
}

Resources