x-editable submit additional "array" to the total AJax POST data - javascript

I'm trying to add an array of object to the post data of a group of bootstrap x-editable in my jsp page.
I recover the data from a table, and build an array of object. After do that, I need to append this array to the list of the other value posted by the editables in the page.
I've an html table with id="user" and this code recover data from it and build the array of object. This is my code, that works and produces the correct object:
function recover_data() {
console.log("Starting recover");
var beneficiary_list = [];
$('.lav').each(function() {
var obj = {'company': $(this).attr('id'), 'num':$(this).text() };
beneficiary_list.push(obj)
});
console.log(beneficiary_list); //output to check array produced
return beneficiary_list;
};
this function is what I call from a save button, that launch my global submit retrieving data from all editable in the page and adding in the "params" the array returned from recover_data(), in this way:
jQuery('#data a').editable('submit',{
url:'test/prove/data_received',
params: function(params) {
params.beneficiary = recover_data();
return params;
},
success:function(resp){ ... }
})
but testing with Postman (Chrome) the produced output to POST, is without the array. Are submitted only the "editables" data, but no "beneficiary" field with array of that values adding. The missing field must be like
"beneficiary": [0: company: "1", num: "22" ..etc..]
How can I "append" to the produced POST data from a group of editables an array of objects, like that I've show?
Looking to this page is possible
Question on github x-editable page
I don't understand why don't works...I follow the example written on second post from vitalets, he wrote:
editable({
...
params: function(params) {
params.checked = ... //get array of checked values
return params;
}
});
To Explain better what I need: I've a Java Controller (servlet) that receive a modelView object (POJO) with several fields (that came from other editables in the page) and a field "ArrayList beneficiary" where Beneficiary is a small object of two fields "company" and "num"
public Class Beneficiary{
private String company;
private String num;
//then get e set methods..
}
instead, my POJO is like:
import java.util.ArrayList;
import Beneficiary;
public class Module {
private Integer id;
private String titolo;
private String companyRating;
private ArrayList<Beneficiary> beneficiary;
//get e set methods
In the console I obtain the correct object for that voice
but not in the post object that is like
instead I need that the produced output "beneficiaries" field to POST url is something similar to this example (found on internet)
How can I obtain a list of that object from my JSP page when submit?
Someone can help me?

params is an option for editable object, while you are using it as options for ajax call.
Your code should look like:
$('#data a').editable({
url: "/post"
});
and then the submit() (note selector for all of your editable objects):
$('.editable').editable('submit', {
data: {beneficiary: recover_data()},
success:function(resp){ ... }
});
Working fiddle. Check your console to see logs

Related

how to read correctly a complex object sent to the back-end

EDIT:
after some tips i edited my code and now i created an object witch contains all my datas as i intended to have it, so now i have an object composed of an int and an array of another object that has an array on the inside
here is the code of the objects:
export class tempfp{
mesi: fp[] = []
id:number=0;}
export class fp{
arr:number[]=new Array();}
this is what i do before to send the data to my backend
(note that the object data has an any type and the object send is a tempfp)
async onSubmit() {
console.log("start: \n"+JSON.stringify(this.data))
for (let i = 0; i < this.data.length; i++) {
let m = new fp();
Object.assign(m.arr, JSON.stringify(this.data[i]));
this.send.mesi[i] = m;
}
this.send.id=this.id;
this.efp.postarray(this.send)//i even tried to put in this function this.data instead of this.send
}}
in my back-end i have the same objects, but when i send the datas using an http post it does not read it correctly indeed when i try to manipulate the datas from the back-end i get error 500 in my browser, and if i try to print this thing in my back-end it looks empty
A post request can have only one body and you're already passing a body, what you need to do is create a model in java that represent the body you want to pass and then pass it from the front end.
//I like to use lombok's #Data annotation to generate getters setters
//and default constructor but you can also write them by hand
#Data
public class MyBody {
private String eff;
private int id;
}
then in your controller you will accept ad body an instance of this model.
#PostMapping("takearrfp")
public void takearr(#RequestBody MyBody body) {
String eff = body.getEff();
int id = body.getId(); //And then do what you want whit this
efps.readAndSave(eff);
}
At this point the only thing remaining to do is passing this model as a body, so you will need to pass as body of the post request an object with the same fields
{
eff: put something here,
id: put the id here
}
What you have to do is simple. As the other answer also said you can only pass only one body at a time. so if you want to include the id then you have to put it into the body. Just try the below code
const body = {
id: id,
arr: arr
}
const obj = JSON.stringify(body)
Then you can read those data from the back end by using the suggested approach from Fabrizio's answer.

