Valider f319bf9d rédigé par RastaPopoulos's avatar RastaPopoulos
Parcourir les fichiers

Et voilà le gros morceau : création d'un sélecteur générique d'objets...

Et voilà le gros morceau : création d'un sélecteur générique d'objets permettant de naviguer hiérarchiquement si besoin.

Il faut appeler "formulaires/selecteur/generique" avec à peu près les mêmes options que dans l'ancien picker, sauf que pour préciser un chemin précis, on ne donne pas {id_article} ou {id_rubrique} mais {objet=truc} et {id_objet=XX}.

Ensuite il y a des options supplémentaires, dont surtout :
{whitelist=#ARRAY{liste des objets à sélectionner}}
{blacklist=#ARRAY{liste des objets à ne pas ...}}

Le code repose sur le même fonctionnement mais avec plus d'inclusions pour découper et détecter chaque type d'objet.

Pour ajouter un nouvel objet, il suffit de créer :
- obligatoirement : "hierarchie-TYPES.html"
- facultatif : lister-racine-TYPES.html pour lister cet objet à la racine du navigateur (peut très bien être une entrée unique si c'est pas hiérarchique)
- facultatif : lister-TYPES-TYPES.html pour faire la liste des TYPES contenu dans un autre TYPES
- facultatif : lister-TYPES-articles.html pour faire la liste des articles contenu dans un TYPES
- facultatif : lister-rubriques-TYPES.html pour faire la liste des TYPES contenu dans une rubrique
- etc etc... à vous de choisir suivant l'objet !

Pour l'instant je n'ai pas branché les interfaces (documents, etc) sur ce nouveau sélecteur, j'attends que l'on (je et ceux qui veulent) teste avant.

À terminer : le champ rapide ne fonctionne pas encore avec autre chose que rubriques/articles.
parent 92bbba58
Chargement en cours
Chargement en cours
Chargement en cours
Chargement en cours
+11 −0
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
@@ -358,14 +358,25 @@ prive/formulaires/recherche_ecrire.html -text
prive/formulaires/recherche_ecrire.php -text
prive/formulaires/rediriger_article.html -text
prive/formulaires/rediriger_article.php -text
prive/formulaires/selecteur/ajax.html -text
prive/formulaires/selecteur/articles.html -text
prive/formulaires/selecteur/articles_fonctions.php -text
prive/formulaires/selecteur/generique.html -text
prive/formulaires/selecteur/generique_fonctions.php -text
prive/formulaires/selecteur/hierarchie-articles.html -text
prive/formulaires/selecteur/hierarchie-racine.html -text
prive/formulaires/selecteur/hierarchie-rubriques.html -text
prive/formulaires/selecteur/inc-nav-articles.html -text
prive/formulaires/selecteur/inc-nav-rubriques.html -text
prive/formulaires/selecteur/inc-sel-articles.html -text
prive/formulaires/selecteur/inc-sel-rubriques.html -text
prive/formulaires/selecteur/jquery-ui-1.6.custom.js -text
prive/formulaires/selecteur/jquery.picker.js -text
prive/formulaires/selecteur/lister-racine-articles.html -text
prive/formulaires/selecteur/lister-racine-rubriques.html -text
prive/formulaires/selecteur/lister-rubriques-articles.html -text
prive/formulaires/selecteur/lister-rubriques-rubriques.html -text
prive/formulaires/selecteur/lister.html -text
prive/formulaires/selecteur/navigateur.html -text
prive/formulaires/selecteur/picker-ajax.html -text
prive/formulaires/selecteur/picker.css -text
+67 −0
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
#SET{bouton_modif,#ENV{select,''}|?{bouton_modifier,bouton_ajouter}|_T}

[(#REM) Afficher un bouton ajax Modifier a la premiere fois ]
[(#ENV{picker,''}|non)
<div class='picker_bouton'>&#91;<a href='[(#SELF|parametre_url{picker,1})]' class='ajax'>#GET{bouton_modif}</a>&#93;</div>
]

[(#REM) Afficher un bouton Fermer/Modifier ensuite ]
[(#ENV{picker,''}|oui)
<div class='picker_bouton'>
&#91;<a
	class='close'
	href='[(#SELF|parametre_url{picker,0})]'
	onclick="jQuery(this).parent().picker_toggle();return false;"
><:bouton_fermer:></a><a
	class='edit'
	href='[(#SELF|parametre_url{picker,1})]' 
	onclick="jQuery(this).parent().picker_toggle();return false;"
	style='display:none;'>#GET{bouton_modif}</a>&#93;
</div>

[(#REM) et enfin le navigateur ------]
<div class='browser'>
	<div class="choix choix_rapide">
		<label for="picker_rapide_#ENV{name}"><:label_ajout_id_rapide:></label>
		<input type="text" value="" id="picker_rapide_#ENV{name}" size="10" />
		<a id="bouton_picker_rapide_#ENV{name}" href="#">#GET{bouton_modif}</a>
		<script type="text/javascript" language="javascript" charset="utf-8">
			jQuery(function(){
				jQuery('#bouton_picker_rapide_#ENV{name}').click(function(){
					jQuery.ajax({
						dataType: 'json',
						url: '[(#URL_PAGE{ajax_selecteur})]',
						data: {
							rubriques: '#ENV{rubriques}',
							articles: '#ENV{articles}',
							ref: jQuery('#picker_rapide_#ENV{name}').attr('value')
						},
						success: function(r, statut, xhr){
							if (r){
								jQuery('#picker_rapide_#ENV{name}').item_pick(r.id,'#ENV{name,id_item}',r.titre,r.type);
							}
							jQuery('#picker_rapide_#ENV{name}').attr('value','');
						}
					});
					return false;
				});
				
				// Ne pas valider le formulaire si on appuie sur Entrée.
				jQuery('#picker_rapide_#ENV{name}').keypress(function(e){
					if (e.which == 13) {
						jQuery('a#bouton_picker_rapide_#ENV{name}').trigger("click");
						return false;
					}
				});
			});
		</script>
	</div>
	[(#ENV{objet}|=={racine}|ou{#ENV{id_objet}|=={0}}|oui)
		#SET{skel, racine}
	]
	[(#ENV{objet}|=={racine}|ou{#ENV{id_objet}|=={0}}|non)
		[(#SET{skel, [(#ENV{objet}|table_objet)]})]
	]
	<INCLURE{fond=formulaires/selecteur/hierarchie-#GET{skel}, env}>
</div>
]
+61 −0
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
#SET{img_unpick, #CHEMIN_IMAGE{supprimer-12.png}}
<script type='text/javascript'>var identifiant_selecteur = 'selecteur_#ENV{name}'; var img_unpick='#GET{img_unpick}';</script>
<script type='text/javascript' src='#CHEMIN{formulaires/selecteur/jquery.picker.js}'></script>
[(#REM)

afficher la selection dans un ul class item_picked

@param int select
	1 => le selecteur se comporte comme un select, avec un seul choix possible
@param string name
	nom de l'input envoye
@param string|array selected
	liste de valeurs sour la forme array("rubrique|9","article|8",...) ou "rubrique|9,article|8,..."
@param int afficher_langue

]

[(#REM) On commence par chercher la liste des objets disposant d'un sélecteur ]
[(#SET{objets, [(#ENV{whitelist,#ARRAY}|selecteur_lister_objets{#ENV{blacklist,#ARRAY}})]})]

<div id="selecteur_#ENV{name}">

<ul class='item_picked[ (#ENV{select,''}|?{select})]'>
<BOUCLE_selected(POUR){tableau #ENV{selected}|picker_selected}>
	[(#SET{objet, [(#VALEUR|table_valeur{objet})]})]
	[(#SET{id_objet, [(#VALEUR|table_valeur{id_objet})]})]
	[(#GET{id_objet}|=={0}|non)
	<li class="#GET{objet}">
		<input type="hidden" name="[(#ENV{name,id_item})][(#VAL{91}|chr)][(#VAL{93}|chr)]" value="#GET{objet}|#GET{id_objet}" />
		[(#ENV{afficher_langue,0}|oui)[&#91;(#INFO_LANG{#GET{objet},#GET{id_objet}})&#93;] ]#INFO_TITRE{#GET{objet},#GET{id_objet}}
		[(#ENV{select,''}|non)<a href='#' onclick='jQuery(this).item_unpick();return false;'><img src='#GET{img_unpick}' alt='(<:lien_supprimer:>)' /></a>]<span class="sep">, </span>
	</li>
	]
	[(#GET{id_objet}|=={0}|oui)
	<li class='rubrique'>
		<input type="hidden" name="[(#ENV{name,id_item})][(#VAL{91}|chr)][(#VAL{93}|chr)]" value="racine|0" />
		<:info_racine_site:>
		[(#ENV{select,''}|non)<a href='#' onclick='jQuery(this).item_unpick();return false;'><img src='[(#GET{img_unpick})]' alt='(<:lien_supprimer:>)' /></a>]<span class="sep">, </span>
	</li>
	]
</BOUCLE_selected>
</ul>

#SET{objet, #ENV{objet,racine}}
#SET{id_objet, #ENV{id_objet,0}}

[(#REM) le container item_picker est ici pour etre voisin de item_picked ------]
<div class='item_picker'>
<INCLURE{fond=formulaires/selecteur/ajax, objets=#GET{objets}, objet=#GET{objet}, id_objet=#GET{id_objet}, ajax, env}>
</div>

</div>

[(#ENV{sortable,'non'}|=={oui}|oui)
<script type='text/javascript' src='#CHEMIN{formulaires/selecteur/jquery-ui-1.6.custom.js}'></script>
<script type='text/javascript'>
jQuery(function() {
		jQuery("ul.item_picked").sortable();
	});
</script>
]
+104 −0
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<?php

if (!defined('_ECRIRE_INC_VERSION')) return;

/*
 * Fournit la liste des objets ayant un sélecteur
 * Concrètement, va chercher tous les formulaires/selecteur/hierarchie-truc.html
 * Ensuite on ajoute les parents obligatoires éventuels
 */
function selecteur_lister_objets($whitelist=array(), $blacklist=array()){
	$liste = find_all_in_path('formulaires/selecteur/', 'hierarchie-[\w]+[.]html$');
	$objets_selectionner = array();
	foreach ($liste as $fichier=>$chemin){
		$objets_selectionner[] = preg_replace('/^hierarchie-([\w]+)[.]html$/', '$1', $fichier);
	}
	
	// S'il y a une whitelist on ne garde que ce qui est dedans
	if (!empty($whitelist)){
		$whitelist = array_map('table_objet', $whitelist);
		$objets_selectionner = array_intersect($objets_selectionner, $whitelist);
	}
	// On supprime ce qui est dans la blacklist
	$blacklist = array_map('table_objet', $blacklist);
	// On enlève toujours la racine
	$blacklist[] = 'racine';
	$objets_selectionner = array_diff($objets_selectionner, $blacklist);
	
	// Ensuite on cherche ce qu'on doit afficher : au moins ceux qu'on peut sélectionner
	$objets_afficher = $objets_selectionner;
	// Il faut alors chercher d'éventuels parents obligatoires :
	// lister-trucs-bidules.html => on doit afficher des "trucs" pour trouver des "bidules"
	$liste = find_all_in_path('formulaires/selecteur/', 'lister-[\w]+-[\w]+[.]html$');
	foreach ($liste as $fichier=>$chemin){
		preg_match('/^lister-([\w]+)-([\w]+)[.]html$/', $fichier, $captures);
		$parent = $captures[1];
		$type = $captures[2];
		// Si le type fait partie de ce qu'on veut sélectionner alors on ajoute le parent à l'affichage
		if (in_array($type, $objets_selectionner)){
			$objets_afficher[] = $parent;
		}
	}
	
	$objets =  array(
		'selectionner' => array_unique($objets_selectionner),
		'afficher' => array_unique($objets_afficher),
	);
	
	return $objets;
}

/**
 * Transformer un tableau d'entrees array("rubrique|9","article|8",...)
 * en un tableau contenant uniquement les identifiants d'un type donne.
 * Accepte aussi que les valeurs d'entrees soient une chaine brute
 * "rubrique|9,article|8,..."
 *
 * @param array/string $selected liste des entrees : tableau ou chaine separee par des virgules
 * @param string $type type de valeur a recuperer ('rubrique', 'article')
 *
 * @return array liste des identifiants trouves.
**/
function picker_selected($selected, $type=''){
	$select = array();
	$type = preg_replace(',\W,','',$type);

	if ($selected and !is_array($selected))
		$selected = explode(',', $selected);

	if (is_array($selected))
		foreach($selected as $value){
			// Si c'est le bon format déjà
			if (preg_match('/^([\w]+)[|]([0-9]+)$/', $value, $captures)){
				$objet = $captures[1];
				$id_objet = intval($captures[2]);
				
				// Si on cherche un type et que c'est le bon, on renvoit un tableau que d'identifiants
				if (is_string($type) and $type == $objet and $id_objet){
					$select[] = $id;
				}
				else{
					$select[] = array('objet' => $objet, 'id_objet' => $id_objet);
				}
			}
		}
	return $select;
}

function picker_identifie_id_rapide($ref,$rubriques=0,$articles=0){
	include_spip("inc/json");
	include_spip("inc/lien");
	if (!($match = typer_raccourci($ref)))
		return json_export(false);
	@list($type,,$id,,,,) = $match;
	if (!in_array($type,array($rubriques?'rubrique':'x',$articles?'article':'x')))
		return json_export(false);
	$table_sql = table_objet_sql($type);
	$id_table_objet = id_table_objet($type);
	if (!$titre = sql_getfetsel('titre',$table_sql,"$id_table_objet=".intval($id)))
		return json_export(false);
	$titre = attribut_html(extraire_multi($titre));
	return json_export(array('type'=>$type,'id'=>"$type|$id",'titre'=>$titre));
}

?>
+28 −0
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<BOUCLE_art(ARTICLES){tout}{id_article=#ENV{id_objet}}{statut?}>
	<div class="chemin">
		<a href="[(#SELF|parametre_url{objet,racine}|parametre_url{id_objet,0})]" class="ajax"><:info_racine_site:></a>
		<BOUCLE_chemin(HIERARCHIE){id_rubrique}> &gt; <a href="[(#SELF|parametre_url{id_objet,#ID_RUBRIQUE})]" class="ajax">#TITRE</a></BOUCLE_chemin> &gt; <strong class="on">#TITRE</strong>
	</div>
	<B_contenu>
	[(#REM) afficher la racine si la profondeur le permet]
	<BOUCLE_test_racine(CONDITION){si (#_contenu:GRAND_TOTAL|<{#_contenu:TOTAL_BOUCLE}|oui)}>
	<div class="frame[ total_(#_contenu:GRAND_TOTAL|max{#_contenu:TOTAL_BOUCLE|moins{1}})] frame_0">
		<h2>
			[(#ENV{racine}|oui)
			<a href="#" onclick="jQuery(this).item_pick('racine|0','#ENV{name,id_item}','<:info_racine_site:>','racine');return false;">
			<img class="add" src="#CHEMIN_IMAGE{ajouter-16.png}" alt="ajouter" width="16" height="16" />
			</a>
			]
			<:info_racine_site:>
		</h2>
		#INCLURE{fond=formulaires/selecteur/lister, quoi=racine, env}
	</div>
	</BOUCLE_test_racine>
	<BOUCLE_contenu(HIERARCHIE){id_rubrique}{tout}{n-4,4}>
	<div class="frame[ total_(#GRAND_TOTAL|min{#TOTAL_BOUCLE|moins{1}})][ frame_(#COMPTEUR_BOUCLE|moins{#GRAND_TOTAL|plus{1}|max{#TOTAL_BOUCLE}}|plus{#TOTAL_BOUCLE})]">
		<a href="[(#SELF|parametre_url{id_objet,#ID_PARENT|?{#ID_PARENT}})]" class="frame_close ajax"><img src="#CHEMIN_IMAGE{fermer-16}" alt="fermer" width="16" height="16" /></a>
		<h2><a class="ajax" href="[(#SELF|parametre_url{id_objet,#ID_RUBRIQUE})]">#TITRE</a></h2>
		#INCLURE{fond=formulaires/selecteur/lister, quoi=rubriques, id_rubrique, env}
	</div>
	</BOUCLE_contenu>
</BOUCLE_art>
Chargement en cours