Why Vue.js template can't interact it's script? - javascript

I'm using vue.js with axios and I'm trying to make an ajax call when I click a certain button. My problem is that my button's onclick event can't find it's function. Can someone explain to me Why can't my template interact with my script in my view?
Here's a short example of what I'm trying to achieve.
Example.vue
<template>
<button onclick="someClickFunction();"></button>
</template>
<script>
function someClickFunction(){
console.log("You've pressed the button");
}
export default {
name: "button-view",
}
</script>
<style scoped>
</style>

in vue you must write functions in the methods object and onclick == #click
<template>
<button #click="someClickFunction();"></button>
</template>
<script>
export default {
name: "button-view",
methods: {
someClickFunction(){
console.log("You've pressed the button");
}
}
}
</script>
<style scoped>
</style>

That's because in vue, you don't use the native onclick event.
Instead you use the
v-on:click
or the
#click
Better check the documentation. It is written very thoroughly
https://v2.vuejs.org/v2/guide/events.html
EDIT:
You also have error on your script. All functions must be declared inside the methods of the vue instance

Related

Polymer: on-click event on dom-repeat item is not identified in index.html

I have a polymer app with entry point index.html . For some reason i had to use dom-repeat inside index.html itself instead of a polymer element. The code is like this
<dom-bind id="mainbody">
<template>
<app-drawer-layout>
<app-drawer slot="drawer">
<template is="dom-repeat" id="mainDemoBody">
<paper-item data-value={{item.is}} id="demoItem" on-tap="onElementSelect">
{{item.is}}
</paper-item>
</template>
</app-drawer>
<div> Main content
<div>
</app-drawer-layout>
</template>
</dom-bind>
And i have on-tap function defined in the script tag like this
<script>
function onElementSelect(e) {
console.log('here');
this.selectedElement = e.model.item;
this.elementTags = this.selectedElement.tags;
this.demoLoaded = false;
}
</script>
But i am getting following error on click of any item of dom-repeat on user interface
listener method onElementSelect not defined
Can someone help me out here, Thanks in advance.
"onElementSelect" doesn't seem to be binded with the dom-bind#mainbody.
My suggestion is to create a function that has binding with mainbody. That seemed to work for me.
Code :-
var mainbody = document.getElementById('mainbody');
mainbody.onElementSelect = function(e){
console.log('here');
this.selectedElement = e.model.item;
this.elementTags = this.selectedElement.tags;
this.demoLoaded = false;
}
Edit: Please note that the solution provided is not proper or necessary for a polymer element. This particular fix is needed in this scenario because polymer components are being used in a html file.

Polymer 2.0 getElementById in different ShadowDom

I'm trying to learn Polymer 2.0 but am stuck with the problem of getting an element from a different Shadow Dom. This worked in Polymer 1 but no longer in Polymer 2.0. What is the correct way of writing this? It just tells me that the targetText = Null.
Thanks for your help!
This is a MWE:
Polymer WC 1:
<dom-module id="sc-navdrawer">
<template>
<style is="custom-style">
p {
font-weight: bold;
}
.changed {
color: red;
}
</style>
<p>Some text in normal p tag</p>
<div id="test" class="htmltextcontent" inner-h-t-m-l="{{inputText}}"></div>
</template>
<script>
Polymer({
is: 'sc-navdrawer',
properties: {
inputText: {
type: String,
value: "<p>Some innerhtml text in p tags</p>"
}
}
});
</script>
</dom-module>
Polymer WC 2:
<dom-module id="sc-testpage">
<template>
<button onclick="{{changeColor}}">Click here to change color</button>
</template>
<script>
Polymer({
is: 'sc-testpage',
changeColor: function() {
var targetText = document.getElementById("test");
console.log(targetText);
targetText.classList.add("changed");
}
});
</script>
</dom-module>
Well first thing that I see is you use document.getElementById("test"); and if you say this worked you have used Shady Dom. Polymer 2 forces you to use Shadow Dom so this command should be replaced by Polymer.dom(this.root).querySelector("#test"). Because Shadow Dom encapsulates your Component you cant access its content with the document Object
But this should not fix your Problem. This Encapsulation means you canĀ“t access the Content of a WebComponent so you cannot access an element with id:xyz from another Component. Have a look at these links they will explain to you how shadowDom works:
1. https://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/
2. https://developer.mozilla.org/en-US/docs/Web/Web_Components/Shadow_DOM
3. https://glazkov.com/2011/01/14/what-the-heck-is-shadow-dom/
Try using paper-input and setting it's value:
<paper-input id="test" label="input" value="{{inputText}}"></paper-input>
Then you can access the variable like this:
var targetText = this.$.inputText;
(this should work with other elements other than paper-input)
Instead of using getElementById you should be using Automatic node finding This works if your two Elements have a child parent relation to each other.
I also believe instead of using a onclick on your button in WC 2, you should be using a on-tap. This is the recommended way in the Polymer documentation.
Further on, I do not really understand why you are using two way data binding on your onclick attribute. I might be missing something but your code should work perfectly fine with a normal function call.
<dom-module id="sc-testpage">
<template>
<button on-tap="changeColor">Click here to change color</button>
</template>
<script>
Polymer({
is: 'sc-testpage',
changeColor: function() {
var targetText = this.$.sc-navdrawer.$.test;
console.log(targetText);
targetText.classList.add("changed");
}
});
</script>
</dom-module>

