Saturday, 11 March 2017

.aspcore sql visual studio 2017 publish

after publish on server, able to access my website via smartphone


create database first project, reference:

//controller

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using publish_test.Models;

namespace publish_test.Controllers
{
    public class dataController : Controller
    {
        testdataContext DB;

        public dataController(testdataContext context)
        {
            DB = context;
        }

        // GET: data
        public ActionResult Index()
        {
            var schools = DB.School.ToList();

            return View(schools);
        }

----------------------------------------------------

//view


@model IEnumerable<publish_test.Models.School>

    <h2>School table </h2>

    <table class="table table-striped">
        <thead>
            <tr>
                <th>
                    @Html.DisplayNameFor(model => model.Id)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Name)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Location)
                </th>
            </tr>
        </thead>

        <tbody>
            @foreach (var item in Model)
            {
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.Id)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Name)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Location)
                </td>
            </tr>
            }
        </tbody>
    </table>

------------------------------------------------------------

//testdataContext

using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;

namespace publish_test.Models
{
    public partial class testdataContext : DbContext
    {
        public virtual DbSet<School> School { get; set; }

        public testdataContext(DbContextOptions<testdataContext> options) : base(options){ }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<School>(entity =>
            {
                entity.ToTable("school");

                entity.Property(e => e.Id).HasColumnName("id");

                entity.Property(e => e.Location)
                    .HasColumnName("location")
                    .HasColumnType("nchar(10)");

                entity.Property(e => e.Name)
                    .HasColumnName("name")
                    .HasColumnType("nchar(10)");
            });
        }
    }
}

--------------------------------------------------------
//school.cs

using System;
using System.Collections.Generic;

namespace publish_test.Models
{
    public partial class School
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Location { get; set; }
    }
}

-------------------------------------------------------

publish to iis


next

save


myweb is published on iis, iis setup reference:

add iis to sql user, reference:




-------------------------------------------------------------------------------------------------------
//not related to publish
//visual studio 2017 dependency System.Net.Http has conflict with Microsoft.AspNet.WebApi.Client
//use method alternative to ReadAsAsync

public async Task<IActionResult> Load_employees_from_HR()
        {
            employees_from_HR = new List<employee_dto>();
            //make call to web api
            using (var client = new HttpClient())
            {
                client.BaseAddress = new Uri("http://localhost:11111/");
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.
                    Add(new MediaTypeWithQualityHeaderValue("application/json"));

                HttpResponseMessage response = await client.GetAsync("api/values");
                if (response.IsSuccessStatusCode)
                {
                    //employees_from_HR = await response.Content.ReadAsAsync<List<employee_dto>>();
                    var stringResult = await response.Content.ReadAsStringAsync();
                    employees_from_HR = JsonConvert.DeserializeObject<List<employee_dto>>(stringResult);
                }
            }

            //employees_from_HR.Add(new employee_dto { Id = "", name = "" });

            return Content("employees are loaded from HR");
        }


reference:
https://docs.microsoft.com/en-us/aspnet/core/publishing/iis
http://stackoverflow.com/questions/6167648/visual-studio-reformat-code-document
http://stackoverflow.com/questions/40699424/project-json-not-found-in-visual-studio-2017-rc-solution-explorer
https://wildermuth.com/2017/02/11/Updating-My-Blog-to-Visual-Studio-2017-and-csproj
http://stackoverflow.com/questions/30400358/cant-find-system-net-http-formatting-dll
https://jonhilton.net/2017/01/24/retrieve-data-from-a-third-party-openweather-api-using-asp-net-core-web-api/

Friday, 10 March 2017

.aspcore web api cors





//ValuesController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Cors;

namespace WebApplication2.Controllers
{
    [EnableCors("AllowAll")]
    [Route("api/[controller]")]
    public class ValuesController : Controller
    {
         List< people> people_list = new List<people> {
                new people {id =1,name="a",position="aa" },
                new people {id =2,name="b",position="bb" },
                new people {id =3,name="c",position="cc" },
                new people {id =4,name="d",position="dd" },
                new people {id =5,name="e",position="ee" },
                new people {id =6,name="f",position="ff" },
            };

        // GET api/values
        [HttpGet]
        public IEnumerable<people> Get()
        {
            return people_list;
        }

        // GET api/values/5
        [HttpGet("{id}")]
        public people Get(int id)
        {
            return people_list.FirstOrDefault(x=>x.id==id);
        }

    }
}

-------------------------------------------------------------------

//startup.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Cors.Infrastructure;

namespace WebApplication2
{
    public class Startup
    {
        public Startup(IHostingEnvironment env)
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
                .AddEnvironmentVariables();
            Configuration = builder.Build();
        }

        public IConfigurationRoot Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
            services.AddCors(options => options.AddPolicy("AllowAll", p => p.AllowAnyOrigin()));
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole(Configuration.GetSection("Logging"));
            loggerFactory.AddDebug();

            app.UseMvc();

            app.UseCors("AllowAll");
        }
    }
}

--------------------------------------------------------------------------

//project.json

{
  "dependencies": {
    "Microsoft.NETCore.App": {
      "version": "1.0.1",
      "type": "platform"
    },
    "Microsoft.AspNetCore.Mvc": "1.0.1",
    "Microsoft.AspNetCore.Routing": "1.0.1",
    "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0",
    "Microsoft.AspNetCore.Server.Kestrel": "1.0.1",
    "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0",
    "Microsoft.Extensions.Configuration.FileExtensions": "1.0.0",
    "Microsoft.Extensions.Configuration.Json": "1.0.0",
    "Microsoft.Extensions.Logging": "1.0.0",
    "Microsoft.Extensions.Logging.Console": "1.0.0",
    "Microsoft.Extensions.Logging.Debug": "1.0.0",
    "Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0",
    "Microsoft.AspNetCore.Cors": "1.1.1"
  },

  "tools": {
    "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final"
  },

  "frameworks": {
    "netcoreapp1.0": {
      "imports": [
        "dotnet5.6",
        "portable-net45+win8"
      ]
    }
  },

  "buildOptions": {
    "emitEntryPoint": true,
    "preserveCompilationContext": true
  },

  "runtimeOptions": {
    "configProperties": {
      "System.GC.Server": true
    }
  },

  "publishOptions": {
    "include": [
      "wwwroot",
      "**/*.cshtml",
      "appsettings.json",
      "web.config"
    ]
  },

  "scripts": {
    "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ]
  }
}

