Handling button mdl-js styling with dynamic innerHTML change - javascript

Changing <button> innerHTML seems to deactivate mdl-js-ripple-effect.
Use the method mentioned here to dynamically build a new element as the workaround or report this as a bug?
<body>
<button id="myButton" class="mdl-button mdl-js-button mdl-js-ripple-effect">OLD VALUE
</button>
</body>
JS:
window.addEventListener("load", () => {
document.getElementById("myButton").innerHTML = "new value";
});
http://codepen.io/anon/pen/KVvMOE
Tried the componentHandler.upgradeElement(button) on the existing element after setting new html, but as mentioned in the docs it's only good for new ones. Trying to reuse existing elements.

I when the component is parsed and upgraded by the MDL script, a lot of extra attributes are added to the outer node, and extra HTML added inside. That means both that setting the innerHTML will remove some of the necessary markup inside and that the upgradeElement will fail because of the markup that was added to the outer node.
You should try de-upgrading the button with componentHandler.downgradeElements first, then set the innerHTML, then call componentHandler.upgradeElement.
Some untested sample code:
function setText(element,newtext){
componentHandler.downgradeElements(element);
element.innerHTML=newtext;
componentHandler.upgradeElement(element);
}
setText(document.getElementById('myButton'),'new value');

I'm having a similar issue. I'm trying to add some card via innerHtml into the page. The card contains a radio button using the class mdl-radio.
Everything seems to work fine, but the radio button doesn't load the style. I'm seeing a simple radio button not the styled one. If I add the card to the page from the beggining the radio button looks OK, as expected.
Any comment is welcome, I'm not sure how to fix this.
main.innerHTML = '<!-- CARD PREGUNTA-->\
<div class="demo-cards mdl-cell mdl-cell--4-col mdl-cell--8-col-tablet" style="margin: 0 auto; display: none;" id="pregunta_card">\
<div class="demo-updates mdl-card mdl-shadow--2dp mdl-cell mdl-cell--4-col mdl-cell--4-col-tablet mdl-cell--12-col-desktop">\
<!-- Contenido -->\
<div class="mdl-card__supporting-text mdl-color-text--grey-600">\
<h2 class="mdl-card__title-text" id="pregunta_card_title"></h2>\
<br>\
<br>\
<!-- Radio Button 1 -->\
<label id="opt1" class="mdl-radio mdl-js-radio mdl-js-ripple-effect" for="option1">\
<input type="radio" id="option1" class="mdl-radio__button" name="options"/>\
<!-- intitial state checked using attribute checked -->\
<span class="mdl-radio__label" id="option1_value"></span>\
</label>\
</div>\
</div>'

Related

Google Analytics - Get nested span event click without class and id

I am using Tag manager and Anayltics 360.
My code as follows,
<div rel="ABC_Links" class="ak_widget" >
<!-- BEGIN: Widget - Links -->
<section class="mfb-30">
<div class="widget_links">
<div class="widget_container">
<div class="widget_content">
<button type="button" class="buttonShadow" onclick="window.open('https://somepagelink.aspx); return false;">
<div class="widget_item">
<div class="widget_icon">
<svg>123</svg>
</div>
<div class="widget_text"><span style="overflow-wrap: normal;">ABCD TEXT</span></div>
</div>
</button>
<button type="button" class="buttonShadow" onclick="window.open('https://somepagelink.aspx); return false;">
<div class="widget_item">
<div class="widget_icon">
<svg> 12345</svg>
</div>
<div class="widget_text"><span style="overflow-wrap: normal;">XYZ TEXT</span></div>
</div>
</button>
</div>
</div>
</div>
</section>
<!-- END: Widget Links --></div>
I have 12 buttons in this same format. Here i have given an example of two buttons.
Button name i can change later so i can not take it as hard coded for "Click Text" in tag manager.
I can use only rel= "ABC_Links" as unique identifier. I can not use any of below class as they are not unique.
I have used Custome javascript to get parent child relationship but didn't work.
I have used DOM element variable but it did not work.
Now Question is, Is there any way to trigger event in tag manager when i click on any of the button below and get the info in real time event in Anayltics 360 ???
One way to achieve this would be to create a User-Defined Custom JavaScript variable in GTM to set isABCLink=true on button click.
On the Variables screen under Built-In Variables make sure you have "Click Element" ticked.
Create a User-Defined Variable
Name: isABCLink
Type: Custom JavaScript
Code:
function() {
return {{Click Element}}.matches("div[rel=ABC_Links] button, div[rel=ABC_Links] button *");
}
Create a Trigger
Trigger Type: Click - All Elements
This trigger fires on: Some Clicks
Conditions: isABCLink equals true
Set up your tag firing on above trigger
Once caveat to point out is that the exact element clicked on could be the button or one of the child elements of the button such as the <svg> which might make it hard to set up your tag depending on what exactly you need.

