How do I use MDCSlider in JavaScript? - javascript

I have created an DOM element for an MDC slider (https://material.io/develop/web/components/sliders).
It looks nice (except for the colors). And it works, but I really have no idea how to initialize it.
I import MDC from the CDN. I can't understand from the documentation how to do the initialization. This is one version that works:
setTimeout(() => { slider = new mdc.slider.MDCSlider(eltSlider) });
Without setTimeout it does not work.
I have tried using a Promise instead and wait a second. That does not work.
And maybe even worse: If I use a Promise to wait after the setTimeout it does not work any more.
What is going on and how am I supposed to do it?
I do not use ts. And I do not use any package handler. Just plain JavaScript. (And I would be glad if the documentation covered this use case first.)
(There seems to be only one other question about MDCSlider here. It does not cover my question: actual use of foundation and adapter class of mdc-components)
EDIT: By "import from CDN" I mean the setup mentioned here: https://material.io/develop/web/docs/getting-started
<link href="https://unpkg.com/material-components-web#latest/dist/material-components-web.min.css" rel="stylesheet">
<script src="https://unpkg.com/material-components-web#latest/dist/material-components-web.min.js"></script>
There is no JavaScript error. It is just the slider on the screen that does not work. (It looks ok, but it does not work.)
I think this is a problem with MDC and the DOM state. The example in the link above suggests that the DOM is ready, but it does not say so. And it does not explain how to check this when manipulating the DOM with JavaScript.

it seems the latest version on unpkg was recently changed from 8.0.0 to 9.0.0 fixing this issue
<script src="https://unpkg.com/material-components-web#9.0.0/dist/material-components-web.js"></script>
<link href="https://unpkg.com/material-components-web#9.0.0/dist/material-components-web.css" rel="stylesheet">
<div class="mdc-slider">
<input class="mdc-slider__input" type="range" min="0" max="100" value="50" name="volume" aria-label="Continuous slider demo">
<div class="mdc-slider__track">
<div class="mdc-slider__track--inactive"></div>
<div class="mdc-slider__track--active">
<div class="mdc-slider__track--active_fill"></div>
</div>
</div>
<div class="mdc-slider__thumb">
<div class="mdc-slider__thumb-knob"></div>
</div>
</div>
<script>
sldr = new mdc.slider.MDCSlider(document.querySelector('.mdc-slider'));
sldr.root.addEventListener('MDCSlider:change', (e)=>console.log(e));
</script>
now works as expected https://stackblitz.com/edit/js-4ycwx5?file=index.html

Here is some documentation about using MDC Web in plain JavaScript - https://material.io/develop/web/docs/importing-js, section "Global / CDN".
Make sure you call JavaScript after slider HTML is loaded. Usually I insert it just before the closing body tag.
Here is an example of slider initialization code for JavaScript:
const MDCSlider = mdc.slider.MDCSlider;
const slider = new MDCSlider(document.querySelector('.mdc-slider'));
Here is a minimum working example of the MDCSlider - https://jsfiddle.net/klyakh/oky0zf7e/1/

Related

Modifying MDL elements on page load

I am trying to set the value of a mdl slider when a page loads. The recommended way of setting the value for a mdl slider is like this-
document.querySelector('#slider').MaterialSlider.change(value);
This however throws an error TypeError: document.querySelector(...).MaterialSlider is undefined if called from $(document).ready() or $(window).load().
Setting a timeout of a second on it fixes the issue but seems hacky.
Is there any other event I can tie it to to ensure it works?
This is how I am loading the scripsts --
//mobile optimized
meta(name='viewport', content='width=device-width, initial-scale=1.0')
//css
link(rel='stylesheet', href='/stylesheets/style.css')
//material-design-lite
link(rel='stylesheet', href='/bower_components/material-design-lite/material.min.css')
script(src='/bower_components/material-design-lite/material.min.js')
link(rel='stylesheet', href='https://fonts.googleapis.com/icon?family=Material+Icons')
//jQuery
script(src='/bower_components/jquery/dist/jquery.min.js')
//Material icon fonts
//link(rel="stylesheet", href="https://fonts.googleapis.com/icon?family=Material+Icons")
link(href='https://fonts.googleapis.com/css?family=Open+Sans', rel='stylesheet', type='text/css')
//polyfill (support for dialog)
script(src="/bower_components/dialog-polyfill/dialog-polyfill.js")
link(rel="stylesheet", type="text/css", href="/bower_components/dialog-polyfill/dialog-polyfill.css")
It took me a few months but I finally found a solution to this. Just needed to add this --
$( document ).ready(function() {
componentHandler.upgradeAllRegistered();
// --- do stuff on mdl elements here ---
});
This has the added advantage of hiding the ugly version of the mdl components before they are fully loaded.
Based on your error message, I do agree with the question line that #e666 is going down. Some other things to check is where you are loading MDL relative to the other scripts. Script loading can get a bit tricky sometimes.
Besides that, something else you can consider is setting the value of the slider in the DOM directly if you are building your HTML pages out dynamically on the server.
For example, a slider's HTML looks like this:
<p style="width:300px">
<input class="mdl-slider mdl-js-slider" type="range" id="s1" min="0" max="10" value="4" step="2">
</p>
Note the value option. You could set that value dynamically with server side code if that is a possible alternative for you.
If you were working with ASP.NET, you may do something like this.
#model MyModel
<div>
<p style="width:300px">
<input class="mdl-slider mdl-js-slider" type="range" id="s1" min="0" max="10" value="#Model.InitialValue" step="2">
</p>
</div>
But, if you are having issues with your JavaScript loading, I would recommend making sure everything is loading properly before going further as it will likely affect you later on.
In which order are your slider and your javascript code?
If you first call your function and then create the slider, the function won't find it. That might be the reason why it is undefined.
That's also the reason why it works after a waiting time of one second. In this one second the page has been loaded completly and the slider can be found.
If you create the slider first and change it afterwards, you can manipulate it.
You can do this with a code-block after the slider, where the function to change the sliders value is called.

My live-search element is not transforming into an input box

I'm using the livesearch plugin for Angular-JS to try and create an AJAX dynamic search box. Following tutorials, I believe that I have everything set up as it should be, but when the page runs, it doesn't transform from a <live-search> element to an <input> element. I can't figure out why.
In my code, I have the scripts ordered like this:
<script src="/Scripts/angular/angular.js"></script>
<script src="/Scripts/Custom/liveSearch.js"></script>
<script src="/Scripts/Custom/application.js"></script>
<script src="/Scripts/Controllers/salesEventEdit.ctrl.js"></script>
Here is a jsFiddle of the relevant code. If you need more, I can update it, but to make it completely functional would be a ton of code to copy over, thanks to angular. The code that I've included in the fiddle is a portion of the salesEventEdit.ctrl.js file.
From everything that I've read, the transformation from <live-search> to <input> should be taken care of via angular by itself and I shouldn't have to do anything.
To help with people in the future in case my fiddle disappears, here is the relevant HTML:
<span class="liveSearchWrap">
<live-search type="text"
class="liveSearch"
name="entitySearch"
live-search-callback="entityCallback"
live-search-item-template="{{result.Name}}"
live-search-select="Name"
live-search-max-result-size="50"
live-search-wait-timeout="500"
live-search-selected-id="Id"
user-id="entity.Id"></live-search>
<a class="btnSearch"><i class="fa fa-search"></i></a>
</span>
While the LiveSearch module does automatically handle <live-search> elements, it needs to be injected into the application. As shown in the GitHub page's README here, inject it like so:
var app = angular.module("MyApp", ["LiveSearch"]);
// -------------------------HERE --^

Swipebox - Loading HTML instead of images

I chose Swipebox as my lightbox because the requirements that I want is that it is swipable in mobile devices ad is responsive.
I mainly used this for images. However, I have a use case where I want to use Swipebox to show HTML.
Can this be done?
If this feature is not supported by Swipebox, are there any alternatives that support the featureset that I am looking for(swipeable + responsive + can show HTML)?
Swipebox can display inline content. Probably is not documented but you can view it in this issue answer:
https://github.com/brutaldesign/swipebox/issues/248
...
...
<div style="display: none">
<div id="slide1">Slide 1 Content</div>
<div id="slide2">Slide 2 Content</div>
</div>
I use the option "afterOpen: function () {}" clean the content of swipebox and put my content there. Here is my code:
var html = $('the HTML');
$('.swipebox').swipebox({
afterOpen: function () {
$('#swipebox-slider').empty();
$('#swipebox-slider').append(html);
}
});
I found this one (bxSlider) but I have not tried it yet. It claims to support what you need.
Perhaps your CSS isnt loaded correctly.
Check to make sure that you have the following code within your head:
<link rel="stylesheet" href="source/swipebox.css"/>
Hope this helps,
#_Sub

Dynamic Content Swap via AJAX

Only this much now: I'm creating a vcard design for myself. My motivation is to make it look as good as possible. I want to apply to a webdesign company with this vcard to get a professional education for webdesign.
I still have a lot to change till it completely fulfills in my requirements, but this is my current version of the design I just uploaded to get you an overview over the design.
So as you can see it's focused on retro, vintage, ribbons and scetch elements.
Right know I want to get rid of these jerking content refreshs. So I thought a dynamic content swap via ajax and jQuery would be the best way to do it.
I never did much with js or actually ajax.
I want to ask you guys about a solution you think benefits in my design. I was thinking about something smoothly.
The content which needs to be changed is placed in
<nav>
(...)
<ul class="ribbon s"><!--Following links got the class="ribbon b/p/l/k"-->
<li class="ribbon-content">Link</li>
<!--
?content=blog
?content=portfolio
?content=lebenslauf
?content=kontakt
-->
</ul>
(...)
</nav>
<section id="content">
<div class="con clearfix">
(...)
</div><!--An empty div for possibly swapping without touching the vintage paper thing -->
</section>
http://robert-richter.com/boilerplate/
for example use jquery.
first add jquery to your html. within the domready-event you can register click events on your ribbon-menue. on each click you load the div-content from the given link-url in the html-part.
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript">
$.ready(function(){
$(".ribbon-content a").on("click", function(event){
event.preventDefault();
$(".con").load($(event.target).attr("href"), function(){
// add code after loading - for example change classes of menue
})
});
})
</script>
additionly you can the the browser-history to enable the prev- and next-buttons of the browser.

jquery selectors problem and efficiency

Hi I have a problem(not exactly problem, I have solved it, but it is at least very interesting) with differet bahaviour of jquery selectors in IE(7-8) mobile Opera, and other browsers..
Here is my example
<div id="galleryEl"><link href="http://designclub.cz/plugins/content/plugin_jw_sig/sig.css" rel="stylesheet" type="text/css">
<style type="text/css">.sig_cont {width:30px;height:20px;}</style>
<script type="text/javascript" src="http://designclub.cz/plugins/content/plugin_jw_sig/mootools.js"></script>
<script type="text/javascript" src="http://designclub.cz/plugins/content/plugin_jw_sig/slimbox.js"></script>
<div class="sig"><div class="sig_cont"><div class="sig_thumb"><a href="http://designclub.cz/images/stories/hp/hp-falper.jpg" rel="lightbox[sig0]" title="<b>hp-falper.jpg</b>" alt="hp-falper.jpg" target="_blank"><img src="http://designclub.cz/plugins/content/plugin_jw_sig/showthumb.php?img=hp/hp-falper.jpg&width=0&height=0&quality=0">
Sorry about the formatting:)
The problem is following..When I use this selector jQuery("#galleryEl .sig_thumb a").eq(index); (index is really an integer) in major modern browsers it just works..
but in IE(7-9) (6 ia haven't tested) it doesn't..When I look into IE developer console, it looks like the result object is some kind of plain dom object???I am really not sure, not so skilled in js, but it seems so:)
When I change the jQuery(".sig_thumb a").eq(index); it selects the right dom element..The markup is so weird because of it's a joomla plugin, I am using it to dynamicaly creating background slideshows accroding to folder structure..So does anybody know wherefrom comes this weird behaviour?
And second question..I really want to make it efficient, so which kind of selector is the best one in this case?I know that when selecting over id, jQuery uses js native method, the same in case of tagName and so on, but I am really not sure how about the combinations if this selectors(whether is better to use id-tag-class-someOtherStuff, or id-class-someOtherStuff, id-someOtherStuff {in case that between id and the result object are many other DOM elements})
Thank for your help
Be sure that there is only 1 element with the ID "galleryEl" . If there are more than one, it depends on the IE-Version and the compatibility-mode if the first or the last be selected.
example for testing:
<script type="text/javascript">
jQuery(
function($)
{
alert('Found:'+jQuery("#someID .someclass").eq(1).text());
}
);
</script>
<div id="someID"><span class="someclass">1</span></div>
<div id="someID"><span class="someclass">2</span><span class="someclass">3</span></div>

Categories

Resources