Vue.js not updating automatically - javascript

I have got this in my html code
<div class="pl_wrapper">
<div class="options_pl">
<input type="button" #click="optionButtonClicked" class="option_button_pl" value="List">
<input type="button" #click="optionButtonClicked" class="option_button_pl" value="Add a language">
</div>
{{show2}}
</div>
And this in my vue.js
const ProgrammingLanguages = new Vue({
el:".pl_wrapper",
data:{
name: "aa",
show1: false,
show2: false
},
methods: {
optionButtonClicked(){
var indexOfClicked = index(event.target,event.target.className);
var equalIndexOfDiv = getOnIndex(indexOfClicked,"pl_divs")
$(".options_pl").hide();
show1 = (indexOfClicked==0) ? true : false
show2 = (indexOfClicked==1) ? true : false
}
}
});
Now when i click option_button_pl i expect {{show2}}'s to also change from false to true and vice versa.But alas that doesn't Jsfiddle: happen.https://jsfiddle.net/3akfzcyf/

you have to use the this keyword. Something like this.show1 and this.show2

here is your code working and I updated your fiddle
Adding the this statement and adding the event param inside optionButtonClicked
const ProgrammingLanguages = new Vue({
el:".pl_wrapper",
data:{
name: "aa",
show1: false,
show2: false
},
methods: {
optionButtonClicked(event){
var indexOfClicked = index(event.target,event.target.className);
this.show1 = (indexOfClicked==0) ? true : false
this.show2 = (indexOfClicked==1) ? true : false
console.log(this.show2)
}
}
});
function index(element,className){
var allElements = document.getElementsByClassName(className);
for (var i = 0; i < allElements.length; i++) {
if(allElements[i]==element){
return i;
}
}
}

Related

conditionally wrap <td> data in a link with vue

I'm trying to look at a certain table cell td element and set a condition, so that if the condition is met I show the data in a link, and if not I just show the data as text
I can't seem to figure out how to make this happen. I currently have a hover over that is set to that link and I've set the condition on my anchor tag but it's not working at all.
I have a snippet below, but basically I expect to see 0 printed as a link that triggers the hover/popover functionality. If test is set to 1, I would expect to just see a printed 1
Where am i wrong here?
<script>
new Vue({
el: "#app",
props: {
text: {
type: String,
required: true
}
},
data: {
timeout: null,
showCard: false,
isLoaded: false,
selected: '',
test: 0
},
methods: {
mouseover: function (event) {
console.log(event.pageX, event.pageY)
clearTimeout(this.timeout)
var self = this
this.timeout = setTimeout(function () {
self.showCard = true
setTimeout(function () {
self.isLoaded=true;
}, 500)
}, 500)
},
mouseleave: function () {
var self = this
this.timeout = setTimeout(function () {
self.showCard = false
self.isLoaded = false
}, 200)
},
cardOver: function () {
console.log('card over')
clearTimeout(this.timeout);
this.showCard = true
},
cardLeave: function () {
var self = this
this.timeout = setTimeout(function () {
self.showCard = false
self.isLoaded = false
}, 200)
}
}
});
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<table id="app">
<tbody>
<td>
<a v-if="test == 0" href="javascript:void(0)"
#mouseover="mouseover"
#mouseleave="mouseleave">#{{test}}
</a>
<div id="hovercard" v-show="showCard" #mouseover="cardOver" #mouseleave="cardLeave">
<div :class="['bg', {'loaded': isLoaded}]"></div>
<div class="content">
<p>Orders ready</p>
</div>
</div>
</td>
</tbody>
</table>
Wrap your anchor inside in-built component tag conditionally. below is the sample snippet.
<td>
<component :is="test == 0 ? 'a' : 'span'" #mouseover="mouseover" #mouseleave="mouseleave" :href="'javascript:void(0)' || ''" target="_blank">{{ test }}</component>
</td>
Have you considered
<a v-if="test == 0"
href="javascript:void(0)"
#mouseover="mouseover"
#mouseleave="mouseleave">{{test}}
</a>
<span v-else>{{test}}</span>
Docs: Conditional rendering

Ext JS treelist store loading infinitely?

