I am using Vue.JS in my build in visualforce page.
I have below piece of Vue template code where I am able to get acc.name print on page. But now I need to send this value to addtoterriotry method inside methods section of Vue app.
Please find below my Vue app component.
<v-dialog v-model="addToTerr" max-width="1000">\
<v-card>\
<v-card-title class="headline">Review Selected Accounts</v-card-title>\
<v-card-text>\
<div v-for="acc in this.items" v-if="acc.selected">{{acc.Name}}</div>\
</v-card-text>\
<v-card-actions>\
<v-btn color="secondary" v-on:click="addToTerriotry">Add</v-btn>\
<v-btn v-on:click="addToTerr = false">Close</v-btn>\
</v-card-actions>\
</v-card>\
</v-dialog>\
addtoterriotry method :
methods: {
selectDeselectAccount: function (props) {
props.item.selected = props.item.selected ? false : true;
if (props.item.selected)
this.accountsSelected = this.accountsSelected + 1;
else
this.accountsSelected = this.accountsSelected - 1;
},
showaccount: function (props) {
this.selectedaccount = props.item;
this.accdetails = true;
},
addToTerriotry: function () {
alert('Invoke Controller Action');
// Fetch acc.name value here.
CallApexMethod();
}
Assuming that you mean that you are trying to access the acc with a selected value of true, just find that element from the items array at the beginning of your addToTerriotry method:
addToTerriotry: function () {
alert('Invoke Controller Action');
let acc = this.items.find(i => i.selected);
console.log(acc.name);
CallApexMethod();
}
Related
inside Laravel Blade file I'm trying to achieve a simple password generator button that inputs generated password in field
Button:
<a class="btn btn-xs btn-success" onClick=generatePass()>Generate Me</a>
<script>
function generatePass() {
var hashed_random_password = Hash::make(str_random(12));
$('#password').val(hashed_random_password);
}
</script>
The button works, tested by using console.log('button clicked');
But hashing doesn't work, I need to achieve generating a hashed password and inputs it value directly into the password form field
Any suggestion how to get that simply in blade without invloving the routes and controller files?
<a class="btn btn-xs btn-success" onClick=generatePass()>Generate Me</a>
<script>
function generatePass() {
var pass = '';
var str='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+ 'abcdefghijklmnopqrstuvwxyz0123456789##$';
for (let i = 1; i <= 8; i++) {
var char = Math.floor(Math.random()* str.length + 1);
pass += str.charAt(char)
}
$('#password').val(pass);
}
Now at your laravel controller Hash this password.
You can't use Hash::make in javascript, that is a PHP/Laravel method.
You can use something like this to generate a random hash:
function generatePass() {
// change 12 to the length you want the hash
let randomPasswordHash = (Math.random() + 1).toString(36).substring(12);
$('#password').val(randomPasswordHash);
}
blade:
<button onclick="generateRandomPassword()">Generate Password</button>
<h2 id="password"></h2>
<script>
function generateRandomPassword() {
$.ajax({
url: '/generate-password',
success: function (data) {
$('#password').html(data);
}
});
}
</script>
route/controller:
Route::any('/generate-password', function () {
return Hash::make(Str::random(12));
});
I am using Vue Components in my blade file. Whenever I need to 'refresh' my customer object, I emit an event to the parent (shown below) and customer is refreshed and any props it passed to children will be shown with their updated values.
This is all well and good so far but I am now using some PHP values. I am passing a prop automatic-payments-enabled and it's using a php value. How can I have that value refresh after making an API call that changes it?
Blade file
<div id="app">
<Account
:customer="customer"
:automatic-payments-enabled={!! json_encode($customer->automaticPaymentsEnabled()) !!}
>
</div>
app.js
Vue.component('Account',
require('./components/Account.vue').default);
new Vue({
el: "#app",
data() {
return {
customer: null
}
}
mounted() {
this.getCustomer();
}
methods: {
getCustomer: function() {
//api call to server
this.customer = response.data
}
}
}
I suppose $customer is actually a Model. If so, you can use
$customer->fresh()->automaticPaymentsEnabled()
in my blade.php use one component
<loading :prop_show_loading="show_loading"></loading>
Still in my blade.php
This Doesn't work
<script>
var show_loading = true;
</script>
this Does't work too
<script>
window.event = new Vue();
window.event.$emit('prop_show_loading', 'true');
</script>
and my component doing this (window is not defined)
created(){
let App = this;
console.log(global.event);
window.event.$on('close-modal', (event) => {
this.prop_show_loading = true;
})
},
Any idea?
if you need pass the prop_show_loading value from laravel to loading vue component.
you don't use ":" in the head:
<loading prop_show_loading="show_loading"></loading>
and in the loading component use:
export default {
props: ['prop_show_loading'],
...
and than you can use this.prop_show_loading to get the value.
This should be a pretty normal task , and yet i am missing something .
I am trying to integrate Socket.io with Polymer [ using the chat application ] - Deciding to change the MessageList and the individual messageItem as Polymer components .
SocketIo exposes a customEvent to be thrown from server , which sends the message as data , which then is being assigned to a property on the custom element .
This is the MessageList element .
<link rel="import" href="/polymer/polymer.html">
<link rel="import" href="message.html">
<dom-module id='message-list'>
<template>
<style>
</style>
<ul id="messages">
<template is='dom-repeat' items="{{messageList}}" is="auto-binding">
<li>
<message-item message = "{{item}}"></message-item>
</li>
</template>
</ul>
</template>
<script>
var messageListElement = Polymer({
is : 'message-list',
properties : {
messageList : {
type : Array,
observer: '_messageListChanged',
reflect : true ,
value : function() {
return [{'inputMessage' : 'Welcome to the Chat' ,
'nickName' : 'System' , 'msgTime' : new Date()}]
}
//, notify : true
}
},
_messageListChanged: function(newValue , oldValue) {
console.log("Data changed");
},
created : function() {
console.log("messagelist created");
},
ready : function() {
console.log("messagelist ready");
},
attributeChanged : function() {
console.log("messagelist attributeChanged");
}
});
</script>
On the index.html Page -
var self = this;
socket.on('chatMessage' , function(msg) {
self.messages.push(msg);
console.log(self.messages);
document.querySelector('message-list').messageList = self.messages;
});
With all of this.. Anytime a client sends a message , the self.messages - posts the total set of messages , but the "_messageListChanged" of the custom elements gets called only the first time .
There are similar questions - Updating a polymer element property with data from API call
However assigning the data , works only for the first time .
Also i would like to be able to do it without using ajax-iron and stuff .
In addition to using the Polymer API for array mutations (as Alon has pointed out in his answer), you need to install an observer for array mutations. The observer you have now will only fire when you assign a new array instance, but not when you add or remove elements from your array.
properties : {
messageList : {
type : Array,
value : function() {
return [{'inputMessage' : 'Welcome to the Chat' ,
'nickName' : 'System' , 'msgTime' : new Date()}]
}
}
},
observers: [
'_messageListChanged(messageList.splices)'
],
Note that this kind of observer takes a single argument, a change record.
Your observer method should accept a single argument. When your observer method is called, it receives a change record of the mutations that occurred on the array.
The problem is that you use push. polymer has his own push function.The regular push does not trigger the observers, and all the change events.
this.push('array',value)
But for you, you can solve it like this:
var self = this;
socket.on('chatMessage' , function(msg) {
self.messages.push(msg);
document.querySelector('message-list').messageList = self.messages.slice();
});
The slice will create new array. And it will trigger all the change in the array.
please try adding reflectToAttribute:true to your messageList property.
if you still don't get it solved try to so this
self.myimmutedArray JSON.parse(JSON.stringify(self.messages))
before document.querySelector('message-list').messageList = self.myimmutedArray;
reason could be the javascript array push or slice will not refelect in polymer's dirty checking
if you use below code in the a polymer component. you must follow polymer's array changes like
this.push('messages', {title:'hey'});
var self = this;
socket.on('chatMessage' , function(msg) {
self.messages.push(msg);
console.log(self.messages);
document.querySelector('message-list').messageList = self.messages;
});
I'm fairly new to django, and I'm trying to figure out how to create a form using the taggit-selectize widget (or django-taggit). Everything I've found online refers to its use the admin page, but I want the tags to be user-facing and editable - much like the tags I create below this post. So far, I've determined that I need to create a form using a widget:
# models.py
from taggit_selectize.managers import TaggableManager
tags = TaggableManager()
# forms.py
from taggit_selectize.widgets import TagSelectize
from .models import MyModel
class TagForm(forms.ModelForm):
class Meta:
model = MyModel
fields = ('tags',)
widgets = {'tags': TagSelectize(),}
but I can't figure out how to include this form in my template so that it appears beside my MyModel objects. Ideally, I guess I'd was expecting it to behave like django-fluent-comments, where I can just call {% render_comment_form for obj %} and call it a day.
Update
I've edited views (see below) and can now access the form in the template, but I can't seem to submit my tags (ideally this wouldn't trigger a redirect, either).
# views.py
from .forms import TagForm
def show_tags(request):
return render(request, 'tags.html', {'tagform' : TagForm})
# tags.html
<div>
{{ tagform.media }}
{{ tagform.as_p }}
</div>
So, I finally figured this out. It involves wrapping the tagform in <form> tags and catching the POST request. For the record, this is part of a project that involves using Haystack to return a list of results that I then want to tag. My views.py subclasses a SearchView rather than defining a function as I do here (show_tags()), and rather than one object per page I have multiple.
For an object obj on the page, you have the following
# views.py
from .forms import TagForm
from .models import MyModel
from django.views.decorators.http import require_POST
from django.views.decorators.csrf import csrf_exempt
def show_tags(request):
# Perhaps the request specifies the object, but
# for simplicity's sake we just pick a specific model instance
object = MyModel.objects.filter(pk = 123)
return render(request, 'tags.html', {'tagform' : TagForm,
'obj' : MyModel})
#require_POST
#csrf_exempt
def create_tag(request):
# See javascript below for creation of POST request
data = request.POST
tag_text_raw = data.get('tag_data')
# clean_tag() not shown, but it splits the serialized
# tag_text_raw and returns a list of strings
tag_text_clean = clean_tag(tag_text_raw)
obj_pk = data.get('obj_pk')
#save tags to document
doc = DocInfo.objects.get(pk = obj_pk)
doc.tags.add(*tag_text_clean)
# not strictly necessary; mainly for logging
response_data = {'tag_text': tag_text_clean,
'obj_pk': obj_pk
}
return JsonResponse(response_data)
So show_tags sends the information to the template with render, then the template has access to those objects. This is what didn't make sense to me initially.
# tags.html (extends base.html)
{% block scripts %}{{ block.super }}
<script type="text/javascript" src="{{ STATIC_URL }}js/ajaxtag.js"></script>
{{ tagform.media }}
{% endblock %}
{{ obj.text }}
<form method="post" action="create_tag/" id="tag-form-{{ obj.pk }}" name="tag-form-obj" data-object-id={{ obj.pk }}>
{{ tagform.as_p }}
<input type="submit" name ="tag-form-input" value="Add Tags" />
</form>
We can catch the POST request with javascript:
#ajaxtag.js
(function($)
{
// A stripped-down version of ajaxcomments.js from fluent_comments
// See that file for further expansions
$.fn.ready(function () {
var tagform = $('form[name="tag-form-obj"]');
if (tagform.length > 0) {
// Detect last active input.
// Submit if return is hit
tagform.find(':input').focus(setActiveInput).mousedown(setActiveInput);
tagform.submit(onTagFormSubmit);
}
});
function onTagFormSubmit(event)
{
event.preventDefault(); // prevents redirect
var form = event.target;
create_tag(form);
return false;
}
function create_tag(form)
{
console.log("create_tag is working!") // sanity check
var $form = $(form);
var tag_text = $form.serialize();
var url = $form.attr('action');
var obj_id = $form.attr('data-object-id')
$.ajax({
url : url,
type: "POST",
data: { tag_data: tag_text, obj_pk: obj_id},
success: function (data) {
data;
console.log(data);
console.log('success');
},
error: function (xhr, errmsg, err) {
// Return error to console
console.log(xhr.status + ": " + xhr.responseText)
}
});
}
function setActiveInput() {
active_input = this.name;
}
})(window.jQuery);
Finally, urls.py sends the request back to create_tag()
# urls.py
from .views import create_tag
...
url(r'^create_tag', create_tag, name = 'tag-form')
...