Isolating select2 version doesn't work - wordpress

I'm using Select2 on my WordPress plugin and I need to isolate the version I load in order to avoid conflicts with other plugins also using Select2.
I have found this answer by #Kevin Brown where he proposes to use save the select2 function into a variable just after being loaded and before removing it to avoid issues with other loads:
<script src="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.js"></script>
<script>
var myOwnSelect2 = $.fn.select2;
delete $.fn.select2;
</script>
The problem I have is that it works in edit-post.php pages, but not anywhere else. I mean, "select" tags/elements are being replaced on edit-post.php pages but not at my plugin settings page. The code on each page looks like this:
edit-post.php
HTML
<div class="myplugin-metabox">
...
<select name="_myplugin_item" class="searchable select2-hidden-accessible" data-placeholder="Select an item..." tabindex="-1" aria-hidden="true">
<option>...</option>
</select>
...
</div>
Javascript
myOwnSelect2.call( $('.myplugin-metabox select'), { dropdownAutoWidth: true, minimumResultsForSearch: Infinity } );
admin.php?page=myplugin
HTML
<div id="myplugin-settings">
...
<select id="option-1" name="myplugin-option-1" class="">
<option value="all">...</option>
...
</select>
...
</div>
Javascript
myOwnSelect2.call( $('#myplugin-settings select'), { dropdownAutoWidth: true, minimumResultsForSearch: Infinity } );
If I don't use any isolation method, everything within my plugin is working just fine... but I need the isolation because many other popular plugins load their own version/copy of Select2.
Javascript initializations are made on the same file. Keeping isolation, if I remove initialization for edit-post.php selects, selects on my plugin settings page doesn't get converted to Select2 dropdowns.
Any suggestion of what I might be doing wrong?
Thanks!

Well, I found the cause of the problem myself. I'm writing it here so it might be of help to others in my situation.
The thing was that I was referencing jQuery as "$", when I should have referenced it as "jQuery". Check out the code below:
Didn't work (in my case):
<script>
var myOwnSelect2 = $.fn.select2;
delete $.fn.select2;
</script>
Does work (in my case):
<script>
var myOwnSelect2 = jQuery.fn.select2;
delete jQuery.fn.select2;
</script>

Related

Controlling JS load order in Meteor with nested templates breaks with template.rendered?

I've got this template named indexmade up of a bunch of partial templates.
<template name="index">
{{> jumbotron }}
{{> crew }}
{{> projects3 }}
{{> projects2 }}
{{> faq }}
{{> contact }}
</template>
Say that I've got JS code page-transitions.js that requires the DOM of jumbotron to be fully loaded in order to run.
It's not enough to simple do:
Template.index.rendered = function(){
// load page-transitions.js
};
I HAVE to do
Template.jumbotron.rendered = function(){
// load page-transitions.js here instead
};
This can get messy really quick because you need to be VERY specific about which partial templates need which JS code. And different templates could require the same JS code so you can run into a situation where you're loading the same JS code multiple times.
Is there a way to wait until the index template has completely rendered EVERYTHING, including all nested child templates, and then run the JS code?
Meteor.startup() doesn't work in this case either.
You can try a couple of things:
First, just use the classic jQuery.ready way. because, why not?
Meteor.startup(function() {
$(document).ready(function() {
// stuff.
});
});
Or you could try Tracker.afterFlush:
Meteor.startup(function() {
// I know each Template.template.rendered has its own afterFlush, but those
// computations are defined way before Meteor.startup so then, theoretically,
// the below code should be executed last even if it triggers recomputations here.
Tracker.afterFlush(function() {
// stuff.
});
});

Getting started with effeckt.css - understanding the documentation?

I'd like to use some of the effects provided with Effeckt.css - buttons and off-screen nav. Looking at the source, I can see it's been neatly arranged to be modular.
I have cloned the project, but I don't really know how to get started as a user - the docs seem to be aimed at contributors.
Say I just want to include a button. I've tried copying the demo.autoprefixed.css and effeckt.autoprefixed.css files to my own project, and then done this:
<link rel="stylesheet" href="assets/css/m.autoprefixed.css">
<link rel="stylesheet" href="assets/css/effeckt.autoprefixed.css">
...
<div class="button-demo-wrap">
<button class="effeckt-button slide-left"><span class="label">Slide Left</span> <span class="spinner"></span></button>
</div>
This doesn't work, and it includes an awful lot of code I don't need for just one button. How do I get started with this project?
This seems to have to do with JavaScript.
I inspected the site, and it seems Effeckt.css is an CSS-Framework which needs a bit of Javascript to trigger the animations.
The following code (which is also in the JS-Fiddle) was found in the buttons.js which is referenced on their demo-site.
I have made a sample demo on how to use these buttons here:
http://jsfiddle.net/fc6ux/
The relevant part is following:
$('.effeckt-button').on( 'click', function(){
showLoader(this);
});
function showLoader(el) {
var button = $(el),
resetTimeout;
if(button.attr( 'data-loading' )){
button.removeAttr( 'data-loading' );
}
else {
button.attr( 'data-loading', true );
}
clearTimeout( resetTimeout );
resetTimeout = setTimeout( function() {
button.removeAttr( 'data-loading' );
}, 2000 );
}

Using a custom javascript script file with durandal template

