Submit form on select change via AJAX - ajax

Let's say I have this form :
<form action="Change-status.php" method="post">
<select class="changeStatus" name="changeStatus">
<option value="0">Starting</option>
<option value="1">Ongoing</option>
<option value="2">Over</option>
</select>
<input class="projectId" type="hidden" name="projectId" value="<?php echo $data['id'];?>"/>
</form>
I am currently using this script to submit the form, but it implies refreshing :
$('select').change(function ()
{
$(this).closest('form').submit();
});
What I want to do is to send the form on select change without refreshing the page. I know I have to use AJAX to do so but I couldn't exactly figure out how to implement it.
Could you orient me on how to do this?
Thanks for your help.
EDIT :
After taking comments into consideration, I ended up with the following code :
Html :
<form action="" method="post">
<select class="changeStatus" name="changeStatus">
<option value="0">Starting</option>
<option value="1">Ongoing</option>
<option value="2">Over</option>
</select>
<input class="projectId" type="hidden" name="projectId" value="<?php echo $data['id'];?>"/>
</form>
JS :
$(document).ready(function() {
$('select.changeStatus').change(function(){
$.ajax({
type: 'POST',
url: 'Change-status.php',
data: {selectFieldValue: $('select.changeStatus').val(), projectId: $('input[name$="projectId"]').val()},
dataType: 'html'
});
});
});
PHP :
<?php
include('../Include/Connect.php');
$changeStatus=$_POST['selectFieldValue'];
$id=$_POST['projectId'];
$sql='UPDATE project SET progress="'.$changeStatus.'" WHERE id="'.$id.'"';
mysql_query($sql) or die("Erreur: ".mysql_error());
?>

Getting cross browser onchange events and AJAX requests working isn't trivial. I'm recommend you use a javascript framework of some kind, which abstracts away all of the cross browser issues so you don't have to worry about them.
Try a js framework
Jquery is just one such framework which has methods such as .change() which attaches a handler to the change event for elements like <select> and .get() which performs a GET request.
Here's a little bit of code to get you started:-
// The $ is the shorthand for a jquery function, you can then use jquery
// selectors which are essentially the same as css selectors, so here
// we select your select field and then bind a function to
// it's change event handler
$('select.changeStatus').change(function(){
// You can access the value of your select field using the .val() method
alert('Select field value has changed to' + $('select.changeStatus').val());
// You can perform an ajax request using the .ajax() method
$.ajax({
type: 'GET',
url: 'changeStatus.php', // This is the url that will be requested
// This is an object of values that will be passed as GET variables and
// available inside changeStatus.php as $_GET['selectFieldValue'] etc...
data: {selectFieldValue: $('select.changeStatus').val()},
// This is what to do once a successful request has been completed - if
// you want to do nothing then simply don't include it. But I suggest you
// add something so that your use knows the db has been updated
success: function(html){ Do something with the response },
dataType: 'html'
});
});
Some references that will be better than my explanations
Please note for this code to work you will need to include the jquery library on you page with a <script> tag.
See here for a quick start guide on using jquery
And here for a beginners tutorial on how to use jquery's ajax() method

Related

Dynamic dropdown in laravel 5.8

