You are getting pretty close. Yes, you definitely can use variables to make certain parts of the data that you send to SharePoint dynamic.
First. let me point out a couple errors I see in the way you have structured your first attempt there:
var typetest={"type":"SP."+TargetListName+"ListItem"};
var savetst={Title:"projname",ver:'test',modname:'browsertest'};
// i am assuming the above lines are not actually inside the
// ajax call, and you were just showing appreviated code
data: JSON.stringify({
__metadata :{typetest},savetxt
})
If we break down what you have inside the JSON.stringify() function, and "fill in" what you have defined in the variables, you get
JSON.stringify({
__metadata: {
{ "type": "SP."+TargetListName+"ListItem" } // notice you end up with double curly braces here
},
{ // and you end up with curly braces here, after the comma after "__metadata", instead of just straight key/value pairs
Title:"projname",
ver:'test',
modname:'browsertest'
}
})
Also, in the first example, for the metadata type you have
"SP.Data.ErrorHandlerListItem"
while in your "dynamic" version you have
"SP."+TargetListName+"ListItem"
which would really end up as "SP.ErrorHandlerListItem", which is missing that .Data. part, so you really want
"SP.Data." + TargetListName + "ListItem"
That all being said, the way I would make this easier to work with is to not put the data payload object inline with the JSON.stringify() function, but to make it it's own separate object in a variable, like this
var payload = {
__metadata :{
"type":"SP.Data.ErrorHandlerListItem"
},
Title:"TEST",
ver:'2.0',
modname:'no name'
};
$.ajax({
type: 'POST',
url: odataUrl,
contentType: "application/json;odata=verbose",
processData: false,
headers: {
"Accept": "application/json;odata=verbose",
"Content-Type":"application/json;odata=verbose",
"X-RequestDigest":$("#__REQUESTDIGEST").val(),
//"If-Match": "*",
//"X-HTTP-Method": "MERGE"
},
data: JSON.stringify(payload)
});
Then you can start to do things like
function getMetadataTypeValue (listName) {
// you can do more sophisticated stuff in here
// like deal with spaces in the list name
return "SP.Data." + listName + "ListItem";
}
var titleValue = "TEST"; // or some other way of dynamically generating this
var versionValue = "2.0"; // or dynamically determined
var modValue = "no name"; // etc
var payload = {
__metadata: {
"type": getMetadataTypeValue(dynamicTargetListName)
},
Title: titleValue,
ver: versionValue,
modname: modValue
}
Also, JavaScript is very forgiving, and you can add properties to an object dynamically just by defining it using dot notation on the fly. So you can start with:
var payload = {
__metadata: {
"type": "SP.Data." + listName + "ListItem" // assume listName = "ErrorHandler"
}
}
Now your original payload object is only
{ __metadata: {
"type": "SP.Data.ErrorHandlerListItem"
}
}
but then you can do something like
var needToAddTitle = true;
var titleValue = "Updated Title";
if (needToAddTitle) {
payload.Title = titleValue;
}
Now your payload object is
{ __metadata: {
"type": "SP.Data.ErrorHandlerListItem"
},
Title: "Updated Title"
}
but if needToAddTitle = false and the line payload.Title = titleValue is never executed, then the payload object is still
{ __metadata: {
"type": "SP.Data.ErrorHandlerListItem"
}
}
because you never defined payload.Title = something.
In that way you can dynamically build up each of the properties you need on the payload object, and not only dynamically add each property as needed, but use variables to set the property values, or even call functions to dynamically generate (and return) the property values.
Then, once your payload is set up the way you want, then you do your ajax call, passing the payload variable/object into the JSON.stringify() function:
$.ajax({
type: 'POST',
url: odataUrl,
contentType: "application/json;odata=verbose",
processData: false,
headers: {
"Accept": "application/json;odata=verbose",
"Content-Type":"application/json;odata=verbose",
"X-RequestDigest":$("#__REQUESTDIGEST").val(),
//"If-Match": "*",
//"X-HTTP-Method": "MERGE"
},
data: JSON.stringify(payload)
});