ViewModel current state to JSON

I have an issue with aps.net mvc project. I have a view where is set list of check boxes inside of begin form, then on submit appropriate fields are shown as a report. So I have to add a button to my view, where user is setting which fields he d like to see, so as he could save all checkbox values as a preset with its name.
I have model with a lot of nested models it looks like this:
public class EmployeeOverallReport
{
public List<PersonalData> ListOfPersonalData { get; set; }
public EmployeeOverallReportBool ColumnsNeeded { get; set; }
public EmployeeOverallReportFilters ModelFilters { get; set; }
}
I actually need ColumnsNeeded model, which has alot of bool properties for storing each checkbox value (true/false).
So on click I have to get current state of checkboxes and make a post with these model values.
I have been trying to serialize my form:
var data = $('#myForm').serialize();
$.post(url, { presetName: Name, entry: data}, function (data) {
$("#saveResult").html("Saglabats");
});
I got JSON string but it was invalid and i could not deserialize it back.
Here is what I am trying to do now:
$("#savePresetButton").on('click', function () {
var url = "/Reports/SavePreset";
var data = #Html.Raw(Json.Encode(Model));
$.post(url, { presetName: Name, entry: data}, function (data) {
$("#saveResult").html("Saglabats");
});
});
this code is using my viewModel with its properties, where all ColumnsNeeded properies are set to false, as it is by default and all user side changes in a view are not set to model yet, so as my form was not submitted and values were not changed.
How could I get current state of all checkboxes on user side?
Not doing it like :
var dataset = {
CategoryBool: $("#ColumnsNeeded_CategoryBool").val(),
NameBool: $("#ColumnsNeeded_NameBool").val(),
KnowledgeLevelBool: $("#ColumnsNeeded_KnowledgeLevelBool").val(),
SkillAdditionalInfoBool: $("#ColumnsNeeded_SkillAdditionalInfoBool").val(),
...
}
because I have more than 90 properties there..
I am sorry for this post, but posting some code is impossible due to count of properties inside the model.
Could you serialize the entire form and ajax submit the form itself?
see: Pass entire form as data in jQuery Ajax function

get JSON object javascript

I have the Student.groovy class that hasMany Note.groovy
Student Class extend to User.groovy
I have a JavaScript function that takes as a parameter a list of notes in JSON.
The code below works.
$.each(data,function(key, value) {
alert(value.note);
alert(value.semester)
});
But if I do alert(value.student); me is returned [object, object]
and when I put alert(value.student.toSource()); It's shown ({class: "project.Student", id: 1})
If I do alert(value.student.name); It's shown undefined
You're most likely not sending back the correct JSON format to access the student's name.
As of now with the examples you have given you can only access the class and id of a given student.
value.student.class //<-- project.student
value.student.id //<-- 1
To be able to access the student's name you would have to have an object like so:
{
class: "project.Student",
id: 1,
name: "Example name"
}
If you think you are actually sending everything you need from the server just do a little $(document.body).append(data); or console.log(data); on your getJSON success callback so you can see clearly what you have.
I wouldn't be surpized if value.name works by the way. Depends on your json structure.

JQuery Autocomplete GET & JSON array data security concerns

