Categories
Ant Design Vue

Ant Design Vue — Customize Autocomplete and Cascade Dropdown

Ant Design Vue or AntD Vue, is a useful UI framework made for Vue.js.

In this article, we’ll look at how to use it in our Vue apps.

Customize Autocomplete

We can customize our autocomplete input with various props.

The filter-options prop lets us change how choices are filtered:

<template>
  <a-auto-complete
    :data-source="dataSource"
    style="width: 200px"
    placeholder="input here"
    :filter-option="filterOption"
  />
</template>
<script>
export default {
  data() {
    return {
      dataSource: ["apple", "orange", "grape"]
    };
  },
  methods: {
    filterOption(input, option) {
      return (
        option.componentOptions.children[0].text
          .toUpperCase()
          .indexOf(input.toUpperCase()) >= 0
      );
    }
  }
};
</script>

We get the text input value which is the input parameter with the option.componentOptions.children[0].text property.

Then we compare both of them as uppercase.

If we return true , then it’s displayed in the dropdown.

Cascade Selection Box

We can add a cascade dropdown menu with the a-cascader component.

For example, we can write:

<template>
  <a-cascader :options="options" placeholder="Please select" @change="onChange"/>
</template>
<script>
export default {
  data() {
    return {
      options: [
        {
          value: "fruit",
          label: "Fruit",
          children: [
            {
              value: "apple",
              label: "Apple"
            }
          ]
        },
        {
          value: "drink",
          label: "Drink",
          children: [
            {
              value: "coffee",
              label: "Coffee"
            }
          ]
        }
      ]
    };
  },
  methods: {
    onChange(value) {
      console.log(value);
    }
  }
};
</script>

to add the options with the options reactive property.

We set that as the value of the options prop.

It emits the change event with the selected item.

We can add the change-on-select prop to emit the change event on select:

<template>
  <a-cascader :options="options" placeholder="Please select" change-on-select @change="onChange"/>
</template>
<script>
export default {
  data() {
    return {
      options: [
        {
          value: "fruit",
          label: "Fruit",
          children: [
            {
              value: "apple",
              label: "Apple"
            }
          ]
        },
        {
          value: "drink",
          label: "Drink",
          children: [
            {
              value: "coffee",
              label: "Coffee"
            }
          ]
        }
      ]
    };
  },
  methods: {
    onChange(value) {
      console.log(value);
    }
  }
};
</script>

Also, we can render the selected item in a custom way by populating the displayRender slot:

<template>
  <a-cascader :options="options" placeholder="Please select" change-on-select @change="onChange">
    <template slot="displayRender" slot-scope="{ labels, selectedOptions }">
      <span v-for="(label, index) in labels" :key="selectedOptions[index].value">
        <span v-if="index === labels.length - 1">
          {{ label }} (
          <a @click="e => handleAreaClick(e, label, selectedOptions[index])">
            {{
            selectedOptions[index].code
            }}
          </a>)
        </span>
        <span v-else @click="onChange">{{ label }} /</span>
      </span>
    </template>
  </a-cascader>
</template>
<script>
export default {
  data() {
    return {
      options: [
        {
          value: "fruit",
          label: "Fruit",
          code: 1,
          children: [
            {
              value: "apple",
              label: "Apple",
              code: 2
            }
          ]
        },
        {
          value: "drink",
          label: "Drink",
          code: 3,
          children: [
            {
              value: "coffee",
              label: "Coffee",
              code: 4
            }
          ]
        }
      ]
    };
  },
  methods: {
    onChange(value) {
      console.log(value);
    }
  }
};
</script>

selectedOptions[index] has the selected item.

labels have the label for each value.

Disable Items

We can disable items with the disabled property:

<template>
  <a-cascader :options="options" @change="onChange"/>
</template>
<script>
export default {
  data() {
    return {
      options: [
        {
          value: "fruit",
          label: "Fruit",
          children: [
            {
              value: "apple",
              label: "Apple"
            }
          ]
        },
        {
          value: "drink",
          label: "Drink",
          disabled: true,
          children: [
            {
              value: "coffee",
              label: "Coffee"
            }
          ]
        }
      ]
    };
  },
  methods: {
    onChange(value) {
      console.log(value);
    }
  }
};
</script>

Conclusion

We can customize our autocomplete component with many ways.

Also, Ant Design Vue comes with a cascade selection dropdown.

Categories
Ant Design Vue

