Change icon on click within a list/loop



  • Hello guys,

    Again, I am not able to figure out how to realize a feature in Quasar/VueJS.
    Problem seems quite simple: I have an Array including articles. Title and some short description for the articles are shown in cards (loop with v-for). For each article I want to have a bookmark icon which the user can click on to change the icon (change icon to mark articles already read). This information then may also be stored in local storage.

    It is nearly the same as discussed here:
    https://forum.quasar-framework.org/topic/2595/change-qbtn-s-color-and-icon-after-click/1?_=1593446941227

    But in my case I have an Array including the articles and would appreciate some hints how to adress this when in need of using key.

    <q-card
          v-for="(Article, key) in ArticleStore"
          :key="key"
          class="my-article-card"
          flat
          bordered
        >
       <q-card-section horizontal>
       <q-card-section class="q-pt-xs">
              <div class="text-overline text-red-8">{{ Article.domain }}</div>
              <q-chip
                v-if="Article.teaserImage == '' || Article.teaserImage == undefined"
                class="absolute-top-right"
                square
                :icon="???"
                @click="???"
              ></q-chip>
              <div class="text-h5 q-mt-sm q-mb-xs">{{ Article.title }}</div>
              <div class="text-caption text-grey">
                {{ Article.teaser }}
            </div>
    </q-card-section>
    

    Thx a lot
    Dirk



  • Okay, after rethinking the problem, I figured out a different approach and that works finde.

    In case someone else will face this topic here is my solution:

    <q-card
          v-for="(Article, key) in ArticleStore"
          :key="key"
          class="my-article-card"
          flat
          bordered
        >
          <q-card-section horizontal>
            <q-card-section class="q-pt-xs">
              <div class="text-overline text-red-8">{{ Article.domain }}</div>
              <q-chip
                v-if="Article.teaserImage == '' || Article.teaserImage == undefined"
                class="absolute-top-right"
                square
                clickable
                :icon="renderedBookmark(key)"
                @click="changeStatusOfArticle(key)"
              ></q-chip>
              <div class="text-h5 q-mt-sm q-mb-xs">{{ Article.title }}</div>
              <div class="text-caption text-grey">
                {{ Article.teaser }}
              </div>
            </q-card-section>
    
            <q-card-section
              v-if="Article.teaserImage != '' && Article.teaserImage != undefined"
              class="col-5 flex flex-center"
            >
              <q-chip
                class="absolute-top-right"
                square
                clickable
                :icon="renderedBookmark(key)"
                @click="changeStatusOfArticle(key)"
              ></q-chip>
              <q-img class="rounded-borders" :src="Article.teaserImage" />
            </q-card-section>
          </q-card-section>
        </q-card>
      </q-page>
    </template>
    
    <script>
    import { mapGetters } from "vuex";
    
    export default {
      data() {
        return {
          readArticlesObject: {},
          lorem:
            "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."
        };
      },
      name: "PageIndex",
      methods: {
        changeStatusOfArticle(val) {
          if (val in this.readArticlesObject) {
            this.readArticlesObject[val] = !this.readArticlesObject[val];
            localStorage["readArticlesObject"] = JSON.stringify(
              this.readArticlesObject
            );
          } else {
            this.readArticlesObject[val] = true;
            localStorage["readArticlesObject"] = JSON.stringify(
              this.readArticlesObject
            );
          }
    
          //localStorage.readArtickleObject = JSON.parse(this.readArticlesObject);
        },
        renderedBookmark(val) {
          if (val in this.readArticlesObject) {
            return this.readArticlesObject[val] ? "bookmark" : "bookmark_border";
          } else {
            this.readArticlesObject[val] = false;
            localStorage["readArticlesObject"] = JSON.stringify(
              this.readArticlesObject
            );
            return "bookmark_border";
          }
        },
        jumpToVue(url) {
          setTimeout(() => {
            this.$router.push(url);
          }, 200);
        }
      },
      mounted() {
        this.readArticlesObject = JSON.parse(localStorage["readArticlesObject"]);
      },
    

Log in to reply