style stripe payment element layout - get rid of stripe grid system - css

I'm trying to configure the stripe payment element for a custom design
From whay I could see, the only option I have is to use the Elements Appearance API
That's because stripe dinamycally inserts an iframe with the markup (to remain PCI DSS compliant), and that's why I can't find a way to modify it.
Stripe payment element generates the following markup
<div class="p-Grid p-CardForm">
<div class="p-GridCell p-GridCell--12 p-GridCell--md6">
<!-- CardNumberInput -->
</div>
<div class="p-GridCell p-GridCell--6 p-GridCell--md3">
<!-- expiryInput -->
</div>
<div class="p-GridCell p-GridCell--6 p-GridCell--md3">
<!-- cvcInput -->
</div>
</div>
Which uses some custom stripe grid system and produces this:
And above md it displays the following (it's applying the p-GridCell--mdXX classes):
I need to keep the first layout regardless the size of the viewport. How can I disable stripe grids or choose what clases to apply?
Update:
I tried the following approaches to modifiy the classes being applied, with no success:
Use javascript to inject a style tag to the iframe's head:
const iframe = document.getElementsByTagName('iframe')[0]; // this works
const doc = iframe.contentDocument; // woops, this is always null!!!
doc.body.innerHTML = doc.body.innerHTML + '<style>.....' // so I can't do something like this
(taken from this article)
Use javascript to get a reference to the container divs and modify the classes being applied (this approach works in the developer console, only after you inspect the element, but it doesn't work from a javascript block from the html page hosting the iframe)
const numberInput = document.getElementById('Field-numberInput'); // returns null
const numberContainer = document.querySelector('.p-GridCell.p-GridCell--12.p-GridCell--md6'); // also returns null
Following this guide I also tried:
const iframe = document.getElementsByTagName('iframe')[0]; // this works
let y = iframe.contentWindow.document;
y.body.style.backgroundColor = "red";
Which throws the following error:
FormElement.svelte:28 Uncaught DOMException: Blocked a frame with origin "http://localhost:3000" from accessing a cross-origin frame.
at HTMLButtonElement.updateStyle

I dont know stripe-payment css file but maybe changing md6 to md12 and md3 to md6 will work.
<div class="p-Grid p-CardForm">
<div class="p-GridCell p-GridCell--12 p-GridCell--md12">
<!-- CardNumberInput -->
</div>
<div class="p-GridCell p-GridCell--6 p-GridCell--md6">
<!-- expiryInput -->
</div>
<div class="p-GridCell p-GridCell--6 p-GridCell--md6">
<!-- cvcInput -->
</div>
</div>
will work

Related

Applying a broad css-changing function to a particular div ID with 'onClick' React/Nextjs

I have a multi-stage dropdown component that works, but unfortunately is applied to all divs that share the same className. I.e: all items drop down when one is clicked - when I obviously just want the one clicked.
Ive tried other solutions that involve mapping, using (this) and also selecting the div by id via document query then iteration with for loops but nothing has worked. Mainly because even if I can isolate the div (say with useRef e.g.), trigging the function inherently involves applying the style change to all divs with the same classname. With this in mind, I'm pretty sure I need to change the initial css hook. Alternative is obviously to give each dropdown item its own css class which I feel would be too repetitive to even try.
Here is my code (for berevity Ive just included the dropdown and not scroll up, also just one of the items - html is identical for the other 7 items:
const [content, Toggle] = useState(styles.CT007Content)
const [TrackList, Drop] = useState(styles.songContainer)
const [artwork, Slide] = useState(styles.artworkContainer)
const [title, Darkmode] = useState(styles.releaseTitle)
const [arrow, Unlock] = useState(styles.arrow)
const open = () => {
if (arrow==styles.arrow){
Unlock(styles.arrowChecked);}
if (title==styles.releaseTitle){
Darkmode(styles.releaseTitleClicked)};
if (TrackList==styles.songContainer){
Drop(styles.songContainerOpen)};
if (content==styles.CT007Content){
Toggle(styles.CT007ContentOpen)};
if (artwork==styles.artworkContainer){
Slide(styles.artworkContainerOpen)};
html
{/* item 1 of 10 */}
<div className={styles.Release} id="CT007">
<div className={styles.releasesHeader} id="CT007">Releases (2014-2018, 2022)</div>
<div className={title} onClick={open} id="CT007">CT007
<div className={arrow} id="CT007">></div>
<div className={arrow} id="CT007">></div>
<div className={arrow} id="CT007">></div>
</div>
<content className={content} id="CT007">
<div className={TrackList} id="CT007">
<div className={styles.trackContainer} onClick={changeStyle} id="CT007">
<audio controls className={audiostyle} src="/TEX86.mp3" id="CT007">
{/* <source src="/TEX86.mp3" type = "audio/mpeg"/> */}
</audio>
<div className={styles.trackText} id="CT007">
<h4>You&apos;ll Never Get Rich</h4>
</div>
</div>
<div className={styles.trackContainer} id="CT007">
<audio controls className={audiostyle} id="CT007">
<source src="" type = "audio/mpeg"/>
</audio>
<div className={styles.trackText} id="CT007">
<h4>Death by Dole</h4>
</div>
</div>
</div>
<div className={artwork} id="CT007">
<svg src=""/>
</div>
</content>
</div>
To iterate, the functionality works fine, I just dont want it applied to all divs when only one is clicked. Many thanks in advance. Im sure it is something obvious but I am new to react, any help would be appreciated
documentQuery Selector, wrapping hook in a function for each div OnClick, mapping/for looping

Data binding in polymer content tag

I am new to polymer & trying to create a configurable template for the received iron-ajax response, means the end user who is using the component can decide the items which need to be displayed in the screen, so I used content tag inside the template but the data is not getting bind with my custom element.
index.html
<custom-element>
<div class="selected_content">
<h2>{{item.id}}</h2>
<span>{{item.member.dept.name}}</span>
</div>
</custom-element>
customElement.html
<iron-ajax
auto
url={{url}}
handle-as="json"
last-response={{lastresponse}}
debounce-duration="300"></iron-ajax>
<template is="dom-repeat" items=[[lastresponse]]>
<content select=".selected_content"></content>
</template>

FullpageJs and Meteor : Capture event from template

I'm struggling with fullpage.js in Meteor.
When I add a button inside a template, the Template.templatename.events function does not fire on event.
For example:
Template HTML (messages.html)
<template name="messages">
<ul>
{{#each mess}}
<li>{{ messContent}}</li>
{{/each}}
<button class="addMessage">Add Message!</button>
</ul>
</template>
Template JavaScript (messages.js)
Template.messages.helpers({
mess: function(){
return Messages.find();
}
});
Template.messages.events({
'click .addMessage' : function(event){
console.log("clicked")
}
})
Main HTML
<head>
<title>fulltest</title>
</head>
<body>
{{> full}}
</body>
<template name="full">
<div id="fullpage">
<div class="section active">
<h1>First slide</h1>
{{> messages}}
</div>
<div class="section">
<h1>Second slide</h1>
</div>
</div>
</template>
My fullpage initialisation:
Template.full.rendered = function(){
$('#fullpage').fullpage();
}
If I remove the fullpage initialisation then the click event gets logged. Still new at Meteor, I didn't manage to grasp what's going wrong here.
All help much appreciated,
Joris
Use delegation or use verticalCentered:false and scrollOverflow:false.
From the fullPage.js FAQs:
My javascript/jQuery events don't work anymore when using fullPage.js
Short answer: if you are using options such as verticalCentered:true or overflowScroll:true in fullPage.js initialization, then you will have to treat your selectors as dynamic elements and use delegation. (by using things such as on from jQuery). Another option is to add your code in the afterRender callback of fullpage.js
Explanation: if you are using options such as verticalCentered:true or overflowScroll:true of fullPage.js, your content will be wrapped inside other elements changing its position in the DOM structure of the site. This way, your content would be consider as "dynamically added content" and most plugins need the content to be originally on the site to perform their tasks. Using the afterRender callback to initialize your plugins, fullPage.js makes sure to initialize them only when fullPage.js has stopped changing the DOM structure of the site.

How do i get an onload function on the body for a specific template using meteor.js?

I'm trying to get the following behavior for a certain template:
<body onload="someInitFunction();">
Let's say i have the following markup (i'm using mrt router, not iron-router, for {{renderPage}}):
// Main Template
<head>
<title>meteorite-knowviz</title>
</head>
<body>
{{> header}}
<div class="container-fluid">
<div class="row">
{{renderPage}}
</div>
</div>
{{> footer}}
</body>
That renderPage is the secondTemplate:
<template name="secondTemplate">
{{#if currentUser}}
<div class="col-md-2">
<div class="list-group">
<a class="list-group-item" href="{{render thirdTemplate please...}}">Third Template</a>
<a class="list-group-item" href="{{render fourthTemplate please...}}">Fourth Template</a>
</div>
</div>
// In this case let's say thirdTemplate gets rendered
{{render the choice taken above please...}}
{{/if}}
</template>
And within this template, depending on which link was clicked on, (in this case the third) there will finally be a thirdTemplate, which will show a data visualization with some help by a javascript framework, which will be in need of a <body onload="initFunction();">in order to display the data:
<template name="thirdTemplate">
<div class="col-md-5">
<h2>THIS!! section needs a "<body onload="initFunction();"> in order to work" ></h2>
</div>
<div class="col-sm-5">
<h2>Some other related content here</h2>
</div>
</template>
To sum up i have three questions:
1a. How could i get the third template to get a <body onload="initFunction();">
2a. In which way can i render different templates within the secondTemplate?
2b. Can i use a {{renderPage}} within this template even though this template is the renderedPage in the main template or should i do it in some other way?
In order to get the <body onload="initFunction();"> i had to do the following:
First add the following function to a .js file in the client folder:
Template.thirdTemplate.rendered = function() { // Template.thirdTemplate.created - also worked.
$('body').attr({
onload: 'init();'
});
}
This however got me an error saying that initFunction is not defined. In an standard html page my could work just fine, but in meteor i had to change my function from:
function initFunction(){
//what ever i wished to do
}
To:
init = function() {
//what ever i wished to do
}
Regarding the rendering of pages, iron-routing is the way to go since the router add on is not under development any more.
1a. How could i get the third template to get a <body
onload="initFunction();">
You probably want to call initFunction when the third template has been rendered, so just put your call to it in the rendered callback.
Template['thirsTemplate'].rendered = function(){
initFunction()
}
2a. In which way can i render different templates within the
secondTemplate?
2b. Can i use a {{renderPage}} within this template even though this
template is the renderedPage in the main template or should i do it in
some other way?
Listen for clicks on the links, and when one happen you manually render the desired template (possible with Meteor.render, if you need reactivity) and add it to the right node in the document. See this question.
It may be possibly to achieve with router (I don't know that package).
I think that what you want to use is the created callback, that will be called each time your template is created, and not the rendered callback, that would be called each time a change has caused the template to re-render.
Template.thirdTemplate.created = function(){
initFunction()
}
See the documentation for templates for other types of callbacks: http://docs.meteor.com/#templates_api

angular js dom manipulation with directives

I am trying to use angular directives to dynamically replace an html portion of a portlet of a page.
The html portlet has 2 sections embedded. The top part has the heading which is obtained from a different backend service
<div class="headerdiv">
<h3 class='headerclass'> Object Heading </h3>
</div>
The content is loaded in to a different section
<div id="objectDiv" ng-controller="ObjectCtrl">
<div ng-show="object.title" mydirective><b>{{object.title}} </b></div>
<div element-trigger><b>{{object.name}} </b></div>
<div element-trigger><b>{{object.description}} </b></div>
</div>
The controller loads the details successfully
The new directive added is
app.directive('mydirective', function(){
return function(scope, elem, attrs){
//obtain old header
var oldHeader = angular.element( '.headerdiv .headerclass' );
//get the new header
//replace old header with new header
}
});
I need to dynamically change the heading in headerdiv with the object.title value . Note that the new directive is bound to the filed that is listening to the object.title div.
I dont think this is the right use of directive, as the directive should be used to affect the functionality of element on which it is defined in most of the cases.
What you can try to do is in ObjectCtrl define a watch on title property, and then broadcast the message
$scope.$watch('object.title',function(newValue) {
$rootScope.$broadcast('titleChanged',newValue); //You can pass any object too
});
If you header is contained inside a controller catch the event
$scope.$on('titleChanged',function(args) {
//Code to handle the title update
});
The html for header should have binding expression for title
<div class="headerdiv">
<h3 class='headerclass'> {{title}} </h3>
</div>
Note: I am not sure about the structure of the html but this all would not be required if the header and the content inside the ObjectCtrl are using the same\shared model (object).

Resources