
Recherche avancée
Autres articles (15)
-
Creating farms of unique websites
13 avril 2011, par kent1MediaSPIP platforms can be installed as a farm, with a single "core" hosted on a dedicated server and used by multiple websites.
This allows (among other things) : implementation costs to be shared between several different projects / individuals rapid deployment of multiple unique sites creation of groups of like-minded sites, making it possible to browse media in a more controlled and selective environment than the major "open" (...) -
Les autorisations surchargées par les plugins
27 avril 2010, par kent1Mediaspip core
autoriser_auteur_modifier() afin que les visiteurs soient capables de modifier leurs informations sur la page d’auteurs -
Gestion des droits de création et d’édition des objets
8 février 2011, par kent1Par défaut, beaucoup de fonctionnalités sont limitées aux administrateurs mais restent configurables indépendamment pour modifier leur statut minimal d’utilisation notamment : la rédaction de contenus sur le site modifiables dans la gestion des templates de formulaires ; l’ajout de notes aux articles ; l’ajout de légendes et d’annotations sur les images ;
Sur d’autres sites (3910)
-
Google Analytics Now Illegal in Austria ; Other EU Member States Expected to Follow
18 janvier 2022, par Erin — PrivacyBreaking news : The Austrian Data Protection Authority (“Datenschutzbehörde” or “DSB” or “DPA”) has ruled that Austrian website providers using Google Analytics are in violation of the GDPR.
This ruling stems from a decision made in 2020 by the Court of Justice of the European Union (CJEU) that stated that cloud services hosted in the US are incapable of complying with the GDPR and EU privacy laws. The decision was made because of the US surveillance laws requiring US providers (like Google or Facebook) to provide personal data to US authorities.
The 2020 ruling, known as “Schrems II”, marked the ending of the Privacy Shield, a framework that allowed for EU data to be transferred to US companies that became certified.
The tech industry was sent into a frenzy following this decision, but many US and EU companies decided to ignore the case. The choice to ignore is what landed one Austrian business in the DPA’s line of fire, damaging the brand’s reputation and possibly resulting in a hefty fine of up to €20 million or 4% of the organisation’s global turnover.
About the Austrian DPA’s Model Case
In this specific case, noyb (the European Center for Digital Rights) found that IP addresses (which are classified as personal data by the GDPR) and other identifiers were sent to the US in cookie data as a result of the organisation using Google Analytics.
This model case led to the DPA’s decision to rule that Austrian website providers using Google Analytics are in violation of GDPR. It is believed that other EU Member States will soon follow in this decision as well.
"We expect similar decisions to now drop gradually in most EU member states. We have filed 101 complaints in almost all Member States and the authorities coordinated the response. A similar decision was also issued by the European Data Protection Supervisor last week."
What does this mean if you are using Google Analytics ?
If there is one thing to learn from this case, it is that ignoring these court rulings and continuing to use Google Analytics is not a viable option.
If you are operating a website in Austria, or your website services Austrian citizens, you should remove Google Analytics from your website immediately.
For businesses in other EU Member States, it is also highly recommended that you take action before noyb and local data protection authorities start targeting more businesses.
"Instead of actually adapting services to be GDPR compliant, US companies have tried to simply add some text to their privacy policies and ignore the Court of Justice. Many EU companies have followed the lead instead of switching to legal options."
Removing Google Analytics from your site doesn’t mean that you need to give up website analytics altogether though. There are a variety of Google Analytics alternatives available today. Matomo in particular is a powerful open-source web analytics platform that gives you 100% data ownership and GDPR compliance.
Glenn F. Henriksen via Twitter Matomo is one of the best Google Analytics alternatives offering privacy by design on our Cloud, On-Premise and Matomo for WordPress. So you can get the insights you need while remaining compliant. As the GDPR continues to evolve, you can rest assured that Matomo will be at the forefront of these changes.
In addition, all Google Analytics data can be imported into Matomo so no historical data is lost. To make your migration as seamless as possible, we’ve put together a guide to migrating from Google Analytics to Matomo.
Ready to begin your journey to GDPR compliance ? Check out our live demo and start your 21-day free trial now – no credit card required.
If you are interested in learning more about GDPR compliance and Matomo, check out our GDPR resources below :
- GDPR Manager user guide
- How to fill in the information asset registration when using Matomo
- How to make Matomo GDPR compliant in 12 easy steps
- How to not process any personal data with Matomo and what it means for you
- PII, personal data and GDPR. Discover what this means for your privacy
- How should I write my privacy notice for Matomo Analytics under GDPR
- Lawful basis for processing personal data under GDPR with Matomo
- How to complete your privacy policy with Matomo Analytics under GDPR
- GDPR compliance for Premium Features
- How to get your Matomo plugin ready for GDPR
- Subprocessors on Matomo Cloud (subprocessors not applicable to On-Premise)
- Privacy in Matomo
What does this mean if you are using Matomo ?
Our users can rest assured that Matomo remains in compliance with GDPR as all data is stored in the EU (Matomo Cloud) or in any country of your choice (Matomo On-Premise). With Matomo you’re able to continue analysing your website and not worry about GDPR.
Final thoughts
For EU businesses operating websites, now is the time to act. While Google pushes out false narratives to try and convince users that it is safe to continue using Google Analytics, it’s clear from these court rulings that the data protection authorities across the EU disagree with Google’s narrative.
The fines, reputational damage and stresses mounting from using Google Analytics are imminent. Find an alternative to Google Analytics as this problem is not going away.
Getting started with Matomo is easy. Make the switch today and start your free 21-day trial – no credit card required.
-
How to Choose the Optimal Multi-Touch Attribution Model for Your Organisation
13 mars 2023, par Erin — Analytics TipsIf you struggle to connect the dots on your customer journeys, you are researching the correct solution.
Multi-channel attribution models allow you to better understand the users’ paths to conversion and identify key channels and marketing assets that assist them.
That said, each attribution model has inherent limitations, which make the selection process even harder.
This guide explains how to choose the optimal multi-touch attribution model. We cover the pros and cons of popular attribution models, main evaluation criteria and how-to instructions for model implementation.
Pros and Cons of Different Attribution Models
First Interaction
First Interaction attribution model (also known as first touch) assigns full credit to the conversion to the first channel, which brought in a lead. However, it doesn’t report other interactions the visitor had before converting.
Marketers, who are primarily focused on demand generation and user acquisition, find the first touch attribution model useful to evaluate and optimise top-of-the-funnel (ToFU).
Pros
- Reflects the start of the customer journey
- Shows channels that bring in the best-qualified leads
- Helps track brand awareness campaigns
Cons
- Ignores the impact of later interactions at the middle and bottom of the funnel
- Doesn’t provide a full picture of users’ decision-making process
Last Interaction
Last Interaction attribution model (also known as last touch) shifts the entire credit allocation to the last channel before conversion. But it doesn’t account for the contribution of all other channels.
If your focus is conversion optimization, the last-touch model helps you determine which channels, assets or campaigns seal the deal for the prospect.
Pros
- Reports bottom-of-the-funnel events
- Requires minimal data and configurations
- Helps estimate cost-per-lead or cost-per-acquisition
Cons
- No visibility into assisted conversions and prior visitor interactions
- Overemphasise the importance of the last channel (which can often be direct traffic)
Last Non-Direct Interaction
Last Non-Direct attribution excludes direct traffic from the calculation and assigns the full conversion credit to the preceding channel. For example, a paid ad will receive 100% of credit for conversion if a visitor goes directly to your website to buy a product.
Last Non-Direct attribution provides greater clarity into the bottom-of-the-funnel (BoFU). events. Yet, it still under-reports the role other channels played in conversion.
Pros
- Improved channel visibility, compared to Last-Touch
- Avoids over-valuing direct visits
- Reports on lead-generation efforts
Cons
- Doesn’t work for account-based marketing (ABM)
- Devalues the quality over quantity of leads
Linear Model
Linear attribution model assigns equal credit for a conversion to all tracked touchpoints, regardless of their impact on the visitor’s decision to convert.
It helps you understand the full conversion path. But this model doesn’t distinguish between the importance of lead generation activities versus nurturing touches.
Pros
- Focuses on all touch points associated with a conversion
- Reflects more steps in the customer journey
- Helps analyse longer sales cycles
Cons
- Doesn’t accurately reflect the varying roles of each touchpoint
- Can dilute the credit if too many touchpoints are involved
Time Decay Model
Time decay models assumes that the closer a touchpoint is to the conversion, the greater its influence. Pre-conversion touchpoints get the highest credit, while the first ones are ranked lower (5%-5%-10%-15%-25%-30%).
This model better reflects real-life customer journeys. However, it devalues the impact of brand awareness and demand-generation campaigns.
Pros
- Helps track longer sales cycles and reports on each touchpoint involved
- Allows customising the half-life of decay to improve reporting
- Promotes conversion optimization at BoFu stages
Cons
- Can prompt marketers to curtail ToFU spending, which would translate to fewer qualified leads at lower stages
- Doesn’t reflect highly-influential events at earlier stages (e.g., a product demo request or free account registration, which didn’t immediately lead to conversion)
Position-Based Model
Position-Based attribution model (also known as the U-shaped model) allocates the biggest credit to the first and the last interaction (40% each). Then distributes the remaining 20% across other touches.
For many marketers, that’s the preferred multi-touch attribution model as it allows optimising both ToFU and BoFU channels.
Pros
- Helps establish the main channels for lead generation and conversion
- Adds extra layers of visibility, compared to first- and last-touch attribution models
- Promotes budget allocation toward the most strategic touchpoints
Cons
- Diminishes the importance of lead nurturing activities as more credit gets assigned to demand-gen and conversion-generation channels
- Limited flexibility since it always assigns a fixed amount of credit to the first and last touchpoints, and the remaining credit is divided evenly among the other touchpoints
How to Choose the Right Multi-Touch Attribution Model For Your Business
If you’re deciding which attribution model is best for your business, prepare for a heated discussion. Each one has its trade-offs as it emphasises or devalues the role of different channels and marketing activities.
To reach a consensus, the best strategy is to evaluate each model against three criteria : Your marketing objectives, sales cycle length and data availability.
Marketing Objectives
Businesses generate revenue in many ways : Through direct sales, subscriptions, referral fees, licensing agreements, one-off or retainer services. Or any combination of these activities.
In each case, your marketing strategy will look different. For example, SaaS and direct-to-consumer (DTC) eCommerce brands have to maximise both demand generation and conversion rates. In contrast, a B2B cybersecurity consulting firm is more interested in attracting qualified leads (as opposed to any type of traffic) and progressively nurturing them towards a big-ticket purchase.
When selecting a multi-touch attribution model, prioritise your objectives first. Create a simple scoreboard, where your team ranks various channels and campaign types you rely on to close sales.
Alternatively, you can survey your customers to learn how they first heard about your company and what eventually triggered their conversion. Having data from both sides can help you cross-validate your assumptions and eliminate some biases.
Then consider which model would best reflect the role and importance of different channels in your sales cycle. Speaking of which….
Sales Cycle Length
As shoppers, we spend less time deciding on a new toothpaste brand versus contemplating a new IT system purchase. Factors like industry, business model (B2C, DTC, B2B, B2BC), and deal size determine the average cycle length in your industry.
Statistically, low-ticket B2C sales can happen within just several interactions. The average B2B decision-making process can have over 15 steps, spread over several months.
That’s why not all multi-touch attribution models work equally well for each business. Time-decay suits better B2B companies, while B2C usually go for position-based or linear attribution.
Data Availability
Businesses struggle with multi-touch attribution model implementation due to incomplete analytics data.
Our web analytics tool captures more data than Google Analytics. That’s because we rely on a privacy-focused tracking mechanism, which allows you to collect analytics without showing a cookie consent banner in markets outside of Germany and the UK.
Cookie consent banners are mandatory with Google Analytics. Yet, almost 40% of global consumers reject it. This results in gaps in your analytics and subsequent inconsistencies in multi-touch attribution reports. With Matomo, you can compliantly collect more data for accurate reporting.
Some companies also struggle to connect collected insights to individual shoppers. With Matomo, you can cross-attribute users across browning sessions, using our visitors’ tracking feature.
When you already know a user’s identifier (e.g., full name or email address), you can track their on-site behaviours over time to better understand how they interact with your content and complete their purchases. Quick disclaimer, though, visitors’ tracking may not be considered compliant with certain data privacy laws. Please consult with a local authority if you have doubts.
How to Implement Multi-Touch Attribution
Multi-touch attribution modelling implementation is like a “seek and find” game. You have to identify all significant touchpoints in your customers’ journeys. And sometimes also brainstorm new ways to uncover the missing parts. Then figure out the best way to track users’ actions at those stages (aka do conversion and events tracking).
Here’s a step-by-step walkthrough to help you get started.
Select a Multi-Touch Attribution Tool
The global marketing attribution software is worth $3.1 billion. Meaning there are plenty of tools, differing in terms of accuracy, sophistication and price.
To make the right call prioritise five factors :
- Available models : Look for a solution that offers multiple options and allows you to experiment with different modelling techniques or develop custom models.
- Implementation complexity : Some providers offer advanced data modelling tools for creating custom multi-touch attribution models, but offer few out-of-the-box modelling options.
- Accuracy : Check if the shortlisted tool collects the type of data you need. Prioritise providers who are less dependent on third-party cookies and allow you to identify repeat users.
- Your marketing stack : Some marketing attribution tools come with useful add-ons such as tag manager, heatmaps, form analytics, user session recordings and A/B testing tools. This means you can collect more data for multi-channel modelling with them instead of investing in extra software.
- Compliance : Ensure that the selected multi-attribution analytics software wouldn’t put you at risk of GDPR non-compliance when it comes to user privacy and consent to tracking/analysis.
Finally, evaluate the adoption costs. Free multi-channel analytics tools come with data quality and consistency trade-offs. Premium attribution tools may have “hidden” licensing costs and bill you for extra data integrations.
Look for a tool that offers a good price-to-value ratio (i.e., one that offers extra perks for a transparent price).
Set Up Proper Data Collection
Multi-touch attribution requires ample user data. To collect the right type of insights you need to set up :
- Website analytics : Ensure that you have all tracking codes installed (and working correctly !) to capture pageviews, on-site actions, referral sources and other data points around what users do on page.
- Tags : Add tracking parameters to monitor different referral channels (e.g., “facebook”), campaign types (e.g., ”final-sale”), and creative assets (e.g., “banner-1”). Tags help you get a clearer picture of different touchpoints.
- Integrations : To better identify on-site users and track their actions, you can also populate your attribution tool with data from your other tools – CRM system, A/B testing app, etc.
Finally, think about the ideal lookback window — a bounded time frame you’ll use to calculate conversions. For example, Matomo has a default windows of 7, 30 or 90 days. But you can configure a custom period to better reflect your average sales cycle. For instance, if you’re selling makeup, a shorter window could yield better results. But if you’re selling CRM software for the manufacturing industry, consider extending it.
Configure Goals and Events
Goals indicate your main marketing objectives — more traffic, conversions and sales. In web analytics tools, you can measure these by tracking specific user behaviours.
For example : If your goal is lead generation, you can track :
- Newsletter sign ups
- Product demo requests
- Gated content downloads
- Free trial account registration
- Contact form submission
- On-site call bookings
In each case, you can set up a unique tag to monitor these types of requests. Then analyse conversion rates — the percentage of users who have successfully completed the action.
To collect sufficient data for multi-channel attribution modelling, set up Goal Tracking for different types of touchpoints (MoFU & BoFU) and asset types (contact forms, downloadable assets, etc).
Your next task is to figure out how users interact with different on-site assets. That’s when Event Tracking comes in handy.
Event Tracking reports notify you about specific actions users take on your website. With Matomo Event Tracking, you can monitor where people click on your website, on which pages they click newsletter subscription links, or when they try to interact with static content elements (e.g., a non-clickable banner).
Using in-depth user behavioural reports, you can better understand which assets play a key role in the average customer journey. Using this data, you can localise “leaks” in your sales funnel and fix them to increase conversion rates.
Test and Validated the Selected Model
A common challenge of multi-channel attribution modelling is determining the correct correlation and causality between exposure to touchpoints and purchases.
For example, a user who bought a discounted product from a Facebook ad would act differently than someone who purchased a full-priced product via a newsletter link. Their rate of pre- and post-sales exposure will also differ a lot — and your attribution model may not always accurately capture that.
That’s why you have to continuously test and tweak the selected model type. The best approach for that is lift analysis.
Lift analysis means comparing how your key metrics (e.g., revenue or conversion rates) change among users who were exposed to a certain campaign versus a control group.
In the case of multi-touch attribution modelling, you have to monitor how your metrics change after you’ve acted on the model recommendations (e.g., invested more in a well-performing referral channel or tried a new brand awareness Twitter ad). Compare the before and after ROI. If you see a positive dynamic, your model works great.
The downside of this approach is that you have to invest a lot upfront. But if your goal is to create a trustworthy attribution model, the best way to validate is to act on its suggestions and then test them against past results.
Conclusion
A multi-touch attribution model helps you measure the impact of different channels, campaign types, and marketing assets on metrics that matter — conversion rate, sales volumes and ROI.
Using this data, you can invest budgets into the best-performing channels and confidently experiment with new campaign types.
As a Matomo user, you also get to do so without breaching customers’ privacy or compromising on analytics accuracy.
Start using accurate multi-channel attribution in Matomo. Get your free 21-day trial now. No credit card required.
-
Matomo analytics for wordpress
15 octobre 2019, par Matomo Core Team — CommunitySelf-hosting web analytics got a whole lot easier ! Introducing Matomo for WordPress
Be the first to try it out ! Your feedback is much needed and appreciated
Get a fully functioning Matomo (which is comparable to Google Analytics) in seconds ! How ? With the new Matomo Analytics for WordPress plugin.
Web analytics in WordPress has never been easier to get, or more powerful. Matomo Analytics for WordPress is the one-stop problem solver. It’ll save you time, money and give you the insights to help your website or business succeed.
Best of all, we get to further the goal of decentralising the internet. Our hope is for Matomo Analytics for WordPress to spread far and wide. We’re so excited that more and more people can now get their hands on this powerful, free, open-source analytics platform, in a few clicks !
Download now and check it out !
What do you get ?
- No more signing up to third party analytics service (like Google)
- No more sending away your valuable data to a third party service (like Google)
- Easy setup – install with a few clicks, no tracking code installation or developer knowledge needed
- 100% accurate data – no data sampling and no data limits
- Full data ownership – all data is stored on your servers and no one else can see your data
- Privacy protection / GDPR compliance
- Ecommerce tracking out-of-the-box (Woocommerce, Easy Digital Downloads, and MemberPress) and we’re keen to add many more over time
- Powerful features – segmenting, comparing reports, different visualisations, real-time reports, visit logs and visitor profiles, Matomo Tag Manager, dashboards, data export, APIs, and many more
- Compared to other WordPress solutions we don’t charge you extra for basic features that should work out-of-the-box
- Just like Matomo On-Premise, Matomo Analytics for WordPress is free
We need your feedback !
We all know and love the versatility of WordPress – with over 55,000 plugins and all the different ways of hosting it. However, with this great versatility comes the potential for things to be missed, so we’re keen to hear your feedback.
- Is our plugin breaking anything on your WordPress, or, not compatible with something ? Please create an issue on our repository.
- Is something not working ? If so, what ? Please create an issue on our repository.
- How does running Matomo impact the performance of your WordPress server ? Also, if you have any other feedback for us – whether good or bad – please email us at wordpress@matomo.org. We’d love to hear what you think !
- Can you perform a security review of the plugin ? Security issues are best reported to security@matomo.org
- Do you have any questions ? Questions are best asked in our forum
Thank you ! We really appreciate your help on this ❤️
How do you get Matomo Analytics for WordPress ?
You can then upload it in your WordPress by going to “Plugins => Add New”. During the upload, if you get an error like “Are you sure you want to do this ?”, we recommend you upload the extracted zip file on to your server and into your ‘wp-content/plugins’ folder manually using ftp or ssh. Make sure the plugin name is ‘matomo’.
All you need is at least WordPress 4.8 and PHP 7.0 or later. MySQL 5.1+ is recommended.
The source code is available at : https://github.com/matomo-org/wp-matomo/.
In perfect harmony : Matomo and WordPress
The idea for this started two years ago when we realised the similarities between the Matomo and WordPress project.
Not only from a technological point of view – where both are based on PHP and MySQL and can be extended using plugins – but also from a philosophical, license and values point of view. We both believe in privacy, security, data ownership, openness, transparency, having things working out-of-the-box, simplicity etc.
WordPress is currently used on approximately 30% of all websites. Many of them use the self-hosted open-source WordPress version. Giving everyone in this market the opportunity to easily get a powerful web analytics platform for free, means a lot to us. We believe WordPress users get a real choice besides the standard solution of Google Analytics, and it furthers our effort and goal of decentralising the internet.
We’re hoping more people will be empowered to protect user privacy, have access to a great free and open-source tool, and keep control of data in their own hands.
We hope you feel the same. Help us spread the word to your friends and get them in on this awesome new project !
Share on facebookShare on twitterShare on linkedinFAQs
Isn’t there already a WP-Matomo plugin for WordPress available ?
Yes, the existing WP-Matomo (WP-Piwik) plugin is an awesome plugin to connect your existing Matomo On-Premise or Matomo Cloud account with WordPress. The difference is that this new plugin installs Matomo Analytics fully in your WordPress. So you get the convenience of having a powerful analytics platform within your WordPress.
We highly recommend you install this new plugin if you use WordPress and are not running Matomo yet.
If you are already using Matomo on our Cloud or On-Premise, we’d still highly recommend you use WP-Matomo (WP-Piwik). So that you get an easier way of inserting the tracking code into your WordPress site and get insights faster.
I have a high traffic website, will it be an issue ?
If you have a lot of traffic, we’d advise you to install Matomo On-Premise separately. There’s no specific traffic threshold we can give you on when it’s better to use Matomo On-Premise. It really depends on your server.
We reckon if you have more than 500,000 page views a month, you may want to think about using Matomo On-Premise with WP-Matomo instead, but this is just an estimate. In general, if the load on your server is already quite high, then it might be better to install Matomo on a separate server. See also recommended server sizing for running Matomo.
How do I report a bug or request a new feature in Matomo for WordPress ?
Please create an issue, on our repository whenever you find a bug or if you have any suggestion or ideas of improvement. We want to build an outstanding analytics experience for WordPress !
Have another question you’re dying to ask ? The Matomo for WordPress FAQ page might have the answer you need.
Matomo Analytics for WordPress newsletter
Get ahead of the crowd – signup to our exclusive Matomo for WordPress newsletter to get the latest updates on this exciting new project.
<script type="text/javascript"><br />
(function(global) {<br />
function serialize(form){if(!form||form.nodeName!=="FORM"){return }var i,j,q=[];for(i=form.elements.length-1;i>=0;i=i-1){if(form.elements[i].name===""){continue}switch(form.elements[i].nodeName){case"INPUT":switch(form.elements[i].type){case"text":case"hidden":case"password":case"button":case"reset":case"submit":q.push(form.elements[i].name+"="+encodeURIComponent(form.elements[i].value));break;case"checkbox":case"radio":if(form.elements[i].checked){q.push(form.elements[i].name+"="+encodeURIComponent(form.elements[i].value))}break;case"file":break}break;case"TEXTAREA":q.push(form.elements[i].name+"="+encodeURIComponent(form.elements[i].value));break;case"SELECT":switch(form.elements[i].type){case"select-one":q.push(form.elements[i].name+"="+encodeURIComponent(form.elements[i].value));break;case"select-multiple":for(j=form.elements[i].options.length-1;j>=0;j=j-1){if(form.elements[i].options[j].selected){q.push(form.elements[i].name+"="+encodeURIComponent(form.elements[i].options[j].value))}}break}break;case"BUTTON":switch(form.elements[i].type){case"reset":case"submit":case"button":q.push(form.elements[i].name+"="+encodeURIComponent(form.elements[i].value));break}break}}return q.join("&")};<br />
<br />
<br />
function extend(destination, source) {<br />
for (var prop in source) {<br />
destination[prop] = source[prop];<br />
}<br />
}<br />
<br />
if (!Mimi) var Mimi = {};<br />
if (!Mimi.Signups) Mimi.Signups = {};<br />
<br />
Mimi.Signups.EmbedValidation = function() {<br />
this.initialize();<br />
<br />
var _this = this;<br />
if (document.addEventListener) {<br />
this.form.addEventListener('submit', function(e){<br />
_this.onFormSubmit(e);<br />
});<br />
} else {<br />
this.form.attachEvent('onsubmit', function(e){<br />
_this.onFormSubmit(e);<br />
});<br />
}<br />
};<br />
<br />
extend(Mimi.Signups.EmbedValidation.prototype, {<br />
initialize: function() {<br />
this.form = document.getElementById('ema_signup_form');<br />
this.submit = document.getElementById('webform_submit_button');<br />
this.callbackName = 'jsonp_callback_' + Math.round(100000 * Math.random());<br />
this.validEmail = /.+@.+\..+/<br />
},<br />
<br />
onFormSubmit: function(e) {<br />
e.preventDefault();<br />
<br />
this.validate();<br />
if (this.isValid) {<br />
this.submitForm();<br />
} else {<br />
this.revalidateOnChange();<br />
}<br />
},<br />
<br />
validate: function() {<br />
this.isValid = true;<br />
this.emailValidation();<br />
this.fieldAndListValidation();<br />
this.updateFormAfterValidation();<br />
},<br />
<br />
emailValidation: function() {<br />
var email = document.getElementById('signup_email');<br />
<br />
if (this.validEmail.test(email.value)) {<br />
this.removeTextFieldError(email);<br />
} else {<br />
this.textFieldError(email);<br />
this.isValid = false;<br />
}<br />
},<br />
<br />
fieldAndListValidation: function() {<br />
var fields = this.form.querySelectorAll('.mimi_field.required');<br />
<br />
for (var i = 0; i < fields.length; ++i) {<br />
var field = fields[i],<br />
type = this.fieldType(field);<br />
if (type === 'checkboxes' || type === 'radio_buttons' || type === 'age_check') {<br />
this.checkboxAndRadioValidation(field);<br />
} else {<br />
this.textAndDropdownValidation(field, type);<br />
}<br />
}<br />
},<br />
<br />
fieldType: function(field) {<br />
var type = field.querySelectorAll('.field_type');<br />
<br />
if (type.length) {<br />
return type[0].getAttribute('data-field-type');<br />
} else if (field.className.indexOf('checkgroup') >= 0) {<br />
return 'checkboxes';<br />
} else {<br />
return 'text_field';<br />
}<br />
},<br />
<br />
checkboxAndRadioValidation: function(field) {<br />
var inputs = field.getElementsByTagName('input'),<br />
selected = false;<br />
<br />
for (var i = 0; i < inputs.length; ++i) {<br />
var input = inputs[i];<br />
if((input.type === 'checkbox' || input.type === 'radio') && input.checked) {<br />
selected = true;<br />
}<br />
}<br />
<br />
if (selected) {<br />
field.className = field.className.replace(/ invalid/g, '');<br />
} else {<br />
if (field.className.indexOf('invalid') === -1) {<br />
field.className += ' invalid';<br />
}<br />
<br />
this.isValid = false;<br />
}<br />
},<br />
<br />
textAndDropdownValidation: function(field, type) {<br />
var inputs = field.getElementsByTagName('input');<br />
<br />
for (var i = 0; i < inputs.length; ++i) {<br />
var input = inputs[i];<br />
if (input.name.indexOf('signup') >= 0) {<br />
if (type === 'text_field') {<br />
this.textValidation(input);<br />
} else {<br />
this.dropdownValidation(field, input);<br />
}<br />
}<br />
}<br />
this.htmlEmbedDropdownValidation(field);<br />
},<br />
<br />
textValidation: function(input) {<br />
if (input.id === 'signup_email') return;<br />
<br />
if (input.value) {<br />
this.removeTextFieldError(input);<br />
} else {<br />
this.textFieldError(input);<br />
this.isValid = false;<br />
}<br />
},<br />
<br />
dropdownValidation: function(field, input) {<br />
if (input.value) {<br />
field.className = field.className.replace(/ invalid/g, '');<br />
} else {<br />
if (field.className.indexOf('invalid') === -1) field.className += ' invalid';<br />
this.onSelectCallback(input);<br />
this.isValid = false;<br />
}<br />
},<br />
<br />
htmlEmbedDropdownValidation: function(field) {<br />
var dropdowns = field.querySelectorAll('.mimi_html_dropdown');<br />
var _this = this;<br />
<br />
for (var i = 0; i < dropdowns.length; ++i) {<br />
var dropdown = dropdowns[i];<br />
<br />
if (dropdown.value) {<br />
field.className = field.className.replace(/ invalid/g, '');<br />
} else {<br />
if (field.className.indexOf('invalid') === -1) field.className += ' invalid';<br />
this.isValid = false;<br />
dropdown.onchange = (function(){ _this.validate(); });<br />
}<br />
}<br />
},<br />
<br />
textFieldError: function(input) {<br />
input.className = 'required invalid';<br />
input.placeholder = input.getAttribute('data-required-field');<br />
},<br />
<br />
removeTextFieldError: function(input) {<br />
input.className = 'required';<br />
input.placeholder = '';<br />
},<br />
<br />
onSelectCallback: function(input) {<br />
if (typeof Widget === 'undefined' || !Widget.BasicDropdown) return;<br />
<br />
var dropdownEl = input.parentNode,<br />
instances = Widget.BasicDropdown.instances,<br />
_this = this;<br />
<br />
for (var i = 0; i < instances.length; ++i) {<br />
var instance = instances[i];<br />
if (instance.wrapperEl === dropdownEl) {<br />
instance.onSelect = function(){ _this.validate() };<br />
}<br />
}<br />
},<br />
<br />
updateFormAfterValidation: function() {<br />
this.form.className = this.setFormClassName();<br />
this.submit.value = this.submitButtonText();<br />
this.submit.disabled = !this.isValid;<br />
this.submit.className = this.isValid ? 'submit' : 'disabled';<br />
},<br />
<br />
setFormClassName: function() {<br />
var name = this.form.className;<br />
<br />
if (this.isValid) {<br />
return name.replace(/\s?mimi_invalid/, '');<br />
} else {<br />
if (name.indexOf('mimi_invalid') === -1) {<br />
return name += ' mimi_invalid';<br />
} else {<br />
return name;<br />
}<br />
}<br />
},<br />
<br />
submitButtonText: function() {<br />
var invalidFields = document.querySelectorAll('.invalid'),<br />
text;<br />
<br />
if (this.isValid || !invalidFields) {<br />
text = this.submit.getAttribute('data-default-text');<br />
} else {<br />
if (invalidFields.length || invalidFields[0].className.indexOf('checkgroup') === -1) {<br />
text = this.submit.getAttribute('data-invalid-text');<br />
} else {<br />
text = this.submit.getAttribute('data-choose-list');<br />
}<br />
}<br />
return text;<br />
},<br />
<br />
submitForm: function() {<br />
this.formSubmitting();<br />
<br />
var _this = this;<br />
window[this.callbackName] = function(response) {<br />
delete window[this.callbackName];<br />
document.body.removeChild(script);<br />
_this.onSubmitCallback(response);<br />
};<br />
<br />
var script = document.createElement('script');<br />
script.src = this.formUrl('json');<br />
document.body.appendChild(script);<br />
},<br />
<br />
formUrl: function(format) {<br />
var action = this.form.action;<br />
if (format === 'json') action += '.json';<br />
return action + '?callback=' + this.callbackName + '&' + serialize(this.form);<br />
},<br />
<br />
formSubmitting: function() {<br />
this.form.className += ' mimi_submitting';<br />
this.submit.value = this.submit.getAttribute('data-submitting-text');<br />
this.submit.disabled = true;<br />
this.submit.className = 'disabled';<br />
},<br />
<br />
onSubmitCallback: function(response) {<br />
if (response.success) {<br />
this.onSubmitSuccess(response.result);<br />
} else {<br />
top.location.href = this.formUrl('html');<br />
}<br />
},<br />
<br />
onSubmitSuccess: function(result) {<br />
if (result.has_redirect) {<br />
top.location.href = result.redirect;<br />
} else if(result.single_opt_in || !result.confirmation_html) {<br />
this.disableForm();<br />
this.updateSubmitButtonText(this.submit.getAttribute('data-thanks'));<br />
} else {<br />
this.showConfirmationText(result.confirmation_html);<br />
}<br />
},<br />
<br />
showConfirmationText: function(html) {<br />
var fields = this.form.querySelectorAll('.mimi_field');<br />
<br />
for (var i = 0; i < fields.length; ++i) {<br />
fields[i].style['display'] = 'none';<br />
}<br />
<br />
(this.form.querySelectorAll('fieldset')[0] || this.form).innerHTML = html;<br />
},<br />
<br />
disableForm: function() {<br />
var elements = this.form.elements;<br />
for (var i = 0; i < elements.length; ++i) {<br />
elements[i].disabled = true;<br />
}<br />
},<br />
<br />
updateSubmitButtonText: function(text) {<br />
this.submit.value = text;<br />
},<br />
<br />
revalidateOnChange: function() {<br />
var fields = this.form.querySelectorAll(".mimi_field.required"),<br />
_this = this;<br />
<br />
var onTextFieldChange = function() {<br />
if (this.getAttribute('name') === 'signup[email]') {<br />
if (_this.validEmail.test(this.value)) _this.validate();<br />
} else {<br />
if (this.value.length === 1) _this.validate();<br />
}<br />
}<br />
<br />
for (var i = 0; i < fields.length; ++i) {<br />
var inputs = fields[i].getElementsByTagName('input');<br />
for (var j = 0; j < inputs.length; ++j) {<br />
if (this.fieldType(fields[i]) === 'text_field') {<br />
inputs[j].onkeyup = onTextFieldChange;<br />
inputs[j].onchange = onTextFieldChange; <br />
} else {<br />
inputs[j].onchange = function(){ _this.validate() };<br />
}<br />
}<br />
}<br />
}<br />
});<br />
<br />
if (document.addEventListener) {<br />
document.addEventListener("DOMContentLoaded", function() {<br />
new Mimi.Signups.EmbedValidation();<br />
});<br />
}<br />
else {<br />
window.attachEvent('onload', function() {<br />
new Mimi.Signups.EmbedValidation();<br />
});<br />
}<br />
})(this);<br />
</script>