I want to hide an element based in a condition,
This is what i do:
First i use a v-if with computed property, but is not working, because when HMR reload the page, the button is hidden. And when i logout and login and refresh the localSorage with other condition, the button is still hidden or vice versa, the button is shown where should not.
Why?
This is my code:
computed:{
RegistrarUsuario(){
var userData = JSON.parse(localStorage.getItem("usuario"));
var acciones = userData.info.Acciones
for(var i = 0; i < acciones.length; i++){
if(acciones[i].accion === 'RegistrarUsuario'){
return false;
}
else{
return true;
}
}
}
},
<v-btn v-if="RegistrarUsuario" slot="activator" dark>Agregar</v-btn>
You're only looking at the first element of your acciones array (you return true or false on the first iteration). I suspect what you want is to return false if any of the elements matches. To do this you could use Array.some():
RegistrarUsuario(){
var userData = JSON.parse(localStorage.getItem("usuario"));
var acciones = userData.info.Acciones
return !acciones.some(a => a.accion === 'RegistrarUsuario');
}
Related
I am using the VScode extensions api. I have an item like so.
const item = vscode.window.createStatusBarItem(
vscode.StatusBarAlignment.Right
);
it's command is set to the following
item.command = "codevids.record";
Which calls the record() function onClick
vscode.commands.registerCommand("codevids.record", () => record());
All of this makes sense to me for the most part. Now I am handling logic in the record function so that when it is clicked again it has a different effect, it determines this by what is in the status bar string.
Like so
const record = () => {
if (item.text === `$(record) codevid` || item.text === `$(stop) codevid`) {
item.text = `$(pass) codevid`;
clearInterval(intervalID);
} else {
item.text = `$(record) codevid`;
There must be a more proper way to handle the status bar getting clicked in a boolean manner. I actually want a click to play, click to pause, and click done and run different functions.
What are my options in this regard.
Thanks ahead of time, and please let me know if you need more details.
I ended up doing a switch statement, maybe there is a more vscode way of doing it instead of checking against the string in the status bar, but works for now.
const record = async () => {
console.log(item.text);
switch (item.text) {
case `$(device-camera-video) codevid`:
console.log("recording");
item.text = `$(record) codevid`;
break;
case `$(record) codevid`:
console.log("recording options");
const go = vscode.window
.showErrorMessage("Pause or Finish", "Pause", "Finish")
.then((selection) => {
if (selection === "Pause") {
item.text = `$(debug-pause) codevid`;
} else if (selection === "Finish") {
item.text = `$(pass) codevid`;
}
return selection;
});
console.log("go", await go);
break;
case `$(debug-pause) codevid`:
console.log("paused");
case `$(pass) codevid`:
console.log("finished");
default:
console.log("default");
}
```
I would like to guarantee that at least one checkboxes are checked and the price are correct calculated.
https://jsfiddle.net/snoke/1xrzy57u/1/
methods: {
calc: function (item) {
item.isChecked = !item.isChecked
this.total = 0;
for (i = 0; i < this.items.length; i++) {
if(this.items[i].isChecked === true) {
this.total += this.items[i].price;
}
}
// fullPackagePrice
if(this.items[0].isChecked === true && this.items[1].isChecked === true && this.items[2].isChecked === true) {
this.total = this.fullPackagePrice;
}
// Trying to guarantee that have at least one checkbox checked
if(this.items[0].isChecked === false && this.items[1].isChecked === false && this.items[2].isChecked === false) {
this.total = this.items[0].price;
this.items[0].isChecked = true;
}
}
}
A good fit for this would be using computed properties instead of a method.
Read more about these here: https://v2.vuejs.org/v2/guide/computed.html#Computed-Properties
A computed property observes all referenced data and when one piece changes, the function is re-run and re-evaluated.
What you could do is first create a allowCheckout computed property like this:
allowCheckout() {
return this.items[0].isChecked || this.items[1].isChecked || this.items[2].isChecked;
}
You will then use it within the button like this:
<button :disabled="allowCheckout"...
This will disable the button when no items are checked.
Next, you'll also want to create a second computed property for the total price
totalPrice() {
// Perform similar checking here to update this.total
}
Lastly, you'll want to change your checkboxes to no longer use v-on:change but to instead use v-model for the relevant parameter for each.
This way your checkbox status will be bound to the true/falseness of the variables.
If you still want to go with your method, you can implement at like shown in this updated fiddle and set a variable atLeastOneItemIsChecked like this:
this.atLeastOneItemIsChecked = this.items.find(item => item.isChecked) !== undefined
Do not force the user to always check a checkbox. Instead, display a hint and disable the button using :disable and tailwind css resulting in this:
I found a tutorial that covered the same functionality for Angular. Here is the code:
openModal() {
document.getElementById('imgModal').style.display = "block";
}
closeModal() {
document.getElementById('imgModal').style.display = "none";
}
plusSlides(n) {
this.showSlides(this.slideIndex += n);
}
currentSlide(n) {
this.showSlides(this.slideIndex = n);
}
showSlides(slideIndex);
showSlides(n) {
let i;
const slides = document.getElementsByClassName("img-slides") as HTMLCollectionOf < HTMLElement > ;
const dots = document.getElementsByClassName("images") as HTMLCollectionOf < HTMLElement > ;
if (n > slides.length) {
this.slideIndex = 1
}
if (n < 1) {
this.slideIndex = slides.length
}
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
for (i = 0; i < dots.length; i++) {
dots[i].className = dots[i].className.replace(" active", "");
}
slides[this.slideIndex - 1].style.display = "block";
if (dots && dots.length > 0) {
dots[this.slideIndex - 1].className += " active";
}
}
}
It directly changes class names and styles using document. Which is the best way to implement this functionality in vue.js?
Option 1 - $refs
For getting element from DOM use ref.
If you set in HTML for an element ref attribute, e.g. <button ref="myButton"> then you can change the style in the same way as in your code:
this.$refs.myButton.style.display="none"
Regarding loops: ref will help only if the elements with the same ref were created by v-for. In this case this.$refs.<your ref> will be an array. Example: let's say you have images displayed by v-for with the same ref:
<img v-for="image in images" ref="imgSlide"...>
Then you can manipulate this.$refs.imgSlide as an array:
this.$refs.imgSlide.forEach(el => el.style.display = 'none')
Option 2 - Class and Style Bindings
Let's say you have <img id='imgModal'...>. You want to change display in 'openModal' method.
Do the folowing steps:
Add style binding: <img id='imgModal' :style="{ display: displayValue }"...
Add binding variable in data and initialize it:
data: {
displayValue: 'none'
}
Change the value of binding variable in the method:
openModal() {
this.displayValue = 'block'
}
With this approach, you don't need loops to change the style for multiple elements. Changing the binding variable will affect all elements bound with it.
Read more about Class and Style Bindings
Specifically for display = "none": Don't hide elements by changing display explicitly. Use v-if or v-show instead.
I am a Python developer and I have been working on Vuejs app.
If have function that is equivalent of a() in python that takes iterables. and if all items in iterable are true than all([...]) returns true
methods: {
all: function(iterable) {
for (var index = 0; index < iterable.length; ++index) {
if (!iterable[index]) return false;
}
return true;
}
}
and here is how I validate.
if (this.all([
this.age,
this.gender,
this.contactNumber,
this.townCity,
this.department.name,
this.attendType
])
) {
window.location = "#slip"
this.displayState = 'block';
}
else{
alert("Please fill all required fields.");
}
but this is not working.
Even if I fill all the mandatory fields I have the values in all the this.* attributes still I get alert saying "Please fill all required fields."
In JS, empty string values will return false on your IF statement.
You should check this point first.
(Maybe you have to check this topic)
Other thing : Make sure your "departement.name" variable is assigned. Vuejs is not reactive with sub-properties in objects.
Reactivity In Depth (Vue.js)
I am currently trying to implement automatic filtering in Yii cGridview, By default it filters 'onclick', or 'enter' key press, But I need to change that event to "onkeyup"|
my code is like this
Yii::app()->clientScript->registerScript('search',"
$('.filters > td >input').keyup(function(){
$('#grid-id').yiiGridView('update', {
data: $(this).serialize()
});
return false;
});
");
?>
when I entered the first letter filtering occured, but after filtering and rendering the code fails.. please give me a solution.. Is there any php yii gridview extension which has filtering onkeyup
You need to change the way you attach the keyup listeners. After the gridview refreshed through AJAX, all elements inside the grid are replaced. So there's no keyup attached anymore. You can try something like:
$('body').on('keyup','.filters > td > input', function() {
$('#grid-id').yiiGridView('update', {
data: $(this).serialize()
});
return false;
});
#Michael Härtl's answer is right. But 2 Problem occur when you use this code.
1) When User Search in filter at that time, every time grid will be refresh so focus of input box will be lost.
2) When you search in one filter input and if you go to second input field field at that time first input box will be lost.
So now I have got the solution for that.
Set this java script code on your grid view.
Yii::app()->clientScript->registerScript('search', "
$('body').on('keyup','.filters > td > input', function() {
$(document).data('GridId-lastFocused',this.name);
data = $('#GridId input').serialize();
$('#GridId').yiiGridView('update', {
data: data
});
return false;
});
// Configure all GridViews in the page
$(function(){
setupGridView();
});
// Setup the filter(s) controls
function setupGridView(grid)
{
if(grid==null)
grid = '.grid-view tr.filters';
// Default handler for filter change event
$('input,select', grid).change(function() {
var grid = $(this).closest('.grid-view');
$(document).data(grid.attr('id')+'-lastFocused', this.name);
});
}
// Default handler for beforeAjaxUpdate event
function afterAjaxUpdate(id, options)
{
var grid = $('#'+id);
var lf = $(document).data(grid.attr('id')+'-lastFocused');
// If the function was not activated
if(lf == null) return;
// Get the control
fe = $('[name=\"'+lf+'\"]', grid);
// If the control exists..
if(fe!=null)
{
if(fe.get(0).tagName == 'INPUT' && fe.attr('type') == 'text')
// Focus and place the cursor at the end
fe.cursorEnd();
else
// Just focus
fe.focus();
}
// Setup the new filter controls
setupGridView(grid);
}
// Place the cursor at the end of the text field
jQuery.fn.cursorEnd = function()
{
return this.each(function(){
if(this.setSelectionRange)
{
this.focus();
this.setSelectionRange(this.value.length,this.value.length);
}
else if (this.createTextRange) {
var range = this.createTextRange();
range.collapse(true);
range.moveEnd('character', this.value.length);
range.moveStart('character', this.value.length);
range.select();
}
return false;
});
}");
Add this line to your gridview widget code.
'afterAjaxUpdate'=>'afterAjaxUpdate',
For example:
$this->widget('zii.widgets.grid.CGridView', array(
'id' => 'GridId',
'afterAjaxUpdate'=>'afterAjaxUpdate',
));