Using the listChanged parameter - javascript

I'm using the jQuery UI plugin fieldchooser and I want to know whenever the list changes so that I can update it in the database. The plugin has a listChanged function, but I'm not sure how to make it work. I working off this example:
<script>
$(document).ready(function () {
var $sourceFields = $("#sourceFields");
var $destinationFields = $("#destinationFields");
var $chooser = $("#fieldChooser").fieldChooser(sourceFields, destinationFields);
});
</script>
<div id="fieldChooser" tabIndex="1">
<div id="sourceFields">
<div>First name</div>
<div>Last name</div>
<div>Home</div>
<div>Work</div>
<div>Direct</div>
<div>Cell</div>
<div>Fax</div>
<div>Work email</div>
<div>Personal email</div>
<div>Website</div>
</div>
<div id="destinationFields">
</div>
</div>
Elsewhere on stack overflow, I found this example:
$chooser.on("listChanged",function(event,selection,list){
//event <- The jQuery event invoking the callback.
//selection <- The field (or set of fields) which has moved.
//list <- The field list to which the selection has moved.
alert("listChanged");
}
and have tried this, without success:
$chooser.on("listChanged",function(mouseup,sourceFields,destinationFields){
alert("listChanged");
});
I'd appreciate any suggestions on making this work. Thanks.

With correct code, this works as expected.
Working Example: https://jsfiddle.net/Twisty/v2Lrm9wq/2/
JavaScript
$(function() {
var $chooser = $("#fieldChooser").fieldChooser();
var $sourceFields = $("#sourceFields").children();
$chooser.getSourceList().add($sourceFields);
$chooser.on("listChanged", function(event, selection, list) {
alert("listChanged");
});
});

Related

jQuery display property not changing but other properties are

I'm trying to make a text editable on clicking it. Below is the code I'm trying. When the title is clicked it shows an input box and button to save it.
<div class="block">
<div class="title">Title</div>
<div class="title-edit">
<input type="text" name="title" value="Title">
<button>Save</button>
</div>
</div>
I have changed other properties like color or changing the text of the elements and its working, but it is not applying the display property or .show()/.hide() function on the title or edit elements.
Below is my jQuery
$(function(){
$('.block').on('click', editTitle);
$('.title-edit button').on('click', saveTitle);
});
function saveTitle(){
var parent = $(this).closest('.block');
var title = $('.title', parent);
var edit = $('.title-edit', parent);
$(title).show();
$(edit).hide();
}
function editTitle(){
$('.title-edit', this).show();
$('.title', this).hide();
}
Here's the jsfiddle
https://jsfiddle.net/ywezpag7/
I've added
$(title).html('abcd');
to the end to show that other properties/functions are working, but just not the display.
For checking the html change on title element you will have to check the source through developer tools cause the title element is hidden.
Where am I going wrong?
Your problem is in the function saveTitle. The first line must stop the event propagation otherwise after this function the editTitle function is called.
The snippet:
$(function(){
$('.block').on('click', editTitle);
$('.title-edit button').on('click', saveTitle);
});
function saveTitle(e){
// this line
e.stopPropagation();
var parent = $(this).closest('.block');
var title = $('.title', parent);
var edit = $('.title-edit', parent);
title.show();
edit.hide();
title.text($('.title-edit input').val());
}
function editTitle(e){
$('.title-edit', this).show();
$('.title', this).hide();
}
.title-edit{
display:none
}
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<div class="block">
<div class="title">Title</div>
<div class="title-edit">
<input type="text" name="title" value="Title">
<button>Save</button>
</div>
</div>
The issue as mentioned already is that your click events are fighting. In your code, the title-edit class is within the block, so when you click on the save button it triggers events for both clicks.
The easiest and, imho, cleanest way to resolve this is to switch your click event to be called on .title, and .title-edit button. You can also simplify the code beyond what you've got there.
$(function(){
$('.title').click(editTitle);
$('.title-edit button').click(saveTitle);
});
function saveTitle(){
$('.title').show();
$('.title-edit').hide();
$(title).html('abcd');
}
function editTitle(){
$('.title-edit').show();
$('.title').hide();
}
https://jsfiddle.net/ywezpag7/7/
I tried debug your code, and I had seen, that then you click to "Save" button, handled both functions, saveTitle() and editTitle(), and in that order. Therefore, the elements initially hidden, and then shown.

get id of dropped div using dragula javascript

I am trying to update a c3.js chart using drag and drops with dragula.js, but I don't know how to get the id of the div that is dragged into a new container. My html is something like this:
<div id="collapse1" class="panel-collapse collapse">
<div id="color1" class="form-inline">1</div>
<div id="color2" class="form-inline">2</div>
<div id="color3" class="form-inline">3</div>
</div>
<div id="collapse2" class="panel-collapse collapse">
</div>
and I'm using dragula.js to drag and drop:
dragula([collapse1,collapse2]);
I am really new to jquery, but following this question, to access the id of the <div> dropped into collapse2 in I was trying to do something like this:
alert($("#collapse1.collapse2 div:first").attr("id"));
But no results. Any help would be really appreciated
Dragula has three Elements One is Source Div, Target Div and Its associated Element. Following Method Works For Me as Charm except i am Not using get() method which has version issue.
You Can Try Both.
Dragula gives you the id of dropped div, Source Div, Target Div.
const dragula = Dragula(['', '']);
dragula.on('drop', (el, target, source, sibling) => {
const elementId = $(el).attr("id");
const targetID = $(target).attr("id");
const sourceId = $(source).attr("id");
}
Can't answer the question directly because I am not familiar with dragula. However, I have used jqueryUI drag drop extensively and its a really good tool. You might want to give that framework a try.
Since you asked for an example, I dug into some of my old code. You might want to go look through the jqueryUI draggable and droppable tutorials to give you some background before looking at this. I have included parts of a function. I put little dots to show you where code has been left out. I have put <<< next the key lines for you. Notice how I use closure to make references available across different parts. Closure is soooo awesome. I abuse the death out of it, so learn how to use it if you can.
Note that once I got my drag object, that is what you are asking for. Notice how I reference the variable to my function later when I register the draggable.
Btw, notice there is also a stop drag function referenced which I don't show the definition of. If you move the declaration of the dragObject outside of startDrag then you can also see it from stopDrag since the definition of the function is "enclosed" in the outside register function.
function tapeChart_registerDraggables(parentObject,scope) {
if ((parentObject==null)||(parentObject==undefined)) {
parentObject=$jq(document.body);
}
var availablesShow = false;
var savingToServer = false;
var dragClone = null;
var startDrag = function(event, ui) {
tapeChartDraggingReservation = true;
var dragObject = event.target; <<<<<<
if (dragObject.getAttribute("unassigned")=="true") {
var is_chrome = window.chrome;
var is_safari = navigator.userAgent.toLowerCase().indexOf('safari/') > -1;
if (!is_chrome && !is_safari) {
$(ui.helper).css("margin-left", event.clientX - $(dragObject).offset().left);
$(ui.helper).css("margin-top", event.clientY - $(dragObject).offset().top);
}
}
...
// assigned rooms
if (scope!="UNBLOCKED") {
// register items in the grid
$(parentObject).find( ".NODRAGHELPER" ).draggable(
{
snap : "true",
revert : "invalid",
start: startDrag, <<<<
stop: stopDrag
}
)
.click(function(){
if ( $(this).is('.NODRAGHELPER-dragging') ) {
return;
}
// seems that the user can drop and click fast
// prevent this
if (!savingToServer) {
tapeChart_getReservation(this);
}
return false;
});
}
...

Can't use jQuery function inside Object Literal

I'm trying to learn how the object literals pattern works in Javascript.
In one of my projects i'm stuck on a part where I use some jQuery functions.
For the sake of the problem I build a little example.
I hope someone can provide me with some awesome hints.
Javascript: creating an object literal, and calling the init() method.
HTML: Some parts with a remove button. When clicked, I want to display an alert with the associated id extracted as data-attribute from the DOM. But there is the part it is failing, javascript does not know what .data means in that specific function.
Thanks... !
var test = {
init: function() {
this.dom();
this.events();
},
dom: function() {
this.$contentbox = $('.box');
this.$buttons = this.$contentbox.find('a');
},
events: function() {
this.$buttons.on('click', this.removeDiv);
},
removeDiv: function(event) {
event.preventDefault();
var div = this.closest('.removeMe'); // This works perfectly
var divID = div.data('id'); // Crashing -> Uncaught TypeError: div.data is not a function
alert('Product ' + divID + ' is to be deleted...');
}
}
test.init();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="box">
<div class="content">
Hi there! Click X to delete item :)
</div>
<div data-id="6" class="removeMe">
Product 6 (X)
</div>
<div data-id="7" class="removeMe">
Product 7 (X)
</div>
<div data-id="8" class="removeMe">
Product 8 (X)
</div>
</div>
div is a vanilla HTMLDivElment not a jQuery object so has no .data() method, instead:
var divID = $(div).data('id')

Replacing widget element with a newly constructed DOM structure

<script>
(function( $ ) {
$.widget( "my.dropbox", {
errorText: function(text) {
$(this.element).next().html(text);
},
_create: function() {
var id = $(this.element).attr("id");
var customDropbox = $(
"<div class='form-group'>"+
"<label for='"+id+"'>"+getLabelFor(id)+"</label>"+
"<select id='"+id+"'></select>"+
"<div class='errors'></div>"+
"</div>"
);
customDropbox.attr("id", id);
$(this.element).replaceWith(customDropbox); // This removes original element from DOM
populateOptions(id);
},
});
}( jQuery ));
$(document).ready(function(){
$("#field1").dropbox(); //blank input field turns into a select with a label, populated options e.t.c..
$("#button1").on("click", function(){
$("#field1").dropbox("errorText", "This is a validation error message"); //throws an error saying dropbox is not initialized
});
});
</script>
<html>
<body>
<input id="field1" />
<button id="button1">Press me</button>
</body>
</html>
So I want a widget with public methods that will replace the original element with all the widget data associated with it. The problem with the above code is that the <select..> element is just a DOM element and if you call .dropbox(..) on it, it will say the widget is not initialized. Is there a way to make the select element into the widget object with the .errorText() method? All widget examples online add stuff around the original element but never replace it. As for the bigger picture, I'm trying to make a generic tool to configure forms dynamically. It's going to be all <input id="..."> in html but then javascript will query a database, get configuration for the field and turn it into a dropbox, checkbox or, say, a date picker with all the labels, validation, and other bells and whistles.
There is more than one issue with your widget code. I'll try to summarize them:
1. Copy the data
You're not copying the data to the newly created customDropbox, so before
this.element.replaceWith(customDropbox);
you should copy the data:
customDropbox.data(this.element.data());
Now the widget will remember that it was initialized.
2. this.element is gone
After
this.element.replaceWith(customDropbox);
you should update this.element so that it points to the newly created customDropbox:
this.element = customDropbox;
3. errorText message takes wrong element
Since the widgets element (this.element) is now pointing to the <div class='form-group'></div> element, the errorText function must be slightly modified to:
this.element.find(".errors").html(text);
4. id should be unique
Now, both the wrapper <div> and the <select> have the same id, which is not allowed in HTML so remove the one on the <select> tag. Luckily, <label> can work without the for attribute, just write it like this:
<label>labelForId <select></select></label>
Then to get the <select>-element, use this.element.find("select") in the widget.
Side note
`this.element` is already a jQuery element, so no need for the additional `$()` wrapping.
See this jsFiddle
function show(){
$("#field1").input({....});
}
function hide(){
$("#field1").input("hide");
}
<button onclick="show()">show</button>
<button onclick="hide()">hide</button>
i think to replace the origin element which initial dropbox() is not a good solution,
because this will force you to rely on the implemention details of jQuery ui factory,
it is easy to make a mistake or introduce bugs, sometimes harder for other people to understand your code
if jquery ui factory change the implemention in the future, you have to modify all your code to make it work
(sorry for my limit understand of jquery ui)
i think we can put the <input/> into a container and initial dropbox() on the container which inturn
replace <input/> with <select> datepicker ..etc.. we can build modules easily by doing so:
<form>
<div class="dropbox"><label for="someID">aaaaaa</label><input id="someID"/></div>
<div class="datepicker"></div>
<div class="othermodule"></div>
</form>
js:
$(".dropbox").dropbox(); // init dropbox you defined
$(".datepicker").datepicker(); // ...
$(".othermodule").othermodule(); // ...
$(".dropbox").dropbox("errorText", "error"); // invoke it smoothly
here is a simple demo: http://jsfiddle.net/m4A3D/
#Wouter Huysentruit's answer provides a list of good suggestion for me
<form>
<div class="dropbox">
<label for="someID">aaaaaa</label>
<input id="someID"/>
</div>
<div class="datepicker"></div>
<div class="othermodule"></div>
</form>
<button id="button1">Press me</button>
<script>
(function ($){
$.widget("my.dropbox", {
_create: function () {
var $input = this.element.find("input");
var sID = $input.attr("id");
var $select = $("<select>");
$select.attr("id", sID);
$input.replaceWith($select);
this.element.append("<div class='errors'></div>");
}, // end _create()
errorText: function (text) {
this.element.find(".errors").text(text);
} // end errorText()
});
}(jQuery));
$(".dropbox").dropbox();
$("#button1").click(function () {
$(".dropbox").dropbox("errorText", "this is error");
});
</script>

Stuck on structure of this jquery plugin

I'm practicing jquery plugins and need help finishing this one, especially the outside skeleton.
Let's say I have this markup
<div class="tochange"></div>
<div class="tochange"></div>
<div class="tochange"></div>
and I want the plugin to add to div.tochange this markup
<div class="root">Root</div>
so that it's
<div class="tochange">
<div class="root">Root</div>
</div>
Then if the root is clicked, replace it with 2 divs so the markup looks like this
<div class="tochange">
<div class="child">Child</div>
<div class="child">Child</div>
</div>
If the child is clicked, it goes back to parent
<div class="tochange">
<div class="root">Root</div>
</div>
I'm following documentation but I don't know if I need methods for this. My guess is that I do but I can't finalize the structure of this plugin in my head. This is my first plugin and I thought a practical idea of my own is the best way to learn, but I'm stuck. Can someone who's done this before set me on the right track. I'm a little lost on this.
(function($){
$.fn.sample = function(options) {
var settings = {
'possibleparam1' : 'value1',
};
var methods = {
init: function( options ) { },
tochildren : function( ) { },
toparent : function( ) { },
};
return this.each(function() { /*(i) {*/
// If options exist, merge them with our default settings
if (options) {
$.extend(settings, options);
}
// plugin code goes here
});
};
})( jQuery );
You can use several methods:
Try $("field_name").update("New text"); or $(this).replaceWith.
I have something like this in my site and I'm using: (don't mind the func name - its my ajax callback)
function setOutput()
{
if(httpObject.readyState == 4)
{
document.getElementById('photos').innerHTML = "<div id=\"gallery\" clas.....</ul></div>";
}
}

Categories

Resources