jQuery plugin method to get object properties - javascript

I´m building a jQuery extension plugin with the following standard:
(function ($) {
var version = "1.1.0";
var active = false;
$.fn.inputPicker = function (options) {
return this.each(function () {
if ($(this)[0].tagName !== 'DIV')
throw new ReferenceError('mz.ui.dialog.dateTimePicker: Method works only on DIV types.');
/// Label
var labelObj = $("<label class='small'>Data Hora Inicial</label>");
$(this).append(labelObj);
/// Input
var inputObj = $("<input type='datetime-local' class='form-control input-sm'></input>");
$(this).append(inputObj);
})
});
};
}(jQuery));
And here is how I call it:
<div id='test'></div>
$('#test').inputPicker();
Later in code I wanna get the data that was entered in the input field, something like:
$('test').inputPicker().getInputData();
What´s the best way to accomplish that ? I´ve tried something like:
this.getInputData = function () {
return $(inputObj).val();
}
But got errors when calling the function.
Can someone help me with this ? Thanks in advance...

You could just make another method to get the input data like this using the DOM structure and class names that you added:
$.fn.getInputData = function() {
return this.eq(0).find("input.input-sm").val();
}
This would operate only on the first DOM element in the jQuery object (since it's returning only a single value).
So, after setting it up like you did:
$("#test").inputPicker();
You'd then retrieve the data like this:
var data = $("#test").getInputData();

Related

Get data attr value on hover

I have a few links. When I hover mouse over the links I would like to get the values stored in data attributes. I need to pick the t values and pass them into function
HTML
<a href="#" data-lat="23.333452" data-lon="-97.2234234">
JS
var loc = document.querySelectorAll("a[data-lat]");
loc.addEventListener("mouseover", locOver);
loc.addEventListener("mouseout", locOut);
function locOver() {
// do something
}
function locOut() {
// do something else
}
It's been a while since I used vanilla JS and it's been a long day so I'm sure it's pretty close but I'm stuck. I keep getting:
Uncaught TypeError: loc.addEventListener is not a function
What am I missing here?
You need to loop through the nodes that you obtained with document.querySelectorAll("a[data-lat]") for adding events.
Working example.
Node
<script>
var loc = document.querySelectorAll("a[data-lat]");
loc.forEach(node => {
node.addEventListener("mouseover", locOver);
node.addEventListener("mouseout", locOut);
})
function locOver(event) {
// do something
console.log('mouseover', event.target.dataset)
}
function locOut() {
// do something
console.log('locOut')
}
</script>
const loc = document.querySelector("a[data-lat]");
const locOver = () => {
console.log("Mouse is over the link");
}
const locOut = () => {
console.log("Mouse is out of the link");
}
loc.addEventListener("mouseover", locOver);
loc.addEventListener("mouseout", locOut);
Link
Explanation:
I target the link using .querySelector method that returns a single node.
After that i created two event handler for mouseOver and mouseOut and than i added the eventListener to the link.

Dynamic dropdowns filtering options with jquery

I am trying to filter one dropdown from the selection of another in a Rails 4 app with jquery. As of now, I have:
$(document).ready(function(){
$('#task_id').change(function (){
var subtasks = $('#subtask_id').html(); //works
var tasks = $(this).find(:selected).text(); //works
var options = $(subtasks).filter("optgroup[label ='#{task}']").html(); // returns undefined in console.log
if(options != '')
$('#subtask_id').html(options);
else
$('#subtask_id').empty();
});
});
The task list is a regular collection_select and the subtask list is a grouped_collection_select. Both which work as expected. The problem is that even with this code listed above I can't get the correct subtasks to display for the selected task.
NOTE: I also tried var tasks=$(this).find(:selected).val() that return the correct number but the options filtering still didn't work.
Try something like this instead (untested but should work).
$(function () {
var $parent = $('#task_id'),
$child = $('#subtask_id'),
$cloned = $child.clone().css('display', 'none');
function getParentOption() {
return $parent.find('option:selected');
}
function updateChildOptions($options) {
$child.empty();
$child.append($options);
}
$parent.change(function (e) {
var $option = getParentOption();
var label = $option.prop('value'); // could use $option.text() instead for your case
var $options = $cloned.find('optgroup[label="' + label + '"]');
updateChildOptions($options);
});
});

jQuery Example: Reseting an input file element in case of non-allowed file-extensions

If someone tries to upload a file with a non-allowed file-extension, this input-file-element should get "reseted".
That is the input-file-element
<input type="file" id="image1">
These are the corresponding jQuery-statements (document is ready) and I get "TypeError: myElement.clone is not a function" (while I am trying this solution here: Clearing <input type='file' /> using jQuery)
$(document).ready(function() {
$('#image1').change(function(event) {
checkExtensions(this.files[0].name, $(this).get());
});
function checkExtensions (fileName, element) {
var myElement = element;
var allowedExtensions = new Array ('pdf','gif','jpg','png');
var currentExtension = fileName.split('.').pop();
if ($.inArray (currentExtension, allowedExtensions) > -1) {
// everythins is OK, further instructions take place
} else {
// reset the file input element
myElement.replaceWith( myElement = myElement.clone( true ) );
}
}
});
You are passing the native DOM element to your function instead of the jQuery object containing the element. Native DOM elements do not have the function clone() (or replaceWith either). Try this instead:
$('#image1').change(function(event) {
checkExtensions(this.files[0].name, $(this)); // note, I removed .get()
});
function checkExtensions (fileName, $element) {
var allowedExtensions = new Array ('pdf','gif','jpg','png');
var currentExtension = fileName.split('.').pop();
if ($.inArray (currentExtension, allowedExtensions) > -1) {
// everything is OK, further instructions take place
} else {
// reset the file input element
$element.replaceWith($element.clone(true).val(''));
}
}
Example fiddle

JS variable equal to html data attribute

I'm trying to create a variable in my Javascript that uses the value assigned on data-start-time.
Here is my html:
<li data-pile="1" id="kQKhpVWBjoQ" data-start-time="20" class="md-trigger md-setperspective">
</li>
Here is my JS:
function playVideo(videoId, cb) {
if(videoId) {
myModal.find('.md-video').append($videoDiv);
myModal.addClass('md-show');
setTimeout(function () {
console.log('#### id', videoId);
var startTime = videoId.getAttribute('data-start-time');
player.loadVideoById({'videoId': videoId, 'startSeconds': startTime});
player.videoEnded = function () {
cb && cb();
};
player.waitForChanges();
}, 1000);
}
}
If I create variable startTime and hardcode some value in my js the player works. However I
can seem to figure out what is wrong with line:
var startTime = videoId.getAttribute('data-start-time');
All I need to do is get the value assigned in html inside data-start-time="..." for each
"li" using the ids that vary according to the specific "li"
Try this:
var startTime = $('#'+videoId).prop('data-start-time');
Assuming what the function in receiving in videoId is a element ID then you need to get that element by the ID. Just naming the ID will not do it. You can also use plain javascript like this:
document.getElementById(videoId).getAttribute('data-start-time');

knockout dirty flag code not working

Just started with knockout and need to implement page change warning. Following is the code snippet. I just need an alert pop up as warning if any change is made on the page.
function parseViewModel() {
var viewModel = JSON.parse(getState());
viewModel.checking = ko.observable(false);
viewModel.Slider = new ko.observable(100 - viewModel.Slider);
viewModel.CausalsList = buildHierarchy(viewModel.Causals);
viewModel.Causals["-1"] = "Total Marketing Budget";
viewModel.GeographiesList = ko.observableArray(gl);
viewModel.Geographies["0"] = "All Geographies";
viewModel.ProductsList = ko.observableArray(pl);
viewModel.Products["0"] = "All Products";
.
.
.
return viewModel;
}
function bindModel() {
model = parseViewModel();
ko.dirtyFlag = function (root, isInitiallyDirty) {
var result = function () { },
_initialState = ko.observable(ko.toJSON(root)),
_isInitiallyDirty = ko.observable(isInitiallyDirty);
result.isDirty = ko.computed(function () {
return _isInitiallyDirty() || _initialState() !== ko.toJSON(root);
});
result.reset = function () {
_initialState(ko.toJSON(root));
_isInitiallyDirty(false);
};
return result;
};
model.dirtyFlag = new ko.dirtyFlag(model);
model.isDirty.subscribe(function () {
alert("Page change warning!");
});
ko.applyBindings(model, $('#const').get(0));
ko.applyBindings(model, $('#buttonDiv').get(0));
}
Referred Ryan Niemeyer's blog. Unfortunately, it's not working anymore. Any insights please?
You would want to subscribe to model.dirtyFlag.isDirty in your case rather than model.isDirty.
One way to do is by using customBinding. I'm not that familiar with KO either but this might be something you're interested on.
Basically you would do is :-
ko.bindingHandlers.myFunction = {
update : function(){
//do something
}
}
http://knockoutjs.com/documentation/custom-bindings.html
And call it on your element using :-
<h1 data-bind="myFunction:{}"></h1>
Also, a jsfiddle to show how it works. (If you change the value of the First Name and focus out of it then the customBinding gets triggered. )
http://jsfiddle.net/3vuTk
Not sure if it's the best practice though.

Categories