Opening multiple jQueryUI dialogs - jquery-ui

I wish to open multiple jQuery dialogs, one after the other. But only the first one opens.
jsFiddle
Dlg 1 -- Presents a YES / NO question.
Dlg 2 -- If YES, stick the word "go" into the hidden field id="frmtrig" and then trigger a change event. When this event is caught, it runs AJAX to populate the $('#message') div with html received via ajax success function, and then displays that in a dialog.
Dlg 3 -- After closing, present one final dialog.
Below code breaks at step 2. The alert('bonk') doesn't even happen...
I also deleted everything between alert('bonk') and the closing } of the success function, and the bonk alert still does not display. Can anyone spot a problem with my AJAX code?
Oddly, I've done a ton of (relatively simple) AJAX, so I'm puzzled that I'm getting stuck here. Note that it might be necessary to copy/paste my code blocks into two or 3 files on your own server to test this out, since jsFiddle won't work for troubleshooting AJAX.
I have been unsuccessful finding an example of doing this, and my own efforts over the past two days have not worked.
HTML
<div id="hot_link">Hover over this line to begin it all</div>
<div id="message"></div>
<div id="alert"></div>
<input type="hidden" id="frmtrig">
JAVASCRIPT
$(function(){
var cnt = 0;
var ans = 0;
var seen = 0;
var dlg = $('#message');
dlg.dialog({
title: '"The Big Test',
autoOpen:false,
modal:true,
width: 500,
close: function() {
if (seen==0 && ans > 0) {
cnt++;
seen++;
dlg.dialog('open');
}
}
});
$('#hot_link').hover(
function() {
//Hover-in
if (cnt < 1 || (cnt % 3 == 0)) {
var msg = '<p>If you say NO, the Dialog will just close. If you press YES, an AJAX call will happen.</p>';
dlg.html(msg);
dlg.dialog(
'option',
'buttons',
[{
text: 'Download',
click: function() {
ans++;
//seen = 5;
$('#frmtrig').val('go').change();
$(this).dialog('close');
}
},
{
text: 'Not now',
click: function() {
ans = 0;
$(this).dialog('close');
}
}]
);
dlg.dialog('open');
//alert('hi');
}
cnt++;
},
function() {
//Hover-out
//need this one to prevent duplicating hover-in code
}
);
$('#frmtrig').change(function() {
alert('boink');
$.ajax({
type: "POST",
async: false,
url: "ajax/ax_all_ajax_fns.php",
data: 'request=freegive_99',
success:function(data){
alert('bonk');
alert(data);
var dlg = $('#message');
alert('me be here');
dlg.html(data);
dlg.dialog(
'option',
'buttons',
[{
text: 'OK',
click: function() {
$(this).dialog('close');
}
}]
);
dlg.dialog('open');
}
});
});
}); //END document.ready
AX_ALL_AJAX_FNS.PHP
if ($_POST['request'] == 'freegive_99') {
echo 'THIS_LINE_WORKS';
}

I have tried your code on my machine and it is working fine.
If the second dialog is not opened, it means that success in your ajax request is not reached.
Are you sure that the problem doesn't come from a wrong path?
url: "ajax/ax_all_ajax_fns.php", // Check this path

Related

jQuery UI Autocomplete perform search on button click issues

I have a working UI Auto complete with jQuery. I wanted to change the way it worked. Instead of a new browser tab opening with the user selects a value from the list I wanted the user to first pick a value then click a search button to trigger the event.
It works but if you perform a search and then a second search it will trigger the previous URL and new URL at the same time. Also if you perform a search then click the search button without typing anything into the search input it triggers the previous search. Weird right? I'll add my code but I think a codepen example will help clarify what I mean.
The other issue I was having is I am trying to set up a custom alert if the value typed is not in the array but I get the invalid error message no matter what I type. I added that as well in the code. It is one of the if statements.
JS
var mySource = [
{
value: "Google",
url: "http://www.google.com"
},
{
value: "Yahoo",
url: "https://www.yahoo.com"
},
{
value: "Hotmail",
url: "https://hotmail.com"
},
{
value: "Reddit",
url: "https://www.reddit.com"
}
];
//Logic for ui-autocomplete
$(document).ready(function() {
$("input.autocomplete").autocomplete({
minLength: 2,
source: function(req, resp) {
var q = req.term;
var myResponse = [];
$.each(mySource, function(key, item) {
if (item.value.toLowerCase().indexOf(q) === 0) {
myResponse.push(item);
}
if (item.value.toUpperCase().indexOf(q) === 0) {
myResponse.push(item);
}
//Add if statement here to determine if what the user inputs is in the
// array
//and if not in the array give an error to #textAlert.
//Example
if (item.value.indexOf(q) != myResponse) {
$('#alertText').text("Invalid Search");
} else {
return false;
}
});
resp(myResponse);
},
select: function(event, ui) {
$('#appSearchBtn').one("click", function() {
window.open(ui.item.url);
$('#appsearch').val('');
return false;
});
}
});
});
//Input and ui text clears when clicked into
$(document).ready(function() {
var input = document.querySelector('#appsearch');
var ui = document.querySelector(".ui-helper-hidden-accessible");
input.onclick = function() {
input.value = '';
ui.textContent = '';
};
});
HTML
<p id="alertText"></p>
<div class="input-group">
<input type="text" id="appsearch" class="form-control autocomplete" placeholder="Application Search" />
<span class="input-group-btn">
<button class="btn btn-primary inputBtn" id="appSearchBtn" type="button">Search</button>
</span>
</div>
Here is a Code pen https://codepen.io/FrontN_Dev/pen/MEmMRz so you can see how it works. I also added how it should work and what the bugs are.
9/29/17 #0732
I resolved the issue with the event firing the same URL over and over but I still need help with the custom invalid search message that appears for every search even if the value is in the array.