HTML element in button prevents disabled in the wrapper element

Fiddle: http://jsfiddle.net/0o1mrapd/20/
Angular stackblitz link: https://stackblitz.com/edit/angular-fhtaki?file=src%2Fapp%2Fapp.component.html
I have a complex case which i need some enlightenment. (For angular developers, you can think the wrapper div as a host selector, <my-button></my-button>)
As you can see in the fiddle I have a disabled button with a wrapper div which has a click event.
<div onclick="alert('hey')" style="display:inline-block">
<button disabled>
<span>Click</span>
</button>
</div>
What I expect is that when I click on that area, nothing will happen but alas I get the alert. If I remove the span element and put plain text inside the button, this works.
<div onclick="alert('hey')" style="display:inline-block">
<button disabled>
Click
</button>
</div>
How can I make the div unclickable in this case? I found out that pointer-events: none does the trick but then I lose the curser-event which I need for accessibility
I stumbled upon this issue while creating a custom button component with an ng-content in Angular but then realized this is bigger than the framework.
Some links i checked:
Can you prevent an Angular component's host click from firing?
Add CSS cursor property when using "pointer-events: none"
How to stop event propagation with inline onclick attribute?
https://github.com/angular/angular/issues/9587
Maybe this example will be useful
function clickHandler() {
console.log('Click');
}
<div onclick="return false;">
<button onclick="clickHandler()">
Click
</button>
</div>
You can use this css property to avoid click event be fired in the span tag. It could be a workaround.
<div onclick="alert('hey')" style="display:inline-block">
<button disabled>
<span style="pointer-events:none;">Click</span>
</button>
</div>

Switching between partial forms using radio inputs

I have this template that depending on which radio input is clicked the form changes. The teacher-signup-form is checked by default.
<!-- when user clicks either teacher or student a different partial will render in view
each partial is wrapped in its own form element -->
<div class="container">
<div class="d-flex flex-row mt-5 mb-5">
<h2 style="font-family: 'champagne-limo';" class="">General Information:</h2>
</div> <!--teacher-student checkboxes -->
<div class="row">
<div class="col-4">
<h5>You are:</h5>
</div>
<div class="col-2">
<input checked name="teacher-student" type="radio" id="teacher-signup">
<label for="teacher-signup">Teacher</label>
</div>
<div class="col-2">
<input type="radio" name="teacher-student" id="student-signup">
<label for="student-signup">Student</label>
</div>
</div>
</div>
<!--this partial would have the id of 'teacher-signup-form' -->
<%-include("./partials/teacher-signup.ejs")%>
<!--this partial would have the id of 'student-signup-form' -->
<%-include("./partials/student-signup.ejs")%>
In my jQuery, I created a simple function that should switch the forms
$('#student-signup-form').hide();
$('#input[name="teacher-student"]:radio').on('change', function(){
$('#teacher-signup-form').hide();
$('#student-signup-form').show();
})
});
Unfortunately this does not work and shows both forms for a few seconds then hides the student-signup-form.
Is there a more cleaner efficient way to do this? My jQuery seems like it isn't the best solution.
I would suggest a few changes. First to hide the student-signup-form on page load you could add the css to do so.
#student-signup-form { display: none; }
Then in order to allow the toggle back and forth from student and teacher, what I would suggest is you give each form a class of signup-form in addition to the ids they have. Then your radio buttons could be changed to something like the following.
<input type="radio" name="teacher-student" class="signup-radio" id="teacher-signup" data-target="#teacher-signup-form" checked>
<input type="radio" name="teacher-student" class="signup-radio" id="student-signup" data-target="#student-signup-form">
Then you can generalize the change handler for the form class and the data element on the radios.
//cache the forms lookup
var $signupForms = $('.signup-form');
$('.signup-radio').on('change', function(e){
var $this = $(e.target);
//hide the forms that do not match the target selector
$signupForms.not($this.data('target')).hide();
//show the form that matches the target selector
$signupForms.filter($this.data('target')).show();
});
Set the initial state based on static CSS. Otherwise while the page is loading you will see both.
So set style display:none on the student partial.
Then your JS would just become
$('#input[name="teacher-student"]:radio').on('change', function(){
$('#teacher-signup-form').toggle();
$('#student-signup-form').toggle();
})
});