Adding HTML Button to Dynamics CRM 2016 Form

What I'm attempting to do is add an HTML button that will trigger as really simple javascript function.
Essentially onclick, I want to see if a field contains a value of 0.00 - if so remove that value. Or, if the field does not contain data, add in the value of 0.00 so it should alternate between those two values.
<html>
<head>
</head>
<body>
<button onclick="ReCalc">Re-Calculate Balance</button>
<script>
function ReCalc() {
var BalanceWriteOff = Xrm.Page.getAttribute("jucy_balancewriteoff").getValue();
if ((BalanceWriteOff) ==null)
Xrm.Page.getAttribute("balancewriteoff").setValue("0");
Xrm.Page.data.entity.save();
if ((BalanceWriteOff) =="0")
Xrm.Page.getAttribute("jucy_balancewriteoff").setValue(null);
Xrm.Page.data.entity.save();
return;
}
</script>
</body>
</html>
When I try to run this on the form where the HTML element has been placed. Nothing is happening. I've thrown in some break points at the var and both if statements and I'm not getting a break when I'm triggering the onclick event.
I'm kind of stumped here. If anyone has any insights for me that would be awesome
Oops! In your onclick attribute you forgot to invoke the method.
To fix this, simply change onclick="ReCalc" to onclick="ReCalc()".
Here's a code pen to show you it works now - https://codepen.io/trentrand/pen/Jyomgr
To access CRM form fields from an HTML web resource, add this script to the HTML:
<script src="ClientGlobalContext.js.aspx" type="text/javascript"></script>
and prepend "parent" to the Xrm.Page object:
parent.Xrm.Page.getAttribute("jucy_balancewriteoff").getValue();

inject content from one react component to another onClick

OK,so i am starting to get my head around ReactJs but keep getting stumped by one simple concept that is a doddle with plain old jQuery.
I want to be able to add to the content of one element on the screen when an on click event happens upon another. Following the react tutorial i completely understand the way they have achieved the adding to the comments list, the comment list is a child of the parent which is setting the state.. but surely this cannot be the only way as it feels very rigid and inflexible.
Here is a simple mockup of what I am trying to explain. On click of the button, i want to inject new content into the div with id "newComments"..
JSBin: http://jsbin.com/vokufujupu/1/edit
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/JSXTransformer.js"></script>
</head>
<body>
<div id="content"></div>
<script type="text/jsx">
var InputBox = React.createClass({
clickHandler: function(){
//Append a new string to the end of the existing copy in the copy box
alert('after this alert the value of the button should be appended to the content of the div#newComments');
},
render: function() {
return (
<div classNmae="copyBox">
<input type="button" name="inputButton" value="click me button" className="bbbc"
onClick={this.clickHandler} />
</div>
);
}
});
var CopyBox = React.createClass({
render: function() {
return (
<div classNmae="copyBox">
<p>div#newComments:</p>
<div id="newComments"></div>
</div>
);
}
});
var Page = React.createClass({
render: function() {
return (
<div>
<CopyBox/>
<InputBox/>
</div>
);
}
});
React.render(
<Page/>,
document.getElementById('content')
);
</script>
<!-- The equiv in plain old js -->
<script type="text/javascript">
function newContent(obj){
document.getElementById('vanBox').innerHTML = document.getElementById('vanBox').innerHTML + obj.value;
}
</script>
<div id="vanilaJsEquiv">
<div id="vanBox"></div>
<input type="button" value="ClickyClik" onclick="newContent(this)"/>
</div>
</body>
</html>
I've been hunting around google and the docs for yonks and cannot find the answer..
In react there is no concept of manipulating HTML / DOM. React is responsible just for rendering based on component state. Every component renders whatever it's current state is.
So you need to manipulate the state of other component. For that Facebook is using Flux. Which is a bit more complex workflow, but once you get it, it is actually pretty simple concept.
On one component click you dispatch an action. That action will trigger event, stores that are subscribed to that event will react and update internal state. After update, store emits change event, all components listening for changes in that store will update.
Yes you will need to write a lot more code. It gets much simpler if component is manipulating it's own state, then it would be enough to just call this.setState({ ... }) inside the component. And yes there, are other ways to do this.

Can I assign an action from javascript dynamically?

Typically, I do this to prompt the alert box, and say Hello
<div style="color:#00FF00" onclick=alert("Hello"); id = "helloDivTag">
<h3>This is a header</h3>
<p>This is a paragraph.</p>
</div>
But this time, I don't want to do it inside the html tag, I want to do it inside the js. How can I do so? Thank you.
i would recommend using the jquery framework then you just do this
$(function(){
$('#helloDivTag').click(function(){
alert("Hello");
});
});
implementing it would look like this you just put it in the header
<script src="http://code.jquery.com/jquery-1.4.4.min.js"></script>
<script>
$(function(){
$('#helloDivTag').click(function(){
alert("Hello");
});
});
</script>
why i recommend using jquery and not simple javascript is because there is alot of other functionality that could get in handy almost everytime you want to do something
window.onload = function() {
document.getElementById('helloDivTag').onclick = function(){
alert('hi');
}
}
when the window loads the click event is attached to your div and whenever you do the clicks the alert happens. This is called seperating behvaiour from structure and style.

Categories