Materialize dropdown options - javascript

I want to use the options from here:
http://materializecss.com/dropdown.html#options (The docs don't say so much).
My app is a rails app that use the materialize gem with the asset
pipeline.
My code now looks like this:
ul#dropdown1.dropdown-content.z-depth-0
li
a Profile settings
li
a payments
a.dropdown-button.btn-large.btn-flat.waves-effect.menu_trigger href="#!" data-activates="dropdown1"
i.material-icons menu
javascript:
var elem = document.querySelector('.menu_trigger');
var instance = M.Dropdown.init(elem, {
coverTrigger: false,
constrainWidth: false,
});

In practice, using the data attribute isn't always the best way. Options can (or rather should be, correct me if I'm wrong) passed the following way:
// native javascript way
document.addEventListener('DOMContentLoaded', function() {
var dropdown1 = document.querySelector('.simple-dropdown');
var dropdownOptions = {
'closeOnClick': true,
'hover':true
}
var instanceDropdown1 = M.Dropdown.init(dropdown1, dropdownOptions);
});
// Initializing the jQuery way
$(".simple-dropdown").dropdown(
{
'closeOnClick': true,
'hover': true,
});

Solved!
Finally like it says here http://archives.materializecss.com/0.100.2/dropdown.html#options
Solved where it says:
To use these inline you have to add them as data attributes. If you
want more dynamic control, you can define them using the jQuery plugin
below.
So then, with something like this:
a.dropdown-button.btn-large.btn-flat.waves-effect href="#!" data-activates="dropdown1" data-beloworigin="true"
i.material-icons menu
Done what i wanted

Couldn't find directly in Materialize docs, but by trial and error I found this javscript code is working fine. It looks like an expected options variable should be an Object with property "dropdownOptions" with assigned another Object with properties listed in docs.
document.addEventListener('DOMContentLoaded', function () {
var options = {
dropdownOptions: {
alignment: 'right',
hover: true
}
}
var elems = document.querySelectorAll('.dropdown-trigger');
var instances = M.Dropdown.init(elems, options);
});

Related

Set Kendo UI Window values globally

