We will continue our tutorial of building a simple forum using Vuejs and Firebase. In this part we will implement how to add and edit forums and topics. Also display the user forums and ability to add replies.
Series Topics:
- Building a Simple Forum With Vue-js, Vuex and Firebase Part1: Authentication
- Building a Simple Forum With Vue-js, Vuex and Firebase Part2: Forum and Topic CRUD
- Building a Simple Forum With Vue-js, Vuex and Firebase Part3: Home Forums and Replies
Creating and Editing Forums
We will add functions to add, edit and delete a forum from firebase so open helper/api.js and modify it like this:
import firebase from "firebase"; // add your own config params, get them from // https://console.firebase.google.com/project/<project-name>/settings/general/ var config = { apiKey: "<your api key>", authDomain: "<your auth domain>", databaseURL: "<your database url>", storageBucket: "<your storage bucket>", }; firebase.initializeApp(config); var db = firebase.database(); export default { authenticate(email, password, successcallback, errorcallback) { firebase.auth().signInWithEmailAndPassword(email, password).then(successcallback).catch(errorcallback); }, logout(successcallback, errorcallback) { firebase.auth().signOut().then(successcallback).catch(errorcallback); }, getCurrentUser(callback) { firebase.auth().onAuthStateChanged(callback); }, register(email, password, successcallback, errorcallback) { firebase.auth().createUserWithEmailAndPassword(email, password).then(successcallback).catch(errorcallback); }, updateUserDisplayname(name) { var user = firebase.auth().currentUser; user.updateProfile({ displayName: name, }).then(function() { // Update successful. }).catch(function(error) { // An error happened. }); }, addUser(name, email, uid) { var usersRef = db.ref('users'); var usersPush = usersRef.push(); const key = usersPush.getKey(); usersPush.set({ name: name, email: email, uid: uid, created_at: (new Date()).toLocaleString() }); return key; }, getUserByUID(UID, callback) { var userRef = db.ref('users').orderByChild("uid").equalTo(UID); userRef.on('value', function(snapshot) { if(snapshot.val() != null) { callback(Object.keys(snapshot.val())[0], snapshot.val()); } else { callback(null, null); } }); }, addForum(title, content, user_id) { var forumRef = db.ref('forums'); var forumPush = forumRef.push(); forumPush.set({ title: title, content: content, user_id: user_id, created_at: (new Date()).toLocaleString() }); }, updateForum(title, content, key) { db.ref("forums/" + key).update({ title: title, content: content }); }, deleteForum(key) { db.ref("forums/" + key).remove(); }, userForums(user_id, callback) { var forumRef = db.ref('forums').orderByChild("user_id").equalTo(user_id); forumRef.on('value', function(snapshot) { callback(snapshot.val()); }); } }
In the above code we added four new functions using the firebase api which are:
- addForum
- updateForum
- deleteForum
- userForums: This will return the user forums when he is login.
Now let’s modify our store so open store.js and modify it like shown below:
import Vue from 'vue' import Vuex from 'vuex' import api from './helper/api' Vue.use(Vuex); export default new Vuex.Store( { state: { auth: { email: "", password: "", name: "" }, currentUser: { id: "", // this id is the datebase key for this record name: "", email: "", uid: "", // this is is the user authenticated object status: 0 // 0=logout 1=login }, forum: { // this object will be used when adding and editing forum title: "", content: "" }, userForums: [] // user forums in case he is login }, mutations: { setAuthEmail(state, data) { state.auth.email = data }, setAuthPassword(state, data) { state.auth.password = data }, setAuthName(state, data) { state.auth.name = data }, setCurrUserId(state, data) { state.currentUser.id = data }, setCurrUserName(state, data) { state.currentUser.name = data }, setCurrUserEmail(state, data) { state.currentUser.email = data }, setCurrUserUid(state, data) { state.currentUser.uid = data }, setCurrUserStatus(state, data) { state.currentUser.status = data }, setForumTitle(state, data) { state.forum.title = data }, setForumContent(state, data) { state.forum.content = data }, setUserForums(state, data) { state.userForums = data } }, actions: { getCurrentUser({commit}) { api.getCurrentUser(function(user) { if(user) { api.getUserByUID(user.uid, function(key, val) { if(key != null && val != null) { commit('setCurrUserId', key); commit('setCurrUserName', user.displayName); commit('setCurrUserEmail', user.email); commit('setCurrUserUid', user.uid); commit('setCurrUserStatus', 1); } }) } }); }, clearUserData({commit}) { commit('setCurrUserId', ''); commit('setCurrUserName', ''); commit('setCurrUserEmail', ''); commit('setCurrUserUid', ''); commit('setCurrUserStatus', 0); commit('setAuthEmail', ''); commit('setAuthPassword', ''); commit('setAuthName', ''); }, getUserForums({commit}, user) { api.userForums(user.id, function(response) { if(response) { commit('setUserForums', response); } else { commit('setUserForums', []); } }); } } } )
In the above code we added some state variables that will be used when adding and updating the forums such as the forum title and forum content and also we added some mutations and actions.
Add Forum Component
Open components/pages/AddForum.vue and insert the below code:
<template> <div> <section class="row panel-body"> <div class="col-md-12"> <form method="post" v-on:submit.prevent="addForum"> <div class="alert alert-danger" v-if="this.errors.length > 0"> <ul> <li v-for="(error, index) in this.errors" :key="index">{{ error }}</li> </ul> </div> <div class="alert alert-success" v-if="this.msg != ''"> {{ this.msg}} </div> <div class="form-group"> <label for="title">Title</label> <input type="text" class="form-control" id="title" placeholder="Title" v-model="title"> </div> <div class="form-group"> <label for="content">Content</label> <textarea name="content" class="form-control" placeholder="Content" v-model="content"></textarea> </div> <button type="submit" class="btn btn-success"><i v-show="isLoading" class="fa fa-refresh fa-lg fa-spin btn-load-indicator"></i> Save</button> </form> </div> </section> </div> </template> <script> import api from '../../helper/api' export default { data() { return { errors: [], msg: "", isLoading: false, } }, computed: { title: { get() { return this.$store.state.forum.title }, set(value) { this.$store.commit('setForumTitle', value) } }, content: { get() { return this.$store.state.forum.content }, set(value) { this.$store.commit('setForumContent', value) } } }, methods: { addForum() { this.errors = []; var self = this; if(this.$store.state.forum.title == "") { this.errors.push('Title required') } if(this.$store.state.forum.content == "") { this.errors.push('Content required') } if(this.errors.length > 0) { return false; } this.isLoading = true; // else save forum api.addForum(this.$store.state.forum.title, this.$store.state.forum.content, this.$store.state.currentUser.id) setTimeout( () => { self.isLoading = false; self.msg = "Forum saved successfully!" self.$store.commit('setForumTitle', "") self.$store.commit('setForumContent', "") self.$store.dispatch('getUserForums', self.$store.state.currentUser); self.$router.push('/my-forums/'); }, 2500 ) } }, created() { if(this.$store.state.currentUser.status != 1) { this.$router.push('/login/'); } } } </script>
Here we created a simple form and then bind it to computed properties that read and write to the store then we added a function that submit the form, and then save the forum to firebase after that we fetch the user forums and add it to the store to be display later in a dedicated page.
Modify components/pages/Login.vue inside the login method locate this line:
self.$store.commit('setCurrUserStatus', 1);
and add this code below it:
// load user forums after successful login api.userForums(user.user.uid, function(response) { self.$store.commit('setUserForums', response); });
and this code fetches the user forums after successful login.
Modify app.js and add this code inside the mounted() lifecycle hook:
// check for current user if he is still login store.dispatch('getCurrentUser') // if user is already login then load user forums setTimeout( () => { if(store.state.currentUser.status == 1) { store.dispatch('getUserForums', store.state.currentUser); } }, 2000 )
Now in the terminal run
npm run dev
Then navigate to http://localhost/project_path/ and login then click on add forum button on the header, on successful add you will be redirected to my forums page, which we will update it in the next section.
Display User Forums
Let’s display the user forums, we loop the forums from the store variable that we added in previous section.
So open component/pages/MyForums.vue and update it as shown:
<template> <div> <section class="row panel-body"> <section class="col-md-12"> <h3> <i class="glyphicon glyphicon-th-list"> </i> My Forums</h3> <hr> </section> </section> <hr/> <div class="alert alert-success" v-if="this.msg != ''"> {{ this.msg}} </div> <div class="container-fluid"> <table class="table table-responsive" v-if="this.$store.state.userForums"> <thead> <tr> <th>Title</th> <th>Content</th> <th>Forum Topic</th> <th>Add Topic</th> <th>Edit</th> <th>Delete</th> </tr> </thead> <tbody> <tr v-for="(value, key, index) in this.$store.state.userForums" :key="index"> <td>{{ value.title }}</td> <td>{{ value.content }}</td> <td><router-link :to="'/forum-topics/' + key" class="btn btn-info">View</router-link></td> <td><router-link :to="'/add-topic/' + key" class="btn btn-info">Add Topic</router-link></td> <td><router-link :to="'/edit-forum/' + key" class="btn btn-success">Edit</router-link></td> <td><a href="javascript:void(0);" class="btn btn-danger" @click="remove(key)">Delete</a></td> </tr> </tbody> </table> <div class="text-center" v-if="!this.$store.state.userForums"> You have no forums yet! <router-link to="/add-forum/">Add forum</router-link> </div> </div> </div> </template> <script> import api from '../../helper/api' export default { data() { return { msg: "" } }, methods: { remove(key) { if(confirm('Are you sure?')) { // delete api.deleteForum(key); // reload user forums setTimeout( () => { this.msg = "Forum deleted successfully!"; this.$store.dispatch('getUserForums', this.$store.state.currentUser) }, 1500 ) } } }, mounted() { document.getElementById("loading").style.display = "none" } } </script>
In the above code we looped over the forums and then displayed them in a grid view and added some buttons like viewing forum topics, add topic, edit forum, and delete forum.
Now reload the page and click on My Forums button in the header, wait for some seconds until the forums appear and try to click on delete, the other buttons will be implemented in the next sections.
Updating User Forums
Open helper/api.js and add this function after userForums function:
userForums(user_id, callback) { ...... }, getForumByKey(key, callback) { var itemRef = db.ref('forums').child(key); var topicsRef = db.ref('topics').orderByChild("forum_id").equalTo(key); itemRef.once('value', function(snapshot) { callback(snapshot.val(), 'forum') }); topicsRef.on('value', function(snapshot) { callback(snapshot.val(), 'topics') }); }
This function will be used to retrieve specific forum by it’s unique key which will be used in the edit form below.
Edit Forum Component
Open components/pages/EditForum.vue and add the below code:
<template> <div> <section class="row panel-body"> <div class="col-md-12"> <form method="post" v-on:submit.prevent="editForum"> <div class="alert alert-danger" v-if="this.errors.length > 0"> <ul> <li v-for="(error, index) in this.errors" :key="index">{{ error }}</li> </ul> </div> <div class="alert alert-success" v-if="this.msg != ''"> {{ this.msg}} </div> <div class="form-group"> <label for="title">Title</label> <input type="text" class="form-control" id="title" placeholder="Title" v-model="title"> </div> <div class="form-group"> <label for="content">Content</label> <textarea name="content" class="form-control" placeholder="Content" v-model="content"></textarea> </div> <button type="submit" class="btn btn-success"><i v-show="isLoading" class="fa fa-refresh fa-lg fa-spin btn-load-indicator"></i> Update</button> </form> </div> </section> </div> </template> <script> import api from '../../helper/api' export default { data() { return { errors: [], msg: "", isLoading: false, } }, computed: { title: { get() { return this.$store.state.forum.title }, set(value) { this.$store.commit('setForumTitle', value) } }, content: { get() { return this.$store.state.forum.content }, set(value) { this.$store.commit('setForumContent', value) } } }, created() { var self = this api.getForumByKey(this.$route.params.id, function(response, item) { if(item == 'forum') { self.$store.commit('setForumTitle', response.title) self.$store.commit('setForumContent', response.content) } }); }, methods: { editForum() { this.errors = []; var self = this; if(this.$store.state.forum.title == "") { this.errors.push('Title required') } if(this.$store.state.forum.content == "") { this.errors.push('Content required') } if(this.errors.length > 0) { return false; } this.isLoading = true; // else save forum api.updateForum(this.$store.state.forum.title, this.$store.state.forum.content, this.$route.params.id) setTimeout( () => { self.isLoading = false; self.msg = "Forum updated successfully!" self.$store.dispatch('getUserForums', self.$store.state.currentUser); self.$router.push('/my-forums/'); }, 2500 ) } } } </script>
Now if you click on the edit button you will see the edit form populated with the forum data, click Update then the forum will be updated and you will be redirected to User Forums page.
Handling Forum Topics
Open helper/api.js and modify it as shown:
import firebase from "firebase"; // add your own config params, get them from // https://console.firebase.google.com/project/<project-name>/settings/general/ var config = { apiKey: "<your api key>", authDomain: "<your auth domain>", databaseURL: "<your database url>", storageBucket: "<your storage bucket>", }; firebase.initializeApp(config); var db = firebase.database(); export default { authenticate(email, password, successcallback, errorcallback) { firebase.auth().signInWithEmailAndPassword(email, password).then(successcallback).catch(errorcallback); }, logout(successcallback, errorcallback) { firebase.auth().signOut().then(successcallback).catch(errorcallback); }, getCurrentUser(callback) { firebase.auth().onAuthStateChanged(callback); }, register(email, password, successcallback, errorcallback) { firebase.auth().createUserWithEmailAndPassword(email, password).then(successcallback).catch(errorcallback); }, updateUserDisplayname(name) { var user = firebase.auth().currentUser; user.updateProfile({ displayName: name, }).then(function() { // Update successful. }).catch(function(error) { // An error happened. }); }, addUser(name, email, uid) { var usersRef = db.ref('users'); var usersPush = usersRef.push(); const key = usersPush.getKey(); usersPush.set({ name: name, email: email, uid: uid, created_at: (new Date()).toLocaleString() }); return key; }, getUserByUID(UID, callback) { var userRef = db.ref('users').orderByChild("uid").equalTo(UID); userRef.on('value', function(snapshot) { if(snapshot.val() != null) { callback(Object.keys(snapshot.val())[0], snapshot.val()); } else { callback(null, null); } }); }, addForum(title, content, user_id) { var forumRef = db.ref('forums'); var forumPush = forumRef.push(); forumPush.set({ title: title, content: content, user_id: user_id, created_at: (new Date()).toLocaleString() }); }, updateForum(title, content, key) { db.ref("forums/" + key).update({ title: title, content: content }); }, deleteForum(key) { db.ref("forums/" + key).remove(); }, userForums(user_id, callback) { var forumRef = db.ref('forums').orderByChild("user_id").equalTo(user_id); forumRef.on('value', function(snapshot) { callback(snapshot.val()); }); }, getForumByKey(key, callback) { var itemRef = db.ref('forums').child(key); var topicsRef = db.ref('topics').orderByChild("forum_id").equalTo(key); itemRef.once('value', function(snapshot) { callback(snapshot.val(), 'forum') }); topicsRef.on('value', function(snapshot) { callback(snapshot.val(), 'topics') }); }, getMyTopics(forum_key, user_key, callback) { var topicsRef = db.ref('topics').orderByChild("userId_forumId").equalTo(user_key + "_" + forum_key); topicsRef.on('value', function(snapshot) { callback(snapshot.val()); }); }, addTopic(title, content, forum_id, user_id) { var forumRef = db.ref('topics'); var forumPush = forumRef.push(); forumPush.set({ title: title, content: content, user_id: user_id, created_at: (new Date()).toLocaleString(), forum_id: forum_id, view_count: 0, userId_forumId: user_id + "_" + forum_id }); }, updateTopic(title, content, key) { db.ref("topics/" + key).update({ title: title, content: content }); }, deleteTopic(key) { db.ref("topics/" + key).remove(); }, updateTopicViewCount(key) { var topicRef = db.ref('topics').child(key).child('view_count'); topicRef.transaction(function(views) { // if (views) { views = views + 1; // } return views; }); }, getTopicByKey(key, callback) { var topicRef = db.ref('topics').child(key); topicRef.on('value', function(snapshot) { var topicVal = snapshot.val() var userRef = db.ref('users').child(topicVal.user_id) userRef.on('value', function(snapshotUser) { var forumRef = db.ref('forums').child(topicVal.forum_id) forumRef.on('value', function(snapshotForum) { callback(topicVal, snapshotUser.val(), snapshotForum.val()) }); }); }); } }
Also Open store.js and modify it as shown:
import Vue from 'vue' import Vuex from 'vuex' import api from './helper/api' Vue.use(Vuex); export default new Vuex.Store( { state: { auth: { email: "", password: "", name: "" }, currentUser: { id: "", // this id is the datebase key for this record name: "", email: "", uid: "", // this is is the user authenticated object status: 0 // 0=logout 1=login }, forum: { // this object will be used when adding and editing forum title: "", content: "" }, userForums: [], // user forums in case he is login userTopics: [], topic: { title: "", content: "" } }, mutations: { setAuthEmail(state, data) { state.auth.email = data }, setAuthPassword(state, data) { state.auth.password = data }, setAuthName(state, data) { state.auth.name = data }, setCurrUserId(state, data) { state.currentUser.id = data }, setCurrUserName(state, data) { state.currentUser.name = data }, setCurrUserEmail(state, data) { state.currentUser.email = data }, setCurrUserUid(state, data) { state.currentUser.uid = data }, setCurrUserStatus(state, data) { state.currentUser.status = data }, setForumTitle(state, data) { state.forum.title = data }, setForumContent(state, data) { state.forum.content = data }, setUserForums(state, data) { state.userForums = data }, setUserTopics(state, data) { state.userTopics = data }, setTopicTitle(state, data) { state.topic.title = data }, setTopicContent(state, data) { state.topic.content = data } }, actions: { getCurrentUser({commit}) { api.getCurrentUser(function(user) { if(user) { api.getUserByUID(user.uid, function(key, val) { if(key != null && val != null) { commit('setCurrUserId', key); commit('setCurrUserName', user.displayName); commit('setCurrUserEmail', user.email); commit('setCurrUserUid', user.uid); commit('setCurrUserStatus', 1); } }) } }); }, clearUserData({commit}) { commit('setCurrUserId', ''); commit('setCurrUserName', ''); commit('setCurrUserEmail', ''); commit('setCurrUserUid', ''); commit('setCurrUserStatus', 0); commit('setAuthEmail', ''); commit('setAuthPassword', ''); commit('setAuthName', ''); }, getUserForums({commit}, user) { api.userForums(user.id, function(response) { if(response) { commit('setUserForums', response); } else { commit('setUserForums', []); } }); } } } )
Add Topic Component
Open components/pages/AddTopic.vue and insert the below code:
<template> <div> <section class="row panel-body"> <div class="col-md-12"> <form method="post" v-on:submit.prevent="addTopic"> <div class="alert alert-danger" v-if="this.errors.length > 0"> <ul> <li v-for="(error, index) in this.errors" :key="index">{{ error }}</li> </ul> </div> <div class="alert alert-success" v-if="this.msg != ''"> {{ this.msg}} </div> <div class="form-group"> <label for="title">Title</label> <input type="text" class="form-control" id="title" placeholder="Title" v-model="title"> </div> <div class="form-group"> <label for="content">Content</label> <textarea name="content" class="form-control" placeholder="Content" v-model="content"></textarea> </div> <button type="submit" class="btn btn-success"><i v-show="isLoading" class="fa fa-refresh fa-lg fa-spin btn-load-indicator"></i> Save</button> </form> </div> </section> </div> </template> <script> import api from '../../helper/api' export default { data() { return { errors: [], msg: "", isLoading: false } }, computed: { title: { get() { return this.$store.state.topic.title }, set(value) { this.$store.commit('setTopicTitle', value) } }, content: { get() { return this.$store.state.topic.content }, set(value) { this.$store.commit('setTopicContent', value) } } }, methods: { addTopic() { this.errors = []; var self = this; if(this.$store.state.topic.title == "") { this.errors.push('Title required') } if(this.$store.state.topic.content == "") { this.errors.push('Content required') } if(this.errors.length > 0) { return false; } this.isLoading = true; // else save topic api.addTopic(this.$store.state.topic.title, this.$store.state.topic.content, this.$route.params.id, this.$store.state.currentUser.id) setTimeout( () => { self.isLoading = false; self.msg = "Topic saved successfully!" self.$store.commit('setTopicTitle', "") self.$store.commit('setTopicContent', "") self.$router.push('/forum-topics/' + self.$route.params.id); }, 2500 ) } }, created() { document.getElementById("loading").style.display = "none" } } </script>
This form the same as the Add Forum form, but in this case we add a topic inside specific forum.
Display Topics Component
Open components/pages/ForumTopics.vue and insert the below code:
<template> <div> <section class="row panel-body"> <section class="col-md-12"> <h3> <i class="glyphicon glyphicon-th-list"> </i> Forum Topics</h3> <hr> </section> </section> <hr/> <div class="alert alert-success" v-if="this.msg != ''"> {{ this.msg}} </div> <div class="container-fluid"> <table class="table table-responsive"> <thead> <tr> <th>Title</th> <th>Content</th> <th>Edit</th> <th>Delete</th> </tr> </thead> <tbody> <tr v-for="(value, key, index) in this.topics" :key="index"> <td>{{ value.title }}</td> <td>{{ value.content }}</td> <td><router-link :to="'/edit-topic/' + forum_id + '/' + key" class="btn btn-success">Edit</router-link></td> <td><a href="javascript:void(0);" class="btn btn-danger" @click="remove(key)">Delete</a></td> </tr> </tbody> </table> <div class="text-center" v-if="!this.topics"> No topics in this forum! <router-link :to="'/add-topic/' + this.$route.params.id">Add new topic</router-link> </div> </div> </div> </template> <script> import api from '../../helper/api' export default { data() { return { msg: "" } }, computed: { topics: { get() { return this.$store.state.userTopics } }, forum_id: { get() { return this.$route.params.id } } }, methods: { remove(key) { if(confirm('Are you sure?')) { // delete api.deleteTopic(key); // reload user forums setTimeout( () => { this.msg = "Topic deleted successfully!"; api.getMyTopics(this.$route.params.id, this.$store.state.currentUser.id, function(response) { self.$store.commit('setUserTopics', response); }); }, 1500 ) } } }, mounted() { var self = this setTimeout( () => { api.getMyTopics(self.$route.params.id, self.$store.state.currentUser.id, function(response) { self.$store.commit('setUserTopics', response); }); }, 2000 ); }, created() { document.getElementById("loading").style.display = "none" } } </script>
Update Topic Component
Open components/pages/EditTopic.vue and modify it as shown:
<template> <div> <section class="row panel-body"> <div class="col-md-12"> <form method="post" v-on:submit.prevent="editTopic"> <div class="alert alert-danger" v-if="this.errors.length > 0"> <ul> <li v-for="(error, index) in this.errors" :key="index">{{ error }}</li> </ul> </div> <div class="alert alert-success" v-if="this.msg != ''"> {{ this.msg}} </div> <div class="form-group"> <label for="title">Title</label> <input type="text" class="form-control" id="title" placeholder="Title" v-model="title"> </div> <div class="form-group"> <label for="content">Content</label> <textarea name="content" class="form-control" placeholder="Content" v-model="content"></textarea> </div> <button type="submit" class="btn btn-success"><i v-show="isLoading" class="fa fa-refresh fa-lg fa-spin btn-load-indicator"></i> Save</button> </form> </div> </section> </div> </template> <script> import api from '../../helper/api' export default { data() { return { errors: [], msg: "", isLoading: false } }, computed: { title: { get() { return this.$store.state.topic.title }, set(value) { this.$store.commit('setTopicTitle', value) } }, content: { get() { return this.$store.state.topic.content }, set(value) { this.$store.commit('setTopicContent', value) } } }, created() { var self = this api.getTopicByKey(this.$route.params.topic_id, function(topic, user, forum) { self.$store.commit('setTopicTitle', topic.title) self.$store.commit('setTopicContent', topic.content) }); }, methods: { editTopic() { this.errors = []; var self = this; if(this.$store.state.topic.title == "") { this.errors.push('Title required') } if(this.$store.state.topic.content == "") { this.errors.push('Content required') } if(this.errors.length > 0) { return false; } this.isLoading = true; // else save topic api.updateTopic(self.$store.state.topic.title, self.$store.state.topic.content, self.$route.params.topic_id) self.msg = "Topic updated successfully!" setTimeout( () => { self.isLoading = false; self.$store.commit('setTopicTitle', "") self.$store.commit('setTopicContent', "") self.$router.push('/forum-topics/' + self.$route.params.forum_id); }, 2500 ) } }, created() { document.getElementById("loading").style.display = "none" } } </script>
At this point we finished adding, editing, displaying and deleting topics. Try to experiment with them and we will implement the home forums and forum display in the next part.
This is my first time visit at here and i am really pleassant to
read everthing at alone place.
Thanks