I work on a Visual Studio 2012 MVC4 Project with the Durandal template. In this template, the shell.js page gives us a quite simple menu solution where every elements are located on top. Personally I need something different. For that purpose, I have a javascript file named dropdown.js which allows me to show/hide sub menus. It works pretty well in a standard project but I was not able to do it working with the durandal template.
Here is what I try:
I added a reference to the dropdown.js script in the Index.chtml:
<script src="~/Scripts/dropdown.js"></script>
Then in the shell.html page, I would like to use it like this:
<li class="dropdown" data-role="dropdown">
...
...
</li>
Here is a little portion of the dropdown.js:
$(function () {
alert('XXXX');
$('[data-role="dropdown"]').each(function () {
alert('YYYY');
$(this).Dropdown();
})
})
As you can see, each element decorated with the 'dropdown' class should have been catched. It doesn't work with durandal. I placed some alert boxes to check it. The alert 'XX' is showed but the alert 'YY' is never showed.
I searched a bunch of hours without success.
Any idea?
Check out the life cycle events tha tyou can tap into for Durandal here
viewAttached may help since you can tap into when the view and dom are ready.
I think the problem is that when the dropdown.js function is executed before the menu renders and because of that the jquery selector doesn't catch any list item.
I think that your best option is to make a knockout binding to transform your list items in dropdowns.
The binding would look something like:
ko.bindingHandlers.dropdown= {
init: function (element, valueAccessor, allBindingsAccessor) {
$(element).Dropdown();
},
update: function (element, valueAccessor) {
}
};
And in the view:
<li class="dropdown" data-bind="dropdown : {}">
...
...
</li>

Reactive updates not received in other browsertabs

Meteor promises reactive updates, so that views are auto-updated when data changes. The included leaderboard example demonstrates this. It runs fine when I test it: data is updated across several browsertabs in different browsers, as expected.
All set and go, I started coding with meteor and progress was being made, but when I tested for reactive updates across browertabs, I noticed that only after a short while the updates across tabs stopped.
I boiled down the problem to the following code, based on a new empty meteor project:
updatebug.html
<head>
<title>updatebug</title>
</head>
<body>
{{> form}}
</body>
<template name="form">
<form onsubmit="return false;">
{{#each items}}
{{> form_item }}
{{/each}}
</form>
</template>
<template name="form_item">
<div>
<label>{{name}}
<input type="text" name="{{name}}" value="{{value}}">
</label>
</div>
</template>
updatebug.js:
Items = new Meteor.Collection("items");
if (Meteor.is_client) {
Template.form.items = function () {
return Items.find();
};
Template.form_item.events = {
'blur input': function(e) {
var newValue = $(e.target).val();
console.log('update', this.name, this.value, newValue);
Items.update({_id: this._id}, {$set: {value: newValue}});
},
};
}
if (Meteor.is_server) {
Meteor.startup(function () {
if (Items.find().count() === 0) {
Items.insert({name: 'item1', value: 'something'});
}
});
}
Run in multiple browsertabs, start changing the value of the input in one tab. The other tabs will reflect the change. Goto the next tab and change the value. Repeat a couple of times.
After a while, no more updates are received by any other tabs. It seems that once a tab has changed the value, it does not receive/show any more updates.
Differences compared to the leaderboard example (since it's very similar):
The leaderboard uses no form controls
The leaderboard example does an increment operation on update, not a set
I am about to file a bug report, but want to be sure I am not doing anything stupid here, or missing an essential part of the Meteor Collection mechanics (yes, autopublish package is installed).
The issue here is input element preservation. Meteor will preserve the input state of any form field with an id or name attribute across a template redraw. The redraw is preserving the old text in your form element, because you wouldn't want to interrupt another user typing in the same field. If you remove the name attribute from the text box, each tab will update on blur.
In fact, I'm not sure why the first update works in your example. That may actually be the bug!
You can see it's not a data problem by opening the console in each browser. On each blur event you will get an updated document in every open tab. (Type Items.find().fetch())

Why wordpress thickbox not really showing for my theme upload option

I've stuck with this problem for more than 8 hours. I created an option panel for my wordpress theme and add an upload button for the upload logo option. I'm using wordpress thickbox. Everything almost done except the thickbox upload never showing only the thickbox overlay that is showing. I checked the source file and the .js file and stylesheet file was registered an enqueue correctly. Why the thickbox not showing? please help me!
here is my script use to call the thickbox via an input button
var fileInput = '';
jQuery('.upload_image_button').click(function() {
fileInput = jQuery(this).parent().prev('input.uploadfield');
//console.log(fileInput);
formfield = jQuery('#upload_image').attr('name');
post_id = jQuery('#post_ID').val();
tb_show('', 'media-upload.php?post_id='+post_id+'&type=image&TB_iframe=true&width=640&height=105');
return false;
});
window.original_send_to_editor = window.send_to_editor;
window.send_to_editor = function(html){
if (fileInput) {
fileurl = jQuery('img',html).attr('src');
fileInput.val(fileurl);
tb_remove();
} else {
window.original_send_to_editor(html);
}
};
and here is my input button code for upload
<input id="" class="uploadfield" type="text" value="" name="" size="50" maxlength="2048">
<div class="upload_buttons">
<input class="upload_image_button" type="button" value="Upload">
</div>
I found the real problem, since I'm using jQuery() in my jquery files instead of $ my code having a conflict with the wordpress built in jquery. so I have to register new jquery with the same name 'jquery' without deregister the wordpress build in jquery.
After I change the sign then I can use the wordpress build in jquery wihout registering new jquery and the thickbox work normally. hope this can help somebody with the same problem. thanks

Resources