----------------------------------------------------------------------------


//index.cshtml


<script src="~/lib/jquery/dist/jquery.js"></script>
<script type="text/javascript">

    //var people_list = [];

    $(document).ready(function () {

        $.ajax({
            url: 'http://localhost:22222/api/values',
            type: 'GET',
            dataType: 'json',
            data: { },
            success: function (result) {

                //alert("success");
                $.each(result, function (index, value) {

                    $('#people_table').append('<tr>\
              <td>' + value.id + '</td>\
              <td>' + value.name + '</td>\
              <td>' + value.position + '</td></tr>');
                });
            },
            error: function () {
                alert("Error");
            }
        });
    });

</script>

<div>
    <table id="people_table" class="table table-striped">

        <thead>
            <tr>
                <th>ID</th>
                <th>Name</th>
                <th>Position</th>
            </tr>
        </thead>
        <tbody>

        </tbody>
    </table>

</div>

--------------------------------------------------------------------

change server to allow only origin from localhsot:12345, request is denied

//webapi startup.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Cors.Infrastructure;

namespace WebApplication2
{
    public class Startup
    {
        public Startup(IHostingEnvironment env)
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
                .AddEnvironmentVariables();
            Configuration = builder.Build();
        }

        public IConfigurationRoot Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
            //services.AddCors(options => options.AddPolicy("AllowAll", p => p.AllowAnyOrigin()));
            services.AddCors(options =>
            {
                options.AddPolicy("AllowSpecificOrigin",
                    builder => builder.WithOrigins("http://localhost:12345"));
            });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole(Configuration.GetSection("Logging"));
            loggerFactory.AddDebug();

            app.UseMvc();

            //app.UseCors("AllowAll");
            app.UseCors( "AllowSpecificOrigin");
        }
    }
}

------------------------------------------

//webapi controller


namespace WebApplication2.Controllers
{
    //[EnableCors("AllowAll")]
    [EnableCors("AllowSpecificOrigin")]
    [Route("api/[controller]")]
    public class ValuesController : Controller

--------------------------------------------------------------------

request from localhost:12345 is accepted

reference:
http://stackoverflow.com/questions/29100538/how-do-you-enable-cross-origin-requests-cors-in-asp-net-5-mvc-6
https://docs.microsoft.com/en-us/aspnet/core/security/cors

Tuesday, 7 March 2017

html dropdowns





<!DOCTYPE html>
<html>
<head>
    <style>
        .dropbtn {
            background-color: #4CAF50;
            color: white;
            padding: 16px;
            font-size: 16px;
            border: none;
            cursor: pointer;
        }

        .dropdown {
            position: relative;
            display: inline-block;
        }

        .dropdown-content {
            display: none;
            position: absolute;
            right: 0;
            background-color: #f9f9f9;
            min-width: 160px;
            box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
            z-index: 1;
        }

            .dropdown-content a {
                color: black;
                padding: 12px 16px;
                text-decoration: none;
                display: block;
            }

                .dropdown-content a:hover {
                    background-color: #f1f1f1;
                }

        .dropdown:hover .dropdown-content {
            display: block;
        }

        .dropdown:hover .dropbtn {
            background-color: #3e8e41;
        }
    </style>
</head>
<body>

    <h2>Aligned Dropdown Content</h2>
    <p>Determine whether the dropdown content should go from left to right or right to left with the left and right properties.</p>

    <div class="dropdown" style="float:left;">
        <button class="dropbtn">Left</button>
        <div class="dropdown-content" style="left:0;">
            <a href="#">Link 1</a>
            <a href="#">Link 2</a>
            <a href="#" onclick="button_confirm()">Link 3</a>
            <button onclick="button_confirm()" type="button" class="btn btn-success">Assign selected assets<br />to selected employee</button>
        </div>
    </div>

    <div class="dropdown" style="float:right;">
        <button class="dropbtn">Right</button>
        <div class="dropdown-content">
            <a href="#">Link 1</a>
            <a href="#">Link 2</a>
            <a href="#" onclick="button_cancel()">Link 3</a>
            <button onclick="button_cancel()" type="button" class="btn btn-danger">Cancel assignment</button>
        </div>
    </div>

</body>
</html>

<script type="text/javascript">

    function button_confirm() {

        alert("confirmed");
    }

