Rendering based on conditions: whether it be components or data

I am currently working on implementing editor functionality for a page using Vue2. The page contains an 'editable' filter which receives a content_id. Based on this content_id, we need to retrieve data from the root Vue instance (e.g. pageContent.mainTitle). Depending on the value of the editModeOn variable in the root, we should either render a component or output the corresponding content (e.g.

<editable content="mainTitle" />
or the content in the mainTitle key).

This is the basic structure of the HTML:

<div id="root">
    {{ 'mainContent' | editable }}

    <label class="checkbox">
        <input type="checkbox" v-model="editModeOn">
        Switch edit mode
    </label>
</div>

Here is an example of the Vue instance:

new Vue({
    el: '#root',
    data: {
        editModeOn: true,
        pageContent: {
            mainTitle: "Test title",
            mainContent: "Lorem ipsum dolor sit amet, consectetur adipisicing elit. At, et!"
        }
    },
    filters: {
        editable(contentId) {
            if (!this.editModeOn) {
                return `<editable content="{{ this.pageContent[contentId] }}" />`;
            } else {
                return this.pageContent[contentId];
            }
        }
    }
});

I decided to utilize filters for this functionality because when edit mode is disabled, I want to avoid adding unnecessary wrappers like span or div.

If there is a better way to achieve the desired functionality, I would appreciate any suggestions. Thank you!

Answer №1

If my understanding of the issue is correct, one possible solution is to utilize a template. When using a template tag, it will not be displayed on the rendered output.

<div id="main">
    <template v-if="!editingMode">
      {{content['primaryContent']}}
    </template>
    <editable v-else :content="content['primaryContent']" />

    <label class="checkbox">
        <input type="checkbox" v-model="editingMode">
        Toggle Edit Mode
    </label>
</div>

Answer №2

Examining the html code, I noticed that the contentId is hardcoded into the div element, suggesting there could be multiple divs like this on the page. My suggestion would be to create a component and pass in a 'content' attribute.
Switching between editing and displaying can be achieved using v-show

Vue.component('editable', {
  template: `
    <div>
      <div v-show="!editModeOn">{{ content }}</div>
      <div v-show="editModeOn">
        <input :value="content" @input="$emit('update:content', $event.target.value)"></input>
      </div>

      <label class="checkbox">
         <input type="checkbox" v-model="editModeOn">
        Switch edit mode
      </label>
    </div>
  `,
  props: ['content'],
  data {
    editModeOn: false
  }
})

Implementation on the main page

<editable :content.sync="pageContent['mainTitle']"></editable>    
<editable :content.sync="pageContent['mainContent']"></editable>

Alternatively,

<editable v-for="item in pageContent" content.sync="item"></editable>    

Some points to consider:

Using v-show instead of v-if allows the user to switch between display and edit modes seamlessly. V-show retains the edited content in memory, while v-if removes the edit node altogether.

By utilizing the .sync modifier, changes made in the edits can be propagated upwards to the parent component, refer to .sync

This code snippet has not been tested extensively, so minor adjustments may be required. Nevertheless, it conveys the concept effectively. For a live demonstration, visit this CodePen link

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Aligning the stars with CSS

One of the components I have deals with a star rating system, and I thought it would be cool to use Font Awesome icons for half stars. Everything is working well except for the CSS styling aspect. While I managed to position some of the stars correctly by ...

Revealing elements with AngularJS ng-show directive prior to concealing them

Currently, I am in the process of implementing a slide effect for bootstrap badges to showcase hierarchical data relationships using AngularJS. My goal is to have a slider-effect that smoothly reveals new sub-categories while concealing previously open su ...

What could be causing the issue of PHP not receiving this multidimensional array through Ajax?