dynamically generated data not working

I have link, when an user clicks, it appends the data into a div like this:
<a href="javascript:void(0);" onclick="StartMesssage()">
<span class="font-icon fa fa-pencil"></span>
</a>
<script>
function StartMesssage(){
$(".div1").append(
'<section class="chat-area d2"><div class="chat-area-in"><input type="text" class="form-control spinner" id="to-message" data-mt-filter-control /> </div></section>'
);
}
</script>
Now the problem I'm facing is that data-mt-filter-control is a jQuery plugin when I get HTML tags dynamically it doesn't work but if I add these tags into my HTML
<section class="chat-area d2">
<div class="chat-area-in">
<input type="text" class="form-control spinner" id="to-message" data-mt-filter-control />
</div>
</section>
and refresh my page, then it works
Event driven plugin's normally has an init method that runs on page load.
After adding content dynamically you likely need to call that init method again, or else their event's is not called/fired on those dynamic added elements.

Adding multiple buttons to form

I'm calling on multiple buttons to show up but it seems that only one button shows up. Please tell me why. I've tried adding a in the body with a class but that seems to screw up the button that's already hidden.
This form basically shows a button when the url contains iphone
Example: http://jsfiddle.net/SDq4P/35/show/#iPhone
Here's the JSFiddle: http://jsfiddle.net/SDq4P/35/
I need all three buttons to show at one time. All three buttons contain iphone but only one shows up.
<div id="linkdiv" href="phone-condition" onclick="location.href = $(this).attr('href')+'?/1234/#iPhone';return false" />
<div id="linkdiv" href="phone-condition" onclick="location.href = $(this).attr('href')+'?/1234/#iPhone';return false" />
<div id="linkdiv" href="phone-condition" onclick="location.href = $(this).attr('href')+'?/1234/#iPhone';return false" />
Try to make use of class instead of IDs. HTML ID is supposed to be unique and your sample HTML has three DIV elements with the same ID. If you are using jQuery like $('#linkDiv') and do something, only the first element is selected.
Use <div ...></div> instead. I don't think you can end divs using the XHTML />. If you check in Chrome Dev Tools the buttons are nested into each other.
It's because your css is targeting a class called "select." Just add the class to the divs and they will show up. Your id's also need to be unique. Here's a fix that should work:
<div class="select" id="linkdiv1" href="phone-condition" onclick="location.href = $(this).attr('href')+'?/1234/#iPhone';return false"></div>
<div class="select" id="linkdiv2" href="phone-condition" onclick="location.href = $(this).attr('href')+'?/1234/#iPhone';return false"></div>
<div class="select" id="linkdiv3" href="phone-condition" onclick="location.href = $(this).attr('href')+'?/1234/#iPhone';return false"></div>
see it in action:
http://jsfiddle.net/mHU84/

Categories

Resources