Capture and Display error inside JqueryUI dialog - javascript

I am using JQuery-UI dialog to load an MVC partial view
Here is some sample code:
$(function () {
function fSetupDialogs() {
$("#dialog-popup").dialog({
autoOpen: false,
resizable: true,
modal: true
});
}
});
$('body').on('click', '.popup-Edit',
function (e) {
url = $(this).data("url");
$("#dialog-popup")
.load(url)
.html("<img src='/content/images/Spinner.gif'>")
.dialog("option", "title", "Edit " + url.split("/").pop())
.dialog('open');
}
);
This works pretty well despite some occasional weird scrollbars and stuff.
The problem is when the view throws an error, I can't work out how to inspect it and display it inside the jqueryui panel
So if the view returns a 500 or 401 error, I'd like to capture that and show it in the dialog. Right now what happens is that the spinner GIF just sits there forever. If I open the F12 console I can see the error in there.
I have tried using the .error event handler which does capture it and pop up a messagebox. But I want to display inside the popup:
// This pops up an error alert
$("#dialog-popup")
.load(url)
.error(alert("error"))
.html("<img src='/content/images/Spinner.gif'>")
.dialog("option", "title", "Edit " + url.split("/").pop())
.dialog('open');
How do I display something inside the dialog? This has no effect - the spinner stays in there
// This has no effect - I want to see the words "error"
$("#dialog-popup")
.load(url)
.error($("#dialog-popup").html("error"))
.html("<img src='/content/images/Spinner.gif'>")
.dialog("option", "title", "Edit " + url.split("/").pop())
.dialog('open');
For bonus points, how do I use the javascript error object to identify 401, 500 whatever? - I haven't got to that yet.

I looked through my own code and found the answer.
The load method takes a callback argument that can be used to do what I need
I wrote a function called popupComplete that is called when the load is finished.
// This loads a partial MVC view into the popup
$("#dialog-popup")
.load(url,popupComplete)
.html("<div align='middle'><img src='/content/images/Spinner.gif'></div>")
.dialog("option", "title", "New")
.dialog("open");
// when the load is complete, this is called
// which optionally displays an error inside the popup
function popupComplete(response, status, xhr) {
if (status === "error") {
var msg =
"<BR><BR><BR><H3 style='text-align: center;'><span style='color: red;' class='glyphicon glyphicon-fire'></span> Confound it!<BR><BR>" +
xhr.status + " " + xhr.statusText +
"<BR><BR>" + (xhr.status == 401 ? "Try logging in again" : "") +
"</B></H3>";
$("#dialog-popup").html(msg);
}
}

Related

Bootbox dialog doesn't open within a loop

