Giter Club home page Giter Club logo

vue-at's Introduction

vue-at

        Join the chat at https://gitter.im/fritx/vue-at

  

  • Chrome / Firefox / Edge / IE9~IE11
  • Plain-text based, no jQuery, no extra nodes
  • Content-Editable / Textarea
  • Avatars, custom templates
  • Vue3 / Vue2 / Vue1
  • Vuetify / Element UI / Element Plus
  • Vue-CLI migration
  • Vite migration

Playground: https://we-demo.github.io/vue-at-vite-app/
Vue3 Docs: https://github.com/fritx/vue-at/tree/vue3#readme
Vue2 Docs: https://fritx.github.io/vue-at/ or see below
See also: react-at

Motivation

At.js is awesome, but:

  • It is based on jQuery and jQuery-Caret.
  • It introduces extra node wrappers.
  • It could be unstable on content edit/copy/paste.

Finally I ended up creating this.

If you're using Vue3, read branch vue3 instead.

npm i vue-at@next  # for Vue3 (branch vue3)
npm i [email protected]  # for Vue2 (branch vue2)
npm i [email protected]  # for Vue1 (branch vue1-legacy)
npm i vue1-at  # for Vue1 (branch vue1-new)
<template>
  <at :members="members">
    <div contenteditable></div>
  </at>
</template>

<script>
import At from 'vue-at'

export default {
  components: { At },
  data () {
    return {
      members: ['Roxie Miles', 'grace.carroll', '小浩']
    }
  }
}
</script>

<style>
#app .atwho-view { /* more */ }
#app .atwho-ul { /* more */ }
</style>

Using V-Model (Recommended)

With Content-Editable, v-model should be bound in <at> container.
With Textarea, v-model should be bound in <textarea> itself.

<at v-model="html">
  <div contenteditable></div>
</at>

<at-ta>
  <textarea v-model="text"></textarea>
</at-ta>

Textarea

<template>
  <at-ta>
    <textarea></textarea>
  </at-ta>
</template>

<script>
// import At from 'vue-at' // for content-editable
import AtTa from 'vue-at/dist/vue-at-textarea' // for textarea

export default {
  components: { AtTa }
}
</script>
npm i -S textarea-caret  # also, for textarea

Custom Templates

Custom List

<template>
  <at :members="members" name-key="name">
    <template slot="item" slot-scope="s">
      <img :src="s.item.avatar">
      <span v-text="s.item.name"></span>
    </template>
    <div contenteditable></div>
  </at>
</template>

<script>
// ...
members: [{
  avatar: 'https://randomuser.me/api/portraits/men/2.jpg',
  name: 'myrtie.green'
}, {
  avatar: 'https://randomuser.me/api/portraits/men/8.jpg',
  name: '椿木'
}]
</script>

<style>
#app .atwho-li { /* more */ }
#app .atwho-li img { /* more */ }
#app .atwho-li span { /* more */ }
</style>

Custom List with Vue 1.x

There is no "scoped slot" feature in Vue 1.
Use a "normal slot" with data- attribute instead.

<!-- vue1-at for [email protected] -->
<template slot="item">
  <img data-src="item.avatar">
  <span data-text="item.name"></span>
</template>

Custom Tags

This gives you the option of changing the style of inserted tagged items. It is only supported for ContentEditable version, not Textarea.

<span slot="embeddedItem" slot-scope="s">
  <span class="tag"><img :src="s.current.avatar">{{ s.current.name }}</span>
</span>

<!-- with Vue 2.6+ 'v-slot' directive -->
<!-- note at least two '<span>' wrapper are required to work -->
<template v-slot:embeddedItem="s">
  <span><span class="tag"><img class="avatar" :src="s.current.avatar">{{ s.current.name }}</span></span>
</template>

Used with 3rd-party libraries

Vuetify v-textarea

<at-ta :members="members">
  <!-- slots -->
  <v-textarea v-model="text"></v-textarea>
</at-ta>

Element-UI el-input

<at-ta :members="members">
  <!-- slots -->
  <el-input v-model="text" type="textarea"></el-input>
</at-ta>

vue-at's People

Contributors

4ver avatar alideniz avatar brimstedt avatar brynne8 avatar fritx avatar gitter-badger avatar nsano-rururu avatar wangbinyq avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vue-at's Issues

Placeholder