Ant Design Vue — Cascade Selection Box and Checkbox

Ant Design Vue or AntD Vue, is a useful UI framework made for Vue.js.

In this article, we’ll look at how to use it in our Vue apps.

Cascade Selection Box Default Value

We can set the default value of a cascade selection box with the default-value prop:

<template>
  <a-cascader :options="options" @change="onChange" :default-value="['fruit', 'apple']"/>
</template>
<script>
export default {
  data() {
    return {
      options: [
        {
          value: "fruit",
          label: "Fruit",
          children: [
            {
              value: "apple",
              label: "Apple"
            }
          ]
        },
        {
          value: "drink",
          label: "Drink",
          disabled: true,
          children: [
            {
              value: "coffee",
              label: "Coffee"
            }
          ]
        }
      ]
    };
  },
  methods: {
    onChange(value) {
      console.log(value);
    }
  }
};
</script>

We just pass in an array of values from top-level down to set it.

Also, we can add an icon on the right of the input by populating the suffixIcon prop:

<template>
  <a-cascader :options="options" @change="onChange">
    <a-icon slot="suffixIcon" type="smile" class="test"/>
  </a-cascader>
</template>
<script>
export default {
  data() {
    return {
      options: [
        {
          value: "fruit",
          label: "Fruit",
          children: [
            {
              value: "apple",
              label: "Apple"
            }
          ]
        },
        {
          value: "drink",
          label: "Drink",
          disabled: true,
          children: [
            {
              value: "coffee",
              label: "Coffee"
            }
          ]
        }
      ]
    };
  },
  methods: {
    onChange(value) {
      console.log(value);
    }
  }
};
</script>

Cascade Selection Field Names

We can set the field-names prop to set the property names of the value and label:

<template>
  <a-cascader
    :options="options"
    @change="onChange"
    :field-names="{ label: 'name', value: 'code', children: 'items' }"
  ></a-cascader>
</template>
<script>
export default {
  data() {
    return {
      options: [
        {
          code: "fruit",
          name: "Fruit",
          items: [
            {
              code: "apple",
              name: "Apple"
            }
          ]
        },
        {
          code: "drink",
          name: "Drink",
          children: [
            {
              code: "coffee",
              name: "Coffee"
            }
          ]
        }
      ]
    };
  },
  methods: {
    onChange(value) {
      console.log(value);
    }
  }
};
</script>

The object has the label , value , and children as the keys.

And we have the property names we want to set them to as the values.

Checkbox

We can add a checkbox to with the a-checkbox component:

<template>
  <a-checkbox @change="onChange">Checkbox</a-checkbox>
</template>
<script>
export default {
  methods: {
    onChange(e) {
      console.log(e.target.checked);
    }
  }
};
</script>

The change event is emitted when we check or uncheck the checkbox.

e.target.checked has the checked value.

Checkbox Group

We can add the a-checkbox-group component to add a group of checkboxes:

<template>
  <div>
    <div>
      <a-checkbox
        :indeterminate="indeterminate"
        :checked="checkAll"
        @change="onCheckAllChange"
      >Check all</a-checkbox>
    </div>
    <br>
    <a-checkbox-group v-model="checkedList" :options="plainOptions" @change="onChange"/>
  </div>
</template>
<script>
const plainOptions = ["Apple", "Pear", "Orange"];
const defaultCheckedList = ["Apple", "Orange"];
export default {
  data() {
    return {
      checkedList: defaultCheckedList,
      indeterminate: true,
      checkAll: false,
      plainOptions
    };
  },
  methods: {
    onChange(checkedList) {
      this.indeterminate =
        !!checkedList.length && checkedList.length < plainOptions.length;
      this.checkAll = checkedList.length === plainOptions.length;
    },
    onCheckAllChange(e) {
      Object.assign(this, {
        checkedList: e.target.checked ? plainOptions : [],
        indeterminate: false,
        checkAll: e.target.checked
      });
    }
  }
};
</script>

The indeterminate prop lets us set whether the checkbox is indeterminate.

a-checkbox-group has the checkbox group.

options has an array of options.

Conclusion

We can add the cascade selection box with various options.

Also, we can add the checkbox group.

Categories
Ant Design Vue

Ant Design Vue — Autocomplete

Ant Design Vue or AntD Vue, is a useful UI framework made for Vue.js.

In this article, we’ll look at how to use it in our Vue apps.

Autocomplete Input

We can add an autocomplete input withn the a-auto-complete component:

<template>
  <a-auto-complete
    v-model="value"
    :data-source="dataSource"
    style="width: 200px"
    placeholder="input here"
    @select="onSelect"
    @search="onSearch"
    @change="onChange"
  />
</template>
<script>
export default {
  data() {
    return {
      value: "",
      dataSource: ["apple", "orange", "grape"]
    };
  },
  watch: {
    value(val) {
      console.log("value", val);
    }
  },
  methods: {
    onSearch(searchText) {
      this.dataSource = this.dataSource.filter(d => d.includes(searchText));
    },
    onSelect(value) {
      console.log("onSelect", value);
    },
    onChange(value) {
      console.log("onChange", value);
    }
  }
};
</script>

We add the v-model directive to bind the inputted value to a reactive property.

It also emits the select , search , and change events.

select is emitted when we select an item.

search is emitted when we are searching.

change is emitted when we change the input.

data-source has an array with the data source.

Also, we can display the autocomplete item by populate the dataSource slot:

<template>
  <div style="width: 250px">
    <a-auto-complete
      class="certain-category-search"
      dropdown-class-name="certain-category-search-dropdown"
      :dropdown-match-select-width="false"
      :dropdown-style="{ width: '300px' }"
      size="large"
      style="width: 100%"
      placeholder="input here"
      option-label-prop="value"
    >
      <template slot="dataSource">
        <a-select-opt-group v-for="group in dataSource" :key="group.title">
          <span slot="label">
            {{ group.title }}
            <a
              style="float: right"
              href="https://www.google.com/search?q=foo"
              target="_blank"
              rel="noopener noreferrer"
            >more</a>
          </span>
          <a-select-option v-for="opt in group.children" :key="opt.title" :value="opt.title">
            {{ opt.title }}
            <span class="certain-search-item-count">{{ opt.count }} people</span>
          </a-select-option>
        </a-select-opt-group>
        <a-select-option key="all" disabled class="show-all">
          <a
            href="https://www.google.com/search?q=baz"
            target="_blank"
            rel="noopener noreferrer"
          >View all results</a>
        </a-select-option>
      </template>
      <a-input>
        <a-icon slot="suffix" type="search" class="certain-category-icon"/>
      </a-input>
    </a-auto-complete>
  </div>
</template>
<script>
const dataSource = [
  {
    title: "Libraries",
    children: [
      {
        title: "foo",
        count: 10000
      },
      {
        title: "bar",
        count: 10600
      }
    ]
  },
  {
    title: "Articles",
    children: [
      {
        title: "baz",
        count: 100000
      }
    ]
  }
];
export default {
  data() {
    return {
      dataSource
    };
  }
};
</script>

We loop through the items in the dataSource reactive property to display the items.

Also, we set the class attribute to set the classes for our auto-complete.

The input can be customized. We just add the input we want to use inside the a-auto-complete component inside:

<template>
  <a-auto-complete
    :data-source="dataSource"
    style="width: 200px"
    @search="handleSearch"
    @select="onSelect"
  >
    <a-textarea
      placeholder="input here"
      class="custom"
      style="height: 50px"
      @keypress="handleKeyPress"
    />
  </a-auto-complete>
</template>
<script>
export default {
  data() {
    return {
      dataSource: ["apple", "orange", "grape"]
    };
  },
  methods: {
    onSelect(value) {
      console.log("onSelect", value);
    },
    handleSearch(value) {
      this.dataSource = this.dataSource.filter(d => d.includes(value));
    },
    handleKeyPress(ev) {
      console.log("handleKeyPress", ev);
    }
  }
};
</script>

We put it in the a-textarea inside the a-auto-complete to use a text area instead of a text input.

Conclusion

We can add autocomplete inputs our Vue app with Ant Design Vue.

Categories
JavaScript

Update the DOM Easily with the Re:dom Library — Placeholders and Routes

We can update the DOM with the Re:dom library in a way easier than plain JavaScript.

In this article, we’ll look at how to use the library to diff the DOM and patch it.

Place

We can create or destroy a component or element and reserve its place with the place method.

For example, we can write:

import { place, mount, el } from "redom";

class Top {
  constructor() {
    this.el = el("p", "top");
  }
}

class Menu {
  constructor() {
    this.el = el("div", "menu");
  }
  update(visible, data) {
    if (visible) {
      this.el.textContent = data;
    }
  }
}

class Content {
  constructor() {
    this.el = el("div", "content");
  }
}