This is my objective:
Custom Bootbox dialog opens to specify a value. User specifies a value, clicks Save and the value is passed to web application via Ajax call.
Web application validates the value and either sends back a "success" message if validation was passed and database was updated or sends back a "failure" message with a reason for a validation failure.
If "success" message was received dialog closes, otherwise it opens again and displays validation message below user input. User can change the input and click Save again or press Cancel to dismiss the dialog.
MCVE (note that while(bContinue == true) is commented out to show that it works without a loop and there is no validation message anywhere but it will be a part of a Message variable (this variable will be updated in Save callback function after an Ajax call)):
$(document).on("click", ".alert", function(e) {
var Message = "<label class='control-label col-sm-1' style='width:30px;' for='assignmentname'>"+"Assignment "+"</label>"
+ "<input type='text' id='assignmentname' class='form-control' style='float: left; max-width:800px;' value='Initial value'>"
var bContinue = true;
//while(bContinue == true)
{
bootbox.dialog({
size: "large",
message: Message,
title: "Edit Assignment",
buttons: {
save:
{
label: "Save",
className: "btn btn-success",
callback: function() {
// perform Ajax call to the web application
// and set bContinue to true or false depending on
// return value
bContinue = true;
}
},
cancel:
{
label: "Cancel",
className: "btn btn-default",
callback: function() {
// exit out of the loop
bContinue = false;
}
}
}
});
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
<script src="https://github.com/makeusabrew/bootbox/releases/download/v4.4.0/bootbox.min.js"></script>
<p><a class="alert" href=#>Click here</a></p>
The problem is - as soon as while(bContinue == true) is un-commented the dialog never opens.
Expected MCVE behavior: dialog opens and if Save is clicked it closes and re-opens. If Cancel is clicked - dialog closes.
The problem is not in the Bootbox , the problem is in the while loop which keep looping very fast without waiting the Bootbox to load, and it make the whole browser hang :)
So you will need to change your logic, may be put the Bootbox dialog in a function and make it call the function again on save.
Or may be using promises: How to use confirm alert and return an AJAX promise?

Jquery elements not rebinding + HTMLDivElement unrecognized expression

I am creating a dynamic refresh feature for div elements on my site that need to be dynamically refreshed.
$(document).ready(function() {
function refreshDiv() {
var refreshUrl = window.location.pathname;
$('.refreshable').each(function() {
$(this).fadeOut("slow", function() {
$(this).hide().load(refreshUrl + " " + this, "").fadeIn("slow");
});
});
}
$(document.body).on("click", ".login_button.submit", function(e) {
e.preventDefault();
var username = $('#username').val();
var password = $('#password').val();
$.ajax({
type : "POST",
url : '/login',
data : {username:username, password:password},
success:function(response) {
if(response.status == 'success') {
$('#sb-site').animate({'opacity': '1'}, 300);
$('#login_form').toggle();
refreshDiv();
} else {
console.log('Something went wrong');
}
},
error:function(response) {
console.log('Something went wrong');
}
});
});
$(document.body).on("click", ".logout_button", function(e) {
e.preventDefault();
$.ajax({
type : "POST",
url : '/logout',
success:function(response) {
if(response.status == 'success') {
refreshDiv();
} else {
console.log('Something went wrong');
}
},
error:function(response) {
console.log('Something went wrong');
}
});
});
});
I have a few issues that have come up.
1) After logout is clicked, it calls the Laravel controller at /logout. After that, it loads up the page with the refreshed content, but the jquery click events wont rebind, so I have to refresh in order to log in again after a logout. The elements rebind fine after login happens, however. I figured using .on() would fix this, but it has not.
2) Elements are duplicated because I am having trouble implementing 'this' into the refreshDiv function. I get an error:
Uncaught Error: Syntax error, unrecognized expression: [object HTMLDivElement]
This doesn't happen if I do
$(this).hide().load(refreshUrl + " .refreshable>*", "").fadeIn("slow");
but I need it to reload each specific targeted element individually, or it overlaps the content with matching classes. I tried:
$(this).hide().load(refreshUrl + " " + this, "").fadeIn("slow");
My goal is to just be able to have a scalable solution to just add a .refresh class to a wrapper that needs to be dynamically refreshed.
It is hard to tell exactly what you want from this as shown in your call to .load(). The reason your error is showing up is because you are implicitly casting this to a string. The result is "[object HTMLDivElement]" which makes your call look like this
$(this).hide().load(refreshUrl + " " + "[object HTMLDivElement]", "").fadeIn("slow");
and that should clear up why the error occurs. What do you need from the div element in that spot?
In order to access the current div, just use prop or attr or native calls to get the information out from that point, such as this.className or this.id or $(this).data('location') etc.
However, as you have already started this chain off with $(this), making the call to .load will already apply the loaded content at refreshUrl to the current this element.
So really all you need to do is
$(this).hide().load(refreshUrl,function(){
$(this).fadeIn('slow'); // only fade in once content is loaded
});
Or perhaps you want the fade to occur while the data loads, in which case $(this).hide().load(refreshUrl).fadeIn("slow"); would be used.

Click button on page when site loading is complete