Thanks for your package. It could be great if this component could display a placeholder, just like a regular textarea (maybe it's already possible, but I did not found how)

Functionality Request: Allow other autocomplete (emoji with : and Tasks with /)

Hey Team,
@Brimstedt @jezzdk @wangbinyq @4ver @Alideniz
This is really awesome package for any vuejs editor. It's easy to integrate.

I request to provide two more feature to make this much powerful:

  • Modifying tag: Allow to add some html so it can allow the click events on it. Just like GITHUB tags does have it. Right now, we just have @somename as plain-text rather than that it would be great if we can have :
<a href="" data="{somedata json}">@somename</a>
OR
<b>@sometag</b>

So once the post is sent for database entry we can also have redirection/link along with it.

  • Just like GITHUB: It would be great if we can have Emojis autocomplete or custom events which can work along with User taging.
    Example: Use / to get task list or user # to bring up groups, etc...

Let me know your view on it.

Use vue-at with textarea

When I try to use this example with <div class="editor" contenteditable></div> :

<template>
  <div id="mention">
    <at :members="members" >
      <template slot="item" scope="s">
        <span v-text="s.item"></span>
      </template>

      <div class="editor" contenteditable></div>
    </at>
  </div>
</template>

It works just fine, but when I change it to use textArea, it didn't work at all. Is there any way I can use vue-at with textarea?

at 前面空格?,at后怎么取出来?

1 以微信为例,不管前面是不是空格只要输入at,都会触发事件,目前博主这里似乎是前面空格才行。这个能否修复?
2 at后 肯定还是要取出来(发送出去),如何区分出,真正由于at触发的(ex:@小浩)和手动输入的(ex:@123),

Is there a way to handle a change?

I would like to handle a change with a specific value for the user mentioned.

Example:

 <at-ta :members="members" name-key="email" @change="handleChante(s.item.email)" v-model="commentForm.comment">
    <template slot="item" slot-scope="s">
        <img :src="s.item.thumb">
        <span v-text="`${s.item.firstName} ${s.item.lastName}`"></span>
    </template>
    <textarea class="editor" rows="1" :disabled="getIsLoading" placeholder="Type here a message, question, information..."></textarea>
 </at-ta>

Is this possible?

Not selecting at Click

Hi.

I'm using vue-at textarea which works fine until the point where I click an item from the showed up list. In that moment, the clicked item does not get selected. Any idea why it could be happening?

Add support for input

I can use vue-at for div and textarea but not input. Do you think it could be possible?

Thanks for your package.

2.5.0-beta w/ styled-tags insertion

Related issues: #13, #35, #42, #51, #52, #53

Related PR: #54 (pending)

README: (coming soon..)
Online demos: (coming soon..)

<at :members="members" name-key="name" v-model="html2">
  <!-- custom tag: avatars -->
  <span slot="embeddedItem" slot-scope="s">
    <span class="tag"><img class="avatar" :src="s.current.avatar">{{ s.current.name }}</span>
  </span>

  <!-- custom list: avatars -->
  <template slot="item" scope="s">
    <img class="avatar" :src="s.item.avatar">
    <span class="name" v-text="s.item.name"></span>
  </template>

  <div class="editor" contenteditable></div>
</at>

More example at branch demo/try-emoji or commit 7cdcea1

Thank you all, @dmitry-kozachek, @jasonlfunk, @Zanzavar, @hfalucas, @gdutwyg, @chieh301, @wuyungen1996, @jrvaja, @Brimstedt

# please try
npm i -S [email protected]

Undefined

Trying to implement the example & getting a simple undefined as the output in the browser.

Inspecting the DOM I can see:

<div class="atwho-wrap"><!----> undefined</div>

dist/vue-at-textarea is missing

I have just installed from npm using: npm i [email protected] and npm i -S textarea-caret. However, in node_modules/vue-at/dist, I don't see vue-at-textarea, I only see index.js and index.map.js. And importing index.js doesn't work (but doesn't throw any error either).

Am i doing something wrong?

Members' List not Showing When the Script is Built

Hi @fritx

Thanks for the amazing package there.

I'm using Vue-at with textarea, and everything works fine in npm run dev server. However, when I build my project using npm run build (no error threw out), the members' list just becomes invisible. The DOM still gets rendered and using arrow keys and enter can still autocomplete the members without any problem, but the list just not there after I type @.

Meanwhile, if you check the example in your own doc (https://fritx.github.io/vue-at/#/en/textarea), something is definitely wrong there. Thanks.

Modify component to use PopperJS

Greetings.

I propose to use PopperJS. I know that adding a dependency to a project has a cost, but I think that PopperJS can be very beneficial to this project. It allows for further customization and covers most corner cases on positioning without needing to implement custom logic.

It has been adopted by the some major frameworks like bootstrap, foundation and element-ui.

I will get familiar with the source code and see If I can submit a PR.

Thank you.

Insert html instead of text

Hi, in At.js there is a possibility to place custom html, so it would be good to have a slot like this:

<div ref="insertItem">
  <slot name="insertItem" :item="selectedItem">
    <span v-text="itemName(selectedItem)"></span>
  </slot>
</div>

and then insertItem() function should look like:

data () {
    return {
      ...
      selectedItem: null
    }
},
...

insertItem () {
      const { range, offset, list, cur } = this.atwho
      const r = range.cloneRange()
      r.setStart(r.endContainer, offset + 1) // 从@后第一位开始
      // hack: 连续两次 可以确保click后 focus回来 range真正生效
      applyRange(r)
      applyRange(r)

      this.selectedItem = list[cur]
      const html = this.$refs.insertItem.innerHTML

      document.execCommand('insertHtml', 0, html + ' ')
    }

Also in this case it would be good to have prop like keepTriggerChar:

...
if(this.keepTriggerChar) {
    offset++;
}
r.setStart(r.endContainer, offset) // 从@后第一位开始
...

display dynamic name on list?

At title,
i got this data

members:[
{ name:first_name,display:this.user.first_name},
{name:last_name,display:this.user.last_name},
{name:today_function_time,display:'Show Dynamic time from computed?'}
]

here is my template

<template slot="item" scope="s">
	<span v-text="s.item.display"></span>
</template>

when i use "@" it will show the text below:

Jason
Lee
*Dynamic Time

wish you can understand what i mean.
Thanks

v-model 的 textarea 不支持吗?

<at-ta at="@" :members="members" name-key="name">
	<template slot="item" slot-scope="s">
		<span v-text="s.item.display"></span>
	</template>
	<textarea class="form-control m-input" v-model.trim="messages" rows="3"></textarea>
</at-ta>
export default {
           data() {
            return {
                        messages: 'This is message'
                        members: [
                                            {
                                                name:'first_name',
	                                        display: 'Customer First Name',
                                            },
	                                    {
                                                name:'last_name',
		                                 display: 'Customer Last Name',
                                            },
	                                    {
                                                name:'full_name',
                                                display: 'Customer Full Name',
                                           }
                       ],
            }
           }
}

当输入@的时候会显示列表,但是点击后却没有输入 name 到框内 只保留了 @。
我的messages data是一个修改框。
就是说会将服务器内的数据库显示再 messages data内。
我测试了 只要去掉

v-model.trim="messages"
就可以正常使用。我也尝试换成

:value="messages"
换成 value 后 就连 @ 的列表都闪关
我这个情况下还有什么方式可以使用吗?
因为我的 messages 是动态框 所以必须用 :value 或者 v-model

Is there a way to get the current text value?

Assuming my code is:

<at-ta :members="members" :filter-match="filterMatch">
  <textarea class="editor" v-text="content"></textarea>
</at-ta>

It seems the text value does not change when I type. Is there a way to get the current value of the textarea?

The Member List Can't Be Autocompleted in IE

Hi @fritx

It's me again.

After the latest update, everything seems to work perfectly in Chrome. However, when I'm doing some final testing on IE compatibility, it seems that the item in member list can't be autocompleted, regardless of using mouse cursor or pressing Enter. This issue can be reproducible in your doc example.

It would be nice if you can shed some light on this. Thanks.

[question] How can I configure a symbol like @ to other data?

Like the At.js docs say;

$('#inputor').atwho({
    at: "@",
    data:['Peter', 'Tom', 'Anne']
})

So I'd like to bind @ to users, and # to something else, like here on Github even. Am I missing something here; it it not possible yet or is it missing from the docs.

Is it possible to wrap `at-structure` in <span> tag?

I am trying to use vue-at with vue-medium-editor, but it seems the at-form inside the paragraph would lead to problems like

  • the space at the end of the at-form is of no use, and the next at would be useless since there's no space between the at and at-form before.
    @someone@
  • the at-form is mixed with the other contents and is not easy for selection

Need assistance for Events

Hey there,

I much appreciate this repository.

I would love know whether it's support events or not.

Example: If I add any in the text, i need to notify the person. So need the list of all user that I have tagged. As well as, if i remove then it should remove from selected list of tagged user.

Your response is really valuable to me.

Best Regards,
Jaimin

Allow selections using Tab

It looks like At.js allows selecting values using the tab key along with the enter key. It would be nice if vue-at also had this functionality.

Backlog

  • compatibility note: display:flex is used http://caniuse.com/#search=flex
  • bug: insertItem in the middle of @'d name
  • remote suggestion request #16
  • v-model support #29, #43
  • scss error in vueify #37
  • dep: insert-text-2
  • getCurrentEditor editable/textarea
  • customized inserted user id and emit a handler? #28
  • maybe close panel at blur/esc (hideOnBlur prop with timer handling) #20
  • insertAt method #26
  • bug: openPanel index error after "delete"
  • IE9~11/Edge compatibility #22
  • textarea #11
  • Position bug when browser scrollbar is visible #10
  • multiple at chars #6
  • prop default: () => []
  • vue1: data-atwho-attrs
  • vue1 standalone npm repo (branch)
  • 如果clientX/Y没变 则忽略 修复"鼠标停留在panel上干扰键盘选择" #12
  • hoverSelect prop #12
  • "Use vue-at with textarea" #11
  • "Insert html instead of text" #13, #53, #54
  • automated testing #54 (comment)
  • bug: 一个name包含另一个name+空格 如@"all" @"Marshall Yu"
  • "Better positioning strategy required" #5
  • scrollIntoView in firefox vuejs/awesome-vue#1028
  • "Position bug when browser scrollbar is visible" #10
  • compatible with vue 1.x #4
  • getPrecedingRange bug
  • feature: custom item templates with avatars
  • improve readme motivation
  • bug: keydown like shift/ctrl, etc causes cur reset to 0
  • missing .npmignore #1

How to remove the suggestions on already selected values on page load

Hi,

Thank you guys for putting efforts on creating this awesome plugin. This works great. I have only one problem. Whenever I reload the page it highlights all already selected values on the screen. I want to remove those so they will appear only when the textarea is selected or the field is selected
Please check below image

image

Mouse hover disturbs keyboard select

Mouse hover on the at-panel disturbs keyboard select.

If the mouse remains at the 3rd item on the list,
when we press the up/down keys,
the list scrolls,
but the 3rd place would keep getting selected unexpectedly.

A workaround to avoid this if you care much about it,
is to disable the hover-selecting feature:

<at :hover-select="false"></at>

Fixing this bug with hover-select turned on (by default), is also under development.

How to debug

I apologize for asking such a general question, but I would like to contribute to this repository, and I am having trouble figuring out exactly how to do it.

Specifically, when I download the repository, how do I add it to my project? Do I use npm? Do I use ‘import’ statements? For example, I am trying to work on the textarea component, but there is no /dist folder in the repository. How do I create that from /src?

在首个字符加入custom tag后删除后出现bug

我用的是2.5.0-beta版本,浏览器是Chrome 49。在content editable内插入类似

<span slot="embeddedItem" slot-scope="s">
  <span class="tag"><img :src="s.current.avatar">{{ s.current.name }}</span>
</span>

的代码,在首个字符就插入at结构@123,然后退格键把它删掉,此时再加入一个at结构@456的时候,发现at上面的菜单关不掉(在Chrome 49出现,最新版Chrome能关掉),并且出现光标在at结构之前(所有浏览器都这样),且无法将光标定位到at结构之后。再次点击未关掉的menu的某个member,Chrome 49提示

Uncaught IndexSizeError: Failed to execute 'setStart' on 'Range': 
The offset -1 is larger than or equal to the node's length (0).

2.4.0-beta with v-model support

Related issues and comments: #8 (comment), #22 (comment), #26, #29, #32 (comment), #41 (comment)

Related PR: #38

README: https://github.com/fritx/vue-at#using-v-model-recommended
Online demos: http://fritx.github.io/vue-at/#/en/vmodel

<at v-model="html">
  <div contenteditable></div>
</at>

<at-ta v-model="text">
  <textarea></textarea>
</at-ta>

Thank you all, @KuiShang, @pingshunhuangalex, @Yuzhongbing, @youyi1314, @iadambrown, @rap2hpoutre, @Brimstedt

# please try
npm i -S [email protected]

Multiple issues with firefox

Hey, thanks for working on this awesome library.
I've faced multiple issues when using the embeddedItem slot with firefox:

Problem with deleting.

How to reproduce:

  1. open the demo.
  2. on the second example (that uses custom embeddedItem template), try inserting two mentions.
  3. hit backspace multiple times.

Current Behavior:

Only the last mention is deleted, then the cursor gets stuck.

Expected Behavior:

Both mentions should be removed.


Problem navigating with arrows

How to reproduce:

  1. open the demo.
  2. on the second example (that uses custom embeddedItem template), insert one mention.
  3. Hit left arrow until the cursor moves to the left side of the mention.
  4. Hit the right arrow multiple times.

Current Behavior:

The cursor gets stuck on the left side of the mention.

Expected Behavior:

The cursor should move to the right side.

Display fullname but insert username

Hello @fritx @Brimstedt @jezzdk @wangbinyq @4ver @Alideniz
Awesome job people!
I am working on a project that involves autosuggesting username of users via the reply textarea.
I am just fiddling around with the component and it occurred to me...wouldn't it be cool if we can get object data from the server that looks something like:
[{username: "username", name: "Fullname", avatar: "imgurl"}]
Then pass the object to the component as a prop.
So during search, just the avatar and the fullname will be displayed, but when clicked, the username will be inserted.
I think this particular use case would be great for users who do not necessarily know the username to search for, but seeing the name and avatar makes it easy for them to choose.

There's nothing that I would want more than to implement this and just submit a pull request...but hey, this is currently above my learning-pay grade 😄

But if you genius can buy into this idea and weave your magic wands again...this would be super cool!
Thanks everyone!!!!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.