Everything you always wanted to know about forms* *but were afraid to askAndrea Giuliano
La componente dei Form di Symfony2 rende possibile la costruzione di diverse tipologie di form in modo del tutto semplice. La sua architettura flessibile e altamente scalabile permette di poter gestire strutture adatte ad ogni tipo di esigenza. Tuttavia, conoscere come utilizzare appieno tutta la sua potenza non è banale. In questo talk verrà trattato in profondità la componente Form di Symfony2, mostrando i suoi meccanismi di base e come utilizzarli per estenderli ed introdurre la propria logica di business, così da costruire form cuciti a misura delle tue necessità.
Everything you always wanted to know about forms* *but were afraid to askAndrea Giuliano
La componente dei Form di Symfony2 rende possibile la costruzione di diverse tipologie di form in modo del tutto semplice. La sua architettura flessibile e altamente scalabile permette di poter gestire strutture adatte ad ogni tipo di esigenza. Tuttavia, conoscere come utilizzare appieno tutta la sua potenza non è banale. In questo talk verrà trattato in profondità la componente Form di Symfony2, mostrando i suoi meccanismi di base e come utilizzarli per estenderli ed introdurre la propria logica di business, così da costruire form cuciti a misura delle tue necessità.
Forms are inevitable. Forms are hard. Forms with React sometimes even harder. In this talk, we’ll start by exploring best practices to efficiently work with react/redux forms and proceed with building a custom abstraction layer for easier form management.
Most iOS apps use one or more UITableViews for at least some portion of their user interface. Unfortunately, UITableViewController code can often be home to monstrous if/else constructs employed to handle cell configuration and user interaction. This talk will illustrate the typical issues encountered with table view code. Whether form-like table views with a fixed number of rows, such as those found in settings views or those used to edit object data, or dynamic tables with multiple sections and rows within each section, you'll learn how to produce concise, readable, and powerful code.
Hacking Your Way to Better Security - PHP South Africa 2016Colin O'Dell
This talk educates developers on common security vulnerabilities, how they are exploited, and how to protect against them. We'll explore several of the OWASP Top 10 attack vectors like SQL injection, XSS, CSRF, and more. Each topic will be approached from the perspective of an attacker to see how these vulnerabilities are detected and exploited using several realistic examples. We'll then apply this knowledge to see how web applications can be secured against such vulnerabilities.
The goal of this talk is to educate developers on common security vulnerabilities, how they are exploited, and how to protect against them. We'll explore several of the OWASP Top 10 attack vectors like SQL injection, XSS, CSRF, session hijacking, and insecure direct object references. Each topic will be approached from the perspective of an attacker to see how these vulnerabilities are detected and exploited using several realistic examples. Once we've established an understanding of how these attacks work, we'll look at concrete steps you can take to secure web applications against such vulnerabilities. The knowledge gained from this talk can also be used for participating in "Capture the Flag" security competitions.
n 2010, I told everyone how to start unit testing Zend Framework applications. In 2011, let’s take this a step further by testing services, work flows and performance. Looking to raise the bar on quality? Let this talk be the push you need to improve your Zend Framework projects.
Forms are inevitable. Forms are hard. Forms with React sometimes even harder. In this talk, we’ll start by exploring best practices to efficiently work with react/redux forms and proceed with building a custom abstraction layer for easier form management.
Most iOS apps use one or more UITableViews for at least some portion of their user interface. Unfortunately, UITableViewController code can often be home to monstrous if/else constructs employed to handle cell configuration and user interaction. This talk will illustrate the typical issues encountered with table view code. Whether form-like table views with a fixed number of rows, such as those found in settings views or those used to edit object data, or dynamic tables with multiple sections and rows within each section, you'll learn how to produce concise, readable, and powerful code.
Hacking Your Way to Better Security - PHP South Africa 2016Colin O'Dell
This talk educates developers on common security vulnerabilities, how they are exploited, and how to protect against them. We'll explore several of the OWASP Top 10 attack vectors like SQL injection, XSS, CSRF, and more. Each topic will be approached from the perspective of an attacker to see how these vulnerabilities are detected and exploited using several realistic examples. We'll then apply this knowledge to see how web applications can be secured against such vulnerabilities.
The goal of this talk is to educate developers on common security vulnerabilities, how they are exploited, and how to protect against them. We'll explore several of the OWASP Top 10 attack vectors like SQL injection, XSS, CSRF, session hijacking, and insecure direct object references. Each topic will be approached from the perspective of an attacker to see how these vulnerabilities are detected and exploited using several realistic examples. Once we've established an understanding of how these attacks work, we'll look at concrete steps you can take to secure web applications against such vulnerabilities. The knowledge gained from this talk can also be used for participating in "Capture the Flag" security competitions.
n 2010, I told everyone how to start unit testing Zend Framework applications. In 2011, let’s take this a step further by testing services, work flows and performance. Looking to raise the bar on quality? Let this talk be the push you need to improve your Zend Framework projects.
When you move beyond adding simple enhancements to your website with jQuery and start building full-blown client-side applications, how do you organize your code? At this month's Triangle JS Meetup, we'll take a look at patterns for application development using jQuery that promote the principles of tight encapsulation and loose coupling, including classes, the publish/subscribe paradigm, and dependency management and build systems.
Ever wondered how to get rid of that spaghetti, single-filed JavaScript code? Wouldn't it be nice if you could write maintainable modules, easily test them, port them to different projects, handle its library dependencies, and have them decoupled from other modules?
In this talk, we'll see how using the AMD API and an event-driven design will help taming an application's JavaScript code and scaling it to the future and beyond.
Slides from the presentation given at Future of Web Design 2012 in London, 14th-16th May.
Session description:
"Are you new to jQuery? Maybe you’ve been using it for a while? Regardless of your skillset or previous experience, join Matt Gifford, developer, author, speaker and lover of jQuery, as he reviews why you should be using it, how not to use it, and some vital tips to assist your jQuery development as well as some common pitfalls to watch out for."
Programmation fonctionnelle en JavaScriptLoïc Knuchel
La programmation fonctionnelle permet de faire du code plus modulaire, avec moins de bugs et de manière plus productive !!!
Cette présentation montre comment la programmation fonctionnelle peut tenir se promesse et comment l'appliquer avec JavaScript.
i am unsure how to make the button below the image instead of on it- a.pdfMattU5mLambertq
i am unsure how to make the button below the image instead of on it, as well as when it is added
to the favourites it shows as undefined instead of the actual picture.
Here is the Javascript code used:
"use strict";
/* JavaScript 7th Edition
Chapter 5
Chapter Case
Application to generate a slide show
Author:
Date:
Filename: js05.js
*/
window.addEventListener("load", setupGallery);
function setupGallery() {
let imageCount = imgFiles.length;
let galleryBox = document.getElementById("lightbox");
let currentSlide = 1;
let runShow = true;
let showRunning;
let galleryTitle = document.createElement("h1");
galleryTitle.id = "galleryTitle";
let slidesTitle = lightboxTitle; // TODO figure out title
galleryTitle.textContent = slidesTitle;
galleryBox.appendChild(galleryTitle);
let slideCounter = document.createElement("div");
slideCounter.id = "slideCounter";
slideCounter.textContent = currentSlide + "/" + imageCount;
galleryBox.appendChild(slideCounter);
let leftBox = document.createElement("div");
leftBox.id = "leftBox";
leftBox.innerHTML = "◀";
leftBox.onclick = moveToLeft;
galleryBox.appendChild(leftBox);
let rightBox = document.createElement("div");
rightBox.id = "rightBox";
rightBox.innerHTML = "▶";
rightBox.onclick = moveToRight;
galleryBox.appendChild(rightBox);
let playPause = document.createElement("div");
playPause.id = "playPause";
playPause.innerHTML = "⏯";
playPause.onclick = startStopShow;
galleryBox.appendChild(playPause);
let slideBox = document.createElement("div");
slideBox.id = "slideBox";
galleryBox.appendChild(slideBox);
for (let i = 0; i < imageCount; i++) {
let image = document.createElement("img");
image.src = imgFiles[i];
image.alt = imgCaptions[i];
image.onclick = createModal;
slideBox.appendChild(image);
}
function moveToRight() {
let firstImage = slideBox.firstElementChild.cloneNode("true");
firstImage.onclick = createModal;
slideBox.appendChild(firstImage);
slideBox.removeChild(slideBox.firstElementChild);
currentSlide++;
if (currentSlide > imageCount) {
currentSlide = 1;
}
slideCounter.textContent = currentSlide + " / " + imageCount;
}
function moveToLeft() {
let lastImage = slideBox.lastElementChild.cloneNode("true");
lastImage.onclick = createModal;
slideBox.removeChild(slideBox.lastElementChild);
slideBox.insertBefore(lastImage, slideBox.firstElementChild);
currentSlide--;
if (currentSlide === 0) {
currentSlide = imageCount;
}
slideCounter.textContent = currentSlide + " / " + imageCount;
}
function startStopShow() {
if (runShow) {
showRunning = window.setInterval(moveToRight, 2000);
runShow = false;
} else {
window.clearInterval(showRunning);
runShow = true;
}
}
}
function createModal() {
let modalWindow = document.createElement("div");
modalWindow.id = "lbOverlay";
let figureBox = document.createElement("figure");
modalWindow.appendChild(figureBox);
let modalImage = this.cloneNode("true");
figureBox.appendChild(modalImage);
let figureCaption = document.createElement("figcaption");
figureCaption.textCon.
jQuery & 10,000 Global Functions: Working with Legacy JavaScriptGuy Royse
Long ago, in the late days of the first Internet boom, before jQuery, before Underscore, before Angular, there was a web application built by a large corporation. This application was written as a server-side application using server-side technology like Java or PHP. A tiny seed of JavaScript was added to some of the pages of this application to give it a little sizzle.
Over the ages, this tiny bit of JavaScript grew like kudzu. Most of it was embedded in the HTML in
6 reasons Jubilee could be a Rubyist's new best friendForrest Chang
(Video here: http://confreaks.com/videos/5014-RubyConf2014-6-reasons-jubilee-could-be-a-rubyist-s-new-best-friend or https://www.youtube.com/watch?feature=player_embedded&v=FFR0G89WXI8)
Rubyconf 2014 talk on Jubilee, a Vert.x module that runs rack apps.
Alternate titles
Beyond Rails while using Rails
Rails can't do everything I want and <fill> makes me want to cry
Rubyconf abstract
Do you do web development in Ruby? Have you been forced to go to node or other technologies just for concurrency/websockets etc. Do miss your gems, and tire of functionality you have to implement from scratch? Do you hate javascript?
Well no need to switch languages/platforms, Jubilee could be your new best friend.
Jubilee, a rack server on top of Vert.x gives you
* Concurrency
* Speed
* Easy Websockets support
* Shared Memory
* Access to the JVM ecosystem
* Ability to reuse your existing Ruby knowledge and gems
"Say Hello to your new friend" - Al Pacino
Rubyconf 2013 presentation on Opal - Ruby in the browser. A New Hope for Ruby Programmers. Actual presentation has a ton of sound and video. I'll post the confreaks link when it's available.
Update 2: link with sound, then a link to the rest of the video - https://vimeo.com/82573680
Update 1: Confreaks link. http://confreaks.com/videos/2904-rubyconf2013-opal-a-new-hope-for-ruby-programmers - They had to mute the star wars music coz youtube would reject all the sound. I'll see what can be done about that
AI Pilot Review: The World’s First Virtual Assistant Marketing SuiteGoogle
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
👉👉 Click Here To Get More Info 👇👇
https://sumonreview.com/ai-pilot-review/
AI Pilot Review: Key Features
✅Deploy AI expert bots in Any Niche With Just A Click
✅With one keyword, generate complete funnels, websites, landing pages, and more.
✅More than 85 AI features are included in the AI pilot.
✅No setup or configuration; use your voice (like Siri) to do whatever you want.
✅You Can Use AI Pilot To Create your version of AI Pilot And Charge People For It…
✅ZERO Manual Work With AI Pilot. Never write, Design, Or Code Again.
✅ZERO Limits On Features Or Usages
✅Use Our AI-powered Traffic To Get Hundreds Of Customers
✅No Complicated Setup: Get Up And Running In 2 Minutes
✅99.99% Up-Time Guaranteed
✅30 Days Money-Back Guarantee
✅ZERO Upfront Cost
See My Other Reviews Article:
(1) TubeTrivia AI Review: https://sumonreview.com/tubetrivia-ai-review
(2) SocioWave Review: https://sumonreview.com/sociowave-review
(3) AI Partner & Profit Review: https://sumonreview.com/ai-partner-profit-review
(4) AI Ebook Suite Review: https://sumonreview.com/ai-ebook-suite-review
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...Globus
Large Language Models (LLMs) are currently the center of attention in the tech world, particularly for their potential to advance research. In this presentation, we'll explore a straightforward and effective method for quickly initiating inference runs on supercomputers using the vLLM tool with Globus Compute, specifically on the Polaris system at ALCF. We'll begin by briefly discussing the popularity and applications of LLMs in various fields. Following this, we will introduce the vLLM tool, and explain how it integrates with Globus Compute to efficiently manage LLM operations on Polaris. Attendees will learn the practical aspects of setting up and remotely triggering LLMs from local machines, focusing on ease of use and efficiency. This talk is ideal for researchers and practitioners looking to leverage the power of LLMs in their work, offering a clear guide to harnessing supercomputing resources for quick and effective LLM inference.
Unleash Unlimited Potential with One-Time Purchase
BoxLang is more than just a language; it's a community. By choosing a Visionary License, you're not just investing in your success, you're actively contributing to the ongoing development and support of BoxLang.
Globus Compute wth IRI Workflows - GlobusWorld 2024Globus
As part of the DOE Integrated Research Infrastructure (IRI) program, NERSC at Lawrence Berkeley National Lab and ALCF at Argonne National Lab are working closely with General Atomics on accelerating the computing requirements of the DIII-D experiment. As part of the work the team is investigating ways to speedup the time to solution for many different parts of the DIII-D workflow including how they run jobs on HPC systems. One of these routes is looking at Globus Compute as a way to replace the current method for managing tasks and we describe a brief proof of concept showing how Globus Compute could help to schedule jobs and be a tool to connect compute at different facilities.
Listen to the keynote address and hear about the latest developments from Rachana Ananthakrishnan and Ian Foster who review the updates to the Globus Platform and Service, and the relevance of Globus to the scientific community as an automation platform to accelerate scientific discovery.
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...Anthony Dahanne
Les Buildpacks existent depuis plus de 10 ans ! D’abord, ils étaient utilisés pour détecter et construire une application avant de la déployer sur certains PaaS. Ensuite, nous avons pu créer des images Docker (OCI) avec leur dernière génération, les Cloud Native Buildpacks (CNCF en incubation). Sont-ils une bonne alternative au Dockerfile ? Que sont les buildpacks Paketo ? Quelles communautés les soutiennent et comment ?
Venez le découvrir lors de cette session ignite
top nidhi software solution freedownloadvrstrong314
This presentation emphasizes the importance of data security and legal compliance for Nidhi companies in India. It highlights how online Nidhi software solutions, like Vector Nidhi Software, offer advanced features tailored to these needs. Key aspects include encryption, access controls, and audit trails to ensure data security. The software complies with regulatory guidelines from the MCA and RBI and adheres to Nidhi Rules, 2014. With customizable, user-friendly interfaces and real-time features, these Nidhi software solutions enhance efficiency, support growth, and provide exceptional member services. The presentation concludes with contact information for further inquiries.
May Marketo Masterclass, London MUG May 22 2024.pdfAdele Miller
Can't make Adobe Summit in Vegas? No sweat because the EMEA Marketo Engage Champions are coming to London to share their Summit sessions, insights and more!
This is a MUG with a twist you don't want to miss.
Enhancing Research Orchestration Capabilities at ORNL.pdfGlobus
Cross-facility research orchestration comes with ever-changing constraints regarding the availability and suitability of various compute and data resources. In short, a flexible data and processing fabric is needed to enable the dynamic redirection of data and compute tasks throughout the lifecycle of an experiment. In this talk, we illustrate how we easily leveraged Globus services to instrument the ACE research testbed at the Oak Ridge Leadership Computing Facility with flexible data and task orchestration capabilities.
In software engineering, the right architecture is essential for robust, scalable platforms. Wix has undergone a pivotal shift from event sourcing to a CRUD-based model for its microservices. This talk will chart the course of this pivotal journey.
Event sourcing, which records state changes as immutable events, provided robust auditing and "time travel" debugging for Wix Stores' microservices. Despite its benefits, the complexity it introduced in state management slowed development. Wix responded by adopting a simpler, unified CRUD model. This talk will explore the challenges of event sourcing and the advantages of Wix's new "CRUD on steroids" approach, which streamlines API integration and domain event management while preserving data integrity and system resilience.
Participants will gain valuable insights into Wix's strategies for ensuring atomicity in database updates and event production, as well as caching, materialization, and performance optimization techniques within a distributed system.
Join us to discover how Wix has mastered the art of balancing simplicity and extensibility, and learn how the re-adoption of the modest CRUD has turbocharged their development velocity, resilience, and scalability in a high-growth environment.
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...informapgpstrackings
Keep tabs on your field staff effortlessly with Informap Technology Centre LLC. Real-time tracking, task assignment, and smart features for efficient management. Request a live demo today!
For more details, visit us : https://informapuae.com/field-staff-tracking/
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...Globus
The U.S. Geological Survey (USGS) has made substantial investments in meeting evolving scientific, technical, and policy driven demands on storing, managing, and delivering data. As these demands continue to grow in complexity and scale, the USGS must continue to explore innovative solutions to improve its management, curation, sharing, delivering, and preservation approaches for large-scale research data. Supporting these needs, the USGS has partnered with the University of Chicago-Globus to research and develop advanced repository components and workflows leveraging its current investment in Globus. The primary outcome of this partnership includes the development of a prototype enterprise repository, driven by USGS Data Release requirements, through exploration and implementation of the entire suite of the Globus platform offerings, including Globus Flow, Globus Auth, Globus Transfer, and Globus Search. This presentation will provide insights into this research partnership, introduce the unique requirements and challenges being addressed and provide relevant project progress.
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...Globus
The Earth System Grid Federation (ESGF) is a global network of data servers that archives and distributes the planet’s largest collection of Earth system model output for thousands of climate and environmental scientists worldwide. Many of these petabyte-scale data archives are located in proximity to large high-performance computing (HPC) or cloud computing resources, but the primary workflow for data users consists of transferring data, and applying computations on a different system. As a part of the ESGF 2.0 US project (funded by the United States Department of Energy Office of Science), we developed pre-defined data workflows, which can be run on-demand, capable of applying many data reduction and data analysis to the large ESGF data archives, transferring only the resultant analysis (ex. visualizations, smaller data files). In this talk, we will showcase a few of these workflows, highlighting how Globus Flows can be used for petabyte-scale climate analysis.
First Steps with Globus Compute Multi-User EndpointsGlobus
In this presentation we will share our experiences around getting started with the Globus Compute multi-user endpoint. Working with the Pharmacology group at the University of Auckland, we have previously written an application using Globus Compute that can offload computationally expensive steps in the researcher's workflows, which they wish to manage from their familiar Windows environments, onto the NeSI (New Zealand eScience Infrastructure) cluster. Some of the challenges we have encountered were that each researcher had to set up and manage their own single-user globus compute endpoint and that the workloads had varying resource requirements (CPUs, memory and wall time) between different runs. We hope that the multi-user endpoint will help to address these challenges and share an update on our progress here.
Large Language Models and the End of ProgrammingMatt Welsh
Talk by Matt Welsh at Craft Conference 2024 on the impact that Large Language Models will have on the future of software development. In this talk, I discuss the ways in which LLMs will impact the software industry, from replacing human software developers with AI, to replacing conventional software with models that perform reasoning, computation, and problem-solving.
Understanding Globus Data Transfers with NetSageGlobus
NetSage is an open privacy-aware network measurement, analysis, and visualization service designed to help end-users visualize and reason about large data transfers. NetSage traditionally has used a combination of passive measurements, including SNMP and flow data, as well as active measurements, mainly perfSONAR, to provide longitudinal network performance data visualization. It has been deployed by dozens of networks world wide, and is supported domestically by the Engagement and Performance Operations Center (EPOC), NSF #2328479. We have recently expanded the NetSage data sources to include logs for Globus data transfers, following the same privacy-preserving approach as for Flow data. Using the logs for the Texas Advanced Computing Center (TACC) as an example, this talk will walk through several different example use cases that NetSage can answer, including: Who is using Globus to share data with my institution, and what kind of performance are they able to achieve? How many transfers has Globus supported for us? Which sites are we sharing the most data with, and how is that changing over time? How is my site using Globus to move data internally, and what kind of performance do we see for those transfers? What percentage of data transfers at my institution used Globus, and how did the overall data transfer performance compare to the Globus users?
2. A JQUERY STORYA JQUERY STORY
Have a problem
Add a little jQuery
Fixed, yay!
3. AS TIME GOES ONAS TIME GOES ON
Add function, add function, nest function
Insert event handlers in DOM
Add business logic
Get input, dialogs
Ajax
Effects
Update DOM
Assign handlers to id
etc.
5. JQUERY SPAGHETTIJQUERY SPAGHETTI
by Steve O'Brien in http://steve-obrien.com/javascript-jquery-spaghetti/
Without a strong framework or architecture you end up
with jQuery spaghetti. This is usually because you start
with a small piece of jquery shoved somewhere in the dom
as you add features it all grows out of proportion and
becomes a tangled mess. The most challenging thing is
maintaining state. Relying heavily on jQuery means your
application state information is stores in the dom, this
works well for small features and isolated components
here and there, but in a complex app it quickly becomes
very difficult to manage.
6. JQUERY SPAGHETTI IS JSAPABO #1JQUERY SPAGHETTI IS JSAPABO #1
JavaScript AntiPatterns Addressed by Opal (JSAPABO)
There are anti patterns addressed by Opal - trying to codify why Opal
makes browser code better, starting w/naming what's wrong
Very much a Work In Progress, apologies
http://funkworks.blogspot.com/2015/04/javascript-antipatterns-
addressed-by.html
7. OPAL CAN HELPOPAL CAN HELP
What is Opal? TLDR; Ruby in the browser
How can it help?
Ruby > JS
Culture, Conventions
OOP
and More!
See here for more info
8. REAL LIFE STORYREAL LIFE STORY
Want slide out bar
Need both Left and right slide bars
Would like simple, low cruft
Demo of finished product
11. HOW ABOUT THE RIGHT SIDEBAR? MY SPIKEHOW ABOUT THE RIGHT SIDEBAR? MY SPIKE
$.asm2 = {};
$.asm2.panels = 1;
function sidebar2(panels) {
$.asm2.panels = panels;
if (panels === 1) {
$('#sidebar-right').animate({
right: -780,
});
} else if (panels === 2) {
$('#sidebar-right').animate({
right: 20,
});
$('#mapCanvas').width($('#mapCanvas').parent().width());
$('#mapCanvas').height($(window).height() - 50);
$('#sidebar-right').height($(window).height() - 50);
}
};
$(function() {
$('#toggleSidebar-right').click(function() {
if ($.asm2.panels === 1) {
$('#toggleSidebar-right i').removeClass('glyphicon-chevron-left');
$('#toggleSidebar-right i').addClass('glyphicon-chevron-right');
return sidebar2(2);
} else {
$('#toggleSidebar-right i').addClass('glyphicon-chevron-left');
$('#toggleSidebar-right i').removeClass('glyphicon-chevron-right');
return sidebar2(1);
}
});
});
12. KINDA UGLY CODEKINDA UGLY CODE
Original code for a jsfiddle - don't expect a lot
Typical for jQuery examples
by itself not bad. NOT good OO code
Now that concept has been proven, time to make the code "real"
13. HOW TO CONVERT?HOW TO CONVERT? JUST TRANSLATE?JUST TRANSLATE?
Didn't like it from the beginning
Document.ready? {
Element.find('#toggleSidebar').on :click {
}
}
14. MIRED IN THE DETAILSMIRED IN THE DETAILS
JSAPABO #6 Stuck in the weeds
What's the big picture
What's my intent?
16. SEGUESEGUE
Reasons Opal Makes your Browser Code Better #1 (ROMYBCB) - a future
blog series
In Ruby, we Think in Objects
So Start w/objects
17. HOW I WANT TO USE IT?HOW I WANT TO USE IT?
# Create w/intent
left_sidebar = Sidebar.new('#toggleSidebar', 'left')
# elsewhere manipulate
left_sidebar.hide
19. CONVERTING THE JS CLICK HANDLERCONVERTING THE JS CLICK HANDLER
// original code
$(function() {
$('#toggleSidebar').click(function() {
if ($.asm.panels === 1) {
$('#toggleSidebar i').addClass('glyphicon-chevron-left');
$('#toggleSidebar i').removeClass('glyphicon-chevron-right');
return sidebar(2);
} else {
$('#toggleSidebar i').removeClass('glyphicon-chevron-left');
$('#toggleSidebar i').addClass('glyphicon-chevron-right');
return sidebar(1);
}
});
});
WHAT DOES IT DO?WHAT DOES IT DO?
if $.asm.panels = 1 // magic number 1 = closed state
make sidebar handle left facing left
sidebar(2) // set sidebar state to 2 (open state) - slide out
else
make sidebar handle face right
sidebar(1) // set sidebar state to 2 (closed state) - slide in
20. WHAT DOES IT DO AT A HIGHER LEVELWHAT DOES IT DO AT A HIGHER LEVEL
step away from the details (JSAPABO #6)
If the slider is open close it
else open it
21. OPAL CLICK HANDLER WITH INTENTION REVEALEDOPAL CLICK HANDLER WITH INTENTION REVEALED
Put it in #initialize(), so it happens for each instance
class Sidebar
def initialize(element_id, side)
@state = :closed
Element.find(element_id).on :click {
if @state == :open
close
else
open
end
}
end
end
22. WHERE TO HANG THE STATE?WHERE TO HANG THE STATE?
JSAPABO #5
Where do you put state?
Coz not using objects, where put state? Global?
In jQuery, can hang off of jQuery
$.asm.panels // hung off of jQuery
Where would you hang data in Ruby/Opal
instance variable, because you use objects from the get go
easy
@state = :closed
23. IMPLEMENT OPEN AND CLOSE, ROUND 1IMPLEMENT OPEN AND CLOSE, ROUND 1
def open
icon = Element.find("#{element_id} i")
icon.add_class('glyphicon-chevron-left')
icon.remove_class('glyphicon-chevron-right')
Element.find('#sidebar').animate left: 20
@state = :open
end
def close
icon = Element.find("#{element_id} i")
icon.remove_class('glyphicon-chevron-left')
icon.add_class('glyphicon-chevron-right')
Element.find('#sidebar').animate left: -180
@state = :close
end
24. ROUND 2: REMOVE DUPLICATIONROUND 2: REMOVE DUPLICATION
def open
set_icon('glyphicon-chevron-left', 'glyphicon-chevron-right')
Element.find('#sidebar').animate left: 20
@state = :open
end
def set_icon(class_to_add, class_to_remove)
icon = Element.find("#{element_id} i")
icon.add_class(class_to_add)
icon.remove_class(class_to_remove)
end
def close
set_icon('glyphicon-chevron-right', 'glyphicon-chevron-left')
Element.find('#sidebar').animate left: -180
@state = :closed
end
25. ROUND 3: REFACTOR MORE DUPLICATIONROUND 3: REFACTOR MORE DUPLICATION
def open
set_icon('glyphicon-chevron-left', 'glyphicon-chevron-right', 20)
@state = :open
end
def set_icon(class_to_add, class_to_remove, new_position)
icon = Element.find("#{element_id} i")
icon.add_class(class_to_add)
icon.remove_class(class_to_remove)
Element.find('#sidebar').animate left: new_position
end
def close
set_icon('glyphicon-chevron-right', 'glyphicon-chevron-left', -180)
@state = :closed
end
26. YET ANOTHER PATTERNYET ANOTHER PATTERN
There's another pattern- the state change, so we move that functionality into
set_icon
def open
set_icon('glyphicon-chevron-left', 'glyphicon-chevron-right', 20, :open)
end
def set_icon(class_to_add, class_to_remove, new_position, new_state)
icon = Element.find("#{element_id} i")
icon.add_class(class_to_add)
icon.remove_class(class_to_remove)
Element.find('#sidebar').animate left: new_position
@state = new_state
end
def close
set_icon('glyphicon-chevron-right', 'glyphicon-chevron-left', -180, :closed)
end
27. NEED A NEW NAMENEED A NEW NAME
set_icon() no longer describes what it's doing
def open
new_state('glyphicon-chevron-left', 'glyphicon-chevron-right', 20, :open)
end
def new_state(class_to_add, class_to_remove, new_position, new_state)
icon = Element.find("#{element_id} i")
icon.add_class(class_to_add)
icon.remove_class(class_to_remove)
Element.find('#sidebar').animate left: new_position
@state = new_state
end
def close
new_state('glyphicon-chevron-right', 'glyphicon-chevron-left', -180, :closed)
end
28. OPAL CODE THAT MATCHES THE JSFIDDLEOPAL CODE THAT MATCHES THE JSFIDDLE
# Sidebar abstraction
class Sidebar
attr_reader :element_id
def initialize(element_id, side)
@element_id = element_id
@state = :closed
Element.find("#{element_id} .toggles").on :click do
if @state == :open
close
else
open
end
end
end
def open
new_state('glyphicon-chevron-left', 'glyphicon-chevron-right', 20, :open)
end
def new_state(class_to_add, class_to_remove, new_position, new_state)
icon = Element.find("#{element_id} i")
icon.add_class(class_to_add)
icon.remove_class(class_to_remove)
Element.find("#{element_id}").animate left: new_position
@state = new_state
end
def close
new_state('glyphicon-chevron-right', 'glyphicon-chevron-left', -180, :closed)
end
end
Document.ready? {
left_sidebar = Sidebar.new('#sidebar', 'left')
}
29. CODE IS BETTERCODE IS BETTER
About same lines of code (LOC)
More intention revealing
Code can be reused/repurposed
Can programmaticaly open or close sidebar easily, i.e. left_sidebar.open
Couldn't do that w/original code WITHOUT refactoring
30. STILL NEED A RIGHT SIDEBARSTILL NEED A RIGHT SIDEBAR
Begin w/the end in mind
Document.ready? {
left_sidebar = Sidebar.new('#sidebar', 'left')
right_sidebar = Sidebar.new('#sidebar-right', 'right)
}
32. NOTESNOTES
Because of JSAPABO #5, needed to store right panel state
Can't use $.asm.panels, cut and paste $.asm2
What if I want a dropdown, $.asm3 ?
Not a problem if dealing with objects from the get go