Rails / Trix Editor save changes via AJAX to server

I am using the very simple to implement Trix Editor provided from Basecamp in an "Edit View".
How would one save automatically changes, without having the user to interact through the update button?
I am thinking about something like this:
(OLD SCRIPT)
window.setInterval(function() {
localStorage["editorState"] = JSON.stringify(element.editor)
}, 5000);
What I actually want to do:
post a ajax "post" request to the rails server. something like:
$('trix-editor').on('blur', function() {
var sendname = $('#note_name').val();
var sendlink = $('#linkinput').val();
var sendnote = $('input[name="note[note]"]').val();
$.ajax({
type: "POST",
url: "/notes",
data: { note: { name: sendname, link: sendlink, note: sendnote } },
success: function(data) {
alert(data.id);
return false;
},
error: function(data) {
return false;
}
});
(There is as well the problem with authentification and devise. Only if you are loged in you should be able to send an ajax post request ..??)
Even better would be to save changes only when the user changes some data, and then wait 5s and then push the updated data via json to the server. I have no clue how to do that...
PS: would have loved to tag this question with a "trix-editor" tag, sorry have not enought rep for doing so...
If you are using plain JavaScript, use a hidden input field:
<form>
<input type="hidden" id="noticeEditorContent"/>
<trix-editor input="noticeEditorContent" id="x" style="min-height: 200px;"></trix-editor>
</form>
Now you have access to the element with the ID x.
Which means, with getElementById, you can do something like that:
var richTex = document.getElementById("x");
With this variable, you can either set an interval as you already explained, or you are using jQuery to do the job:
$('#x').on('input', function() {
localStorage["editorState"] = JSON.stringify($('#x').val());
});
Just a suggestion. You can write this code a bit nicer and cleaner.
Now it depends. Is setting an interval every 5 seconds better or writing every change to the LocalStorage?
Suggestion:
Save the input when the user deselects the field:
$('#x').on('blur', function() {
localStorage["editorState"] = JSON.stringify($('#x').val());
});
Update: Here is a working JSFiddle.
so I came up with this code which saves via ajax on 'trix-blur' (which fires when the user disselects the trix-editor). There is only the question left if this code is secure enought with devise, or if now anyone can send data to be saved?!?
I have the authentification in the notes controller like that:
before_action :authenticate_user!
and here is the javascript part (with a custom messages functionality):
$('trix-editor').on('trix-blur', function() {
var sendname = $('#note_name').val();
var sendlink = $('#linkinput').val();
var sendnote = $('input[name="note[note]"]').val();
var sendid = $('#note_id').val();
$.ajax({
type: "PUT",
url: "/notes/" + sendid,
dataType: "json",
data: { note: { name: sendname, link: sendlink, note: sendnote }, id: sendid, commit: "Update Note" },
success: function(data) {
addMessage('auto saved ...', 'msg-success');
return false;
},
error: function(data) {
alert('error');
return false;
}
});
var addMessage = function(msg, msgclass) {
$('#notifications').append('<div id="msg" class="msg '+msgclass+'">'+msg+'</div>');
setTimeout(function() {
$('#msg:last-child').addClass('msgvisible');
}, 100);
displayMessage();
};
var displayMessage = function() {
setTimeout(function() {
hideMessage();
}, 2000);
};
var hideMessage = function() {
$('#msg').addClass('msghide');
setTimeout( function() {
deleteMessage();
}, 300);
};
var deleteMessage = function() {
$('#msg').remove();
if ($('#notificatosn').find('#msg') > 1) {
displayMessage();
}
};
});
Per the Trix project page the trix-editor emits different events on specific conditions.
The trix-change event is what you need; it fires whenever the editor’s contents has changed.
So, the first line of your JavaScript code could be
$('trix-editor').on('trix-change', function() {
/* Here will be your code to save the editor's contents. */
})

jQuery UI Tooltip delayed loading

When hovering over a link, I'd like to wait at least a second before showing a tooltip with dynamically loaded tooltip.
What I've created is the follow jQuery Code:
$(document).ready(function () {
$("div#galleries ul li:not(.active) a").tooltip({
items: "a",
show: { delay: 1000 },
content: 'Loading preview...',
open: function (event, ui) {
previewGallery(event, ui, $(this));
}
});
});
function previewGallery(event, ui, aLinkElement) {
event.preventDefault();
ui.tooltip.load("http://www.someurl.com/Preview.aspx #preview");
}
Which seemed to work pretty fine, you can see it here:
http://fotos.amon.cc/ (simply hover over the list of galleries)
But I didn't realize at the beginning, that the loading of preview text happens immediately when hovering over the link. So if you quickly hover over all the links, you'll set up several requests:
From the users point of view (without knowing that requests are fired) it looks already the way I want, but how to only start loading the preview, when tooltip is actually showing up?
Thanks,
Dominik
What I did in the end was to use window.setTimeout and window.clearTimeout:
var galleryToolTipTimer = null;
var previewElement = null;
$(document).ready(function () {
$("div#photos div a img").tooltip();
$("div#galleries ul li:not(.active) a")
.tooltip({ items: "a", content: 'Loading preview...', disabled: true, open: function (event, ui) { previewElement.appendTo(ui.tooltip.empty()); } })
.mouseover(function (e) {
if (galleryToolTipTimer != null) { window.clearTimeout(galleryToolTipTimer); }
var aLinkObject = $(this);
galleryToolTipTimer = window.setTimeout(function () { previewGallery(aLinkObject); }, 500);
}).mouseleave(function (e) {
window.clearTimeout(galleryToolTipTimer);
$(this).tooltip("option", { disabled: true });
});
});
function previewGallery(aLinkElement) {
previewElement = $("<div/>").load(aLinkElement.closest("div").data("galleryPreview") + "/" + aLinkElement.data("path") + " #preview", function () {
aLinkElement.tooltip("open");
});
}
Works at least the way I want.
To see it in action, simply navigate to http://fotos.amon.cc/ and hover over one of the gallery links on the left for a preview:

jQuery UI Dialog Will Not Close

Given the following script:
$(function () {
$(".editLink").button();
$('#editPersonDialog').dialog({
autoOpen: false,
width: 800,
resizable: false,
title: 'Edit Person',
modal: true,
buttons: {
"Save": function () {
$("#update-message").html('');
$("#updatePersonForm").submit();
},
"Close": function () {
$(this).dialog('close');
}
},
close: function (event, ui) {
$(this).dialog('close');
}
});
$(".editLink").click(function () {
var dialogDiv = $('#editPersonDialog');
var linkObj = $(this);
var viewUrl = linkObj.attr('href');
$.get(viewUrl, function (data) {
dialogDiv.html(data);
//validation
var $form = $("#updatePersonForm");
// unbind existing validation
$form.unbind();
$form.data("validator", null);
// check document for changes
$.validator.unobtrusive.parse(document);
// re-add validation with changes
$form.validate($form.data("unobtrusiveValidation").options);
// open dialog
dialogDiv.dialog('open');
});
return false;
});
});
function updateSuccess() {
if ($("#update-message").html() == "True") {
$('#editPersonDialog').dialog('close');
$("#commonMessage").html("Update Complete");
$("#commonMessage").delay(400).slideDown(400).delay(3000).slideUp(400);
}
else {
$("#update-message").show();
}
}
If I click the "X" button on the dialog the form closes fine. If I click the "Close" button then it does not close. I have verified that the code for the "Close" button is being called.
Both the "X" button and the "Close" button are both running the same statement: '$(this).dialog('close');'. Why would one work and the other not work?
As an aside the dialog will not open a second time unless I refresh the page. I imagine that these 2 problems may be related.
I have found many people with similar problems and a number of different solutions that worked for them. Unfortunately none of them worked for me.
Further Info:
The dialog displays a partial view in an Ajax form:
#using (Ajax.BeginForm("Edit", "Person", null,
new AjaxOptions
{
UpdateTargetId = "update-message",
InsertionMode = InsertionMode.Replace,
HttpMethod = "POST",
OnSuccess = "updateSuccess"
},
new { #id = "updatePersonForm" }))
{
#Html.ValidationSummary(true)
<div id="update-message" class="hiddenDiv"></div>
<div class="blockGraygradient">
#Html.Partial("_CreateEditCommon")
#Html.HiddenFor(model => model.SelectedPerson.Id)
#Html.HiddenFor(model => model.SelectedPerson.RowVersion)
#Html.HiddenFor(model => model.SelectedPerson.CreateTime)
</div><p/>
}
Try using this instead.
$(this).dialog('destroy');
We had exactly the same problem. In the end, every time you re-opened the dialog it was actually re-injecting the dialog markup into the DOM. Then, when you click close (for the second time) it only closes the first occurrence of the dialog, but not necessarily the one that's open. You can check this using a run-time DOM inspector like FireBug or Chrome's built-in developer tools.
I found out that the cause of both problems (the close button not working and being unable to show the dialog more than once without refreshing the page) was that I had included references to my script files in both my main page and the partial view being displayed by the dialog. Once I removed the script references from the partial view the problems disappeared.
(As an aside this has now raised another problem to do with an Ajax update back onto the main page when the dialog is closed. I think this is the reason that I put the scripts into the partial view in the first place).
You have too much recursion. You don't need to subscribe to the close event of your jQuery dialog and invoke $(this).dialog('close'); inside it. Simply comment this line or remove completely the close event subscription:
$('#editPersonDialog').dialog({
autoOpen: false,
width: 800,
resizable: false,
title: 'Edit Person',
modal: true,
buttons: {
"Save": function () {
$("#update-message").html('');
$("#updatePersonForm").submit();
},
"Close": function () {
$(this).dialog('close');
}
}
});

jQuery UI dialogs: how to close dialog when click outside?

In docs I didn't see such information.
There are options to close dialog in such cases:
1) push Esc;
2) click on "OK" or "Close" buttons in the dialog.
But how to close dialog if click outside?
Thanks!
Here are 2 other solutions for non-modal dialogs:
If dialog is non-modal Method 1:
method 1: http://jsfiddle.net/jasonday/xpkFf/
// Close Pop-in If the user clicks anywhere else on the page
jQuery('body')
.bind(
'click',
function(e){
if(
jQuery('#dialog').dialog('isOpen')
&& !jQuery(e.target).is('.ui-dialog, a')
&& !jQuery(e.target).closest('.ui-dialog').length
){
jQuery('#dialog').dialog('close');
}
}
);
Non-Modal dialog Method 2:
http://jsfiddle.net/jasonday/eccKr/
$(function() {
$( "#dialog" ).dialog({
autoOpen: false,
minHeight: 100,
width: 342,
draggable: true,
resizable: false,
modal: false,
closeText: 'Close',
open: function() {
closedialog = 1;
$(document).bind('click', overlayclickclose);
},
focus: function() {
closedialog = 0;
},
close: function() {
$(document).unbind('click');
}
});
$('#linkID').click(function() {
$('#dialog').dialog('open');
closedialog = 0;
});
var closedialog;
function overlayclickclose() {
if (closedialog) {
$('#dialog').dialog('close');
}
//set to one because click on dialog box sets to zero
closedialog = 1;
}
});
I found solution on ryanjeffords.com:
<script type="text/javascript">
$(document).ready(function() {
$("#dialog").dialog();
$('.ui-widget-overlay').live("click",function(){
$("#dialog").dialog("close");
});
});
</script>
If dialog is modal, then paste these 3 lines of code in the open function when you create your dialog options:
open: function(event,ui) {
$('.ui-widget-overlay').bind('click', function(event,ui) {
$('#myModal').dialog('close');
});
}
Facing the same problem, I have created a small plugin that enables to close a dialog when clicking outside of it whether it a modal or non-modal dialog. It supports one or multiple dialogs on the same page.
More information on my website here: http://www.coheractio.com/blog/closing-jquery-ui-dialog-widget-when-clicking-outside
The plugin is also on github: https://github.com/coheractio/jQuery-UI-Dialog-ClickOutside
Laurent
This is my solution.
I have, for example
<div id="dialog1">Some content in here</div>
<div id="dialog2">Different content in here</div>
<div id="dialog3">And so on...</div>
Each div gets opened as a dialog depending on what the user interacts with. So being able to close the currently active one, I do this.
// This closes the dialog when the user clicks outside of it.
$("body").on('click', '.ui-widget-overlay', function() {
if( $("div.ui-dialog").is(":visible") )
{
var openDialogId = $(".ui-dialog").find(".ui-dialog-content:visible").attr("id");
if ($("#"+openDialogId).dialog("isOpen"))
{
$("#"+openDialogId).dialog('close');
}
}
});

Resources