Having an issue with receiving a multidimensional array in PHP after posting it from JS using Ajax: $.ajax({ type: 'post', url: 'external_submit.php', dataType: "json", data: { edit_rfid_changes_submit ...

The installation of npm modules is failing with the error message: "'react-scripts' is not recognized as a valid command, internally or externally."

As I revisited my old project on GitHub, things were running smoothly a few months prior. However, upon attempting to npm install, I noticed the presence of the node modules folder and encountered some npm errors. https://i.stack.imgur.com/awvjt.png Sub ...

Select2 script fails to render properly after returning from Action Result

In my MVC4 application, the index page features JQuery UI tabs that I use to display content updated via Ajax action links. One of the tabs includes a Select2 option box which renders correctly initially but defaults to basic functionality after clicking a ...

Concealing content to prevent it from being accessed through HTML and JavaScript inspection techniques

I created a website with a simple guessing game where users can win if they enter the right code. My approach involves using JavaScript: <script> function z() { var b = document.getElementById('idea'); var a = document.g ...

The transfer of character data from PHP to jQuery is not successful

Working with HTML files In this scenario, the values for the sub combobox are being retrieved through a PHP select query and these values are in character format. I have successfully tested passing integer values. <select name="sub" id="sub"> ...

When resizing the window, the width change in JQuery always resets to 0

I've been trying to adjust the width of a div element when the window is resized, but for some reason, the width always ends up being 0 after the resize event. function resizeUploadField() { var uploadInputField = $('.input-append&apo ...

Classes were successfully stored on the icon following the page's refresh

I'm struggling with the following code snippet: <div class="places-item"> <div class="places-item-img"></div> <div class="places-item-header"> <h2>Machu Picchu, Peru</h2> <div cl ...

What could be causing my Vue.js project's favicon not to show up?

My favicon has suddenly disappeared from my Vue.js project, despite it working fine before. I haven't made any changes to the code related to the favicon or moved the file. In the <head> section of my index.html document, I have linked to the fa ...

Can you explain the distinction between mutation and action?

Can you explain the rationale behind Vuex having both "actions" and "mutations?" I can see the point of components not directly modifying state, but it seems redundant to have actions trigger mutations to update the state. What sets "actions" apart from ...

The grid fails to apply remote filtering values when an additional Nested ajax call is incorporated alongside the current HttpProxy configuration

Whenever I click for filter/sort for remote filtering, Forms.asp triggers using a proxy and automatically reloads. Previously, when I used the script below to reload the ExtJS grid with Forms.asp returning new XML with filtered grid data, everything worked ...

Challenge implementing custom javascript to display categorical/string features on Shiny slider

I'm attempting to design a unique Shiny slider that represents the months of the year. My desired outcome is for the slider to display the names of the months as strings, rather than numeric values where 1 corresponds to January, 2 corresponds to Febr ...

Retrieve the current date and time in JSON format using moment.js for the local

Below is the code snippet I am working with: var startTime = moment("2020-09-08 16:00:00").toDate(); console.log(startTime) const data = {start: startTime} console.log(JSON.stringify(data) After running it, the result is as follows: Tue Sep 08 ...

When it comes to identifying a click outside of an element, the Jquery or Javascript function may encounter some challenges specifically with Internet Explorer

After reviewing various solutions online, I noticed that they all function properly on Chrome and Firefox but encounter issues with Internet Explorer when interacting with an SVG. For instance, consider the following code snippet: $(document).on("click",( ...

Invoking a function within a loop disrupts its flow

In my coding project, I have developed a function that iterates through an object retrieved from a MongoDB collection. This object represents all possible connections for various mail transportation posts. The goal is to identify and remove inverse connect ...

Utilize Angular 2 interceptor to incorporate HTTP requests

Dealing with the 401 response from an interceptor using the HttpClientModule in Angular and JWT authentication can be a bit tricky. When the accessToken expires, it's necessary to use the refreshToken to obtain a new one before making the actual API r ...

Prettier eliminates the need for parentheses in mathematical expressions

When working with mathematical expressions in React and attempting to slice an array based on those expressions, I encountered an issue with the Prettier extension. It automatically removes parentheses from the expressions, resulting in incorrect calculati ...

How can I disable the onClick event for an image within a div in an onClick function?

Is there a way to disable click events for an image using its image id? For example, if the id is id12, I want to disable the click event. I attempted to use `unbind` but it appears that it only works if the event is bound using jQuery? ...

Styling div elements to match the dimensions of table rows in CSS

When it comes to CSS, I wouldn't call myself an expert; My question is: is there a way for a div tag to inherit dimensions from specific table rows based on their class or id? For instance: Imagine we have a table with multiple rows, but we don&apos ...