Ext js View
There is option called treelist in the view. when use some static data in the tree list it working fine. when changed to dynamic data load from store it not loading.
Ext.define('Count.view.History', {
extend : 'Ext.Panel',
xtype : 'historyView',
controller : 'main',
requires : ['Count.store.History'],
width : '100%',
height : '100%',
title : 'History',
closable : true,
autoDestroy : true,
centered : true,
layout : 'fit',
fullscreen : true,
scrollable : true,
items :
[
{
xtype : 'tree',
store : 'History'
}
],
});
Store
Ext.define('Count.store.History', {
extend : 'Ext.data.TreeStore',
autoLoad : false,
alias : 'store.HistoryStore',
requires : ['Count.Db', 'Count.model.history'],
config :
{
model : 'Count.model.history'
},
loadData : function()
{
var meObj=this;
var sqlString = "SELECT tbl_list.ListName, tbl_list.MasterCount, tbl_sub_count.masterCountId, tbl_sub_count.subCount FROM tbl_list INNER JOIN tbl_sub_count ON tbl_list.Id=tbl_sub_count.masterCountID where tbl_sub_count.status='1';";
Count.Db.selectQuery(sqlString, meObj.callbackLoadData, meObj);
},
callbackLoadData : function(results, scope)
{
var store = scope;
var len = results.rows.length;
var MainListArray = {'root': {'expanded': true, 'children': []}};
var masterCountId = "";
var resultObj = "";
for (var i=0; i<len; i++)
{console.log(results);
if(masterCountId == "" || masterCountId != results.rows.item(i).masterCountId)
{
if(resultObj != "")
{
MainListArray.root.children.push(resultObj);
}
resultObj = {'ListName': results.rows.item(i).ListName, 'expanded': true, 'children': []}
masterCountId = results.rows.item(i).masterCountId;
var subListObj = {'subCount': results.rows.item(i).subCount, 'leaf': true}
resultObj.children.push(subListObj);
}
else
{
var subListObj = {'subCount': results.rows.item(i).subCount, 'leaf': true}
resultObj.children.push(subListObj);
}
}
if(resultObj != "")
{
MainListArray.root.children.push(resultObj);
}
console.log(MainListArray);
store.setData(MainListArray);
}
});
Controller
onShowHistory:function()
{
var showHistoryView = Ext.create('Count.view.History');
var storeHistory = Ext.create('Count.store.History');
storeHistory.loadData();
Ext.Viewport.add(showHistoryView);
}
But when call loadData function in store data looping loading infinitely?
I tried all the solution before answered few solutions. But it won't work.
Anyone please suggest me good solution for this.
Thanks in Advance.
I can't test without a working fiddle, anyway it seems you are not filling the TreeStore correctly.
Here is some changes can help you to load/view data correctly. First try to initialize the store with an empty root node adding root: {} in your store config.
And then try to load data using setRoot instead of setData, change
var MainListArray = {'root': {'expanded': true, 'children': []}};
with
var MainListArray = {'ListName': 'root', 'expanded': true, 'children': []};
and then
store.setData(MainListArray);
with
store.setRoot(MainListArray);
Finally got the solution.
Store.js
Ext.define('Count.store.History', {
extend : 'Ext.data.TreeStore',
alias : 'store.HistoryStore',
requires : ['Count.Db', 'Count.model.History'],
autoLoad: false,
rootProperty: "root",
root: {},
loadData : function()
{
var meObj=this;
var sqlString = "SELECT list.ListName, list.Count, sub_count.masterCountId, tbl_sub_count.subCount FROM tbl_japa_list INNER JOIN tbl_sub_count ON list.Id=tbl_sub_count.masterCountID where tbl_sub_count.status='1';";
Count.Db.selectQuery(sqlString, meObj.callbackLoadData, meObj);
}, callbackLoadData : function(results, scope)
{
var store = scope;
var len = results.rows.length;
var MainListArray = { 'expanded': true, 'children': []};
var CountId = "";
var resultObj = "";
for (var i=0; i<len; i++)
{
if(CountId == "" || CountId != results.rows.item(i).CountId)
{
if(resultObj != "")
{
MainListArray.children.push(resultObj);
}
resultObj = {'text': results.rows.item(i).ListName, 'expanded': true, 'children': []}
CountId = results.rows.item(i).CountId;
var subListObj = {'text': results.rows.item(i).subCount, 'leaf': true}
resultObj.children.push(subListObj);
}
else
{
var subListObj = {'text': results.rows.item(i).sub, 'leaf': true}
resultObj.children.push(subListObj);
}
}
if(resultObj != "")
{
MainListArray.children.push(resultObj);
}
store.setRoot(MainListArray);
}
View .js
item :[ { xtype : 'treelist' }]

Can't Target repeated component in DOM - Vue.js

Excuse any syntax errors, It works perfectly, but I could have made an error copying over.
Problem: I have a component, 'dropdown', that is repeated three times with
v-for='(item, index) in search'
which is an array with three objects. Below in the 'filterInput' method, The for loop and if statement does indeed work as intended, HOWEVER, I do not know how to target the 'dropdown' element that matches the search[i]. I need to remove the search[i]'s element in the DOM when the search[i].text doesn't match the input.
<div id='app'>
<input type='text' placeholder='Start typing here...' v-model='input'
#click='drop()' v-on:blur='close()'>
<ul id="dropdown" class='nodisplay'>
<dropdown v-for='(item, index) in search' v-bind:item='item' v-
bind:index='index'></dropdown>
</ul>
</div>
Vue.component('dropdown', {
props: ['item', 'index'],
template: `<li> {{item.text}}</li>`
})
var app = new Vue({
el: '#app',
data: {
input: '', //reactive
search: [
{id: 1, text: 'Jacob'},
{id: 2, text: 'Jeff'},
{id: 3, text: 'Tom'}
]
},
methods: {
drop: function() {
let dropdown = document.getElementById('dropdown');
dropdown.classList.toggle('nodisplay');
},
close: function() {
let dropdown = document.getElementById('dropdown');
dropdown.classList.toggle('nodisplay');
document.querySelector('input').value = '';
},
filterInput: function(index) {
//dropdown items in console: app.search[index].text = 'xyz'
for (let i = 0; i < this.search.length; i++) {
if (!(this.search[i].text.startsWith(this.input))) {
//hide or remove this current search element from dropdown
}
}
}
},
watch: {
input: function() {
this.filterInput();
}
}
})
tl;dr; how do I target
What you are looking for is how to have parent child communication, which I have answered today itself here.
You need to $emit an event from the child component and set the value used in input field, just like the example in documentation.
Here is the code:
HTML
<div id='app'>
<input type='text' placeholder='Start typing here...' v-model='input'
#click='drop()' >
<ul id="dropdown" :class="{'nodisplay': dropDownClosed}">
<dropdown v-for='(item, index) in search' v-bind:item='item' v-
bind:index='index' v-on:getdropdowninput="getdropdowninput"></dropdown>
</ul>
</div>
JS
dropdown = Vue.component('dropdown', {
props: ['item', 'index'],
template: `<div><li ><a #click="selectval(item.text)" href="#"> {{item.text}}</a></li></div>`,
methods: {
selectval (value) {
this.$emit("getdropdowninput", value)
}
}
})
var app = new Vue({
el: '#app',
data: {
input: '', //reactive
dropDownClosed: false,
search: [
{id: 1, text: 'Jacob'},
{id: 2, text: 'Jeff'},
{id: 3, text: 'Tom'}
]
},
methods: {
drop: function() {
this.dropDownClosed = true
},
getdropdowninput: function(value) {
this.dropDownClosed = false
this.input = value;
},
filterInput: function(index) {
//dropdown items in console: app.search[index].text = 'xyz'
for (let i = 0; i < this.search.length; i++) {
if (!(this.search[i].text.startsWith(this.input))) {
//hide or remove this current search element from dropdown
}
}
}
},
watch: {
input: function() {
this.filterInput();
}
}
})
Here is the working fiddle.
Use dynamic classes: I have also modified how to add/remove a class dynamically in vue way, instead of document.getElementById. Notice in following line:
<ul id="dropdown" :class="{'nodisplay': dropDownClosed}">
nodisplay class will be applied when dropDownClosed variable will be true and it will be removed when dropDownClosed variable will be false.
How to Filter:
To filter, you can use a computed property in the v-for and whenever input changes you can filter the search array, like following
computed: {
filteredInput: function(){
if(this.input === '' || !this.input){
return this.search
} else {
var self = this
return this.search.filter(
function( s ) {
return s.text.indexOf( self.input ) !== -1; }
);
}
}
See working fiddle here.

How to implement heritage with knockoutJS objects

I have a model consisting of a project object, a text object and a setting object. The settings object can hold values for both projects and texts.
A text is always coupled to a project. Thus it should inherit the projects settings (if any). However if the text itself has settings, the user should be able to choose between using the project default or the text-specific settings.
The problem I'm having in my project is that updating the text local setting is also updating the project default settings. I guess this has to do with the observables relation, but so far I have been unable to find the connection.
Here's my code:
Text = function (data) {
var self = this;
self.textID = data.textID;
self.title = ko.observable(data.title);
self.projectID = data.projectID;
// settings
self.settings = ko.observable(); // initiated with "each" loop hook-up in viewmodel.
self.project = ko.observable(); // initiated with "each" loop hook-up in viewmodel.
self.projectSettings = ko.computed(function () {
var project = self.project();
if (project) {
var proset = project.settings();
return proset;
}
return null;
});
self.useProjectSettings = ko.observable(data.useProjectSettings || true);
self.hasLocalSettings = ko.observable(false); // initiated with each loop hook-up in viewmodel.
self.activeSettings = ko.computed(function () {
return self.useProjectSettings() ? self.projectSettings() : self.settings();
});
return self;
};
Project = function (data) {
var self = this;
self.projectID = data.projectID;
self.title = ko.observable(data.title);
// settings
self.settings = ko.observable();
return self;
};
Setting = function (data) {
var self = this;
self.settingID = data.settingID;
self.projectID = data.projectID;
self.textID = data.textID;
self.isVisible = ko.observable(data.isVisible);
self.isProjectDefault = ko.observable(data.isProjectDefault || true);
return self;
};
ViewModel = function (myprojects, mysettings, mytexts) {
var self = this,
koEach = ko.utils.arrayForEach, koFirst = ko.utils.arrayFirst, koFilter = ko.utils.arrayFilter;
self.selectedText = ko.observable();
//data - load
self.Projects = ko.observableArray(
ko.utils.arrayMap(myprojects, function (item) {
return new Project(item);
}));
self.Settings = ko.observableArray(
ko.utils.arrayMap(mysettings, function (item) {
return new Setting(item);
}));
self.Texts = ko.observableArray(
ko.utils.arrayMap(mytexts, function (item) {
return new Text(item);
}));
//alert("self.Projects()[0].projectID=" + self.Projects()[0].projectID );
// hook up 'settings' on 'project'
koEach(self.Settings(), function (s) {
if (s.isProjectDefault()) {
var project = koFirst(self.Projects(), function (p) {
return p.projectID === s.projectID;
});
if (project) {
project.settings(s);
}
}
});
//alert("self.Texts()[0].textID=" + self.Texts()[0].textID + ", self.Texts()[0].title()=" + self.Texts()[0].title() );
//hook up 'project' on 'texts'
koEach(self.Texts(), function (t) {
var project = koFirst(self.Projects(), function (p) {
return p.projectID === t.projectID;
});
t.project(project);
// initiate default publishingSettings for textbatch
var initsettings = project.settings();
t.settings(initsettings);
});
// hook up 'settings' on 'text'
koEach(self.Settings(), function (s) {
if (!s.isProjectDefault()) {
var text = koFirst(self.Texts(), function (t) {
return t.textID === s.textID;
});
if (text) {
text.settings(s);
}
}
});
};
// console log
var consoleLine = "<p class=\"console-line\"></p>";
console = {
log: function (text) {
$("#console-log").append($(consoleLine).html(text));
}
};
// input
var projects = [{ projectID: 0, title: 'project 0' }, { projectID: 1, title: 'project 1' }];
var settings = [
{ settingID: 0, projectID: 1, textID: null, isVisible: true, isProjectDefault: true },
{ settingID: 1, projectID: null, textID: 0, isVisible: true, isProjectDefault: false },
{ settingID: 2, projectID: 1, textID: 1, isVisible: false, isProjectDefault: false }
];
var texts = [{ textID: 0, projectID: 0, title: 'first text' }, { textID: 1, projectID: 1, title: 'second text' }];
// binding
ko.applyBindings(new ViewModel(projects, settings, texts));
HereĀ“s my HTML:
<select data-bind="options: $root.Texts, optionsCaption: 'choose...', optionsText: 'title', value: selectedText"></select>
<br/>
Selected: <span data-bind="text: $root.selectedText().title"></span><br>
Selected2: <span data-bind="text: $root.selectedText().title"></span><br>
TextID: <span data-bind="text: selectedText().textID"></span><br>
<hr/>
<div data-bind="with: $root.selectedText">
<h2 data-bind="text:title"></h2>
<div class="form-group">
<div class="checkbox">
<label>
<input type="checkbox" data-bind="checked: useProjectSettings" />Use project settings
</label>
</div>
</div>
Settings for text '<span data-bind="text: title"></span>' (id='<span data-bind="value: textID"></span>').<br/><br/>
<div class="pubset" data-bind="css: {'unabled' : useProjectSettings() }">
<div class="form-group">
<div class="checkbox">
<label>
<input type="checkbox" data-bind="enable: !useProjectSettings(),checked: activeSettings().isVisible"/>
Show text
</label>
</div>
</div>
</div>
</div>
With my example code here, it seems I also have another problem, as it's not progressing to the second <span> node. Fiddle here.

Finding text to compare true or false

I'm trying to build out a json object in javascript/jquery that compares . Here's what I have
html:
<div class="field">
<div>size</div>
<div>large</div>
<div>medium</div>
<div>number</div>
</div>
js:
selectedObj = {
'fieldSize':false,
'sizeXSmall':false,
'sizeSmall':false,
'sizeMedium':false,
'sizeLarge':false,
'sizeXLarge':false,
'fieldName':false,
'fieldNum':false
};
if(jQuery('.field div:contains("size")')){selectedObj['fieldSize'] = true}
if(jQuery('.field div:contains("xs")')){selectedObj['sizeXSmall'] = true}
if(jQuery('.field div:contains("small")')){selectedObj['sizeSmall'] = true}
if(jQuery('.field div:contains("medium")')){selectedObj['sizeMedium'] = true}
if(jQuery('.field div:contains("large")')){selectedObj['sizeLarge'] = true}
if(jQuery('.field div:contains("xl")')){selectedObj['sizeXLarge'] = true}
if(jQuery('.field div:contains("name")')){selectedObj['fieldName'] = true}
if(jQuery('.field div:contains("number")')){selectedObj['fieldNum'] = true}
So ideally I would end up with an object that looks like this:
selectedObj = {
'fieldSize':true,
'sizeXSmall':false,
'sizeSmall':false,
'sizeMedium':true,
'sizeLarge':true,
'sizeXLarge':false,
'fieldName':false,
'fieldNum':true
};
I instead end up with an object where everything is true. Here is an example:
http://jsfiddle.net/vz600nd7/
Also, when I console log it before an after it looks like this:
It looks like the 'preview' is giving the right info but the actual view is not.
As I said in the comments, jQuery(selector) will return a jQuery object which will always be a truthy value. So your if condition will get executed every time.
I will try something like
var log = (function() {
var $log = $('#log');
return function(msg) {
$('<p/>', {
text: msg
}).appendTo($log)
}
})();
var map = {
'fieldSize': 'size',
'sizeXSmall': 'xs',
'sizeSmall': 'small',
'sizeMedium': 'medium',
'sizeLarge': 'large',
'sizeXLarge': 'xl',
'fieldName': 'name',
'fieldNum': 'number'
};
selectedObj = {
'fieldSize': false,
'sizeXSmall': false,
'sizeSmall': false,
'sizeMedium': false,
'sizeLarge': false,
'sizeXLarge': false,
'fieldName': false,
'fieldNum': false
};
var $els = jQuery('.field div');
$.each(map, function(key, value) {
selectedObj[key] = $els.is(':contains("' + value + '")')
});
log('After: ' + JSON.stringify(selectedObj))
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="field">
<div>size</div>
<div>large</div>
<div>medium</div>
<div>number</div>
</div>
<div id="log"></div>
if you want to detect, if object exists, use:
if($('.field div:contains("size")')[0]) selectedObj['fieldSize'] = true;
...

Categories

Resources