here's what i want to happened
- First dropdown (Parent)
- Second dropdown (Child)
- The options on the second dropdown will depend on the selected value of the first dropdown.
I am using laravel 5.8.
In Your view
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select class="form-control{{ $errors->has('state') ? ' is-invalid' : '' }}" onchange="dropdown(this.value);" name="state" id="state">
<option>--select state--</option>
<option value="Kerala">Kerala</option>
<option value="Karnataka">Karnataka</option>
<option value="Tamil Nadu">Tamil Nadu</option>
</select>
<select class="form-control{{ $errors->has('district') ? ' is-invalid' : '' }}" name="district" id="district">
<option>Please choose state from above dropdown</option>
</select>
<script >
function dropdown(msg){
var state=msg;
$.ajax({
url: 'getdistrict/'+state,
type: 'get',
dataType: 'json',
success: function(response){
$("#district").empty();
var len = 0;
if(response['data'] != null){
len = response['data'].length;
}
if(len > 0){
// Read data and create <option >
for(var i=0; i<len; i++){
var id = response['data'][i].id;
var name = response['data'][i].name;
var option = "<option value='"+name+"'>"+name+"</option>";
$("#district").append(option);
}
}
}
});
}
In your controller
public function district($id)
{
$userData['data'] = DB::table('alldistricts')
->where('state', $id)
->orderBy('name', 'asc')
->get();
echo json_encode($userData);
exit;
}
In your web.php
Route::get('/getdistrict/{id}','RegistrationController#district')->name('getdistrict');
To achieve this you must know front end script like Vue js or at least native javascript. I'll show how to achieve this using vue js and axios package and native js and ajax.
Vue js and axios:
Documentation:
1)https://vuejs.org (for vue js)
2)https://www.npmjs.com/package/axios (for axios package)
include this line in you header.
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>
Note: I used Vue js cdn for development mode. Make sure to change to production mode on live. Check the documentation for further.
Then add this in the form:
<form method='post' action="http://example.com/location" id="developers">
<select name="developer_type" v-on:change="getLanguages" v-model="developerType">
<option disabled> Select Developer Type </option>
<option value="front"> Front-End Developer </option>
<option value="back"> Back-End Developer </option>
<option value="full"> Full Stack Developer </option>
</select>
<select name="Coding_language">
<option disabled v-if="developerType!=null"> Select Developer Type First </option>
<option disabled v-else="developerType!=null"> Select Coding Language </option>
<option v-for="lang in codingLaguanges" value="lang"> #{{lang}} </option>
</select>
</form>
Note: use #{{}} if only you use Laravel blade as your template engine Otherwise use only {{}}
Then add this on footer script
let developerForm = new Vue({
el:'#developers',
data:{
developerType:null,
codingLanguages:null
},
methods:{
getLanguages: function () {
axios
.post('/developers/getLanguages',{
type: developerForm.developerType
})
.then(response => (
developerForm.codingLanguages = response.data.languages
));
}
}
});
Note:I have used v-on:change and v-model in select instead of using watcher ands-model because this concept will be easier if you are new to vue js, Otherwise use Watcher itself. Check Vue js Documentation. However Both will work in this case.
In .post give you correct url to get result.
then define your route
Route::post('/developers/getLanguages', ['as'=>'dev.getLang','uses'=>'web\DevController#getLanguages']);
Note this is laravel part. you ca see Documentation in https://laravel.com
then in your DevController add this method
public function getLanguages(Request $request){
//do something to fetch result from db. Let us consider user has selected backend as developer type and there is array named Languages and it contains elements named php, python and java. i.e. $languages = ['php','python','java'].
return response()->Json(['languages'=>$languages],200);
}
Note: This will be your method for Controller to know detailed about controller check laravel documentation mentioned in previous note. Here you can retrieve the variable value from db also. but I used only sample values. In return I used array in json because you can n number of variables in that array(For example you can use statusCode to identify your error in future and much more.). Then make sure the name of the key in json array and name of the object in axios while retrieving is same. And I used status code as 200 because the browser take response of the request is successful. if you use 400 browser take response of the request is error.
This is the easiest method you can achieve.
You can also use jquery ajax and jquery or native javascript and javascript ajax to achieve this. But it has some complexity and limitation.
If you need code for native js or jQuery comment it and I will post it

Thymeleaf + Spring how to pass to a controller a #PathVariable from a form select option value