I have made a simple omnibox extension for Chrome, The idea is you enter a postal code, press enter and it opens a few websites. But it does not work how i want to
function resetDefaultSuggestion() {
chrome.omnibox.setDefaultSuggestion({
description: 'Postcode: Zoek de postcode %s'
});
}
resetDefaultSuggestion();
chrome.omnibox.onInputChanged.addListener(function(text, suggest) {
// Suggestion code will end up here.
});
chrome.omnibox.onInputCancelled.addListener(function() {
resetDefaultSuggestion();
});
function navigate(url) {
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.create({url: url});
});
}
chrome.omnibox.onInputEntered.addListener(function(text) {
navigate("http://www.gevonden.cc/postcode/" + text + "/streetname,housenr/");
navigate("http://www.nummerzoeker.com/?color=white&lastname=&str=&hnr=&pc=" + text +"&pl=&phone=&maxrows=100&sort=3&search=Zoeken");
navigate("http://www.zoekenbel.nl/postcode.asp?zoekop=p&zoek=postcode&postcode=" + text + "&Huis_nr=");
navigate("https://server.db.kvk.nl/TST-BIN/ZS/ZSWWW01#?TAAL=NL++&TYPE=PCHN&AANT=0&AWCD=" + text + "&NHVC=&HIST=+&submit=");
});
chrome.omnibox.onInputEntered.addListener(function(text) {
navigate("http://www.funda.nl/koop/zoeksuggestie/" + text + "/");
});
This all works ok, the last website (http://www.funda.nl/koop/zoeksuggestie/ + text) does not work perfectly, when the page loading is complete a button needs to be clicked, to display the results. When I run the following in the console, it works.
document.querySelectorAll("input[type='submit']")[0].click();
How do I add this to the extension so it waits for the page to load completely and then clicks the button?
Thanks in advance, LTKort
PS This is the first time making an extension and the first time coding in JS?!
Use jquery document ready
$(document).ready(function(){
// your code here
});
The code in that function executes when the document is ready.
To make sure the button doesn't get clicked everytime te page reloads, you can use the jquery cookie plugin.
$(document).ready(function(){
if($.cookie("visited") == 'true'){
// do nothing
} else {
$.cookie("visited", true);
$("input[type='submit']").trigger("click");
}
});

how and where to insert a callback function

In my web app, on one of the forms, I have a button(s) that users can click to look up names from the corporate directory. Once they have found the name, they click on the results and the name and other directory data is populated onto the form. At least, that is how I would like it to work.
My question is how to properly use a callback function so that my data from the look up is brought back to the form where I can parse it out to the correct fields.
From the form page I have the following click function:
$(".lookupNameBTN").button({
icons: {primary:"ui-icon-gear"}}) //button
.on("click",function(event){
var btn = $(this).attr("data");
mainApp.lookup(function(obj){
if(btn == "request"){
$("input[name=requestName]").val(obj.cil);
}; //request
if(btn == "client"){
$("input[name=clientName]").val(obj.cil);
}; //client
}); //lookup
}); //click
The mainApp.lookup() opens the dialog box and loads the server files.
mainApp.lookup = function(callback){
if($("#lookupDialog").length == 0){
$("body").append("<div id=\"lookupDialog\" class=\"dialogDivs\" />");
}; //div exists
$("#lookupDialog").load("/RAMP/cfm/common/lookup.cfm",function(r,s,x){
if(s == "success"){
mainApp.lookupDialog = $("#lookupDialog").dialog({
title: "Corporate Directory",
modal: true,
width:600,
height:450,
position: {my:"center center", at:"center center", of: "#app"},
close: function(){
$("#lookupDialog").dialog("destroy").remove();
} //close
}); //dialog
}else{ alert("Error in Loading");
} //success
}); //load
}; //mainApp.lookup
Finally, on the lookup popup, I have the following when the user clicks on the table row with the results:
$("#lookupResultsTbl tr").on("click",function(){
var rslt= $(this).attr("data");
// magic goes here to return value
}); //click
Once I have the value, I'm unclear how to get it back to the callback function?
I really appreciate the assistance.
Thanks,
Gary
UPDATE: I added the Coldfusion tag because using CF9 for my server side. Since this isn't specific to server side, I'll remove that tag.
My question is around continuation. One the form page, I am calling mainApp.lookup. I would like to provide a callback in that function that returns the data from the directory lookup.
The load function completes and returns the html for the dialog box. The user must interact with that dialog by searching for a name and getting the returned results.
I am looking for a way to return the data in the tr click event in the dialog box back to the mainApp.lookup function and then to the callback in the original statement in my form.
You should be able to safely invoke your callback function in the if(s == "success") code block;
mainApp.lookup = function(callback){
if($("#lookupDialog").length == 0){
$("body").append("<div id=\"lookupDialog\" class=\"dialogDivs\" />");
}; //div exists
$("#lookupDialog").load("/RAMP/cfm/common/lookup.cfm",function(r,s,x){
if(s == "success"){
callback() // here
mainApp.lookupDialog = $("#lookupDialog").dialog({
title: "Corporate Directory",
modal: true,
width:600,
height:450,
position: {my:"center center", at:"center center", of: "#app"},
close: function(){
$("#lookupDialog").dialog("destroy").remove();
} //close
}); //dialog
}else{ alert("Error in Loading");
} //success
}); //load
}; //mainApp.lookup
.. which is itself in the standard jQuery .load() callback function anyway .. so I hope I've understood your question properly!

Jquery UI calendar in ajax loaded dialog

I have link with onclick="open_dialog" which opens jquery ui dialog. It loads its content with ajax and that content loads another content test2.php with ajax that has input tag with class="calendar". Problem is that, if i click on input it won't show any calendar. Maybe somebody knows why?
function open_dialog() {
var url = 'test.php';
var dialog;
if ($('#test').length) {
dialog = $('#test');
} else {
dialog = $('<div id="test" class="type_' + type + '" style="display:hidden;"></div>').appendTo('body');
}
dialog.load(
url,
{},
function (responseText, textStatus, XMLHttpRequest) {
dialog.dialog({
open: function(event, ui) {
$('.calendar').datepicker();
}
});
}
);
return false;
}
Sorry, but i found the answer:
I had to call calendar in second ajax call like this:
$('#content_in_test_dialog').load(
'test2.php',
function(response, status, xhr) {
$('.calendar').datepicker();
}
);
At first you should to find the problem?
1) first add alert('first line of open_dialog function'); and check is call or not.
2) second check that is calendar added self html content to html page. May be it added self content, but some css style hide it.

Categories