1. السلام عليكم ورحمة الله وبركاته..
     
    في هذا الدرس الثالث من دروس النود جي اس سنقوم بتعلم كيفية ضبط ويب سيرفر NGINX للعمل مع تطبيقات / مايكرو سيرفس الNodeJS و تحويل requests الى بورتات تطبيقاتك بشكل ضمني
     
    ماهو الnginx؟
    ببساطة هو بروكسي سيرفر عالي الاداء او ويب سيرفر،  بديل الapache.
     
    في ماذا يستخدم؟
    يستخدم في ريفيرس بروكسي للبروتوكولات HTTP, HTTPS, SMTP, IMAP, POP3 و كذلك لعمل توازن الضغط على السيرفر مثلا عندما يكون هناك عدد كبير جدا من الrequests تستطيع توزيع هذه الطلبات بالupstream بين عدة بورتات في نفس السيرفر او سيرفر خارجي مثلا اذا كان التطبيق او الموقع مبرمج بالNodeJS.

     
    بالعربي: لا تحاتي بتعرف كلشي بعد شوي.
    اولا: تثبيت الويب سيرفر.
    لتثبيت الويب سيرفر nginx اتبع التعليمات / الخطوات التالية:
    افتح التيرمنال وقم بإيقاف الapache اذا كان مثبت sudo /etc/init.d/apache stop حدث sudo apt-get update ثبت sudo apt-get install nginx تأكد ان الويب سيرفر يعمل sudo /etc/init.d/nginx status  
    ملاحظة: مهم جدا ايقاف Apache قبل تثبيت Nginx
     
    ثانيا: تشغيل تطبيقك الNode على الدومين الرئيسي.
    لتشغيل التطبيق عليك تحويل جميع الطلبات requests التي تأتي من العميل الى الPort الذي يعمل عليه التطبيق (3000 مثلا) عبر الويب سيرفر NGINX.

     
    ولعمل ذلك، افتح التيرمنال و قم بمتابعة هذه الاوامر
    اذهب لمجلد الويب سيرفر cd /etc/ngin/sites-available اكتب ls وسترى ملف بإسم default. افتح الملف للتعديل بإستخدام vim او nano وفي هذا الدرس سنستخدم الاول sudo vim default امسح كلشي واكتب هذا الكود server { listen 80 default_server; listen [::]:80 default_server; server_name www.example.com example.com; access_log /path/to/log/static_domain_access.log; location / { proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_set_header X-NginX-Proxy true; proxy_pass http://127.0.0.1:3000; proxy_redirect off; } }  
    اخيرا قم بإعادة تشغيل الويب سيرفر
     
    افتح المتصفح و اكتب موقعك http://www example.com
     
    Bonus
    إذا كان لديك تطبيق \ موقع كبير جدا او API و تريد عمل load balancing لتوزيع عمليه الطلبات في الصورتين ادناه الطريقة لذلك, لاحظ ان التطبيق يعمل على اكثر من بورت وكذلك الـproxy pass هو عباره عن اسم الـupstream .cluster
     
    تطبيق الNode

     
    كونفيقريشن الـNginx

    مستوى المقال: مبتدئ
  2. السلام عليكم و رحمة الله و بركاته ..
    عودة الى الجزء الاول، وضحت كيفية ارسال بيانات من تطبيق الNode الى Pug وكيفية استقبال البيانات في الطرف الاخر و عرضها.
     
    في هذا الدرس سنتعامل مع قاعدة البيانات ونرسل البيانات بطريقتين مختلفتين:
    سيتم ارسال جميع البيانات من احد الجداول الى الواجهة و سأعرض لكم طريقة التعامل مع هذا النوع من البيانات المرسله سننشأه items عباره عن json objects  وبعدها نرسلهم.  
    الطريقة الأولى:
    و بالحديث عن قواعد البيانات، سنستخدم قاعدة بيانات MySQL هذه المره ( الرجاء الرجوع للدرس الاول للحصول على كافة التجهيزات لهذا الدرس). / هنا , انشأ قاعدة بيانات بإسم company وجدول employees مثلا  ومن ثم اضف هذه المدخلات.
    -- phpMyAdmin SQL Dump -- version 4.5.4.1deb2ubuntu2 -- http://www.phpmyadmin.net -- -- Host: localhost -- Generation Time: Jun 09, 2017 at 10:41 AM -- Server version: 5.7.18-0ubuntu0.16.04.1 -- PHP Version: 7.1.5-1+deb.sury.org~xenial+2 SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; SET time_zone = "+00:00"; /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!40101 SET NAMES utf8mb4 */; -- -- Database: `company` -- -- -------------------------------------------------------- -- -- Table structure for table `employees` -- CREATE TABLE `employees` ( `ID` int(11) NOT NULL, `name` text COLLATE utf8_unicode_ci NOT NULL, `position` text COLLATE utf8_unicode_ci NOT NULL, `office` text COLLATE utf8_unicode_ci NOT NULL, `age` int(11) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; -- -- Dumping data for table `employees` -- INSERT INTO `employees` (`ID`, `name`, `position`, `office`, `age`) VALUES (1, 'Airi Satou', 'Accountant', 'Tokyo', 23), (2, 'Airi Satou', 'Accountant', 'Tokyo', 23), (3, 'Donna Snider', 'Customer Support', 'New York', 27), (4, 'Brenden Wagner', 'Software Engineer', 'San Francisco', 28), (5, 'Caesar Vance', 'Pre-Sales Support', 'New York', 23), (6, 'Cedric Kelly', 'Senior Javascript Developer', 'Edinburgh', 22), (7, 'Dai Rios', 'Personnel Lead', 'Edinburgh', 35); -- -- Indexes for dumped tables -- -- -- Indexes for table `employees` -- ALTER TABLE `employees` ADD PRIMARY KEY (`ID`); -- -- AUTO_INCREMENT for dumped tables -- -- -- AUTO_INCREMENT for table `employees` -- ALTER TABLE `employees` MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=8; /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;  
    افتح ملف app.js و انشأ هذا الاوبجكت لعمل connection بين التطبيق وقاعدة البيانات
    // connection var connection = mysql.createConnection({ host : 'localhost', user : '...', password : '...', database : 'db_name' });  
    بعد ذلك،  سنقوم بتعديل صفحة الـdetails في ملف app.js  - المسار الذي يعرض صفحة الـdetails  -  لعمل Selection query
    app.get('/details', function(req, res) { connection.query('SELECT * From `employees`', function (error, results, fields) { if (error) throw error; console.log('The solution is: ', results); res.render('details', { title: 'Details - Pug ExpressJS NodeJS Tutorial', employees: results }); }); }); الـsyntax بسيط جدا، اولا connection وهو متغير التوصيل مم ثم query ثابته بعد ذلك الكويري  ومن ثم الارقيومنتس (لمعلومات اكثر تجدونها هنا https://github.com/mysqljs/mysql/blob/master/Readme.md )
     
    مخرجات اي query دائما ما يكون json object بالتالي متغير results هو عباره عن list of objects
    [ { "prop1":"value1", "prop2":"value2" }, { "prop1":"value3", "prop2":"value4" } ]  
    نرجع إلى ملف details.pug ونقوم بتعديل block الجدول إلى التالي
    table#example.display.nowrap.dataTable.dtr-inline.collapsed(cellspacing='0') thead tr(role='row') th.sorting(tabindex='0', aria-controls='example', rowspan='1', colspan='1', aria-label='Name: activate to sort column ascending', style='width: 142px;') Name th.sorting(tabindex='0', aria-controls='example', rowspan='1', colspan='1', aria-label='Position: activate to sort column ascending', style='width: 192px;') Position th.sorting(tabindex='0', aria-controls='example', rowspan='1', colspan='1', aria-label='Office: activate to sort column ascending', style='width: 89px;') Office th.dt-body-right.sorting_asc(tabindex='0', aria-controls='example', rowspan='1', colspan='1', aria-label='Age: activate to sort column descending', style='width: 37px;', aria-sort='ascending') Age tfoot tr th(rowspan='1', colspan='1') Name th(rowspan='1', colspan='1') Position th(rowspan='1', colspan='1') Office th.dt-body-right(rowspan='1', colspan='1') Age tbody for employee in employees tr.odd(role='row') td #{employee.name} td #{employee.position} td #{employee.office} td.dt-body-right.sorting_1 #{employee.age}  
    نلاحظ وجود الـfor loop و طريقة استقبال وعرض المعلومات بسطر واحد فقط و ترجمته حرفيا ان لكل موظف في اوبجكت الموظفين ( الذي ارسلناه من الـNode ) قم بعمل صف في الجدول واضف مابعده
    for employee in employees tr.odd(role='row') td #{employee.name} td #{employee.position} td #{employee.office} td.dt-body-right.sorting_1 #{employee.age}  
    بهذا انتهينا من الجزء الأول للدرس وننتقل للجزء الثاني:
    هذا الجزء من الدرس يتعلق بكيفية عمل items بشكل تخصيصي .. ان ماذا لو انك لا تريد ان تضم عمر الموظف في جدول العرض؟ سنقوم بالتالي في ملف app.js و details.pug - وكلشئ آخر يبقى كما هو:
    //app.js app.get('/details', function (req, res) { connection.query('SELECT * From `employees`', function (error, results, fields) { if (error) { throw error; } else { console.log('The solution is: ', results); var employees_json = []; for (var index = 0; index < results.length; index++) { var item = { name: results[index].name, position: results[index].position, office: results[index].office } employees_json.push(item); } res.render('details', { title: 'Details - Pug ExpressJS NodeJS Tutorial', employees: employees_json }); } }); }); //details.pug table#example.display.nowrap.dataTable.dtr-inline.collapsed(cellspacing='0') thead tr(role='row') th.sorting(tabindex='0', aria-controls='example', rowspan='1', colspan='1', aria-label='Name: activate to sort column ascending', style='width: 142px;') Name th.sorting(tabindex='0', aria-controls='example', rowspan='1', colspan='1', aria-label='Position: activate to sort column ascending', style='width: 192px;') Position th.sorting(tabindex='0', aria-controls='example', rowspan='1', colspan='1', aria-label='Office: activate to sort column ascending', style='width: 89px;') Office //th.dt-body-right.sorting_asc(tabindex='0', aria-controls='example', rowspan='1', colspan='1', aria-label='Age: activate to sort column descending', style='width: 37px;', aria-sort='ascending') Age tfoot tr th(rowspan='1', colspan='1') Name th(rowspan='1', colspan='1') Position th(rowspan='1', colspan='1') Office th.dt-body-right(rowspan='1', colspan='1') Age tbody for employee in employees tr.odd(role='row') td #{employee.name} td #{employee.position} td #{employee.office} //td.dt-body-right.sorting_1 #{employee.age}  
     
    إضغط هنا لتحميل ملفات الدرس الثاني anwbh-app-lesson2.zip
    مستوى المقال: مبتدئ

  3. السلام عليكم و رحمة الله و بركاته..

    في هذا الموضوع سنتحدث عن عن علاقة إطار العمل ExpressJS مع الباترن NodeJS و كيفية عمل Pug as template engine 

    اولا: حتى لا تكون هناك امور مبهمه و ابعاد الغيوم التي تدور حول اذهان الكثير من يريد العمل او التوجه لهذا الباترن يجب عرض بعض من الحقائق:
    الـNodeJS ليست لغة جديدة .. انما بيئة مبرمجة بالـJS. هذه البيئه تعمل في جهة السيرفر. ان كنت مبرمج AngularJS or ReactJS ليس هناك سطر محدد تربط فيه بين تطبيقك الNode مع الفريموورك الذي تعمل به. طريقة الربط تكون من خلال HTTP requests. تستطيع التعامل مع قواعد البيانات المختلفه مباشره بالـNode مثل MySQL, MariaDB و اشهرهم في هذا المجال هي MongoDB.  
    نعود مرة اخرى للـExpressJS الذي هو يعتبر فريم وورك ابعد مما ان يقال عنه "مساعد" في تطبيقات الـNode.
    بإستخدام هذا الفريم وورك الذي يعمل كذلك في السيرفر،  يتم تسهيل العمل و كمية الكود في تطبيق الـNode  بشكل كبير جدا.
    مثال على تطبيق Node بإستخدام فريم وورك ExpressJS وسيتم شرح اجزائه جميعها
    var express = require('express'); var app = express(); app.get('/', function (req, res) {  res.send('Hello World!') }); app.listen(3000, function () {  console.log('Example app listening on port 3000!') });  
    اول سطرين استدعاء موديول الاكسبرس و من ثم دالة الاكسبرس في المتغير app الذي استخدمناه في صنع التطبيق.
     
    الشطر الثاني get هو عبارة عن نوع الـhttp request قد يكون GET, POST, DELETE, UPDATE etc ….
     
    بعد ذلك يأتي المسار - لتفاصيل اكثر حول هذا الجزء الرجاء زيارة الدرس السابق.
     
    نننقل الآن الى امر اخر في الـExpressJS وهو الـtemplating ( عمل الواجهات UI و استقبال البيانات المرسلة من  الـNode )
    لعمل الواجهات الديناميكيه يفضل استخدام محركات التمبليت التي تتوافق مع الاكسبرس وهي
    PUG - know as Jade Mustache EJS  
    و في هذا الدرس سنستخدم المحرك الاول لعمل صفحة ويب اعتيادية و اخرى ديناميكية, لصنع واجهة بمحرك التمبليت pug يجب عليك ان تتقن او ان تاخذ فكره عن هذا المحرك لتعرف كيفية كتابه الكود ومثال على ذلك
    doctype html html(lang='en') head title Jade script(type='text/javascript'). foo = true; bar = function () {}; if (foo) { bar(1 + 5) } body h1 Jade - node template engine #container.col p You are amazing p | Jade is a terse and simple | templating language with a | strong focus on performance | and powerful features.  
    يعادل في الHTML 
    <!DOCTYPE html> <html lang="en"> <head> <title>Jade</title> <script type="text/javascript"> foo = true; bar = function () {}; if (foo) { bar(1 + 5) } </script> </head> <body> <h1>Jade - node template engine</h1> <div id="container" class="col"> <p>You are amazing</p> <p> Jade is a terse and simple templating language with a strong focus on performance and powerful features. </p> </div> </body> </html>  
    لمعلومات اكثر حول اللغة اطلع على موقعهم الرسمي
     
    وبذلك سنقوم بإنشاء مجلدات ومستندات بهذه الطريقة

     
    حمل الـbootstrap وانقل كل من bootstrap.min.css إلى مجلد css , انقل bootstrap.min.js إلى مجلد js
     
    بعد ذلك إبدأ بتثبيت الـpackages التي سنعمل بها من خلال فتح الـterminal في مجلد myapp من خلال الاوامر التالية
    $ npm install express --save $ npm install cookie-parser --save $ npm install body-parser --save $ npm install mysql --save  
    افتح ملف التطبيق app.js وقم بإستدعاء هذه البكجات
    var express = require('express'); var cookieParser = require('cookie-parser'); var bodyParser = require('body-parser'); var mysql = require('mysql');  
    الآن نبدأ بإعداد config فريم وورك الـExpressJS مع cookie-parser body-parser ( سنستخدمهم لاحقا )
    var router = express.Router(); var app = express(); app.use(bodyParser.json({limit: "50mb"})); app.use(cookieParser()); var urlencodedParser = bodyParser.urlencoded({ extended: true, parameterLimit:50000 }); app.use("/", router);  
    نضيف امكانية استخدام ملفات الـcss, js , images etc من خلال استخدام الـmiddleware ـexpress static بإعطاء مسار وهمي لهذه الملفات
    app.use('/css', express.static(__dirname + '/public/css')); app.use('/js', express.static(__dirname + '/public/js'));  
    نرى وجود ملفات الـcss and js في مجلد public/css ولكن المسار الذي سنكتبه في الكود هو فقط css/ وليس بالضرورة ان يكون اسم المسار الوهمي ذو علاقه بالمسار الاساسي .. تستطيع ان تسميه مثلا sambosa/ و في الحقيقة هو public/css/ 
     
    تحديد نوع الـtemplate engine الذي سنستخدمه في هذا التطبيق مع تحديد مسار مجلد الـviews الذي يحتوي على صفحات الموقع او التطبيق
    app.set('views', __dirname + '/views'); app.set('view engine', 'pug');  
    بعد إنشاء ملفات الـpug في إحدى الخطوات السابقه , انسخ والصق كود الصفحتين index.pug and layout.pug details.pug كلن على حدى
    //layout.pug doctype html html head title= title script(src='https://code.jquery.com/jquery-3.2.1.min.js') link(rel='stylesheet', href='/css/bootstrap.min.css') script(src='/js/bootstrap.min.js') body nav.navbar.navbar-default .container .navbar-header button.navbar-toggle.collapsed(type='button', data-toggle='collapse', data-target='#navbar', aria-expanded='false', aria-controls='navbar') span.sr-only Toggle navigation span.icon-bar span.icon-bar span.icon-bar a.navbar-brand(href='/') NodeJS #navbar.navbar-collapse.collapse ul.nav.navbar-nav li.active a(href='/') Home li a(href='/details') details li.dropdown a.dropdown-toggle(href='#', data-toggle='dropdown', role='button', aria-haspopup='true', aria-expanded='false') | Dropdown span.caret ul.dropdown-menu li a(href='#') Action li a(href='#') Another action li a(href='#') Something else here li.divider(role='separator') li.dropdown-header Nav header li a(href='#') Separated link li a(href='#') One more separated link block content //index.pug extends layout block content .container h1 #{msg} p #{username} , welcome to the first templating tutorial //details.pug extends layout block content .container .table-responsive h2 user table p This is all users we have so far table.table.table-bordered#example thead tr th Firstname th Lastname th Email tbody tr td John td Doe td john@example.com tr td Mary td Moe td mary@example.com tr td July td Dooley td july@example.com link(rel='stylesheet', type='text/css', href='https://cdn.datatables.net/v/dt/dt-1.10.15/datatables.min.css') script(type='text/javascript', src='https://cdn.datatables.net/v/dt/dt-1.10.15/datatables.min.js') script(). $(document).ready(function() { $('#example').DataTable(); }); ملاحظة: نستخدم extends layout  لكي لا نكرر الـhead في الصفحات الاخرى , مثل include في الـPHP ( في هذا الدرس ) - الاستخدام الحقيقي للـlayout هو تصميم شكل معين لصفحات معينه .. كـtemplate خاص مثلا - معلومات اكثر من خلال الرابط هنا
     
     
    الأن تم تجهيز المستوى الأول من التطبيق وهو الـconfigurations , ننتقل إلى النص الآخر وهو الـroutes . اولا  route الصفحة الرئيسية سيكون كالتالي
    app.get('/', function(req, res) { res.render('index', { title: 'Pug ExpressJS NodeJS Tutorial', username: 'abdulla', msg: 'Hey There!' }) });  
    نلاحظ ان مسار الـroute هو مجرد slash للامام .. بذلك يتم تحديد المسار الرئيسي للتطبيق, بعد ذلك res.render اي تعني response render حيث يقوم تطبيق الـNode بالأجابة من بعد عمل طلب request من طرف المستخدم , للتوضيح اكثر الـHTTP هو عباره عن بروتوكول طلب و اجابة وبذلك request and response - req, res فعند طلب العميل امر ما يجب عليه ان يحصل على شي ما في المقابل.
     
    و كما موضع في الدالة اعلاه ان الـresponse هو عباره عن عمل render لملف index.pug الموجود في مجلد views مع ارسال ثلاث متغيرات title, username and msg , و طريقة استقبال البيانات في الـpug هي كالتالي ( يوجد اكثر من طريقة )
    h1 #{username} p Welcome to #{title}  
    خطوة اخيره لتشغيل التطبيق يجب تحديد بورت معين ولنفترض 3000
    app.listen(3000, function() { console.log('The app is running http://localhost:3000'); });  
    افتح الـterminal داخل مجلد التطبيق myapp واكتب الامر التالي لتشغيل التطبيق
    node app.js  
    افتح المتطفح على المسار
     
    انتهى الدرس الاول .. تم من خلاله
    عمل configuration لتطبيق الـnode الذي سنستخدمه في الدروس القادمة تثبيت template engine و توصيله مع تطبيق الـNode ارسال بيانات من الـNode إلى pug  
    الدرس القادم سيكون هناك سنعرض لكم كيفية التعامل مع قواعد البيانات وإرسال المعلومات الى pug 
     
    للحصول على ملفات العمل تجدونهم في المرفقات, بعد تحميل الملف قم بفك الضغط انتقل إلى داخل المجلد واكتب الأمر التالي لتثبيت جميع الـpackages دفعة واحده
    $ npm install --save  
     
    أضغط هنا لتحميل ملفات العمل anwbh-app.zip
    موقع مساعد لتحويل كودات الـHTML إلى Pug 
    http://html2jade.org
    مستوى المقال: مبتدئ
  4. السلام عليكم ورحمة الله وبركاته
    من خلال الدرسين السابقين والملاحظات:
    ماهو الNode.js؟ الدرس الأول في الNode.js عمل تسجيل دخول
    ملاحظات في الـJQuery مع الـNode.js
     
    تم التعرف على الفرق بين الـNode.js والـPHP , ماهو سبب تفوق سرعة النود وماهو النود جي اس مجملا , كما تم طرح الدرس الأول عن كيفية عمل خاصية تسجيل الدخول و حفظ الكوكيز في المتصفح ومنها يكون:
    عمل كونكشن مع الداتا بيس ارسال البيانات من فورم , طريقة استقبال المعلومات المرسلة , وبشكل خاص في الـNode.js , التعامل مع الـCookies بعد تسجيل الدخول  ,كيفية التعامل مع البيانات من ومطابقتها مع قاعدة البيانات.  
    في هذا الدرس الثاني سيتم عمل خاصية البحث بالطريقة الاعتيادية اولا ومن ثم سيكون هناك درس آخر لتبيان التغييرات لعمل البحث بشكل حي Live.
     
    إذا, لنبدأ هذا الدرس حيث سأفترض اولا بأنك اتممت قراءة الدرس الأول وتطبيق الدرس الأول و فهم ملاحظات الـJQuery مع الـNode.js , سنبدأ بعمل ملف الـبحث ومثلا يكون كالتالي:
    <!DOCTYPE html> <html lang="en"> <head id="head"> </head> <script src='js/jquery.js'></script> <script src="js/head.layout.js"></script> <script src="js/search.js"></script> <body> <!--/.nav-start --> <!-- Navigation Goes Here --> <nav class="navbar navbar-default"> <script src="js/nav.js"></script> </nav> <!--/.nav-end --> <div class="container"> <div class="col-md-12"> <div class="col-md-3"> <form class="form-horizontal" action="/api/search" method="GET" id='searhform'> <div class="form-group"> <label for="search"><h4><i class="fa fa-search" id="spinning_animation"></i> Search Key</h4></label> <input name='search' id='search' class="form-control" class="form-control" /> </div> <div class="form-group"> <button type="submit" class="btn btn-primary"> Search</button> </div> </form> </div> </div> <div class="col-md-12"> <!-- Search Results --> <div id="search_results"></div> </div> </div> </body> </html>  
    والملف الآخر في مجلد js يحتوي على ajax لإرسال قيمة الـinput#search
    $(document).ready(function() { //Ajax Search $(document).on("submit","#searhform",function(e){ $("#search_results").empty(); $("#spinning_animation").removeClass("fa fa-search"); $("#spinning_animation").addClass("fa fa-circle-o-notch fa-spin"); var search = $("#search").val(); $.ajax({ type: "GET", url: "api/search", async:true, timeout: 500, data: {search:search}, success: function(response){ // $(".img-responsive").hide(); $("#spinning_animation").removeClass("fa fa-circle-o-notch fa-spin"); $("#spinning_animation").addClass("fa fa-search"); $.each( response, function( key, val ) { if(val.ID != null){ $("#search_results").append( "<div class='col-md-3 text-center'>"+ "<div class='box'>"+ "<h3>"+val.car_name+"</h3>"+ "<p>Brand: "+val.car_brand+"<p>"+ "<p>Model: "+val.car_model+"<p>"+ "</div>"+ "</div>" ); } else{ $("#spinning_animation").removeClass("fa fa-circle-o-notch fa-spin"); $("#spinning_animation").addClass("fa fa-search"); $("#search_results").html("<p style='color:red;'>No Results</p>"); } }); }, error: function(){ $("#spinning_animation").removeClass("fa fa-circle-o-notch fa-spin"); $("#spinning_animation").addClass("fa fa-search"); $("#search_results").html("<p style='color:red;'>Error In Request</p>"); } }); e.preventDefault(); }); });  
    البحث سيكون في قاعدة البيانات التي سبق وعملتها وللتأكد , هذه هي القاعدة والجدول الذي سنبحث فيه حيث يحتوي على car_name, car_model, car_brand, ID (Primary)
    SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; SET time_zone = "+00:00"; -- -- Table structure for table `cars` -- CREATE TABLE `cars` ( `ID` int(11) NOT NULL, `car_name` text NOT NULL, `car_brand` text NOT NULL, `car_model` int(11) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1; -- -- Dumping data for table `cars` -- INSERT INTO `cars` (`ID`, `car_name`, `car_brand`, `car_model`) VALUES (1, 'Nissan Patrol', 'Nissan', 2016), (2, 'Camaro SS', 'Chevy', 2010), (3, 'Mustang', 'Ford', 2013), (4, 'S500', 'Mercedes', 2009), (5, '330i', 'BMW', 2014); -- ------------------------------------ -- -- Indexes for dumped tables -- -- -- Indexes for table `cars` -- ALTER TABLE `cars` ADD PRIMARY KEY (`ID`); -- -- AUTO_INCREMENT for dumped tables -- -- -- AUTO_INCREMENT for table `cars` -- ALTER TABLE `cars` MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=6;  
    وبهذا تم الانتهاء من اعداد قاعدة البيانات, ملف الـsearch.html وكذلك Ajax لارسال قيمة البحث إلى الـserver.js , لننتقل إلى ملف الـserver.js ونضيف الـroute المسؤول عن استقبال قيمة متغير البحث, عمل اللازم و ارجاع الناتج بعد ذلك .. حيث سيكون كالتالي:
    var http = require('http'); var express = require("express"); var mysql = require('mysql'); var app = express(); app.use('/bootstrap', express.static(__dirname + '/bootstrap')); app.use('/css', express.static(__dirname + '/css')); app.use('/js', express.static(__dirname + '/js')); app.use('/images', express.static(__dirname + '/images')); app.use('/faawesome', express.static(__dirname + '/faawesome')); var mysql = require('mysql'); var connection = mysql.createConnection({ host : 'localhost', user : 'root', password : '', database : 'cars' }); app.get('/api/search', function (req, res) { var searchkey = req.query.search; console.log(JSON.stringify(searchkey, null, 4)); if(searchkey != ""){ connection.query('SELECT * FROM cars WHERE `car_name` LIKE ?',"%"+searchkey+"%", function(err, rows, fields) { if (err){ throw err; } else { if(rows.length > 0){ res.writeHead(200, {'Content-Type': 'application/json'}); console.log(JSON.stringify(rows, null, 4)); res.end(JSON.stringify(rows ,null, 4)); } } }); } else { res.send("Nothing"); } }); app.get('/',function(req,res){ res.redirect("/home"); }); app.get('/home',function(req,res){ res.sendFile(__dirname + "/home.html"); }); app.get('/search',function(req,res){ res.sendFile(__dirname + "/search.html"); }); app.listen(3000,function(){ console.log("Working on port 3000"); });  
    شرح: هنا نلاحظ الـRoute المسؤول عن استقبال قيمة متغير البحث
    app.get('/api/search', function (req, res) { var searchkey = req.query.search; console.log(JSON.stringify(searchkey, null, 4)); if(searchkey != ""){ connection.query('SELECT * FROM cars WHERE `car_name` LIKE ?',"%"+searchkey+"%", function(err, rows, fields) { if (err){ throw err; } else { if(rows.length > 0){ res.writeHead(200, {'Content-Type': 'application/json'}); console.log(JSON.stringify(rows, null, 4)); res.end(JSON.stringify(rows ,null, 4)); } } }); } else { res.send("Nothing"); } });  
    خطوة اخيرا , قم بتشغيل التطبيق من خلال الأمر
    node server.js  
    افتح المتصفح على الصفحة
    127.0.0.1:3000/search  
    الملفات المرفقة
    js/nav.js
    $(".navbar.navbar-default").append( "<div class='container'>"+ "<div class='navbar-header'>"+ "<button type='button' class='navbar-toggle collapsed' data-toggle='collapse' data-target='#navbar' aria-expanded='false' aria-controls='navbar'>"+ "<span class='sr-only'>Toggle navigation</span>"+ "<span class='icon-bar'></span>"+ "<span class='icon-bar'></span>"+ "<span class='icon-bar'></span>"+ "</button>"+ "<a class='navbar-brand home' href='home'>"+ "<img src='images/nodejs-logo.png' style='max-width:52px;height:auto;' class='hidden-xs'>"+ "<img src='images/nodejs-logo-small.png' class='visible-xs'><span class='sr-only'></span>"+ "</a>"+ "</div>"+ "<div id='navbar' class='collapse navbar-collapse'>"+ "<ul class='nav navbar-nav navbar-left' id='uls'>"+ "<li class='active'><a style='color: #FFF;'><i class='fa fa-home'></i> Home</a></li>"+ "<li><a href='about'><i class='fa fa-folder-open'></i> About</a></li>"+ "<li><a href='contact'><i class='fa fa-phone'></i> Contact</a></li>"+ "</ul>"+ "</div>"+ "</div>" );  
    js/head.layout.js
    // $(document).ready(function() { $("#head").append( "<meta charset='utf-8'>"+ "<meta http-equiv='X-UA-Compatible' content='IE=edge'>"+ "<meta name='viewport' content='width=device-width, initial-scale=1'>"+ "<title>Search / NodeJS Bootstrap 101</title>"+ "<link rel='stylesheet' href='bootstrap/css/bootstrap.css'>"+ "<link href='css/style.blue.css' rel='stylesheet' id='theme-stylesheet'>"+ "<link rel='stylesheet' href='faawesome/css/font-awesome.css' media='screen' title='Font Awesome'>"+ "<script src='js/jquery.form.js'></script>"+ "<script src='bootstrap/js/bootstrap.js'></script>" ); // });  
    مستوى المقال: متوسط

  5. .....
    بعد المقدمة عن باترن الـNode.js في المقال السابق سأقوم بشرح اهم الدروس التي لطالما  كانت اولى الخطوات المتبعه في جميع اللغات لمعرفة كيفية التعامل مع:
    قواعد البيانات. طريقة ارسال المعلومات من Form. طريقة استقبال المعلومات المرسلة. وبشكل خاص في الـNode.js , كيفية التعامل مع البيانات من ومطابقتها مع قاعدة البيانات. التعامل مع الـCookies بعد تسجيل الدخول.  
    في بداية هذا الدرس, سأفترض امرين الأول هو مسبقا بأنك قمت بتثبيت الـ Dependencies وهم:
    npm install mysql npm install express npm install cookie-parser  
    والثاني هو ان تكون لديك معرفة متوسطة مسبقة بلغة الـ javascript و jquery
     
    وبعد التأكد من التثبيت, اعمل قاعدة بيانات سواء كانت خارجية ام داخليةوستكون كالتالي مثلا:
    -- phpMyAdmin SQL Dump -- version 4.5.1 -- http://www.phpmyadmin.net -- -- Host: 127.0.0.1 -- Generation Time: Sep 09, 2016 at 11:50 PM -- Server version: 10.1.16-MariaDB -- PHP Version: 5.6.24 SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; SET time_zone = "+00:00"; /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!40101 SET NAMES utf8mb4 */; -- -- Database: `cars` -- -- -------------------------------------------------------- -- -- Table structure for table `cars` -- CREATE TABLE `cars` ( `ID` int(11) NOT NULL, `car_name` text NOT NULL, `car_brand` text NOT NULL, `car_model` int(11) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1; -- -- Dumping data for table `cars` -- INSERT INTO `cars` (`ID`, `car_name`, `car_brand`, `car_model`) VALUES (1, 'Nissan Patrol', 'Nissan', 2016), (2, 'Camaro SS', 'Chevy', 2010), (3, 'Mustang', 'Ford', 2013), (4, 'S500', 'Mercedes', 2009), (5, '330i', 'BMW', 2014); -- -------------------------------------------------------- -- -- Table structure for table `users` -- CREATE TABLE `users` ( `ID` int(11) NOT NULL, `username` text NOT NULL, `password` text NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1; -- -- Dumping data for table `users` -- INSERT INTO `users` (`ID`, `username`, `password`) VALUES (1, 'androidworldbh', '123123'), (2, 'user2', 'bahrain'), (3, 'user3', '4567'); -- -- Indexes for dumped tables -- -- -- Indexes for table `cars` -- ALTER TABLE `cars` ADD PRIMARY KEY (`ID`); -- -- Indexes for table `users` -- ALTER TABLE `users` ADD PRIMARY KEY (`ID`); -- -- AUTO_INCREMENT for dumped tables -- -- -- AUTO_INCREMENT for table `cars` -- ALTER TABLE `cars` MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=6; -- -- AUTO_INCREMENT for table `users` -- ALTER TABLE `users` MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4; /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;  
    اسم قاعدة البيانات هو cars تحتوي على جدولين users,cars وكل جدول يحتوي على بيانات كما هو موضح في الكود السابق.
     
    بعد ذلك قم بعمل ملف اسمه ولنفترض server.js يحتوي على التالي وبالتفصيل سأقوم بعرض الملف .. في البداية نستدعي مانريد من Packages
    var http = require('http'); var express = require("express"); var cookieParser = require('cookie-parser'); var mysql = require('mysql'); var app = express();  
    نقوم بعمل الـRouting لنحدد للتطبيق المعني بالمتغير app كيفية استجابة طلب المتصفح ( العميل ) والـSyntax هو
    app.METHOD(PATH, HANDLER);  
    في ملف server.js ستقوم بإضافة
    app.use(cookieParser()); app.use('/bootstrap', express.static(__dirname + '/bootstrap')); app.use('/css', express.static(__dirname + '/css')); app.use('/js', express.static(__dirname + '/js')); app.use('/images', express.static(__dirname + '/images')); app.use('/faawesome', express.static(__dirname + '/faawesome'));  
    لتستطيع استخدام الملفات الـCSS & JS وكذلك الصور , ولنستهل ربط قاعدة البيانات بالتطبيق من خلال الكود التالي:
    var connection = mysql.createConnection({ host : 'localhost', user : 'root', password : '', database : 'cars' }); ملاحظة: تستطيع استدعاء المتغيرات السابقة من ملف خارجي وبالغالب يتم تسميته بـconfig.js يحتوي على جميع المتغيرات الثابته constants مثل متغيرات ربط قواعد البيانات او ماشابه ذلك ولكن في هذا المثال سنستعمل الطريقة الإعتيادية والمباشرة.
    وبهذا تم اعداد وربط قاعدة البيانات مع التطبيق, وبما ان هذا الدرس عبارة عن كيفية عمل تسجيل دخول سنقوم بكتابة كود الفورم  داخل ملف login.html ( وسأفترض مسبقا بأنك تعرف ذلك ):
    <div class="container"> <div class="card card-container"> <img id="profile-img" class="profile-img-card" src="images/nodejs-logo.png" /> <p id="profile-name" class="profile-name-card"></p> <form class="form-signin" action="/api/login" method="get" id="loginForm"> <span id="reauth-email" class="reauth-email"></span> <input type="text" id="username" class="form-control" placeholder="Username" name="username" required autofocus> <input type="password" id="password" class="form-control" placeholder="Password" name="password" required> <div id="remember" class="checkbox"> <label> <input type="checkbox" value="remember-me"> Remember me </label> </div> <button class="btn btn-lg btn-primary btn-block btn-signin" type="submit">Sign in</button> </form> <a href="#" class="forgot-password" id="status"> Forgot the password? </a> </div> </div>  
    سكربت ارسال بيانات فورم تسجيل الدخول في ملف الـhtml سيكون:
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script> <script> $(document).ready(function() { $('#loginForm').submit(function() { $("#status").empty().text("loging in..."); $(this).ajaxSubmit({ error: function(xhr) { status('Error: ' + xhr.status); }, success: function(response) { console.log(response) if(response == 401){ $("#status").html("Error In Provided Info"); } else { window.location.href = '/home/'+response; } } }); return false; }); }); </script>  
    نعود مرة اخرى لملف server.js ونضيف routing الفورم الذي بدوره يستقبل بيانات الدخول وهم اسم المستخدم username والباسسورد password ويطابق ما تم ارساله من قبل المستخدم مع ماهو موجود في جدول Users في قاعدة البيانات
    app.get('/api/login', function (req, res) { var user_credentials = { username: req.query.username, password: req.query.password } connection.query('SELECT * FROM users WHERE `username` = ?',user_credentials.username, function(err, rows, fields) { if (err) throw err; if(rows.length > 0){ var userpass = rows[0].password; if(userpass == user_credentials.password){ console.log(JSON.stringify(user_credentials, null, 4)); res.send(user_credentials.username); } else { return res.json(401); console.log("password aint right"); } } }); });  
    هنا نلاحظ عدة امور اولها الميثود المستخدم في هذا الـrouting او الـcontroller كما يستميه البعض وهي GET , ذلك يعني انه يجب على ميثود الفورم الذي عملته ان يكون GET ليستقبل البيانات
    app.get  
    الملاحظة الثانية هي المتغيرين الأثنين وهم اسم المستخدم والباسسورد , تستطيع استخدامهم في الكود بشكل مباشر بهذه الطريقة
    var username = req.query.username var pssword = req.query.password  
    ولكن لسهولة التعامل قمنا بإضافتهم إلى متغير user_credentials بهذه الطريقة
    var user_credentials = { username: req.query.username, password: req.query.password }  
    ولأستدعاء اسم المستخدم مثلا:
    user_credentials.username  
    ولمعلومات طرق عمل الـqueries الرجاء زيارة الرابط التالي:
    https://www.npmjs.com/package/mysql
     
    الملاحظة الثالثة وهي rows.length , عند execute الكويري, البكج المستخدم بشكل مباشر يقوم بإرجاع عدة بيانات تستطيع الإطلاع عليها في الـconsole وإحدى هذه الأمور هي عدد الصفوف التي هي متطابقة مع الكويري
    connection.query('SELECT * FROM users WHERE `username` = ?',user_credentials.username, function(err, rows, fields) ...  
    وستكون بالعادة صف واحد, لذلك نضع شرط إذا كان عدد الصفوف المعنية بالكويري اكثر من صفر rows.length > 0 ذلك يعني بأن اسم المستخدم موجود في قاعدة البيانات ونطابق الـpassword كالتالي:
    if(rows.length > 0){ var userpass = rows[0].password; // الباسسورد الذي تم استخراجه من الصف المرجع من الكويري if(userpass == user_credentials.password){ console.log(JSON.stringify(user_credentials, null, 4)); res.send(user_credentials.username); } else { return res.json(401); console.log("password aint right"); } }  
    إذا كان كلمة المرور متطابقة, سنقوم بإرسال اسم المستخدم مرة اخرى لصفحة login.html لنرسلها إلى صفحة اخرى المعنية بحفظ الـcookies
    res.send(user_credentials.username);  
    او اذا كانت كلمة المرور غير متطابقة سنرسل json عبارة عن
    return res.json(401);  
    وفي ajax صفحة الـlogin.html
    success: function(response) { console.log(response) if(response == 401){ $("#status").html("Error In Provided Info"); // إذا كان الكود المسترجع هو 401 ذلك يعني بأن كلمة السر غير متطابقة } else { window.location.href = '/home/'+response; // خلاف ذلك, سنرسل اسم المستخدم إلى روتنج معني بحفظ اسم المستخدم في كوكيز } }  
    إذا كانت كلمات السر متطابقة, ميثود الـAjax ستقوم بتحويل المستخدم إلى Routing لحفظ اسم المستخدم في كوكيز , وكود الـRounting هو:
    app.get('/home/:user',function(req,res){ res.cookie('name', req.params.user).redirect('/home'); });  
    الذي بدوره يحفظ اسم المستخدم في كوكيز بعنوان name وبعد ذلك يحوله إلى صفحة الـhome.html
    <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Node.js Bootstrap 101</title> <link rel="stylesheet" href="bootstrap/css/bootstrap.min.css"> <script src="/bootstrap/js/bootstrap.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script> <script type="text/javascript"> $.ajax({ type: "GET", url: '/api/cookies', success: function(response) { if(response != "undefined"){ $("#uls").append("<li><a href='logout'><i class='fa fa-lock'></i> Logout</a></li>"); $("#navbar").append("<ul class='nav navbar-nav navbar-right'><li><a href='#'><i class='fa fa-user'></i> Welcome Back. "+response+"</a></li></ul>") } else { window.location.href = '/login'; } }, error: function(){ window.location.href = '/login'; } }); </script> </head> <body> <nav class="navbar navbar-default"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">Node.js</a> </div> <div id="navbar" class="collapse navbar-collapse"> <ul class="nav navbar-nav" id="uls"> <li class="active"><a href="#">Home</a></li> <li><a href="about">About</a></li> <li><a href="contact">Contact</a></li> </ul> </div> <!--/.nav-collapse --> </div> </nav> <div class="container"> <div class="col-md-12"> <h1>Home Page</h1> <h3>Bootstrap & NodeJS</h3> </div> </div> </body> </html>  
    و لا تنسى كتابة routing صفحتي الlogin and home و كذلك اللسنر في ملف server.js
    app.get('/',function(req,res){ res.redirect("/home"); }); app.get('/home',function(req,res){ res.cookie('name', req.cookies.name).sendFile(__dirname + "/home.html"); }); app.get('/login',function(req,res){ res.sendFile(__dirname + "/login.html"); }); app.listen(3000,function(){ console.log("Working on port 3000"); });  
    وللتاكد بأنه تم حفظ اسم المستخدم سنعمل routing اخر وهو:
    app.get('/api/cookies', function (req, res) { if(res.cookie('name', req.cookies.name) != null){ res.send(req.cookies.name); } else { res.cookie('name', "undefined") return res.json(401); } });  
    او من خلال console متصفح chrome بكتابة
     
    وبهذا, تستطيع تشغيل التطبيق الآن من خلال كوماند:
    node server.js  
    و في المتصفح
    127.0.0.1:3000/home  
    مستوى المقال: متوسط
  6. ماهو الNode.js؟
    كثير ماسمع المطورين بهذا الإطار في الفتره الاخيره حيث حصد هذا الاطار على اهتمام الكثير من المبرمجين في مجال تطوير الويب  لما يقدمه من امور خرافيه نوعا ما و مستوى جديد كليا في هذا العالم.
     
    ال Node.js هو اطار عمل برمج العديد من وحداته Modules الأساسية بلغه الJavaScript تم تطويره  من قبل مبرمج امريكي يعيش في المانيا  يدعى ريان دال و السوبر فايز جوينت، و كان اول إطلاق لهذا الباترن في عام 2009.
     
    من المعروف بأن لغة الجافا سكربت هي لغة الClient Side، بمعنى ذلك انها لغة تعمل بجانب المستخدم وليس في السيرفر ولكن بعد تطوير ريان دال لهذا الباترن (النود جي اس) الذي يعمل بمحرك قوقل V8 والعديد من الlibraries الاخرى اصبح الامر اكثر تعقيدا من ذي قبل و تحول هذا الإطار بالعمل في السيرفر كمثل الPHP، بمعنى اخر، الNode.js اصبح إطار عمل Functionality حركية و ديناميكية بشكل تام بإمكانك التعامل مع قواعد البيانات وما الى ذلك من خلاله بكل سهوله.
     
    يستخدم إطار الNode.js لبرمجة تطبيقات الويب بالتحديد و المواقع بشكل عام، يعتمد في عمله على الevents او باللغة العربية تدعى ( المناسبات )  لذلك اي شي يحصل على السيرفر يقوم بإطلاق non-blocking event كل كونكشن جديد => fires event ، معلومات مرسله من فورم => fires event ، طلب بيانات من قاعدة البيانات من قبل المستخدم => fires event.

    عمليا، هذا يعني ان الموقع او التطبيق لا يمكن ان يتاخر بتنفيذ مناسبة event حتى لو دخله او استخدمه آلاف المستخدمين في نفس الوقت لان إطار ال Node.js برمج ليكون Non-Blocking بذلك الأوامر يتم تنفيذها بالتوازي بخلاف الPHP التي هي لغة block until completion اي ان الاوامر لايتم تنفيذها الا بتنفيذ ما سبق من اوامر وهذا هو الفرق الاكبر مابين PHP & Node.js وهذا هو سبب تميز إطار عمل النود وسبب السرعه الرهيبه في تنفيذ الاوامر.
     

     
    لتثبيت الإطار، قم بزيارة الموقع ادناه، يدعم الانظمة جميعها Windows, OSX & Linux
    https://nodejs.org/en/download/  
    امثلة: بعد التحميل والتثبيت، في هذا القسم سيتم وضع عدة امثلة لطريقة بدائية Hello World ومن ابسط الامثلة هو
    1- انشأ ملف بإسم hello.js و اكتب فيه التالي
    var http = require('http'); http.createServer(function (req, res) {     res.writeHead(200, {'Content-Type': 'text/plain'});     res.end('Hello World!'); }).listen(3000, '127.0.0.1');  
    2- افتح الterminal او cmd على الوندوز واكتب
    node hello.js
    بذلك، اصبح التطبيق يعمل على port 3000 كما هو محدد.
    3- افتح اي متصفح تستخدمه وادخل على الرابط
    http://127.0.0.1:3000  
    مثال آخر على كيفية التعامل مع Bootstrap & Node.js
    صفحة الHTML
    <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Node.js Bootstrap 101</title> <link rel="stylesheet" href="bootstrap/css/bootstrap.min.css"> <script src="/bootstrap/js/bootstrap.min.js"></script> </head> <body> <nav class="navbar navbar-default"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">Node.js</a> </div> <div id="navbar" class="collapse navbar-collapse"> <ul class="nav navbar-nav"> <li class="active"><a href="#">Home</a></li> <li><a href="about">About</a></li> <li><a href="contact">Contact</a></li> </ul> </div> <!--/.nav-collapse --> </div> </nav> <div class="container"> <div class="col-md-12"> <h1>Home Page</h1> <h3>Bootstrap & NodeJS</h3> </div> </div> </body> </html>  
    صفحة الAbout
    <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Node.js Bootstrap 101</title> <link rel="stylesheet" href="bootstrap/css/bootstrap.min.css"> <script src="/bootstrap/js/bootstrap.min.js"></script> </head> <body> <nav class="navbar navbar-default"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">Node.js</a> </div> <div id="navbar" class="collapse navbar-collapse"> <ul class="nav navbar-nav"> <li><a href="home">Home</a></li> <li class="active"><a href="#">About</a></li> <li><a href="contact">Contact</a></li> </ul> </div> <!--/.nav-collapse --> </div> </nav> <div class="container"> <div class="col-md-12"> <h1>ِAbout Page</h1> <h3>Bootstrap & NodeJS</h3> </div> </div> </body> </html>  
    صفحة الContact
    <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Node.js Bootstrap 101</title> <link rel="stylesheet" href="bootstrap/css/bootstrap.min.css"> <script src="/bootstrap/js/bootstrap.min.js"></script> </head> <body> <nav class="navbar navbar-default"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">Node.js</a> </div> <div id="navbar" class="collapse navbar-collapse"> <ul class="nav navbar-nav"> <li><a href="home">Home</a></li> <li><a href="about">About</a></li> <li class="active"><a href="#">Contact</a></li> </ul> </div> <!--/.nav-collapse --> </div> </nav> <div class="container"> <div class="col-md-12"> <h1>Contact Page</h1> <h3>Bootstrap & NodeJS</h3> </div> </div> </body> </html>  
    قم بتثبيت Dependency Express
    npm install express --save  
    ملف الserver.js
    var express = require("express"); var app = express(); app.use('/bootstrap', express.static(__dirname + '/bootstrap')); app.get('/',function(req,res){ res.sendFile(__dirname + "/home.html"); }); app.get('/home',function(req,res){ res.sendFile(__dirname + "/home.html"); }); app.get('/about',function(req,res){ res.sendFile(__dirname + "/about.html"); }); app.get('/contact',function(req,res){ res.sendFile(__dirname + "/contact.html"); }); app.listen(3000,function(){ console.log("Working On Port 3000"); });  
    تأكد من وضعك ملفات الBootstrap في المسار التالي ( في مجلد اسمه bootstrap بجانب ملف السيرفر)
    <link rel="stylesheet" href="/bootstrap/css/bootstrap.min.css"> <script src="/bootstrap/js/bootstrap.min.js"></script>  
    خطوة اخير, قم بتشغيل السيرفر من خلال الأمر
    node server.js  
    افتح المتصفح على الرابط التالي
    http://127.0.0.1:3000  
    وهذا هي اولى الدروس في الNode.js ولاستخدامات اكثر، قم بزيارة رابط Github ادناه للحصول على tools مفتوحه المصدر.
    https://github.com/developerbh  
    إسأل ماشئت وسأحاول الأجابة ان شاء الله.
    مستوى المقال: مبتدئ
  7. بسم الله الرحمن الرحيم
    اللَّهُمَّ انْفَعْنَا بِمَا عَلَّمْتَنَا، وَعَلِّمْنَا مَا يَنْفَعُنَا، وَزِدْنَا عِلْمًا إِلَى عِلْمِنَا
    سلسلة دروس JavaScript: الدرس الثاني حلقات التكرار.
    قائمة الدروس السابقة:


    في هذا الدرس إن شاء الله سوف نتعلم حلقات التكرار في لغة JavaScript، ولكن قبل أن نبدأ سوف نستذكر بعض المصطلحات و النقاط الهامة والتي سنستذكرها إن شاء الله دومًا خلال سلسلة الدروس هذه.
    أولا تذكر JavaScript ليست Java.
    ثانيًا سوف نرمز لاحقًا ل JavaScript بالرمز JS.
    ثالثًا  JavaScript التي سنخوضها في هذه الدروس هي Client Side ( طرف العميل)،  وليست Server Side ( طرف الخادوم ).
    ماهو التكرار؟ أو ماهي حلقات التكرار؟
    في لغة JS قد نحتاج أحيانًا لتنفيذ اجراء (Action) ما مرارًا وتكرارًا وليس مرة واحدة فقط، ومن هذا المنطلق تستطيع مثلًا طباعة ارقام الأسطر بطريقة ديناميكية دون الحاجة لعمل هذا الإجراء بشكل يدوي، ومن الأمثلة كذلك طباعة المصفوفات والبيانات، مثلًا لديك مصفوفة (Array) تحتوي على مئة صف، وتريد أن تقوم بطباعة كُل الصفوف، وهذه العملية لا تتم من دون حلقات التكرار.
    أولًا While loop:
    النوع الأساسي من حلقات التكرار هو While loop والهدف منه هو القيام بعملية تنفيذ النص (statement) أو الشفرة المعطاة (code) مرارًا وتكرارًا مادام شرط التكرار (expression) يحمل القيمة TRUE (قيمة الصواب). متى ماأصبح شرط التكرار FALSE (قيمة الخطأ) يتوقف التكرار بشكل كامل. وقد تتضح الفكرة من خلال الصورة التالية:

    لاحظ مادام شرط التكرار (Expression) المرمز له بـ A يحمل القيمة TRUE فسوف يستمر تكرار البيان البرمجي (Statement) المرمز له بـ B بالتنفيذ (Execute) حتى تصبح قيمة A تحمل القيمة FALSE  عندها سوف يتوقف التكرار.
    لاحظ النقطة البيضاء هي نقطة البداية التي سوف تعود لها حلقة التكرار  مرارًا وتكرارًا أثناء التنفيذ مادام A يحمل القيمة TRUE والسوداء نقطة نهاية التكرار (End of loop) سوف تذهب إليها حلقة التكرار عندما تحمل A القيمة FALSE.
    قد لا يبدو الأمر بتِلك السهولة من الصورة فقط، لذلك سوف نحاول طرح مثال وذلك لتوضيح الفكرة 
    ولكن أوه ، قبل المثال، فالنتعلم كيف نقوم بكتابة While-loop. من الأن فصاعدًا سوف نضع بنية الشفرة (Syntax) بطريقة Pseudo code.
     
    ~ نقطة خارج الموضوع ولكن للفائدة:
    Pseudo code أو بالعربية الشفرة الزائفة هي طريقة لتوضيح خطوات برمجية دون استخدام اوامر برمجية فعلية، وتستخدم احيانا لشرح Syntax للغة البرمجة ولكن مع الإخلال قليلًا في القيود، كوضع نص مكتوب مثلًا بين الشفرة البرمجية.
     
    الصورة التالية توضح البنية الكتابية للـ while-loop في لغة JS.

    لاحظ الخط الأحمر المتعرج يعني أن هذا النص مخالف لقيود اللغة.
    الأن بعض الأمثلة البسيطة التي توضح عمل While-loop
    <html> <body> <script type="text/javascript"> <!-- // سوف يحتفظ هذا المتغير بعدد الدورات var count = 0; // سيتم طباعة هذه الجملة أولًا. document.write("Starting Loop "); // حلقة التكرار // هذا شرط التكرار while (count < 10){ // سيتم طباعة هذا السطر في كل دورة document.write("Current Count : " + count + "<br />"); // من الدرس الأول، هل تتذكر ماذا يعمل هذا السطر؟ count++; } // سيتم طباعة هذا السطر بعد انتهاء عمل جملة التكرار While document.write("Loop stopped!"); //--> </script> <p>Set the variable to different value and then try...</p> </body> </html> لاحظ الشفرة أعلاه تحتوي على بعض أكواد HTML، وذلك يعود لما شرحناه بالدرس الاول وهو أن لغة JS التي نتعلمها Client-side ويتم تنفيذها واستخدامها بجانب HTML للتعامل مع عناصرها.
    لاحظ اذهب للدرس الأول لاستذكار موضوع DOM.
     
    في المثال أعلاه سوف يبدأ التكرار عندما يكون المتغير count يحمل القيمة 0 وينتهي عندما يحمل القيمة 10. وسيكون ناتج الشفرة ( Code output ) كالأتي:
    Starting Loop Current Count : 0 Current Count : 1 Current Count : 2 Current Count : 3 Current Count : 4 Current Count : 5 Current Count : 6 Current Count : 7 Current Count : 8 Current Count : 9 Loop stopped! Set the variable to different value and then try... لاحظ الناتج (output) صحيح 100% ولكن يوجد خطأ بسيط فماذا تعتقد أن يكون ؟! الاجابة هي أننا استخدمنا document.write وليس document.writeln وهذا يجعل السطر الأول يكون بجانب السطر الثاني، والسطر ماقبل الأخير يكون بجانب السطر الذي يسبقه. لم تفهم؟  .. فقط قم بمراجعة الدرس الأول 
    ثانيًا Do-while:
    ال do-while هي نوع ثاني من while أو بالأصح هي نفس الشيء ولكن الفرق بينها وبين while هي أنها تقوم بالتحقق من شرط التكرار في نهاية التكرار، مما يعني أنها تقوم بالتكرار على الأقل مرة واحدة فقط. 
    هذا يعني أن البرنامج سيقوم بالدخول لحلقة التكرار دون التحقق من شرط التكرار (Expression) ثم بعد ذلك اثناء محاولته للقيام بدورة ثانية سيتحقق من شرط التكرار فإن كان الشرط يعطي النتيجة TRUE سيتم استكمال دورة ثانية أما ان كان شرط التكرار يعطي النتيجة FALSE سوف يقوم بالخروج من حلقة التكرار، وقد يتضح هذا الأمر من خلال الصورة التالية:

    لاحظ مادام شرط التكرار (Expression) المرمز له بـ A يحمل القيمة TRUE فسوف يستمر تكرار البيان البرمجي (Statement) المرمز له بـ B بالتنفيذ (Execute) حتى تصبح قيمة A تحمل القيمة FALSE سوف يتوقف التكرار.
    لاحظ النقطة البيضاء هي نقطة البداية التي سوف يعود لها مرارًا وتكرارًا أثناء التنفيذ مادام A يحمل القيمة TRUE والسوداء نقطة نهاية التكرار (End of loop) سوف يذهب إليها عندما تحمل A القيمة FALSE.
    لاحظ لان العملية هي Do while فلا يوجد تحقق في البداية (Condition) ولكن التحقق يتم بعد دورة كاملة مما يعني أن do-while تقوم بعملة دورة واحدة على الأقل في كُل الحالات.
     
    الصورة التالية توضح البنية الكتابية (syntax) لشفرة do-while:

     
    الأن مثال بسيط لتوضح عمل do-while:
    <html> <body> <script type="text/javascript"> <!-- // متغير سوف يحمل عدد الدورات وسيكون شرط التكرار. var count = 0; // جملة طباعة document.write("Starting Loop" + "<br />"); // بداية حلقة التكرار // لاحظ لايوجد تحقق هنا do{ // جملة طباعة document.write("Current Count : " + count + "<br />"); // ؟ count++; } // التحقيق بعد اتمام الدورة .. while (count < 5); // جملة طباعة document.write ("Loop stopped!"); //--> </script> <p>Set the variable to different value and then try...</p> </body> </html> في المثال أعلاه سوف تقوم جملة التكرار بتنفيذ دورة واحدة في البداية، بعد ذلك سيتم التحقق من شرط التكرار ان كانت النتيجة TRUE سوف يعمل دورة أخرى. عدى ذلك سوف تنتهي حلقة التكرار.
    ناتج الشفرة أعلاه:
    Starting Loop Current Count : 0 Current Count : 1 Current Count : 2 Current Count : 3 Current Count : 4 Loop Stopped! Set the variable to different value and then try...  
    ثالثًا for-loop:
    هذا النوع الأخير و إن لم يكن كذلك من حلقات التكرار الأساسية، وهو مشابه تمامًا لل while إلا أنه قد يكون أبسط في الإستخدام وذو خصائص اضافية.
    تحتوي for-loop على ثلاثة أقسام:
    القسم الأول Initialization (العداد) وهو قيمة افتراضية تحتوي على رقم (عدد حقيقي -Integer-) من خلاله يتم المقارنة لاحقًا في القسم الثاني وهو مهم ومسؤول عن استمرار حلقة التكرار.
    القسم الثاني Test Statement او Condition (شرط التكرار): يتم هنا التحقق من العداد (Counter) بواسطة Expression (تعبير منطقي)، وهو المسؤول الأول عن استمرار حلقة التكرار.
    القسم الثالث Iteration Statement (جملة التكرار): يتم هنا التعديل على العداد بعد انتهاء دورة كاملة إما بزيادته او إنقاصه أو حتى القيام بعملية حسابية عليه لتغييره و هو قسم مهم جدًا لتفادي مشكلة التكرار اللامتناهي.
    تتم العملية كالأتي، يتم تعيين قيمة في العداد ثم بعد ذلك التحقق منها من خلال شرط التكرار، ثم بعد ذلك يتم تنفيذ دورة كاملة في حال إنتهاء الدورة يتم التعديل على قيمة العداد من خلال جملة التكرار؛ والصورة التالية توضح طريقة عملها:

     
    أما البنية الكتابية (Syntax) لل for-loop فهي كالأتي:
     

    لاحظ يتم الفصل بين كل قسم بفاصلة منقوطة (Semi coma) وهذا يعني أن الأقسام ليست Parameter (معامل) وانما Section (قسم).
    ولنوضح الفكرة بشكل كامل سنقوم بطرح مثال بسيط لعملها.
    <html> <body> <script type="text/javascript"> <!-- // العداد var count; // جملة طباعة document.write("Starting Loop" + "<br />"); // حلقة التكرار //Counter //Condition //Iteration statement for(count = 0; count < 10; count++){ // جمل طباعة يتم تنفيذها في كل دورة document.write("Current Count : " + count ); document.write("<br />"); } // جملة طباعة يتم تنفيذها بعد انتهاء حلقة التكرار document.write("Loop stopped!"); //--> </script> <p>Set the variable to different value and then try...</p> </body> </html> وناتج المثال أعلاه:
    Starting Loop Current Count : 0 Current Count : 1 Current Count : 2 Current Count : 3 Current Count : 4 Current Count : 5 Current Count : 6 Current Count : 7 Current Count : 8 Current Count : 9 Loop stopped! Set the variable to different value and then try...  
    رابعًا أخطاء شائعة قد تقع بها عند استخدام حلقات التكرار:
    الخطأ الأول تعيين شرط تكرار تكون نتيجته دائمًا TRUE (قيمة صواب) وهذا يوقعك بخطأ منطقي شائع جدًا يمسى Infinite loops (دورات لا متناهية).
    الخطأ الثاني تعيين جملة تكرار غير صحيحة بحيث تقوم بتغيير العداد بشكل غير صحيح مما يؤدي لزيادة دوراة أو تنقيص دوراة أو حتى تجاوز البعض منها وهو خطئ شائع جدًا يمسى Logic error (خطأ منطقي).
    أخيرًا نصائح في استخدام حلقات التكرار:
    النصيحة الأولى حاول أن لا تستخدم حلقات التكرار بشكل كبير لأن ذلك يبطئ من سرعة أداء برنامجك.
    النصيحة الثانية قم بالتخطيط قبل كتابة البرنامج لأن ذلك سوف يساعدك على اختيار النوع الأمثل من حلقات التكرار بالشكل الأمثل.
    النصيحة الثالثة في معالجة البيانات باستخدام حلقات التكرار قم باستخدام Algorithm (آلقيوريثم) مناسب وذلك لزيادة اداء البرنامج.
     
    هذا وصلى الله وسلم على سيدنا محمد وعلى آله وصحبه أجمعين.
    أسأل الله تعالى أن أكون قد وفقت في إيصال المعلومة لكم، وأن أكون قد نفعتكم بهذا الدرس.
    تحياتي لكم.
     
    في الدرس القادم سوف نتحدث عن الأتي:
    1 - الدوال Functions
    مستوى المقال: مبتدئ
  8. بسم الله الرحمن الرحيم
    اللَّهُمَّ انْفَعْنَا بِمَا عَلَّمْتَنَا , وَعَلِّمْنَا مَا يَنْفَعُنَا , وَزِدْنَا عِلْمًا إِلَى عِلْمِنَا
    مقدمة:
    استكمالًا  لسلسلة دروس (مقدمة في JavaScript -سنرمز لها لاحقأ بالاختصار JS-) سوف نتعلم اليوم النوع الأخير من العمليات في لغة JS وهي عمليات البيتوايز (Bitwise operators).

    تذكر JavaScript ليست Java
    العمليات (Operations): 
    هُنا جدول يوضح عمليات ال Bitwise
    # وصف العملية & المسمى: Bitwise AND
    الوظيفة: يقوم بعمل مقارنة لكل بت (Bit) في السلسلة بحيث اذا تقابل البت 1 مع البت 1 سيكون الناتج 1 عدى ذلك 0.
    // مثال توضيحي var x = 2; // In (4) bit: 0010 var y = 3; // In (4) bit: 0011 var z; z = (x & y); // Z = 2  
    | المسمى: Bitwise OR
    الوظيفة: يقوم بعمل مقارنة لكل بت (Bit) في السلسلة بحث اذا تقابل البت 0 مع البت 0 سيكون الناتج 0 عدى ذلك 1.
    // مثال توضيحي var x = 2; // In (4) bit: 0010 var y = 3; // In (4) bit: 0011 var z; z = (x | y); // Z = 3  
    ^ المسمى: Bitwise exclusive OR
    الاختصار: XOR
    الوظيفة: يقوم بعمل مقارنة لكل بت (Bit) في السلسلة بحيث اذا تشابه البت في كلا الطرفين سيكون الناتج 0 عدى ذلك 1.
    // مثال توضيحي var x = 2; // In (4) bit: 0010 var y = 3; // In (4) bit: 0011 var z; z = (x ^ y); // Z = 1  
    ~ المسمى: Bitwise NOT
    الوظيفة: يقوم بعمل مقارنة لكل بت (Bit) في السلسلة بحيث يقوم بتحويل ال 1 الى 0 وال 0 الى 1.
    // مثال توضيحي var y = 3; // In (4) bit: 0011 var z; z = (~y); // y = -4 In (4) bit: 1100  
    المسمى: Bitwise left shift
    الوظيفة: يقوم بعمل ازاحة لكل بت حسب المكان المعطى الى جهة اليسار.
    // مثال توضيحي var y = 3; // In (4) bit: 0011 var z; z = (y << 1); // y = 6 In (4) bit: 0110  
    المسمى: Bitwise right shift
    الوظيفة: يقوم بعمل ازاحة لكل بت حسب المكان المعطى الى جهة اليمين.
    // مثال توضيحي var y = 3; // In (4) bit: 0011 var z; z = (y >> 1); // y = 1 In (4) bit: 001  
    المسمى: Bitwise right shift with ZERO
    الوظيفة: يقوم بعمل ازاحة لكل بت حسب المكان المعطى الي جهة اليمين. الفرق بينها وبين Right shift انها دومًا تعوض جهة اليسار بالبت 0. تستخدم غالبًا مع الاعداد السالبة.
    // مثال توضيحي var y = 3; // In (4) bit: 0011 var z; z = (y >>> 1); // y = 1 In (4) bit: 001  
    في الجدول أعلاه قمنا بوضع كل عملية مع مثال مبسط لها، ومنه نستنتج أن  Bitwise Operator تتعامل مع ال Binary لكل عدد وتقارن وتزيح حسب العملية المستخدم والازاحة المعطاة.
     
    ولنبسط الفكرة، سوف نأخذ كل عملية ونقوم بوضع مثال مشروح لها.
    اولًا : Bitwise AND
    لنفترض أن لدينا العدد 2 والعدد 3 كما في المثال المدرج في الجدول، ولكل عدد قيمة رقمية متسلسلة (Binary) خاصة به وكل قيمة سوف نجعلها 4 Bit أي متكونة من 4 خانات كالأتي:
    العدد 2 لديه القيمة: 10 ولنجعلها 4 Bit نضيف اصفار من على اليسار لتصبح 0010
    العدد 3 لديه القيمة: 11 ولنجعلها 4 Bit نضيف أصفار من على اليسار لتصبح 0011
     
    عملية بسيطة أليس كذلك؟ وللتبسيط أكثر ياصديقي سوف نخرج عن الموضوع قليلًا لنشرح ماهي ال Binary.
    باللغة العربية ( نظام العد الثنائي )، وبالإنجليزية ( Binary Numeral System ) هو نظام أعداد -غير بشري أي لا يستطيع البشر فهمه أو قراءته بسهولة - يستخدم لتمثيل قيم عددية باستخدام الرمزين (الرقمين) 1 و 0، وهو لغة الآلة أو اللغة التي يتحدث بها الكمبيوتر ( الحاسب الآلي ). 
    ملاحظة: نظام الأرقام الذي نستخدمه نحن بنو البشر هو Decimal Numeral System بالعربية ( نظام العد العشري ).
     
    نعود لمثالنا، الأن عند استخدام العميلة (AND) والتي يرمز لها بالرمز & فالذي يحدث هو أن النظام يقوم بمقارنة كُل خانة من سلسلة الأرقام الأولى بكل خانة من سلسلة الأرقام الثانية ... لم تفهم صح 
    سأبسط لك العملية بهذه الصورة:

     
    لاحظ المنطق، يكون الناتج 1 فقط اذا تقابل 1 مع 1 .. عدى ذلك سيكون الناتج دائمًا 0، والناتج النهائي هو الرقم 2 بالتأكيد. فهمت كيف تعمل الان ؟! 
     
    ثانيًا: Bitwise OR
    لنفترض نفس المثال مع AND، والصورة التالية تشرح الأمر:

     
    هل لاحظت الإختلاف عن العملية AND، الأن في العملية OR اذا تقابل 0 مع 0 يكون الناتج 0 عدى ذلك فهو 1.
     
    ونفس المنطق تمامًا يعمل مع بقية العمليات عدى أن المنطق يختلف قليلًا من عملية إلى أخرى، وربما تكون أصعب عملية هي الـ Shifting ( التحريك )، كونها تحتاج لمبدأ ثابت ومنطق صارم لكي يكون الناتج صحيح.
    ولنبسط الـ Shifting كما فعلنا مع الـ AND والـ OR سوف نشرحها في بطاقة ( صورة توضيحية )، وبالتأكيد سأقوم بشرح واحدة من العمليات الثلاث، كون أن فهم واحدة منهن يكفي لفهم الإثنتان الأخريين.
     
    ثالثًا: Bitwise Shifting
    الصورة التالية توضح عملية الـ Left Shift (  ):

     
    لاحظ عندما قمنا بالتحريك لليسار ( من اليمين إلى اليسار ) تحركت الأرقام حتى خسرنا 0 من جهة اليسار، وللتعويض قمنا بوضع 0 في اليمين ... وهكذا تتم العملية. 
    ولكي أتأكد من عدم وجود أي غموض بالموضوع، هذه صورة متحركة تشرح الخطوات! الصورة تحتوي على مصطلحات مثل Flip Flop و Clear و Data Input تجاهلها فقط، لأن الصورة تشرح عمل ال Register وهو لا يهمنا ولكن مايهمنا توضيح الفكرة 

     
    أتمنى أن تكون الأمور أكثر وضوحًا الان، واسأل الله العلي العظيم أن أكون قد وفقت في إيصال المعلومة.
    تحياتي.
    مستوى المقال: مبتدئ

  9. اللَّهُمَّ انْفَعْنَا بِمَا عَلَّمْتَنَا , وَعَلِّمْنَا مَا يَنْفَعُنَا , وَزِدْنَا عِلْمًا إِلَى عِلْمِنَا
    مقدمة:
    في هذه الدرس إن شاء الله، ودروس قادمة تليه، سوف أقدم شرح لأساسيات لغة البرمجة الرائعة (JavaScript)، وسوف يكون مستوى هذه الدروس للمبتدئين  فهي عبارة عن مقدمة (Introduction) للغة.
    تعريف لغة JavaScript هي Object-base Scripting Language وهي ليست لغة Java وإنما هي لغة مختلفة كُليًا تستخدم لمعالجة او التلاعب (Maintaining) بالكائنات المرتبطة في صفحات الويبْ.
    تاريخ لغة JavaScript والتي سأرمز لها لاحقًا بـ JS بدأ من شركة Netscape عندما قامت بتطوير لغة برمجة تدعى LiveScript والتي تغير اسمها لاحقًا إلى JavaScript بعد ان تعاونت شركة Netscape مع شركة Sun Microsystems لتطوير اللغة.
    تذكر JavaScript ليست Java
    في الجدول التالي سابين الفروقات بين لغة Java ولغة JavaScript لكي ارسخ الفكرة لديك
    جدول يصف الفروقات بين لغة Java ولغة JavaScript
    JavaScript Java An Interpreted Language A Compiled Language Required only editor Required JDK and JVM  

     
    اولًا بنية اللغة Syntax:
    لغة JS لغة سهلة جدًا ذات بنية لغوية (Syntax) سهلة الفهم والحفظ مع الممارسة
    ماسوف نتطرق إليه في هذا الدرس سيكون
    المتغيرات (Variables) العمليات (Operations) الشروط (IF...ELSE) المحدد (Switch-Case) المتغيرات (Variables): 
    ملاحظة المتغيرات في لغة JS هي Case Sensitive أي حساسة لحالة الأحرف، فالمتغير x مختلف عن المتغير X.
    ملاحظة المتغيرات في لغة JS هي Loosely Typed أي انه لاداعي لتحديد نوع البيانات المراد اسنادها للمتغير.
    var variable_name; // انشاء المتغير variable_name = "Hello World"; // اسناد قيمة للمتغير المثال اعلاه يظهر عملية انشاء متغير (Declare Variable) واسناد قيمة إليه، بحيث أن variable_name هو اسم المتغير، وكلمة var هي كلمة اساسية تبين أن ماسوف أقوم بإنشائه هو متغير.
    var variable_name1, variable_name2; // انشاء أكثر من متغير variable_name1 = 9; // اسناد العدد 9 الى المتغير 1 variable_name2 = variable_name1; // ??? المثال أعلاه يظهر عملية إنشاء اكثر من متغير في سطر واحد، وذلك بفصل اسماء المتغيرات بفاصلة، بعد ذلك قمنا بإسناد قيمة الى المتغير في السطر الثاني، اما السطر الثالث فهو لك لتعمل على فهمه (Practice)
    var x = 10, y = 5, c; // انشاء متغيرات x, y, c c = 0; // اسناد القيمة 0 الى المتغير c المثال أعلاه يوضح أنه بإمكاننا وضع قيم افتراضية اثناء انشاء المتغير (Declare).
     
    العمليات (Operations): 
    جدول يوضح العمليات الرياضية (Arithmetic Operators)
    # وصف العملية +
    عملية الجمع (Addition)
    يوجد عملية اضافية وهي (++) وتسمى Increment وهي زيادة العدد بـ 1
    مثال على ذلك
    var x = 1; x++; // الأن قيمة المتغير x هي 2  
    -
    عملية الطرح (Subtraction)
    يوجد عملية إضافية وهي (--) وتسمى Decrement وهي تنقيص العدد بـ 1
    var x = 1; x--; // الأن قيمة المتغير x هي 0  
    * عملية الضرب (Multiplication) / عملية القسمة (Division) % عملية باقي القسمة (Mod)
     
    عمليات المقارنة (Comparison Operators) 
    # وصف العملية == عملية المساواة (Equal) != عملية اللامساواة (Not Equal) > عملية الأكبر من (Greater than) < عملية الأصغر من (Less than) >= الأكبر من أو يساوي  (Greater than or equal to) <= الأصغر من أو يساوي (Less than or equal to)  
    عمليات المنطق (Logic operators)
    # وصف العملية &&
    علامة "و" (Logic AND)
    تذكر TRUE AND TRUE هو TRUE عدا ذلك FALSE
    || علامة "أو" (Logic OR)
    تذكر FALSE OR FALSE هو FALSE عدا ذلك TRUE
    ! علامة النفي "لا" (NOT)
    تذكر NOT TRUE تساوي FALSE والعكس بالعكس
     
    عمليات الإسناد (Assignment Operators)
    # وصف العملية = اسناد قيمة دون تغيير (Assign) += اسناد قيمة بعد جمعها بالقيمة الحالية -= اسناد قيمة بعد طرحها من القيمة الحالية =* اسناد قيمة بعد مضاعفتها بالقمية الحالية /= اسناد قيمة بعد قسمتها على القيمة الحالية =% اسناد قيمة بعد اخذ باقي القسمة على القيمة الحالية يوجد ايضًا عمليات البيتوايز (Bitwise Operators) ولكني سأجعل لها درس منصفل وذلك لعمقها.
     
    والأن مع الأمثلة على العمليات
    var x = 1; var y = 10; var z = 0; // أمثلة على العمليات الرياضية z = x + y; // z = 1 + 10 => 11 z = x - y; // z = 1 - 10 => -9 z = x * y; // z = 1 * 10 => 10 z = x / y; // z = 1 / 10 => 0.1 z = x % y; // z = 1 % 10 => 0.1 z = x++; // z = 2; z = x--; // z = 0; // أمثلة على عمليات المقارنة z = x == y; // FALSE z = x != y; // TRUE z = x > y; // FALSE z = x < y; // TRUE z = x >= y; // FALSE z = x <= y; // TRUE // أمثلة على عمليات المنطق var a1 = true; var a2 = false; var a3; a3 = (a1 && a2); // FALSE a3 = (a1 || a2); // TRUE لاحظ هنا علامة النفي حول قيمة الخطأ الى صواب. a3 = (a1 AND !a2); // TRUE // أمثلة على عمليات الاسناد x = y + 1; // x = 10 + 1 => 11 x += y; // x = 11 + 10 => 21 x -= y; // x = 21 - 10 => 11 x *= y; // x = 11 * 1 => 110 x /= y; // x = 110 / 10 => 11 x %= y; // x = 11 % 10 => 1.0  
    الشروط (IF...ELSE):
    هذا اسهل جزء بالدرس كٌله (ان تحقق الشرط افعل كذا، ان لم يتحقق افعل كذا)، مثال واحد كافي لفهمه.
    var x = 1; var y = x + 2; // y = 3 // ان تحقق الشرط افعل شئًا ما، ان لم يتحقق افعل شيئًا أخر. if (x != y) { // Do something } else { // Do something } // ان تحقق الشرط الأول افعل شيئًا ما، ان لم يتحقق وتحقق الثاني افعل شيئًا ما.. ان لم يتحقق ايًا منهم افعل شيئًا ما if (y >= x) { // Do something } else if (x < y) { // Do something } else { // Also do something } // لاحظ انت لا تحتاج لاستخدام الأقواس {} ان كان ماسوف ينفذ عبارة عن سطر واحد if (x == y) // Do something لاحظ الأقواس {} تسمى Body فكل مابينها هو تابع للشرط
     
    المحدد (Switch):
    تخيل أن لديك نص (Statement) يتكون من مئة شرط أو أكثر، ليس من المنطقي أن نستخدم الجملة الشرطية (If..Else) مئة مرة، فالهدف من البرمجة التبسيط وليس التعقيد، وهذه هي فكرة جملة Switch فهي تعتمد على المتغير الخاص بها والذي يعتبر المحدد لها، أي ستكون النتائج حسب قيمة ذلك المتغير، ستتضح أكثر مع الأمثلة.
    var select; select = 10; switch (select) { case '0': // If value of select equal to 0 then switch will moving here. // Break statement used to tell switch to stop moving from here. break; case '10': // If value of select equal to 10 then switch will moving here. break; default: // IF value of select does not matching any case, then switch will moving here. } في المثال اعلاه المتغير select قيمته 10، اذا سيقوم المحدد Switch بالتوجه إلى الـ case الذي يحمل القيمة 10 وتنفيذه، جملة Break وضيفتها ان توقف المحدد من الاستمرار، يعني اننا لو لم نضعها سوف ينفذ ال case 10 ثم ينفذ الـ default او لو كان تحت ال case 10 مجموعة cases اخرى فسيقوم المحدد بتنفيذها كلها وصولًا الى default او جملة Break.
    لاحظ Default دومًا نضعها في نهاية المحدد.
     
    ثانيا تضمينها مع HTML:
    لغة JS ليست Client-side فقط وانما من الممكن أن تكون Server-side ايضًا، ولكن ماسوف اشرحه هنا هو جزئية ال Client-side.
    يوجد ثلاث طرق لتضمين JS مع HTML
    Embedded code (كود مضمن) External source (ملف خارجي) Event (حدث) سوف أشرح 1 و 2 .. وسأترك 3 عندما نصل لجزئية الأحداث (Events)
    <!-- Embed Code --> <script type="text/javascript"> // JavaScript code come here </script> <!-- External source --> <script type="text/javascript" src="PATH"></script> في المثال أعلاه استخدمنا وسم <script> في كلا الحالتين، ولكن مع الـ External وضعنا Attribute اضافي وهو src، وقميته PATH هي مسار الملف أو الرابط الخاص به ويجب أن يكون بالامتداد (*.js).   لاحظ ان قمت بوضع شفرى بين <script> و </script> في حالة ال External Source فسيتم تجاهل الشفرة واستخدام الشفرة الناتجة من الملف فقط.  
    هنا أكون قد وصلت إلى نهاية درسي لهذا اليوم.
    اتمنى ان تطبقو عليه قبل البدأ في الدرس الذي يليه، والذي سيتضمن الجمل التكرارية أو حلقات التكرار.
    While-loop for-loop
    مستوى المقال: مبتدئ
  10.  
    جافاسكربت JavaScript من أهم لغات الويب حيث عن طريقها تسطيع عمل مواقع تفاعلية وجذابة وسهلة الإستخدام وإضفاء دينامكية للصفحات تعجز عنها لغات برمجة الويب الأخرى والفضل يعود لكون جافاسكربت تم برمجتها وتطويرها لتعمل بشكل رئيسي من خلال المتصفح لايكاد يوجد موقع الا ويستخدم JavaScript بعضهم يستخدمها للتحكم بالنماذج او الحماية للتحقق من البيانات المدخلة بالنماذج والبعض يستخدمها لإضافة مؤثرات حركية بالصفحات ويمكن استخدامها لزيادة سرعة تصفح الموقع او التعامل مع مستخدمي الموقع بحيث لايحتاج ان يقوم المستخدم بزيارة اكثر من صفحة لتنفيذ أمر ما حيث يمكن تقليص عدد النقرات او تحميل اكثر من صفحة لتنفيذ الأمر باستخدام تقنيات AJAX وتعتبر مكتبات Libraries و أطر العمل Frameworks الجافاسكربت من الأشهر والأكثر وفرة على موقع GitHub.
    وفي الأونة الأخيرة تم تطوير تقنيات تسمح باستخدام JavaScript كلغة خادم يتم معالجة أوامرها بالسيرفر وعرض النتيجة بالمتصفح وأيضا امكانية الإتصال بقواعد البيانات وتخزين وجلب البيانات بكل سهولة بواسطة Node.js مما مكن جافاسكربت ان تكون لغة متصفحات وايضا سيرفرات لتتميز على لغات الويب الأخرى.
    في الواقع، هناك الكثير من المكتبات Libraries و أطر العمل Frameworks للجافاسكربت وفي بعض الاحيانا من الصعب الاختيار من بينها وما هو الأفضل لك. وخصوصا عندما تكون قد بدأت للتو تصميم الموقع الالكتروني. لذلك في هذا المقال اخترنا افضل 10 مكتبات Libraries و أطر العمل Frameworks المفيدة يمكنك استخدامها بمشاريعك.
    بعض هذه المكتبات Libraries و أطر العمل Frameworks تعتبر شامله وتستخدم لجميع المواقع الالكترونيه والبعض الاخر قد تحتاجها وتستخدمها لوظيفة محددة فقط على موقعك الالكتروني ويمكنك استخدام اكثر من مكتبة بمشروع واحد ولكن الأفضل تقليل عدد المكتبات التي يعتمد عليها المشروع ليسهل تطويره وتحديثه بالمستقبل.
    مهم جدا ان تعلم أن المكتبات Libraries تختلف عن أطر العمل Frameworks في طريقة بناء المشاريع وهذا توضيح بسيط عنها:
    المكتبات Libraries: هي مجموعة من الإجراءات البرمجية المستقلة التي يمكن استدعاؤها من قبل البرامج لتنفيذ وظائف تكمل عملها وتقوم بتوفير الوقت حيث انك تسطيع استخدامها مباشرة بصفحات مشروعك حيث ان هذه المكتبات توفر ادوات و وظائف تم برمجتها مسبقا اشهر مثال على المكتبات مكتبة Jquery.
    أطر العمل Frameworks: هي مجموعة من المكونات الجاهزة التي يستخدمها المبرمج في برنامج، حيث أن الهدف منها هو عمل نوع من الأدوات أو البنية التحتية الضرورية للمبرمج، بحيث لا يبدأ برنامجه من الصفر تم عمل هذه الأطر لتسهيل عملية تطوير التطبيقات وعلى عكس المكتبات لاتسطيع استخدام الأدوات او الوظائف المبرمجة مسبقا مباشرة ولكن يجب ان تتبع طريقة عمل الإطار Framework Work Flow ويعود الفضل لإسخدام inversion of control. من اشهر أطر العمل في عالم الجافاسكربت AngularJS من تطوير شركة Google و إطار React من تطوير Facebook و ايضا إطار العمل Backbone. 
    ( الترتيب ابجدي فقط )
    1- AngularJS: ( إطار عمل )

    هو إطار عمل جافا سكربت من خلال المتصفح يتبع بنية Model-View-Controller
    أن كنت قد وجدت HTML5 أقل شمولا مما كنت تريد فأن AngularJS الحل وهي وجدت لتصحيح هذا الوضع. العديد من المطورين يعتمدون على نهج (MVC) لأنشاء تطبيقاتهم على نطاق واسع فأن AngularJS تجعل من الممكن تمديد HTML التي تكتبها. لا تحتاج الكثير من الوقت لتعلم AngularJS اذا كنت تعرف (MVC) و هو اختصار لـModel-View-Controller، أي نموذج-طريقة عرض-متحكم.
    مع ذلك الكثير يعتقد ان Angular معقده ولا تصلح للمبرمجين المبتدئين.
    2- Backbone.js: ( إطار عمل )

    هو إطار عمل جافا سكربت مشابه AngularJS لكنه يختلف في بعض الامور فبإمكان إطار العمل هذا التعامل مع البيانات قبل وصولها DOM كذلك تتعامل Backbone.js مع الأحداث و ايضا تعتبر سهله جداً مقارنه بـ AngularJS. تحتاج التركيز نسبياً لتعلمها وبأمكانك الدخول لموقع إطار العمل حيث يوجد شرح مفصل للأوامر.
    3- Breeze.js: ( مكتبة )

    هي مكتبة جافاسكربت تتعامل وتساعد في ادارة البيانات الكبيره. من مميزاتها الاستعلام و التخزين المؤقت و الرسوم البيانية التفاعلية و التحقق من صحة النموذج الخ... Breeze.js يتصل مع أي خادم يتحدث HTTP وJSON.
    4- Ember.js: ( إطار عمل )

    هو إطار عمل للجافاسكربت يعتمد على MVC في طريقة بنائه ويعتبر إطار عمل Ember.js من إطارات العمل مفتوحة المصدر. انها تسمح للمطورين لإنشاء تطبيقات الويب القابلة للصفحة الواحدة من خلال دمج التعابير الشائعة وأفضل الممارسات في هذا الإطار.
    5- jQuery: ( مكتبة )

    من اشهر المكتبات للجافاسكربت حيث توفر للمطورين امكانية التحكم بمحتوى DOM والتلاعب به ومايميزها هو التحديثات المستمره وان معظم المطورين يعتمدون اعتماد كبير عليها في مشاريعهم. هناك ثلاث اسباب رئيسية جعلة مكتبة jQuery من اشهر المكتبات وهي كالتالي:
    - مكتبة jQuery سهلة التعلم. وايضا الشرح المفصل لاستخدامها بعكس معظم المكتبات الاخر.
    - سرعة مكتبة jQuery لاتصدق لانها تركز على اداء مهام محددة وذلك مايجعلها سريعة في التعامل.
    - الدعم الكبير لهذه المكتبة جعلها من اشهر المكاتب.
    تم انشاء jQuery لتكون حل سريع في كتابة اكواد جافاسكربت وتقلل من تكرار الأوامر والتي تعد إستهلاك كبير من وقت المبرمج ايضا هي مكتبه ممتازه لكثير من الوظائف المهمه. 
    6- jQuery UI: ( مكتبة )

    هي مكتبة لصناعة الواجهات بنيت بواسطة مكتبة jQuery والتي استخدامها يمكنك من بناء تطبيقات ويب تفاعلية. ومن الامثله على ذلك الاكمال التلقائي , التقويم , القوائم , شريط التقدم , شريط التمرير , و علامات التبويب. هذه المكتبة توفر عليك الوقت والجهد في صنع بعض القوائم المهمه لموقعك.
    7- jQuery Mobile: ( مكتبة )

    هي مكتبة جافاسكربت مخصصة لتطبيقات الويب على الهواتف الذكية. ايضا jQuery Mobile نظام مخصص لواجهات المستخدم بنائاً على HTML.
    وكذلك المكتبة مصممة لتتناسب مع جميع مقاسات الشاشة للهواتف الذكية. لذلك اذا كنت تحلم بعمل تطبيقك على الهواتف الذكية فأن مكتبة jQuery Mobile
    قد تكون احد اختياراتك.
    8- Meteor.js: ( إطار عمل )

    يعتبر إطار العمل هذا منصة تطوير كامله لبناء المواقع وايضا التطبيقات للهواتف الذكية. تم بناء هذا الإطار بواسطة Node.js.  تم بناء Meteor.js على افكار مكتبات سابقه لتقديم طريقة سهلة لبدء التطبيق، لكنه يتيح لك الأدوات والمرونة لبناء كامل التطبيق وإنتاجه بشكل مكتمل.
    9- React: ( إطار عمل )

    هو إطار عمل للجافاسكربت يعتمد على MVC في طريقة بنائه ويعتبر إطار عمل React من إطارات العمل مفتوحة المصدر. المميز في إطار العمل هذا سرعته في التعامل مع البيانات. وايضا مايميزه عن غيره هو المرونة والسرعة عند العمل مع المشاريع الكبيرة. 
    10- Vue.js: ( مكتبة )

    Vue.js هي مكتبة لبناء واجهات الويب الحديثة. تدعم مكونات البيانات التفاعليه بطريقه سهله ومرنه بواسطة (API) من المكتبات الجديدة والواعدة بالمستقبل والسبب يعود لسهولة الإستخدام وقوة الأداء ومميزات تفوقت على بقية الأطر تم اعتماد بناء المكتبة على بنية MVVM حيث لاتحتاج ان يوكن لديك Controller كما بالأطر الأخرى إنما تربط View مباشرة بـ Model مما يضيف مرونة التحكم DOM وسهولة التلاعب فيه تستطيع إنشاء نموذج يحتوي على حقل نص وزر إرسال عن طريق Vue تسطيع ان تجعل هذا النموذج مرن حيث لن يرسل النموذج الا إذا قام المستخدم بإدخال نص تسطيع ايضا إضهار رسالة إذا لم يقم بإدخال نص وأيضا عندما تقوم بالكتابة يظهر زر الإسال وتختفي رسالة التحذير بدون تحديث الصفحة هذا كله بـ ٣ اسطر برمجية لايكاد يتعدى السطر كم امر برمجي هذا مجرد مثال بسيط لقوة هذه المكتبة ومرونتها
     
    الخلاصة:
    من المهم أن نعلم أن كل موقع الكتروني له احتياجاته الخاصة به. فليس من الممكن ان تتطابق مع احتياجات موقع اخر. لذلك هناك اشياء يجب مراعاتها عند اختيارك لهذه المكتبات أو أطر العمل وهي كالتالي:
    عليك ضمان ان المكتبة او إطار العمل الذي قمت بأختياره أن يكون مرن ويلبي الاحتياجات الخاصه بك بحيث انه يؤدي العمل بالشكل المطلوب. عليك التحقق من الاصدارات الجديده للمكتبات او أطر العمل حتى تلبي احتياجاتك الجديده وضمان التوافق مع المعايير الجديدة. عليك التأكد من أمان المكتبة او إطار العمل الذي قمت بأختياره , حيث انه قد يكون من الصعب إصلاح المشاكل الأمنية في المستقبل. أختر المكتبة او إطار العمل التي لها دعم كبير من قبل المطورين لأن ذلك يسهل عليك استعمالها. دائماً ابحث عن الامثله للمكتبات او إطارات العمل التي تريد استخدامها لأن ذلك يسهل عليك استيعابها و فهمها بالشكل المطلوب لتستعملها.
    مستوى المقال: متوسط
  11. العالم حولنا يحتوي كم هائل من المعلومات و أرقام مهولة لأشياء لايمكن تخيلها بحياتنا اليومية ولكن ماهي أهمية هذه الأرقام إذا لم تعرض بشكل جميل ومفهوم وبصورة تفاعلية تضيف الحيوية لهذه الأرقام وتبسط هذه الأرقام المعقدة بصور بيانية جذابة 
    وتعتبر لغة جافا سكربت JavaScript من أقوى اللغات التي تميزت بهذا المجال ودخلته من واسع أبوابه لما لديها من القدرة على إضفاء الطابع الحيوي وعرض هذه البيانات بشكل جميل وجذاب وتعمل بكل المتصفحات والأجهزة وعن طريقها تم إنشاء اجمل وأفضل المكتبات لعرض هذه البيانات والأرقام على هيئة رسوم بيانية وتفاعلية وسوف نستعرض بهذا المقال أهم هذه المكتبات وأفضلها لخدمة المشاريع البرمجية التي تحتاج إلى عرض البيانات على شكل رسوم بيانية تفاعلية للمستخدم وتبسيطها له بشكل جذاب ومفهوم 
    D3.js — Data-Driven Document

    من أقدم وأقوى المكتبات لإنشاء الرسوم البيانية وذات مصدر مفتوح مجانية الإستخدام وتحتوي على مميزات كثيرة كانت مفقودة بكثير من المكتبات الأخرى بوقتها من أهم مميزاتها خاصية "Enter and Exit" والتي تسمح لك بإضافة مجموعة جديدة من البيانات للرسم البياني الذي تم إنشائه مسبقا وحذف البيانات القديمة بشكل تفاعلي وحيوي وتميزت بطريقة كتابة الأكواد البسيطة وقوة عرض البيانات بتأثيرات حركية مرنة وتقوم مكتبة D3.js بإنشاء الرسوم البيانية بإستخدام HTML, SVG, CSS
    عيبها الوحيد أنها لاتأتي مع نماذج لرسوم بيانية مبنية مسبقا عند إستخدامها وينبغي ان تبني رسومك البيانية بنفسك ولكن قام العديد من المطورين ببناء الكثير من الرسوم البيانية باستخدام D3.js ونشرها وتوجد صفحة مخصصة لهذه الأعمال يمكن أن تستخدمها كنقطة بداية لأعمالك يمكنك مشاهدتها من هنا صفحة لرسوم بيانية مبنية على D3.js ولكن تم بناء العديد من المكتبات عليها سوف نستعرض بعضها بهذا المقال
    ايضا لاتعمل جيدا مع متصفحات قديمة مثل IE8 لكن من الممكن استخدام إضافات مثل  aight plugin لتمكين المكتبة من دعم أغلب المتصفحات 
    الترخيص: مصدر مفتوح - مجانية الإستخدام
    Google Charts

    تقدم مكتبة Google Charts العديد من الرسوم البيانية الجاهزة للإستخدام وبكل سهولة مثل area charts و bar charts و calendar charts و  pie Charts و geo charts والكثير 
    تميزت المكتبة بكثرة الخيارات التي تسمح لك بسهولة التعامل مع الرسوم البيانية وتغييرها لما ترغب بكل مرونة ويتم عمل هذه الرسوم البيانية بواسطة HTML5 و SVG وتدعم جميع انواع المتصفحات والأجهزة وتدعم المتصفحات القديمة مثل النسخ القديمة من متصفحات IE عن طريق VML لإنشاء الرسوم البيانية 
    يمكنك مشاهدة جميع الرسوم البيانية التي تسطيع هذه المكتبة إنشائها وعرض الخيارات للتحكم بها من هنا صفحة الرسوم البيانية المبنية بواسطة Google Charts
    الترخيص: مجاني - ولكن ليس مفتوح المصدر فترخيص Google لايسمح لك بأن تقوم بتحميل ملف JS بموقعك فإن كان مشروعك ذو بيانات حساسة وخاصة فهذه المكتبة غير مناسبة لك لأن جميع البيانات يجب ان تمر بسيرفرات Google ليتم تحليلها ثم عرضها كرسوم بيانية بالمتصفح 
    ChartJS

    من أجمل المكتبات وأخفهم حجما تميزت بتصميمها ذو الطابع Flat Design ومرونتها حيث تم برمجة المكتبة على شكل وحدات تدعم مكتبة ChartJS جميع انواع المتصفحات والشاشات وتحتوي على ٦ انواع من الرسوم البيانية (core, bar, doughnut, radar, line, and polar area) يتم تشكيل هذه الرسوم على المتصفح بإستخدام HTML5 Canvas بالمتصفحات الحديثة وعن طريق Polyfill للمتصفحات القديمة مثل IE7/8 تعتبر من أقوى المكتبات وتمكنك من إستخدام اي نوع من الرسوم البيانية التي تدعمها المكتبة على حدة مما يسمح لك بتصغير حجم ملف المكتبة أكثر مما هو عليه على حسب إحتياجات مشروعك
    الترخيص: مفتوح المصدر - مجانية الإستخدام
    Chartist.js

    من المكتبات التي تميزت بسهولة الإستخدام ودعمها لجميع انواع الشاشات وتميزت عن غيرها بالمؤثرات الحركية مما يعطي بياناتك الطابع الحي والتفاعل مع المستخدم ولكن هذه الخاصية تعمل فقط بالمتصفحات الحديثة و تميزت بمرونة تعديل شكل الرسوم البيانية بواسطة CSS ودعم الشاشات عن طريق Media Query تستخدم المكتبة SVG لرسم البيانات بالمتصفح مما يجعلها مهيئة للتطويرات المستقبلية
    معلومة: تم بناء هذه المكتبة لتلافي حدود المكتبات الآخرى بوقتها وبسبب غلاء إستخدام المكتبات المدفوعة لذلك تم تزويد المكتبة بمميزات وخواص كانت مفقودة من المكتبات الأخرى 
    الترخيص: مفتوح المصدر - مجانية الإستخدام
    Ember Charts

    مكتبة مفتوحة المصدر تم بنائها على D3.js و Ember.js تقدم انواع متعددة من الرسوم البيانية مثل time series و bar و pie و scatter وتسمح لك بإنشاء ماتريد من رسوم بيانية خاصة بك وتميزت بطريقة تعاملها مع الأخطاء عند تزويدها ببيانات خاطئة مما يضمن عدم توقف عمل برمجياتك عند حدوث أي خطأ 
    هذه المكتبة من ضمن سلسلة جميلة لتحسين وتسهيل التعامل مع Ember.js ويوجد مكتبات أخرى من نفس المطور مثل Ember Tables و Ember Widgets
    الترخيص: مفتوح المصدر - مجانية الإستخدام
    n3-charts

    إذا كنت مطور AngularJS وترغب بإنشاء رسوم بيانية خطية Line Charts فإن n3-charts ستكون ضمن إهتماماتك حيث تم تطويرها على AngularJS و D3.js عيبها عدم دعمها لأنواع أخرى من الرسوم البيانية يمكنك مشاهدة صفحة الأمثلة لرسوم بيانية مبنية على n3-charts
    الترخيص: مفتوح المصدر - مجانية الإستخدام
    Smoothie Charts

    إذا كنت تتعامل مع بيانات حية RealTime Data يتم تحديثها بإستمرار يمكن ان تفيدك هذه المكتبة هي تستخدم HTML5 Canvas لتشكيل الرسوم البيانية بالمتصفح تم برمجتها بدون مكتبات آخرى مثل Jquery او AngularJS وتقدم خيارات عديدة مثل تاخيرعرض البيانات او تغير الآلوان للبيانات الحية التي يتم رسمها بالمتصفح مثلا لو ترغب بعرض رسم بياني يوضح لك إستخدام CPU بالسيرفر بشكل حي وتفاعلي بمجرد تزويد بيانات حية للمكتبة
    الترخيص: مفتوح المصدر - مجانية الإستخدام
    Chartkick

    هذه المكتبة مخصصة لمطوري برمجيات Ruby وتدعم أغلب انواع الرسوم البيانية مثل pie, column, bar, area, geo, timeline, and multiple series تسمح لك بإنشاء أي من هذه الرسوم البيانية بسطر برمجي واحد وتقوم بتشكيل الرسوم بواسطة SVG أيضا تتوفر منها نسخة لمطوري Python و JavaScript
    الترخيص: مفتوح المصدر - مجانية الإستخدام 
    ZingChart

    مكتبة لمعالجة البيانات الضخمة و إنشاء رسوم بيانية جميلة لها تميزت بخفتها وسرعتها ومرونتها يتم إستخدام هذه المكتبة من قبل شركات كبيرة مثل Apple و Microsoft و Adobe و Boeing و Walmart حيث تستخدم تقنيات حديثة مثل Ajax و JSON و HTML5 لإنشاء رسوم بيانية جميلة وبسرعة كبيرة 
    يمكنك تجربة المكتبة مجانا ولكن يلزمك شراء ترخيص إذا كنت ترغب بإستمرار إستخدام هذه المكتبة
    الترخيص: مدفوع تجاري - غير مجانية يجب شراء ترخيص
    Highcharts JS

    تعتبر أحد أشهر المكتبات وتدعم العديد من انواع الرسوم البيانية وتحتوي على العديد من المؤثرات الحركية مما يمكنك من إنشاء رسوم بيانية جميلة وجذابة للمستخدم مثل بعض المكتبات وتاتي Highcharts JS وبحوزتها العديد من الرسوم البيانية الجاهزة للإستخدام مثل spline و area و areaspline و column و  bar و  pie و scatter والعديد
    تميزت هذه المكتبة عن غيرها بدعم جميع انواع المتصفحات حتى القديمة مثل IE6 بدون أي إضافات وأيضا تقدم خدمة Highchart cloud لبناء الرسوم البيانية السحابية تستطيع إستخدام المكتبة شخصيا ولكن إذا كنت تقدم منتج تجاري يجب أن تقوم بشراء ترخيص للإستخدام
    الترخيص: مجانية للإستخدام الشخصي - مدفوعة للإستخدام التجاري
    Flot

    من أقدم المكتبات وأشهرهم تم تطويرها بواسطة Jquery وتم التركيز على سهولة الإستخدام والمؤثرات الحركية مما تميزت به المكتبة المرونة وسهولة التحكم بالمؤثرات الحركية بواسطة Jquery ودعمها لجميع انواع المتصفحات حتى القديمة جدا مثل IE6 و Firefox 2 وتدعم المكتبة العديد من انواع الرسوم البيانية مثل lines و points و filled areas و bars والعديد أيضا يوجد بالموقع مكتبة تحتوي على مشاركات العديد من المطورين على شكل إضافات يمكنك مشاهدة صفحة الإضافات المطورة على Flot من هنا او مشاهدة صفحة أمثلة الرسوم البيانية المبنية على Flot من هنا
    الترخيص: مفتوحة المصدر - مجانية الإستخدام
    amCharts

    من أجمل المكتبات الموجودة حيث تم تقسيم المكتبة لثلاث مكتبات متخصصة وهم JavaScript Charts و Maps Charts و Stock Charts 
    1- JavaScript Charts متخصصه بإنتاج العديد من الرسوم البيانية وتقوم بإنشاء هذه الرسوم بواسطة SVG وتعمل على المتصفحات الحديثة فقط أمثلة للرسوم البيانية التي تسطيع هذه المكتبة إنشائها 
    2- Maps Charts او كما تسمى amCharts متخصصه بعرض رسوم بيانية على شكل خرائط ووضع أيقونات أو صور ببعض الأماكن ورسم خطوط بين بعض الأماكن أو دعم خاصية التقريب و التبعيد بالخريطة أو دعم وضع النصوص على الخرائط التي تم إنشائها 
    3- Stock Charts مخصصة لإنشاء رسوم بيانية خاصة بالأسهم ومتخصصة بالرسم البياني المالي 
    يوجد نسختين مجانية الإستخدام ولكن ستضع رابط بالرسم البياني لموقع المكتبة ونسخة مدفوعة ولكن عيبها غلاء قيمة النسخة المدفوعة
    الترخيص: مجانية بوضع رابط بالرسم البياني - مدفوعة لحذف الرابط والحصول على الدعم الفني
    Fusioncharts

    من أقدم المكتبات حيث تم إصدار اول نسخة بعام 2002 يتم إنشاء الرسوم البيانية باستخدام HTML5 و SVG للمتصفحات الحديثة و VML للمتصفحات القديمة تميزت هذه المكتبة عن غيرها بدعمها انواع البيانات من نوع JSON أو XML وإمكانية تصدير الرسوم البيانية على هيذة PNG أو JPG أو PDF تحتوي هذه المكتبة على أكثر من 90 نوع من الرسوم البيانية الجاهزة للإستخدام 
    من مميزاتها دعمها لأنواع كثيرة من لغات البرمجة او المكتبات البرمجية عن طريق مكتباتهم المتخصصة مثل إمكانية إنشاء الرسوم البيانية بواسطة PHP أو Jquery أو AngularJS أو Rails يمكنك مشاهدة صفحة المكتبات البرمجية من هنا
    تحتوي مكتبة Fusioncharts على كل ماتتمناه من مميزات وخصائص لإنشاء الرسوم البيانية بشكل جميل وجذاب وتدعم لغات متعددة لها إمكانيات تميزها عن غيرها بسهولة الإستخدام و التعامل 
    عيبها عند إستخدامها تقوم المكتبة بوضع شعار صغير على الرسمة البيانية المنتجة ولحذفها يجب أن تقوم بشراء ترخيص
    الترخيص: مجانية للإستخدام الشخصي - مدفوعة للإستخدام التجاري
    EJS Chart

    على حسب موقع المكتبة أنها قادرة على إنتاج رسوم بيانية للشركات سواء كانت بيانات بسيطة أو كبيرة بكل قوة ومرونة وتقوم بإنشاء رسوم بيانية سهلة القراءة والتعامل ليس كبقية المكتبات الأخرى تدعم جميع انواع المتصفحات حتى القديمة منها مثل IE6 يمكنك مشاهدة صفحة أمثلة مبنية على EJS Chart من هنا
    عيبها ان النسخة المجانية منها تسمح لك بإنشاء رسم بياني واحد بكل صفحة وكحد أقصى إنشاء مجموعتين فقط 
    الترخيص: مجاني إنشاء رسم بياني واحد بالصفحة - مدفوع للإستخدام غير المحدود
    uvCharts

    مكتبة مفتوحة المصدر تم بنائها على D3.js وتحتوي على 12 نوع من الرسوم البيانية الجاهزة للإستخدام ولديها أكثر من 100 خيار للتحكم بإعدادات المكتبة من مميزات المكتبة إزالة الصعوبة عن التعامل مع مكتبة D3.js وتبسيط التعامل معها عن طريق API سهل ومرن للتحكم بشكل الرسوم البيانية وايضا تقديم انواع جاهزة للإستخدام مباشرة بدون إنشاء الرسوم البيانية من برمجيا من الصفر مثل D3.js تقوم المكتبة بإنشاء الرسوم البيانية بواسطة SVG و HTML و CSS
    الخلاصة
    تحليل وعرض البيانات بالرسوم البيانية الجميلة والجذابة مهمة جدا لأي مشروع سواء كان ضخم او متوسط أو حتى صغير الحجم قمنا بهذا المقال عرض أهم المكتبات سواء كانت متخصصة بالبيانات الضخمة أو البسيطة فإختر مايناسب مشاريعك على حسب إحتياجاتك لتبسيط عرض البيانات وجعلها مفهومة للمستخدم عن طريق رسوم جذابة و سهلة الفهم لكل مكتبة نقاط قوة وعيوب تسطيع التجربة وإختيار مايناسب إحتياجاتك أتمنى أن يكون المقال ذو فائدة لمشاريعكم
    مستوى المقال: متوسط
  12. DropzoneJS هي مكتبة JavaScript مفتوحة المصدر حجمها خفيف لاتعتمد بعملها على مكتبات أخرى مثل Jquery وسهلة التعامل ومرنة بالإستخدام حيث تتيح لك العديد من الخيارات والمزايا لعمل خاصية رفع الملفات في مشاريعك البرمجية بواسطة السحب والإفلات مع إمكانية عرض مصغرات للصور المرفوعة وعرض بعض معلومات  الملف المرفوع مثل اسم الملف و حجم الملف وعند اكتمال التحميل سوف تظهر لك ايقونة بعلامة صح✔️ اما اذا حدث خطأ فستحصل على ايقونة بعلامة خطأ✖️تسطيع عن طريق المكتبة توليد حقل بهذا الشكل 

    آلية عمل DropzoneJS
    عند استخدام المكتبة مع أحد النماذج لديك وتوليد حقل رفع الملفات فإنه سيتم إنشاء مربع خاص بسحب وإفلات الملفات المراد تحميلها بداخله عندها ستقوم المكتبة باخذ الملفات ومعلوماتها وإرسال امر اجاكس AJAX إلى موقعك لتقوم انت بوضع آلية لإستقبال ورفع الملفات لموقعك باي لغات برمجة المواقع مثل PHP
    طريقة إستخدام DropzoneJS
    قم بتحميل آخر إصدار عن طريق هذا الرابط >> Download << وبعد انتهاء عملية التحميل داخل مجلد المكتبة يوجد مجلد بإسم dist وبداخله اهم ملفين dropzone.css و dropzone.js قم بتضمين الملفين داخل صفحتك بواسطة 
    <script src="dropzone.js"></script> <link rel="stylesheet" href="dropzone.css"> وبعدها قم بإنشاء نموذج Form وقم بتحديد action و class و id ليسهل التعامل مع النموذج بكل سهولة بمجرد ان تقوم بوضع dropzone داخل class فإن المكتبة ستتعرف على النموذج وتقوم بإدراج حقل رفع الملفات بشكل آلي للنموذج مثال للنموذج كالتالي 
    <form action="file-upload.php" class="dropzone" id="my-awesome-dropzone"> </form> لو توجهت للمتصفح فإن الناتج سيكون كالتالي 

    إذا كنت ترغب بإضافة نص داخل المربع توضح للمستخدم كيفية الإستخدام تختفي بمجرد ان يقوم المستخدم بإفلات ملف لتحميله تستطيع بكل سهولة بإضافة div داخل النموذج وحدد له class باسم dz-message ليصبح كود النموذج كالتالي
    <form action="file-upload.php" class="dropzone" id="my-awesome-dropzone"> <div class="dz-message"> Drop files here or click to upload.<br> <span class="note"> (This is just a demo dropzone. Selected files are <strong>not</strong> actually uploaded.) </span> </div> </form> بعدها تستطيع التحكم بشكل الحقل كما تريد عن طريق CSS فلو ترغب ان يكون شكل النموذج نفس الشكل الذي بموقع المكتبة كل ماعليك هو إنشاء ملف css جديد لنفرض ان اسم الملف basic.css وقم بوضع هذا الكود باخله
    #dropzone { margin-bottom: 3rem; } .dropzone { border: 2px dashed #0087F7; border-radius: 5px; background: white; } .dropzone .dz-message { font-weight: 400; } .dropzone .dz-message .note { font-size: 0.8em; font-weight: 200; display: block; margin-top: 1.4rem; } بعدها قم بتضمين الملف داخل الصفحة باستخدام 
    <link rel="stylesheet" href="basic.css"> ليصبح شكل النموذج بالمتصفح كالتالي 

    كما تستطيع عمل حقل احتياطي لتحميل الملفات في حالة تم تعطيل عمل JavaScript بالمتصفح باستخدام هذا الكود داخل النموذج 
    <div class="fallback"> <input name="file" type="file" multiple /> </div> حيث انه اذا كانت المكتبة تعمل بدون مشاكل فإنه سيتم حذف الحقل الإحتياطي مباشرة وعرض مربع المكتبة وتضمين حقل تحميل الملفات تلقائيا للمنوذج 
    هذه ابسط طرق عمل حقل تحميل الملفات بالسحب والإفلات عن طريق HTML و لكن ان كنت ترغب بإنشاء النموذج عن طريق Javascript فتسطيع عن طريق هذا الأمر إنشاء النموذج و حقل تحميل الملفات و تحديد رابط action لإرسال الملفات لكي يتم تحميلها للسيرفر 
    // Dropzone class: var myDropzone = new Dropzone("div#myId", { url: "/file/post"}); ايضا تستطيع عن طريق استخدام Jquery بواسطة هذا الأمر 
    // jQuery $("div#myId").dropzone({ url: "/file/post" }); التحكم بخصائص المكتبة 
    تسطيع وبكل سهولة التحكم بجميع خصائص المكتبة عن طريق JavaScript مثلا تسطيع تغير اسم المتغير المستخدم عند إنشاء حقل تحميل الملفات إفتراضيا يكون اسم المتغير file وتسطيع تغييره لما يناسبك او تسطيع اضافة action url إذا لم يتم تعريف action داخل النموذج ومن الممكن تحديد حجم الملفات المراد تحميلها قبل إرسالها للسيرفر ومن الممكن السماح لرفع مجموعة ملفات دفعة واحدة للسيرفر او لا تسطيع زيارة موقع المكتبة وتصفح جميع خيارات التحكم بالمكتبة
    نسطتيع التحكم بجميع الخيارات عن طريق استهداف اسم المعرف للنموذج id بعدما نقوم بتغيير المسمى ودمج الكلمات ان وجدت واستخدام camelized version من الإسم ونستخدم Dropzone.options.idName لتحديد جميع الإعدادات مثلا 
    // "myAwesomeDropzone" is the camelized version of the HTML element's ID Dropzone.options.myAwesomeDropzone = { paramName: "file", // The name that will be used to transfer the file maxFilesize: 2, // MB }; تحميل الملفات للسيرفر 
    عمل المكتبة هو إنشاء واجهة جميلة ومنسقة وتسهيل عملية رفع الملفات عن طريق سحبهم وإفلاتهم داخل مربع ثم عرض مصغرات لهم ولكن يجب ان تقوم انت ببرمجة طريقة رفعهم الفعلية للسيرفر باستخدام إحدى اللغات التي تتعامل مع السيرفرات مثل PHP المكتبة سوف تقوم بأخذ الملفات وإرسال طلب اجاكس AJAX Request الى عنوان action الذي قمت بتحديده داخل النموذج حيث ان جميع الملفات سوف تكون تحت اسم المتغير file مالم تقم انت بتغييره تسطيع زيارة موقع المكتبة حيث يوجد الكثير من روابط الدروس لطريقة برمجة آلية رفع الملفات للسيرفر بعدة لغات عن طريق هذا الرابط server side implementation
    مستوى المقال: مبتدئ

عالم البرمجة

عالم البرمجة مقالات برمجة و دورات مجانية لإحتراف البرمجة هدفنا تبسيط البرمجة ونشرها بيد الكل بشكل ممتع ومتطور ومحدث بإستمرار لمواكبة جديد تطورات البرمجة الحديثة و المتقدمة بدون مقابل