-3

var loaderGif = "https://www.tietennis.com/img/loaders/LoaderIcon.gif"

var processingImageUrl = '<img id="imgProcessing" src="' + loaderGif + '" />'

$(document).on("click", "input[name='PermissionID']", function() {
    var PermissionCheckBox = $(this)[0];

    $.ajax({
        method: "POST",
        url:    "https://httpbin.org/post",
        cache:  false,
        async:  true,
        beforeSend: function(xhr, opts) {
            $(PermissionCheckBox).after(processingImageUrl);
        },
        success: function(result) {
            $(PermissionCheckBox).parent().find('#imgProcessing').remove();
        }
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
    <tr>
        <td>
             Check me:
             <input name="PermissionID" type="checkbox" value="1">
        </td>
    </tr>
</table>

I was actually trying to convert the jQuery code to vue.js.

I am trying to find a way if I could put the image with checkbox on click in vue.js.

I tried below code, but now sure how could I use event passed from checkbox to add image and remove it

updatePermission(roleModulePermissionID, event) {
}

Can you suggest something for this?

acdcjunior
  • 132,397
  • 37
  • 331
  • 304
Pankaj
  • 9,749
  • 32
  • 139
  • 283

1 Answers1

2

In Vue, you (optimally) don't directly manipulate the DOM. You manipulate the data and configure the template to react to that data according to what you need.

To create multiple rows, use v-for.

So, for instance, instead of adding and removing a "loading image", you would create an <img> whose display depended on some flag from your data, say permission.loading:

<img v-show="permission.loading" :src="loadingImg">

That way, when you set permission.loading to true, the loading image will show. When you set permission.loading to false it will hide.

Since you want to show it while the Ajax is performing, set permission.loading to true before calling the Ajax (the fetch() below) and set permission.loading to false when it completes.

Full demo below.

new Vue({
  el: '#app',
  data: {
    loadingImg: "https://www.tietennis.com/img/loaders/LoaderIcon.gif", // for demo purposes
    permissions: [{
      id: 1,
      label: 'Permission to Take off',
      ticked: false,
      loading: false,
      postURL: "https://httpbin.org/post?take-off" // demo URL
    },{
      id: 2,
      label: 'Permission to Board',
      ticked: true,
      loading: false,
      postURL: "https://httpbin.org/post?board" // demo URL
    },{
      id: 3,
      label: 'Permission to Land',
      ticked: false,
      loading: false,
      postURL: "https://httpbin.org/post?land" // demo URL
    }]
  },
  methods: {
    updatePermission(permission) {
      permission.loading = true; // set loading and image will be shown
      fetch(permission.postURL, {method: "POST", body: {}})
        .then(() => permission.loading = false); // setting to false will make it disappear
    }
  }
})
img { height: 17px; margin-bottom: -1px; }
<script src="https://unpkg.com/vue"></script>
<div id="app">
  <table>
    <tr v-for="permission in permissions">
      <td>
        <label>
          {{ permission.label }}:
          <input name="PermissionID" type="checkbox" :value="permission.id" @change="updatePermission(permission)" v-model="permission.ticked" :disabled="permission.loading">
        </label>
        <img v-show="permission.loading" :src="loadingImg">
      </td>
    </tr>
  </table>
</div>

I also would add a :disabled="permission.loading" to prevent another click when it is loading.

acdcjunior
  • 132,397
  • 37
  • 331
  • 304
  • actually there will be many checkboxes in the table which are rendering dynamically. Can u please suggest for that? – Pankaj Mar 22 '18 at 17:06
  • You can use `v-for` for that. Gimme a sec. – acdcjunior Mar 22 '18 at 17:08
  • Updated. Check it out. – acdcjunior Mar 22 '18 at 17:21
  • Working perfectly. Only one thing left, My image has src property defined like this. `` Problem I think comes when the checkbox is clicked and it updates the loading property in the component and that time I get the error: **Cannot read property 'domain_Name' of undefined** but this is not the case at the time of load or at the time of click. I can confirm that I am using same property to concatenate post url. – Pankaj Mar 22 '18 at 19:42
  • There is no problem if the url is this: https://www.tietennis.com/img/loaders/LoaderIcon.gif Also there is no problem in other components as I am using this same code. I am assuming that it is 2 way process and that's why something is happening. – Pankaj Mar 22 '18 at 20:20
  • Try using `$root` without `this`, like: `:src="$root.domain_Name + 'Images/ajax-loader.gif'" ` – acdcjunior Mar 23 '18 at 01:44
  • any idea about : https://stackoverflow.com/questions/49460260/inform-user-that-message-is-still-being-typed – Pankaj Mar 24 '18 at 01:14
  • Seems good.. You could maybe do some sort of "debounce", to not send requests every typed char, but once every 4s, and if the other part doesn't receive a notification in 5s it stops displaying that the other one is typing. Anyway, it looks cgood – acdcjunior Mar 24 '18 at 01:20
  • Do I have an event called whisper as shown here https://laravel.com/docs/5.6/broadcasting#client-events ? I am using vue.js and laravel 5.6.7 – Pankaj Mar 24 '18 at 01:38
  • That seems proper. Though I think you should paste it there in the question. I like to help but I know Vue.js more than Laravel... So I think I can't help you much in this one.. sorry... – acdcjunior Mar 24 '18 at 01:43
  • can u please suggest in vue.js only? – Pankaj Mar 24 '18 at 02:44
  • But your code actually seems to work. Do you encounter any problem using it? – acdcjunior Mar 24 '18 at 03:21