    function button_cancel() {

        alert("canceled");
    }

</script>


reference:
https://www.w3schools.com/css/css_dropdowns.asp

阿省急需9000人去建房!春季马上要开工,急缺人!



阿省中部的Fort McMurray麦克默里堡,大家都知道去年那场臭名昭著的山林大火毁了N多房子。


马上这个春天,天气变暖春暖花开,麦堡大规模重建工作就要开始了!


然鹅! Wood Buffalo经济发展委员会却告知媒体说,麦堡重建蓄势待发,当前一共有2400栋房屋等待开工,但目前急缺人工!预估2017年大约需要招9000人才能填补人才空缺!


急缺9000人!妈呀,不知道我们卡城藏龙卧虎,有很多才华横溢的小伙伴么?


麦堡招聘会,40家公司摆摊要人!


在上周五麦堡为了招人还专门举办了一场招聘会。YMMHome Show and Job Fair,招聘会上有超过40家建筑公司在那里摆摊招人,有超过1000人涌进了会场。


麦堡商业委员会的执行总监Alexis Foster说,之前就有很多企业会员来抱怨招不到人。于是就联合经济发展委员会一起组织了这场招聘会,希望通过这场招聘会,能够将职工和急需人才的建筑商们联系起来。


现场一家做通风系统的公司Fort McMurray Filter Shop 接受采访时说,他们公司当前急需6名工人来填补空缺。之前在麦堡大火后公司流失了不少人才,现在马上春季开工来临,必须要填补这一空缺。


重建规模$36亿!


去年的那场大火夷平了整个麦堡,当前需要重建至少2400套房屋!资金规模超过36亿加币!而水牛城市政当前已经颁发了470个建筑许可,马上这个4月份既可以开工干起!


Wood Buffalo经济发展委员会说,这么大规模的建筑开工,将至少需要9000人来填补岗位空缺!


不仅是工人,还包括各种承包商,例如装修,通风过滤,电气,管道,园艺等方面,通通需要人!


听说,因为太缺人了,居然还有大老远闻风从安大略省赶来的Builder!


安大略省的都来了,我们阿省的小伙伴们肥水岂能流外人田呀,迅速走起!

Sunday, 5 March 2017

Asset tracking 6, dropdownlist option, button enable, disable javascript DOM. controller create postback overload

dropdownlist options are filtered by other dropdownlist selected option

filter by asset type, 3 items left enabled in model dropdownlist


add manufacture filter, only one item left

when model item is selected, manufacture and asset type are automatically selected

click blank option in any filter dropdownlist to refresh all filter dropdownlists

dropdownlist refreshed

submit button is disabled when model is not selected

serial # is required, submit will stop if left empty

submit button click, controller overloaded create action receives data 

redirected to display, serial ccc item is created


//asset controller.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using BLL;
using Data;
using Microsoft.AspNetCore.Mvc.Rendering;
using BLL.DTOs;
using System.Net.Http;
using System.Net.Http.Headers;

namespace AssetTracking.Controllers
{
    public class AssetController : Controller
    {
        asset_manager Manager;
        List<employee_dto> employees_from_HR;

        public AssetController(AssetContext context)
        {
            Manager = new asset_manager(context);          
        }    

        // GET: Asset
        public async Task<IActionResult> Index()
        {
            await Load_employees_from_HR();
            employees_from_HR.Add(new employee_dto { Id = "", name = "" });
            ViewBag.employee_viewbag = new SelectList(employees_from_HR.OrderBy(x => x.name), "Id", "name");

            var asset_types_list = Manager.get_asset_types();
            ViewBag.asset_types_viewbag = new SelectList(asset_types_list.OrderBy(x=>x.Name), "Id", "Name");

            var assets = Manager.get_all();

            return View(assets);
        }

        public async Task<IActionResult> Assign()
        {
           
            await Load_employees_from_HR();
            var employee_without_asset = Manager.find_employees_without_asset(employees_from_HR);

            var asset_types_list = Manager.get_asset_types();
            ViewBag.asset_types_viewbag = new SelectList(asset_types_list.OrderBy(x => x.Name), "Id", "Name");

            var unassigned_asset = Manager.get_unassigned_assets();
            ViewBag.unassigned_asset =unassigned_asset.OrderBy(x => x.name);
                     

            return View(employee_without_asset);
        }

        public async Task<IActionResult> Load_employees_from_HR()
        {
            employees_from_HR = new List<employee_dto>();
            //make call to web api
            using (var client = new HttpClient())
            {
                client.BaseAddress = new Uri("http://localhost:11111/");
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.
                    Add(new MediaTypeWithQualityHeaderValue("application/json"));

                HttpResponseMessage response = await client.GetAsync("api/values");
                if (response.IsSuccessStatusCode)
                {
                    employees_from_HR = await response.Content.ReadAsAsync<List<employee_dto>>();
                }
            }

            //employees_from_HR.Add(new employee_dto { Id = "", name = "" });

            return Content("employees are loaded from HR");
        }

        [HttpPost]
        public ActionResult update_assignment(List<asset_assign_class> assignment)
        {
            Manager.assign_asset(assignment);

            //redirect to Index is handled by Ajax on success event in Assign View
            return Content("assignment success");
        }


        [HttpPost]
        public ActionResult return_asset(string employee_id)
        {
            Manager.retun_asset(employee_id);

            //redirect to Index is handled by Ajax on success event in Assign View
            return Content("return success");
        }    

        // GET: Asset/Create
        public async Task<IActionResult> Create()
        {
            await Load_employees_from_HR();
            employees_from_HR.Add(new employee_dto { Id = "", name = "" });
            ViewBag.employee_viewbag = new SelectList(employees_from_HR.OrderBy(x => x.name), "Id", "name");

            var asset_types_list = Manager.get_asset_types();
            ViewBag.asset_types_viewbag = new SelectList(asset_types_list.OrderBy(x => x.Name), "Id", "Name");

            var manufacture_list = Manager.get_manufacture();
            ViewBag.manfuacture_viewbag = new SelectList(manufacture_list.OrderBy(x => x.name), "id", "name");

            var model_list = Manager.get_model();
            ViewBag.model_viewbag = new SelectList(model_list.OrderBy(x => x.name), "id", "name");

            var assets = Manager.get_all();

            return View(assets);
        }