class App {
  constructor() {
    const app = el(
      ".app",
      (this.top = new Top()),
      (this.menu = place(Menu)),
      (this.content = new Content())
    );
    this.menu.update(true, "foo");
    this.menu.update(true, "bar");
    this.menu.update(false);
    return app;
  }
}

mount(document.body, new App());

We call the place function to reserve place for the menu.

Router

Re:dom comes with a router.

We can use it by using the router function:

import { el, router, mount } from "redom";

class Home {
  constructor() {
    this.el = el("h1");
  }
  update(data) {
    this.el.textContent = `Hello ${data}`;
  }
}

class About {
  constructor() {
    this.el = el("about");
  }
  update(data) {
    this.el.textContent = `About ${data}`;
  }
}

class Contact {
  constructor() {
    this.el = el("contact");
  }
  update(data) {
    this.el.textContent = `Contact ${data}`;
  }
}

const app = router(".app", {
  home: Home,
  about: About,
  contact: Contact
});

mount(document.body, app);

const data = "world";

app.update("home", data);
app.update("about", data);
app.update("contact", data);

We create the component classes and then pass them all to the object we pass into router .

The first argument is the selector for the app.

The app.update method lets us change the route.

Conclusion

We can add routes and call place to add placeholders for components.

Categories
JavaScript

Update the DOM Easily with the Re:dom Library — SVG and Components

tm_medium=referral) on Unsplash

We can update the DOM with the Re:dom library in a way easier than plain JavaScript.

In this article, we’ll look at how to use the library to diff the DOM and patch it.

SVG

We can use the svg method to add SVGs.

For example, we can write:

import { svg, mount } from "redom";

const drawing = svg(
  "svg",
  svg(
    "symbol",
    { id: "box", viewBox: "0 0 50 50" },
    svg("rect", { x: 100, y: 100, width: 50, height: 50 })
  ),
  svg("circle", { r: 50, cx: 100, cy: 100 }),
  svg("use", { xlink: { href: "#box" } })
);

mount(document.body, drawing);

We add the center of the circle with cx and cy .

x and y are the coordinates of the top left corner.

width and height are the width and height.

Children

We can add the children to the component by writing:

import { el, setChildren } from "redom";

const p = el("p", "foo");
const div = el("div", "bar");
const span = el("span", "baz");

setChildren(document.body, [p, div, span]);

We call setChildren with an array of elements with the items.

Update Elements

The setAttr method lets us set the attributes of an element:

import { el, setAttr, mount } from "redom";

const hello = el("h1", "Hello!");

setAttr(hello, {
  style: { color: "red" },
  className: "hello"
});

mount(document.body, hello);

We set the style attribute to an object to set the styles.

className is the class attribute.

Also, we can set the styles with the setStyle method:

import { el, setStyle, mount } from "redom";

const hello = el("h1", "Hello!");

setStyle(hello, { color: "green" });

mount(document.body, hello);

Mount

The mount metho can be used to insert elements anywhere.

For example, we can write:

import { el, mount } from "redom";

const hello = el("h1", "Hello!");

mount(document.body, hello);

to append as a child of the body.

Also, we can insert before an element by providing a 3rd argument:

import { el, mount } from "redom";

const hello = el("h1", "Hello!");

mount(document.body, hello, document.body.firstChild);

It’ll insert the h1 before the first child of the body.

We can replace an existing element by passing in the old and new element and true as the 4th argument:

import { el, mount } from "redom";

const hello = el("h1", "Hello!");
const newElement = el("h1", "new");
mount(document.body, hello);
mount(document.body, newElement, hello, true);

The new element goes is the 2nd argument.

And the existing is in the 3rd argument.

Unmount

We can call unmount to unmount an element:

import { el, mount, unmount } from "redom";

const hello = el("h1", "Hello!");
mount(document.body, hello);
unmount(document.body, hello);

Components

We can create a component with a JavaScript class.

For example, we can write:

import { el, mount } from "redom";

class Hello {
  constructor() {
    this.el = el("h1");
  }
  update(data) {
    this.el.textContent = `Hello ${data}`;
  }
}

const hello = new Hello();
hello.update("world");

mount(document.body, hello);

to create a component with a plain JavaScript class.

In the constructor, we create an element.

Then we set the textContent property of this.el with our own content in the update method.

We then mount the component with mount into the body.

Conclusion

We can add components, update elements, and SVGs with Re:dom.