I would like to use a select box to redirect to an URL containing the select value.
Here bellow the HTML page with thymeleaf variables :
<form th:action="#{/app/}">
<select id="app" name="app">
<option th:each="app : ${apps}"
th:value="${app.id}"
th:text ="${app.name}">
</option>
</select>
<button>Go</button>
</form>
The controller is written as following :
#RequestMapping("/app/{appId}")
public ModelAndView getApp(#PathVariable String appId){...}
My goal is to access the controller with the URL : mydomain/app/{app.id}/
I tried to use th:field onto the select without success. I'm missing something here.
Please, could you explain me how to add the select value to the URL expected by the controller ?
Thank you for the hints
EDIT following #NicolaiEhemann answer
I moved to javascript using jquery and ajax :
$('button').click(function() {
$.ajax({
url: '/app/' + $('#app').val(),
dataType: 'html'
}).done(function(data) {
$('#result').html(data)
});
});
Thank you.
Thymeleaf will only generate static html code. To achieve what you want, you have to write client side javascript to handle the 'input' event event to change the form action when a different value is selected, or handle the form 'submit' event to override the default action of the form submission. The relevant js code will probably be dependent on which framework you use.
Simply, add the path variable to the form action with double uderscores around
i.e. replace <form th:action="#{/app/}"> with <form th:action="#{/app/__${app.id}__">
source: http://forum.thymeleaf.org/Sending-pathvariable-to-controller-td4028739.html

form data moves through ajax on page load instead of on submit

I am sure there are things I haven't read out there, but every search I do just turns up purple links. My goal is to have a form that uses ajax in order to avoid page refresh and avoid submit on manual page refresh. I want to both upload a file and insert data into the database table. I actually have this part down. The problem is that the action is started on page load. I think this is because my ajax function uses #multiform).submit, but if I change that to #submit).submit then the ajax script doesn't send the data to upload.php and I just end up with a blank array being passed to upload.php.
I can make the upload work on click with a button instead of an input for the form submit. That's all without using formdata though. I need to use formdata to also upload the file. The below script does work. I just need it to work after clicking submit, and not automatically when the page loads.
As I'm learning, I'm thinking that formObj=$(this) is referring to the multiform and grabbing the objects, so when I change multiform to submit (this) doesn't work anymore. Is it possible that I just need to change that field somehow? I've been working on this non stop for weeks. I keep getting closer, but still not there. Please help me. Thank you.
my form:
<form name="multiform" id="multiform" action="upload.php" method="POST" enctype="multipart/form-data">
Name: <input type="text" name="dname" value="Ravi"/> <br/>
Age :<input type="text" name="age" value="1" /> <br/>
Image :<input type="file" name="photo" /><br/>
<input type="submit" id="submit" value="Ajax File Upload" />
</form>
my js:
jQuery(document).ready(function($) {
$("#multiform").submit(function(e)
{
var formObj = $(this);
var formURL = formObj.attr("action");
var formData = new FormData($(this)[0]);
$.ajax({
url: formURL,
type: 'POST',
data: formData,
mimeType:"multipart/form-data",
contentType: false,
cache: false,
processData:false,
success: function(data, textStatus, jqXHR)
{ alert(data)
},
error: function(jqXHR, textStatus, errorThrown)
{
}
});
e.preventDefault(); //Prevent Default action.
});
$("#multiform").submit(); //Submit the form
});
I figured this out by looking at it backwards. I googled how to make the form submit automatically on page load and found out that $(document).submit() makes a form submit on page load, so I took out $("#multiform").submit(); and now it works. An added note to anyone else who might find this and be working on something similar. For some reason, having an id of submit for input type submit causes the name and age variables to be ignored.

How to use the AJAX response in FLUID templates TYPO3 Extbase

I finally made my AJAX working in Extbase Typo3 6. However, I'm trying to use the returned array from AJAX in my FLUID view.
my Ajax action in Controller:
public function ajaxAction(){
$id = $this->request->getArgument['id'];
$record = $this->articleRepository->findByUid($id);
return json_encode(['record'=>$record,'status' => 'Loaded']);
}
My AJAX :
function dropCall(selectFieldObj) {
$.ajax({
type: 'POST',
url: link,
dataType: 'json',
success: function(data){
alert(data.status);
}
});
}
Now the question is how do I use the data object sent from the controller action in my View ? The alert is being displayed.
My List.html view
<script type="text/javascript">
var link
= '<f:uri.action action="ajax" controller="Article" pageType="99" arguments="{data:1}"/>';
</script>
<script type="text/javascript" src="fileadmin/myScript.js"></script>
<select id="drop" onchange="dropCall(this)">
<option value="1">Apple</option>
<option value="2">Mango</option>
<option value="3">Grape</option>
</select>
In my view, I should be able to do something like
<h1> {record.name} </h1>
EDIT
The object record might contain many properties and each record.property like record.name will be under <h1> tags and record.somethingelse can be under some under tag.
Just like we send objects from controller to view and use them in FLUID, I would want to do the same with AJAX

HTML form Ajax post on Success

As below, I am using a 'Form' and 'AJAX' to post the content of a text area to a URL within my site. I see the POST does work and posts the conetn to the server and on success I have tried to find the element on the page to append it, though it is not working.
Can you please advise?. The function success part of the call should be where I specificy the destination, though how do I append this data, put some ajax in the destination page html, on load etc?
<form id="test" onclick="submitForm();">{% csrf_token %}
<textarea id="red_content" name="content"></textarea>
<p>
<input type="submit" value="Publish" name="send">
</p>
</form>
function submitForm()
{
$.ajax({
url: "http://127.0.0.1:8000/Test/Trial",
data: $('#test'),
type: 'POST',
dataType: 'html',
success: function(data)
{
//$('.content-container5').setFocus();
$('.content-container5').html(data);
}
});
Many Thanks,
Tom
I'm not very familiar with submitting a single field via ajax (or in your case jQuery's ajax function). I did however have to do a similar function in a project I recently had.
I found this plugin:
jQuery Ajax Form Submit
It seemed to work really well. You may want to look into this for your project as well. In this case, instead of submitting your one field, the form will be submitted. This may be easier since you won't have to map the fields yourself. You can post the form to the same page and process it or post it to a given url.
Hope this helps.

Resources