        // POST: Asset/Create
        [HttpPost]
        //[ValidateAntiForgeryToken]
        public ActionResult Create(IFormCollection collection)
        {
            try
            {

                Manager.add_new(new asset_dto
                {
                    AssetTypeId = Convert.ToInt32(collection["asset_types_viewbag"]),
                    AssignedTo = collection["employee_viewbag"],
                    ManufacturerId = Convert.ToInt32(collection["manfuacture_viewbag"]),
                    ModelId=Convert.ToInt32(collection["model_viewbag"]),
                    SerialNumber = collection["serial"]
                });

                return RedirectToAction("Index");
            }
            catch
            {
                return View();
            }
        }

    }
}

-----------------------------------------------------

//view/asset/create.cshtml

@model IEnumerable<BLL.DTOs.asset_dto>

<h2><label id="title_label">Create new asset</label></h2>
<label id="status" class="text-danger"></label>

<script src="~/lib/jquery/dist/jquery.js"></script>
<script type="text/javascript">

    var asset_list = [];

    $(document).ready(function () {

        @foreach (var item in Model)
        {
            <text>
        asset_list.push(new asset_class('@item.Id', '@item.AssetTypeId',
            '@item.ManufacturerId', '@item.ModelId', '@item.AssignedTo', '@item.SerialNumber'));
        </text>
        }

        @*change dropdownlist color*@
        document.getElementById("asset_types_viewbag").style.color = "yellow";
        document.getElementById("asset_types_viewbag").style.backgroundColor = "green";

        document.getElementById("manfuacture_viewbag").style.color = "yellow";
        document.getElementById("manfuacture_viewbag").style.backgroundColor = "green";

        document.getElementById("model_viewbag").style.color = "yellow";
        document.getElementById("model_viewbag").style.backgroundColor = "green";

        document.getElementById("employee_viewbag").style.color = "yellow";
        document.getElementById("employee_viewbag").style.backgroundColor = "green";

        //disable submit button
        document.getElementById("ux_submit").disabled = true;
    });

    function asset_class(id, asset_type_id, manufacture_id, model_id, employee_id, serial_number) {
        this.id = id;
        this.asset_type_id = asset_type_id;
        this.manufacture_id = manufacture_id;
        this.model_id = model_id;
        this.employee_id = employee_id;
        this.serial_number = serial_number;
    }

    function asset_type_onchange(){    

        //set manufacture and model dropdownlist selected value to "", if empty option is selected from asset_type_dropdownlist
        if ($("#asset_types_viewbag").val() == 0) {
            document.getElementById("manfuacture_viewbag").options[0].selected = true;
            document.getElementById("model_viewbag").options[0].selected = true;

            //enable all asset_type_dropdownlist option, if empty option is selected from asset_type_dropdownlist
            $("#asset_types_viewbag option").each(function (index, element) {

                document.getElementById("asset_types_viewbag").options[index].disabled = false;
            });
        }

        //disable options in manufacture dropdownlist
        $("#manfuacture_viewbag option").each(function (index, element) {

            document.getElementById("manfuacture_viewbag").options[index].disabled = true;
        });

        //disable options in model dropdownlist
        $("#model_viewbag option").each(function (index, element) {

            document.getElementById("model_viewbag").options[index].disabled = true;
        });

        //enable empty option selection, option for no filter
        document.getElementById("manfuacture_viewbag").options[0].disabled = false;
        document.getElementById("model_viewbag").options[0].disabled = false;

        //enable options in manufacture and model dropdownlist based on asset type
        $.each(asset_list, function (index, value) {

            if ($('#asset_types_viewbag').val() == value.asset_type_id || $('#asset_types_viewbag').val() == 0) {                                

                //find option in manufacture dropdownlist with id = manufacture_id of the filtered asset item, enable it
                //$("#manfuacture_viewbag").find('option[value*=' + value.manufacture_id + ']').prop('disabled', false);
                $("#manfuacture_viewbag option").each(function (index2, element) {

                    if (element.value == value.manufacture_id) {

                        document.getElementById("manfuacture_viewbag").options[index2].disabled = false;
                    }
                });              
            }

            //filter model dropdown list with both asset type and manufacture
            if (($('#manfuacture_viewbag').val() == value.manufacture_id || $('#manfuacture_viewbag').val() == 0) &&
                ($('#asset_types_viewbag').val() == value.asset_type_id || $('#asset_types_viewbag').val() == 0)) {

                //find option in model dropdownlist with id = model_id of the filtered asset item, enable it
                $("#model_viewbag option").each(function (index2, element) {

                    if (element.value == value.model_id) {

                        document.getElementById("model_viewbag").options[index2].disabled = false;
                    }
                });
            }

        });
    }

    function manufacture_onchange() {

        //set asset type and model dropdownlist selected value to "", if empty option is selected from manufacture dropdownlist
        if ($("#manfuacture_viewbag").val() == 0) {
            document.getElementById("asset_types_viewbag").options[0].selected = true;
            document.getElementById("model_viewbag").options[0].selected = true;

            //enable all manufacture_dropdownlist option, if empty option is selected from manufacture_dropdownlist
            $("#manfuacture_viewbag option").each(function (index, element) {

                document.getElementById("manfuacture_viewbag").options[index].disabled = false;
            });
        }

        //disable options in asset type dropdownlist
        $("#asset_types_viewbag option").each(function (index, element) {

            document.getElementById("asset_types_viewbag").options[element.value].disabled = true;
        });

        //disable options in model dropdownlist
        $("#model_viewbag option").each(function (index, element) {

            document.getElementById("model_viewbag").options[element.value].disabled = true;
        });

        //enable empty option selection, option for no filter
        document.getElementById("asset_types_viewbag").options[0].disabled = false;
        document.getElementById("model_viewbag").options[0].disabled = false;

        //enable options in asset type and model dropdownlist based on manufacture
        $.each(asset_list, function (index, value) {

            if ($('#manfuacture_viewbag').val() == value.manufacture_id || $('#manfuacture_viewbag').val() == 0) {              

                //find option in asset type dropdownlist with id = asset_type_id of the filtered asset item, enable it
                $("#asset_types_viewbag option").each(function (index2, element) {

                    if (element.value == value.asset_type_id) {

                        document.getElementById("asset_types_viewbag").options[index2].disabled = false;
                    }
                });
            }

            //filter model dropdown list with both asset type and manufacture
            if (($('#manfuacture_viewbag').val() == value.manufacture_id || $('#manfuacture_viewbag').val() == 0)&&
                ($('#asset_types_viewbag').val() == value.asset_type_id || $('#asset_types_viewbag').val() == 0)) {

                //find option in model dropdownlist with id = model_id of the filtered asset item, enable it
                $("#model_viewbag option").each(function (index2, element) {

                    if (element.value == value.model_id) {

                        document.getElementById("model_viewbag").options[index2].disabled = false;
                    }
                });
            }
        });
   
    }

