Symfony form & Ajax - html

I am working on Symfony 4.4.
To refresh a table, users select three options with an input:
InProgress
Finished
All
Then they must press a validate button.
I want to improve the use of this page by automating the refresh of the table.
Currently on my model I have AJX which allows me to retrieve the value of my entry:
<script>
$(document).on('change', '#campagnes_tel_isAttending', function () {
$('#flash').remove();
let $field = $(this)
let $preselect = $('#campagnes_tel_isAttending')
let $form = $field.closest('form')
let data = {}
data[$field.attr('name')] = $field.val()
console.log(data)
// On soumet les données
// $.post($form.attr('action'), data).then(function (data) {
// // On récupère le nouveau <select>
// $('#planningsms_client_label').val($(data).find('#planningsms_client option:selected').text());
// let $input = $(data).find(target)
// // On remplace notre <select> actuel
// $(target).replaceWith($input)
// })
});
</script>
I am now stuck because I cannot figure out how to get information back to my Controller, allowing me to modify a PreSelect variable with the value of the input and change the structure of the SQL query.
Create a route? Call a route in an Ajax POST?
Use this route in my Controller?
I think it's more or less that, but on the other hand I have no idea how to implement it.
EDIT :
It has moved forward a bit.
I manage to recover the data of the change of the input in my controller.
On the other hand I try to recall the function which will allow me to make a new SQL query with the selected filter, but that does not seem to work.
Ajax :
<script>
$(document).on('change', '#campagnes_tel_isAttending', function () {
$('#flash').remove();
let $field = $(this)
let $preselect = $('#campagnes_tel_isAttending')
let $form = $field.closest('form')
let data = {}
data['isAttending'] = $field.val()
console.log(data)
$.ajax({
type: "POST",
url: "/campagnestel/ajax",
data: data,
dataType: "json",
success: function(response) {
console.log(response);
}
});
});
</script>
And function in my controller :
/**
* #Route("/ajax", methods={"GET", "POST"})
*/
public function testAjax(Request $request)
{
if (!$request->isXmlHttpRequest()) {
return new JsonResponse(array(
'status' => 'Error',
'message' => 'Error'),
400);
}
if(isset($request->request)) {
$preSelect = $request->request->get('isAttending');
return $this->queryFollowingFilter($preSelect);
}
// return $this->queryFollowingFilter($preSelect);
return new JsonResponse(array(
'status' => 'OK'),
200);
}
Error :
The controller must return a "Symfony\Component\HttpFoundation\Response" object but it returned an array

As the error message states:
The controller must return a "Symfony\Component\HttpFoundation\Response" object
A JsonResponse meets that requirement and suits your needs. Try this:
if($request->request->has('isAttending')) {
$preSelect = $request->request->get('isAttending');
return new JsonResponse(
$this->queryFollowingFilter($preSelect),
200
);
}

Related

How to get data from html form?

What is the most modern way to get data from an html form and email it to yourself?
One way could be to have a JQuery .sumbit() event handler on your submit button which would gather all the info from the form and send them to a backed controller which would actually send the email.
JQuery example:
$('form').submit(function(event) {
// get the form data
var formData = {
'name' : $('input[name=name]').val(),
'email' : $('input[name=email]').val(),
'phone' : $('input[name=phone]').val()
};
// process the form
$.ajax({
type : 'POST',
url : 'process.php',
data : formData,
dataType : 'json',
encode: true
})
// using the done promise callback
.done(function(data) {
// log data to the console so we can see
console.log(data);
});
event.preventDefault();
});
The server side could look something like:
<?php
// process.php
$errors = array();
$data = array();
// Validation
if (empty($_POST['name']))
$errors['name'] = 'Name is required.';
if (empty($_POST['email']))
$errors['email'] = 'Email is required.';
if (empty($_POST['phone']))
$errors['phone'] = 'phone is required.';
if ( ! empty($errors)) {
$data['success'] = false;
$data['errors'] = $errors;
} else {
// Send email here
$data['success'] = true;
$data['message'] = 'Success!'
}
?>
In this way you would decouple client side logic (gather form data) and backend logic (send the email).

Login Service implementation in angularjs not working

