I have a page in which I've implemented an ajax call to a controller that returns search results that are packaged in a JsonNetResult.
I have a lot of javascript to then deal with the return package, iterating over each item in the results set and outputting to the page.
Now, however, I need to implement the usage of these same methods for a single item that will be known on page load. I'd like to just pass this info to the View in a ViewData dictionary.
However, I don't know how to use Json.Net in this way.
How do I load a Json.Net object into a native json variable on page load, assuming that object has been stuffed into ViewData["DeepLinkedMessage"]?
I started to go down the path of this:
var thisMessage = (from userMessageProduct .... more linq2sql stuff...);
bool success = (thisMessage.Count() == 0) ? false : true;
var returnPackage = new { success = success, results = thisMessage };
JavaScriptSerializer serializer = new JavaScriptSerializer();
ViewData["DeepLinkedMessage"] = serializer.Serialize(returnPackage);
It worked just fine. But I quickly noticed I'd have to solve the date formatting problems that I'd already solved when I set up the ajax call that returned JsonNetResult. I want to use the exact same methods that I'm using now.
So, I started down this path:
JsonNetResult jsonNetResult = new JsonNetResult();
jsonNetResult.SerializerSettings.Converters.Add(new IsoDateTimeConverter());
jsonNetResult.Data = returnPackage;
ViewData["DeepLinkedMessage"] = jsonNetResult.ToString();
Then, in my view:
<script type="text/javascript">
deepLinkedMessageId = '<%=ViewData["DeepLinkMessageId"] %>';
deepLinkedMessageRaw = '<%=ViewData["DeepLinkedMessage"]%>';
</script>
But this is returning this:
<script type="text/javascript">
deepLinkedMessageId = '1';
deepLinkedMessageRaw = 'WebUI.Controllers.JsonNetResult';
</script>
While I'm looking for something like this:
<script type="text/javascript">
deepLinkedMessageId = '1';
deepLinkedMessageRaw = '{"success":true,"results":[{"UserId":1,"InternalId":"1356935180","FirstName":"Scott","LastName":"Roberson","MessageId":1,"MessageText":"i just love your product!!!", "MessageCreateTime":"\/Date(1295289549930)\/","ProductId":5,"Flavor":"Almonds","ActivePixel":false,"ActiveClass":null,"TileNumber":0}]}';
</script>
Help using Json.Net for this?
Thanks.
Well, I found out from here that I can just do this:
bool success = (thisMessage.Count() == 0) ? false : true;
var returnPackage = new { success = success, results = thisMessage };
ViewData["DeepLinkedMessage"] = JsonConvert.SerializeObject(returnPackage, new IsoDateTimeConverter());
<wipes hands> "problem solved!"
You should set your view to implement your model explicitely:
Inherits="System.Web.View<YourModelName>"
Then in your view you can do
Model.Property
I just find this easier to isolate where the problem is happening (plus viewdata can be a pain in the ass)
Related
I have figured out how to run a Google App Script project/function on a form submit using the information at https://developers.google.com/apps-script/guides/triggers/events#form-submit_4.
Once I have e I can call e.response to get a FormResponse object and then call getItemResponses() to get an array of all of the responses.
Without iterating through the array and checking each one, is there a way to find the ItemResponse for a specific question?
I see getResponseForItem(item) but it looks like I have to somehow create an Item first?
Can I some how use e.source to get the Form object and then find the Item by question, without iterating through all of them, so I could get the Item object I can use with getResponseForItem(item)?
This is the code I use to pull the current set of answers into a object, so the most current response for the question Your Name becomes form.yourName which I found to be the easiest way to find responses by question:
function objectifyForm() {
//Makes the form info into an object
var myform = FormApp.getActiveForm();
var formResponses = myform.getResponses()
var currentResponse = formResponses[formResponses.length-1];
var responseArray = currentResponse.getItemResponses()
var form = {};
form.user = currentResponse.getRespondentEmail(); //requires collect email addresses to be turned on or is undefined.
form.timestamp = currentResponse.getTimestamp();
form.formName = myform.getTitle();
for (var i = 0; i < responseArray.length; i++){
var response = responseArray[i].getResponse();
var item = responseArray[i].getItem().getTitle();
var item = camelize(item);
form[item] = response;
}
return form;
}
function camelize(str) {
str = str.replace(/[\.,-\/#!$%\^&\*;:{}=\-_`~()#\+\?><\[\]\+]/g, '')
return str.replace(/(?:^\w|[A-Z]|\b\w|\s+)/g, function(match, index) {
if (+match === 0) return ""; // or if (/\s+/.test(match)) for white spaces
return index == 0 ? match.toLowerCase() : match.toUpperCase();
});
}
//Use with installable trigger
function onSubmittedForm() {
var form = objectifyForm();
Logger.log(form);
//Put Code here
}
A couple of important things.
If you change the question on the form, you will need to update your
code
Non required questions may or may not have answers, so check if answer exists before you use it
I only use installable triggers, so I know it works with those. Not sure about with simple triggers
You can see the form object by opening the logs, which is useful for finding the object names
I am using the alternative JSON format along with AJAX to load data in tree. Now there is a new ask, I am required to add a new element at the end of <li> tag.
I have created sample URL to display what I am currently doing.
Tree crated using alternative JSON format along with AJAX
And how the new LI should appear
Tree created using hard coded HTML but shows how the LI should look like
I think I should be able to do this if I use HTML Data but since the project is already live with JSON format this would require me to change a lot so before I start making this major change I just wanted to check if this is possible using JSON and AJAX format or not.
So I got answer from Ivan - Answer
In short there is misc.js in the src folder which has question mark plugin, this is the best example of what I wanted to do.
I tweaked its code for my needs and here is the new code.
(function ($, undefined) {
"use strict";
var span = document.createElement('span');
span.className = 'glyphicons glyphicons-comments flip jstree-comment'
$.jstree.defaults.commenticon = $.noop;
$.jstree.plugins.commenticon = function (options, parent) {
this.bind = function () {
parent.bind.call(this);
};
this.teardown = function () {
if (this.settings.commenticon) {
this.element.find(".jstree-comment").remove();
}
parent.teardown.call(this);
};
this.redraw_node = function (obj, deep, callback, force_draw) {
var addCommentIcon = true;
var data = this.get_node(obj).data;
//....Code for deciding whether comment icon is needed or not based on "data"
var li = parent.redraw_node.call(this, obj, deep, callback, force_draw);
if (li && addCommentIcon) {
var tmp = span.cloneNode(true);
tmp.id = li.id + "_commenticon";
var $a = $("a", li);
$a.append(tmp);
}
return li;
};
};
})(jQuery);
I am facing a strange problem here. I have a Select box displaying Department field value. Onchange of the department option, I have to populate the grid. When the page loads first time, the onChange event works fine and the data gets loaded perfectly in the grid. When I change the Department in the Select box, I get error in firebug "dojo.data.ItemFileReadStore: Invalid item argument".
I checked the JSON returned from server and it is exactly same as the JSON loaded earlier. Here are the code snippet of my code
HTML
<div id="costCenter" data-dojo-type="dijit/form/Select" data-dojo-attach-point="costCenter" data-dojo-attach-event="onChange:loadStacks"></div>
JS
loadStacks: function() {
var requestParams = {};
requestParams.Action = "getStacks";
requestParams.callType = "ajaxCall";
requestParams.deptID = deptID;
var docData = null;
request.invokePluginService("MyPlugin", "UtilityService",
{
requestParams: requestParams,
requestCompleteCallback: lang.hitch(this, function(response) { // success
docData= response.Data;
var dataStore = new dojo.data.ItemFileReadStore({data: docData});
grid = dijit.byId("docGrid");
grid.attr('structure', docStructure);
grid.attr('store', dataStore);
grid.render();
})
}
);
}
JSON data returned:
docData : {"items":[{"docName":"test3","id":135,"order":1},{"docName":"Ashish","id":4085,"order":21},{"docName":"fsdfsadf","id":4088,"order":23}],"identifier":"docName"}
Any idea about it?
Solved it myself. Added below lines before setting new store to the grid.
if (null != grid.store)
{
grid.store.close();
grid.store.fetch({query: {docName: "*"}});
grid._refresh();
}
And set clearOnClose: true while setting new store.
There is another issue when I try to set the preselected (or any) value of my store-fed dijit/form/Select widget.
The markup code is:
<div data-dojo-type="dijit/form/Select" jsId="editOptionsDialog_select" id="editOptionsDialog_select"></div>
and the js:
function editOptionsDialog_fetchData(cId, fieldName, vId) {
var store;
var def;
var return_def = new Deferred();
store = new degreeStore();
def = store.getJsonData();
def.then(function(data) {
store.data = data.items;
editOptionsDialog_select.setStore(new ObjectStore({
objectStore : store
}));
editOptionsDialog_select.value = vId;
editOptionsDialog_select.startup();
editOptionsDialog_select.set('value', 5);
console.info(editOptionsDialog_select);
// here, firebug still shows value = 1
return_def.resolve();
});
return return_def;
}
thx in advance
Greetings
Finally found a solution to the problem:
Since the selection-element DOES NOT support numerical indexes, the indexes had to be casted to strings. With that, a editOptionsDialog_select.set('value', vId.toString()) has finally worked!
Be sure to feed your store by casted numerical ids or then textual-keys by default -> (String)id where id is an integer.
Greetings
I have a fairly vanilla HTML page with an (inquiry) form. That form has topic field. I'd like to be able to link to that page from another topic-specific page (using an A tag?) on the website, causing that topic field (and maybe some subset of other fields) to be filled in automatically.
Suggestions?
Add a custom param (topic name) to the page where the link points and use it as a subject/topic field.
like:
link
Then, on a target page (with inquiry) use this javascript:
<script type="text/javascript">
// Read a page's GET URL variables and return them as an associative array.
function getUrlVars()
{
var vars = [], hash;
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
for(var i = 0; i < hashes.length; i++)
{
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1];
}
return vars;
}
var params = getUrlVars();
document.getElementById('your_topic_field_id').value = params['topic_title'];
</script>