    function model_onchange() {

        //disable submit button
        document.getElementById("ux_submit").disabled = true;

        //set asset type and manufacture dropdownlist selected value to "", if empty option is selected from model dropdownlist
        if ($("#model_viewbag").val() == 0) {
            document.getElementById("asset_types_viewbag").options[0].selected = true;
            document.getElementById("manfuacture_viewbag").options[0].selected = true;

            //enable all dropdownlist option, if empty option is selected from manufacture_dropdownlist
            $("#manfuacture_viewbag option").each(function (index, element) {

                document.getElementById("manfuacture_viewbag").options[index].disabled = false;
            });

            $("#asset_types_viewbag option").each(function (index, element) {

                document.getElementById("asset_types_viewbag").options[index].disabled = false;
            });

            $("#model_viewbag option").each(function (index, element) {

                document.getElementById("model_viewbag").options[index].disabled = false;
            });

            return;
        }

        //disable options in asset type dropdownlist
        $("#asset_types_viewbag option").each(function (index, element) {

            document.getElementById("asset_types_viewbag").options[element.value].disabled = true;
        });

        //disable options in manufacture dropdownlist
        $("#manfuacture_viewbag option").each(function (index, element) {

            document.getElementById("manfuacture_viewbag").options[element.value].disabled = true;
        });

        //enable empty option selection, option for no filter
        document.getElementById("asset_types_viewbag").options[0].disabled = false;
        document.getElementById("manfuacture_viewbag").options[0].disabled = false;

        //select options in asset type and manufacture dropdownlist based on model
        $.each(asset_list, function (index, value) {

            if ($('#model_viewbag').val() == value.model_id) {

                //select asset type
                $("#asset_types_viewbag option").each(function (index2, element) {

                    if (element.value == value.asset_type_id) {

                        document.getElementById("asset_types_viewbag").options[index2].disabled = false;
                        document.getElementById("asset_types_viewbag").options[index2].selected = true;
                    }
                });

                //select manufacture type
                $("#manfuacture_viewbag option").each(function (index2, element) {

                    if (element.value == value.manufacture_id) {

                        document.getElementById("manfuacture_viewbag").options[index2].disabled = false;
                        document.getElementById("manfuacture_viewbag").options[index2].selected = true;
                    }
                });
            }
        });

        //if model dropdownlist selected option is not "", enable submit button
        if ($('#model_viewbag').val() != 0) {
            document.getElementById("ux_submit").disabled = false;
        }
    }  

   
</script>


<form id="create_form" method="post" onsubmit="return check_model_selct()">

    <div class="col-md-2">
        @Html.Label("Asset type")
        @Html.DropDownList("asset_types_viewbag", null, htmlAttributes: new { @class = "form-control", onchange = "asset_type_onchange()" })
    </div>

    <div class="col-md-2">
        @Html.Label("Manufacture")
        @Html.DropDownList("manfuacture_viewbag", null, htmlAttributes: new { @class = "form-control", onchange = "manufacture_onchange()" })
    </div>

    <div class="col-md-2">
        @Html.Label("Model")
        @Html.DropDownList("model_viewbag", null, htmlAttributes: new { @class = "form-control", onchange = "model_onchange()" })
    </div>

    <div class="col-md-2">
        @Html.Label("Employee")
        @Html.DropDownList("employee_viewbag", null, htmlAttributes: new { @class = "form-control" })
    </div>

    <div class="col-md-2">
        @Html.Label("Serial #")
        @Html.TextBox("serial",null, htmlAttributes: new { @class = "form-control", required = "required" })
    </div>

    <div class="col-md-2">
        @Html.Label("Select model and input serail # first")
        <input id="ux_submit" type="submit" value="submit" class="form-control" />
    </div>

</form>

-----------------------------------------------------

using Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using BLL.DTOs;
using System.Net.Http;
using System.Net.Http.Headers;

namespace BLL
{

    public class asset_manager
    {
        AssetContext DB;

        public asset_manager(AssetContext context)
        {
            DB = context;
        }

        public IList<asset_dto> get_all()
        {
            return DB.Assets.Select(x => new asset_dto
            {

                Id = x.Id,
                AssignedTo = x.AssignedTo,
                Description = x.Description,
                SerialNumber = x.SerialNumber,
                TagNumber = x.TagNumber,

                AssetTypeId = x.AssetTypeId.HasValue ? (int)x.AssetTypeId : 0,

                ////try to find manufacture_id from DB.Asset, if not found, try DB.Models, not found 0
                ManufacturerId = x.ManufacturerId.HasValue ? (int)x.ManufacturerId : (x.ModelId.HasValue?
                (int)DB.Models.FirstOrDefault(y=>y.Id==x.ModelId).ManufacturerId:0),

                ModelId = x.ModelId.HasValue ? (int)x.ModelId : 0,

                AssetType = x.AssetTypeId.HasValue ? DB.AssetType.FirstOrDefault(y => y.Id == x.AssetTypeId).Name : "",
                Model = x.ModelId.HasValue ? DB.Models.FirstOrDefault(y => y.Id == x.ModelId).Name : "",

                //try to find manufacture from DB.Asset, if not found, try DB.Models, not found ""
                Manufacturer = x.ManufacturerId.HasValue ? DB.Manufacturers.FirstOrDefault(y => y.Id == x.ManufacturerId).Name :
                (x.ModelId.HasValue ? DB.Manufacturers.FirstOrDefault(M => M.Id ==
                DB.Models.FirstOrDefault(z => z.Id == x.ModelId).ManufacturerId).Name : "")

            }).ToList();
        }    