I am learning JQuery with a MVC3 book. I find that Json data is really easy to use, but it may not be safe.
Consider the scenario, say, I got a CRM with senstive customer infomation. Ajax returns Json array as search results. The search textbox ajax autocomplete also return Json array of senstive keywords from database. etc...They all use GET method.
However, it is said that GET method has vulnerabilities when passing around Json array data:
http://haacked.com/archive/2009/06/25/json-hijacking.aspx
http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx
How do you JQuery experts out there go about fixing this issue? Please help.
--- EDIT: ---
#Gren. Awesome. Thank you. Based on your tips, here is what I figured out.
The normal autocomplete returning json array
and a mod one with a json object wrapping the array
Here is the code, assuming we got a global List named txtlst in the controller.cs...
// normal one
public JsonResult AutoCompleteHelper1(string term) {
//if (!Request.IsAjaxRequest()) return null;
var lst = txtlst.Where(s => s.StartsWith(term)).ToList();
var res = lst.Select(x => new { value = x }).ToList();
return Json(res, JsonRequestBehavior.AllowGet);
}
//mod one
public JsonResult AutoCompleteHelper2(string term) {
//if (!Request.IsAjaxRequest()) return null;
var lst = txtlst.Where(s => s.StartsWith(term)).ToList();
var res = lst.Select(x => new { value = x }).ToList();
return Json(new { wrapper= res, name="wrapper" }, JsonRequestBehavior.AllowGet);
}
}
and then in the .cshtml file...
<p>Auto Complete Example</p>
<input type="text" name="q" id="MyInput1" data-autocomplete-source="#Url.Action("AutoCompleteHelper1", "Home")"/>
<input type="text" name="q" id="MyInput2" data-autocomplete-source="#Url.Action("AutoCompleteHelper2", "Home")" />
and then in the .js file...
$(document).ready(function () {
// normal autocomplete
$("#MyInput1").autocomplete({ source: $("#MyInput1").attr("data-autocomplete-source") });
// mod autocomplete with a wrap
$("#MyInput2").autocomplete({
source: function (req, add) {
$.getJSON($("#MyInput2").attr("data-autocomplete-source"), req, function (data) {
var suggestions = [];
$.each(data.wrapper, function (i, o) {
suggestions.push(o.value);
});
add(suggestions);
});
}
});
});
--- EDIT 2: ---
Please ignore those comments that are telling me to use POST. They
are not reading the blog links or do not understand the issue.
The other option is to wrap your JSON Arrays within JSON objects. The article and comments in it answered this question.
Edit:
From the article:
The fact that this is a JSON array is important. It turns out that a script that contains a JSON array is a valid JavaScript script and can thus be executed. A script that just contains a JSON object is not a valid JavaScript file.
If you wrap your json array in an object {"myJsonArray":[{"name":"sensitive"},{"name":"data"}]} the HTML script tag would not be able to execute.
Security of an Ajax/JSONP/JSON call is the same exact thing as the security of an http call since Ajax requests are http requests. Nothing changes in how you handle it. You make sure the user is logged in and can access the information.
If you are worried about data being cached, use Post or set the proper no caching headers with the backend.
EDIT:
Things you can do to prevent JOSN from being read is the infinite loop trick. Stick an infinte loop in front of the call, means your Ajax call will have to strip this before using it.
You can use keys, third party site would not have the keys needed to validate the request.
You can check referrers.

Data Filter - View User Interface

I have an Asp.Net MVC web app that I need to provide a user interface in the view to apply data filters to display a subset of the data.
I like the design of what is used on fogbugz with a popup treeview that allows for the selection of data filters in a very concise manner: http://bugs.movabletype.org/help/topics/basics/Filters.html
My controller's action method has some nullable parameter's for all of the available filters:
public ActionResult EmployeeList(int? empId, int? month, int? year,
string tag1, string tag2 //and others....)
{
//...filter employee list on any existing parameters
return View(viewModel);
}
My intention was whenever a filter was applied by clicking on a link, entering text...that filter would be added to the parameter list and reload the page with the correct data to display.
Looking for some guidance or examples on how to create a filter toolbar or best practices for this type of problem. I haven't been able to find a jquery ui plugin or javascript library to do something similar to this so a little lost on where to start.
Thanks.
I did something similar to this by having a main page containing a number of dropdowns containing the parameter options, then a div that had the resultant set ViewUserControl loaded into it on both page load and on dropdown selection change. The controller for the data, in this case TaskList, just needs to return a normal ActionResult View(newTaskList(data)); Example below.
<script>
$(document).ready(function () {
loadDataSet();
});
function loadDataSet(){
var status = document.getElementById('ddlStatus');
var selectedStatus = status.options[status.selectedIndex].value;
if (status.selectedIndex == 0) selectedStatus = '';
$.post('<%= Url.Action("TaskList") %>', { status: selectedStatus },
function (data) {
$('#divTaskList').html(data);
});
}
</script>
<%= Html.DropDownList("ddlStatus", Model.StatusOptions, null, new { onchange = "javascript:loadDataSet();" })%>
<div id='divTaskList' />

Categories

Resources