Webアプリケーション開発

こんにちは、Habr!



Ext JSとJavaの技術を研究しながら、彼はWebアプリケーション「Car Catalog」を作成しました。 この経験を皆さんと共有したいと思います。



アプリビューと機能









追加と検証










編集中






検索する








ツール



  1. IntelliJ IDEA 13の ダウンロード
  2. Ext JS 5.0.1 ダウンロード
  3. Apache Tomcat 8.0.12の ダウンロード
  4. MySQL 5.6.20 ダウンロード
  5. Apache Maven 3.0.5 ダウンロード
  6. Java 1.8.0_20 ダウンロード
  7. Java doc read
  8. Ext JSガイドを 読む
  9. 休止状態の 読み取り
  10. JPA 読み取り
  11. 春の 読書
  12. SQL 読み取り
  13. MVC 読み取り
  14. DAO 読み取り
  15. レイヤーサービスの 読み取り
  16. デプロイメント記述子の 読み取り




プロジェクト作成


Project SDKでJavaパスを指定します。





Mavenホームディレクトリへのパスを指定します。





「Mavenプロジェクトをインポートする必要があります」「自動インポートを有効にする」をクリックします





サーバーを追加する
Tomcatサーバーを追加します。









アプリケーションサーバーで、Tomcatサーバーへのパスを指定します。







OK->適用-> OK



すべてが機能することを確認します。











クライアント(ExtJS)



Ext JSフレームワークファイルを追加します。





Ext JS MVCモデル:





app.jsファイルを作成します。





app.js

Ext.application({ name: 'CarCatalog', launch: function () { Ext.create('Ext.container.Viewport', { layout: 'fit', items: { xtype: 'panel', html: '<h2> </h2>' } }); } });
      
      







index.jspファイルで、Ext JSスタイル、次にExt JSフレームワーク、そしてapp.jsのみを接続します。

 <%@page contentType="text/html" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title></title> <link rel="stylesheet" type="text/css" href="resources/packages/ext-theme-neptune/build/resources/ext-theme-neptune-all.css"/> <script type="text/javascript" src="resources/ext-all.js"></script> <script type="text/javascript" src="resources/packages/ext-theme-neptune/build/ext-theme-neptune.js"></script> <script type="text/javascript" src="app.js"></script> </head> <body> </body> </html>
      
      







すべてが機能することを確認します。





表示する


4つのビューが必要です。これは、検索ビューSearchCarView.js 、テーブルビューCarGridView.js 、データ追加フォームAddCarFormView.jsのビュー、およびすべてのビューを配置するフレームビューCarCatalogView.jsです。





SerachCarView.js

 Ext.define('CarCatalog.view.SearchCarView', { extend: 'Ext.form.Panel', alias: 'widget.searchCarView', bodyPadding: 10, items: [ { xtype: 'textfield', name: 'search', fieldLabel: '  ', maxLength: 200 } ] });
      
      







CarGridView.js

 Ext.define('CarCatalog.view.CarGridView', { extend: 'Ext.grid.Panel', alias: 'widget.carGridView', width: 400, height: 300, frame: true, iconCls: 'icon-user', viewConfig:{ markDirty:false }, columns: [ { text: '', flex: 1, sortable: true, dataIndex: 'name', editor: { xtype:'textfield', allowBlank: false, blankText: '    ' } }, { flex: 2, text: '', sortable: true, dataIndex: 'price', editor: { xtype:'textfield', regex: /^([0-9]{1,20})*$/, regexText: '    ', allowBlank: false, blankText: '    ' } } ], plugins: [ Ext.create('Ext.grid.plugin.RowEditing', { clicksToEdit: 2, saveBtnText: '', cancelBtnText: '' }) ], selType: 'rowmodel', dockedItems: [ { xtype: 'toolbar', items: [ { text: '', action: 'add', iconCls: 'icon-add' }, '-', { action: 'delete', text: '', iconCls: 'icon-delete', disabled: true } ] } ] });
      
      







AddCarFormView.js

 Ext.define('CarCatalog.view.AddCarFormView', { extend: 'Ext.window.Window', alias: 'widget.addCarFormView', autoShow: true, layout: 'fit', modal: true, items: [ { bodyPadding: 10, xtype: 'form', items: [ { xtype: 'textfield', name: 'name', fieldLabel: ' ', allowBlank: false, blankText: '    ' }, { xtype: 'textfield', name: 'price', fieldLabel: '', regex: /^([0-9]{1,20})*$/, regexText: '    ', allowBlank: false, blankText: '    ' } ] } ], buttons: [ { text: '', action: 'save', disabled: true }, { text: '', handler: function () { this.up('window').close(); } } ] });
      
      







