I have an own TagLib and one Tag called boxLink to generate an Remote Link and open an Modal:
Closure boxLink = { attrs, body ->
Integer modalId = OwnUtil.getRandomNumber(1000)
Map params = attrs.params ? attrs.params : [:]
params.put('modalId', modalId)
Map linkParams = params
out << '<a href="#" class="modalBoxLink ' + attrs.class
if (attrs.title)
out << ' tooltipSpan" title="' + attrs.title
out << '" onclick="'
out << remoteFunction(controller: attrs.controller, action: attrs.action, onLoading: attrs.onClick + ';loadingSpinner()', onComplete: 'removeSpinner()',
onSuccess: 'viewModalBox(data,' + modalId + ');initForm();', onFailure: 'errorAlert();', params: linkParams)
out << '">'
out << body()
out << '</a>'
}
In some Cases I neet to read an value of an Form Element to put it into the data of the AJAX Request, so I tried this
if(attrs.elementid){
def elParam = attrs.elementid
if(attrs.elementname)
elParam = attrs.elementname
linkParams.put(elParam,"document.getElementById('${attrs.elementid}').value")
}
this generates this data value of the ajax request
data:{'modalId': '357','application': 'document.getElementById('elementid').value'}
How Can I set an data property of the ajax request by getting the value of an HTML element?
The tag lib is executed on the server, you want the generated code to act on the client. This will only be possible through javascript. You may be best off using jQuery and ajaxForm for this. You could tie a function to the modal opening or some other action and set the value(s) of hidden fields in your form.
Here is an example from what I use, which populates a modal with html from a hidden div and adds data to two hidden fields. Note that I am not using ajaxForm here but it's the same idea.
<script type="text/javascript">
function configModal() {
$(".clickable-row").click(function() {
var row = $(this)
var modal = $('#notificationModal');
var title = row.find('td').find('a').html();
var html = row.find('.notification-content').html();
var notificationId = row.attr('id');
modal.find('.modal-body').html( html );
modal.find('.modal-title').html( title );
modal.find('#modal-form').find('input[name=id]').attr('value', notificationId)
modal.find('#modal-form').find('input[name=isDeleted]').attr('checked', row.hasClass('deleted'));
modal.modal();
$.post("${createLink(controller: 'notification', action: 'update')}",
{ id : notificationId, isRead : true },
function() { row.addClass('read'); });
});
}
$(document).ready(configModal);
</script>
Related
This code is inside the function submitForm(){}, means, everytime when user click the save button it will trigger this part. the code shows no error, but during the page load, it gives this error:
PrintDebug.println("Final SeqNo: "+finalSeqno);
%>
<%ResultSet rsVal = aDBManager.retrieveRec(sqlgetSeq);%>
<%if(rsVal.next()){ %>
[Stacktrace:] with root cause
java.lang.NullPointerException
I have tried to remove this part of code,and everything work as expected.Seems like the resultset of the select statement giving me the error.for the stored proc resultset , it works fine. This actually confuse me, why the stored proc is ok but not the select statement in ajax jquery.If this can't be done, is there another way for me to pass the value from select statement to input label?
Thanks in advance..
callback: function (result) {
if(result){
var forTempValue = "";
var forFieldValue = "";
var forMandatory = "";
var forDataImageNoApp = "";
var loopInt = 0;
$('input[type=textbox][name^=tmpField],select[name^=tmpField],input[type=text][name^=tmpField]').each(
function(index){
var input = $(this);
forTempValue+=("'" + input.prop('value').replace(/&/g,"") + "' Col" + loopInt + ",");
forFieldValue+=("'" + input.prop('value').replace(/&/g,"") + "'" + "±");
loopInt++;
}
);
$('input[type=hidden][name^=MandatoryName]').each(
function(index){
var input = $(this);
forMandatory+=(input.val() + ",");
}
);
$('input[type=hidden][name^=tempNoAppLoop]').each(
function(index){
var input = $(this);
forDataImageNoApp+=(input.val() + ",");
}
);
$.ajax({
type: "POST",
url: "../ESSCheckerMakerOperation",
data: "sTabID=<%=sTabID%>&sFieldNameApp=<%=sFieldNameApp%>",
success: function(msg){
<%
String getSeqNo = "SELECT MAX(fldSeqno) FROM "+MappingID+"";
String finalSeqno="";
ResultSet rs = aDbManager.retrieveRec(getSeqNo);
if(rs.next()){
finalSeqno=rs.getString(1);
}rs.close();
String cmd="EXEC sp_RelationshipValidation '"+MappingID+"'," + finalSeqno;
aDbManager.SQLTransaction(cmd);
String sqlgetSeq= "Select fldCommonErrorFlag " +
" From tblGeneralError" +
" Where fdSeqNo '" +finalSeqno + "' "+
" And fldTableName = '" +MappingID + "' ";
PrintDebug.println("Final SeqNo: "+finalSeqno);
%>
<%ResultSet rsVal = aDBManager.retrieveRec(sqlgetSeq);%>
<%if(rsVal.next()){ %>
document.getElementById('lblError').style.visibility = 'visible';
document.getElementById('lblError').innerHTML = <%=finalSeqno%>;
Ko
<%}else{%>
bootbox.alert({
title:"Record is successfully ",
message:"There is a problem with the validation for" + <%=finalSeqno%> ,
});
<%
}%>
//}
},
error: function(msg){
bootbox.alert({
title:"Error",
message: "Failed to save the record.",
});
}
});
};
}
});
This is really a classic one: The key is to realize, where and when which code is executed - JSP on the server when the page is requested and rendered (i.e. before the response is send to the browser) and Javascript in the browser, after the browser receives the already generated response.
Your main mistake is to use JSP scriptlet in the success handler of the AJAX call - the scriptlet is run on the server side, before when the page is generated, i.e. before the AJAX request can even be fired by the browser. Thus, the variables you expect to be filled by the call are null.
Battlefield Page
In the image above, there is a page that has a battlefield with 20 users on it. I have written JavaScript to capture the data and store it in a MySQL db. The problem comes into the picture when I need to hit next to go to the next page and gather that data.
It fetches the next 20 users with an Ajax call. Obviously when this happens, the script can't log the new information because the page never loads on an Ajax call which means the script doesn't execute. Is there a way to force a page load when the Ajax link is clicked?
Here's the code:
grabData();
var nav = document.getElementsByClassName('nav')[0].getElementsByTagName('td')[2].getElementsByTagName('a')[0];
nav.addEventListener("click", function(){
grabData();
});
function grabData(){
var rows = document.getElementsByClassName('table_lines battlefield')[0].rows;
var sendData = '';
for(i=1; i < rows.length -1 ; i++){
var getSid = document.getElementsByClassName('table_lines battlefield')[0].getElementsByTagName('tr')[i].getElementsByTagName('td')[2].getElementsByTagName('a')[0].href;
var statsID = getSid.substr(getSid.indexOf("=") + 1); //Grabs ID out of stats link
var name = document.getElementsByClassName('table_lines battlefield')[0].getElementsByTagName('tr')[i].getElementsByTagName('td')[2].textContent.replace(/\,/g,"");
var tff = document.getElementsByClassName('table_lines battlefield')[0].getElementsByTagName('tr')[i].getElementsByTagName('td')[3].textContent.replace(/\,/g,"");
var rank = document.getElementsByClassName('table_lines battlefield')[0].getElementsByTagName('tr')[i].getElementsByTagName('td')[6].textContent.replace(/\,/g,"");
var alliance = document.getElementsByClassName('table_lines battlefield')[0].getElementsByTagName('tr')[i].getElementsByTagName('td')[1].textContent.trim();
var gold = document.getElementsByClassName('table_lines battlefield')[0].getElementsByTagName('tr')[i].getElementsByTagName('td')[5].textContent.replace(/\,/g,"");
if(alliance == ''){
alliance = 'None';
}
if(gold == '??? Gold'){
gold = 0;
}else{
gold = gold.replace(/[^\/\d]/g,'');
}
sendData += statsID + "=" + name + "=" + tff + "=" + rank + "=" + alliance + "=" + gold + "#";
}
$.ajax({
// you can use post and get:
type: "POST",
// your url
url: "url",
// your arguments
data: {sendData : sendData},
// callback for a server message:
success: function( msg ){
//alert(msg);
},
// callback for a server error message or a ajax error
error: function( msg )
{
alert( "Data was not saved: " + msg );
}
});
}
So as stated, this grabs the info and sends to the php file on the backend. So when I hit next on the battlefield page, I need to be able to execute this script again.
UPDATE : Problem Solved. I was able to do this by drilling down in the DOM tree until I hit the "next" anchor tag. I simply added an event listener for whenever it was clicked and had it re execute the JavaScript.
Yes, you can force a page load thus:
window.location.reload(true);
However, what the point of AJAX is to not reload the page, so often you must write javascript code that duplicates the server-side code that builds your page initially.
However, if the page-load-code-under-discussion runs in javascript on page load, then you can turn it into a function and re-call that function in the AJAX success function.
Reference:
How can I refresh a page with jQuery?
I currently have a servlet setup to send over a list of our active servers. The method grabs the servlet data, processes it, then injects the html into the datalist tag. HTML injection process works, but when I'm splitting the array by the concat separator (which I've done before), I get no values. Below I'll explain with code examples:
HTML:
<label for="server_id_text">Server ID: </label>
<input id="server_id_text" list="server_names" name="server_id" required>
<datalist id="server_names">
<!--This gets injected with the active servers grabbed through a get request-->
</datalist>
Javascript connecting to server to get data:
Note: serverList is a global variable.
var serverList = "";
function setupAutoComplete() {
$.get(baseURL + "/SupportPortal", function (data, status) {
console.debug("Status with auto comp id: " + status);
serverList = data;
console.debug("server list auto comp at post mailing: " + serverList);
});
}
This method is called in the function that is called when the onload event is called in the body tag
Here are the two methods that inject the html:
function setupServerName() {
document.getElementById("server_names").innerHTML = getServerListHTML();
}
function getServerListHTML(){
console.debug("Autocomplete process running...");
var servArr = String(serverList).split('*');
var html = '';
var temp = '<option value="{serverName}">';
console.debug("Array:" + servArr.toString());
if (serverList == 'undefined' || servArr.length == 0){
console.debug("serverList is empty...");
return '';
}
for (var i =0; i < servArr.length; ++i){
html += temp.replace("{serverName}", servArr[i]);
}
console.debug("html: " + html);
console.debug("ServList size " + servArr.length);
return html;
}
When the page loads, setupAutoCompelte() is called first. Then, setupServerName() is called.
My issue is that after I load the page, I get the correct response from the server. For instance, I'll get server1*server2 as a response to the jQuery $.get(...) call. Then I go to split the string into an array, and I get back an empty html tag (<option value="">);
Also, the debug console info are as follows:
Autocomplete process running...
Array:
html: <option value="">
ServList size 1
Status with auto comp id: success
server list auto comp at post mailing: server1*server2
Thanks for the help!
I believe that your setupServerName() function is being called before the AJAX request in setupAutoComplete() returns, so your serverList is an empty string at that point. What you need to do is populate your <datalist> from inside your AJAX callback in setupAutoComplete().
// setup autocomplete datalist
function setupAutoComplete() {
var $datalist = $('#server_names');
$.get(baseURL + '/SupportPortal').then(function (data) {
// update datalist
if (!data || !data.length) {
// no servers, empty list
$datalist.html('');
} else {
// create options html:
// reduce array of server names
// to HTML string, and set as
// innerHTML of the dataset
$datalist.html(data.split('*').reduce(function (html, server) {
return html + '<option value="' + server + '">\n';
},''));
}
});
}
// on page load, setup autocomplete
$(function () {
setupAutoComplete();
});
As you can see from "debug console info":
the get function is asyncrhonous so you need to change your setupAutoComplete get part to:
$.get(baseURL + "/SupportPortal", function (data, status) {
console.debug("Status with auto comp id: " + status);
serverList = data;
setupServerName();
console.debug("server list auto comp at post mailing: " + serverList);
});
On page load try to call directly the setupServerName function within the success event of get function. A different approach is to divide the setupServerName function so that the part related to the serverList variable becomes part of another function.
The serverList variable is global but its content is filled after the setupServerName is executed.
I have a default page with list of items. When I click on those Items I need to dynamically append data to div in Page B and redirect the app to Page B.
I added this div in PageB
''
On Click event I am doing following action in .js file:
'$(document).on('click', '#selectConcept', function (node) {
var ncid = this.textContent.slice(6,25);
$.ajax({
dataType: "json",
url: "http://txv-trmindexer01:8080/CommonTerminologyLeopardSearch/rest/getConceptByNcid/" + ncid,
error: function () {
alert("ERROR");
},
success: function (data) {
window.location.href = 'getfacets.html';
for (var result = 0; result < finalSearchResults.length; result++) {
if (finalSearchResults[result].ncid == ncid) {
$("#selectedConceptitem").empty();
var selectedconcept = "<p>" + "ncid: " + finalSearchResults[result].ncid + "," + "cid: " + finalSearchResults[result].cid + "</p>";
$(selectedconcept).appendTo("#selectedConceptitem");
}
}
} });
});'
I am able to redirect page, but nothing is appended to Div.
Can anyone help me out with this..
I'm not really sure, but I guess the code runs before the new page is loaded. So you could try to wrap the code in a function run at onload event time
window.location.href = 'getfacets.html';
window.onload = function() {
for (var result = 0; result < finalSearchResults.length; result++) {
if (finalSearchResults[result].ncid == ncid) {
$("#selectedConceptitem").empty();
var selectedconcept = "<p>" + "ncid: " + finalSearchResults[result].ncid + "," + "cid: " + finalSearchResults[result].cid + "</p>";
$(selectedconcept).appendTo("#selectedConceptitem");
}
}
}
The problem:
As soon as you set "window.location.href" property the page navigates to your page B and you loose your fetched data.
You have two solutions to the problem:
Use Single Page Application (SPA) application approach wherein you could create a new global scope for your fetched data, which can now be used by page B
Send the ncID as a querystring parameter to page B and and implement the service call and data appending logic on page B
I have a MVC3 action method with 3 parameters like this:
var url = "/Question/Insert?" + "_strTitle='" + title + "'&_strContent='" + content + "'&_listTags='" + listTags.toString() + "'";
and I want to call this by normal javascript function not AJAX (because it's not necessary to use AJAX function)
I tried to use this function but it didn't work:
window.location.assign(url);
It didn't jump to Insert action of QuestionController.
Is there someone would like to help me? Thanks a lot
This is more detail
I want to insert new Question to database, but I must get data from CKeditor, so I have to use this function below to get and validate data
// insert new question
$("#btnDangCauHoi").click(function () {
//validate input data
//chủ đề câu hỏi
var title = $("#txtTitle").val();
if (title == "") {
alert("bạn chưa nhập chủ đề câu hỏi");
return;
}
//nội dung câu hỏi
var content = GetContents();
content = "xyz";
if (content == "") {
alert("bạn chưa nhập nội dung câu hỏi");
return;
}
//danh sách Tag
var listTags = new Array();
var Tags = $("#list_tag").children();
if (Tags.length == 0) {
alert("bạn chưa chọn tag cho câu hỏi");
return;
}
for (var i = 0; i < Tags.length; i++) {
var id = Tags[i].id;
listTags[i] = id;
//var e = listTags[i];
}
var data = {
"_strTitle": title,
"_strContent": content,
"_listTags": listTags.toString()
};
// $.post(url, data, function (result) {
// alert(result);
// });
var url = "/Question/Insert?" + "_strTitle='" + title + "'&_strContent='" + content + "'&_listTags='" + listTags.toString() + "'";
window.location.assign(url); // I try to use this, and window.location also but they're not working
});
This URL call MVC action "Insert" below by POST method
[HttpPost]
[ValidateInput(false)]
public ActionResult Insert(string _strTitle, string _strContent, string _listTags)
{
try
{
//some code here
}
catch(Exception ex)
{
//if some error come up
ViewBag.Message = ex.Message;
return View("Error");
}
// if insert new question success
return RedirectToAction("Index","Question");
}
If insert action success, it will redirect to index page where listing all question include new question is already inserted. If not, it will show error page. So, that's reason I don't use AJAX
Is there some one help me? Thanks :)
Try:
window.location = yourUrl;
Also, try and use Fiddler or some other similar tool to see whether the redirection takes place.
EDIT:
You action is expecting an HTTP POST method, but using window.location will cause GET method. That is the reason why your action is never called.
[HttpPost]
[ValidateInput(false)]
public ActionResult Insert(string _strTitle, string _strContent, string _listTags)
{
// Your code
}
Either change to HttpGet (which you should not) or use jQuery or other library that support Ajax in order to perform POST. You should not use GET method to update data. It will cause so many security problems for your that you would not know where to start with when tackling the problem.
Considering that you are already using jQuery, you might as well go all the way and use Ajax. Use $.post() method to perform HTTP POST operation.
Inside a callback function of the $.post() you can return false at the end in order to prevent redirection to Error or Index views.
$.post("your_url", function() {
// Do something
return false; // prevents redirection
});
That's about it.
You could try changing
var url = "/Question/Insert?" + "_strTitle='" + title + "'&_strContent='" + content + "'&_listTags='" + listTags.toString() + "'";
to
var url = "/Question/Insert?_strTitle=" + title + "&_strContent=" + content + "&_listTags=" + listTags.toString();
I've removed the single quotes as they're not required.
Without seeing your php code though it's not easy to work out where the problem is.
When you say "It didn't jump to Insert action of QuestionController." do you mean that the browser didn't load that page or that when the url was loaded it didn't route to the expected controller/action?
You could use an iframe if you want to avoid using AJAX, but I would recommend using AJAX
<iframe src="" id="loader"></iframe>
<script>
document.getElementById("loader").src = url;
</script>