Software
how to use listeners in vue.js for events like scroll and windows resizing
Hello i am learning vuejs and was converting one of my projects into vuejs i wanted to know that i can write my custom functions in methods and call those in mounted hook i wanted to know how do i use listeners in vuejs.
also can i used my jquery by importing in vue project
The event listener documentation on vue website states only v-on and click example but no examples are for windows listeners
jQuery(document).ready(function(){ //cache DOM elements var mainContent = $('.cd-main-content'), header = $('.cd-main-header'), sidebar = $('.cd-side-nav'), sidebarTrigger = $('.cd-nav-trigger'), topNavigation = $('.cd-top-nav'), searchForm = $('.cd-search'), accountInfo = $('.account'); //on resize, move search and top nav position according to window width var resizing = false; moveNavigation(); $(window).on('resize', function(){ if( !resizing ) { (!window.requestAnimationFrame) ? setTimeout(moveNavigation, 300) : window.requestAnimationFrame(moveNavigation); resizing = true; } }); //on window scrolling - fix sidebar nav var scrolling = false; checkScrollbarPosition(); $(window).on('scroll', function(){ if( !scrolling ) { (!window.requestAnimationFrame) ? setTimeout(checkScrollbarPosition, 300) : window.requestAnimationFrame(checkScrollbarPosition); scrolling = true; } }); //mobile only - open sidebar when user clicks the hamburger menu sidebarTrigger.on('click', function(event){ event.preventDefault(); $([sidebar, sidebarTrigger]).toggleClass('nav-is-visible'); }); //click on item and show submenu $('.has-children > a').on('click', function(event){ var mq = checkMQ(), selectedItem = $(this); if( mq == 'mobile' || mq == 'tablet' ) { event.preventDefault(); if( selectedItem.parent('li').hasClass('selected')) { selectedItem.parent('li').removeClass('selected'); } else { sidebar.find('.has-children.selected').removeClass('selected'); accountInfo.removeClass('selected'); selectedItem.parent('li').addClass('selected'); } } }); //click on account and show submenu - desktop version only accountInfo.children('a').on('click', function(event){ var mq = checkMQ(), selectedItem = $(this); if( mq == 'desktop') { event.preventDefault(); accountInfo.toggleClass('selected'); sidebar.find('.has-children.selected').removeClass('selected'); } }); $(document).on('click', function(event){ if( !$(event.target).is('.has-children a') ) { sidebar.find('.has-children.selected').removeClass('selected'); accountInfo.removeClass('selected'); } }); //on desktop - differentiate between a user trying to hover over a dropdown item vs trying to navigate into a submenu's contents sidebar.children('ul').menuAim({ activate: function(row) { $(row).addClass('hover'); }, deactivate: function(row) { $(row).removeClass('hover'); }, exitMenu: function() { sidebar.find('.hover').removeClass('hover'); return true; }, submenuSelector: ".has-children", }); function checkMQ() { //check if mobile or desktop device return window.getComputedStyle(document.querySelector('.cd-main-content'), '::before').getPropertyValue('content').replace(/'/g, "").replace(/"/g, ""); } function moveNavigation(){ var mq = checkMQ(); if ( mq == 'mobile' && topNavigation.parents('.cd-side-nav').length == 0 ) { detachElements(); topNavigation.appendTo(sidebar); searchForm.removeClass('is-hidden').prependTo(sidebar); } else if ( ( mq == 'tablet' || mq == 'desktop') && topNavigation.parents('.cd-side-nav').length > 0 ) { detachElements(); searchForm.insertAfter(header.find('.cd-logo')); topNavigation.appendTo(header.find('.cd-nav')); } checkSelected(mq); resizing = false; } function detachElements() { topNavigation.detach(); searchForm.detach(); } function checkSelected(mq) { //on desktop, remove selected class from items selected on mobile/tablet version if( mq == 'desktop' ) $('.has-children.selected').removeClass('selected'); } function checkScrollbarPosition() { var mq = checkMQ(); if( mq != 'mobile' ) { var sidebarHeight = sidebar.outerHeight(), windowHeight = $(window).height(), mainContentHeight = mainContent.outerHeight(), scrollTop = $(window).scrollTop(); ( ( scrollTop + windowHeight > sidebarHeight ) && ( mainContentHeight - sidebarHeight != 0 ) ) ? sidebar.addClass('is-fixed').css('bottom', 0) : sidebar.removeClass('is-fixed').attr('style', ''); } scrolling = false; } });The width of columns in a table change when a row of input boxes is added dinamically
The table before the row with input-boxes is shown As you see in the image above, there is a table that contains on the first row, a button for showing/hiding the row that contains input-boxes like in the image below.
The table where the row with input boxes is shown
The problem is that the width of the columns is changed when the row that contains input-boxes is displayed. (It can be seen from the images the difference of width's columns, before and after)
And the width of the input-boxes is set to 100%.
Also the padding and border are not changed, only the width of td.
So the question is, how can I mentain the same width of the columns, without setting a fixed width, like in the code below?
And also adding white-space: nowrap doesn't work!
Here is the part of the code for showing the row with the input-boxes.
<tr v-if="showFilters"> <td v-for="key in filterKeys" v-if="key.visible"> <div class="input-group"> <pf-text-field v-model="key.value" tooltip="Filter"> </pf-text-field> </div> </td> </tr>Vue 2 - vuex mapGetters and pass params
Is it possible to pass params with mapGetters?
I have this in main Vue instance:
computed: { filterAuthors() { return this.$store.getters.filterAuthors(this.search.toLowerCase()); } }this.search is bind to the input field via v-model="search=, and in my Vuex instance I have this getters:
getters: { filterAuthors: (state) => (search) => { return state.authors.filter((author) => { return author.name.toLowerCase().indexOf(search) >= 0; }) } },This one is working fine, but I am trying to find a way (if it is possible) to use mapGetters and to pass the argument. Can this be done?
align content with bootstrap strange behaviour
I am working with vuejs and bootstrap so i am calling different components and attach them inside my html dynamicly.
My problem is i don't get the desirable effect, at the moment i have this:
the section title gives soo much space realted to the input and i don't know why, the section is a diferent component and the data at the bottom gets loaded dynamicly depending on the selectbox choice.
the rows columns and cells are a horizontal form but it occupy all the widht of my row, i want the inputs to be lower and the button at center a little bigger, i can't set it like i want if i try for example to increase button it will not be at center anymore.
So here is my code:
<template> <div class="container"> <div class="row"> <div> <h1 class="text-center">Document Creation</h1> </div> <div class="col-md-4"> <div class="row"> <div class="col-md-6"> </div> <div class="col-md-6"> </div> </div> </div> <div class="col-md-8 margin-above"> <div class="form-group"> <label class="control-label col-sm-2">Section</label> <div class="col-sm-6"> <select class="form-control" v-model="currentView"> <option v-for="(item,index) in sections" :value="item.key">{{item.text}}</option> </select> </div> </div> </div> </div> <!-- Here we load the diferent sections based on the selection choice --> <component v-bind:is="currentView"> <!-- component changes when vm.currentView changes! --> </component> </div> </template>inside the component the other component that has the rows and cells and columns get loaded like this:
<template> <div class="row"> <div class="col-md-offset-4"> <form class="form-inline margin-above"> <div class="form-group"> <label for="rows">rows:</label> <input type="number" min="1" value="1" class="form-control" id="rows"> </div> <div class="form-group"> <label for="columns">columns:</label> <input type="number" min="1" value="1" class="form-control" id="cols"> </div> <div class="form-group"> <label for="cells">cells:</label> <input type="number" min="1" value="1" class="form-control" id="cols"> </div> <div class="text-center"> <button type="submit" class="btn btn-success margin-above2">Add Table</button> </div> </form> </div> </div> </template>please i need some help trying to display it correctly . Thanks
Saga alternative for Vue
I finished learning Vue.js, it has had almost all I wanted from it! But I can't find something similar to redux-saga. redux-saga is very great tool, and it would be nice to have something like this.
Can someone propose alternative library, or share experience how to manage big projects with complex data-flow without redux-saga.
Pass data from one component to all with $emit without using @click in VueJS
Trying to learn vuejs I got to the question how to pass any data from one component to all, using $emit but without using any @click. It is possible some how that the data to be just available and grab it any time, without using the click?
Let's say we have this example with normal @click and $emit.
main.js
export const eventBus = new Vue()Hello.vue
<template> <div> <h2>This is Hello component</h2> <button @click="emitGlobalClickEvent()">Click me</button> </div> </template> <script> import { eventBus } from '../main' export default { data () { return { msg: 'Welcome to Your Vue.js App' } }, methods: { emitGlobalClickEvent () { eventBus.$emit('messageSelected', this.msg) } } } </script>User.vue
<template> <div> <h2>This is User component</h2> <user-one></user-one> </div> </template> <script> import { eventBus } from '../main' import UserOne from './UserOne.vue' export default { created () { eventBus.$on('messageSelected', msg => { console.log(msg) }) }, components: { UserOne } } </script>UserOne.vue
<template> <div> <h3>We are in UserOne component</h3> </div> </template> <script> import { eventBus } from '../main' export default { created () { eventBus.$on('messageSelected', msg => { console.log('From UserOne message !!!') }) } } </script>I want to get this message : Welcome to Your Vue.js App from Hello.vue in all components, but without @click, if is possible.
Webix not working with Vue2
I am adding some Vue2 components to an existing page that uses webix, but that is breaking my webix components.
If I comment this line out , webix works as expected. When app-provider-ui.js is included on the page, webix datatables render, but nothing happens when I click on them.
I use Laravel 5.4, Vue2, and webpack. The Vue instance is mounted on #provider-js-app
Thanks.
<!DOCTYPE html> <html lang="en"> <head> <link href="{{ asset('/css/stylesheet.css') }}" rel="stylesheet"> <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> <script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.min.js"></script> <script src="{{ asset('/webix/codebase/webix.js') }}" type="text/javascript"></script> </head> <body> <div id="provider-js-app"> @yield('content') <open-modal></open-modal> <notifications></notifications> </div> @include('partials.footer') <!--[if lt IE 9]> <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script> <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> <![endif]--> <script src="{{ asset('/js/bootstrap-select.min.js') }}"></script> <script src="{{ asset('/js/typeahead.bundle.js') }}"></script> <script src="{{asset('/js/bootstrap.min.js')}}"></script> <script src="{{asset('/js/DateTimePicker.min.js')}}"></script> <script src="{{asset('js/app-provider-ui.js')}}"></script> </body> </html>vue js in bootstrap navbar
i am implementing vue js in bootstrap html template... problem i am facing is in navbar..
my code is
<router-link tag="li" to="#"> <a><i class="fa fa-book" aria-hidden="true"></i> <span class="nav-label">Syllabus</span><span class="fa arrow"></span></a> <ul class="nav nav-second-level collapse"> <router-link tag="li" to="/syllabus"> <a> Syllabus</a> </router-link> <router-link tag="li" to="/syllabus/topic"> <a>Syllabus Topic</a> </router-link> </ul> </router-link>i have also tried using
<li> <a><i class="fa fa-book" aria-hidden="true"></i> <span class="nav-label">Syllabus</span><span class="fa arrow"></span></a> <ul class="nav nav-second-level collapse"> <router-link tag="li" to="/syllabus"> <a> Syllabus 1</a> </router-link> <router-link tag="li" to="/syllabus/topic"> <a>Syllabus Topic</a> </router-link> </ul> </li>but the problem is when i am reloading the page the menu collapse and expands normally as it should work but when i am clicking on a a sub menu for instance "syllabus1" the page redirects to syllabus but the menu freezes and does not any longer collapse or expands...then again on reloading the menu starts working fine
please help me with this... thanks in advance... please provide an example in jsfiddle if possible... thankx..
Vue 2 add class active through exploring list
i have problem with input and lists, I would like to go through from input to list element below and add class 'active' to current li element
<div class="control"> <label class="label">Input Test</label> <input type="text" class="input" @keydown="keyHandler"> <ul> <li v-for="suggestion in suggestions" v-bind:class="{active}">{{suggestion.message}}</li> </ul> </div> methods : { keyHandler(e){ if(e.keyCode === 38){ e.preventDefault(); console.log('arrow up') this.currentKey = e.key } else if(e.keyCode === 40){ e.preventDefault(); console.log('arrow down') this.currentKey = e.key } } }here is fiddle: https://jsfiddle.net/o8fwf0gh/13/
I would be grateful for help
Passing data from parent to be rendered on component, data passage failure
I am trying to pass a first and last name to a child component to render as a custom element. Should be simple. But I am not able to link up my props for some reason. Here is the relevant parent code...
<div class="panel-body"> <full-name :userData.firstname="firstname" :userData.lastname="lastname"></full-name> </div> <script> import toggleSwitch from './components/toggleSwitch.vue'; export default { data () { return{ userData: { firstname: '', lastname: '' } } }, components: { 'fullName': fullName } } </script>As you can see I call the element and pass it my two data props. Once there I simply output my data via string interpolation, and... nothing shows. Here is my output component
<template> <div> <p>{{firstname}} {{lastname}}</p> </div> </template> <script> export default{ props: ['firstname', 'lastname'] } </script>Am I missing something obvious? Thanks in advance.
Vue.js raw HTML within attribute
Is there a way to output raw HTML to a tags attributes rather than content?
Example:
<input :placeholder="data.raw-html-message"/> ... data.raw-html-message = "some text…"v-html seems to only output it to the innerHTML of the tag and the triple curly braces have been removed in version 2.
Currently with a standard v-bind the output is:
<input placeholder="Message…" />
and the HTML entity is not interpreted when displayed in the browser.
vue-router same route with different param
I am on the /entry/12 route. On the same component I would like to push /entry/13 when user clicks the next button.
Code is like :
//e is the next page number. this.$router.push({ name: 'Entries', params: { pageNum: e }});I get below error:
If i try different route that works.
VueJS - v-if and v-show don't work properly
I have this structure inside Vue DIV:
<div class="row"> <div class="well chart-container"> <div id="chart" v-if="chartShown"></div> <h1 v-if="textShown">{{staticPropertyValue}}</h1> </div> </div>In my application I'd like to be able to display chart div OR h1 tag. Here's a part of my javaScript:
app.textShown = false; app.chartShown = true; if (data.length == 0) { MG.data_graphic({ title: "Missing Data", description: "", error: 'No data', chart_type: 'missing-data', missing_text: 'There is no data', target: '#chart', full_width: true, height: 600 }); return; }; if (data.length == 1) { app.staticPropertyValue = data[0].value; app.chartShown = false; app.textShown = true; return; } console.log('DRAWING GRAPH'); console.log(document.getElementById('chart')); MG.data_graphic({ title: "Fetched data", description: "", data: data, full_width: true, height: 600, target: '#chart', x_accessor: 'time', y_accessor: 'value' });So, depending on data.length property, the chart is shown or h1 tag is shown. The problem appears, when I first time call above code and display h1 tag (because data.length == 1) and then next time I call it with date.length > 1 (chart should appear). I get error:
The specified target element "#chart" could not be found in the page. The chart will not be rendered.
It is from the library that I'm using for drawing charts - metricsgraphics.js. So I console logged the result of
document.getElementById('chart')and it was null. So it means that although i switch chartShown to true, it's not done fast enough. How can I fix this?
I also tried using v-show instead of v-if - didn't work well - I had some errors about the width of some elements being NaN.
Vue router async route guard progress
I'm doing async work in my router's navigation guard:
router.beforeEach((to, from, next) => { somethingAsync().done(next) })Does the router expose anything to tell me that it's currently "loading"? Or do I need to keep track of it myself? Right now the content will pop up in<router-view></router-view> once the async work is completed. My current solution is to keep track of active work in my Vuex store and show a loading element next to the router view.
How to break v-for loop in vue.js?
I have this v-for loop an my vue.js app:
<div v-for="(word, index) in dictionary"> // break if index > 20 <p>{{word}}</p> </div>I want to break out of the loop after rendering 20 words. How can I achieve this? I looked at the docs but did not see anything about this.
How can I print source code in Vue.js
example:
<div id="app"> {{ message }} </div> var app = new Vue({ el: '#app', data: { message: 'Hello Vue!' } })How can I print source code '{{message}}' not 'Hello Vue!'
Mozilla releases research results: Zero rating is not serving as an on-ramp to the internet
Can digital literacy and Equal Rating solutions help connect the unconnected?
Today, 4 billion people live without the internet. There’s a global debate about how to connect the unconnected, but it’s often dominated by assumptions and not a lot of data or talking to actual users on the ground.
To better inform this issue, Mozilla recently supported a series of focus groups to investigate how and why people use subsidized services in India, Myanmar, Peru, Kenya, Nigeria, Rwanda and South Africa. Today, we’re releasing the results of this research carried out by Research ICT Africa, LIRNEasia and IEP.
Why do we care?
Many companies and organizations are working to connect the unconnected. For us at Mozilla, it is our mission to ensure the internet is a global public resource that’s open and accessible to all.
We’ve focused our work in this space on a concept we call Equal Rating. Building on Mozilla’s strong commitment to net neutrality, Equal Rating models are free of discrimination, gatekeepers, and pay-to-play schemes. Equal Rating stands in contrast to zero rating business models, which reduce the cost to zero only for some sites and services. We’ve pursued this through policy engagement with governments, an innovation challenge to catalyze new thinking in providing affordable access, and this research.
What did we ask?
- What barriers are keeping people offline?
- Is zero rating serving as an on-ramp to the internet?
- Why and how do people use subsidized services?
- Do people move beyond subsidized services, or do they just stay in the subsidized walled garden?
- How does use of subsidized services affect future internet usage?
What did we find?
Zero rating is not serving as an on-ramp to the internet
In all countries surveyed — excluding India where zero rating has been banned by the regulator — focus groups revealed that users are not coming online through zero rated services. While more research is needed, if zero rating is not actually serving as an on-ramp to bring people online, the benefits seem low, while the resulting risk of these offerings creating an anti-competitive environment is extremely high.
People use zero rating as one of many cost saving strategies
This research revealed that people who use zero rated services usually also have full access to the internet, and make use of zero rated and subsidized data services as one of many money-saving strategies, including:
- Use of multiple SIM cards cards to take advantage of promotions, better reception quality, or better prices for a given service.
- Use of public Wi-Fi. For example, many buses in Rwanda now provide wifi access, and participants reported being willing to wait for a bus that was Wi-Fi-enabled.
- Tethering to mobile hotspots. In South Africa and India, users not only share data but also promotions and subsidized offers from one phone to another.
- Earned reward applications (where users download, use, or share a promoted application in return for mobile data/credit). The research indicates that most users tend to play the system to get the most credit possible and then abandon the earned reward application.
- While users, especially in the African studies, report skepticism about whether zero rated promotions are truly free, partially subsidized bundles are popular. Notably, many of these offerings are Equal Rating compliant.
Some, particularly rural and low income users, are trapped in walled gardens
While zero rated services tend to be only part of internet usage for most users studied, some users are getting trapped in the walled gardens of these subsidized offerings.
- In particular, low income respondents in Peru and Rwanda use zero rated content for much of their browsing activity, as do rural respondents in Myanmar.
- Awareness matters: in Myanmar, respondents who know they are in a zero rated walled garden (e.g., due to lack of photos and video) are more likely to access the full internet beyond the walled garden.
- But, when Facebook is subsidized without impacting user experience, users tend to concentrate their usage on that single site, demonstrating concerns around the anti-competitive effects of zero rating.
Digital illiteracy limits access for connected and unconnected alike
Infrastructure and affordability are commonly cited barriers to internet access around the world; yet, this research also points to a third important barrier: digital literacy.
- Users and non-users alike do not understand all that the internet can offer.
- Users generally restrict their internet use to a few large websites and services.
- A lack of understanding about the internet and internet-connected devices exacerbates misconceptions and spreads fear around privacy, security, and health, which in turn undermines use of the internet. One Kenyan respondent said of non-users: “there are some assumptions that they can get diseases transmitted to them like skin cancer through the use of the internet.”
Many companies and NGOs are already doing great work to advance digital literacy, but we need to scale up these efforts.
Competition, literacy, language, and gender are also barriers to internet access
This research highlighted a series of consistent and persistent barriers to access.
- While 95% of the world has access to an internet signal, far too often, users have access to only one, low quality provider, usually the most expensive option in their country.
- Without basic literacy, some respondents cannot access the internet. As one respondent in rural South Africa said, “if you cannot read or write you cannot use internet, many people in this community are not educated and I believe most of them want to be able to use internet because it makes life easier.”
- Others in Myanmar, Peru, and Rwanda cite the lack of local language content and tools as keeping them from coming online.
- Evidence of a gendered digital divide is seen throughout all of the countries studied, with some women afraid of “breaking the machine” while others say social stigma, domestic abuse, negative impressions, and housework obligations limit their use of the internet.
These are just some of the highlights and interesting findings. We have results from nearly 80 focus groups in these seven countries. For more detailed information, the country summaries and full reports are available here.
Next steps to bring the next 4 billion online
Mozilla supported this research to help better inform what we believe is a global imperative to bring the world’s 4 billion unconnected people online to access the full and open internet.
Based on these findings, we believe the internet needs:
- The development of more Equal Rating compliant models, many of which seemed to be quite popular with research respondents and provide access to the full diversity of the open internet, not just some parts of it.
- Further investment in digital literacy training, especially in schools, on devices, and in retail outlets. For more information about Mozilla’s digital literacy efforts, see our recent Digital Skills Observatory study.
- Work on all barriers to access to address infrastructure investment especially in rural areas, affordability, local content and local language tools, and gender equality.
Bringing the full internet to all people is one of the great challenges of our time. While we know there is more research needed, this research better informs the global debate on how to connect the unconnected, and makes clear the challenges ahead. We are committed to tackling these challenges but we know it will take all of us — tech companies, telecom companies, governments, civil society groups and philanthropists — working together to get everyone online.
We’d like to thank the researchers at Research ICT Africa, LIRNEasia, and IEP, as well as Jochai Ben-Avie (who manages all our Equal Rating work) and Peter Cihon (our awesome summer intern) who helped analyze this research.
The post Mozilla releases research results: Zero rating is not serving as an on-ramp to the internet appeared first on The Mozilla Blog.
How to use JavaScript functions in Vue directives?
Assume I have a JS function like this:
function myFunc() { return true; }Now, I want to show an element if the output of is true:
<p v-if="myFun()">I am Test</p>I know I can write this myFunc method inside Vue methods but I don't want this.
Any idea would be great appreciated.
VueJS - Passing data from the created to mounted()
Is there a way to pass data from the created function to the mounted function in VueJS. I am building a VueJS application and my created function looks like this,
created: function(){ $.getJSON({ url: 'static/timeline.json', success:function(json) { return json; } }) }I want to pass the json value into vis.DataSet() of my mounted function which looks like this,
var items = {}; mounted(){ container = document.getElementById('mynetwork'); items = new vis.DataSet(json); }So, is there a way using which I can pass data from created to the mounted() function?
$router.push doesn't respect route meta fields
When using $router.push like so:
this.$router.push({name: 'Home'})... it seems my route meta fields aren't being recognised. Here's my route meta fields and how I'm calling them:
Route meta fields
router.beforeEach((to, from, next) => { if (to.matched.some(record => record.meta.requiresAuth)) { // this route requires auth, check if logged in // if not, redirect to login page. if (!auth.user.authenticated) { next({ path: '/login' }) } else { next() } } else { next() // make sure to always call next()! } }) router.beforeEach((to, from, next) => { if (to.matched.some(record => record.meta.preventAdmin)) { // this route shouldn't be available for admin, check role // if so, redirect to admin area. if (auth.user.role === '1') { next({ path: '/admin/users' }) } else { next() } } else { next() // make sure to always call next()! } })Routes
routes: [ { path: '/', name: 'Home', component: Home, meta: { requiresAuth: true, preventAdmin: true } }, ]If I refresh when I am on the particular route they work as intended.
Do I have to do something to ensure my route meta fields work when using $router.push?