I'm a Java programmer, but not a JavaScript programmer. I have just discovered YUI, and am trying to get started using it. What I'd like to try and do is have the query form at the top of the page, the user press Submit and the results show up in a YUI DataTable below the query form.
Normally, of course, on a HTML form the user presses Submit, the request gets sent to the server, and I use Struts to process it and then forward the request to a JSP and HTML gets sent back to the browser. That's what I do on a daily basis. With Ajax, I understand it's different in that I should return XML instead. Not a problem. Easy to do.
The questions I have deal with the YUI side of things. When the Submit button is pressed, what happens? Not normal form submission, right? Do I implement an onSubmit() JavaScript function which then triggers some YUI DataSource to go fetch the data? How do the request params get passed? Hopefully I don't have to construct the request manually. I'm guessing that I use a YAHOO.util.XHRDataSource and that's the DataSource for the DataTable.
I've managed to get the YUI DataTable to work using an HTML table element. Now I just need to switch it over to real data. Curiously, the YUI documentation seems a bit weak here, unless I'm missing something. Maybe this is just basic Ajax that the YUI docs don't cover?
First of all, when working with Ajax you don't need to return XML from the server, you could return plain text, XML, JSON strings, literally any form of textual data that you want. One example of populating a Datatable with JSON data is provided here:
http://developer.yahoo.com/yui/examples/datatable/dt_xhrjson.html
An example of how to send a post request using Ajax and YUI is provided here.
http://developer.yahoo.com/yui/examples/connection/post.html
That should get you started, now just link both of them together.
To connect to the server you can use the Yahoo.util.Connect.asyncRequest method which takes in the following parameters:
static object asyncRequest ( method , uri , callback , postData );
See an example here, this one uses "GET" so you can use either "GET" or "POST" just make sure you pass in your parameters
http://developer.yahoo.com/yui/examples/json/json_connect.html
Once your function returns on your "onSuccess" do the following to parse the response text to JSON
try {
jsonData = YAHOO.lang.JSON.parse(o.responseText);
}
catch (x) {
alert("JSON Parse failed!");
return;
}
The "jsonData" object now contains your data, so now you can follow this example:
http://developer.yahoo.com/yui/examples/datatable/dt_basic.html
It shows you how to initialize a datatable with a local object holding the datasource. basically it would be something like this
var myColumnDefs = [
{key:"Column1Data", label:"Column1 Header" sortable:true, resizeable:true},
{key:"Column2Data", label:"Column2 Header" sortable:true, resizeable:true}
];
var myDataSource = new YAHOO.util.DataSource(jsonData);
myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSARRAY;
myDataSource.responseSchema = {
fields: ["Column1Data","Column2Data"]
};
var myDataTable = new YAHOO.widget.DataTable("basic",
myColumnDefs, myDataSource, {caption:"DataTable Caption"});
For this to work, you have to have a "div" container in the HTML code with an id of "basic" note this matches the first parameter on the DataTable
Hope this helps
Related
I have a JSF page contentEdit.xhtml which accepts a request parameter "code" to load the content for editing and other operations related. To provide access control, I create a filter ContentAccessFilter and applies it to contentEdit.xhtml to check whether the current user is authorized to the content which is identified by "code".
Fragment of ContentAccessFilter:
boolean isAuthorized = false;
String userId = httpReq.getRemoteUser();
String code = httpReq.getParameter("code");
if (code != null && !code.isEmpty())
{
ContentDAO dao = ContentDAO.getInstance();
isAuthorized = dao.isContentAuthorized(code, userId);
}
if (!isAuthorized)
{
httpRes.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
For the first entry of the contentEdit.xhtml, the filter works properly as the code parameter always exists during the first entry by calling such as /contentArea.xhtml?code=cnn from an anchor html tag. However, the code parameter is lost when there is subsequent operations on contentEdit.xhtml. For example, I have buttons like these.
<p:commandButton value="Download" action="#{contentView.downloadContent}"/>
<p:commandButton value="Publish" action="#{contentView.publishContent}"/>
Clicking the button will call the same URL as contentEdit.xhtml, while the parameter code is not included in the request URL. This missing parameter fails in the filter.
Is using a Servlet Filter a proper way to achieve the access control in this case? If it is, how to include a request parameter when triggers a commandButton?
Filters are a great way to implement authorization in a web app... you're on the right track.
The best way would be to use your filter but store the code parameter value in a session (javax.servlet.http.HttpSession), that way the parameter doesn't need to be passed in the query string with each request. You would set the code attribute in the session data on the first request and retrieve it whenever a new request is received.
If you must use the query string to pass the code value with each request, you'll need to use the includeViewParams parameter in the query string creation to preserve the code parameter in the generated URLs. BalusC (the JSF God) explains this better than anyone... https://stackoverflow.com/a/17745573/3858863
I have written a suitelet which has two parts - GET and POST.
In GET method I have a dropdown and a submit button.
In POST method, I have 5 text fields which display the data based on value fetched from dropdown in GET.
I want to call an iframe on submit button click. iframe will show POST method logic. In short, I don't want to navigate to new page on submit, but to make the whole thing work on a single page.
MY CODE
function init(request, response)
{
if(request.getMethod() == 'GET')
{
//... some code for dropdown and submit
//code for iframe
var context = nlapiGetContext();
var url = 'https://**url-of-post-method-results**.com';
var title = context.getSetting('SCRIPT', 'custscript_suitelet_title')
var content = '<iframe width=960px height=100% style="height:640px;" src=' + url + '></iframe>'
var newField = form.addField ('content', 'inlinehtml', title);
form.addField('extra', 'inlinehtml', '')
form.setTitle (title);
newField.setLayoutType('outsidebelow');
newField.setDefaultValue (content);
form.addSubmitButton('Submit');
response.writePage(form);
}
}
I referred to Marty Zigman's tutorial on embedding iframe. But I'. confused where to embed the iframe, in GET or POST?
To the best of my knowledge, NetSuite has no built in way via their API to avoid a page refresh in a case like this. Clicking the submit button, will by default, submit the form via a post method synchronously. You need to interrupt the click() event method via jQuery on NetSuite's default form submit button using client side code. You would then send the post yourself using jQuery, and on a response, show the information you would like, again via jQuery, by updating the iframe src url.
I apologize I do not have currently have access to an account to be able to give you the appropriate JavaScript. I would be cautious of breakage though since you will need to hack into the NetSuite UI a bit to make this work.
When a form is saved via a button, I want to also create a new document using the form "MSG", which has fields for message title, body and recipient. At first I thought it might be possible using only a JS library, but now I am unsure. What about opening an unrendered XPage which is bound to that document's form, and inheriting the values into it?
I hope I understand your question right: try inserting code like this in XPage's datasource (e.g. document1) postSave event:
var doc:NotesDocument=database.createDocument();
doc.replaceItemValue("Form","msg");
doc.replaceItemValue("title",document1.getItemValueString("title"));
...
doc.save(true);
I have a search form I generated using the filterGrid option in JqGrid. I want to add a JavaScript logic which is invoked before I submit the Search form. I have added a method which is invoked by the beforeSubmit property for the filterGrid. It goes into the method before submitting, but always submits the form regardless of the value returned. I would like the form to not submit if the javascript returns false.
Have any of you guys implemented anything like this before. Or is there any othe rbetter way to implement this. Any help on this will be really appreciated.
Code:
$("#search").filterGrid("#resultsGrid",
{gridModel:true,gridNames:true,enableSearch:true,
formtype:"vertical",buttonclass:"submitButton",
enableClear:true,beforeSearch:validateDate});
function validateDate(dateDiff) {
if(daysDiff < 0){
return [false,"Message"];
}
} // ??? (commented by Oleg)
return [true,""];
}
There are at least three different ways how searching can be used: Toolbar Searching, Custom Searching which you use and Single field searching or Advanced Searching which share the same code. So one have currently three different implementations of close things.
Only Toolbar Searching has beforeSearch event handler which can return false to stop searching. In case of Custom Searching the value returned by the event handler beforeSearch will not used. Single field searching or Advanced Searching don't call any event handler before searching. In all cases for the searching will set searching filter and the jqGrid parameter search to true and then force grid reloading with the code like
$("#gridId").trigger("reloadGrid",[{page:1}]);
To be able to make any validations and stop reloading of the grid I see no simple way. So I suggest only following.
You can overwrite the standard reloadGrid event handler and chain it. The corresponding code con look like following:
var grid = $("#gridId");
var events = grid.data("events"); // read all events bound to
var originalReloadGrid; // here we will save the original event handle
var skipRefresh = false; // this can be changed by owe validation function
// Verify that one reloadGrid event hanler is set. It is typical sitation
if (events && events.reloadGrid && events.reloadGrid.length === 1) {
originalReloadGrid = events.reloadGrid[0].handler; // save old
grid.unbind('reloadGrid');
var newEvents = grid.data("events");
grid.bind('reloadGrid', function(e,opts) {
if (!skipRefresh && grid[0].p.search) {
originalReloadGrid(e,opts);
}
});
}
Probably I will create later a demo which demonstrate this on an example and place the link to the demo here. Moreover I will try to suggest code changes to jqGrid so, that in all different implementations of searching will be possible to stop serching by returning false by beforeSearch event handle.
UPDATED: OK! I prepared a demo for you. In the demo I use no server components, so it will not really do searching, but you can see the results if the grid will be refreshed and goes to the page 1.
To test the demo you can do following:
type in the "Client" input field a text not starting with 'test' and click "search" button. You receive an alert which simulate the validation dialog.
type in the "Client" input field a text starting with 'test' like test1 and click "search" button. Now the grig will refreshed because the validation will be OK.
I have been using asp.net mvc for a bit (but I'm still a beginer). I want to have the ability to update two views as a result of a jquery postback.
Basically I have a list and a details view. The details view is presented using a jquery popup (using jquery-UI popup). I only want to update the list if the details save is successful (i.e. there are no validation errors on the details view). However, if there are any validation errros in the details view, I want to update the details view so that the user sees the validation errors.
so I thought in my controller, I return a JsonResult instead of a View.
[HttpPost]
public ActionResult SavePersonInfo(Person p) {
if(ModelState.Valid) {
return View("PersonList");
}
return Json({Error = true, View = PartialView("PersonDetails", p)});
}
As you can see if there are no errors I return the person list view, but if there are any validation errors, I have return the details view. The reason that I'm returning a JsonResult is I need to tell my view there is an error so that the view (jquery) knows which section to update (as in whether to update the person list 'div' or the popup dialog 'div').
So, in my view, the jquery is as follows (please assume that there is a form for entering in the person details and "SubmitPersonForm();" function is called upon clicking on the "Save" button):
<script type="text/javascript>
$('#btnSave').click(function (event) {
onBegin();
$.ajax(
{
type: "POST",
url: "/Person/Save",
data: $('form').serialize(),
success: function (result) {
if(result.Error) {
$('#dvDetails').html($(result).View));
}
else {
$('#dvPersonList').html($result);
}
}
});
});
</script>
So the problem that I have now, is that when there is a validation error, I do see the correct, 'div' being updated, but I lose the asp.net mvc validation messages. I do not see any validation errors in red, as if ASP.NET MVC is completely ignored them. However, my ModelState does have those errros, just not displayed in the details view. I do have valication summary and Html.ValidationFor(m => ...) statements put in my details view.
Could someone tell me why I'm not seeing the validation errors? although I'm using a JSonResult, I do use the right property which is a valid view when I render the 'dvDetails'. Am I doing something that I'm not suppose to in asp.net mvc? Btw I'm using asp.net mvc2 RC with Visual Studio 2010 RC.
Thank you.
The Url does not match the Action name ... not sure if you maybe are calling the wrong Method on the controller ... just an idea. :-)
ASP.NET MVC code processes the response to display validation errors stored in the ModelState during a postback. Because you are using an Ajax Post, the postback code is not rebuilding the page and displaying the validation errors. If you want to display validation errors, you have to handle it yourself.
I've done it by passing the ModelState errors as an array in the response. I process my Ajax response to update the validation error placeholder elements in the form with corresponding error messages in the response.
A warning, though: the keys in the ModelState may have their case changed, so an element ID string in the form doesn't exactly match the string that's used for the key. ModelStateDictionary is case-insensitive, but DOM ID's are not.