Delete a DOM element and its associated jquery plugin and data - javascript

First, I'm using a jquery plugin on an element, lets say $('#myElement').usePlugin();.
Second, I want to destroy the original element and any plugin variables etc that may still exist in JS.
Third, create a new #myElement and redo $('#myElement').usePlugin();.
I'm having trouble with step #2. When I do $('#myElement').remove(), there is residual strange behavior when I recreate the element and instantiate the plugin.
FYI: this is the plugin I'm having trouble with: http://mindmup.github.io/editable-table/. If I create a table, make it editable, everything works fine.
But then if I delete the table, recreate the table, make it editable, I get strange behavior where fields are editable, but when I hit "enter", the value does not save and I get this error Uncaught TypeError: Cannot read property 'trigger' of undefined.

I would modify this line in the plugin:
https://github.com/mindmup/editable-table/blob/master/mindmup-editabletable.js#L115
to:
$(window).on('resize.mindmup', function () {
Now, when you want to remove that event, remove it by namespace.
$(window).off("resize.mindmup");
Continue removing and re-creating the table, then use the above line to remove the window resize event before re-initializing the plugin.

Related

Rerender Dynamic Elements when using jQuery Plugin Selectize and Bootstrap-Switch

I am new to jQuery so please go easy, I have a form that will represent an Advanced Search. Users will be able to add rows to refine their specific search.
Each row has 3 elements: A Checkbox & 2 x Select boxes.
As can be seen in the fiddle I am using jquery to clone the row and place the cloned row after the last row.
Everything is working fine except visually I would like the checkbox to use Bootstrap-Switch http://www.bootstrap-switch.org/
And the select boxes to use Selectize https://github.com/brianreavis/selectize.js
Now, when I clone the row with these plugins not active, everything works.
I have NO idea how to re-render or re activate them once a new row is inserted.
Is this something that is plugin specific? Or kind of universal to jquery?
I have read HEAPS of answers on here about similar things but I cannot seem to get it right.
Here is the jquery snippet:
$adSearchForm = $('#adSearchForm');
$adSearchForm.on('click', 'button, input, select, option', function (event) {
console.log("Button Clicked", event)
});
$('#addSearchRow').click(function(event){
$('[data-content=adSearch-3]:first').clone().insertAfter('[data-content=adSearch-3]:last');
// $('.searchByField,.searchOperator').selectize({refreshItems: true});
// $('[data-toggle=switch]').bootstrapSwitch({refreshItems: true});
});
Here is the fiddle, hope its ok. http://jsfiddle.net/CkVQr/6/
Thankyou very much for your help.
Cheers
Plugins change your HTML
There are two major problems you may not be fully aware of with your code:
Whenever you do a .clone() it merely deep clones your DOM element subtree, but not any event handlers bound to cloned elements.
Your .selectize() plugin changes HTML of your form quite considerably, converting input elements to other things. So whenever you clone your already converted select filter row, and subsequently want to run .selectize() on it again, this particular plugin won't find any suitable input elements to convert. Hence it won't work. Everything will just look as it should but won't work.
What can be done?
The main idea is that whenever you clone your search filter row, you have to clone your original HTML and not after it was converted using your plugins.
HTML Templates to the rescue
One of the possibilities is to change you page (and functionality) a bit and put your search filter row in a template and always use that. When you create your first row, you should read the template (and cache it) and add+convert it on your page. When you'd add an additional row, just use the same cached template and add+convert it again.
HTML template
<script id="filterRow" type="text/x-template">
<!-- Your filter rown HTML goes in here -->
</script>
Some Javascript
var cachedTemplate = cachedTemplate || $("#filterRow").html();
...
$('#addSearchRow').click(function(evt) {
var newRow = cachedTemplate.clone(); // clone for reusability
newRow.insertAfter('[data-content=adSearch-3]:last');
newRow.selectize();
...
});

jquery selectize error: issue with adding new select fields and combox-ifying them

I am trying to the Selectize library so I can have a comboboxes on my form.
So my form has a way to dynamically add more dropdowns (that i want to be comboboxes), so whenever the user adds a new dropdown, I want to apply Selectize combobox to it. So within my function that adds the new dropdown, after I have appended it, I use the following code:
$('select').each(function() {
if (!$(this).is('selectized')) {
$(this).selectize({
create: true,
sortField: 'text'
});
}
});
I thought that this would only apply it to dropdowns that do not already have Selectized combo box applied to it, but something is going wrong. Basically it is applying it to new comboboxes but something strange is going on with the existing ones. It's adding some kind of blank dropdown each time.
I tried to look around but I cannot find an "official" solution for combobox-ifying a newly added select fields. I don't know if it's an issue with how I am applying it, or if it's some kind of weird conflict with twitter bootstrap or jquery-ui or jquery itself (I included all of those in the fiddle)
Anyways, here is a link where you can see this issue in action:
http://jsfiddle.net/Qz7Ar/2/
Does anybody have experience with this or know what's going on here?
edit:
I also made a fork removing jquery-ui and bootstrap, so it's just jquery (required for Selectize) and Serialze, and the issue is still happening:
http://jsfiddle.net/Wxxub/1/
Okay well I figured out how to fix it..
If I add an id attrib to the new element and target by that instead, it works. Here is another fork demonstrating it:
http://jsfiddle.net/Wg7J6/1/
I can't find anywhere in the Selectize doc that it's necessary (I could be blind though!) that the select field must have an id or if it would work without one but i'm just doing it wrong or what, though.

Adding HTML element after the dataset is brought in

In Typeahead JS I'm trying to add an option that appears at the bottom of the dropdown after the user has started typing. Currently I'm using the 'onOpened' Custom Event to trigger adding some HTML after the 'tt-dropdown-menu' element is initialised.
.on('typeahead:opened', onOpened)
function onOpened($e) {
$('.tt-dropdown-menu').html( "Add Option" );
}
The problem is that the jQuery HTML is added when the dropdown is initialised, as expected, then when the user starts typing the new dataset element with the autocomplete results in is added below that jQuery HTML so the jQuery HTML can never appear at the bottom of the dropdown. You can't append the jQuery HTML to the dataset either as that element doesn't exist when the dropdown is initialised.
Is there an easier way around this? The other Custom Events don't seem to cover this scenario.
If you only have one dataset, you can do as I do: add a footer to the dataset, and add it as a DOM element, not plain HTML string. You can then change it at will (say on any event you wish) and your changes are reflected in the dropdown.
Example:
$('#myinput').typeahead({
// rest of your regular stuff, like 'name', 'remote', etc.
footer: $('#dropdown-footer'),
});
... where dropdown-footer is the ID of a div you have somewhere in your dom. You can then do things like:
$('#dropdown-footer').html('Hello')

Preserve selection after clicking a custom button in tinyMCE issue

Here is my issue :
I have a custom button with a code onClick. This code modify the selection's parent node, and I would like that my selection stays the same after my code, but tinyMCE disable my selection and give me a caret instead.
I tried getRng() and setRng from tinyMCE API but without success, the results are pretty odd. Sometimes it works and sometimes it deactivate my selection and give me a caret instead. Plus, sometimes it works only 2 times and then my button does not respond.
Here is my code which does not work:
onclick : function() {
range_selection = tinymce.activeEditor.selection.getRng();
//Here is my own code which modify my parent node
tinymce.activeEditor.selection.setRng(range_selection);
}
Problem here is that this range is probably not applicable anymore because of a changed DOm structure. I would use a bookmark to overcome this issue:
var bookmark = ed.selection.getBookmark();
// do what you like to do here
ed.selection.`moveToBookmark`(bookmark);

How to hide / show yui.calendar.DatePicker in wicket

I've run in to a problem I hope you guys can help me with.
I'm using a DateTextField with a DatePicker (from yui.calendar), they are both added to a WebMarkupContainer with OutputMarkupId and OutputMarkupPlaceholderTag set to true.
I want to be able to set the visibility of the container, but when I set it from true to false to true, the datepicker is no longer visible (I'm guessing it has to do with it not beeing mentioned in the HTML(?)) and I have to reload the entire page (and loose the input data) to get the DatePicker visible again. There is no problem with the DateTextField. Is there any good way to work around this?
JAVA:
invoiceDateFromField = new DateTextField("invoiceDateFromField", new PropertyModel(this, "invoiceDateFrom"), new PatternDateConverter("yyyy-MM-dd", true));
invoiceDateFromField.setOutputMarkupPlaceholderTag(true);
invoiceDateFromField.add(new DatePicker());
containsAllContainer.add(invoiceDateFromField);
AjaxLink onClick:
containsAllContainer.setVisible(!containsAllContainer.isVisible());
target.add(containsAllContainer);//Edit
I tried to remove the DatePicker from invoiceDateFromField, and then add a new one when the container is set to visible, but this did not seem to work either.
Thanks!
Olle
YUI will lose its connection to the DOM element when you set it visible=false in Wicket (because the node is removed from the DOM). So when you add it back to the page, your instance of YUI calendar no longer has any associated field in the DOM. You need to be sure to update your reference with a new instance of calendar every time you re-render the DateTextField with Wicket

Categories