This is my controller which is calling the login service
mod.controller("loginCtrl",function($scope,loginService,$http)
{
$scope.Userlogin = function()
{
var User = {
userid :$scope.uname,
pass:$scope.pass
};
var res = UserloginService(User);
console.log(res);
alert("login_succ");
}
});
And this is the login service code which takes the User variable and checks for username & password
mod.service("loginService",function($http,$q) {
UserloginService = function(User) {
var deffered = $q.defer();
$http({
method:'POST',
url:'http://localhost:8080/WebApplication4_1/login.htm',
data:User
}).then(function(data) {
deffered.resolve(data);
}).error(function(status) {
deffered.reject({
status:status
});
});
return deffered.promise;
// var response = $http({
//
// method:"post",
// url:"http://localhost:8080/WebApplication4_1/login.htm",
// data:JSON.stringify(User),
// dataType:"json"
// });
// return "Name";
}
});
I have created a rest api using springs which upon passing json return back the username and password in json like this
Console shows me this error for angular
You need to enable CORS for your application for guidance see this link
https://htet101.wordpress.com/2014/01/22/cors-with-angularjs-and-spring-rest/
I prefer to use Factory to do what you're trying to do, which would be something like this:
MyApp.factory('MyService', ["$http", function($http) {
var urlBase = "http://localhost:3000";
return {
getRecent: function(numberOfItems) {
return $http.get(urlBase+"/things/recent?limit="+numberOfItems);
},
getSomethingElse: function(url) {
return $http.get(urlBase+"/other/things")
},
search: function (searchTerms) {
return $http.get(urlBase+"/search?q="+searchTerms);
}
}
}]);
And then in your controller you can import MyService and then use it in this way:
MyService.getRecent(10).then(function(res) {
$scope.things = res.data;
});
This is a great way to handle it, because you're putting the .then in your controller and you are able to control the state of the UI during a loading state if you'd like, like this:
// initialize the loading var, set to false
$scope.loading = false;
// create a reuseable update function, and inside use a promise for the ajax call,
// which is running inside the `Factory`
$scope.updateList = function() {
$scope.loading = true;
MyService.getRecent(10).then(function(res) {
$scope.loading = false;
$scope.things = res.data;
});
};
$scope.updateList();
The error in the console shows two issues with your code:
CORS is not enabled in your api. To fix this you need to enable CORS using Access-Control-Allow-Origin header to your rest api.
Unhandled rejection error, as the way you are handling errors with '.error()' method is deprecated.
'Promise.error()' method is deprecated according to this and this commit in Angular js github repo.
Hence you need to change the way you are handling errors as shown below :
$http().then(successCallback, errorCallback);
function successCallback (res) {
return res;
}
function errorCallback (err) {
return err;
}
One more thing in your code which can be avoided is you have defined a new promise and resolving it using $q methods, which is not required. $http itself returns a promise by default, which you need not define again inside it to use it as a Promise. You can directly use $http.then().

Unable to send data in response to the view in nodejs