I'm working with a lot of Kendo UI windows. Is there some way to specify default values somehow globally? Or maybe a more realistic version, can I create some parent with predefined values and then just overwrite the values I need to change?
For example, I want the same error behavior and a modal parameter for all of the windows, so I would like to do something like:
$("#parentWindow").kendoWindow({
modal: true,
error: function () {
this.close();
new Notification().error();
}
});
And then use the parent window as a base for new windows:
$("#newWindow").kendoWindow({
title: "This window should have the options (modal and error) of the parentWindow",
}).??getTheRestOfTheValuesFromParent()??;
Or rewrite some parameter:
$("#newWindow2").kendoWindow({
modal: false,
title: "A window with overwritten modal parameter",
}).??getTheRestOfTheValuesFromParent()??;
Is it somehow possible to achieve this, is there any possibility of something like C# inheritance?
Maybe it's a stupid question, but I'm not so familiar with JS.
I highly encourage you to create your own wrapper code over all - or at least those more complex - kendo widgets. My team has been doing it for years in a project we use kendo for everything and we are having very positivelly results. The main purpose is what you need: a global behaviour. If after thousand windows coded over your project, you need to change them all, just change the wrapper. It's just a simple jQuery function:
$.fn.MyWindow = function(options) {
var $target = $(this);
var widget = {
_defaultOptions: {
actions: ["Minimize", "Maximize", "Close"],
visible: false,
width: 400,
height: 400,
modal: true
},
_options: options || {},
_target: $target,
_widget: null,
_init: function() {
this._manageOptions();
this._createWidget();
return this;
},
_manageOptions: function() {
// Here you can perform some validations like displaying an error when a parameter is missing or whatever
this._options = $.extend(this._options, this._defaultOptions);
},
_createWidget: function() {
this._widget = this._target.kendoWindow(this._options).data("kendoWindow");
// Create here some behaviours that the widget doesn't haves, like closing the window when user click the black overlay
if (this._options.closeOnOverlayClick) {
$('body').off('click', '.k-overlay').on('click', '.k-overlay', function() {
this._widget.close();
}.bind(this));
}
},
Show: function(center) {
if (center) {
this._widget.center();
}
this._widget.open();
}
};
return widget._init();
};
var wnd = $("#wnd").MyWindow({
title: "My first window",
closeOnOverlayClick: true // Your own parameter
});
// Now you work with your own functions:
wnd.Show(true);
Demo.
There are so many customizations, like your own events - some of those kendo's widgets doesn't haves - etc..
I will just add that there is an article(here) about creating custom Kendo widgets where you can find more information about the specifics of different scenarios that may be implemented.
Ι had a case like yours with kendo windows, kendo grids and kendo dropdownlists. For that I created HtmlHelpers for all my elements and called them when I needed to. Since you are using kendo asp.net-mvc I would recommend to look at this way.
public static WindowBuilder GlobalKendoWindow(this HtmlHelper helper)
{
return helper.Kendo().Window()
.Draggable()
.Animation(true)
.Visible(false)
.AutoFocus(true)
.Modal(true)
.Scrollable(true)
.HtmlAttributes(new { #class = "atn-modal-container" })
.Actions(actions => actions.Minimize().Close())
.Deferred();
}
and render it in my Html like this
#(Html.GlobalKendoWindow()
.Name("addCandidateDialog")
.Title(Html.GetResource(cps, "AddCandidateDialogTitle"))
.LoadContentFrom("AddCandidate", "Candidate")
.Events(events => events.Open("athena.addCandidacy.onAddCandidateOpen").Close("athena.addCandidacy.onAddCandidateClose"))
)

Facing issue with Mouse Event

I am new to web development, so I am taking a Pluralsight course called "Building a Web App with ASP.NET Core RC1, MVC 6, EF7 & AngularJS" by Shawn Wildermuth. In his jQuery module, Shawn has this piece of code that works flawlessly for him:
var main = $("#main");
main.on("mouseenter", function() {
main.style = "background-color: #888;";
});
main.on("mouseleave", function() {
main.style = "";
});
I have a div with id="main" on my index.html page, js file is referenced, other jQuery functionality in the same file works, I just can't get this piece of code to work. I know it is not significant, but at this point it is personal. Any suggestions are helpful. Thank you!
As style is a property of native DOM element and main is a jQuery object. You can use .css() and .removeAttr() jQuery method to get the desired result.
var main = $("#main");
main.on("mouseenter", function() {
main.css("background-color": "#888");
});
main.on("mouseleave", function() {
main.removeAttr('style');
});
You can't access the style property like this. Try the following:
var main = $("#main");
main.mouseenter(function() {
main.css("background-color", "#888");
});
main.mouseleave(function() {
main.css("background-color", "none");
});
Try this:
var main = document.getElementById("main");
main.onmouseenter=function(){
main.setAttribute('style', 'background-color:#888;');
};
main.onmouseleave=function(){
main.removeAttribute("style")
};

Unable to get Quicksand.js working

I'm trying to filter collections of data using quicksand.js. However, I'm having problems getting my data to appear. I have been able to get the data to disappear. Yet, it won't re-appear. I've created a jsfiddle, which is available here. Basically, my JavaScript looks like this:
var $content = $('#stage');
var $data = $content.clone();
function filterData(tag) {
var data = [];
if (tag === null) {
data = $data.find('li');
} else {
data = $data.find('li[data-tags=' + tag + ']');
}
console.log(data);
$content.quicksand(data, {
duration: 800,
easing: 'easeInOutQuad'
});
return false;
}
Everything looks correct to me. I can't figure out what I'm doing wrong.
First, your fiddle is broken. One, you link quicksand 1.3 and pair it with a recent jquery version it doesn't support. Two, you call out the easeInOutQuad without linking the jquery.easing.1.3.js. Three, you have scope issues, the filterData function is not defined globally.
Your real problem, though, is this line in the documentation:
attribute – attribute containing unique value able to identify same item within source and destination collection, default: 'data-id'
None of your "stage" data lis have this attribute so it won't filter them properly. Add it and all seems to work:
<ul id="stage">
<li data-tags="A" data-id="1">Item A-1</li>
<li data-tags="A" data-id="2">Item A-2</li>
<li data-tags="B" data-id="3">Item B-1</li>
<li data-tags="B" data-id="4">Item B-2</li>
</ul>
Updated fiddle.

jQuery custom plugin - setting private options for multiple instances

Hi folks!
I'm currently developing a client project where I saw myself doing the same javascript code over and over again. So I though it would be useful to wrap the logic inside a custom jQuery plugin. I've achieved it for a single instance of the plugin, but for multiple instances, I think I'm having a problem with the properties of each instance overwriting each other.
Well, let's get to the code! Here is the currently code that I have for the plugin:
// RESPONSIVE MENU ===========================//
// wrapper for a responsive menu plugin, //
// made by Favolla Comunicação //
//============================================//
/* INSTRUCTIONS
Apply the plugin on the main wrapper of the responsive menu. For example:
$(#menu).responsiveMenu($(#trigger));
The plugin just toggles the classes, leaving the effects and layout for the css
CONFIG
- trigger: the selector of the button that will activate the menu (required)
- activeClass: class name to be injectet when the toggle is activated (default: active)
- submenuTrigger: the selector of the buttons that will activate the submenus, if the menu will have another levels (default: $('sub-toggle'))
- submenu: the selector of the submenus (default: $('.submenu'))
- submenuActiveClass: class name to be injected on the submenus when they are activated (default: open)
- breakpoint: max window whidth where the plugin will work (default: 720)
- timeOut: time in milissegundos to limite the onResize repeat. (default: 100)
- moveCanvas: option to activate the "off canvas" pattern or not (just puts a class on the main elements of the page). (default: false)
- canvas: class name of the elements that build the "canvas" (default: null)
*/
;(function ( $, window, document, undefined ) {
$.fn.responsiveMenu = function(settings){
var config = {
'trigger': '',
'activeClass': 'active',
'submenuTrigger': $('.sub-toggle'),
'submenu': false,
'submenuActiveClass': 'open',
'breakpoint': 720,
'timeOut': 100,
'moveCanvas': false,
'canvas': '',
};
if (settings){$.extend(config, settings);}
// plugin variables
var mTrigger,
menu = $(this),
active = config.activeClass,
button = config.trigger,
bpoint = config.breakpoint,
submTrigger = config.submenuTrigger,
submenu = config.submenu,
submenuActive = config.submenuActiveClass;
canvasOn = config.moveCanvas;
canvas = config.canvas;
time = config.timeOut;
return this.each(function () {
if($(window).width() > bpoint){
mTrigger = false;
} else {
mTrigger = true;
}
onChange = function(){
clearTimeout(resizeTimer);
var resizeTimer = setTimeout(function(){
if($(window).width() > bpoint){
mTrigger = false;
menu.removeClass(active);
button.removeClass(active);
if(canvasOn){
canvas.removeClass(active);
}
} else {
mTrigger = true;
}
}, time);
}
$(window).bind('resize',onChange);
$(document).ready(onChange);
button.click(function(){
if(mTrigger) {
menu.toggleClass(active);
button.toggleClass(active);
if(canvasOn){
canvas.toggleClass(active);
}
}
});
if(submenu){
var submenuClass = '.' + submenu.prop('class');
// toggle for the submenus
submTrigger.click(function(){
if(mTrigger) {
if($(this).hasClass(active)){
submTrigger.removeClass(active);
submenu.removeClass(submenuActive);
} else {
submTrigger.removeClass(active);
$(this).addClass(active);
submenu.removeClass(submenuActive);
$(this).next(submenuClass).addClass(submenuActive);
}
}
});
}
});
}
})( jQuery, window, document );
And then, when I want to apply the plugin, I make like this:
$('#menu-wrapper').responsiveMenu({
trigger: $('#nav-toggle'),
submenu: $('.submenu'),
submenuTrigger: $('.submenu-toggle'),
moveCanvas: true,
canvas: $('.canvas'),
breakpoint: 862
});
$('#search').responsiveMenu({
trigger: $('#search-toggle'),
breakpoint: 862
});
The main issue here is when I set to instances of the responsiveMenu();, it seems like some options are overwriting. For example, the first instance set moveCanvas to true, and it works, but when I leave it blank for the second instance (which leaves the moveCanvas option set to false for this element, this options for the first instance don't work anymore.
I know that maybe I'm not following the jQuery plugin best pratices, and I even read something about the jQuery Boilerplate, which looks great, but I'm not an advanced javascript developer, so there a lot of things that I could do better, but I just don't now how to do.
Anyway, any help with this issue (and opinions about the plugin) will be very welcome!
var mTrigger,
menu = $(this),
active = config.activeClass,
button = config.trigger,
bpoint = config.breakpoint,
submTrigger = config.submenuTrigger,
submenu = config.submenu,
Until here you were doing correct.
submenuActive = config.submenuActiveClass;
canvasOn = config.moveCanvas;
canvas = config.canvas;
time = config.timeOut;
Then, you introduced a semicolon - which leads to the further assignments (canvasOn, canvas and time) not being part of the var statement any more. They're no variable declarations, you assign to global variables here - and that way you overwrite the settings of the first plugin instance.
Change every but the last semicolon to commata.
You need to encapsulate your settings in a class or closure and store them for each element the plugin is called on.
return this.each(function () {
...
$(this).data('some-key', settings);
...
});
If you'd like to learn about jQuery plugin authoring, they have an article on it here http://learn.jquery.com/plugins/basic-plugin-creation/

TypeError: this.$E_0.getElementsByTagName is not a function

I am attempting to create a modal dialog in sharepoint 2010, but I'm getting this error:
TypeError: this.$E_0.getElementsByTagName is not a function
my code is:
var options = SP.UI.$create_DialogOptions();
options.html = '<div class="ExternalClass23FFBC76391C4EA5A86FC05D3D9A1904"><p>RedConnect is now available.​</p></div>';
options.width = 700;
options.height = 700;
SP.UI.ModalDialog.showModalDialog(options);
using firebug, i tried simply using the url field instead of the html field and it gave no error.
also related to this, what does SP.UI.$create_DialogOptions() actually do? what is the difference between using it and simply using a dict of values for your options?
options.html requires a HTML DOM element instead of plain HTML code:
<script>
function ShowDialog()
{
var htmlElement = document.createElement('p');
var helloWorldNode = document.createTextNode('Hello world!');
htmlElement.appendChild(helloWorldNode);
var options = {
html: htmlElement,
autoSize:true,
allowMaximize:true,
title: 'Test dialog',
showClose: true,
};
var dialog = SP.UI.ModalDialog.showModalDialog(options);
}
</script>
Boo
Example code taken from the blog post Rendering html in a SharePoint Dialog requires a DOM element and not a String.
also related to this, what does SP.UI.$create_DialogOptions() actually do? what is the difference between using it and simply using a dict of values for your options
When you look at the definition of the SP.UI.DialogOptions "class" in the file SP.UI.Dialog.debug.js you see that its a empty javascript function.
SP.UI.DialogOptions = function() {}
SP.UI.$create_DialogOptions = function() {ULSTYE:;
return new SP.UI.DialogOptions();
}
My guess is that it is there for client diagnostic purpose. Take a look at this SO question: What does this Javascript code do?

Categories

Resources