New to YII. I have to load a page with AJAX call on selection from CJuiAutoComplete Field.
<?php
echo CHtml::label(Yii::t('location', 'PLZ'), 'GeoData_plz');
?>
</td><td>
<?php
$this->widget('zii.widgets.jui.CJuiAutoComplete', array(
'name' => 'GeoData[plz]',
'source' => 'js:function(request, response) {getAutoCompleteData("plz", response);}',
'options' => array(
'minLength' => '0',
),
'htmlOptions' => array(
'size' => 8,
'maxlength' => 15,
'class'=>'addrChange'
),
'value' => $model->geo_data->plz));
?>
I tried adding onSelect of different plz in htmlOptions (to act as submit buttion) but its not working, Here I just want to submit plz in database on select of different plz below is the code.
echo CHtml::label(Yii::t('location', 'PLZ'), 'GeoData_plz'); ?></td><td><?php $this->widget('zii.widgets.jui.CJuiAutoComplete', array(
'id' => 'GeoData_plz',
'name' => 'GeoData[plz]',
'source' => 'js:function(request, response) {
getAutoCompleteData("plz", response);
}',
'options' => array(
'minLength' => '0',
//'select' => 'js:function(event, ui){ alert(ui.item.value) }',
),
'htmlOptions' => array(
'size' => 8,
'maxlength' => 15,
'class'=>'addrChange',
'onSelect' => 'CHtml::ajax({
url: "'.$this->createUrl('location/getAddressTabContent').'",
dataType: "json",
data: {
loc_id: ' . $model->id . '
},
success: function(data) {
$("#addressBricks").html(data.brick_table);
}
})'
),
'value' => $model->geo_data->plz
));
Thanks for the reply, But here i just want to submit data on select I used the code given by you but its not working
$this->widget('zii.widgets.jui.CJuiAutoComplete', array(
'model'=>$model,
'attribute'=>'GeoData[plz]',
'source'=>'js: function(request, response) {
getAutoCompleteData("plz", response);
$.ajax({
url: "'.$this->createUrl('location/getAddressTabContent').'",
dataType: "json",
data: {
loc_id: ' . $model->id . '
},
success: function (data) {
$("#addressBricks").html(data.brick_table);
}
})
}',
'options'=>array(
'delay'=>300,
'minLength'=>0,
'select'=>'js:function(event, ui) {
$.ajax({
type:"POST",
url: "' . $this->createUrl('location/getAddressTabContent'') . '",
data: {selected: ui.item.value},
success:function(data) {$("#addressBricks").html(data.brick_table);}
});}'
),
'htmlOptions' => array(
'size' => 8,
'maxlength' => 15,
'class'=>'addrChange',
'value' => $model->geo_data->plz,
'id' => 'GeoData_plz',
),
));
It's in options array, not in htmlOptions:
'options'=>array(
.....
'select'=>'js:function(event, ui) {
//your ajax request here
//use $.ajax()
//your selected item = ui.item.id
}
Hope this will help.
I have edited your widget. Just use this widget to get it working.
$this->widget('zii.widgets.jui.CJuiAutoComplete', array(
'model'=>$model,
'attribute'=>'GeoData[plz]',
'source'=>'js: function(request, response) {
$.ajax({
url: "'.$this->createUrl('location/getAddressTabContent').'",
dataType: "json",
data: {
loc_id: ' . $model->id . '
},
success: function (data) {
$("#addressBricks").html(data.brick_table);
}
})
}',
'options'=>array(
'delay'=>300,
'minLength'=>1,
),
'htmlOptions' => array(
'size' => 8,
'maxlength' => 15,
'class'=>'addrChange',
'value' => $model->geo_data->plz,
'id' => 'GeoData_plz',
),
));
Related
I'm having problems updating a record with an image. I don't what I need to do. My image is stored in a public folder called 'img/products'
ProductController.php
This is my controller. It works well without modifying the image.
public function update(Request $request, $id)
{
$validator = Validator::make($request->input(), array(
'name' => 'required',
'category_id' => 'required',
'description' => 'required',
'price_neto' => 'required',
'iva' => 'required',
'price_total' => 'required',
'image' => '',
));
if ($validator->fails()) {
return response()->json([
'error' => true,
'messages' => $validator->errors(),
], 422);
}
$products = Product::find($id);
$products->name = $request->input('name');
$products->category_id = $request->input('category_id');
$products->description = $request->input('description');
$products->price_neto = $request->input('price_neto');
$products->iva = $request->input('iva');
$products->price_total = $request->input('price_total');
$products->image = $request->input('image');
$products->save();
return response()->json([
'error' => false,
'products' => $products,
], 200);
}
Product.js
All I know is that I have to use var formData = new FormData ($ ("# frmAddProduct") [0]); as in the store function. I can enter records with images but not edit them. My image is stored in a public folder called 'img/products'
$(document).ready(function() {
$("#btn-edit").click(function() {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
type: 'PUT',
url: '/product/' + $("#frmEditProduct input[name=product_id]").val(),
data: {
name: $("#frmEditProduct input[name=name]").val(),
category_id: $("#frmEditProduct select[name=category_id]").val(),
description: $("#frmEditProduct input[name=description]").val(),
price_neto: $("#frmEditProduct input[name=price_neto2]").val(),
iva: $("#frmEditProduct input[name=iva2]").val(),
price_total: $("#frmEditProduct input[name=price_total2]").val(),
image: $("#frmEditProduct input[name=image]").val(),
},
dataType: 'json',
success: function(data) {
$('#frmEditProduct').trigger("reset");
$("#frmEditProduct .close").click();
window.location.reload();
},
error: function(data) {
var errors = $.parseJSON(data.responseText);
$('#edit-product-errors').html('');
$.each(errors.messages, function(key, value) {
$('#edit-product-errors').append('<li>' + value + '</li>');
});
$("#edit-error-bag").show();
}
});
});
});
function editProductForm(product_id) {
$.ajax({
type: 'GET',
url: '/product/' + product_id,
success: function(data) {
$("#edit-error-bag").hide();
$("#frmEditProduct input[name=name]").val(data.products.name);
$("#frmEditProduct select[name=category_id]").val(data.products.category_id);
$("#frmEditProduct input[name=description]").val(data.products.description);
$("#frmEditProduct input[name=price_neto2]").val(data.products.price_neto);
$("#frmEditProduct input[name=iva2]").val(data.products.iva);
$("#frmEditProduct input[name=price_total2]").val(data.products.price_total);
$("#frmEditProduct file[name=image]").val(data.products.image);
$("#frmEditProduct input[name=product_id]").val(data.products.id);
$('#editProductModal').modal('show');
},
error: function(data) {
console.log(data);
}
});
}
You should check if the file exists before trying to delete, for example:
$product = Product::find($id);
if(!$product)
{
return response()->json(['error' => 'Product not found'], 404);
}
if (Storage::disk('local')->exists('img/products/'.$product->image)) {
Storage::disk('local')->delete('img/products/'.$product->image);
}
Take a look one example only:
public function update(UpdateProductFormRequest $request, $id)
{
$product = Product::find($id);
$data = $request->only('name','category_id','description',
'price_neto','iva','price_total');
if(!$product)
{
return response()->json(['error' => 'Product not found'], 404);
}
// when saving the file, delete the old file first
if ($request->hasFile('image')) {
$file = $request->file('image');
$original_filename = $file->getClientOriginalName();
// $mime = $file->getMimeType(); // Suggestion
$extention = $file->getExtension();
// $size = $file->getClientSize(); // Suggestion
$stored_filename = $original_filename; // md5($original_filename); // Suggestion
$file_path = storage_path('public/img/products/');
if (Storage::disk('local')
->exists("public/img/products/{$stored_filename}.{$extention}"))
{
Storage::disk('local')
->delete("public/img/products/{$recordSet->stored_filename}.{$extention}");
}
$file_moved = $file->move($file_path, "{$stored_filename}.{$extention}");
$data->image = "{$stored_filename}.{$extention}";
}
// Updating data
$result = $product->update($data);
if ($result) {
/* return redirect()
->route('products.index')
->withSuccess('Product was successfully updated'); */
return response()->json([
'message' => 'Product was successfully updated'
'product' => $product
]); // You don't have to put 200 because it's the default
}
/* return back()
->withErrors(['Unable to update the product'])
->withInput($request->input()); */
return response()->json(['error' => 'Unable to update the product'], 400);
}
It would be better if you create a form request to do your validations.
Don't forget to create links to the storage path:
php artisan storage:link
I think it would be helpful:
$("#btn-edit").click(function() {
var formData = new FormData($("#frmAddProduct")[0]);
formData.append('_method', 'put');
formData.append('_token', "{{ csrf_token() }}"); // if you are using Blade
var route= "{{ route('products.update', ['id' => ':id']) }}"; // if you are using Blade
route= route.replace(':id', $("#frmEditProduct input[name=product_id]").val())
$.ajax({
method: 'post',
url: route,
data: formData,
dataType: 'json',
success: function(data) {
$('#frmEditProduct').trigger("reset");
$("#frmEditProduct .close").click();
window.location.reload();
},
error: function(data) {
var errors = $.parseJSON(data.responseText);
$('#edit-product-errors').html('');
$.each(errors.messages, function(key, value) {
$('#edit-product-errors').append('<li>' + value + '</li>');
});
$("#edit-error-bag").show();
}
});
});
Is your js script in "Blade" ? If so, try it this way:
var image = '{{ asset("/img/products/_image_file") }}'
image.replace('_image_file', data.products.image)
$("#frmEditProduct file[name=image]").val(image)
Note that we can first use the "asset ()" helper to create the full path to use to find the image, but with a "_image_file" placeholder
After that, we use the replace () function to change the "_image_file" placeholder with the actual image file brought from the ajax response.
Something like this?
ProductController.php
public function update(Request $request, $id)
{
$validator = Validator::make($request->input(), array(
'name' => 'required',
'category_id' => 'required',
'description' => 'required',
'price_neto' => 'required',
'iva' => 'required',
'price_total' => 'required',
'image' => '',
));
if ($validator->fails()) {
return response()->json([
'error' => true,
'messages' => $validator->errors(),
], 422);
}
$products = Product::find($id);
if ($request->hasFile('image')) {
$productImage = $request->file('image');
$productImageName = rand() . '.' . $productImage->getClientOriginalExtension();
if (Storage::disk('local')->exists("img/products/{$productImageName}")) {
Storage::disk('local')->delete("img/products/{$recordSet->$productImageName}");
}
$file_moved = $productImage->move(public_path('img/products'), $productImageName);
$data->image = "{$productImageName}";
}
$products->save([
'name' => $request->name,
'category_id' => $request->category_id,
'description' => $request->description,
'price_neto' => $request->price_neto,
'iva' => $request->iva,
'price_total' => $request->price_total,
'image' => $productImageName,
]);
return response()->json([
'error' => false,
'products' => $products,
]);
}
Product.js
$("#btn-edit").click(function() {
var formData = new FormData($("#frmEditProduct")[0]);
formData.append('_method', 'put');
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
type: 'POST',
url: '/product/' + $("#frmEditProduct input[name=product_id]").val(),
data: formData,
dataType: 'json',
success: function(data) {
$('#frmEditProduct').trigger("reset");
$("#frmEditProduct .close").click();
window.location.reload();
},
error: function(data) {
var errors = $.parseJSON(data.responseText);
$('#edit-product-errors').html('');
$.each(errors.messages, function(key, value) {
$('#edit-product-errors').append('<li>' + value + '</li>');
});
$("#edit-error-bag").show();
}
});
});
I am trying to build a small program on a webpage that shows a drop-down list input type with the makes of cars (Ford and BMW in this case). Once a selection is made, the user clicks the submit button and below the form, a list of models specific to the make will appear in the results div.
I was provided with 4 files:
index.php:
<form id="form">
<label for="make">
Make
<select name="make" id="make">
<option value="" selected="selected">None</option>
<option value="Ford">Ford</option>
<option value="BMW">BMW</option>
</select>
</label>
<input name="submit" value="submit" type="submit" id="submit">
</form>
<div id="results">
</div>
<script src="js/main.js"></script>
data.php:
<? php
function data() {
$data = array(
array(
'make' => 'Ford',
'model' => 'Fiesta'
),
array(
'make' => 'Ford',
'model' => 'Focus'
),
array(
'make' => 'Ford',
'model' => 'Mustang'
),
array(
'make' => 'BMW',
'model' => '320'
),
array(
'make' => 'BMW',
'model' => 'X3'
),
array(
'make' => 'BMW',
'model' => 'X5'
),
);
}
ajax.php:
<?php
require_once( 'data.php' );
$data = data();
$json_data = array();
And main.js:
$(document).ready(() => {
var run_ajax = function() {
results = $('#results');
$.ajax({
type: 'post',
url: 'ajax.php',
data: formData,
dataType: 'json',
beforeSend: function() {
},
success: function(response) {
},
});
}
$('#submit').on('submit', function(e) {
e.preventDefault();
run_ajax();
});
});
How do I access the data in data.php from main.js? I'd appreciate a thorough explanation of possible. Thank you in advance.
Every thing is done seeing your provided code you have to just connect them but first you need to change the data.php file to the following
<?php
function data() {
return array(
array(
'make' => 'Ford',
'model' => 'Fiesta'
),
array(
'make' => 'Ford',
'model' => 'Focus'
),
array(
'make' => 'Ford',
'model' => 'Mustang'
),
array(
'make' => 'BMW',
'model' => '320'
),
array(
'make' => 'BMW',
'model' => 'X3'
),
array(
'make' => 'BMW',
'model' => 'X5'
),
);}
then your ajax.php file to the following
<?php
require_once( 'data.php' );
$data = data();
$make = $_POST['make'];
// print_r($data);exit;
foreach($data as $car){
if(in_array($make,$car)){
$filtered[]=$car;
}
}
echo json_encode($filtered);
then change your main.js function to the following
$(document).ready(() => {
var run_ajax = function () {
results = $('#results');
$.ajax({
type: 'post',
url: 'ajax.php',
data: $("form").serialize(),
dataType: 'json',
beforeSend: function () {},
success: function (response) {
for (var key in
response) {
$("#results").append(" <div > Make: " + response[key]['make'] +
", Model:" + response[key]['model'] + " </div>");
}
},
});
}
$('#form').on('submit', function (e) {
e.preventDefault();
run_ajax();
});
});
hope that sorts out
EDIT
Actually, we have to send the select dropdown's selected make and filter out the cars with the same make to be responsed back and shown in the lower div have to change a few more things inside the ajax.php file
Your data() function must first return an array:
function data(){
$data = array('key'=>'value');
return $data;
}
Then echo or print() the json_encoded array:
$data = data();
echo json_encode($data);
Firstly your you dont need to define a function in your data.php file, since it is included in the ajax.php file, any variable there would be accessible
data.php:
<? php
$data = array(
array(
'make' => 'Ford',
'model' => 'Fiesta'
),
array(
'make' => 'Ford',
'model' => 'Focus'
),
array(
'make' => 'Ford',
'model' => 'Mustang'
),
array(
'make' => 'BMW',
'model' => '320'
),
array(
'make' => 'BMW',
'model' => 'X3'
),
array(
'make' => 'BMW',
'model' => 'X5'
),
);
the ajax.php file reads the data from data.php file filters the array and put the models of the selected make into a new array and echo as json string
ajax.php:
<?php
require_once('data.php');
$filtered_make = [];
$make = $_POST['make'];
foreach ($data as $car) {
if (strtolower($make) == strtolower($car['make'])) $filtered_make[] = $car['model'];
}
echo json_encode($filtered_make);
index.php:
<form id="form">
<label for="make">
Make
<select name="make" id="make">
<option value="" selected="selected">None</option>
<option value="Ford">Ford</option>
<option value="BMW">BMW</option>
</select>
</label>
<input name="submit" value="submit" type="submit" id="submit">
</form>
<div id="results">
</div>
<script src="http://www.izivote.com/res/js/jquery.min.js"></script>
<script src="js/main.js"></script>
onsuccess, in the main.js file, the returned list of models in the json object from ajax.php is put in a list and displayed in the result container
main.js:
$(document).ready(() => {
var run_ajax = function() {
results = $('#results');
var formData = $('#form').serialize();
$.ajax({
type: 'post',
url: 'ajax.php',
data: formData,
dataType: 'json',
beforeSend: function() {
},
success: function(response) {
var resultHTML = "<ul>";
for(var index in response){
resultHTML += "<li>" + response[index] + "</li>";
}
resultHTML += "</ul>";
results.html(resultHTML);
},
});
}
$('#form').on('submit', function(e) {
e.preventDefault();
run_ajax();
});
});
I hope this helps
return the data() as an array.
then encode the $data to json.
<?php
require_once( 'data.php' );
$data = data();
$json_data = json_encode(array());
and ajax:
$.ajax({
type: 'post',
url: 'ajax.php',
data: formData,
dataType: 'json',
beforeSend: function() {
},
success: function( response ) {
console.log(response); // check the return result
$.each(response, function(key, val){
$("#results").append("<div>Make:"+key+" , Model:"+val+"</div>");
});
},
error: function (msg) {
alert("Error: check console");
console.log(msg);
}
});
not tested but hope it helps
By using kartik select2 plugins in Yii2, I try to make dependence dropdown for country and states.
Form field for country and states:
$url = yii\helpers\Url::toRoute('op-client/lists');
$this->registerJs($this->render('script.js'), \yii\web\VIEW::POS_READY);
$form->field($model, 'country_id')->widget(Select2::classname(), [
'data' => $countryData,
'language' => 'en',
'options' => ['placeholder' => 'Select'],
'pluginOptions' => [
'allowClear' => true,
],
'pluginEvents' =>
[
'change' => 'function()
{
getstate
(
$("#select2-opclient-country_id-container").val(),
"'.$url.'"
)
}',
],
]).'
$form->field($model, 'states_id')->widget(Select2::classname(), [
'data' => $statesData,
'language' => 'en',
'options' => ['placeholder' => 'Select'],
'pluginOptions' => [
'allowClear' => true,
],
]).'
Script.js
function getstate($countryid,url)
{
//console.log(startdate + enddate);
var csrfToken = $('meta[name="csrf-token"]').attr("content");
$.ajax({
type:"POST",
cache:false,
url:url,
data:{countryid:countryid, _crsf:csrfToken},
success:function(data){
$("#select2-opclient-states_id-container").val(data);
},
})
}
Controller:
public function actionLists()
{
$request = Yii::$app->request;
$country = $request->post('countryid');
$countStates = OpStates::find()
->where(['country_id' => $country])
->count();
$states = OpStates::find()
->where(['country_id' =>$country])
->all();
if($countStates > 0)
{
foreach($states as $state){
echo "<option value='".$state->id."'>".$state->state_name."</option>";
}
}
else
{
echo "<option></option>";
}
}
When I run the program, it show error "Uncaught ReferenceError: countryid is not defined".
But I thought i passed the countryid into it already? Where have I done wrong?
Any help/advice will be appreciated. Thankss
Please check below code,i think you did little mistake in country_id variable name.
public function actionLists()
{
$request = Yii::$app->request;
$country = $request->post('country_id');
$countStates = OpStates::find()
->where(['country_id' => $country])
->count();
$states = OpStates::find()
->where(['country_id' =>$country])
->all();
if($countStates > 0)
{
foreach($states as $state){
echo "<option value='".$state->id."'>".$state->state_name."</option>";
}
}
else
{
echo "<option></option>";
}
}
and here
function getstate(countryid,url)
{
//console.log(startdate + enddate);
var csrfToken = $('meta[name="csrf-token"]').attr("content");
$.ajax({
type:"POST",
cache:false,
url:url,
data:{countryid:countryid, _crsf:csrfToken},
success:function(data){
$("#select2-opclient-states_id-container").val(data);
},
})
}
It will solve your issue.
I have a simple ajax call:
function init() {
$.ajax({
url: "./myFolder/user.php",
data: {
action: "init"
},
type: "post",
success: function (output) {
console.log("Success");
console.log("Output: " + output);
}
});
}
The PHP init method gets called and simply should return some json data:
function init() {
$arr = array(
array(
"region" => "valore",
"price" => "valore2"
),
array(
"region" => "valore",
"price" => "valore2"
),
array(
"region" => "valore",
"price" => "valore2"
)
);
return json_encode($arr);
}
but my console says:
Success
Output:
So the output variable is empty. Where is my json data?
On user.php page you need to do :-
function init() {
$arr = array(
array(
"region" => "valore",
"price" => "valore2"
),
array(
"region" => "valore",
"price" => "valore2"
),
array(
"region" => "valore",
"price" => "valore2"
)
);
echo json_encode($arr);
}
u should have in your user.php somthing like this:
die(init());
I'm adding the feature like in Solgema Fullcalendar - http://plone.org/products/solgema.fullcalendar/releases/2.1.2
(selecting and showing events with checkboxes selection)
My eventSourses look like:
eventSources: [
...
{
url: '/admin_schedule/get_schedule_db_recurring_events_on_daysweek/',//"<?echo $data_path?>",
type: 'GET',
data: {sch_teacher_id: sch_teacher_id},
backgroundColor: 'red',
}
],
And I want implement checkboxes for "filtering" events by teachers, checked in checkboxes. For beginning make just one checkbox (later make foreach cover)
<div class="box">
<?php
$js = 'onClick="rerender_schedule()"';
echo form_checkbox('teacher', 'vika', FALSE, $js)." Vika";
?>
</div>
By this code as I think, fullcalendar must call rerender_schedule() function which filters data from eventSource with vika's sch_teacher_id
If somebody could help with rerender_schedule() function, I will be thankful, because not good in ajax.
EDIT: (thanks to tocallaghan!). It's just a beginning right now.
My 3 checkboxes:
$data = array(
'name' => 'teacher',
'class' => 'teacher',
'id' => 'teacher',
'value' => '128',
'checked' => FALSE,
'style' => 'margin:10px',
);
echo form_checkbox($data); echo "Вика";
$data = array(
'name' => 'teacher',
'class' => 'teacher',
'id' => 'teacher2',
'value' => '111',
'checked' => FALSE,
'style' => 'margin:10px',
);
echo form_checkbox($data); echo "Вася";
$data = array(
'name' => 'teacher',
'class' => 'teacher',
'id' => 'teacher3',
'value' => '1',
'checked' => FALSE,
'style' => 'margin:10px',
);
echo form_checkbox($data); echo "Саша";
ajax on change them:
$('.teacher').change(function (event) {
events1.data.sch_teacher_id = $(this).val();
events2.data.sch_teacher_id = $(this).val();
events3.data.sch_teacher_id = $(this).val();
$calendar.fullCalendar('refetchEvents');
});
vars for eventSourses:
var events1 = {
url: 'url1',
type: 'GET',
data: {sch_teacher_id: $('#teacher').val() },
success: function (response) {
return response;
}
};
var events2 = {
url: 'url2',
type: 'GET',
data: {sch_teacher_id: $('#teacher').val() },
backgroundColor: 'green',
success: function (response) {
return response;
}
};
var events3 = {
url: 'url3',
type: 'GET',
data: { sch_teacher_id: $('#teacher').val() },
backgroundColor: 'red',
success: function (response) {
return response;
}
};
my eventSources call
eventSources: [
events1,
events2,
events3
],
You need refetchEvents , but be careful to update you data parameter before calling (otherwise it will remain the initially set value)
$('.CheckBoxClass').change(function () {
events.data.sch_teacher_id = $(this).val();
$('#calendar').fullCalendar('refetchEvents');
});
Edit: code to declare events object:
var events = {
url: 'url',
type: 'GET',
data: { Id: $('#divId').val() },
success: function (response) {
return response;
}
};
$('#calendar').fullCalendar({
events: events
});