I am trying to create a simple web application which fires a http.request call, get the data and display it over to the html(ejs here). I am able to fire the request, get the data, massage it etc.. but unable to pass it to the view. Sample code is as below:
var searchData = [];
router.post('/',requesthandler);
function requesthandler(req,res){
var options = {
host: url,
port: 9999,
path: qstring,
method: 'GET'
};
var reqget = http.request(options,responsehandler);
reqget.end();
console.log('Rendering now:............................ ');
res.render('result',{title: 'Results Returned',searchdata : searchData});
}
function responsehandler(ress) {
console.log('STATUS: ' + ress.statusCode);
ress.on('data', function (chunk) {
output += chunk;
console.log('BODY: ' );
});
/* reqget.write(output); */
ress.on('end',parseresponse);
}
function parseresponse(){
var data = JSON.parse(output);
console.log(data.responseHeader);
// populate searchData here from data object
searchData.push({//some data});
}
function errorhandler(e) {
console.error(e);
}
module.exports = router;
Problem is I a unable to pass the objeect searchData to the view via res.render();
'Rendering now: ...........' gets executed before execution starts in parseresponse() and so the page is displayed without the data which seems to be in conjuction with using callbacks, So how can I pass the data object to the view once the searchData is loaded in parseresponse().
PS: I am able to print all console statements
define res variable globally:
var res;
function requesthandler(req,resObj){
res = resObj;//set it to the resObj
}
wrap res.render inside a function like this:
function renderPage(){
res.render('result',{title: 'Results Returned',searchdata : searchData});
}
then in parseresponse function do this:
function parseresponse(){
var data = JSON.parse(output);
searchData.push({some data});
renderPage();
}
Hope this solves your problem.

Pass dropbox value to a HttpGet action submit button click?

Basically I'm trying to pass the value of my dropbox to a get action.
The submit-button re-directs to the correct action , but what is the correct way to add the value of the dropbox with the re-direction?
My view:
#model TrackerModel
#using (Html.BeginForm("MyAction", "MyController", FormMethod.Get, new { ???}))
{
<div>
<strong>#Html.LabelFor(m => m.CustomerName)</strong>
#Html.TextBoxFor(m => m.CustomerName, new { type = "hidden", #class = "customer-picker" })
</div>
<button class="styledbutton" onclick="window.location.href='/Tracker/Index'">Cancel</button>
<button type="submit" value="submit" id="selectCustomer-button" class="styledbutton">Submit</button>
}
[HttpGet]
public ActionResult MyAction(IPrincipal user, Tracker model)
Customer-picker
$(document).ready(function () {
CustomerPicker();
});
function CustomerPicker() {
$('.customer-picker').select2({
placeholder: 'Select customer',
minimumInputLength: 1,
ajax: { // instead of writing the function to execute the request we use Select2's convenient helper
url: '/JsonData/GetCustomers',
type: 'POST',
dataType: 'json',
data: function (term) {
return {
query: term // search term
};
},
results: function (data) { // parse the results into the format expected by Select2.
// since we are using custom formatting functions we do not need to alter remote JSON data
return { results: data };
}
},
formatResult: function (data) {
return data;
},
formatSelection: function (data) {
return data;
}
});
}
I was expecting the value to be within my Tracker model parameter in the action, but this returns nulls. Also I'm not sure what to place in the "new" parameter in the form tag?
I also tried the following but all I get returning to the controller is text:"".
#Html.TextBoxFor(m => m.CustomerName, new { type = "hidden", #id = "selectedCustomer", #class = "customer-picker" })
<script type="text/javascript">
$(function () {
$("#Form1").submit(function (e) {
alert("boo");
e.preventDefault();
var selectCustValue = $("#selectedCustomer").val();
$.ajax({
url: '/CalibrationViewer/SentMultipleCalsToCustomer',
data: { text: selectCustValue }
});
});
});
OK got it,
var selectCustValue = $("#s2id_CustomerName span").text();
Found another piece of code the used the customer-picker and the javascript associated with view used the above.
I viewed the page source and it still show's both id and name as CustomerName, it has something to do with the "Select 2" helper.
I may get slated for marking this as the answer, considering I should have figured it out earlier, but there you have it !

viewbag data is empty in $.ajax

Iam using asp.net mvc4 and facing some problem in accessing viewbag.price.
This is what i am doing:-
[HttpPost]
public ActionResult FillModel(int id)
{
var vehModel = db.Vehicle_Model.Where(vehMod => vehMod.MakeID == id).ToList().Select(vehMod => new SelectListItem() { Text = vehMod.Model, Value = vehMod.pkfModelID.ToString() });
ViewBag.Price = 100;
return Json(vehModel, JsonRequestBehavior.AllowGet);
}
i am calling above using below:-
$.ajax({
url: '#Url.Action("FillModel","Waranty")',
type: 'post',
data: { id: id },
dataType: 'json',
success: function (data) {
$('#ddModel').empty();
$.each(data, function (index, val) {
var optionTag = $('<option></option>');
$(optionTag).val(val.Value).text(val.Text);
$('#ddModel').append(optionTag);
});
var a = '#ViewBag.Price';
},
error: function () {
alert('Error');
}
});
But i am not able to access ViewBag.Price.
Anyone know the reason??
thanks
The reason you aren't able to access items from the ViewBag inside your ajax success function is because the view that contains your script has already been rendered by the Razor view engine, effectively setting the variable a to whatever the value of #ViewBag.Price was at the time the page was rendered.
Looking at the process flow might be helpful:
(1) The request comes in for the view that has your script fragment in it.
(2) The controller method that returns your view is called.
(3) The Razor view engine goes through the view and replaces any references to #ViewBag.Price in your view with the actual value of ViewBag.Price. Assuming ViewBag.Price doesn't have a value yet, the success function in your script is now
success: function (data) {
$('#ddModel').empty();
$.each(data, function (index, val) {
var optionTag = $('<option></option>');
$(optionTag).val(val.Value).text(val.Text);
$('#ddModel').append(optionTag);
});
var a = '';
}
(4) The rendered html gets sent to the client
(5) Your ajax request gets triggered
(6) On success, a gets set to the empty string.
As you had mentioned in the comments of your question, the solution to this problem is to include a in the Json object returned by your action method, and access it using data.a in your script. The return line would look like
return Json(new {
model = vehModel,
a = Price
});
Keep in mind that if you do this, you'll have to access model data in your ajax success function with data.model.Field. Also, you shouldn't need to specify the JsonRequestBehavior.AllowGet option, since your method only responds to posts and your ajax request is a post.