CarCatalogView.js

 Ext.define('CarCatalog.view.CarCatalogView', { extend: 'Ext.panel.Panel', width: 500, height: 360, padding: 10, alias: 'widget.carCatalogView', layout: 'border', items: [ { xtype: 'carGridView', region: 'center' }, { xtype: 'panel', html: '<div style="font: normal 18px cursive"><center><font size = "10"> </font></center></div>', region: 'north', height: 80 }, { xtype: 'searchCarView', title: '', region: 'west', width: 300, collapsible: true, collapsed: false } ], renderTo: Ext.getBody() });
      
      







app.jsでビューを指定します。

 Ext.application({ name: 'CarCatalog', views: [ 'AddCarFormView', 'CarCatalogView', 'CarGridView', 'SearchCarView' ], launch: function () { Ext.create('Ext.container.Viewport', { layout: 'fit', items: { xtype : 'carCatalogView' } }); } });
      
      







すべてが機能することを確認します。





コントローラー








CarCatalogController.js

 Ext.define('CarCatalog.controller.CarCatalogController', { extend: 'Ext.app.Controller', init: function () { this.control({ }); } });
      
      









モデルとストレージ






CarCatalogModel.js

 Ext.define('CarCatalog.model.CarCatalogModel', { extend: 'Ext.data.Model', fields: ['name', 'price'], proxy: { type: 'rest', api: { create: 'car', read: 'car', destroy: 'car', update: 'car' }, reader: { type: 'json', root: 'data', successProperty: 'success' }, writer: { type: 'json', writeAllFields: true } } });
      
      







CarCatalogStore.js

 Ext.define('CarCatalog.store.CarCatalogStore', { extend: 'Ext.data.Store', requires : [ 'CarCatalog.model.CarCatalogModel' ], model: 'CarCatalog.model.CarCatalogModel', autoLoad: true, autoSync: true, proxy: { type: 'rest', api: { create: 'car', read: 'car', destroy: 'car', update: 'car' }, reader: { type: 'json', root: 'data', successProperty: 'success' }, writer: { type: 'json', writeAllFields: true } } });
      
      







ストアパラメーター「CarCatalogStore」をCarGridView.jsに追加して、テーブルにデータを表示します。





app.jsでコントローラーCarCatalogController.jsCarCatalogStore.jsリポジトリーを指定します。

 Ext.application({ name: 'CarCatalog', views: [ 'AddCarFormView', 'CarCatalogView', 'CarGridView', 'SearchCarView' ], controllers : [ 'CarCatalogController' ], stores : [ 'CarCatalogStore' ], launch: function () { Ext.create('Ext.container.Viewport', { layout: 'fit', items: { xtype : 'carCatalogView' } }); } });
      
      







すべてが機能することを確認します。 404(見つかりません)-これは正常です。localhostには8080 /車がまだないためです。





サーバー(Java)