        public IList<asset_short_dto> get_unassigned_assets()
        {
            return DB.Assets.Where(y=>y.AssignedTo==""||y.AssignedTo==null).
                Select(x => new asset_short_dto{
                    Id = x.Id,
                    name = x.ModelId.HasValue ? DB.Models.FirstOrDefault(z => z.Id == x.ModelId).Name : "",
                    type_id = x.AssetTypeId.HasValue ? (int)x.AssetTypeId : 0
                }).ToList();

        }

        public IList<asset_type_dto> get_asset_types()
        {
            var asset_types =  DB.AssetType.Select(x=> new asset_type_dto
            {
                Id=x.Id,
                Name=x.Name

            }).ToList();

            asset_types.Add(new asset_type_dto { Id = 0, Name = "" });

            return asset_types;
        }

        public void assign_asset(List<asset_assign_class> assignment)
        {
            foreach(var item in assignment)
            {
                DB.Assets.FirstOrDefault(x => x.Id == item.id).AssignedTo = item.employee_id;
                DB.SaveChanges();
            }
        }

        public IList<employee_dto> find_employees_without_asset(List<employee_dto> employees)
        {
            foreach(var item in DB.Assets)
            {
                if(item.AssignedTo!="")
                {
                    var employee_with_asset = employees.FirstOrDefault(x => x.Id == item.AssignedTo);

                    if (employee_with_asset != null)
                    {
                        employees.Remove(employee_with_asset);
                    }
                }
            }

            return employees;
        }

        public void retun_asset(string employee_id)
        {
            foreach(var item in DB.Assets)
            {
                if(item.AssignedTo==employee_id)
                {
                    item.AssignedTo = "";
                }
            }
            DB.SaveChanges();
        }

        public IList<manufacture_dto> get_manufacture()
        {
            var manufactures = DB.Manufacturers.Select(x => new manufacture_dto
            {
                id = x.Id,
                name = x.Name

            }).ToList();

            manufactures.Add(new manufacture_dto { id = 0, name = "" });

            return manufactures;
        }

        public IList<model_dto> get_model()
        {
            var models = DB.Models.Select(x => new model_dto
            {
                id = x.Id,
                manufacture_id = (int)x.ManufacturerId,
                name = x.Name
            }).ToList();

            models.Add(new model_dto { id = 0, manufacture_id = 0, name = "" });

            return models;
        }

        public void add_new(asset_dto new_item)
        {
            DB.Assets.Add(new Domain.Asset
            {
                AssetTypeId = new_item.AssetTypeId,
                ManufacturerId = new_item.ManufacturerId,
                ModelId = new_item.ModelId,
                AssignedTo = new_item.AssignedTo,
                SerialNumber=new_item.SerialNumber
            });

            DB.SaveChanges();
        }
    }
}

-----------------------------------------------

//BLL/DTOs/model.dto

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace BLL.DTOs
{
    public class model_dto
    {
        public int id { get; set; }
        public int manufacture_id { get; set; }
        public string name { get; set; }
    }
}

Tuesday, 28 February 2017

AssetTracking 5, client side: jquery 2 listbox exchange items, Ajax send obj to controller. server sdie: async controller action



click assign asset menu, list unassigned employee, assets

select multiple asset, click unassigned asset, goes to selected asset, vice-versa

assets can be filtered, if employee or asset is not selected, alert, otherwise assign

employee with id SM1003 is assigned multiple assets

//asset controller

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using BLL;
using Data;
using Microsoft.AspNetCore.Mvc.Rendering;
using BLL.DTOs;
using System.Net.Http;
using System.Net.Http.Headers;

namespace AssetTracking.Controllers
{
    public class AssetController : Controller
    {
        asset_manager Manager;
        List<employee_dto> employees_from_HR;

        public AssetController(AssetContext context)
        {
            Manager = new asset_manager(context);        
        }    

        // GET: Asset
        public ActionResult Index()
        {
            var asset_types_list = Manager.get_asset_types();

            ViewBag.asset_types_viewbag = new SelectList(asset_types_list.OrderBy(x=>x.Name), "Id", "Name");

            var assets = Manager.get_all();

            return View(assets);
        }

        public async Task<IActionResult> Assign()
        {
         
            await Load_employees_from_HR();
            var employee_without_asset = Manager.find_employees_without_asset(employees_from_HR);

            var asset_types_list = Manager.get_asset_types();
            ViewBag.asset_types_viewbag = new SelectList(asset_types_list.OrderBy(x => x.Name), "Id", "Name");

            var unassigned_asset = Manager.get_unassigned_assets();
            ViewBag.unassigned_asset =unassigned_asset.OrderBy(x => x.name);
                     

            return View(employee_without_asset);
        }

        public async Task<IActionResult> Load_employees_from_HR()
        {
            employees_from_HR = new List<employee_dto>();
            //make call to web api
            using (var client = new HttpClient())
            {
                client.BaseAddress = new Uri("http://localhost:11111/");
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.
                    Add(new MediaTypeWithQualityHeaderValue("application/json"));

                HttpResponseMessage response = await client.GetAsync("api/values");
                if (response.IsSuccessStatusCode)
                {
                    employees_from_HR = await response.Content.ReadAsAsync<List<employee_dto>>();
                }
            }

            return Content("employees are loaded from HR");
        }

