So the code below is called when a user selects Save on an ExtJS popup modal window. This window ONLY contains a combobox. Now, sometimes when a user saves this, and then re-opens it later on, the combobox will appear BEHIND the window all grayed out, unable to get to. Other times, it will be fine and work, and no difference in events happening either time, just complete utter inconsistency.
Does anyone know what this could be?
var changeProductOK = function() {
var win = getChangeProductWindow();
if (win.subProductId.getValue() == '') {
Global.alert('Choose a product');
return;
}
win.hide();
PropertiesWin.hide();
Global.confirm('You sure?', 'Confirm', function(result) {
if (result) {
Global.mask('Changing the product', workspacePanel.getEl());
WorkspaceController.ChangeProduct(applicationId, win.subProductId.getValue(), function(response) {
Global.unmask(workspacePanel.getEl());
if (!response) {
showWorkflowMessages([{ Type: 0, Text: 'A timeout occurred while changing the product. Please try again.'}]);
return;
}
if (response.Data.Result == false) {
showWorkflowMessages(response.Data.Messages);
} else {
Global.mask('Reloading the application');
reloadWorkspace();
}
});
}
win.subProductId.setValue('');
});
}
The problem has to do with some kind of bug involving the z-indexes. I just fixed it by making sure the z-index was a bit higher than the window by adding:
<style>
.x-combo-list {z-index: 10000 !important} /* A hack to fix superboxselect dropdowns showing up behind window */
</style>
Not beautiful, but it works.
I'm answering for how I get around this, but feel free to post other answers before it lets me accept this one if you know of a common way to prevent this from happening.
I placed
win.close();
right after
win.subProductId.setValue('');
That way it destroys the modal everytime a successful save completes and therefore it will always load up as the initial window (which worked everytime)
Related
Being semi-JS illiterate, I am unable to write my own code—can I get some help here?
What I am trying to do: stop a page from showing content until after a 3-second forced refresh.
I have a HubSpot thank-you page that shows personalized data based on a form filled on the previous page (I know I can customize the HubSpot JS code to do this, but since the page is already built, I cannot place custom form code.) The problem is that the personalization data doesn't come in until well after the page loads (so users see the default values first).
I've got some JS code that forces the refresh after 3 seconds, but I cannot figure out how to coordinate hiding the default content until that forced-refresh:
console.log(document.referrer);
console.log(document.location.href);
if (document.referrer !== document.location.href) {
setTimeout(function() {
document.location.reload()
}, 3000);
}
I tried adding this CSS: body { opacity: 0; }, along with this JS: document.body.style.opacity="100";
... by adding it after the setTimeout, by adding it after the the document reload, and by adding it as a new function to the reload. The best result was a flash of visible content at 3 seconds, then all content gone permanently.
I then just decided to write a whole separate setTimeout function outside the IF statement (in the hopes that it would just sync), but it still just shows blank content to everyone:
window.onload = function() {
setTimeout(function(){
document.body.style.opacity="100";
},3000);
};
I am sorry that I don't know enough about JavaScript to paint my way out—can anyone help me get closer to the correct way to hide content until a force-refresh?
This is my final code—at least it seems to work:
<style>
#hs_cos_wrapper_widget { opacity: 0; }
</style>
<script>
function showContent() {
document.getElementById("hs_cos_wrapper_widget").style.opacity = "1";
}
setTimeout("showContent()", 4000);
console.log(document.referrer);
console.log(document.location.href);
if (document.referrer !== document.location.href) {
setTimeout(function() {
document.location.reload();
}, 3000);
}
</script>
The only thing I don't like is that the page now takes more than 9 seconds to load (a preloader would be nice.) A more elegant solution is more than welcome.
I'm using jQuery to show tooltips on every link on my page that has a 'details' attribute
$(function() {
$tooltip = $(document).tooltip({
show: false,
track: true,
items: "a[data-details]",
content: function() {
return $( this ).data('details');
}
});
});
This works very well. However, when the user clicks one of those links, the URL is opened in a new tab (using target="_blank"). The problem is that the tooltip is still open when the user gets back on the first tab.
Here's what I tried so far:
$('a[data-details]').on('click mousedown mouseup', function() { // this might be overkill
$(document).tooltip("close"); // Doesn't work at all
$('div[class^="ui-tooltip"]').remove(); // removes the tooltip onclick, but gets it back opened when returning on the tab
});
Is there a way to keep the tooltips closed when the new page is opened?
Thank you for your help.
Here's a fiddle illustrating the problem: https://jsfiddle.net/su4v757a/
Note: I'm using jQuery 1.12.4 with jQueryUI 1.12.1
This is probably a bug.
As far as I can tell this must be a bug.
And you could let them know over at https://bugs.jqueryui.com/report/10?P=tooltip
I notice that the .tooltip("close") doesn't work in the fiddle. However the tooltip listens to the "mouseleave"-event to close, and we can force that by $('a[data-details]').trigger("mouseleave");
If you try this out you will see that it do close, but pops up again:
$('a[data-details]').on('click mousedown mouseup', function() { // this might be overkill
$(this).trigger("mouseleave");
});
Hover and click the "me":
Coming back to the page notice that the tooltip has closed and come back again:
Workaround - possible solution
Since .hide()-ing an element triggers the "mouseleave"-event you could do something funky like hiding the link on click, and showing it just a moment later.
$('a[data-details]').click(function() {
var $this = $(this);
$this.hide();
setTimeout(function() {
$this.show()
}, 1);
});
Setting the timeout to 1 ms would not create any flickering of the link, making the hide/show unnoticeable for the user.
Works in Chrome. Try it here: https://jsfiddle.net/cyx6528e/1/
Good luck!
tooltip usually works on hover functionality, can you provide js fiddle for your problem
I'm trying to optimize my Wordpress install - and one of the culprits I'm seeing, is the "Pin It" button widget for Pinterest. I'm now trying to find a way to dynamically load the JS code (when they initially hover over the button), and then apply it to the page. So far I've only managed to get this far:
jQuery(document).on("mouseenter click",'.pinItSidebar', function() {
jQuery.getScript("http://assets.pinterest.com/js/pinit_main.js", function() {
// do something here?
});
});
I can't seem to find a function that I can call (as a callback, after the JS is loaded). Obviously I will only do this once per page load (the above is just a very basic version at the moment)
Does anyone have any suggestions on how I can achieve this? The end game of how I want it to function, is with:
Working solution:
Here is a working solution I've now got, which will allow you to load the pinterest stuff ONLY when they click the button (and then trigger the opener as well). The idea behind this, is that it saves a ton of Pinterest JS/CSS / onload calls, which were slowing the page down.
jQuery(document).on("click",'.pinItSidebar', function() {
if (typeof PinUtils == "undefined") {
jQuery.getScript("http://assets.pinterest.com/js/pinit_main.js", function() {
PinUtils.build();
PinUtils.pinAny();
});
} else {
PinUtils.pinAny();
}
});
...and just call with:
foo
Hopefully this helps save someone else some time :)
Extra tweak: I'm just playing around, to see if I can make this even more awesome :) Basically, I want to be able to decide which images are pinnable. Below this will do that for you:
jQuery("img").each(function() {
if (jQuery(this).data('pin-do')) {
// its ok, lets pin
} else {
jQuery(this).attr('nopin',"1");
}
});
All you need to do to make an image pinnable, is have the data-pin-do="1" param set the images you want to allow them to share :)
This is probably basic to most reading, but I can't seem to figure it out.
I have a little test function that I want to execute if under a certain width. When the screen rotates or gets resized above that width, I want the function to cease to work. Here is some example code for simplicity sake.
enquire.register("screen and (max-width:500px)",{
match : function() {
$(".block .block-title").click(function(){
alert("Hello World!");
});
}
}).listen();
So if the page loads above 500px, it works as intended. Clicking won't execute. If the page loads at 500px or below, the click function executes. Only problem is that if you resize the viewport or change orientation to something above 500px, the function still executes. I'd like to be able to disable that.
The real world scenario I'm actually trying to do here is I have an un-ordered list of 4 items. Above a certain width they are displayed right away. If under a certain width, I just want to hide them and on click show them. I know there are a few ways to do it (.toggle(), .toggleClass("myclass"), etc).
I have done this a bunch of times but I always get caught with the entering / exiting break points and things not being reset, or working as intended. Usually it doesn't matter, but lately in some of my use cases it has mattered.
I know of the unmatch option but I'm not sure how to really kill the matched function above.
enquire.register("screen and (max-width:500px)",{
match : function() {
$(".block .block-title").click(function(){
alert("Hello World!");
});
},
{
unmatch : function() {
// what do I do here do kill above?
}
}
}).listen();
Any help would be appreciated. I am pretty sure it will help my current situation but will also help me expand my knowledge of enquire.js for other things.
Thanks.
edit: I forgot to mention... if you load the page under 500px, then resize or orientate wider then 500px, then go BACK under 500px, the click function won't work again.. which confuses me also. I basically was hoping it would work no matter what when under 500px, and not work at all when over 500px.
I'm the author of enquire.js, so hopefully I'll be able to help you ;-)
Basically, you want to add an event handler on match and remove event handler on unmatch. You seem to have the gist of how to do this above, but you've got the syntax a little wrong. Once the syntax is corrected it's just some jQuery knowledge to remove the click handler.
So let's look at how the syntax should be:
enquire.register("screen and (max-width:500px)", {
match: function() {
//match code here
},
unmatch: function() {
//unmatch code here
}
}).listen();
Notice that match and unmatch are part of a single object supplied to register.
Ideally you should be putting this in your document ready callback. To assign your click handler use jQuery's on method, as this allows you to use the off method to unassign:
$(".block .block-title").on("click", function() {
alert("hello");
});
$(".block .block-title").off("click");
This is great because you can even namespace your events, read up on the jQuery docs for more details on this. So to put it all together, we would have this:
$(document).ready(function() {
var $target = $(".block .block-title");
enquire.register("screen and (max-width:500px)", {
match: function() {
$target.on("click", function() {
alert("Hello World!");
});
},
unmatch: function() {
$target.off("click");
}
}).listen();
});
You can find a working example here: http://jsfiddle.net/WickyNilliams/EHKQj/
That should then be all you need :) Hope that helps!
Update: I still haven't figured this out, but saw Jquery - Jeditable: How Reset to non-editable without page refresh which looks similar to what I'm wanting to do. Tried to incorporate it but am not sure I'm doing it correctly since it is taking 2 clicks (or 2 ctrl-clicks) for it to behave in the way I'm expecting.
$("div.wanttoedit").click(function(e){
if (e.ctrlKey) {
$('div.wanttoedit').addClass('non_edit').removeClass('edit').unbind('click.editable');
alert('Ctrl was pressed');
} else {
alert('Ctrl was NOT pressed');
$('div.wanttoedit').addClass('edit').removeClass('non_edit');
$('.edit').editable('http://#request.host#/vp/metrics.cfc?method=updateMetrics&returnformat=plain');
}
});
<div id="#results.id#" class="wanttoedit non_edit">#val(value_disp)#</div>
Again, any help is mightily appreciated. Thanks.
I'm still very new to jquery/javascript/jeditable so please be kind and as explicit as possible. :)
I have a table with row labels = Metric Name and column labels = Months. The cells contain the corresponding metric values. I want to be able to single left-click and have the metric value be editable but also be able to ctrl-click (or right-click, shift-click or other) and be able to enter a reason why the metric was missed (if it was). These two things are updated in two different tables in my database, but both are linked back to the metric_id/name and timeframe/month they are associated to.
I have been able to get the single left-click editing of the metric value working through jeditable but I have been unsucessful so far in finding a way to make the field also allow the other-click pop-up of a dialog box to enter the miss information.
Any help would be sincerely appreciated especially if you can make it easy to understand for this rather simple girl.
I'm using Coldfusion (not sure if that is necessary knowledge, but thought I'd mention it just in case) and can provide any code snippets as necessary to allow you to help me get this fixed.
Here is a sample of my code, I'm using jquery tabs, so the editable is in a rather different place than usual (hopefully I'm including everything you need to see...if not just let me know what I might be missing)
$(document).ready(function() {
$("#cymteamtabs").tabs( {
cache: false,
load: function(event,ui) {
$(".editMetric").editable("http://#request.host#/vp/metrics.cfc?method=updateMetrics&returnformat=plain");
},
ajaxOptions: {cache: false}
}
);
<cfloop query="metrics">
<tr>
<td>#metrics.mdisplay#</td>
<cfloop query="dates">
<td id="#results.id#" class="editMetric">#val(value_disp)#</td>
</cfloop>
</tr>
</cfloop>
Oh and just to make sure I was clear on what I want it to do....if I ctrl-click on the field, the pop-up would appear allowing the entry of the miss info (the editing is disabled). Once that dialog is closed, if I left-click on the field it would enable editing of that field so, basically I don't want to ever turn off jeditable completely, I just want it to go into hibernation mode between the time that the user ctrl-clicks on the field and when the dialog box that pops-up because of that is closed.
Thanks in advance.
I'm not certain that this is the best way to do this, nor am I positive that it is doing exactly what I want it to do, but it so far appears to work.
$(document).ready(function()
{
$("#cymteamtabs").tabs(
{
cache: false,
ajaxOptions: {cache: false},
load: function(event,ui)
{
$(".editMetric").click(function(e) {
if (e.ctrlKey) {
var metric_id = $(this).attr('data-metric-id');
var date_type = $(this).attr('data-date-type');
var value_date = $(this).attr('data-value-date');
var url_tf = 'cym';
var url_view = 'edit';
scorecards.display.miss_details(metric_id,date_type,value_date,url_tf,url_view);
e.stopImmediatePropagation();
}
});
$(".editMetric").editable("http://<cfoutput>#request.host#</cfoutput>/vp/metricCFComponents.cfc?method=updateMetrics&returnformat=plain");
}
});
});
This appears to check first for the ctrl-click and if it is pressed, then the non-jeditable code runs and the e.stopImmediatePropagation(); appears to not allow the jeditable code below it to run.
The only way I can think of sorting this is a little bit of a hack.
There doesn't seem to be anyway of running a conditional on the event so what I propose is setting two event types and switching between them when ctrl is pressed
The problem is the event types - unbinding them seems a bit excessive.
The best option would be to set the editable element as the <td /> as you have but have a separate element (like a span) as the trigger.
To continue with your current html you could try this:
$('.editMetric').editable('url1', {
event: "nrmlClick"
}).editable('url2', {
event: "ctrlClick"
}).bind('toggleClick', function(e) {
if (e.ctrley) {
/* modal javascript here */
$(this).trigger('ctrlClick')
} else {
$(this).trigger('nrmlClick')
}
});
I don't have the facilities to test this properly but this should work.
I've never made up event names before so I don't know how good an idea that is (hopefully someone can enlighten us) but I can't see the harm right now.
Hope that helps!