pom.xmlに依存関係を追加します
 <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.jvm.version>1.7</project.jvm.version> <spring.version>3.2.2.RELEASE</spring.version> <spring.security>3.1.4.RELEASE</spring.security> <slf4j.version>1.5.6</slf4j.version> <log4j.version>1.2.17</log4j.version> <hibernate.version>4.2.2.Final</hibernate.version> <jackson.version>1.9.12</jackson.version> <lombok.version>0.11.8</lombok.version> <querydsl.version>3.2.0</querydsl.version> <springkex.version>0.0.23-SNAPSHOT</springkex.version> </properties> <dependencies> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.6</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>${hibernate.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>2.2.2</version> </dependency> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.4</version> <scope>test</scope> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>4.3.1.Final</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-jpamodelgen</artifactId> <version>1.2.0.Final</version> <scope>provided</scope> </dependency> <dependency> <groupId>com.mysema.querydsl</groupId> <artifactId>querydsl-jpa</artifactId> <version>${querydsl.version}</version> </dependency> <dependency> <groupId>com.mysema.querydsl</groupId> <artifactId>querydsl-apt</artifactId> <version>${querydsl.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-core-asl</artifactId> <version>${jackson.version}</version> </dependency> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-mapper-asl</artifactId> <version>${jackson.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.0.1</version> <scope>provided</scope> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.1.3</version> </dependency> <dependency> <groupId>joda-time</groupId> <artifactId>joda-time</artifactId> <version>2.2</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> <version>${spring.security}</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-ldap</artifactId> <version>${spring.security}</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> <version>${spring.security}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-taglibs</artifactId> <version>${spring.security}</version> </dependency> <dependency> <groupId>opensymphony</groupId> <artifactId>quartz</artifactId> <version>1.6.3</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.7.2</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.7.2</version> <scope>provided</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <dependency> <groupId>commons-dbcp</groupId> <artifactId>commons-dbcp</artifactId> <version>1.4</version> <exclusions> <exclusion> <artifactId>commons-pool</artifactId> <groupId>commons-pool</groupId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>${log4j.version}</version> </dependency> <dependency> <groupId>com.jolbox</groupId> <artifactId>bonecp</artifactId> <version>0.7.1.RELEASE</version> </dependency> </dependencies>
      
      







Javaフォルダーを作成します。





データモデルとデータアクセスレイヤー(DAO)を作成します。





Car.java

 @Entity @Table(name = "cars") public class Car implements Serializable { @Id @Column(name = "ID") @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(name = "name") private String name; @Column(name = "price") private Long price; public Car() { } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Long getPrice() { return price; } public void setPrice(Long price) { this.price = price; } }
      
      







Cardao.java

 public interface CarDao { void add(Car car); void update(Car car); void delete(Car car); Collection<Car> getCars(String search); public List findByCar(String name, Long price); }
      
      







CarDaoImpl.java

 public class CarDaoImpl implements CarDao { @PersistenceContext private EntityManager emf; @Override public void add(Car car) { emf.persist(car); } @Override public void update(Car car) { emf.merge(car); } @Override public void delete(Car car) { emf.remove(emf.getReference(Car.class, car.getId())); } @Override public Collection<Car> getCars(String search) { if (null == search || search.trim().isEmpty()) { return emf.createQuery( "select c from Car c") .getResultList(); } return emf.createQuery( "select c from Car c where c.name like :search") .setParameter("search", search.trim() + "%") .getResultList(); } public List<Car> findByCar(String name, Long price) { return emf.createQuery( "select c from Car c where c.name = :name and c.price = :price") .setParameter("name", name) .setParameter("price", price) .getResultList(); } }
      
      







サービスレイヤーを作成します。





CarService.java

 public interface CarService { Boolean add(Car car); void update(Car car); Collection<Car> getCars(String search); void delete(Car car); }
      
      







CarServiceImpl.java

 public class CarServiceImpl implements CarService { private CarDao carDao; public CarDao getCarDao() { return carDao; } public void setCarDao(CarDao carDao) { this.carDao = carDao; } @Transactional @Override public Boolean add(Car car) { List<Car> duplicate = carDao.findByCar(car.getName(), car.getPrice()); if (duplicate.isEmpty()) { carDao.add(car); return true; } return false; } @Transactional @Override public void update(Car car) { carDao.update(car); } @Transactional @Override public Collection<Car> getCars(String search) { return carDao.getCars(search); } @Transactional @Override public void delete(Car car) { carDao.delete(car); } }
      
      







/ carアドレスにマッピングされるコントローラーを作成して、クライアントからのリクエストを処理します。





Carcontroller.java

 @Controller @RequestMapping("/car") public class CarController { @Autowired private CarService carService; @RequestMapping(method = RequestMethod.GET) @ResponseBody public Collection<Car> getCars(String search) { return carService.getCars(search); } @RequestMapping(method = RequestMethod.POST) @ResponseBody public ExtResult setCar(@RequestBody Car car) { return new ExtResult(carService.add(car), car); } @RequestMapping(value = "{id}", method = RequestMethod.DELETE) @ResponseBody public String deleteCar(@RequestBody Car car) { carService.delete(car); return "delete"; } @RequestMapping(value = "{id}", method = RequestMethod.PUT) @ResponseBody public String updateCar(@RequestBody Car car) { carService.update(car); return "update"; } }
      
      











ExtResult.java

 public class ExtResult { private boolean success; private Car data; public ExtResult(boolean success, Car data) { this.success = success; this.data = data; } public ExtResult() { } public boolean isSuccess() { return success; } public void setSuccess(boolean success) { this.success = success; } public Car getData() { return data; } public void setData(Car data) { this.data = data; } }
      
      







すべてが機能していることを確認します。 Mavenインストールを使用してプロジェクトをビルドし、アプリケーションを実行します。



スプリングコンテキストmy-context.xml cを作成します。







my-context.xml

 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" p:dataSource-ref="dataSource" p:packagesToScan="model" p:jpaProperties-ref="jpaProperties" p:persistenceProvider-ref="persistenceProvider"/> <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" depends-on="entityManagerFactory"/> <bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close" p:driverClass="com.mysql.jdbc.Driver" p:jdbcUrl="jdbc:mysql://localhost:3306/CarCatalog?characterEncoding=UTF-8" p:username="root" p:password="1234" p:idleConnectionTestPeriodInMinutes="1" p:idleMaxAgeInSeconds="240" p:minConnectionsPerPartition="2" p:maxConnectionsPerPartition="5" p:partitionCount="2" p:acquireIncrement="1" p:statementsCacheSize="100" p:releaseHelperThreads="2" p:statisticsEnabled="false"/> <bean id="persistenceProvider" class="org.hibernate.ejb.HibernatePersistence"/> <bean id="jpaProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean"> <property name="properties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> <prop key="connection.pool_size">1</prop> <prop key="current_session_context_class">thread</prop> <prop key="show_sql">true</prop> <prop key="hibernate.hbm2ddl.auto">create</prop> <prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop> </props> </property> </bean> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" p:entityManagerFactory-ref="entityManagerFactory"/> <tx:annotation-driven transaction-manager="transactionManager"/> <bean name="carDao" class="model.dao.impl.CarDaoImpl"> </bean> <bean name="CarService" class="service.impl.CarServiceImpl"> <property name="carDao" ref="carDao"> </property> </bean> </beans>
      
      







CarCatalogという名前とエンコードutf_general_ciを使用してデータベースを作成するか、コンテキストmy-context.xmlの名前を独自の名前に変更します。 また、 p:ユーザー名p:パスワードが一致しない場合は変更します



クライアントからのリクエストを処理するspring DispatcherServletの設定を作成しましょう。





mvc-dispatcher-servlet.xml

 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="controllers"/> <mvc:view-controller path="/" view-name="/index.jsp"/> <mvc:resources mapping="/**" location="/"/> <mvc:annotation-driven/> </beans>
      
      







Springコンテキストmy-context.xmlとspring DispatcherServletの設定をweb.xmlデプロイメント記述子に追加します。

 <?xml version="1.0" encoding="UTF-8"?> <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <servlet> <servlet-name>mvc-dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>mvc-dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath:/my-context.xml </param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app>
      
      







コンポーネントのrefsパラメーターとハンドラーをCarCatalogController.jsコントローラーに追加します。

 Ext.define('CarCatalog.controller.CarCatalogController', { extend: 'Ext.app.Controller', refs: [ {selector: 'carGridView', ref: 'carGridView'}, {selector: 'carGridView button[action="add"]', ref: 'carGridAdd'}, {selector: 'carGridView button[action="delete"]', ref: 'carGridDelete'}, {selector: 'searchCarView button[action="search"]', ref: 'searchCar'}, {selector: 'addCarFormView', ref: 'addCarFormView'}, {selector: 'carCatalogView', ref: 'carCatalogView'}, {selector: 'addCarFormView textfield[name=name] ', ref: 'addCarFormName'}, {selector: 'addCarFormView textfield[name=price]', ref: 'addCarFormPrice'}, {selector: 'addCarFormView button[action=save]', ref: 'addCarFormSave'} ], init: function () { this.control({ 'carGridView button[action=add]': { click: this.onAddCar }, 'carGridView button[action=delete]': { click: this.onDelCar }, 'searchCarView textfield[name="search"]': { change: this.onChangeText }, 'carGridView': { cellclick: this.onLineGrid }, 'addCarFormView button[action=save]': { click: this.onSaveCar }, 'addCarFormView textfield[name=name]': { change: this.onValidation }, 'addCarFormView textfield[name=price]': { change: this.onValidation } }); }, onSaveCar: function (button) { var me = this; var carModel = Ext.create('CarCatalog.model.CarCatalogModel'); carModel.set(this.getAddCarFormView().down('form').getValues()); carModel.save({ success: function (operation, response) { var objAjax = operation.data; Ext.getStore('CarCatalogStore').add(objAjax); me.getAddCarFormView().close(); }, failure: function (dummy, result) { Ext.MessageBox.show({ title: '!', msg: '     ', buttons: Ext.Msg.OK, icon: Ext.Msg.ERROR }); } }); }, onAddCar: function () { Ext.widget('addCarFormView'); }, onDelCar: function () { var sm = this.getCarGridView().getSelectionModel(); var rs = sm.getSelection(); this.getCarGridView().store.remove(rs[0]); this.getCarGridView().store.commitChanges(); this.getCarGridDelete().disable(); }, onChangeText: function () { Ext.getStore('CarCatalogStore').load({ params: { search: this.getCarCatalogView().down('searchCarView').getValues() } }); }, onLineGrid: function () { this.getCarGridDelete().enable(); }, onValidation: function () { if (this.getAddCarFormName().validate() && this.getAddCarFormPrice().validate()) { this.getAddCarFormSave().enable(); } else { this.getAddCarFormSave().disable(); } } });
      
      







そして最後-アイコンを「追加」ボタンと「削除」ボタンに追加します。





index.jsp

 <%@page contentType="text/html" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title></title> <link rel="stylesheet" type="text/css" href="resources/packages/ext-theme-neptune/build/resources/ext-theme-neptune-all.css"/> <script type="text/javascript" src="resources/ext-all.js"></script> <script type="text/javascript" src="resources/packages/ext-theme-neptune/build/ext-theme-neptune.js"></script> <script type="text/javascript" src="app.js"></script> <style type="text/css"> .icon-delete { background-image: url(resources/delete.png) !important; } .icon-add { background-image: url(resources/add.png) !important; } </style> </head> <body> </body> </html>
      
      














All Articles