        [HttpPost]
        public ActionResult update_assignment(List<asset_assign_class> assignment)
        {
            Manager.assign_asset(assignment);

            //redirect to Index is handled by Ajax on success event in Assign View 
            return Content("assignment success");
        }
}

---------------------------------------------------------------------------------------------------

//manager

using Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using BLL.DTOs;
using System.Net.Http;
using System.Net.Http.Headers;

namespace BLL
{

    public class asset_manager
    {
        AssetContext DB;

        public asset_manager(AssetContext context)
        {
            DB = context;
        }

        public IList<asset_dto> get_all()
        {
            return DB.Assets.Select(x => new asset_dto
            {

                Id = x.Id,
                AssignedTo = x.AssignedTo,
                Description = x.Description,
                SerialNumber = x.SerialNumber,
                TagNumber = x.TagNumber,

                AssetTypeId = x.AssetTypeId.HasValue ? (int)x.AssetTypeId : 0,
                ManufacturerId = x.ManufacturerId.HasValue ? (int)x.ManufacturerId : 0,
                ModelId = x.ModelId.HasValue ? (int)x.ModelId : 0,

                AssetType = x.AssetTypeId.HasValue ? DB.AssetType.FirstOrDefault(y => y.Id == x.AssetTypeId).Name : "",
                Model = x.ModelId.HasValue ? DB.Models.FirstOrDefault(y => y.Id == x.ModelId).Name : "",

                //try to find manufacture from DB.Asset, if not found, try DB.Models, not found ""
                Manufacturer = x.ManufacturerId.HasValue ? DB.Manufacturers.FirstOrDefault(y => y.Id == x.ManufacturerId).Name :
                (x.ModelId.HasValue ? DB.Manufacturers.FirstOrDefault(M => M.Id ==
                DB.Models.FirstOrDefault(z => z.Id == x.ModelId).ManufacturerId).Name : "")

            }).ToList();
        }    

        public IList<asset_short_dto> get_unassigned_assets()
        {
            return DB.Assets.Where(y=>y.AssignedTo==""||y.AssignedTo==null).
                Select(x => new asset_short_dto{
                    Id = x.Id,
                    name = x.ModelId.HasValue ? DB.Models.FirstOrDefault(z => z.Id == x.ModelId).Name : "",
                    type_id = x.AssetTypeId.HasValue ? (int)x.AssetTypeId : 0
                }).ToList();

        }

        public IList<asset_type_dto> get_asset_types()
        {
            var asset_types =  DB.AssetType.Select(x=> new asset_type_dto
            {
                Id=x.Id,
                Name=x.Name

            }).ToList();

            asset_types.Add(new asset_type_dto { Id = 0, Name = "" });

            return asset_types;
        }

        public void assign_asset(List<asset_assign_class> assignment)
        {
            foreach(var item in assignment)
            {
                DB.Assets.FirstOrDefault(x => x.Id == item.id).AssignedTo = item.employee_id;
                DB.SaveChanges();
            }
        }

        public IList<employee_dto> find_employees_without_asset(List<employee_dto> employees)
        {
            foreach(var item in DB.Assets)
            {
                if(item.AssignedTo!="")
                {
                    var employee_with_asset = employees.FirstOrDefault(x => x.Id == item.AssignedTo);

                    if (employee_with_asset != null)
                    {
                        employees.Remove(employee_with_asset);
                    }
                }
            }

            return employees;
        }
    }
}

--------------------------------------------------------------------------

//View

@model IEnumerable<BLL.DTOs.employee_dto>

<h2>Asset Assignment</h2>

<script src="~/lib/jquery/dist/jquery.js"></script>
<script type="text/javascript">

    var employee_list = [];
    var unassigned_asset_list = []
    var selected_asset_list = []
    var assignment_list = []

    $(document).ready(function () {

        //populate unassigned employee listbox
        @foreach (var item in Model)
        {
            <text>
        employee_list.push(new employee_class('@item.Id', '@item.name'));
        </text>
        }

        populate_employee();

        //populate unassigned assets listbox
        @foreach (var item in ViewBag.unassigned_asset)
        {
            <text>
        unassigned_asset_list.push(new asset_class('@item.Id', '@item.name', '@item.type_id'));
        </text>
        }

        populate_asset();
    });

    function employee_class(id, name) {
        this.id = id;
        this.name = name;
    }

    function asset_class(id, name, type) {
        this.id = id;
        this.name = name;
        this.type = type;
    }

    function assignment_class(id, employee_id) {

        this.id = id;
        this.employee_id = employee_id;
    }

    //delete element from array
    function array_delete(array, element_id) {

        //find index of the element going to be deleted in the arry
        indexes = $.map(array, function (obj, index) {

            if (element_id == obj.id) {

                return index;
            }
        })

        //return deleted element as asset class
        deleted_item = array.splice(indexes[0], 1);

        return new asset_class(deleted_item[0].id, deleted_item[0].name, deleted_item[0].type);
    }

    function populate_employee() {

        $.each(employee_list, function (index, value) {
            $('#ux_employee_unassigned').append('<option value=' + value.id + '>' + value.name + '</option>');
        });
    }

    //populate unassigned asset listbox
    function populate_asset() {

        $.each(unassigned_asset_list, function (index, value) {
            $('#ux_unassigned_asset').append('<option value=' + value.id + '>' + value.name + '</option>');
        });
    }

    //populate unassigned asset listbox based on type
    function populate_asset_baseon_type(_type) {

        $.each(unassigned_asset_list, function (index, value) {

            if (value.type == _type) {
                $('#ux_unassigned_asset').append('<option value=' + value.id + '>' + value.name + '</option>');
            }
        })
    }

    //populate selected asset listbox
    function populate_asset_selected() {      

        $.each(selected_asset_list, function (index, value) {
            $('#ux_selected_asset_listbox').append('<option value=' + value.id + '>' + value.name + '</option>');
        });
    }

    //populate selected asset listbox based on type
    function populate_asset_selected_basedon_type(_type) {

        $.each(selected_asset_list, function (index, value) {

            if (value.type == _type) {
                $('#ux_selected_asset_listbox').append('<option value=' + value.id + '>' + value.name + '</option>');
            }
        });
    }

    //asset type dropdownlist change event
    function asset_types_onchange() {

        $('#ux_unassigned_asset').empty();
        $('#ux_selected_asset_listbox').empty();

        //if selected type = "", populate with all assets
        if ($('#asset_types_viewbag :selected').text() == "") {
            populate_asset();
            populate_asset_selected();
        }
            //populate unassigned assets listbox based on asset type
        else {
            populate_asset_baseon_type($('#asset_types_viewbag').val());
            populate_asset_selected_basedon_type($('#asset_types_viewbag').val());
        }
    }

    //unassigned asset listbox onselect event, move asset to selected listbox
    function unassigned_asset_listbox_onchange() {

        //delete selected item from uassigned_asset_listbox
        deleted_element = array_delete(unassigned_asset_list, $("#ux_unassigned_asset").val());

        //add selected item to selected_asset_listbox
        selected_asset_list.push(deleted_element);

        //sort selectd asset list
        selected_asset_list.sort(function (a, b) {

            var aName = a.name.toLowerCase();
            var bName = b.name.toLowerCase();
            return ((aName < bName) ? -1 : ((aName > bName) ? 1 : 0));
        });

        //repopulate unassigned_asset_listbox
        asset_types_onchange();        
    }


    //selected asset listbox onselect event, return asset to unassigned listbox
    function selected_asset_listbox_onchange() {

        //delete selected item from selected asset listbox
        deleted_element = array_delete(selected_asset_list, $("#ux_selected_asset_listbox").val());

        //add selected item to unassigned asset listbox
        unassigned_asset_list.push(deleted_element);

        //sort unassigned asset list
        unassigned_asset_list.sort(function (a, b) {

            var aName = a.name.toLowerCase();
            var bName = b.name.toLowerCase();
            return ((aName < bName) ? -1 : ((aName > bName) ? 1 : 0));
        });

        //repopulate unassigned_asset_listbox and selected_asset_listbox
        asset_types_onchange();
    }

    //confirm button click event
    function button_confirm() {

        if ($('#ux_employee_unassigned').val() == undefined) { alert("please select employee"); return }

        if (selected_asset_list.length == 0) { alert("please select asset"); return}

        //create asset assignment to selected employee
        $.each(selected_asset_list, function (index, value) {

            assignment_list.push(new assignment_class(value.id, $('#ux_employee_unassigned').val()));
        })

        //send assignment to controller
        $.ajax({
            type: "POST",
            url: '/Asset/update_assignment',
            data: { "assignment": assignment_list },
            success: function (result) {
                //alert("success");
                window.location.replace("/Asset/Index");
            },
            error: function (xhr) {
                alert("Error button confirm Assign view");
            }
        });
    };
</script>

<div>
    <div class="col-md-3">

        <center>@Html.Label("select unassigned employee")</center>
        <select size="20" id="ux_employee_unassigned" class="form-control"></select>
    </div>

    <div class="col-md-6">

        <center> @Html.Label("select asset type")</center>
        <center> @Html.DropDownList("asset_types_viewbag", null, htmlAttributes: new { @class = "form-control", onchange = "asset_types_onchange()" })</center> 
        <br />

        <div class="row">
            <div class="col-md-6">

                <center>  @Html.Label("select unassigned asset")</center>
                <select size="15" id="ux_unassigned_asset" class="form-control" onchange="unassigned_asset_listbox_onchange()"></select>
            </div>

            <div class="col-md-6">

                <center> @Html.Label("return selected asset")</center>

                <select size="15" id="ux_selected_asset_listbox" class="form-control" onchange="selected_asset_listbox_onchange()"></select>
            </div>
        </div>
  
    </div>

    <div class="col-md-3">
        <br />
        <br />
        <br />
        <br />
        <br />
        <br />
        <center> <button onclick="button_confirm()" type="button" class="btn btn-success">Assign selected assets<br />to selected employee</button></center>
        <br />
        <br />
        <br />
        <br />
        <center> <button onclick="button_cancel()" type="button" class="btn btn-danger">Cancel assignment</button></center>
        <br />
        <br />
        <br />
        <br />
        <br />
        <br />
        <br />
       
    </div>
    
</div>

---------------------------------------------------------------------

//asset_assign_class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace BLL.DTOs
{
    public class asset_assign_class
    {
        public int id { get; set; }
        public string employee_id { get; set; }
    }
}


reference:
http://stackoverflow.com/questions/12944329/add-onclick-function-to-a-submit-button
http://stackoverflow.com/questions/8893111/how-do-i-disable-input-element-whose-type-is-submit
https://www.w3schools.com/tags/att_input_required.asp
http://stackoverflow.com/questions/1594952/jquery-disable-enable-submit-button
http://stackoverflow.com/questions/2950152/iterate-through-select-options
https://www.w3schools.com/jsref/prop_option_disabled.asp
http://stackoverflow.com/questions/40422727/disable-drop-down-options-based-on-selected-value-with-jquery
http://stackoverflow.com/questions/1263852/prevent-form-redirect-or-refresh-on-submit
http://stackoverflow.com/questions/12944329/add-onclick-function-to-a-submit-button
http://stackoverflow.com/questions/23071795/how-to-add-required-attribute-to-mvc-5-razor-view-text-input-editor